/* ============================================================
   FinDocAI - Complete Theme
   retailaccounting-inspired light enterprise UI
   make.com-inspired left rail + expandable menu panel
   ============================================================ */

/* ============================================================
   ROOT VARIABLES
   ============================================================ */
:root {
    --brand-dark: #0f2741;
    --brand-dark-2: #17324d;
    --brand-panel: #1c3852;
    --brand-panel-2: #21415d;
    /* Brand accent — sage palette aligned with the left nav rail
       (defined further down as --sage / --sage-dark / --sage-deep). The
       workbook header, primary CTAs, focus rings, and tab indicators all
       read off these vars so the entire product matches the left menu's
       deep-emerald character in one place.
       Note: --success stays at the bright #22a06b so success-state pills
       (Paid / Approved checkmarks) remain visually distinct from brand. */
    --brand-accent:      #2e4d3c;                       /* sage-dark — deep emerald, primary fills */
    --brand-accent-2:    #6c8e84;                       /* sage      — lighter sibling for hover    */
    --brand-accent-soft: rgba(108, 142, 132, 0.18);     /* sage tint — soft fills / focus halo      */
    --bg-page: #f6f8fb;
    --bg-card: #ffffff;
    --bg-soft: #f4f8fb;
    --bg-soft-2: #edf3f7;
    --bg-hover: #eef3f0;                                /* very light sage — matches --sage-soft family */
    --text-primary: #1d2733;
    --text-secondary: #627181;
    --text-muted: #8c98a6;
    --text-inverse: #ffffff;
    --text-nav: #dce7f0;
    --border: #e4ebf0;
    --border-strong: #d8e1e8;
    --border-focus: #6c8e84;                            /* sage — focus ring matches brand-accent-2 */
    --danger: #d94b4b;
    --warning: #d59a1f;
    --info: #4476d9;
    --success: #22a06b;
    --purple: #7a5ad8;
    --radius-sm: 8px;
    --radius-md: 14px;
    --radius-lg: 20px;
    --radius-xl: 24px;
    --topbar-h: 64px;
    --shadow-sm: 0 2px 8px rgba(16, 24, 40, 0.06);
    --shadow-md: 0 8px 24px rgba(16, 24, 40, 0.10);
    --shadow-lg: 0 18px 40px rgba(16, 24, 40, 0.14);
    --transition: 180ms ease;
    --font: 'Inter', 'Segoe UI', system-ui, sans-serif;
    --font-mono: 'JetBrains Mono', 'Cascadia Code', monospace;

    /* ── Type scale — single source of truth for the whole app.
       Keep new pages anchored to these tokens; never inline a font-size
       in pixels unless a one-off composite is genuinely required.

       Migration mapping for legacy inline px values you find in pages:
         font-size: 11px  →  var(--fs-caption)   (11.2px)
         font-size: 12px  →  var(--fs-meta)      (12.5px)
         font-size: 13px  →  var(--fs-body)      (14.0px)  ← slight upsize
         font-size: 14px  →  var(--fs-body)
         font-size: 16px  →  (use a class — default body context)
         font-size: 18-20px → var(--fs-h1) / var(--fs-h2) per intent */
    --fs-stat:    2rem;      /* dashboard hero-stat value (.stat-card-value) */
    --fs-display: 1.5rem;    /* page hero title — one per page */
    --fs-h1:      1.15rem;   /* card title */
    --fs-h2:      0.95rem;   /* section heading */
    --fs-body:    0.875rem;  /* default body text */
    --fs-meta:    0.78rem;   /* secondary/metadata text */
    --fs-caption: 0.7rem;    /* legend / pill / small uppercase headings */

    /* Spacing scale (4px base). Same idea — pages should hit this scale. */
    --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;
    --sp-4: 16px; --sp-5: 20px; --sp-6: 24px;
    --sp-8: 32px; --sp-10: 40px;
}

/* ============================================================
   RESET / BASE
   ============================================================ */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
    font-family: var(--font);
    font-size: 14px;
    color: var(--text-primary);
    background: var(--bg-page);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    overflow: hidden;
}

a {
    color: var(--brand-accent);
    text-decoration: none;
}

    a:hover {
        color: var(--brand-accent-2);
        text-decoration: none;
    }

button,
input,
select,
textarea {
    font: inherit;
}

/* ============================================================
   APP SHELL
   ============================================================ */
.app-shell {
    display: flex;
    min-height: 100vh;
    width: 100%;
    overflow: hidden;
    background: var(--bg-page);
}

.sidebar {
    display: flex;
    flex-direction: row;
    flex-shrink: 0;
    background: transparent !important;
    box-shadow: 2px 0 18px rgba(15, 39, 65, 0.08);
    z-index: 100;
}

/* ============================================================
   LEFT ICON RAIL
   ============================================================ */
.rail {
    width: 74px;
    min-width: 74px;
    height: 100vh;
    background: linear-gradient(180deg, #13304b 0%, #0f2741 100%);
    border-right: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 14px 0 12px;
    gap: 6px;
    overflow: hidden;
}

.rail-logo {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: linear-gradient(180deg, var(--brand-accent-2) 0%, var(--brand-accent) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    margin-bottom: 12px;
    box-shadow: 0 10px 22px rgba(34, 160, 107, 0.24);
    flex-shrink: 0;
}

.rail-spinner {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rail-nav {
    flex: 1;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2px 0;
    scrollbar-width: none;
}

    .rail-nav::-webkit-scrollbar {
        display: none;
    }

.rail-btn {
    width: 54px;
    min-height: 54px;
    border: none;
    border-radius: 16px;
    background: transparent;
    color: #a8b8c7;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 7px 5px;
    cursor: pointer;
    transition: all var(--transition);
    flex-shrink: 0;
}

    .rail-btn:hover {
        background: rgba(255, 255, 255, 0.08);
        color: #ffffff;
        transform: translateY(-1px);
    }

.rail-btn--on {
    background: rgba(34, 160, 107, 0.18);
    color: #b3f3d4;
    box-shadow: inset 0 0 0 1px rgba(179, 243, 212, 0.10);
}

    .rail-btn--on:hover {
        background: rgba(34, 160, 107, 0.24);
        color: #c7f7e0;
    }

.rail-icon {
    font-size: 18px;
    line-height: 1;
}

.rail-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.35px;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    max-width: 46px;
    text-overflow: ellipsis;
    text-align: center;
}

.rail-logout {
    margin-top: auto;
    color: rgba(255, 255, 255, 0.46);
}

    .rail-logout:hover {
        background: rgba(255, 84, 84, 0.12);
        color: #ff9d9d;
    }

/* ============================================================
   EXPANDABLE NAV PANEL
   ============================================================ */
.nav-panel {
    width: 0;
    min-width: 0;
    height: 100vh;
    overflow: hidden;
    background: transparent;
    border-right: none;
    display: flex;
    flex-direction: column;
    transition: width 220ms cubic-bezier(.4, 0, .2, 1);
}

.nav-panel--open {
    width: 240px;
    min-width: 240px;
    background: linear-gradient(180deg, #1c3852 0%, #17324d 100%);
    border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.nav-panel-header {
    height: 56px;
    padding: 0 14px 0 18px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    flex-shrink: 0;
}

.nav-panel-title {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 1.15px;
    text-transform: uppercase;
    color: #a9bdd0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-panel-close {
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: #88a0b8;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all var(--transition);
}

    .nav-panel-close:hover {
        background: rgba(255, 255, 255, 0.08);
        color: #ffffff;
    }

.nav-panel-items {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 10px 0;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}

.nav-panel-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 42px;
    padding: 0 16px;
    color: rgba(226, 235, 243, 0.78);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    transition: all var(--transition);
}

    .nav-panel-link:hover {
        background: rgba(255, 255, 255, 0.06);
        color: #ffffff;
    }

.nav-panel-link--active {
    background: rgba(34, 160, 107, 0.16);
    color: #b4f4d5;
}

    .nav-panel-link--active::before {
        content: "";
        position: absolute;
        left: 0;
        top: 6px;
        bottom: 6px;
        width: 3px;
        border-radius: 0 3px 3px 0;
        background: var(--brand-accent);
    }

.nav-panel-icon {
    font-size: 14px;
    flex-shrink: 0;
    opacity: 0.95;
}

.nav-panel-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-panel-badge {
    flex-shrink: 0;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--brand-accent);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
}

/* ============================================================
   MAIN AREA
   ============================================================ */
.main-area {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* ============================================================
   TOPBAR
   ============================================================ */
.topbar {
    height: var(--topbar-h);
    min-height: var(--topbar-h);
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 22px;
    box-shadow: var(--shadow-sm);
    z-index: 20;
    flex-shrink: 0;
}

.topbar-context {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.topbar-tenant {
    font-size: 15px;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.topbar-store {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

    .topbar-store .bi {
        color: var(--brand-accent);
        font-size: 10px;
    }

.topbar-spacer {
    flex: 1;
}

.topbar-icon-btn {
    width: 38px;
    height: 38px;
    border: none;
    border-radius: 12px;
    background: transparent;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    transition: all var(--transition);
}

    .topbar-icon-btn:hover {
        background: var(--bg-hover);
        color: var(--brand-accent);
    }

    .topbar-icon-btn .bi {
        font-size: 17px;
    }

.topbar-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #e03535;
    color: #fff;
    font-size: 9px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid #fff;
}

.topbar-user-wrap {
    position: relative;
    flex-shrink: 0;
}

.topbar-avatar-btn {
    border: 1px solid var(--border);
    border-radius: 999px;
    background: #fff;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 4px 4px;
    cursor: pointer;
    transition: all var(--transition);
}

    .topbar-avatar-btn:hover {
        border-color: rgba(34, 160, 107, 0.35);
        background: var(--bg-hover);
    }

.topbar-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(180deg, var(--brand-accent-2) 0%, var(--brand-accent) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 800;
    flex-shrink: 0;
}

.topbar-avatar--lg {
    width: 38px;
    height: 38px;
    font-size: 14px;
}

.topbar-user-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 0;
    gap: 1px;
}

.topbar-user-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.2;
}

.topbar-user-role {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.2;
}

.topbar-caret {
    font-size: 10px;
    color: var(--text-muted);
    transition: transform 200ms ease;
    flex-shrink: 0;
}

    .topbar-caret.rotated {
        transform: rotate(180deg);
    }

.topbar-dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    min-width: 240px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    z-index: 200;
}

/* ── Notification bell + dropdown ─────────────────────────────────────── */
.topbar-notify-wrap {
    position: relative;
    display: inline-flex;
}

.topbar-icon-btn-active {
    background: var(--bg-soft);
    color: var(--brand-accent);
}

/* Dropdown shape mirrors the user-menu dropdown so they read as siblings.
   Wider so notification text doesn't wrap awkwardly. */
.notify-dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    width: 380px;
    max-width: calc(100vw - 2rem);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: var(--shadow-lg, 0 16px 40px rgba(15, 23, 42, 0.14));
    overflow: hidden;
    z-index: 200;
    animation: notify-dropdown-in 140ms ease-out;
}

@keyframes notify-dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.notify-dropdown-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 1rem 0.7rem;
    border-bottom: 1px solid var(--border);
}

.notify-dropdown-title {
    font-weight: 700;
    color: var(--text-primary);
    font-size: 0.95rem;
}

.notify-dropdown-clear {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.3rem 0.45rem;
    border-radius: 6px;
    transition: background-color 120ms ease, color 120ms ease;
}

.notify-dropdown-clear:hover {
    background: #fee2e2;
    color: var(--danger);
}

/* Empty-state — first-run / inbox-zero look. */
.notify-dropdown-empty {
    padding: 2rem 1.25rem 1.75rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.88rem;
}

.notify-dropdown-empty .bi {
    display: inline-block;
    font-size: 1.65rem;
    margin-bottom: 0.55rem;
    opacity: 0.55;
}

.notify-dropdown-empty-sub {
    margin-top: 0.4rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    opacity: 0.85;
    line-height: 1.4;
}

/* List with vertical scroll cap so a long history doesn't blow out the
   viewport; rows themselves are full-width buttons. */
.notify-dropdown-list {
    max-height: 460px;
    overflow-y: auto;
    padding: 0.25rem 0;
}

.notify-item {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    width: 100%;
    padding: 0.65rem 0.95rem;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    cursor: pointer;
    text-align: left;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.notify-item:hover {
    background: var(--bg-soft);
}

/* Unread → soft brand-soft tint + a green accent rail on the left edge.
   Mirrors the read/unread treatment Gmail / Linear use. */
.notify-item-unread {
    background: var(--brand-accent-soft, rgba(34, 160, 107, 0.08));
    border-left-color: var(--brand-accent);
}

.notify-item-unread:hover {
    background: rgba(34, 160, 107, 0.14);
}

.notify-item-icon {
    font-size: 1.05rem;
    margin-top: 0.15rem;
    flex-shrink: 0;
}

.notify-item-body {
    flex: 1;
    min-width: 0;
}

.notify-item-title {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.1rem;
}

.notify-item-sub {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.notify-item-time {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-top: 0.2rem;
}

.topbar-dropdown-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: var(--bg-soft);
}

.topbar-dropdown-name {
    font-size: 13.5px;
    font-weight: 800;
    color: var(--text-primary);
}

.topbar-dropdown-role {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
}

.topbar-dropdown-divider {
    height: 1px;
    background: var(--border);
}

.topbar-dropdown-item {
    width: 100%;
    border: none;
    background: transparent;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 13.5px;
    text-align: left;
    transition: all var(--transition);
}

    .topbar-dropdown-item:hover {
        background: var(--bg-hover);
        color: var(--brand-accent);
    }

    .topbar-dropdown-item .bi {
        width: 18px;
        text-align: center;
        font-size: 15px;
    }

.topbar-dropdown-item--danger {
    color: #d13f3f;
}

    .topbar-dropdown-item--danger:hover {
        background: #fff1f1;
        color: #bb2d2d;
    }

/* ============================================================
   PAGE CONTENT
   ============================================================ */
.page-content {
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 24px;
    background: var(--bg-page);
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

/* ============================================================
   PAGE HEADER
   ============================================================ */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}

.page-header-left {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.page-header-title {
    /* Same display weight as .page-hero-title so simple-flat headers
       and icon-rich heroes share a vocabulary. */
    font-size: var(--fs-display);
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1.2;
}

.page-header-sub {
    font-size: var(--fs-body);
    color: var(--text-secondary);
}

.page-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.page-hero {
    display: flex;
    align-items: center;
    gap: 14px;
}

.page-hero-icon {
    width: 46px;
    height: 46px;
    border-radius: 14px;
    background: rgba(34, 160, 107, 0.12);
    color: var(--brand-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    flex-shrink: 0;
}

.page-hero-title {
    /* Hero pairs with an icon and sits on a card-like surface, so it's
       intentionally a notch smaller than the flat .page-header-title.
       Uses the same scale as a major card title for visual rhyme. */
    font-size: var(--fs-h1);
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1.2;
}

.page-hero-sub {
    font-size: var(--fs-body);
    color: var(--text-secondary);
    margin-top: 2px;
}

/* ============================================================
   UI PRIMITIVES — every reviewer / inbox / list page should
   reuse these so heading sizes, spacings, status pills, and
   table chrome stay consistent across the app. Tokens come
   from :root above.
   ============================================================ */

/* KPI strip — 1-to-N small stat tiles above a list. */
.kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
.kpi-tile {
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 10px;
    padding: var(--sp-3) var(--sp-4);
    position: relative;
    overflow: hidden;
}
.kpi-tile-label {
    font-size: var(--fs-caption);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted, #94a3b8);
}
.kpi-tile-value {
    font-size: 1.55rem;
    font-weight: 700;
    line-height: 1.1;
    margin-top: 4px;
    color: var(--text-primary, #0f172a);
}
.kpi-tile-sub {
    font-size: var(--fs-meta);
    color: var(--text-muted, #64748b);
    margin-top: 2px;
}
/* Tone modifiers — colour the value + a thin bottom bar. */
.kpi-tile.kpi-pending  .kpi-tile-value { color: #b45309; }
.kpi-tile.kpi-pending::after  { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: #f59e0b; }
.kpi-tile.kpi-approved .kpi-tile-value { color: #166534; }
.kpi-tile.kpi-approved::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: #22c55e; }
.kpi-tile.kpi-rejected .kpi-tile-value { color: #991b1b; }
.kpi-tile.kpi-rejected::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: #ef4444; }
.kpi-tile.kpi-info     .kpi-tile-value { color: #2563eb; }
.kpi-tile.kpi-info::after     { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: #3b82f6; }

/* Toolbar — universal layout for "search box on the left, filter pills /
   dropdowns on the right, primary action button at the far right". Most
   list / inbox / admin pages should grow into this instead of rolling
   their own grid. The toolbar is a thin wrapper; controls inside use
   their own classes (.form-control, .pill, .btn). */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 12px;
    padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-4);
}
.toolbar-search {
    position: relative;
    flex: 1 1 260px;
    max-width: 360px;
}
.toolbar-search > .bi {
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    color: #94a3b8;
    font-size: 0.85rem;
    pointer-events: none;
}
.toolbar-search .form-control,
.toolbar-search .form-control-sm { padding-left: 2rem !important; }
.toolbar-spacer { flex: 1; }   /* push trailing controls to the right */
.toolbar-actions { display: inline-flex; gap: var(--sp-2); align-items: center; }

/* Filter bar — pill row + free-text + dropdowns. */
.filter-bar {
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 12px;
    padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-4);
    display: flex;
    gap: var(--sp-3);
    align-items: center;
    flex-wrap: wrap;
}
.filter-bar label {
    font-size: var(--fs-caption);
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    display: block;
    margin-bottom: 4px;
}
.filter-bar .form-control,
.filter-bar .form-control-sm { font-size: var(--fs-body); padding: 6px 10px; min-height: 34px; height: auto; }

/* Pill-row tabs — reused for status filtering on inbox / review pages. */
.pill-row { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.pill {
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: var(--fs-meta);
    font-weight: 500;
    color: var(--text-strong, #1e293b);
    cursor: pointer;
    transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}
.pill:hover         { border-color: var(--brand-accent, #166534); color: var(--brand-accent, #166534); }
.pill.is-active     { background: var(--brand-accent, #166534); border-color: var(--brand-accent, #166534); color: #fff; }
.pill:focus-visible { outline: 2px solid var(--brand-accent, #166534); outline-offset: 2px; }

/* Data table chrome — every reviewer / inbox table should wrap with
   .data-table-wrap so the pager (PagerControls) sits inside the same
   border + radius. */
.data-table-wrap {
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 12px;
    overflow: hidden;
}
.data-table {
    width: 100%;
}
.data-table thead th {
    font-size: var(--fs-caption);
    font-weight: 700;
    color: var(--text-secondary, #475569);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 10px 14px;
    background: #f8fafc;
    border-bottom: 1px solid var(--border, #e2e8f0);
    text-align: left;
}
.data-table tbody tr      { border-bottom: 1px solid #f1f5f9; transition: background-color 120ms ease; }
.data-table tbody tr:last-child { border-bottom: none; }
.data-table tbody tr:hover{ background: #f8fafc; }
.data-table tbody td      { padding: 12px 14px; font-size: var(--fs-body); vertical-align: top; }
.data-table .data-row-clickable { cursor: pointer; }

/* Status pill — used everywhere a record carries a state. Keep the
   colour palette in sync with the kpi-tile tones above. */
.status-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: var(--fs-meta);
    font-weight: 600;
    line-height: 1.4;
}
.status-pill.is-draft      { background: #e2e8f0; color: #475569; }
.status-pill.is-submitted,
.status-pill.is-pending,
.status-pill.is-pendingreview { background: #fef3c7; color: #92400e; }
.status-pill.is-approved   { background: #dcfce7; color: #166534; }
.status-pill.is-rejected,
.status-pill.is-error      { background: #fee2e2; color: #991b1b; }
.status-pill.is-correction,
.status-pill.is-sentforcorrection { background: #ede9fe; color: #6d28d9; }
/* Pipeline states — short-lived stages the document moves through
   between Upload and PendingReview. Same blue family as info KPIs. */
.status-pill.is-uploaded,
.status-pill.is-classifying,
.status-pill.is-extracting,
.status-pill.is-validating { background: #dbeafe; color: #1d4ed8; }
/* Batch-mode Stage 2 — distinct teal so reviewers can tell at a glance
   that the doc is asleep waiting for Azure OpenAI Batch (up to 24h)
   rather than actively in pipeline. */
.status-pill.is-awaitingbatchextraction { background: #ccfbf1; color: #115e59; }
.status-pill.is-exported   { background: #cffafe; color: #155e75; }
.status-pill.is-cancelled  { background: #f1f5f9; color: #64748b; }
.status-pill.is-other      { background: #e2e8f0; color: #475569; }


/* ============================================================
   CARDS
   ============================================================ */
.card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.card-header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.card-title {
    font-size: var(--fs-h1);
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.3;
}

/* Optional caption sub-line under a card title — same scale as table caption text. */
.card-subtitle {
    font-size: var(--fs-meta);
    color: var(--text-secondary);
    margin-top: 2px;
}

.card-body {
    padding: 20px;
}

.card-footer {
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    background: var(--bg-soft);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}

/* ============================================================
   STAT CARDS
   ============================================================ */
.stat-grid,
.stats-grid,
.dash-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

/* Quick Actions strip — full-width row of 4 tiles. Auto-fit keeps it 4-up on
   wide screens, dropping to 2-up / 1-up at narrower widths. Used on the
   dashboard and reusable on any page that needs a row of CTA tiles. */
.dash-quick-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
}

.quick-tile {
    display: flex; align-items: center; gap: 12px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    text-decoration: none;
    color: inherit;
    background: #fff;
    cursor: pointer;
    transition: all .15s ease;
    min-height: 78px;
}
.quick-tile:hover {
    border-color: #6366f1;
    background: linear-gradient(180deg, #ffffff 0%, #f5f3ff 100%);
    transform: translateY(-1px);
    box-shadow: 0 6px 14px -8px rgba(99, 102, 241, .30);
}
.quick-tile-primary {
    background: linear-gradient(135deg, #4f46e5 0%, #6366f1 60%, #818cf8 100%);
    border-color: transparent;
    color: #fff;
    box-shadow: 0 4px 12px -4px rgba(79, 70, 229, .45);
}
.quick-tile-primary:hover {
    background: linear-gradient(135deg, #4338ca 0%, #4f46e5 60%, #6366f1 100%);
    color: #fff;
}
.quick-tile-icon {
    width: 42px; height: 42px; border-radius: 10px;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    background: #eef2ff; color: #4f46e5;
    font-size: 18px;
}
.quick-tile-primary .quick-tile-icon { background: rgba(255, 255, 255, .18); color: #fff; }
.quick-tile-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.quick-tile-text strong { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quick-tile-text small { font-size: 12px; opacity: .85; margin-top: 2px; }
.quick-tile-primary .quick-tile-text small { color: rgba(255, 255, 255, .92); }

/* Generic widget grid used by dashboard + report pages. Auto-fill so widgets
   reflow from N-up → 2-up → 1-up without media queries. Cards inside the grid
   share the same min-height so widget rows visually align even when content
   varies (table vs. progress bars vs. activity feed). card-body scrolls
   internally when content overflows. */
.dash-widget-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 20px;
    margin-bottom: 24px;
}
.dash-widget-grid > .card {
    display: flex; flex-direction: column;
    min-height: 380px;
}
.dash-widget-grid > .card > .card-body {
    flex: 1 1 auto;
    overflow-y: auto;
}

.stat-card {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 22px;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

    .stat-card:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
        border-color: rgba(34, 160, 107, 0.22);
    }

.stat-card-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

.stat-card-label {
    font-size: var(--fs-meta);
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

.stat-card-icon {
    width: 38px;
    height: 38px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
}

.stat-icon-green {
    background: #e8f8f0;
    color: #1d9a68;
}

.stat-icon-blue {
    background: #ecf3ff;
    color: #4773db;
}

.stat-icon-amber {
    background: #fff6e8;
    color: #dc9a22;
}

.stat-icon-red {
    background: #fff0f0;
    color: #d74c4c;
}

.stat-icon-purple {
    background: #f3edff;
    color: #7d57db;
}

.stat-card-value {
    font-size: var(--fs-stat);
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1;
}

.stat-card-delta {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: var(--fs-meta);
    font-weight: 700;
}

.delta-up {
    color: #1c9664;
}

.delta-down {
    color: #d13f3f;
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 9px 16px;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.4;
    border-radius: 10px;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    transition: all var(--transition);
}

    .btn:disabled {
        opacity: 0.55;
        pointer-events: none;
    }

    .btn .bi {
        font-size: 14px;
    }

.btn-primary {
    background: linear-gradient(180deg, var(--brand-accent-2) 0%, var(--brand-accent) 100%);
    color: #fff;
    border-color: var(--brand-accent);
    box-shadow: 0 8px 18px rgba(34, 160, 107, 0.18);
}

    .btn-primary:hover {
        background: linear-gradient(180deg, #31bb83 0%, #1c9664 100%);
        border-color: #1c9664;
        color: #fff;
        transform: translateY(-1px);
        box-shadow: 0 12px 24px rgba(34, 160, 107, 0.24);
    }

    .btn-primary:focus {
        outline: none;
        box-shadow: 0 0 0 4px rgba(34, 160, 107, 0.18);
    }

.btn-dark {
    background: var(--brand-dark);
    color: #fff;
    border-color: var(--brand-dark);
}

    .btn-dark:hover {
        background: var(--brand-dark-2);
        border-color: var(--brand-dark-2);
        color: #fff;
    }

.btn-outline {
    background: #fff;
    color: var(--text-primary);
    border-color: var(--border);
}

    .btn-outline:hover {
        background: var(--bg-hover);
        color: var(--brand-accent);
        border-color: rgba(34, 160, 107, 0.35);
    }

.btn-ghost {
    background: transparent;
    color: var(--text-secondary);
    border-color: transparent;
}

    .btn-ghost:hover {
        background: rgba(34, 160, 107, 0.08);
        color: var(--brand-accent);
    }

.btn-danger {
    background: #d74747;
    color: #fff;
    border-color: #d74747;
}

    .btn-danger:hover {
        background: #c63838;
        border-color: #c63838;
    }

.btn-sm {
    padding: 6px 12px;
    font-size: 12px;
}

.btn-lg {
    padding: 12px 22px;
    font-size: 15px;
}

.btn-block {
    width: 100%;
}

/* ============================================================
   FORMS
   ============================================================ */
.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 18px;
}

.form-label {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
}

.form-label-required::after {
    content: " *";
    color: var(--danger);
}

.form-hint {
    font-size: 12px;
    color: var(--text-muted);
}

.input-wrapper {
    position: relative;
    display: flex;
    align-items: center;
}

.input-icon {
    position: absolute;
    left: 12px;
    z-index: 1;
    color: var(--text-muted);
    font-size: 15px;
    pointer-events: none;
}

.input-icon-right {
    position: absolute;
    right: 12px;
    z-index: 1;
    color: var(--text-muted);
    font-size: 15px;
    cursor: pointer;
}

.form-control {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: #fff;
    color: var(--text-primary);
    font-size: 13.5px;
    font-family: var(--font);
    outline: none;
    transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}

    .form-control:focus {
        border-color: var(--border-focus);
        background: #fff;
        box-shadow: 0 0 0 4px rgba(34, 160, 107, 0.10);
    }

    .form-control.has-icon-left {
        padding-left: 38px;
    }

    .form-control.has-icon-right {
        padding-right: 38px;
    }

    .form-control.is-invalid {
        border-color: var(--danger);
    }

        .form-control.is-invalid:focus {
            box-shadow: 0 0 0 4px rgba(217, 75, 75, 0.10);
        }

select.form-control {
    cursor: pointer;
}

textarea.form-control {
    resize: vertical;
    min-height: 96px;
}

.form-check {
    display: flex;
    align-items: center;
    gap: 8px;
}

.form-check-input {
    width: 16px;
    height: 16px;
    accent-color: var(--brand-accent);
    cursor: pointer;
}

.form-check-label {
    font-size: 13px;
    color: var(--text-primary);
    cursor: pointer;
}

.form-error {
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--danger);
    font-size: 12px;
}

/* ============================================================
   FILTER BAR
   ============================================================ */
.filter-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

    .filter-bar .input-wrapper {
        flex: 1;
        min-width: 200px;
        max-width: 320px;
    }

.filter-bar-full {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    padding: 14px 16px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

    .filter-bar-full .input-wrapper {
        min-width: 180px;
        max-width: 260px;
    }

    .filter-bar-full select.form-control {
        min-width: 140px;
    }

.filter-separator {
    width: 1px;
    height: 24px;
    background: var(--border);
    flex-shrink: 0;
}

.filter-actions {
    display: flex;
    gap: 6px;
    margin-left: auto;
}

/* ============================================================
   TABLES
   ============================================================ */
.table-wrapper {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    /* overflow-x:auto + width:max-content on the table = horizontal scroller
       only when columns exceed the wrapper. overflow:hidden was clipping right-
       hand columns silently on grids with many fields (Payroll Net/Currency,
       Invoices Source/Actions). overflow-y stays clipped so the rounded-corner
       border-radius isn't broken by sticky column shadows. */
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    box-shadow: var(--shadow-sm);
}

.data-table {
    width: max-content;
    min-width: 100%;
    border-collapse: collapse;
}

    .data-table thead th {
        background: var(--bg-soft);
        color: var(--text-muted);
        font-size: 11.5px;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        text-align: left;
        white-space: nowrap;
        padding: 12px 16px;
        border-bottom: 1px solid var(--border);
    }

    .data-table tbody tr {
        border-bottom: 1px solid var(--border);
        transition: background var(--transition);
    }

        .data-table tbody tr:last-child {
            border-bottom: none;
        }

        .data-table tbody tr:hover {
            background: var(--bg-hover);
        }

    .data-table tbody td {
        padding: 13px 16px;
        font-size: 13.5px;
        color: var(--text-primary);
        vertical-align: middle;
    }

.table-actions {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* ============================================================
   BADGES
   ============================================================ */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 700;
    white-space: nowrap;
}

.badge-success {
    background: #e8f8f0;
    color: #1c9664;
}

.badge-warning {
    background: #fff6e8;
    color: #b77d14;
}

.badge-danger {
    background: #fff0f0;
    color: #c23c3c;
}

.badge-info {
    background: #edf4ff;
    color: #3f69cb;
}

.badge-neutral {
    background: #f2f5f8;
    color: var(--text-secondary);
}

.badge-purple {
    background: #f3edff;
    color: #7250c7;
}

.status-approved {
    background: #e8f8f0;
    color: #1c9664;
}

.status-pending {
    background: #fff6e8;
    color: #b77d14;
}

.status-review {
    background: #edf4ff;
    color: #3f69cb;
}

.status-error {
    background: #fff0f0;
    color: #c23c3c;
}

.status-processing {
    background: #f3edff;
    color: #7250c7;
}

.status-neutral {
    background: #f2f5f8;
    color: var(--text-secondary);
}

/* ============================================================
   ALERTS
   ============================================================ */
.alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    margin-bottom: 16px;
    border-radius: 12px;
    border: 1px solid;
    font-size: 13.5px;
}

    .alert .bi {
        font-size: 15px;
        margin-top: 1px;
        flex-shrink: 0;
    }

.alert-success {
    background: #e8f8f0;
    border-color: #bfead3;
    color: #155f3f;
}

.alert-warning {
    background: #fff6e8;
    border-color: #f6d89b;
    color: #8a5b12;
}

.alert-danger {
    background: #fff0f0;
    border-color: #f0b9b9;
    color: #8e2525;
}

.alert-info {
    background: #edf4ff;
    border-color: #c9daf9;
    color: #214e9b;
}

/* ============================================================
   LOADING / SPINNERS
   ============================================================ */
.spinner-ring {
    width: 24px;
    height: 24px;
    display: inline-block;
    border: 3px solid rgba(34, 160, 107, 0.18);
    border-top-color: var(--brand-accent);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

.spinner-sm {
    width: 16px;
    height: 16px;
    border-width: 2px;
}

.spinner-lg {
    width: 40px;
    height: 40px;
    border-width: 4px;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

.loading-overlay {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 48px;
    color: var(--text-muted);
    font-size: 13px;
}

/* ============================================================
   EMPTY STATE
   ============================================================ */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 56px 32px;
    text-align: center;
    color: var(--text-muted);
}

.empty-state-icon {
    font-size: 48px;
    color: #c7d1dc;
}

.empty-state-title {
    font-size: 16px;
    font-weight: 800;
    color: var(--text-secondary);
}

.empty-state-text {
    font-size: 13px;
    max-width: 340px;
}

/* ============================================================
   PAGINATION
   ============================================================ */
.pagination {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
}

.page-btn {
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    cursor: pointer;
    transition: all var(--transition);
}

    .page-btn:hover {
        background: var(--bg-hover);
        border-color: rgba(34, 160, 107, 0.35);
        color: var(--brand-accent);
    }

    .page-btn.active {
        background: var(--brand-accent);
        border-color: var(--brand-accent);
        color: #fff;
    }

    .page-btn:disabled {
        opacity: 0.45;
        pointer-events: none;
    }

.page-info {
    font-size: 12.5px;
    color: var(--text-muted);
    padding: 0 6px;
    white-space: nowrap;
}

/* Always-visible footer for data grids: "Showing N of M" + page-size selector
   + page nav. Used by Invoices/Payroll grids. Renders in flow under the table-
   wrapper, so the wrapper's horizontal scroller doesn't truncate the controls. */
.pagination-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding: 10px 14px;
    background: var(--bg-soft, #f8fafc);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.pagination-meta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-muted);
}

.pagination-meta strong { color: var(--text-primary); font-weight: 700; }

.pagination-controls {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.pagination-page-size {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
}

.pagination-page-size select {
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: #fff;
    font-size: 12px;
    color: var(--text-primary);
    cursor: pointer;
}

/* ============================================================
   MODAL
   ============================================================ */
.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: rgba(10, 20, 30, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.modal-box {
    width: 100%;
    max-width: 540px;
    /* Max-height keeps the modal inside the viewport; flex column + scrollable
       body means the header and footer stay pinned even when the form grows
       (the AI provider modal kept clipping its Save button when endpoint /
       strategy fields were added because the box was overflowing the screen). */
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 20px;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.modal-header {
    flex: 0 0 auto;     /* never shrink — keeps the title + close button visible */
    padding: 18px 24px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.modal-title {
    font-size: 16px;
    font-weight: 800;
    color: var(--text-primary);
}

.modal-close {
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    cursor: pointer;
}

    .modal-close:hover {
        background: var(--bg-hover);
        color: var(--text-primary);
    }

.modal-body {
    /* Body owns the leftover height + scrolls. Important so an over-tall form
       (AI providers with strategy mappings, vendor edit with GL picker open)
       doesn't push the footer's Save / Cancel buttons off the screen. */
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 24px;
}

.modal-footer {
    flex: 0 0 auto;   /* never shrink — keeps Save / Cancel visible */
    padding: 16px 24px;
    border-top: 1px solid var(--border);
    background: var(--bg-soft);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ============================================================
   TABS
   ============================================================ */
.tabs {
    display: flex;
    gap: 0;
    border-bottom: 2px solid var(--border);
    margin-bottom: 24px;
}

.tab-btn {
    border: none;
    background: transparent;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    padding: 10px 18px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-muted);
    cursor: pointer;
    transition: color var(--transition), border-color var(--transition);
}

    .tab-btn:hover {
        color: var(--text-primary);
    }

    .tab-btn.active {
        color: var(--brand-accent);
        border-bottom-color: var(--brand-accent);
    }

/* ============================================================
   BREADCRUMB
   ============================================================ */
.breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 20px;
    font-size: 13px;
    color: var(--text-muted);
}

    .breadcrumb a {
        color: var(--text-muted);
    }

        .breadcrumb a:hover {
            color: var(--brand-accent);
        }

.breadcrumb-sep {
    color: #c8d2db;
}

.breadcrumb-current {
    color: var(--text-primary);
    font-weight: 700;
}

/* ============================================================
   LOGIN  — fits at 100 % zoom on 1280 × 768 + viewports
   ============================================================ */
.login-shell {
    display: flex;
    width: 100vw;
    height: 100vh;           /* exact viewport — no overflow */
    overflow: hidden;
    background: radial-gradient(circle at top right, rgba(34,160,107,0.06) 0, rgba(34,160,107,0.00) 22%),
                radial-gradient(circle at bottom left, rgba(15,39,65,0.04) 0, rgba(15,39,65,0.00) 28%),
                #f7fafc;
}

/* ── LEFT BRAND PANEL ─────────────────────────────────────── */
.login-panel-left {
    width: 44%;
    min-width: 360px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 36px 44px;
    position: relative;
    overflow: hidden;            /* clips decorative blobs — prevents all scrollbars */
    border-right: 1px solid rgba(255,255,255,0.12);
}

/* Content wrapper sits above blobs and can scroll if viewport is very short */
.login-panel-left > * {
    position: relative;
    z-index: 1;
}

    .login-panel-left::before,
    .login-panel-left::after {
        content: "";
        position: absolute;
        border-radius: 50%;
        pointer-events: none;
        z-index: 0;
    }

    .login-panel-left::before {
        width: 380px;
        height: 380px;
        top: -120px;
        right: -120px;
        background: radial-gradient(circle, rgba(34,160,107,0.09) 0%, transparent 70%);
    }

    .login-panel-left::after {
        width: 300px;
        height: 300px;
        bottom: -100px;
        left: -80px;
        background: radial-gradient(circle, rgba(15,39,65,0.06) 0%, transparent 72%);
    }

.login-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 28px;         /* was 42px */
    position: relative;
    z-index: 1;
}

.login-brand-icon {
    width: 44px;
    height: 44px;
    border-radius: 14px;
    background: linear-gradient(180deg, #2db67d 0%, #22a06b 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 22px;
    box-shadow: 0 8px 20px rgba(34,160,107,0.20);
    flex-shrink: 0;
}

.login-brand-name {
    font-size: 22px;             /* was 28px */
    font-weight: 800;
    color: #f6f8fb;
    letter-spacing: -0.3px;
}

.login-hero {
    position: relative;
    z-index: 1;
}

.login-hero-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 14px;
    border-radius: 999px;
    background: rgba(34,160,107,0.12);
    color: #1d9a68;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    margin-bottom: 14px;         /* was 20px */
}

.login-hero-title {
    font-size: 36px;             /* was 52px — the main culprit */
    line-height: 1.12;
    font-weight: 800;
    color: #f6f8fb;
    margin: 0 0 14px;            /* was 20px */
    letter-spacing: -0.8px;
}

    .login-hero-title span { color: #f6f8fb; }

.login-hero-text {
    font-size: 14px;             /* was 20px */
    line-height: 1.65;
    color: rgba(246,248,251,0.70);
    margin-bottom: 22px;         /* was 34px */
}

.login-features {
    display: flex;
    flex-direction: column;
    gap: 12px;                   /* was 16px */
    position: relative;
    z-index: 1;
}

.login-feature-row {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;             /* was 18px */
    line-height: 1.5;
    color: rgba(246,248,251,0.85);
}

.login-feature-icon {
    width: 34px;
    height: 34px;
    min-width: 34px;
    border-radius: 10px;
    background: rgba(34,160,107,0.12);
    color: #4cd99a;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    box-shadow: inset 0 0 0 1px rgba(34,160,107,0.10);
    flex-shrink: 0;
}

/* ── RIGHT FORM PANEL ─────────────────────────────────────── */
.login-panel-right {
    flex: 1;
    min-width: 0;               /* prevents flex child from overflowing shell */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 24px;
    background: var(--bg-page, #f7fafc);
    overflow-y: auto;
    overflow-x: hidden;
}

.login-form-box {
    width: 100%;
    max-width: 420px;
    background: #ffffff;
    border: 1px solid #e4ebf0;
    border-radius: 20px;
    box-shadow: 0 16px 40px rgba(16,24,40,0.09);
    padding: 32px 30px;
}

.login-form-title {
    font-size: 22px;
    font-weight: 800;
    color: var(--text-primary, #1d2733);
    margin-bottom: 6px;
}

.login-form-subtitle {
    font-size: 13px;
    color: var(--text-secondary, #627181);
    margin-bottom: 24px;
    line-height: 1.55;
}

.login-form-box .form-group {
    margin-bottom: 16px;
}

.login-form-box .form-control {
    background: #fff;
    border: 1px solid #dfe7ed;
    min-height: 42px;
    font-size: 13.5px;
}

    .login-form-box .form-control:focus {
        border-color: #22a06b;
        box-shadow: 0 0 0 3px rgba(34,160,107,0.10);
    }

.login-form-box .btn-primary {
    width: 100%;
    min-height: 42px;
    border-radius: 10px;
    font-size: 14px;
}

.login-footer {
    margin-top: 18px;
    text-align: center;
    font-size: 12px;
    color: var(--text-muted, #8c98a6);
}

    .login-footer a {
        color: var(--brand-accent, #22a06b);
        font-weight: 700;
    }

/* ── Short viewport adjustments ──────────────────────────── */
@media (max-height: 680px) {
    .login-panel-left { padding: 24px 36px; }
    .login-brand      { margin-bottom: 16px; }
    .login-hero-title { font-size: 28px; margin-bottom: 10px; }
    .login-hero-text  { display: none; }
    .login-features   { gap: 8px; }
}

/* ============================================================
   DROP ZONE
   ============================================================ */
.drop-zone {
    border: 2px dashed var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-soft);
    padding: 40px 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    text-align: center;
    cursor: pointer;
    transition: border-color var(--transition), background var(--transition);
}

    .drop-zone:hover,
    .drop-zone.dragging {
        border-color: var(--brand-accent);
        background: var(--bg-hover);
    }

.drop-zone-icon {
    font-size: 40px;
    color: var(--text-muted);
}

.drop-zone-title {
    font-size: 15px;
    font-weight: 800;
    color: var(--text-primary);
}

.drop-zone-hint {
    font-size: 13px;
    color: var(--text-muted);
}

/* ============================================================
   FORM GRID / SECTIONS
   ============================================================ */
.form-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0 20px;
}

/* 4-column sub-row used under each party's street-address input on
   DocPreview so City / Province / Postal Code / Country all sit
   together right under the street line. Tighter font + no left icon
   keeps the row scannable without overwhelming the section. */
.address-subgrid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    margin-top: 6px;
}

.address-subgrid .form-control {
    font-size: 13px;
    padding: 6px 10px;
}

@media (max-width: 720px) {
    .address-subgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.form-section {
    margin-bottom: 24px;
}

.form-section-title {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-muted);
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 16px;
}

/* ============================================================
   ENTITY CARDS
   ============================================================ */
.entity-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    transition: background var(--transition);
    gap: 8px;
}

    .entity-card:last-child {
        border-bottom: none;
    }

    .entity-card:hover {
        background: var(--bg-hover);
    }

.entity-card--active {
    background: rgba(34, 160, 107, 0.08);
    border-left: 3px solid var(--brand-accent);
}

.entity-card-name {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.entity-card-sub {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

.entity-card-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

/* ============================================================
   TOGGLE SWITCH
   ============================================================ */
.toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

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

.toggle-label {
    font-size: 13.5px;
    color: var(--text-primary);
    font-weight: 500;
}

.toggle-label-sub {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

.toggle-switch {
    position: relative;
    width: 40px;
    height: 22px;
    flex-shrink: 0;
}

    .toggle-switch input {
        display: none;
    }

.toggle-slider {
    position: absolute;
    inset: 0;
    background: #ccd5de;
    border-radius: 22px;
    cursor: pointer;
    transition: background 200ms ease;
}

    .toggle-slider::before {
        content: '';
        position: absolute;
        width: 16px;
        height: 16px;
        background: #fff;
        border-radius: 50%;
        top: 3px;
        left: 3px;
        transition: transform 200ms ease;
        box-shadow: 0 1px 4px rgba(0,0,0,.2);
    }

.toggle-switch input:checked + .toggle-slider {
    background: var(--brand-accent);
}

    .toggle-switch input:checked + .toggle-slider::before {
        transform: translateX(18px);
    }

/* ============================================================
   PIPELINE STEPS
   ============================================================ */
.pipeline-steps {
    display: flex;
    align-items: center;
    gap: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: 20px;
}

.pipeline-step {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 20px;
    flex: 1;
    position: relative;
    background: var(--bg-soft);
    border-right: 1px solid var(--border);
    transition: background var(--transition);
}

    .pipeline-step:last-child {
        border-right: none;
    }

.pipeline-step--active {
    background: rgba(34, 160, 107, 0.07);
}

.pipeline-step-num {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--border);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.pipeline-step--active .pipeline-step-num {
    background: var(--brand-accent);
    color: #fff;
}

.pipeline-step-body {
    min-width: 0;
}

.pipeline-step-label {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
}

.pipeline-step-sub {
    font-size: 11.5px;
    color: var(--text-muted);
}

/* ============================================================
   DOCUMENT STATUS STRIP
   ============================================================ */
.doc-status-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: 16px;
}

.doc-status-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 16px;
    cursor: pointer;
    border-right: 1px solid var(--border);
    background: var(--bg-card);
    transition: background var(--transition);
    position: relative;
}

    .doc-status-item:last-child {
        border-right: none;
    }

    .doc-status-item:hover {
        background: var(--bg-hover);
    }

.doc-status-item--active {
    background: rgba(34, 160, 107, 0.06);
}

    .doc-status-item--active::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 3px;
        background: var(--brand-accent);
    }

.doc-status-count {
    font-size: 28px;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1;
}

.doc-status-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-top: 4px;
    display: flex;
    align-items: center;
    gap: 5px;
}

.doc-status-item--active .doc-status-label {
    color: var(--brand-accent);
}

/* ============================================================
   PROFILE PAGE
   ============================================================ */
.profile-avatar {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: var(--brand-accent);
    color: #fff;
    font-size: 28px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto;
}

.profile-context-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 8px;
}

.profile-context-row {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    color: var(--text-secondary);
    margin-bottom: 6px;
}

    .profile-context-row .bi {
        font-size: 13px;
        color: var(--text-muted);
    }

/* ============================================================
   UPLOAD INTAKE
   ============================================================ */
.upload-intake-card {
    border: 1px solid var(--border-focus);
    border-radius: var(--radius-md);
    background: rgba(34, 160, 107, 0.03);
    margin-bottom: 20px;
    overflow: hidden;
}

.upload-intake-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-card);
}

.upload-intake-body {
    padding: 20px;
}

.upload-intake-note {
    font-size: 12px;
    color: var(--text-muted);
    padding: 10px 14px;
    background: var(--bg-soft);
    border-radius: var(--radius-sm);
    border-left: 3px solid var(--brand-accent);
    margin-top: 14px;
}

/* ============================================================
   ROLE CARDS
   ============================================================ */
.role-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.role-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 18px;
    box-shadow: var(--shadow-sm);
    transition: border-color var(--transition), box-shadow var(--transition);
}

    .role-card:hover {
        border-color: var(--brand-accent);
        box-shadow: var(--shadow-md);
    }

.role-card-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 10px;
}

.role-card-name {
    font-size: 15px;
    font-weight: 700;
    color: var(--text-primary);
}

.role-card-meta {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

.role-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.role-card-stat {
    font-size: 12px;
    color: var(--text-muted);
}

.role-card-actions {
    display: flex;
    gap: 6px;
}

/* ============================================================
   UTILITIES
   ============================================================ */
.text-muted {
    color: var(--text-muted) !important;
}

.text-accent {
    color: var(--brand-accent) !important;
}

.text-danger {
    color: var(--danger) !important;
}

.text-success {
    color: var(--success) !important;
}

.fw-600 {
    font-weight: 600;
}

.fw-700 {
    font-weight: 700;
}

.gap-8 {
    gap: 8px;
}

.gap-12 {
    gap: 12px;
}

.mt-auto {
    margin-top: auto;
}

.mb-0 {
    margin-bottom: 0;
}

.flex-center {
    display: flex;
    align-items: center;
    justify-content: center;
}

.flex-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.flex-col {
    display: flex;
    flex-direction: column;
}

.avatar-initials {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--brand-accent);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 800;
}

/* ============================================================
   BLAZOR / VALIDATION
   ============================================================ */
.blazor-error-boundary {
    background: #b32121;
    color: #fff;
    border-radius: 10px;
    padding: 1rem 1rem 1rem 3.7rem;
}

    .blazor-error-boundary::after {
        content: "An unhandled error has occurred.";
    }

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 16px;
    right: 16px;
    padding: 14px 20px;
    background: #b32121;
    color: #fff;
    border-radius: 14px;
    box-shadow: var(--shadow-lg);
    font-size: 13.5px;
    z-index: 9999;
    align-items: center;
    gap: 12px;
}

#blazor-error-ui.blazor-error-ui-show {
    display: flex;
}

    #blazor-error-ui a {
        color: #fff;
        font-weight: 700;
        text-decoration: underline;
    }

.valid.modified:not([type=checkbox]) {
    border-color: #26b050;
}

.invalid {
    border-color: var(--danger);
}

.validation-message {
    color: var(--danger);
    font-size: 12px;
    margin-top: 4px;
}



:root {
    /* Sage green palette from retailaccounting.ca */
    --sage: #6c8e84; /* primary sage green */
    --sage-dark: #2e4d3c; /* hover / active forest */
    --sage-deep: #1e3428; /* deepest — rail/sidebar bg */
    --sage-mid: #2a3f36; /* drawer bg */
    --sage-soft: #e8efec; /* tint */
    --taupe: #747864; /* secondary neutral */
}

/* ── App shell: full-height, internal scrolling only ───────── */
.app-shell {
    display: flex;
    flex-direction: row;
    height: 100vh;
    width: 100%;
    overflow: hidden;
    background: #f6f7f5;
}

/* ── Sidebar host (aside) ──────────────────────────────────── */
/* Single full-width side nav. Width matches the per-store
   WorkspaceSidebar (.aw-side) so both look identical and the main
   content's left edge stays put when the user navigates between
   global and per-store pages. */
.sidebar-shell {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    width: 256px;
    height: 100vh;
    background: var(--bg-page);
    border-right: 1px solid var(--border, #e2e8f0);
    z-index: 50;
    overflow: hidden;          /* inner .aw-side handles its own scroll */
    /* Smooth width transition when the user toggles desktop collapse.
       Animating width directly avoids the content-jump that
       transform-based collapses cause, and the main-shell flexbox
       auto-fills the freed space without further work. */
    transition: width 180ms cubic-bezier(.2, .8, .2, 1);
}

/* ── Desktop collapsed state ──────────────────────────────────────────
   Activated by .app-shell.sidebar-collapsed on screens ≥ 1025px.
   The sidebar shrinks to a 64px icon strip; labels, section headings,
   and the brand text fade out; main content's flex: 1 auto-expands.

   Mobile (< 1024px) ignores this class — the off-canvas drawer rules
   in the lower @media block override .sidebar-shell width entirely. */
.app-shell.sidebar-collapsed .sidebar-shell {
    width: 64px;
}

/* When collapsed we let the sidebar overflow horizontally so the hover
   tooltips can escape to the right of the icon. Vertical scroll still
   works (the inner .aw-side-global keeps its own scroll). */
.app-shell.sidebar-collapsed .sidebar-shell {
    overflow: visible;
}
.app-shell.sidebar-collapsed .aw-side-global {
    overflow-x: visible;
    overflow-y: auto;
    padding: 0.85rem 0.3rem;
}
.app-shell.sidebar-collapsed .aw-side-brand-text,
.app-shell.sidebar-collapsed .aw-side-heading,
.app-shell.sidebar-collapsed .aw-side-link > span:not(.bi),
.app-shell.sidebar-collapsed .aw-side-link .aw-badge,
.app-shell.sidebar-collapsed .aw-side-logout > span:not(.bi) {
    opacity: 0;
    width: 0;
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
    transition: opacity 120ms ease;
}

/* Center the icons in their now-narrow rows. */
.app-shell.sidebar-collapsed .aw-side-link,
.app-shell.sidebar-collapsed .aw-side-logout,
.app-shell.sidebar-collapsed .aw-side-brand {
    justify-content: center;
    gap: 0;
    padding-left: 0.4rem;
    padding-right: 0.4rem;
}

/* Section divider becomes a thin rule with no label. */
.app-shell.sidebar-collapsed .aw-side-section {
    margin-top: 0.4rem;
}
.app-shell.sidebar-collapsed .aw-side-heading {
    height: 0;
    padding: 0;
    margin: 0;
    border: 0;
}

/* The icons themselves get a touch bigger so the hit target stays
   comfortable even without text alongside. */
.app-shell.sidebar-collapsed .aw-side-link .bi,
.app-shell.sidebar-collapsed .aw-side-logout .bi {
    font-size: 1.15rem;
}

/* ── Collapsed-sidebar hover tooltip ──────────────────────────────────
   Critical UX for the icon-only state: with text labels hidden, users
   need a way to identify each icon. We render an INSTANT custom tooltip
   from the title attribute (no 500ms browser-native delay) as a small
   dark pill anchored to the right of the icon. The pill includes a
   left-facing arrow so it visually attaches to its row.

   Why not just rely on the native browser tooltip?
   The browser's title tooltip has a ~500ms hover delay AND is styled by
   the OS — inconsistent across Chrome / Firefox / Edge / Safari. The
   CSS pill below is instant, branded, and identical across browsers.
   The native title attribute is KEPT on the markup for screen-reader
   accessibility — the browser tooltip will also appear, but later than
   ours, in the same spot, so users don't notice. */
.app-shell.sidebar-collapsed .aw-side-link,
.app-shell.sidebar-collapsed .aw-side-logout {
    position: relative;
}
.app-shell.sidebar-collapsed .aw-side-link:hover::after,
.app-shell.sidebar-collapsed .aw-side-logout:hover::after {
    content: attr(title);
    position: absolute;
    left: calc(100% + 14px);
    top: 50%;
    transform: translateY(-50%);
    background: #1f2937;
    color: #fff;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    pointer-events: none;
    z-index: 200;
    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.18);
    opacity: 0;
    animation: aw-tip-in 120ms ease-out forwards;
}
/* Left-facing arrow tip — drawn with a thin diamond rotated 45deg so it
   inherits the same background as the pill and reads as one solid shape. */
.app-shell.sidebar-collapsed .aw-side-link:hover::before,
.app-shell.sidebar-collapsed .aw-side-logout:hover::before {
    content: "";
    position: absolute;
    left: calc(100% + 8px);
    top: 50%;
    transform: translateY(-50%) rotate(45deg);
    width: 8px;
    height: 8px;
    background: #1f2937;
    z-index: 199;
    box-shadow: -2px 2px 4px rgba(15, 23, 42, 0.06);
    pointer-events: none;
    opacity: 0;
    animation: aw-tip-in 120ms ease-out forwards;
}
@keyframes aw-tip-in {
    from { opacity: 0; transform: translate(-4px, -50%); }
    to   { opacity: 1; transform: translate(0, -50%); }
}
.app-shell.sidebar-collapsed .aw-side-link:hover::before {
    /* keep the arrow's combined rotate + translate after animation */
    animation: aw-tip-arrow-in 120ms ease-out forwards;
}
.app-shell.sidebar-collapsed .aw-side-logout:hover::before {
    animation: aw-tip-arrow-in 120ms ease-out forwards;
}
@keyframes aw-tip-arrow-in {
    from { opacity: 0; transform: translate(-4px, -50%) rotate(45deg); }
    to   { opacity: 1; transform: translate(0, -50%) rotate(45deg); }
}

/* ── Global side nav (NavMenu.razor) ──────────────────────────
   Uses the .aw-side* classes shared with the per-store
   WorkspaceSidebar so both surfaces look identical. The
   .aw-side-global modifier here just makes the global one
   full-height with internal scroll instead of the workspace's
   sticky-top behaviour. */
.aw-side-global {
    height: 100vh;
    border-radius: 0;
    border: none;
    border-right: 1px solid var(--border, #e2e8f0);
    background: #fff;
    padding: 0.85rem 0.65rem;
    overflow-y: auto;
    overflow-x: hidden;
    position: relative;
    top: 0;
    display: flex;
    flex-direction: column;
}

.aw-side-brand {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.4rem 0.6rem 0.85rem 0.6rem;
    font-weight: 700;
    font-size: 1.02rem;
    color: var(--brand-accent, #2e4d3c);
    letter-spacing: -0.01em;
    border-bottom: 1px dashed var(--border, #e2e8f0);
    margin-bottom: 0.85rem;
}
.aw-side-brand .bi { font-size: 1.15rem; }
.aw-side-brand-text { letter-spacing: -0.005em; }

.aw-side-loading {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem 0;
    color: var(--text-muted, #94a3b8);
}

/* Logout button at the bottom of the nav. Uses the same row visual
   as a menu link so the family stays consistent. */
.aw-side-footer {
    margin-top: auto;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--border, #e2e8f0);
}
.aw-side-logout {
    width: 100%;
    border: none;
    background: transparent;
    color: var(--danger, #b02020);
    cursor: pointer;
    font-family: inherit;
    text-align: left;
}
.aw-side-logout:hover {
    background: rgba(217, 75, 75, 0.08);
    color: var(--danger, #b02020);
}

/* ── Main shell (topbar + scrollable page) ─────────────────── */
.main-shell {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    height: 100vh;
    overflow: hidden;
}

.app-topbar {
    height: 64px;
    background: #fff;
    border-bottom: 1px solid #e4e7e2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 24px;
    flex-shrink: 0;
    box-shadow: 0 1px 4px rgba(30, 52, 40, 0.04);
}

.app-topbar-left {
    display: flex;
    align-items: center;
    gap: 14px;
}

.app-topbar-right {
    display: flex;
    align-items: center;
    gap: 12px;
}

.topbar-context {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    padding: 0 12px 0 0;
    border-right: 1px solid #d4ddd6;
    margin-right: 4px;
}

.topbar-context-tenant {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 700;
    color: #1e3428;
    line-height: 1.2;
}

.topbar-context-store {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--taupe, #7c7263);
    line-height: 1.2;
}

    .topbar-context-tenant .bi,
    .topbar-context-store .bi {
        font-size: 11px;
        opacity: 0.7;
    }

.app-title-block {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.app-title {
    font-size: 15px;
    font-weight: 700;
    color: #1e3428;
    letter-spacing: -0.2px;
}

.app-subtitle {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--taupe);
}

/* Topbar buttons */
.topbar-icon-btn {
    position: relative;
    width: 38px;
    height: 38px;
    border: none;
    background: transparent;
    border-radius: 10px;
    color: var(--taupe);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    transition: background 150ms ease, color 150ms ease;
}

    .topbar-icon-btn:hover {
        background: var(--sage-soft);
        color: var(--sage-dark);
    }

.topbar-badge {
    position: absolute;
    top: 6px;
    right: 6px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    background: var(--sage);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.topbar-user-wrap {
    position: relative;
}

.topbar-user-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 10px 4px 4px;
    border: none;
    background: transparent;
    border-radius: 10px;
    cursor: pointer;
    transition: background 150ms ease;
}

    .topbar-user-btn:hover {
        background: var(--sage-soft);
    }

.topbar-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--sage);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.topbar-avatar-lg {
    width: 48px;
    height: 48px;
    font-size: 16px;
}

.topbar-user-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
}

.topbar-user-name {
    font-size: 13px;
    font-weight: 600;
    color: #1e3428;
    line-height: 1.2;
}

.topbar-user-role {
    font-size: 11px;
    color: var(--taupe);
}

.topbar-caret {
    font-size: 11px;
    color: var(--taupe);
    transition: transform 180ms ease;
}

    .topbar-caret.rotated {
        transform: rotate(180deg);
    }

.topbar-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 240px;
    background: #fff;
    border: 1px solid #e4e7e2;
    border-radius: 12px;
    box-shadow: 0 8px 24px rgba(30, 52, 40, 0.14);
    padding: 6px;
    z-index: 200;
}

.topbar-dropdown-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px;
}

.topbar-dropdown-name {
    font-size: 13px;
    font-weight: 700;
    color: #1e3428;
}

.topbar-dropdown-role {
    font-size: 11px;
    color: var(--taupe);
}

.topbar-dropdown-divider {
    height: 1px;
    background: #e4e7e2;
    margin: 4px 0;
}

.topbar-dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: none;
    background: transparent;
    border-radius: 8px;
    font-size: 13px;
    color: #1e3428;
    cursor: pointer;
    text-align: left;
    transition: background 150ms ease;
}

    .topbar-dropdown-item:hover {
        background: var(--sage-soft);
    }

.topbar-dropdown-item-danger {
    color: #b02020;
}

    .topbar-dropdown-item-danger:hover {
        background: #ffe6e6;
    }

/* ============================================================
   ACCOUNTANT WORKSPACE — per-store shell + sidebar
   Used by every page under /accountant/stores/{id}/**. The sidebar
   itself is the WorkspaceSidebar.razor component; these rules let
   any workspace page reuse it without duplicating CSS.
   ============================================================ */
.aw-shell {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 1.25rem;
    align-items: start;
}
@media (max-width: 1023px) {
    .aw-shell { grid-template-columns: 1fr; }
}

.aw-side {
    background: #fff;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 12px;
    padding: 1rem 0.75rem;
    position: sticky;
    top: 1rem;
}

.aw-back {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--text-muted, #475569);
    margin: 0 0.25rem 1rem;
}
.aw-back:hover { color: var(--brand-accent, #166534); }

.aw-side-section { margin-bottom: 1.05rem; }
.aw-side-heading {
    /* Sentinel small-cap heading — same typography rule both nav surfaces
       use, so eyes don't have to re-tune when switching. */
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.075em;
    font-weight: 700;
    color: var(--text-muted, #94a3b8);
    margin: 0 0.4rem 0.45rem;
    user-select: none;
}
.aw-side-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.65rem;
    border-radius: 8px;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-strong, #1e293b);
    text-decoration: none;
    transition: background-color 140ms ease, color 140ms ease;
}
.aw-side-link:hover {
    background: var(--brand-accent-soft, #f0f7ee);
    color: var(--brand-accent, #166534);
}
.aw-side-link:focus-visible {
    outline: 2px solid var(--brand-accent, #166534);
    outline-offset: 2px;
}
.aw-side-link-active {
    background: var(--brand-accent, #166534);
    color: #fff;
}
.aw-side-link-active:hover { background: var(--brand-accent, #166534); color: #fff; }
.aw-side-link .bi {
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
    opacity: 0.85;
}
.aw-side-link-active .bi { opacity: 1; }
.aw-side-link .aw-count {
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
}
.aw-count.is-pending { background: #fef3c7; color: #92400e; }
.aw-count.is-messages { background: var(--brand-accent, #2e4d3c); color: #fff; }

.aw-main { min-width: 0; }

/* ── Page content: THIS is the scroll container ────────────── */
.app-page {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    /* Top + sides only. Removing the bottom padding lets pages whose root
       element fills the scroll area (DocPreview's inv-preview-shell, etc.)
       reach the viewport bottom flush — keeping a 24px bottom padding here
       caused a visible cream strip below the document preview's action bar.
       Pages that genuinely need bottom breathing room add it via their own
       content margins (most do — cards, tables, sections all carry their
       own margin-bottom). */
    padding: 24px 24px 0 24px;
    background: #f6f7f5;
    min-height: 0;
}

/* DocPreview-only override — when the doc preview page is rendered, the
   .app-page becomes a flex column container so the .inv-preview-shell
   can use flex:1 0 auto to fill the visible viewport reliably. Scoped
   via :has() so it ONLY applies on this page (no global impact on
   dashboards, timesheet review, etc., which expect block flow).

   IMPORTANT: we DON'T set overflow:hidden here. .app-page keeps its
   existing `overflow-y: auto` so the page-level scroll continues to
   work — when the form gets tall (Line Items + Additional Info both
   enabled), the user scrolls the WHOLE page, not an inner sub-region.
   That was the regression the previous revision introduced. */
.app-page:has(> .inv-preview-shell) {
    display: flex;
    flex-direction: column;
}

/* (DocPreview shell extends itself over the parent padding-bottom via
   negative margin — see .inv-preview-shell rule. Earlier we used a
   :has() rule here which was less reliable across browser cache states.) */

/* ── Login page — sage accents ─────────────────────────────── */
.login-panel-left {
    background: var(--sage-deep) !important;
}

.login-brand-icon {
    background: var(--sage) !important;
}

.login-feature-icon,
.login-hero-tag .bi {
    color: var(--sage) !important;
}

/* Override existing accent with sage where it matters */
.btn-primary {
    background: var(--sage) !important;
    border-color: var(--sage) !important;
}

    .btn-primary:hover {
        background: var(--sage-dark) !important;
        border-color: var(--sage-dark) !important;
    }


/* ============================================================
   DATA GRID
   ============================================================ */
.dg-wrap {
    background: #fff;
    border: 1px solid #e4e7e2;
    border-radius: 12px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 1px 3px rgba(30, 52, 40, 0.04);
}

.dg-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid #e4e7e2;
    background: #fafbfa;
    gap: 12px;
}

.dg-toolbar-left {
    display: flex;
    align-items: center;
    gap: 10px;
}

.dg-toolbar-right {
    display: flex;
    align-items: center;
    gap: 8px;
}

.dg-title {
    font-size: 14px;
    font-weight: 700;
    color: #1e3428;
}

.dg-count {
    font-size: 11px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 10px;
    background: var(--sage-soft);
    color: var(--sage-dark);
}

.dg-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.dg-table {
    min-width: 100%;
    width: max-content;
    border-collapse: collapse;
    font-size: 13px;
}

.dg-head-row {
    background: #fafbfa;
}

.dg-th {
    text-align: left;
    padding: 10px 14px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--taupe);
    border-bottom: 1px solid #e4e7e2;
    user-select: none;
    white-space: nowrap;
}

.dg-th-inner {
    display: flex;
    align-items: center;
    gap: 6px;
}

.dg-sort {
    font-size: 10px;
    color: var(--sage);
}

.dg-th-actions {
    text-align: right;
}

.dg-filter-row {
    background: #fff;
}

.dg-filter-cell {
    padding: 6px 10px;
    border-bottom: 1px solid #eef1ed;
}

.dg-filter-input {
    width: 100%;
    padding: 5px 8px;
    font-size: 12px;
    border: 1px solid #e4e7e2;
    border-radius: 6px;
    background: #fafbfa;
    color: #1e3428;
    outline: none;
    transition: border-color 150ms ease, background 150ms ease;
}

    .dg-filter-input:focus {
        border-color: var(--sage);
        background: #fff;
    }

.dg-row {
    cursor: default;
    transition: background 120ms ease;
}

    .dg-row:hover {
        background: var(--sage-soft);
    }

.dg-td {
    padding: 12px 14px;
    border-bottom: 1px solid #eef1ed;
    color: #1e3428;
    vertical-align: middle;
    white-space: nowrap;
}

.dg-td-actions {
    text-align: right;
    white-space: nowrap;
}

.dg-state {
    text-align: center;
    padding: 44px 20px;
    color: var(--taupe);
    font-size: 13px;
}

    .dg-state .bi {
        font-size: 28px;
        display: block;
        margin-bottom: 6px;
        opacity: .6;
    }

.dg-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 18px;
    border-top: 1px solid #e4e7e2;
    background: #fafbfa;
    font-size: 12px;
    color: var(--taupe);
    gap: 12px;
    flex-wrap: wrap;
}

.dg-pager-info b {
    color: #1e3428;
}

.dg-pager-controls {
    display: flex;
    align-items: center;
    gap: 6px;
}

.dg-pager-size {
    padding: 5px 8px;
    font-size: 12px;
    border: 1px solid #e4e7e2;
    border-radius: 6px;
    background: #fff;
    color: #1e3428;
    margin-right: 8px;
}

.dg-pager-btn {
    width: 30px;
    height: 30px;
    border: 1px solid #e4e7e2;
    background: #fff;
    border-radius: 6px;
    color: var(--taupe);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 150ms ease;
}

    .dg-pager-btn:hover:not(:disabled) {
        border-color: var(--sage);
        color: var(--sage-dark);
        background: var(--sage-soft);
    }

    .dg-pager-btn:disabled {
        opacity: .4;
        cursor: not-allowed;
    }

.dg-pager-page {
    padding: 0 6px;
}

    .dg-pager-page b {
        color: #1e3428;
        font-weight: 700;
    }

/* Inline row-action icon buttons (used in RowActions slot) */
.dg-act-btn {
    width: 30px;
    height: 30px;
    border: 1px solid transparent;
    background: transparent;
    border-radius: 6px;
    color: var(--taupe);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 150ms ease;
    margin-left: 2px;
}

    .dg-act-btn:hover {
        background: var(--sage-soft);
        color: var(--sage-dark);
        border-color: #e4e7e2;
    }

.dg-act-btn-danger:hover {
    background: #ffe6e6;
    color: #b02020;
    border-color: #f5b0b0;
}

.dg-act-btn-success:hover {
    background: #e6f9f0;
    color: #166534;
    border-color: #86efac;
}

/* ============================================================
   MODAL (custom, no bootstrap dependency)
   ============================================================ */
.modal-backdrop-custom {
    position: fixed;
    inset: 0;
    background: rgba(30, 52, 40, 0.45);
    backdrop-filter: blur(2px);
    z-index: 1050;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    overflow-y: auto;
    animation: modalFadeIn 180ms ease;
}

@keyframes modalFadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.modal-dialog-custom {
    background: #fff;
    border-radius: 14px;
    box-shadow: 0 20px 60px rgba(30, 52, 40, 0.32);
    width: 100%;
    max-width: 560px;
    display: flex;
    flex-direction: column;
    animation: modalSlideIn 220ms cubic-bezier(.4,0,.2,1);
    max-height: calc(100vh - 80px);
}

@keyframes modalSlideIn {
    from {
        transform: translateY(-16px);
        opacity: 0;
    }

    to {
        transform: translateY(0);
        opacity: 1;
    }
}

.modal-sm {
    max-width: 420px;
}

.modal-md {
    max-width: 560px;
}

.modal-lg {
    max-width: 780px;
}

.modal-xl {
    max-width: 1040px;
}

.modal-header-custom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 18px 22px;
    border-bottom: 1px solid #e4e7e2;
    flex-shrink: 0;
}

.modal-header-text {
    display: flex;
    align-items: center;
    gap: 12px;
}

.modal-header-icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--sage-soft);
    color: var(--sage-dark);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
}

.modal-title-custom {
    font-size: 16px;
    font-weight: 700;
    color: #1e3428;
    letter-spacing: -0.2px;
}

.modal-subtitle {
    font-size: 12px;
    color: var(--taupe);
    margin-top: 2px;
}

.modal-close {
    width: 32px;
    height: 32px;
    border: none;
    background: transparent;
    border-radius: 8px;
    color: var(--taupe);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 150ms ease, color 150ms ease;
}

    .modal-close:hover {
        background: var(--sage-soft);
        color: var(--sage-dark);
    }

.modal-body-custom {
    padding: 22px;
    overflow-y: auto;
    flex: 1;
}

.modal-footer-custom {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 22px;
    border-top: 1px solid #e4e7e2;
    background: #fafbfa;
    border-radius: 0 0 14px 14px;
    flex-shrink: 0;
}
/* ============================================================
   TEMPLATE BUILDER
   ============================================================ */

.template-editor-layout {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: 20px;
    align-items: start;
}

.template-editor-sidebar {
    position: sticky;
    top: 20px;
}

.template-editor-main { min-width: 0; }

.template-group-header {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    font-weight: 700;
    color: var(--text-secondary);
    margin-bottom: 10px;
    padding: 0 4px;
}

.template-section-card {
    border: 1px solid var(--border-color);
    border-radius: 10px;
    overflow: hidden;
    margin-bottom: 12px;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,.05);
    transition: box-shadow .15s;
}

    .template-section-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,.08); }

.template-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    cursor: pointer;
    background: #fafbfa;
    border-bottom: 1px solid transparent;
    user-select: none;
    transition: background .12s;
}

    .template-section-card.expanded .template-section-header {
        border-bottom-color: var(--border-color);
        background: #f2f5f2;
    }

    .template-section-header:hover { background: #f2f5f2; }

.template-section-body { padding: 16px; }

.template-section-meta-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.template-field-row {
    border: 1px solid var(--border-color);
    border-radius: 8px;
    margin-bottom: 8px;
    overflow: hidden;
    transition: box-shadow .12s;
}

    .template-field-row.editing {
        border-color: var(--brand-accent, #2d6a4f);
        box-shadow: 0 0 0 2px rgba(45,106,79,.12);
    }

.template-field-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    cursor: pointer;
    background: #fafbfa;
    user-select: none;
}

    .template-field-row-top:hover { background: #f2f5f2; }

.template-field-editor {
    padding: 16px;
    background: #fff;
    border-top: 1px solid var(--border-color);
}

.template-field-editor-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.badge-control-type {
    background: #e8f0fe;
    color: #1a56db;
    font-size: 10px;
    padding: 2px 7px;
    border-radius: 4px;
    font-weight: 700;
    font-family: monospace;
    letter-spacing: .03em;
}

/* Preview page */
.preview-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    background: #f2f5f2;
    border-bottom: 1px solid var(--border-color);
    font-size: 14px;
}

    .preview-section-header.clickable { cursor: pointer; }

.preview-field label.form-label { font-size: 12px; }

/* Tab bar */
.tab-bar {
    display: flex;
    gap: 2px;
    border-bottom: 2px solid var(--border-color);
    padding-bottom: 0;
}

.tab-btn {
    background: none;
    border: none;
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    border-radius: 6px 6px 0 0;
    transition: all .12s;
}

    .tab-btn:hover { color: var(--text-secondary); background: var(--bg-hover); }
    .tab-btn.active { color: var(--brand-accent, #2d6a4f); border-bottom-color: var(--brand-accent, #2d6a4f); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 900px) {
    .nav-panel--open {
        width: 200px;
        min-width: 200px;
    }

    .page-content {
        padding: 18px;
    }

    .topbar {
        padding: 0 16px;
    }

    .topbar-user-text {
        display: none;
    }
}

@media (max-width: 800px) {
    .login-panel-left {
        display: none;
    }

    .login-panel-right {
        padding: 32px 20px;
    }
}

@media (max-width: 720px) {
    .form-grid-2 {
        grid-template-columns: 1fr;
    }
}

/* ── Invoice Preview Shell ────────────────────────── */
.inv-preview-shell {
    /* Layout is driven by the inline style="" on the .inv-preview-shell
       element in DocPreview.razor — that's load-bearing for the
       min-height calc and the flex column behavior. Class rules here
       only carry background; everything that affects sizing or
       positioning lives inline to bypass any CSS caching path. */
    background: transparent;
}

.inv-preview-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 1.25rem;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    gap: 0.75rem;
}

.inv-preview-topbar-left {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* workspace */
.inv-preview-workspace {
    display: flex;
    flex: 1;
    /* No overflow:hidden — the workspace flows in document order so the
       toggle row + Line Items + Additional Info + Action bar below all
       remain visible. The legacy split-pane layout used overflow:hidden
       to keep two iframes side-by-side; that's gated behind the
       _showSidebarPreview feature flag now. */
    gap: 0;
}

.inv-split {
    flex-direction: row;
}

.inv-full {
    flex-direction: column;
}

/* panels */
.inv-panel {
    overflow-y: auto;
    background: var(--bg-card);
}

.inv-panel-fields {
    flex: 0 0 55%;
    min-width: 420px;
    max-width: 880px;
    border-right: 1px solid var(--border);
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.inv-full .inv-panel-fields {
    flex: 1;
    max-width: 100%;
    border-right: none;
}

.inv-panel-doc {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* doc panel header */
.inv-doc-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-soft);
    flex-shrink: 0;
    font-size: 0.85rem;
}

.inv-doc-frame {
    flex: 1;
    overflow: hidden;
    position: relative;
}

.inv-iframe {
    width: 100%;
    height: 100%;
    border: none;
    display: block;
}

/* form sections (always expanded) */
.inv-section {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm, 8px);
    margin-bottom: 0.65rem;
    overflow: hidden;
    background: var(--bg-card, #fff);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.inv-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.6rem 0.9rem;
    background: var(--bg-soft);
    border-bottom: 1px solid var(--border);
    font-size: var(--fs-h2);
    font-weight: 600;
    color: var(--text-primary, #0f172a);
    transition: background-color 120ms ease;
}

.inv-section-header:hover {
    background: var(--bg-soft-hover, #eef1f6);
}

.inv-section-header:focus-visible {
    outline: 2px solid var(--brand-accent, #2e4d3c);
    outline-offset: -2px;
}

.inv-section-body {
    padding: 0;
}

/* legacy class kept for any older references; renders as plain header */
.inv-section-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0.6rem 0.9rem;
    background: var(--bg-soft);
    border: none;
    font-size: var(--fs-h2);
    font-weight: 600;
    text-align: left;
    cursor: default;
}

/* fields grid inside a section — CSS Grid, 12-col span model */
.inv-fields-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: 0.85rem;
    row-gap: 0.65rem;
    padding: 0.75rem 0.85rem;
}

/* field-width spans (mirrors FieldWidth enum) */
.inv-fw-full  { grid-column: span 12; }
.inv-fw-half  { grid-column: span 6; }
.inv-fw-third { grid-column: span 4; }

@media (max-width: 720px) {
    .inv-fw-half, .inv-fw-third { grid-column: span 12; }
}

/* individual field */
.inv-field {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;        /* allow shrinking inside CSS Grid tracks */
    width: 100%;
}

.inv-field-label {
    font-size: var(--fs-meta);
    font-weight: 600;
    color: var(--text-primary, #1f2937);
    display: flex;
    align-items: center;
    gap: 0.35rem;
    letter-spacing: 0.005em;
    margin-bottom: 0.15rem;
}

.inv-field-icon {
    font-size: var(--fs-meta);
    opacity: 0.85;
    color: var(--brand-accent, #2e4d3c);
}

.inv-field-input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    min-width: 0;
    font-size: var(--fs-body);
    padding: 0.45rem 0.6rem;
    height: auto;
    min-height: 2.25rem;
    line-height: 1.35;
    color: var(--text-primary, #0f172a);
    background: var(--bg-card, #fff);
    border: 1px solid var(--border, #d4d8e0);
    border-radius: 6px;
    transition: border-color 140ms ease, box-shadow 140ms ease;
}

textarea.inv-field-input { min-height: 4.5rem; resize: vertical; }
select.inv-field-input  { appearance: auto; -webkit-appearance: auto; }

.inv-field-input:focus {
    /* Sage focus ring — matches the rest of the app's focus state.
       Was using var(--accent) which is undefined and fell back to
       a hardcoded #4f6ef7 blue, the source of a long-standing
       colour drift versus every other input on the app. */
    border-color: var(--brand-accent, #2e4d3c);
    box-shadow: 0 0 0 3px var(--brand-accent-soft, rgba(108, 142, 132, 0.18));
    outline: none;
}

/* ── Form Builder — field state modifiers ────────────────────────────── */
.inv-field--warn .inv-field-label       { color: var(--warning, #f59e0b); }
.inv-field--warn .inv-field-input       { border-color: var(--warning, #f59e0b); }
.inv-field--required .inv-field-label   { color: var(--text-secondary); }

.inv-field-required-mark {
    color: var(--danger, #ef4444);
    margin-left: 0.15rem;
    font-size: var(--fs-meta);
}
.inv-field-warn-icon {
    margin-left: auto;
    font-size: var(--fs-caption);
    color: var(--warning, #f59e0b);
}

/* read-only display value */
.inv-field-readonly {
    font-size: var(--fs-body);
    padding: 0.45rem 0.6rem;
    background: var(--bg-subtle, #f8f9fa);
    border: 1px solid var(--border, #dee2e6);
    border-radius: 6px;
    min-height: 2.3rem;
    color: var(--text-primary, #0f172a);
    word-break: break-word;
    line-height: 1.35;
}

/* currency input wrapper */
.inv-field-currency-wrap {
    display: flex;
    align-items: stretch;
    gap: 0;
    width: 100%;
    min-width: 0;
    border: 1px solid var(--border, #dee2e6);
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-card, #fff);
}
.inv-field-currency-symbol {
    background: var(--bg-subtle, #f3f4f6);
    color: var(--text-secondary);
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.3rem 0.5rem;
    border-right: 1px solid var(--border, #dee2e6);
    white-space: nowrap;
    user-select: none;
}
.inv-field-input--currency {
    border: none !important;
    border-radius: 0 !important;
    flex: 1;
    text-align: right;
}
.inv-field-input--currency:focus { box-shadow: none; }

/* The legacy .status-badge / .status-{lowercase} stack has been
   consolidated into the canonical .status-pill / .status-pill.is-{state}
   primitive in the UI PRIMITIVES section above. New code should use
   .status-pill exclusively. */

/* action bar */
.inv-action-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 1.25rem;
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    flex-shrink: 0;
    /* Sticky to the bottom of the .app-page scroll viewport. On tall
       content (toggles expanded, 19 additional fields, etc.) the bar
       stays visible at the bottom of viewport while the user scrolls
       through the cards above. On short content, sticky is a no-op and
       the bar sits naturally just under the last card — no forced gap
       above it (which is what margin-top:auto used to do, leaving a
       visible cream slab between cards and the bar). */
    margin: 1rem 1rem 0 1rem;
    position: sticky;
    bottom: 0;
    z-index: 5;
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04), 0 1px 2px rgba(15, 23, 42, 0.03);
}

/* ── Document summary band ────────────────────────────────────────────────
   Enterprise AP-review pattern (Bill.com / Stampli / Ramp / Tipalti) — a
   strip of key-stat cells at the top of the preview so the reviewer can
   scan vendor / number / due date / total without scrolling. Cells flex
   so missing fields collapse cleanly; the Total cell anchors right and
   carries brand colour for hierarchy.
*/
.inv-summary-band {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    margin: 0 1.5rem 0.75rem;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm, 8px);
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    flex-shrink: 0;
}

.inv-summary-band-cell {
    flex: 1 1 160px;
    min-width: 0;
    padding: 0.55rem 0.85rem;
    background: var(--bg-card, #fff);
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.inv-summary-band-label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted, #64748b);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.inv-summary-band-label .bi {
    font-size: 0.75rem;
    opacity: 0.75;
}

.inv-summary-band-value {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--text-primary, #0f172a);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Due date cell — amber accent so reviewers spot deadlines */
.inv-summary-band-due .inv-summary-band-value {
    color: #b45309;
}

/* Total cell — brand colour + larger so it's the visual anchor */
.inv-summary-band-total {
    background: linear-gradient(135deg, var(--brand-accent-soft, rgba(108, 142, 132, 0.18)), var(--bg-card, #fff));
}

.inv-summary-band-total .inv-summary-band-value {
    font-size: 1.1rem;
    color: var(--brand-accent, #2e4d3c);
}

.inv-summary-band-ccy {
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--text-muted, #64748b);
    margin-left: 0.2rem;
}

/* ── Section reveal pills ──────────────────────────────────────────────
   Compact, enterprise-style row sitting between the summary band and the
   form. Shows one pill per non-essential section that carries data; the
   reviewer clicks a pill to reveal that section in the workspace below.
   Independent (not a toggle group) — multiple can be open at once. */
.inv-detail-pills {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0 1.5rem 0.85rem;
    padding: 0.55rem 0.7rem;
    background: var(--bg-card, #fff);
    border: 1px solid var(--border, #e2e8f0);
    border-radius: var(--radius-sm, 8px);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.inv-detail-pills-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-muted, #64748b);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.15rem 0.35rem 0.15rem 0.15rem;
    margin-right: 0.15rem;
}
.inv-pill {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.32rem 0.7rem;
    border-radius: 999px;
    border: 1px solid var(--border, #e2e8f0);
    background: var(--bg-card, #fff);
    color: var(--text-primary, #0f172a);
    font-size: 0.82rem;
    font-weight: 500;
    line-height: 1;
    transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
    white-space: nowrap;
}
.inv-pill:hover {
    border-color: var(--brand-accent, #2e4d3c);
    background: var(--brand-accent-soft, rgba(108, 142, 132, 0.18));
}
.inv-pill > .bi {
    font-size: 0.85rem;
    color: var(--text-muted, #64748b);
}
.inv-pill .inv-pill-chev {
    font-size: 0.72rem;
    opacity: 0.55;
    margin-left: 0.1rem;
}
.inv-pill-count {
    background: var(--border, #e2e8f0);
    color: var(--text-muted, #64748b);
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.18rem 0.42rem;
    border-radius: 999px;
    min-width: 1rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.inv-pill.is-active {
    background: var(--brand-accent, #2e4d3c);
    border-color: var(--brand-accent, #2e4d3c);
    color: #fff;
}
.inv-pill.is-active > .bi,
.inv-pill.is-active .inv-pill-chev { color: #fff; opacity: 0.95; }
.inv-pill.is-active .inv-pill-count {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}
.inv-pill-clear {
    all: unset;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    margin-left: auto;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-muted, #64748b);
}
.inv-pill-clear:hover {
    background: var(--brand-accent-soft, rgba(108, 142, 132, 0.18));
    color: var(--brand-accent, #2e4d3c);
}

/* ── DocPreview toggle switches (Line Items + Additional Info reveals) ──
   Each label is a chunky button-style toggle: prominent border, a real
   iOS-style track, and a clear active state (filled sage when on). Sits
   in its own row between the Invoice Details card and the gated panels
   so it can't be missed. */
.dp-toggles {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin: 0.25rem 0 1rem;
    padding: 0.7rem 0.9rem;
    background: var(--bg-card, #fff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .04);
}
.dp-toggles-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted, #64748b);
    margin-right: 0.25rem;
}
.dp-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    cursor: pointer;
    user-select: none;
    background: var(--bg-card, #fff);
    border: 1.5px solid var(--border-color, #e2e8f0);
    border-radius: 999px;
    padding: 0.45rem 0.95rem 0.45rem 0.6rem;
    transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease;
}
.dp-toggle:hover { border-color: var(--brand-accent, #2e4d3c); background: #fafdf8; }
.dp-toggle.is-on {
    border-color: var(--brand-accent, #2e4d3c);
    background: var(--brand-accent-soft, rgba(108, 142, 132, 0.18));
    box-shadow: 0 1px 4px rgba(22, 101, 52, 0.15);
}
.dp-toggle input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.dp-toggle-track {
    position: relative;
    width: 36px;
    height: 20px;
    border-radius: 999px;
    background: #cbd5e1;
    transition: background 120ms ease;
    flex-shrink: 0;
}
.dp-toggle-track::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
    transition: left 140ms ease;
}
.dp-toggle input:checked + .dp-toggle-track {
    background: var(--brand-accent, #2e4d3c);
}
.dp-toggle input:checked + .dp-toggle-track::after {
    left: 18px;
}
.dp-toggle-text {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text-primary, #0f172a);
}
.dp-toggle-text > .bi { color: var(--brand-accent, #2e4d3c); font-size: 0.95rem; }
.dp-toggle-count {
    background: var(--brand-accent, #2e4d3c);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.2rem 0.5rem;
    border-radius: 999px;
    min-width: 1.1rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
    margin-left: 0.25rem;
}

/* ── DocPreview Additional Information — flat label/value editor ────────
   Single column on narrow viewports, two columns on wider screens. Each
   row is an inline label-input + a value input + a remove button — both
   the label and value are editable so reviewers can rename + retype
   ad-hoc fields without touching the JSON. */
.dp-kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 0.6rem 1rem;
}
.dp-kv-row {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 0.5rem;
    align-items: start;
}
/* Editable variant — label / value / type-select / remove. The type
   selector sits between the value input and the remove X so reviewers
   can change Text → Date / Number / Yes-No without leaving the row. */
.dp-kv-row-editable {
    grid-template-columns: 150px 1fr 110px 32px;
}
.dp-kv-type {
    font-size: 0.78rem;
    padding: 0.25rem 0.4rem;
    height: auto;
}
.dp-kv-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted, #64748b);
    padding-top: 0.5rem;
}
.dp-kv-label-input {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted, #64748b);
    background: var(--bg-page, #f8fafc);
}
.dp-kv-input {
    width: 100%;
    font-size: 0.85rem;
}

/* Per-row remove button — small grey X that turns red on hover. Used by
   both the Line Items table and the Additional Information editor so
   the affordance is identical across the page. */
.dp-row-remove {
    all: unset;
    cursor: pointer;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted, #94a3b8);
    transition: background 120ms ease, color 120ms ease;
}
.dp-row-remove:hover {
    background: #fee2e2;
    color: #b91c1c;
}

/* ── DocPreview tax-breakdown rows (read-only, sidebar) ─────────────────
   Matches the AddInvoice tax-row visual language — label + sub-label on
   the left, rate in the middle, amount right-aligned. Read-only so no
   checkbox or input — just typeface weight + colour to distinguish. */
.dp-tax-row {
    display: grid;
    grid-template-columns: 1fr 70px 90px;
    gap: 8px;
    align-items: center;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-color, #e2e8f0);
}
.dp-tax-row:last-of-type { border-bottom: none; }
.dp-tax-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary, #0f172a);
}
.dp-tax-sub {
    font-size: 10px;
    color: var(--text-muted, #94a3b8);
    margin-top: 1px;
}
.dp-tax-rate {
    font-size: 12px;
    color: var(--text-muted, #64748b);
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.dp-tax-amount {
    font-size: 13px;
    font-weight: 600;
    text-align: right;
    color: var(--brand-accent, #2e4d3c);
    font-variant-numeric: tabular-nums;
}

/* Zero-amount tax row — show the canonical slot but muted so the eye
   skips past it, vs. populated rows in brand colour. The slot is still
   visible (so the reviewer knows GST/HST/PST/QST were considered), it
   just doesn't pretend to carry a real amount. */
.dp-tax-row.is-zero .dp-tax-label   { color: var(--text-muted, #94a3b8); font-weight: 500; }
.dp-tax-row.is-zero .dp-tax-rate    { color: var(--text-muted, #cbd5e1); }
.dp-tax-row.is-zero .dp-tax-amount  { color: var(--text-muted, #cbd5e1); font-weight: 500; }

/* Editable tax rows — wraps a small numeric input + currency / percent
   sigil so the row stays compact and right-aligned. The non-editable
   span variants above carry the same colour treatment so toggling
   between read-only and review modes doesn't shift the layout. */
.dp-tax-rate-edit,
.dp-tax-amount-edit {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    justify-content: flex-end;
    font-variant-numeric: tabular-nums;
}
.dp-tax-rate-edit   { color: var(--text-muted, #64748b); font-size: 12px; }
.dp-tax-amount-edit { color: var(--brand-accent, #2e4d3c); font-size: 13px; font-weight: 600; }
.dp-tax-unit       { color: var(--text-muted, #94a3b8); font-size: 11px; font-weight: 500; }
.dp-tax-input {
    width: 70px;
    border: 1px solid transparent;
    border-radius: 4px;
    padding: 2px 4px;
    text-align: right;
    background: transparent;
    font: inherit;
    color: inherit;
    font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
    appearance: textfield;
}
.dp-tax-input::-webkit-outer-spin-button,
.dp-tax-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dp-tax-input:hover { border-color: var(--border-color, #cbd5e1); }
.dp-tax-input:focus {
    outline: none;
    border-color: var(--brand-accent, #2e4d3c);
    background: #fff;
    box-shadow: 0 0 0 2px var(--brand-accent-soft, rgba(46, 77, 60, 0.12));
}

/* ── Searchable Dropdown ─────────────────────────── */
.sdl-wrap { position: relative; }
.sdl-list {
    position: absolute; z-index: 200; top: 100%; left: 0; right: 0;
    max-height: 220px; overflow-y: auto;
    background: var(--surface, #fff); border: 1px solid var(--border, #ddd);
    border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,.12);
    margin-top: 4px;
}
.sdl-item {
    padding: 8px 12px; cursor: pointer; font-size: 13px;
    transition: background .12s;
}
.sdl-item:hover { background: var(--row-hover, #f5f5f5); }
.sdl-item-active { background: rgba(108,142,132,.10); font-weight: 600; }
.sdl-empty { color: var(--text-muted, #888); font-style: italic; cursor: default; }
.sdl-empty:hover { background: transparent; }

/* ============================================================
   UPLOAD FLOW — guided doc-type → department → drag-drop wizard
   /upload          → doc-type tabs landing (Upload.razor)
   /upload/bills    → department cards (BillsDepartments.razor)
   ============================================================ */

/* Period picker — sits top-right next to the page hero */
.upload-period-picker {
    min-width: 260px;
    display: flex;
    align-items: center;
}

.upload-period-picker .form-select {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    padding: 0.5rem 0.85rem;
    font-size: 0.85rem;
    color: var(--text-primary);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    cursor: pointer;
}

.upload-period-picker .form-select:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: 1px;
}

/* Doc-type pill tabs — matches screenshot 1: 4 horizontal pills in
   one bar, active tab raised in white, others flat. */
.upload-tab-bar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
    margin: 0.25rem 1.5rem 1.25rem;
    padding: 0.45rem;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
}

.upload-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    padding: 0.85rem 1rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: calc(var(--radius-md, 14px) - 4px);
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text-primary);
    cursor: pointer;
    transition: background-color 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
    position: relative;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.upload-tab:hover {
    background: var(--bg-card);
    border-color: var(--border);
}

.upload-tab:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: -2px;
}

/* Active state — first tab (Bills) is enabled in this build, so it
   gets the raised treatment automatically via :not(.upload-tab-disabled). */
.upload-tab:not(.upload-tab-disabled):hover,
.upload-tab:not(.upload-tab-disabled):focus-visible {
    background: var(--bg-card);
    box-shadow: 0 2px 6px rgba(15, 23, 42, 0.06);
    border-color: var(--brand-accent-soft);
}

.upload-tab-icon {
    font-size: 1.05rem;
    opacity: 0.9;
}

.upload-tab-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* "Coming soon" tabs — visually present so users see what's planned,
   but disabled with a subtle badge. */
.upload-tab-disabled {
    color: var(--text-muted);
    cursor: not-allowed;
    opacity: 0.7;
}

.upload-tab-soon {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 0.1rem 0.4rem;
    border-radius: 999px;
    background: var(--bg-soft-2);
    color: var(--text-secondary);
}

.upload-tab-help {
    margin: 0 1.5rem 1rem;
    color: var(--text-muted);
    font-size: 0.82rem;
    text-align: center;
}

/* /documents/upload — 12-card doc-type grid. One card per
   DocumentTypeEnum member; each card carries an icon + title + tagline
   and routes to its own per-type flow. Disabled cards show a "Soon" pill
   so users see the roadmap without dead links. */
.docupload-card-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.85rem;
    padding: 0 1.5rem 0.75rem;
}

@media (max-width: 1280px) { .docupload-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 980px)  { .docupload-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .docupload-card-grid { grid-template-columns: 1fr; } }

.docupload-card {
    position: relative;
    text-align: left;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    padding: 1rem 1.1rem;
    cursor: pointer;
    transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    min-height: 96px;
}

.docupload-card:not(.docupload-card-disabled):hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);
    border-color: var(--brand-accent);
}

.docupload-card:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
}

.docupload-card-icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    flex-shrink: 0;
}

.docupload-card-body {
    min-width: 0;
    flex: 1;
}

.docupload-card-title {
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.15rem;
}

.docupload-card-sub {
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.35;
}

.docupload-card-soon {
    position: absolute;
    top: 0.6rem;
    right: 0.7rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 0.12rem 0.45rem;
    border-radius: 999px;
    background: var(--bg-soft-2);
    color: var(--text-secondary);
}

.docupload-card-disabled {
    cursor: not-allowed;
    opacity: 0.65;
}

.docupload-help {
    margin: 0 1.5rem 1.5rem;
    color: var(--text-muted);
    font-size: 0.82rem;
    text-align: center;
}

/* Department-cards grid — screenshot 2 layout: 3 columns desktop,
   collapses to 2 / 1 at narrower widths. Each card is clickable. */
.bills-back {
    margin-right: 0.25rem;
}

.bills-workbook {
    background: var(--brand-accent);
    color: #fff;
    border-color: var(--brand-accent);
    font-weight: 600;
    padding: 0.55rem 1rem;
    white-space: nowrap;
}

.bills-workbook:hover {
    background: var(--brand-accent-2);
    border-color: var(--brand-accent-2);
    color: #fff;
}

/* Grid header — back button | title block | workbook CTA. The grid
   `auto 1fr auto` layout guarantees the title block can shrink without
   the CTA ever sliding under it (the previous flex+space-between
   recipe overlapped on mid-width viewports because the title block
   carried an implicit 100% min-content). On narrow viewports the
   third column wraps to a new row via grid-auto-flow. */
.bills-page-header {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.85rem;
    padding: 1rem 1.25rem;
}
.bills-page-header .bills-back { margin: 0; }
.bills-page-title-block { min-width: 0; }
.bills-page-title-block .page-hero-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (max-width: 720px) {
    .bills-page-header {
        grid-template-columns: auto 1fr;
    }
    .bills-page-header .bills-workbook {
        grid-column: 1 / -1;
        justify-self: stretch;
    }
    .bills-workbook-text {
        font-size: 0.85rem;
    }
}

.dept-card-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    padding: 0 1.5rem 0.75rem;
}

@media (max-width: 1100px) {
    .dept-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
    .dept-card-grid { grid-template-columns: 1fr; }
}

.dept-card {
    text-align: left;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    padding: 1.1rem 1.25rem;
    cursor: pointer;
    transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-height: 96px;
}

.dept-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);
    border-color: var(--brand-accent);
}

.dept-card:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
}

.dept-card-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
}

.dept-card-name {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary);
}

/* Per-card invoice count — green pill matching the screenshot, sits next
   to the dept name on cards that already carry uploads. Only renders for
   non-zero counts so empty cards stay visually quiet. */
.dept-card-badge {
    background: var(--brand-accent);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 700;
    padding: 0.18rem 0.5rem;
    border-radius: 6px;
    line-height: 1;
    min-width: 1.5rem;
    text-align: center;
}

/* Active dept card — adds a subtle green wash so populated cards stand
   out from empty ones at a glance. */
.dept-card-active {
    background: linear-gradient(180deg, rgba(34, 160, 107, 0.04), var(--bg-card));
    border-color: var(--brand-accent-soft);
}

.dept-card-stat {
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* Workbook button count — secondary label inside the green CTA. Lighter
   weight than the title, parenthesised, so it reads as a quantity, not
   a competing word. */
.bills-workbook-count {
    margin-left: 0.4rem;
    font-weight: 500;
    opacity: 0.92;
}

.dept-card-footer {
    text-align: center;
    margin: 1rem 1.5rem 1.5rem;
    color: var(--text-muted);
    font-size: 0.82rem;
}

/* ============================================================
   /upload/bills/{deptCode} — drag-drop upload page
   ============================================================ */
.bills-upload-card {
    margin: 0 1.5rem 1.25rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.bills-upload-header {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.95rem 1.25rem 0.85rem;
    color: var(--brand-accent);
    font-weight: 700;
    font-size: 1.05rem;
}

.bills-upload-body {
    padding: 0 1.25rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.bills-upload-field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* Lever 3 — Processing-mode toggle on the upload page.
   iOS-style pill switch with a sliding thumb. The whole row is itself
   a <label> so clicking anywhere on the text — title, subtitle, even the
   gap — flips the switch (mobile-friendly hit-target). */
.bills-batch-toggle          { margin-top: 0.25rem; }

.bills-batch-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 12px;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.bills-batch-row:hover       { background: #f1f5f9; border-color: #cbd5e1; }
.bills-batch-row:has(input:checked) { background: #f0fdf4; border-color: #86efac; }

.bills-batch-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    line-height: 1.35;
    flex: 1;
    min-width: 0;
}
.bills-batch-title {
    font-size: 14px;
    font-weight: 600;
    color: #0f172a;
}
.bills-batch-sub {
    font-size: 12.5px;
    color: #64748b;
}

/* ── The switch itself ─────────────────────────────────────────────── */
.bills-switch {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    width: 44px;
    height: 24px;
    align-self: center;
}

/* Visually-hidden but still focusable + screen-reader-readable. */
.bills-switch input[type="checkbox"] {
    position: absolute;
    inset: 0;
    margin: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    z-index: 2;
}

.bills-switch-track {
    position: absolute;
    inset: 0;
    background: #cbd5e1;
    border-radius: 999px;
    transition: background .18s ease;
}

.bills-switch-thumb {
    position: absolute;
    top: 50%;
    left: 3px;
    width: 18px;
    height: 18px;
    background: #ffffff;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .25), 0 0 0 0.5px rgba(15, 23, 42, .08);
    transform: translateY(-50%);
    transition: left .18s ease;
}

/* ON state — green pill + thumb slid right. */
.bills-switch input:checked ~ .bills-switch-track            { background: #16a34a; }
.bills-switch input:checked ~ .bills-switch-track .bills-switch-thumb { left: 23px; }

/* Keyboard focus ring (only when tabbed-to, not when clicked). */
.bills-switch input:focus-visible ~ .bills-switch-track {
    outline: 2px solid #4f46e5;
    outline-offset: 2px;
}

/* Disabled-style only if we ever wire one. */
.bills-switch input:disabled ~ .bills-switch-track           { opacity: .55; cursor: not-allowed; }
.bills-switch input:disabled                                  { cursor: not-allowed; }

.bills-upload-label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-primary);
}

.bills-required {
    color: var(--danger);
    font-weight: 700;
}

/* Drag-drop zone — large dotted border, file picker behind a label so a
   click anywhere triggers it and HTML5 drag-and-drop works natively. */
.bills-dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    padding: 2.75rem 1rem;
    border: 2px dashed #d4c8a4;
    border-radius: var(--radius-md, 14px);
    background: #faf6ec;
    cursor: pointer;
    transition: background-color 140ms ease, border-color 140ms ease;
    text-align: center;
}

.bills-dropzone:hover,
.bills-dropzone-active {
    background: var(--brand-accent-soft);
    border-color: var(--brand-accent);
}

.bills-dropzone-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.bills-dropzone-icon {
    font-size: 2.25rem;
    color: var(--brand-accent);
    opacity: 0.85;
}

.bills-dropzone-title {
    font-size: 0.95rem;
    color: var(--text-primary);
}

.bills-dropzone-link {
    color: var(--brand-accent);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.bills-dropzone-sub {
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* Selected files list — appears below the drop zone after the user picks
   files; one row per file with file icon, name, size, and a per-row remove
   button (X) that disappears once that file is uploading / uploaded. */
.bills-selected {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.bills-selected-header {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--text-primary);
}

.bills-selected-list {
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    background: var(--bg-card);
    max-height: 260px;
    overflow-y: auto;
}

.bills-selected-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.85rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.88rem;
}

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

.bills-selected-icon {
    color: var(--text-secondary);
    font-size: 1rem;
    flex-shrink: 0;
}

.bills-selected-name {
    flex: 1;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bills-selected-size {
    color: var(--text-muted);
    font-size: 0.8rem;
    flex-shrink: 0;
}

.bills-selected-status {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.82rem;
    flex-shrink: 0;
}

.bills-selected-remove {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.3rem;
    border-radius: 6px;
    flex-shrink: 0;
    transition: background-color 120ms ease, color 120ms ease;
}

.bills-selected-remove:hover {
    background: var(--bg-soft);
    color: var(--danger);
}

/* Primary commit button — full width, brand green, mirrors the
   screenshot's "Upload N Invoices to Grocery" CTA. */
.bills-cta {
    width: 100%;
    padding: 0.85rem 1rem;
    background: var(--brand-accent);
    color: #fff;
    border: 1px solid var(--brand-accent);
    border-radius: var(--radius-md, 14px);
    font-size: 0.95rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    cursor: pointer;
    transition: background-color 140ms ease, opacity 140ms ease;
}

.bills-cta:hover:not(:disabled) {
    background: var(--brand-accent-2);
    border-color: var(--brand-accent-2);
}

.bills-cta:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* "How it works" helper card — green-tinted explainer below the upload
   card. Sets context for first-time uploaders without competing visually
   with the primary CTA above it. */
.bills-howto {
    margin: 0 1.5rem 1.5rem;
    padding: 1rem 1.25rem 1.1rem;
    background: #e9f8f0;
    border: 1px solid var(--brand-accent-soft);
    border-radius: var(--radius-md, 14px);
}

.bills-howto-title {
    color: var(--brand-accent);
    font-size: 0.98rem;
    font-weight: 700;
    margin-bottom: 0.55rem;
}

.bills-howto-list {
    margin: 0;
    padding-left: 1.15rem;
    color: var(--text-secondary);
    font-size: 0.88rem;
    line-height: 1.7;
}

.bills-howto-list li {
    margin-bottom: 0.1rem;
}

.bills-howto-list strong {
    color: var(--text-primary);
    font-weight: 700;
}

/* ============================================================
   /upload/bills/{deptCode}/review — extracted-invoices datagrid
   ============================================================ */
.bills-grid-wrap {
    margin: 0 1.5rem 1rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    overflow: hidden;
}

.bills-grid-scroll {
    overflow-x: auto;
    overflow-y: visible;
}

.bills-grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.84rem;
    color: var(--text-primary);
    /* 16 columns including Type / Status / Method dropdowns + Comments;
       the previous 1280px allocation collapsed Type/Status to a few px
       so the selected value clipped to "P…". The wrapper already
       horizontal-scrolls when the viewport is narrower. */
    min-width: 1500px;
}

.bills-grid thead th {
    position: sticky;
    top: 0;
    background: var(--bg-soft);
    color: var(--text-secondary);
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    padding: 0.7rem 0.65rem;
    text-align: left;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    z-index: 2;
}

.bills-grid tbody td {
    padding: 0.55rem 0.65rem;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.bills-grid tbody tr:nth-child(even) td {
    background: #fafbfc;
}

.bills-grid tbody tr:hover td {
    background: var(--bg-hover);
}

.bg-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.bg-cell-total {
    font-weight: 700;
}

.bg-col-check {
    width: 2.2rem;
    text-align: center;
}

.bg-col-num {
    width: 2.2rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.78rem;
}

.bg-col-actions {
    width: 7.5rem;
    text-align: right;
    white-space: nowrap;
}

.bg-cell-vendor,
.bg-cell-comments {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bg-cell-comments {
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.8rem;
    max-width: 160px;
}

/* Wider Comments column - applied via the bg-cell-comments-wide
   modifier on the workbook surfaces so the placeholder + note input
   has breathing room. Pre-fix the column was 160px so even short
   notes truncated mid-word. */
.bg-col-comments,
.bg-cell-comments-wide {
    min-width: 280px;
    max-width: 360px;
}
.bg-cell-comments-wide .bg-cell-input {
    width: 100%;
}

/* ============================================================
   Inline review modal (Components/Shared/InvoiceReviewModal.razor)
   ------------------------------------------------------------
   Opens the DocPreview page inside an iframe so a workbook user
   can verify / amend a single document without losing the grid
   context. Modal sized at 95vw x 92vh so the embedded preview
   has full editing room on any laptop; iframe carries the JWT
   cookie automatically (same origin).
   ============================================================ */
.dp-modal-mask {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.55);
    z-index: 1500;
    display: flex; align-items: center; justify-content: center;
    padding: 1.5vh 1.5vw;
}
.dp-modal-shell {
    width: 95vw;
    height: 92vh;
    max-width: 1600px;
    background: var(--surface-elevated, #fff);
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(15, 23, 42, 0.35);
    display: flex; flex-direction: column;
    overflow: hidden;
}
.dp-modal-head {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border-soft, #e5e7eb);
    background: linear-gradient(180deg, #f9fafb 0%, #ffffff 100%);
    flex-shrink: 0;
}
.dp-modal-eyebrow {
    font-size: 0.7rem; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--text-muted, #6b7280);
    font-weight: 600;
}
.dp-modal-title {
    font-size: 0.95rem; font-weight: 600;
    color: var(--text, #111827);
    max-width: 50vw;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dp-modal-spacer { flex: 1; }
.dp-modal-link {
    font-size: 0.8rem;
    color: var(--brand-accent, #0d6efd);
    text-decoration: none;
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
}
.dp-modal-link:hover { background: rgba(13, 110, 253, 0.08); }
.dp-modal-close {
    border: 0; background: transparent;
    width: 32px; height: 32px;
    border-radius: 6px;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
}
.dp-modal-close:hover { background: #f3f4f6; color: #111827; }
/* Scrolling content area of the modal. DocPreview renders inside this
   region as a Blazor child component (NOT an iframe), so the parent
   workbook's auth state + Blazor circuit are in scope and the modal
   doesn't bounce the user to /login. We just give the body its own
   scroll context so a long extraction list scrolls inside the modal
   instead of pushing the workbook page around. */
.dp-modal-body {
    flex: 1;
    width: 100%;
    overflow: auto;
    background: var(--surface, #f9fafb);
    padding: 0;
}

/* DocPreview, when hosted in the modal via Embed=true, may still render
   its own outer container sized against 100vh. Constrain it to the
   modal-body box so its inner scroll area lines up with our scroll
   context, not the viewport. */
.dp-modal-body .dp-shell,
.dp-modal-body .doc-preview-shell {
    height: auto !important;
    min-height: 100%;
}

/* Generic spin utility — used by refresh icons. There's already a
   @keyframes spin defined for the spinner; this just exposes it as a
   class the refresh button can toggle while loading. */
.spin {
    display: inline-block;
    animation: spin 0.85s linear infinite;
}

/* In-flight pill — shows next to the row count while Azure DI is still
   extracting one or more docs. Soft amber so reviewers know to wait. */
.bg-inflight-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: 0.6rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    background: #fef3c7;
    color: #78350f;
    font-size: 0.78rem;
    font-weight: 600;
}

.bg-inflight-pill .spinner-border {
    width: 0.75rem;
    height: 0.75rem;
    border-width: 0.15rem;
}

/* Status pills — Process / Paid / Error map onto neutral / green / red */
.bg-status {
    display: inline-block;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.bg-status-process { background: #fef3c7; color: #78350f; }
.bg-status-paid    { background: #dcfce7; color: #14532d; }
.bg-status-error   { background: #fee2e2; color: #991b1b; }

/* Inline-cell dropdowns — minimal native <select> styled to look like a
   plain label with a chevron, so the grid stays compact and the dropdown
   affordance is obvious on hover/click. Used by the Type / Vendor /
   Department / Status / Method columns. */
.bg-cell-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background: transparent
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%23627181' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/></svg>")
        no-repeat right 0.4rem center;
    border: 1px solid transparent;
    border-radius: 6px;
    padding: 0.32rem 1.4rem 0.32rem 0.45rem;
    font-size: 0.84rem;
    font-family: inherit;
    color: var(--text-primary);
    cursor: pointer;
    /* Size the dropdown to its content (so the selected value never
       gets ellipsis-clipped to "P…") and let the table column expand
       to fit. Without min-width the column collapses to a few px when
       the grid is tight; without auto width the select inherits the
       narrow td and clips. */
    width: auto;
    min-width: 7.5rem;
    max-width: 100%;
    white-space: nowrap;
    transition: background-color 120ms ease, border-color 120ms ease;
}

/* Wider min for the Method column — its longest option ("Bank Transfer"
   / "Credit Card" / "EFT/PAD") needs more room than Type/Status. */
.bills-grid td:nth-child(13) .bg-cell-select { min-width: 9rem; }

.bg-cell-select:hover {
    background-color: var(--bg-soft);
    border-color: var(--border);
}

.bg-cell-select:focus {
    background-color: var(--bg-card);
    border-color: var(--brand-accent);
    outline: none;
    box-shadow: 0 0 0 3px var(--brand-accent-soft);
}

/* Status cell — wrap the select with the pill background so the dropdown
   adopts the colour without painting the entire <td>. The select itself
   inherits the cell's text colour (set by .bg-status-{kind} on the td). */
.bg-status-cell {
    padding: 0.35rem 0.55rem !important;
}

.bg-cell-status-select {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: inherit;
    border-radius: 999px;
    padding: 0.2rem 1.2rem 0.2rem 0.6rem;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/></svg>");
    background-position: right 0.45rem center;
    /* Status pill — uppercase 0.72rem so "APPROVED" + chevron needs
       roughly 6.5rem. Pin a min-width so the pill never truncates to
       "P…" inside a tight column. */
    min-width: 6.5rem;
}

.bg-cell-status-select:hover { background-color: rgba(0, 0, 0, 0.04); }

.bg-cell-status-select option { color: var(--text-primary); }

td.bg-status-process    { background: #fef3c7 !important; color: #78350f; }
td.bg-status-paid       { background: #dcfce7 !important; color: #14532d; }
td.bg-status-error      { background: #fee2e2 !important; color: #991b1b; }
/* Submitted to accountant — informational blue, locks the row but
   doesn't suggest a problem (vs. error red or pending amber). */
td.bg-status-submitted  { background: #dbeafe !important; color: #1e3a8a; }
/* Sent for Correction — accountant returned the doc for fixes; amber
   like Process but with a darker border to signal "action required". */
td.bg-status-correction { background: #ffedd5 !important; color: #9a3412; }

/* Inline text input for the Comments cell — same low-chrome styling as
   the dropdowns, so an editable note doesn't visually shout. */
.bg-cell-input {
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    padding: 0.32rem 0.45rem;
    font-size: 0.82rem;
    color: var(--text-primary);
    width: 100%;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.bg-cell-input::placeholder {
    color: var(--text-muted);
    font-style: italic;
}

.bg-cell-input:hover  { background: var(--bg-soft); border-color: var(--border); }
.bg-cell-input:focus  {
    background: var(--bg-card);
    border-color: var(--brand-accent);
    outline: none;
    box-shadow: 0 0 0 3px var(--brand-accent-soft);
}

/* Numeric variant — right-align so column reads as a money column even
   in edit mode. Hides the spinner so the cell stays clean. */
.bg-cell-input-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.bg-cell-input-num::-webkit-outer-spin-button,
.bg-cell-input-num::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.bg-cell-input-num { -moz-appearance: textfield; }

/* Row of input + warning glyph inside a single cell. The flex layout
   keeps the icon snug against the value without pushing column widths
   around. min-width:0 on the wrapper lets the input shrink past the
   content size so long values get the input's normal overflow. */
.bg-cell-value-row {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
}
.bg-cell-value-row > .bg-cell-input,
.bg-cell-value-row > .bg-cell-select { flex: 1; min-width: 0; }

/* Split badge — shown when an invoice is allocated across multiple depts */
.bg-split-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.18rem 0.55rem;
    border-radius: 6px;
    background: var(--brand-accent-soft);
    color: var(--brand-accent);
    font-size: 0.78rem;
    font-weight: 700;
}

/* Split slice indicator — appears next to the file name on workbook
   rows that represent one allocation of a split invoice. Tells the
   reviewer "this is slice 1 of 2 of {file}" without taking a column. */
/* ── Doc ID subtitle pill ─────────────────────────────────────────────
   Compact monospace pill rendered UNDER the filename (workbook) or row
   number (review) to expose the 8-char preview of the Document GUID.
   Click copies the full GUID; tooltip shows the full GUID for manual
   copy when JS interop is unavailable.

   The pill is intentionally subtle — small, muted background, low-
   weight typography — so the filename stays the primary row identifier.
   Brand-accent hover state gives the click affordance. */
.bg-doc-id {
    display: inline-block;
    margin-top: 2px;
    padding: 1px 6px;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 3px;
    background: var(--bg-soft, #f1f5f9);
    color: var(--text-muted, #475569);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 10.5px;
    font-weight: 500;
    cursor: pointer;
    line-height: 1.25;
    letter-spacing: 0.02em;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
.bg-doc-id:hover {
    background: var(--brand-accent-soft, #e0e9e3);
    border-color: var(--brand-accent, #2e4d3c);
    color: var(--brand-accent, #2e4d3c);
}
.bg-doc-id:active {
    background: var(--brand-accent, #2e4d3c);
    color: #fff;
    border-color: var(--brand-accent, #2e4d3c);
}

/* Filename above the doc-id pill in the vendor cell. Forces a line
   break so the pill ends up directly below the filename, not inline. */
.bg-cell-filename {
    display: block;
    line-height: 1.3;
    word-break: break-word;
}

/* On BillsReview the doc-id pill lives under the row number, which is
   centered. Override the small left-anchored margin to keep it visually
   tied to its parent number. */
.bg-row-no {
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}
.bg-doc-id-sub {
    margin-top: 4px;
}

.bg-split-slice {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    background: var(--brand-accent-soft);
    color: var(--brand-accent);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    vertical-align: middle;
}

/* Manual-split-needed badge — rendered next to a document filename in the
   bills workbook + review when the analyzer flagged the source page as
   carrying content from more than one logical document and the splitter
   could not separate them (e.g. a credit-note strip overlaid on an
   unrelated supplier invoice). Amber colour-coding distinguishes it from
   the blue "split slice" badge (which marks a confirmed split) and from
   the red error pill (which marks a hard failure). Hover shows the full
   detection rationale so reviewers know WHY it was flagged. */
.bg-manual-split {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    background: #fef3c7;     /* amber-100 */
    color: #92400e;          /* amber-800 */
    border: 1px solid #fcd34d; /* amber-300 */
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    vertical-align: middle;
    cursor: help;
}
.bg-manual-split::before {
    content: "\26A0";  /* U+26A0 WARNING SIGN */
    margin-right: 0.25rem;
}

/* Warning pill - shown next to the row number when the row has any
   missing/inconsistent fields or AI emitted an extraction_warnings code.
   Amber so it reads as "look at this" without screaming "broken" - a
   row with warnings is still usable, just needs the reviewer to verify
   the highlighted fields before approving. Hover the pill (title attr)
   to see the full list. */
.bg-row-warning {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-left: 0.4rem;
    padding: 0.1rem 0.45rem;
    border-radius: 10px;
    background: #fef3c7;
    color: #b45309;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.1;
    vertical-align: middle;
    cursor: help;
    border: 1px solid #fcd34d;
}
.bg-row-warning .bi {
    font-size: 0.75rem;
}

/* Per-cell warning — amber inset border + soft amber tint on the cell
   itself. Pairs with the row-level pill: the pill says "row has N
   issues", the cell tint says "this is one of them". Both share the
   amber-50/amber-300 palette so they read as one alert system.
   cursor: help signals the tooltip; the title attribute carries the
   specific field's warning text. Modal inputs apply the same class on
   themselves (no surrounding td) — the inset shadow degrades gracefully. */
.bg-cell-warning {
    background: #fffbeb;
    box-shadow: inset 0 0 0 1px #fcd34d;
    cursor: help;
}

/* Inline warning glyph — the explicit ⚠ that sits next to the offending
   value. Border + tint are easy to miss in dense grids; the icon is the
   loud signal. Amber-500 fill, slightly smaller than body text so it
   doesn't push numeric columns to a new width. Pair with title= on the
   wrapping element to surface the warning text on hover. */
.bg-cell-warning-icon {
    color: #d97706;
    font-size: 0.78rem;
    margin-left: 0.25rem;
    vertical-align: middle;
    cursor: help;
}
/* When the icon lives inside an input-wrapper (DocPreview pattern), pin
   it to the right edge so it doesn't shove the input around. */
.input-wrapper .bg-cell-warning-icon {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.85rem;
    z-index: 2;
    pointer-events: auto;
}

/* Edit-mode address grid — Street takes the full row, then City /
   Province / Postal / Country pack into a 4-up row so the address
   stays as compact as the read-only composed display while exposing
   every component for editing. Bound straight to the InvoiceDto so
   the auto-save overlay picks up the changes via the same write path
   as every other invoice field. */
.dp-addr-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.4rem;
}
.dp-addr-grid > input:first-child { grid-column: span 4; }

/* Row actions — tight icon-only buttons (eye / scissors / red X) */
.bg-act {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-secondary);
    padding: 0.3rem 0.45rem;
    margin-left: 0.15rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.95rem;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.bg-act:hover {
    background: var(--bg-soft);
    border-color: var(--border);
}

.bg-act-eye:hover    { color: var(--brand-accent); }
.bg-act-split:hover  { color: #2563eb; }
.bg-act-del          { color: var(--danger); }
.bg-act-del:hover    { background: #fee2e2; border-color: var(--danger); }

/* Sticky totals row — anchors at the bottom of the table viewport so the
   batch totals stay visible while the user scrolls through line items. */
.bills-grid-totals td {
    position: sticky;
    bottom: 0;
    background: var(--brand-accent);
    color: #fff;
    font-weight: 700;
    padding: 0.65rem;
    font-size: 0.85rem;
    border-top: 1px solid var(--brand-accent-2);
}

.bg-totals-label {
    text-align: right;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.78rem;
}

/* Confirmed-row tint — soft brand-green wash so reviewers see at a glance
   which rows have already been verified. Sits on top of the alternating
   row background; status pills + selects keep their original styling. */
.bills-grid tbody tr.bg-row-confirmed td {
    background: rgba(34, 160, 107, 0.10) !important;
}

.bills-grid tbody tr.bg-row-confirmed:hover td {
    background: rgba(34, 160, 107, 0.14) !important;
}

/* Submitted-row tint — soft blue wash signaling the row is locked +
   awaiting accountant decision. Disabled controls inside the row stay
   visible but de-emphasised so reviewers can still scan the data. */
.bills-grid tbody tr.bg-row-submitted td {
    background: rgba(37, 99, 235, 0.06) !important;
}

.bills-grid tbody tr.bg-row-submitted:hover td {
    background: rgba(37, 99, 235, 0.10) !important;
}

.bills-grid tbody tr.bg-row-submitted .bg-cell-select:disabled,
.bills-grid tbody tr.bg-row-submitted .bg-cell-input:disabled {
    color: var(--text-secondary);
    opacity: 0.85;
    cursor: not-allowed;
    background-image: none;
    padding-right: 0.45rem;
}

/* Lock icon shown in the actions column on submitted rows — replaces
   the scissors + delete buttons that the manager no longer owns. */
.bg-act-locked {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 6px;
    color: #1e3a8a;
    background: #dbeafe;
    margin-left: 0.15rem;
}

/* Decision-roundtrip banner — surfaces accountant actions on docs the
   manager previously submitted. Soft brand-blue tint so it reads as a
   notification rather than an alert; rows inside link to the preview. */
.decisions-banner {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    margin: 0 1.5rem 1rem;
    padding: 0.75rem 1rem;
    background: #eef4fb;
    border: 1px solid #c7dbf0;
    border-radius: var(--radius-md, 14px);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.decisions-banner-icon {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: #dbeafe;
    color: #1d4ed8;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.decisions-banner-body {
    flex: 1;
    min-width: 0;
}

.decisions-banner-title {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.3rem;
}

.decisions-banner-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.85rem;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.decisions-banner-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
}

.decisions-banner-item a {
    color: var(--brand-accent);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px dashed var(--brand-accent-soft);
}

.decisions-banner-item a:hover {
    border-bottom-style: solid;
}

.decisions-banner-status {
    color: var(--text-muted);
    font-size: 0.78rem;
}

.decisions-banner-more {
    color: var(--text-muted);
    font-style: italic;
}

/* Header action cluster — counter + 5 buttons aligned right, wrapping
   on narrow screens so the page doesn't break at small widths. */
.bills-header-actions {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.bills-confirmed-counter {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.7rem;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin-right: 0.25rem;
}

.bills-confirmed-counter strong {
    color: var(--brand-accent);
    font-weight: 700;
}

.bills-confirmed-counter .bi {
    color: var(--brand-accent);
}

.bills-confirmed-sep {
    color: var(--text-muted);
    margin: 0 0.05rem;
}

/* Submit All — primary CTA, brand green, distinct from the outlined
   Save Draft / Receiving Sheet siblings. Disabled state is muted. */
.bills-submit-all {
    background: var(--brand-accent);
    color: #fff;
    border-color: var(--brand-accent);
    font-weight: 600;
}

.bills-submit-all:hover:not(:disabled) {
    background: var(--brand-accent-2);
    border-color: var(--brand-accent-2);
    color: #fff;
}

.bills-submit-all:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* The link-style "View Receiving Sheet" — outlined so it doesn't compete
   with Submit All visually. */
.bills-workbook-link {
    color: var(--brand-accent);
    border-color: var(--brand-accent-soft);
}

.bills-workbook-link:hover {
    background: var(--brand-accent-soft);
    color: var(--brand-accent);
}

/* Bulk-action bar — shown below the grid whenever any row is checked.
   Same card-with-shadow shape as the totals row but ghost-white so it
   reads as actionable rather than informational. */
.bills-bulk-bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0 1.5rem 1rem;
    padding: 0.7rem 1rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 14px);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    animation: bills-bulk-bar-in 180ms ease-out;
}

@keyframes bills-bulk-bar-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.bills-bulk-count {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-right: 0.25rem;
}

.bills-bulk-count strong {
    color: var(--text-primary);
    font-weight: 700;
}

.bills-bulk-remove {
    color: var(--danger);
    border-color: var(--danger);
}

.bills-bulk-remove:hover {
    background: var(--danger);
    color: #fff;
    border-color: var(--danger);
}

/* ============================================================
   Receiving Sheet Workbook (/documents/upload/bills/workbook)
   ============================================================ */

/* Dark green page header — bigger than the per-dept review header
   because it carries both title row + dept tabs. Mirrors the
   screenshot's deep-emerald banner. */
/* Light card header matching the global page-hero pattern (Weekly
   Timesheet / Employees / Run Payroll). Sage accents stay; the dark-
   green slab is gone. The page now reads as part of the same product
   as Submit Timesheet rather than a black banner pasted on top. */
.workbook-header {
    background: var(--bg-card, #fff);
    color: var(--text-primary, #0f172a);
    padding: 1rem 1.25rem 0;
    margin: 0 1rem 1rem;
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .04), 0 1px 2px rgba(15, 23, 42, .03);
}

.workbook-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding-bottom: 0.85rem;
}

.workbook-back {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    color: var(--text-secondary, #475569);
    background: var(--brand-accent-soft, rgba(108, 142, 132, 0.18));
    flex-shrink: 0;
}

.workbook-back:hover {
    background: var(--brand-accent-soft, #d8ecd8);
    color: var(--brand-accent, #166534);
}

.workbook-title {
    color: var(--text-primary, #0f172a);
    font-size: 1.2rem;
    font-weight: 800;
    line-height: 1.2;
}

.workbook-sub {
    color: var(--text-secondary, #64748b);
    font-size: 0.85rem;
    margin-top: 0.15rem;
}

/* Header CTAs use the standard global button styles — Save Draft is
   the default outlined sage, Submit All is .btn-success (filled sage).
   No overrides needed now that the header is on a light card and the
   buttons read against the cream backdrop the same way they do on
   every other workflow page. */

/* Department tabs — Stripe / Linear style underline tabs.
   Sit at the bottom of the header card. Active tab gets a 2-px sage
   underline + sage label + filled sage count chip; inactive tabs are
   muted grey so the eye lands on the active one without effort. */
.workbook-tabs {
    display: flex;
    gap: 0;
    overflow-x: auto;
    margin: 0 -1.25rem;
    padding: 0 1.25rem;
    border-top: 1px solid var(--border-color, #e2e8f0);
}

.workbook-tab {
    background: transparent;
    border: 0;
    color: var(--text-secondary, #64748b);
    font-size: 0.88rem;
    font-weight: 600;
    padding: 0.7rem 0.95rem 0.65rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    border-bottom: 2px solid transparent;
    transition: color 120ms ease, border-color 120ms ease;
    white-space: nowrap;
}

.workbook-tab:hover {
    color: var(--text-primary, #0f172a);
}

.workbook-tab-active,
.workbook-tab-active:hover {
    color: var(--brand-accent, #166534);
    border-bottom-color: var(--brand-accent, #166534);
    background: transparent;
}

.workbook-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-page, #f1f5f9);
    color: var(--text-secondary, #64748b);
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.12rem 0.45rem;
    border-radius: 999px;
    line-height: 1;
    min-width: 1.4rem;
    transition: background 120ms ease, color 120ms ease;
}

.workbook-tab-active .workbook-tab-count {
    background: var(--brand-accent, #166534);
    color: #fff;
}

.workbook-header-btn {
    margin-left: 0.25rem;
}

/* ── Workbook toolbar (search + rows-per-page) ───────────────────────
   Sits between the dept tabs and the grid. Flexbox so the search box
   takes the available width on the left and the page-size selector
   sits at the right edge. */
.workbook-toolbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1.5rem 0.75rem;
    flex-wrap: wrap;
}
.workbook-search {
    position: relative;
    flex: 1 1 320px;
    max-width: 480px;
}
.workbook-search-icon {
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted, #94a3b8);
    font-size: 0.95rem;
    pointer-events: none;
}
.workbook-search-input {
    width: 100%;
    height: 36px;
    padding: 0 2.2rem 0 2.2rem;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 8px;
    background: #fff;
    font-size: 13.5px;
    color: var(--text, #1f2937);
    transition: border-color 120ms ease, box-shadow 120ms ease;
}
.workbook-search-input:focus {
    outline: none;
    border-color: var(--brand-accent, #166534);
    box-shadow: 0 0 0 3px rgba(46, 77, 60, 0.12);
}
.workbook-search-clear {
    position: absolute;
    right: 0.4rem;
    top: 50%;
    transform: translateY(-50%);
    border: none;
    background: transparent;
    color: var(--text-muted, #94a3b8);
    cursor: pointer;
    padding: 4px 6px;
    border-radius: 4px;
    font-size: 0.85rem;
    line-height: 1;
}
.workbook-search-clear:hover { color: var(--danger, #b02020); background: rgba(176,32,32,0.06); }
.workbook-toolbar-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-left: auto;
}
.workbook-pagesize {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12.5px;
    color: var(--text-muted, #475569);
    white-space: nowrap;
}
.workbook-pagesize-select {
    height: 32px;
    padding: 0 0.5rem;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 6px;
    background: #fff;
    font-size: 13px;
    cursor: pointer;
}
.workbook-pagesize-select:focus {
    outline: none;
    border-color: var(--brand-accent, #166534);
}

/* Status filter — visual sibling of the page-size selector so the
   toolbar reads as a coherent set of controls. The clear-X only
   appears when a filter is active (status != null). */
.workbook-statusfilter {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12.5px;
    color: var(--text-muted, #475569);
    white-space: nowrap;
    position: relative;
}
.workbook-statusfilter-select {
    height: 32px;
    padding: 0 0.5rem;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 6px;
    background: #fff;
    font-size: 13px;
    cursor: pointer;
    min-width: 165px;
}
.workbook-statusfilter-select:focus {
    outline: none;
    border-color: var(--brand-accent, #166534);
}
.workbook-statusfilter-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border: none;
    background: transparent;
    color: var(--text-muted, #94a3b8);
    cursor: pointer;
    border-radius: 4px;
    font-size: 0.85rem;
    line-height: 1;
    margin-left: -0.2rem;
}
.workbook-statusfilter-clear:hover {
    color: var(--danger, #b02020);
    background: rgba(176, 32, 32, 0.06);
}

/* ── Sortable column header ──────────────────────────────────────────
   Clickable th. Cursor + hover-tint reveal the affordance; the chevron
   icon on the right shows current direction. */
.bg-sortable {
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease;
}
.bg-sortable:hover {
    background: rgba(46, 77, 60, 0.06);
}
.bg-sort-icon {
    margin-left: 0.3rem;
    font-size: 0.75rem;
    opacity: 0.55;
    vertical-align: middle;
}
.bg-sortable:hover .bg-sort-icon { opacity: 0.85; }
/* Active sort column (chevron is bi-sort-up / bi-sort-down, not the
   default arrow-down-up) gets a fully-opaque icon. */
.bg-sort-icon.bi-sort-up,
.bg-sort-icon.bi-sort-down { opacity: 1; color: var(--brand-accent, #166534); }

/* ── Pagination footer ───────────────────────────────────────────────
   Sits below the table. Left side: "Showing X-Y of Z". Right side: page
   number window with prev/next chevrons. Buttons match the topbar's
   icon-button family for visual consistency. */
.workbook-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 1.5rem 1rem;
    gap: 1rem;
    flex-wrap: wrap;
    border-top: 1px solid var(--border, #e2e8f0);
    background: #fff;
}
.workbook-pagination-info {
    font-size: 13px;
    color: var(--text-muted, #475569);
}
.workbook-pagination-info strong { color: var(--text, #1f2937); }
.workbook-pagination-controls {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}
.workbook-page-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 0.55rem;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 6px;
    background: #fff;
    color: var(--text, #1f2937);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.workbook-page-btn:hover:not(:disabled) {
    background: var(--bg-soft, #f1f5f9);
    border-color: var(--border-strong, #cbd5e1);
}
.workbook-page-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.workbook-page-btn-active,
.workbook-page-btn-active:hover {
    background: var(--brand-accent, #166534);
    border-color: var(--brand-accent, #166534);
    color: #fff;
}
.workbook-page-ellipsis {
    padding: 0 0.35rem;
    color: var(--text-muted, #94a3b8);
    font-size: 13px;
}

/* "(filtered by 'foo')" pill inside the totals row — communicates that
   the totals reflect the current filter, not the full upload. */
.bg-totals-filter {
    margin-left: 0.5rem;
    font-weight: 400;
    color: var(--text-muted, #475569);
    font-size: 12px;
    font-style: italic;
}

@media (max-width: 768px) {
    .workbook-toolbar { padding: 0.55rem 0.85rem 0.7rem; }
    .workbook-pagination { padding: 0.75rem 0.85rem 0.9rem; }
    .workbook-pagination-info { width: 100%; text-align: center; }
    .workbook-pagination-controls { width: 100%; justify-content: center; }
    .workbook-search { flex: 1 1 100%; }
    .workbook-toolbar-right { margin-left: 0; }
}

/* ============================================================
   Accountant Review (/accountant/review)
   ============================================================ */

/* Dark navy header — matches the left-rail brand-dark colour so the
   accountant flow visually inherits from the menu, distinct from the
   green store-manager pages. */
.acct-header {
    background: var(--brand-dark);
    color: #fff;
    padding: 1.1rem 1.5rem 1.1rem;
    margin-bottom: 0.85rem;
}

.acct-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.acct-title {
    color: #fff;
    font-size: 1.4rem;
    font-weight: 800;
    line-height: 1.2;
}

.acct-sub {
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.88rem;
    margin-top: 0.2rem;
}

.acct-refresh {
    color: #fff;
    border-color: rgba(255, 255, 255, 0.45);
}

.acct-refresh:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
}

/* Per-row accountant action buttons — colour-coded so the four-up cluster
   reads at a glance: approve (green), correction (amber), reprocess
   (slate), reject (red). */
.acct-act {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 6px;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    margin-left: 0.15rem;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
    font-size: 0.95rem;
}

.acct-act:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.acct-act-approve     { color: var(--brand-accent); }
.acct-act-approve:hover:not(:disabled) {
    background: var(--brand-accent-soft);
    border-color: var(--brand-accent);
}

.acct-act-correction  { color: #b45309; }
.acct-act-correction:hover:not(:disabled) {
    background: #ffedd5;
    border-color: #b45309;
}

.acct-act-reprocess   { color: #475569; }
.acct-act-reprocess:hover:not(:disabled) {
    background: var(--bg-soft-2);
    border-color: #475569;
}

.acct-act-reject      { color: var(--danger); }
.acct-act-reject:hover:not(:disabled) {
    background: #fee2e2;
    border-color: var(--danger);
}

/* ============================================================
   Split-Invoice modal — opened from the scissors action on the
   datagrid. Wider than the default modal because each allocation
   row carries Department + Net + GST + PST + Total in one line.
   ============================================================ */
.split-modal {
    max-width: 720px;
}

.split-modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1rem 1.25rem 0.75rem;
    border-bottom: 1px solid var(--border);
}

.split-modal-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary);
}

.split-modal-sub {
    font-size: 0.85rem;
    color: var(--text-muted);
    margin-top: 0.15rem;
}

.split-modal-body {
    padding: 1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-height: 70vh;
    overflow-y: auto;
}

.split-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0.85rem 1.25rem;
    border-top: 1px solid var(--border);
    background: var(--bg-soft);
}

/* Top row — Total Invoice Amount input + Status pill */
.split-totals-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    padding: 0.85rem 1rem;
    background: var(--bg-soft);
    border-radius: 10px;
}

.split-total-cell label {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    display: block;
    margin-bottom: 0.3rem;
}

.split-status-ok,
.split-status-warn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.92rem;
    font-weight: 600;
}

.split-status-ok   { color: #15803d; }
.split-status-warn { color: #b45309; }

/* Money input — $ prefix + number field, matches screenshot styling */
.split-money-input {
    display: flex;
    align-items: center;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0 0.6rem;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.split-money-input:focus-within {
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px var(--brand-accent-soft);
}

.split-currency {
    color: var(--text-muted);
    font-weight: 600;
    margin-right: 0.35rem;
}

.split-money-input input {
    border: none;
    outline: none;
    background: transparent;
    padding: 0.5rem 0;
    font-size: 0.92rem;
    color: var(--text-primary);
    width: 100%;
    -moz-appearance: textfield;
}

.split-money-input input::-webkit-outer-spin-button,
.split-money-input input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Allocations header */
.split-allocations-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
}

/* Per-allocation row — number badge + dept + net + gst + pst + total + remove */
.split-rows {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.split-row {
    display: grid;
    grid-template-columns: auto 1.4fr 0.9fr 0.7fr 0.7fr 0.9fr auto;
    gap: 0.55rem;
    align-items: end;
    padding: 0.7rem 0.75rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
}

.split-row-num {
    width: 1.65rem;
    height: 1.65rem;
    border-radius: 50%;
    background: var(--bg-soft);
    color: var(--text-secondary);
    font-size: 0.78rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.15rem;
}

.split-row-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.split-row-field label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.split-row-field .form-select {
    padding: 0.45rem 0.6rem;
    font-size: 0.9rem;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--bg-card);
}

.split-row-total-value {
    padding: 0.55rem 0.6rem;
    background: var(--bg-soft);
    border-radius: 8px;
    font-weight: 700;
    color: var(--text-primary);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.split-row-remove {
    background: transparent;
    border: none;
    color: var(--text-muted);
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 120ms ease, color 120ms ease;
    align-self: flex-end;
    margin-bottom: 0.05rem;
}

.split-row-remove:hover {
    background: #fee2e2;
    color: var(--danger);
}

.split-add-row {
    background: transparent;
    border: 1px dashed var(--border-strong, #d8e1e8);
    color: var(--text-secondary);
    padding: 0.7rem 1rem;
    border-radius: 10px;
    font-size: 0.92rem;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.split-add-row:hover {
    background: var(--bg-soft);
    border-color: var(--brand-accent);
    color: var(--brand-accent);
}

/* Bottom summary — Total / Allocated / Remaining stat row */
.split-summary {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    padding: 0.85rem 1rem;
    background: var(--bg-soft);
    border-radius: 10px;
}

.split-summary-label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.25rem;
}

.split-summary-value {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.split-summary-ok   { color: #15803d; }
.split-summary-warn { color: #d97706; }

/* Validation messages — amber for "warn" (must-fix-but-soft), red for
   "error" (won't-confirm). Both list under the summary card. */
.split-validations {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding-top: 0.25rem;
}

.split-validation {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    font-weight: 500;
}

.split-validation-warn  { color: #b45309; }
.split-validation-error { color: #b91c1c; }

/* ============================================================
   Undo bar — bottom-anchored toast that holds a pending delete
   reversible for 6s (Gmail / Linear / Stripe pattern). Slides in
   from below; auto-finalises on timer expiry or another action.
   ============================================================ */
.undo-bar {
    position: fixed;
    left: 50%;
    bottom: 1.25rem;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.65rem 1rem 0.65rem 1.1rem;
    background: var(--text-primary, #1d2733);
    color: #fff;
    border-radius: 999px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.28);
    font-size: 0.88rem;
    z-index: 1100;
    max-width: calc(100vw - 2rem);
    animation: undo-bar-in 200ms ease-out;
}

@keyframes undo-bar-in {
    from { opacity: 0; transform: translate(-50%, 6px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

.undo-bar > .bi-trash {
    color: #fca5a5;
    font-size: 1rem;
}

.undo-bar-text {
    color: rgba(255, 255, 255, 0.92);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 50ch;
}

.undo-bar-text strong {
    color: #fff;
    font-weight: 700;
}

.undo-bar-button {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.82rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.undo-bar-button:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.55);
}

.undo-bar-button:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* ============================================================
   Shared form validation — used by all CRUD editor forms via
   FormValidationState + <FieldError>. Keeps required-field UX
   identical everywhere (red ring + inline message + asterisk).
   ============================================================ */
.field-required { color: #dc2626; font-weight: 700; margin-left: 0.1rem; }

.form-control.is-invalid,
.is-invalid {
    border-color: #dc2626 !important;
    background: #fef2f2;
}
.form-control.is-invalid:focus,
.is-invalid:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
}

.field-error {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.2rem;
    font-size: 0.74rem;
    font-weight: 600;
    color: #dc2626;
}
.field-error .bi { font-size: 0.8rem; }

.field-validation-summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #b91c1c;
    border-radius: 8px;
    padding: 0.6rem 0.8rem;
    font-size: 0.82rem;
    font-weight: 600;
    margin-bottom: 0.8rem;
}
.field-validation-summary .bi { font-size: 0.95rem; flex-shrink: 0; }

/* ============================================================
   REVIEW-PAGE WIDGETS (warning chip, confidence bar, line input)
   Shared by every per-doc review surface so a tweak lands once.
   ============================================================ */

/* Compact per-field warning chip */
.fw-wrap        { position:relative; }
.fw-warn        { position:absolute; top:-7px; right:-6px; width:18px; height:18px; border-radius:50%; background:#fef3c7; color:#92400e; font-size:var(--fs-caption); display:flex; align-items:center; justify-content:center; cursor:help; border:1px solid #fcd34d; box-shadow:0 1px 2px rgba(0,0,0,.05); z-index:2; }
.fw-warn.danger { background:#fee2e2; color:#991b1b; border-color:#fca5a5; }
.fw-warn:hover  { transform:scale(1.1); }
.fw-tip         { display:none; position:absolute; top:-2px; right:18px; min-width:200px; max-width:260px; background:#1e293b; color:#fff; font-size:var(--fs-caption); line-height:1.45; padding:6px 9px; border-radius:6px; z-index:50; white-space:normal; box-shadow:0 4px 12px rgba(0,0,0,.18); }
.fw-warn:hover + .fw-tip,
.fw-warn:focus + .fw-tip { display:block; }

/* Per-field confidence bar inside .form-control wrapper */
.conf-bar       { position:absolute; bottom:0; left:0; right:0; height:2px; border-radius:0 0 6px 6px; }
.conf-bar.high  { background:#22c55e; }
.conf-bar.med   { background:#f59e0b; }
.conf-bar.low   { background:#ef4444; }

/* Borderless line-item / employee-row input */
.line-input     { border:1px solid transparent; background:transparent; border-radius:6px; padding:4px 6px; font-size:12.5px; width:100%; }
.line-input:focus { border-color:var(--brand-primary,#4f46e5); outline:none; background:#fff; }


/* ============================================================== */
/*  RESPONSIVE / MULTI-DEVICE                                     */
/* ============================================================== */
/* Breakpoints:                                                   */
/*   ≤ 480px   small phone                                        */
/*   ≤ 768px   tablet portrait + large phone                      */
/*   ≤ 1024px  tablet landscape                                   */
/*   > 1024px  desktop (default styles above)                     */
/*                                                                */
/* Strategy: the desktop layout above is untouched. These rules   */
/* only fire below 1024px so a regression on desktop is           */
/* impossible. The off-canvas drawer is the centrepiece — every   */
/* other rule (form collapse, modal full-screen, tap-target bump) */
/* is additive polish.                                            */
/* ============================================================== */

/* Hamburger button — always rendered in MainLayout's topbar-left
   but hidden on desktop. Width / height match the topbar's other
   icon buttons so it lines up with the bell + avatar. */
.topbar-hamburger {
    display: none;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
    color: var(--text-strong, #0f172a);
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    margin-right: 4px;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.topbar-hamburger:hover  { background: var(--bg-soft, #f1f5f9); }
.topbar-hamburger:active { background: var(--bg-soft-strong, #e2e8f0); }

/* Desktop-only sidebar collapse toggle.
   Same visual family as the mobile hamburger (round button, hover tint)
   so the topbar reads as a coherent toolbar. Hidden on tablet/mobile
   via the @media block below — small viewports already have the
   hamburger drawer, no need for two controls competing for the same
   spot. */
.topbar-sidebar-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 1px solid var(--border, #e2e8f0);
    border-radius: 10px;
    background: #fff;
    color: var(--text, #1f2937);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    margin-right: 4px;
    transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.topbar-sidebar-toggle:hover  { background: var(--bg-soft, #f1f5f9); }
.topbar-sidebar-toggle:active { background: var(--bg-soft-strong, #e2e8f0); transform: scale(0.96); }
.topbar-sidebar-toggle .bi    { color: var(--brand-accent, #2e4d3c); }

@media (max-width: 1024px) {
    /* Hide the desktop collapse toggle on small screens — the hamburger
       (also in the topbar-left) takes over there with the off-canvas
       drawer pattern, so two controls would be redundant + confusing. */
    .topbar-sidebar-toggle { display: none; }
}

/* Backdrop sits behind the open drawer. Click-through closes the
   drawer (wired via @onclick="CloseSidebar"). Off-screen by default
   to keep it from intercepting clicks on desktop. */
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    z-index: 90;
    opacity: 0;
    pointer-events: none;
    transition: opacity 180ms ease;
}

/* ── Tablet landscape & narrower ──────────────────────────────── */
@media (max-width: 1024px) {
    /* Sidebar becomes an off-canvas drawer: pinned to the left edge,
       translateX-hidden by default, slides in when .app-shell.sidebar-open
       is present. width: min(85vw, 320px) keeps the drawer comfortable on
       both tablet portrait and phone widths without ever covering the
       whole screen. */
    .sidebar-shell {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        width: min(85vw, 320px);
        transform: translateX(-100%);
        transition: transform 220ms cubic-bezier(.2, .8, .2, 1);
        z-index: 100;          /* above backdrop (90), above topbar */
        box-shadow: 4px 0 18px rgba(15, 23, 42, 0.18);
    }

    .app-shell.sidebar-open .sidebar-shell {
        transform: translateX(0);
    }

    .app-shell.sidebar-open .sidebar-backdrop {
        display: block;
        opacity: 1;
        pointer-events: auto;
    }

    .topbar-hamburger { display: inline-flex; }

    /* Main content takes the full viewport width when sidebar is
       off-canvas. The flex layout still works because .sidebar-shell
       no longer participates in flow (position: fixed). */
    .main-shell {
        width: 100%;
        min-width: 0;          /* lets internal grids shrink properly */
    }

    /* Two-column form grids → single column. This catches the bulk
       of admin pages (Roles, Vendors, Stores, AI Models, …) without
       per-page edits. */
    .form-grid-2,
    .form-grid-3,
    .form-grid-4 {
        grid-template-columns: 1fr !important;
    }

    /* Topbar — make room. The active-store pill is the biggest
       offender; hide it on small screens and the user still sees the
       store name in the page header / breadcrumb. */
    .app-topbar {
        padding-left: 12px;
        padding-right: 12px;
    }
    .app-title-block { min-width: 0; }
    .app-title { font-size: 14px; }
}

/* ── Tablet portrait & phones ─────────────────────────────────── */
@media (max-width: 768px) {
    /* Page padding shrinks so dense pages have room. */
    .app-page,
    main.app-page {
        padding: 12px !important;
    }

    /* Page headers — the hero block at the top of each page often
       has a row of buttons that wrap awkwardly. Stack on phones. */
    .page-header > div[style*="flex"],
    .page-header > .flex-between {
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 12px !important;
    }

    /* Topbar — hide the store pill + the "Live/Offline" status pill
       on tight phones; they're nice-to-have, not load-bearing. The
       bell + user menu still fit. */
    .topbar-store-pill,
    .rt-status {
        display: none;
    }
    .topbar-user-meta { display: none; }    /* keep just the avatar */
    .topbar-user-btn  { padding: 4px 6px; }

    /* Tables — every table in a .table-wrapper / .dg-scroll already
       has overflow-x. Force a min-width so the cells don't crush
       and the user can swipe horizontally. */
    .table-wrapper,
    .dg-scroll,
    .bills-grid-scroll {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Modals — full-screen on phones. The desktop modal uses
       max-width: 540px which is already narrower than 768px, but the
       padding/centering makes them feel cramped on small phones. */
    .modal-backdrop,
    .modal-backdrop-custom {
        padding: 0 !important;
    }
    .modal-box,
    .modal-dialog-custom,
    .dp-modal-shell {
        max-width: 100% !important;
        max-height: 100vh !important;
        width: 100% !important;
        height: 100vh !important;
        border-radius: 0 !important;
        margin: 0 !important;
    }
    .modal-body,
    .dp-modal-body {
        max-height: calc(100vh - 120px) !important;
    }

    /* Tap targets — bump small buttons to 40px minimum height so a
       finger can hit them without zooming. Keeps existing typography. */
    .btn-sm     { padding: 9px 14px; min-height: 40px; }
    .page-btn   { min-width: 40px;  min-height: 40px; }
    .dg-act-btn { min-width: 36px;  min-height: 36px; }

    /* Card grids that used auto-fit minmax — collapse to single
       column under 600px to avoid the 1.5-card-and-a-half overflow. */
    .smd-grid,
    .smd-grid-2,
    .smd-kpi-grid {
        grid-template-columns: 1fr !important;
    }

    /* Document upload cards (UploadHome.razor) — collapse to 2-up
       on phones (default is auto-fit 200px which usually gives 1
       anyway, but be explicit so it never gives 1.5). */
    .docupload-card-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ── Data tables — column hiding via data-priority ────────────── */
/* Pages opt-in by marking non-essential <th> and <td> with
   data-priority="low" (and matching cells). On phones (≤ 768px)
   those columns disappear, leaving the table readable without
   horizontal scroll. Tablets still see everything. Used by:
     • Documents list
     • (add others by marking their cells the same way)                */
@media (max-width: 768px) {
    th[data-priority="low"],
    td[data-priority="low"] { display: none !important; }
}

/* ── Generic responsive-input helpers ─────────────────────────── */
/* Replaces inline style="max-width:NNNpx" overrides on form inputs.
   Caps the input at the desktop width but lets it claim the full
   viewport on phones so placeholders aren't truncated and tap
   targets aren't squeezed. Pages opt-in by adding the class:
       <div class="input-wrapper responsive-input-320">…</div>
   The number suffix encodes the desktop cap in pixels.            */
.responsive-input-200 { max-width: 200px; width: 100%; }
.responsive-input-240 { max-width: 240px; width: 100%; }
.responsive-input-320 { max-width: 320px; width: 100%; }
.responsive-input-420 { max-width: 420px; width: 100%; }
.responsive-input-560 { max-width: 560px; width: 100%; }
@media (max-width: 768px) {
    .responsive-input-200,
    .responsive-input-240,
    .responsive-input-320,
    .responsive-input-420,
    .responsive-input-560 { max-width: 100%; }
}

/* ── ReceivingSheets header search — responsive sizing ───────── */
/* The accountant's receiving-sheets list has a search box that needs
   to share space with pill filters on desktop, but claim full width
   on phones so the placeholder text isn't truncated. */
.rs-search-responsive {
    margin-left: auto;
    flex: 1 1 280px;
    max-width: 340px;
}
@media (max-width: 768px) {
    .rs-search-responsive {
        margin-left: 0;
        flex: 1 1 100%;
        max-width: 100%;
    }
}

/* ── BillsReview grid — mobile polish ─────────────────────────── */
/* The grid keeps its 1500px min-width on phones so reviewers see
   every column (deliberately; auto-hiding columns hides data they
   need to verify). Instead we:
     • shrink the wrapper margin so the table claims max viewport
     • tighten cell padding + font so the column count fits the
       swipe area instead of being walls of whitespace
     • pin the first two columns (# + Vendor) using sticky so the
       user keeps context while swiping right for amounts / actions
     • beef up the borders on sticky columns so the seam reads
       clearly when scrolled content is sliding under them
   The .bills-grid-scroll already has overflow-x: auto from the
   desktop rules, so swipe works for free. */
@media (max-width: 1024px) {
    .bills-grid-wrap   { margin: 0 0.5rem 0.75rem; border-radius: 8px; }
    .bills-grid        { font-size: 0.78rem; }
    .bills-grid thead th,
    .bills-grid tbody td { padding: 0.32rem 0.4rem; }

    /* Sticky first two columns (#, Type) — keeps row context while
       the user swipes horizontally across the wide grid. background
       must be solid so scrolled cells underneath don't bleed through. */
    .bills-grid thead th:nth-child(1),
    .bills-grid tbody td:nth-child(1),
    .bills-grid thead th:nth-child(2),
    .bills-grid tbody td:nth-child(2) {
        position: sticky;
        left: 0;
        background: var(--bg-card, #fff);
        z-index: 2;
    }
    .bills-grid thead th:nth-child(2),
    .bills-grid tbody td:nth-child(2) { left: 2.2rem; }
    .bills-grid tbody tr:nth-child(even) td:nth-child(1),
    .bills-grid tbody tr:nth-child(even) td:nth-child(2) {
        background: var(--bg-soft, #fafafa);
    }
    .bills-grid thead th:nth-child(2),
    .bills-grid tbody td:nth-child(2) {
        border-right: 1px solid var(--border, #e2e8f0);
    }
}

/* ── DocPreview / Invoice Review Modal — mobile polish ────────── */
/* The main layout (.inv-layout) already stacks below 1023px from
   invoice-form.css, and .dp-addr-grid already collapses below 720px.
   These additions handle the chrome that surrounds the form: the
   summary band cells, the modal title/close header, and the trailing
   action bar.                                                       */
@media (max-width: 768px) {
    /* Summary band — let four cells become two rows of two on phones
       (default flex: 1 1 160px would otherwise leave one orphan cell
       at 100% width). */
    .inv-summary-band {
        margin: 0 0.5rem 0.5rem;
    }
    .inv-summary-band-cell {
        flex: 1 1 calc(50% - 1px);
        padding: 0.45rem 0.6rem;
    }
    .inv-summary-band-value { font-size: 0.92rem; }

    /* Modal chrome — make the X button + "Open full" link finger-sized
       and tighten the title row so the file name has room. */
    .dp-modal-head {
        padding: 8px 12px;
        gap: 6px;
        flex-wrap: wrap;
    }
    .dp-modal-title {
        font-size: 0.95rem;
        min-width: 0;
    }
    .dp-modal-eyebrow { display: none; }    /* "Document review" label */
    .dp-modal-link   { padding: 6px 10px; }
    .dp-modal-close  { width: 40px; height: 40px; }

    /* Action bar — Approve / Reject / Reprocess wrap to a column on
       phones so each button is full-width and reaches the tap-target. */
    .inv-action-bar {
        flex-direction: column !important;
        align-items: stretch !important;
        padding: 10px 12px !important;
    }
    .inv-action-bar > .btn {
        width: 100%;
        justify-content: center;
    }
    .inv-action-bar > div[style*="flex:1"] {
        display: none;            /* the flex-1 spacer is meaningless when stacked */
    }
}

/* ── Small phones ─────────────────────────────────────────────── */
@media (max-width: 480px) {
    /* Document type cards on UploadHome go single-column when the
       2-up grid would crowd. */
    .docupload-card-grid {
        grid-template-columns: 1fr;
    }

    /* Login page hero — the two-column split is fine until ~480px;
       below that, stack the hero above the form. */
    .login-shell,
    .login-split {
        flex-direction: column !important;
    }

    /* Page title fonts — slightly smaller so they don't wrap to
       3+ lines on tiny screens. */
    .page-hero-title { font-size: 1.05rem; }
    .page-hero-sub   { font-size: 0.78rem; }
}
