/* ==========================================================================
   ChitPro — Premium design system
   ========================================================================== */
:root {
    /* Brand (indigo / violet) */
    --brand-50:  #eef2ff;
    --brand-100: #e0e7ff;
    --brand-200: #c7d2fe;
    --brand-300: #a5b4fc;
    --brand-400: #818cf8;
    --brand-500: #6366f1;
    --brand-600: #4f46e5;
    --brand-700: #4338ca;
    --brand-800: #3730a3;
    --brand-900: #312e81;

    --primary: var(--brand-600);
    --primary-hover: var(--brand-700);
    --accent: #f59e0b;
    --accent-soft: #fef3c7;

    /* Neutrals */
    --ink: #0f172a;
    --ink-soft: #1e293b;
    --muted: #64748b;
    --muted-2: #94a3b8;
    --line: #e6e8f0;
    --line-soft: #eef0f6;
    --surface: #f5f6fb;
    --card: #ffffff;

    /* Status */
    --success: #10b981;
    --success-soft: #d1fae5;
    --danger: #ef4444;
    --danger-soft: #fee2e2;
    --warning: #f59e0b;
    --warning-soft: #fef3c7;
    --info: #3b82f6;
    --info-soft: #dbeafe;

    /* Sidebar */
    --sidebar-w: 268px;
    --sidebar-bg: linear-gradient(185deg, #1b1740 0%, #14112e 55%, #0d0b20 100%);
    --sidebar-ink: #c7cce0;
    --sidebar-ink-dim: #8b90ad;
    --sidebar-active: #ffffff;

    /* Shape & depth */
    --radius: 16px;
    --radius-sm: 12px;
    --radius-xs: 8px;
    --radius-pill: 999px;
    --shadow-xs: 0 1px 2px rgba(16, 24, 40, .06);
    --shadow-sm: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .04);
    --shadow-md: 0 6px 18px -4px rgba(16, 24, 40, .12), 0 2px 6px -2px rgba(16, 24, 40, .06);
    --shadow-lg: 0 24px 48px -12px rgba(16, 24, 40, .22);
    --topbar-h: 70px;

    /* Type scale — every size on the app resolves to one of these. Integers only: fractional px
       (the old 14.5/13.8/13.6/12.5/11.8/11.5/10.5) round differently across zoom levels and DPI,
       so the same label rendered a hair apart from machine to machine. */
    --text-2xs:  11px;   /* uppercase micro-labels */
    --text-xs:   12px;   /* column heads, captions, badges */
    --text-sm:   13px;   /* secondary lines under a value */
    --text-md:   14px;   /* table data, controls, buttons, nav */
    --text-base: 15px;   /* body prose */
    --text-lg:   16px;
    --text-xl:   18px;
    --text-2xl:  20px;
    --text-3xl:  24px;
    --text-4xl:  30px;
    --text-5xl:  36px;

    /* Spacing scale — a 4px grid. Before this the stylesheet used 31 different gaps
       (1,2,3,5,6,7,9,10,11,13,14,15,18,22,26,30,34,38,42,46...), so no two components were
       ever quite aligned. 1-3px stays literal: that is optical correction, not spacing. */
    --space-1:   4px;
    --space-2:   8px;
    --space-3:  12px;
    --space-4:  16px;
    --space-5:  20px;
    --space-6:  24px;
    --space-8:  32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-14: 56px;
}

* { box-sizing: border-box; }

html, body {
    height: 100%;
}

body {
    margin: 0;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    /* No font-feature-settings here, on purpose. The self-hosted Inter is a latin subset and its
       character variants did not survive the subsetting, so asking for the tailed l (cv05) or the
       single-storey a (cv11) is a no-op. Measured in the browser at 200px: cv01, cv05 and cv11 each
       leave the glyph metrics untouched while "tnum" moves them 92.91px to 129.55px — the file does
       honour features, just not those. Restoring them means shipping a fuller Inter build.
       Tabular figures DO survive, and every register asks for them with font-variant-numeric. */
    background: var(--surface);
    color: var(--ink);
    font-size: var(--text-base);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 { letter-spacing: -.015em; color: var(--ink); font-weight: 650; }
a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-hover); }

/* ====== App shell ====================================================== */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--sidebar-bg);
    color: var(--sidebar-ink);
    position: fixed;
    inset: 0 auto 0 0;
    display: flex;
    flex-direction: column;
    z-index: 1040;
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}

.sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-5) var(--space-5) var(--space-4);
}
.sidebar__logo {
    width: 40px; height: 40px;
    border-radius: var(--radius-sm);
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--brand-400), var(--brand-600));
    color: #fff; font-weight: 800; font-size: var(--text-2xl);
    box-shadow: 0 6px 16px rgba(79, 70, 229, .45);
}
/* An uploaded logo replaces the gradient initial. Company artwork is drawn for white, so keep a light
   tile under it rather than letting it sit on the dark sidebar; contain preserves any aspect ratio. */
.sidebar__logo--img {
    background: #fff;
    padding: var(--space-1);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .28);
}
.sidebar__logo--img img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

.sidebar__brand-name { color: #fff; font-weight: 700; font-size: var(--text-xl); line-height: 1.1; }
.sidebar__brand-sub { color: var(--sidebar-ink-dim); font-size: var(--text-xs); letter-spacing: .04em; text-transform: uppercase; }

/* Company-logo preview on the Companies form — same light-tile reasoning as the sidebar mark. */
.logo-preview {
    display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
    min-height: 74px; padding: var(--space-2) var(--space-3);
    border: 1px dashed var(--line-soft); border-radius: var(--radius-sm);
}
.logo-preview img {
    max-height: 54px; max-width: 190px; object-fit: contain;
    background: #fff; border-radius: var(--radius-xs); padding: var(--space-1);
}

.sidebar__nav { flex: 1 1 auto; overflow-y: auto; padding: var(--space-1) var(--space-3) var(--space-5); }
.sidebar__nav::-webkit-scrollbar { width: 6px; }
.sidebar__nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); border-radius: var(--radius-xs); }

.nav-section { margin-top: var(--space-4); }
.nav-section__label {
    font-size: var(--text-2xs); font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--sidebar-ink-dim);
    padding: 0 var(--space-3) var(--space-2);
}

.nav-item {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) var(--space-3); margin: 2px 0;
    border-radius: var(--radius-sm);
    color: var(--sidebar-ink);
    font-weight: 500; font-size: var(--text-md);
    position: relative;
    transition: background .15s, color .15s;
}
.nav-item i { font-size: var(--text-xl); width: 20px; text-align: center; color: var(--sidebar-ink-dim); transition: color .15s; }
.nav-item:hover { background: rgba(255,255,255,.06); color: #fff; }
.nav-item:hover i { color: var(--brand-300); }
.nav-item.active { background: rgba(99,102,241,.18); color: #fff; }
.nav-item.active i { color: var(--brand-300); }
.nav-item.active::before {
    content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
    width: 4px; height: 22px; border-radius: 0 4px 4px 0;
    background: linear-gradient(var(--brand-300), var(--brand-500));
}
.nav-item .badge { margin-left: auto; }

/* ====== Main column ==================================================== */
.main {
    flex: 1 1 auto;
    margin-left: var(--sidebar-w);
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.topbar {
    height: var(--topbar-h);
    position: sticky; top: 0; z-index: 1030;
    display: flex; align-items: center; gap: var(--space-4);
    padding: 0 var(--space-6);
    background: rgba(255,255,255,.82);
    backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--line);
}
.topbar__title { font-size: var(--text-2xl); font-weight: 680; margin: 0; }
.topbar__subtitle { font-size: var(--text-xs); color: var(--muted); margin: 0; }
.topbar__spacer { flex: 1 1 auto; }

.topbar__search {
    display: flex; align-items: center; gap: var(--space-2);
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); min-width: 260px; color: var(--muted);
}
.topbar__search input { border: 0; background: transparent; outline: none; width: 100%; font-size: var(--text-sm); color: var(--ink); }

.icon-btn {
    width: 40px; height: 40px; border-radius: var(--radius-sm);
    display: grid; place-items: center; border: 1px solid var(--line);
    background: #fff; color: var(--ink-soft); cursor: pointer; position: relative;
    transition: background .15s, border-color .15s;
}
.icon-btn:hover { background: var(--surface); border-color: var(--brand-200); }
.icon-btn .dot { position: absolute; top: 9px; right: 10px; width: 7px; height: 7px; border-radius: 50%; background: var(--danger); border: 2px solid #fff; }

.menu-toggle { display: none; }

/* User chip */
.user-chip { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; padding: var(--space-1) var(--space-1) var(--space-1) var(--space-1); border-radius: var(--radius-sm); }
.user-chip:hover { background: var(--surface); }
.avatar {
    width: 38px; height: 38px; border-radius: var(--radius-sm); flex: 0 0 38px;
    display: grid; place-items: center; font-weight: 650; font-size: var(--text-md); color: #fff;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
}
.avatar--sm { width: 30px; height: 30px; flex-basis: 30px; font-size: var(--text-xs); border-radius: var(--radius-xs); }
.user-chip__name { font-size: var(--text-sm); font-weight: 620; line-height: 1.15; }
.user-chip__role { font-size: var(--text-xs); color: var(--muted); }

/* ---- Theme switcher (built at runtime by js/theme.js) ---- */
/* The light/dark toggle and the colour-scheme picker are injected into the topbar rather than
   written into the markup, so their styling lives here — without it the picker has no collapsed
   state and every swatch renders at once. */
.theme-toggle,
.color-scheme-btn {
    width: 40px; height: 40px; border-radius: var(--radius-sm);
    display: grid; place-items: center; border: 1px solid var(--line);
    background: #fff; color: var(--ink-soft); cursor: pointer;
    font-size: var(--text-lg); line-height: 1; padding: 0;
    transition: background .15s, border-color .15s, color .15s;
}
.theme-toggle:hover,
.color-scheme-btn:hover { background: var(--surface); border-color: var(--brand-200); }
.theme-toggle:focus-visible,
.color-scheme-btn:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }

.color-scheme-menu { position: relative; display: inline-flex; }

.color-scheme-dropdown {
    /* Collapsed by default — this is what .show toggles against. */
    display: none;
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 1040;
    min-width: 208px; padding: var(--space-1);
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    animation: popIn .16s cubic-bezier(.2, .8, .3, 1);
}
.color-scheme-dropdown.show { display: block; }
/* theme.js also sets `hidden`; this keeps the rule above from overriding it, so the collapsed state
   holds even if the class and the attribute ever disagree. */
.color-scheme-dropdown[hidden] { display: none; }

.color-scheme-option {
    display: block; width: 100%; text-align: left;
    padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs);
    border: 0; border-left: 3px solid currentColor;   /* colour comes from the inline style theme.js sets */
    background: transparent; color: var(--ink-soft);
    font: inherit; font-size: var(--text-sm); cursor: pointer;
    transition: background .15s, color .15s;
}
.color-scheme-option + .color-scheme-option { margin-top: 2px; }
.color-scheme-option:hover { background: var(--surface); }
.color-scheme-option.active { background: var(--brand-50); color: var(--brand-600); font-weight: 600; }

/* Below the tablet breakpoint the topbar is already tight — the picker is a preference, not a
   task, so it gives up its space first. The same choice is available in the user menu. */
@media (max-width: 900px) {
    .theme-toggle, .color-scheme-menu { display: none; }
}

/* ====== Content ======================================================== */
.content { padding: var(--space-6) var(--space-6) var(--space-10); flex: 1 1 auto; }
.page-head { margin-bottom: var(--space-5); }
.page-head h1 { font-size: var(--text-3xl); margin: 0 0 3px; }
.page-head p { color: var(--muted); margin: 0; font-size: var(--text-sm); }

/* ====== Cards ========================================================== */
.card {
    background: var(--card);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}
.card-header { background: transparent; border-bottom: 1px solid var(--line-soft); padding: var(--space-4) var(--space-5); font-weight: 650; }
.card-body { padding: var(--space-5); }

.stat-card {
    background: var(--card);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);
    position: relative;
    overflow: hidden;
    transition: transform .18s, box-shadow .18s;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.stat-card__icon {
    width: 46px; height: 46px; border-radius: var(--radius-sm);
    display: grid; place-items: center; font-size: var(--text-3xl); margin-bottom: var(--space-3);
}
.stat-card__label { color: var(--muted); font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.stat-card__value { font-size: var(--text-4xl); font-weight: 720; letter-spacing: -.02em; margin: var(--space-1) 0 var(--space-1); font-variant-numeric: tabular-nums; }
.stat-card__trend { font-size: var(--text-xs); font-weight: 600; display: inline-flex; align-items: center; gap: var(--space-1); }
.trend-up { color: var(--success); }
.trend-down { color: var(--danger); }

.tint-indigo { background: var(--brand-50); color: var(--brand-600); }
.tint-emerald { background: var(--success-soft); color: var(--success); }
.tint-amber { background: var(--warning-soft); color: var(--warning); }
.tint-rose { background: var(--danger-soft); color: var(--danger); }
.tint-blue { background: var(--info-soft); color: var(--info); }

/* ====== Buttons ======================================================== */
.btn { border-radius: var(--radius-sm); font-weight: 600; font-size: var(--text-md); padding: var(--space-2) var(--space-4); transition: all .15s; }
.btn-brand {
    background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
    border: none; color: #fff; box-shadow: 0 6px 16px -4px rgba(79,70,229,.5);
}
.btn-brand:hover { color: #fff; filter: brightness(1.06); box-shadow: 0 10px 22px -6px rgba(79,70,229,.6); }
.btn-soft { background: var(--brand-50); color: var(--brand-700); border: 1px solid var(--brand-100); }
.btn-soft:hover { background: var(--brand-100); color: var(--brand-800); }
.btn-ghost { background: #fff; color: var(--ink-soft); border: 1px solid var(--line); }
.btn-ghost:hover { background: var(--surface); border-color: var(--brand-200); }

/* ====== Badges ========================================================= */
.badge-soft { font-weight: 600; padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); font-size: var(--text-xs); }
.badge-success { background: var(--success-soft); color: #047857; }
.badge-danger { background: var(--danger-soft); color: #b91c1c; }
.badge-warning { background: var(--warning-soft); color: #b45309; }
.badge-info { background: var(--info-soft); color: #1d4ed8; }
.badge-muted { background: #f1f5f9; color: var(--muted); }

/* ====== Tables ========================================================= */
.table-premium { width: 100%; border-collapse: separate; border-spacing: 0; }
.table-premium thead th {
    text-align: left; font-size: var(--text-xs); font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line); background: var(--surface);
}
.table-premium tbody td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--line-soft); font-size: var(--text-md); vertical-align: middle; }
.table-premium tbody tr:hover { background: var(--brand-50); }
.table-premium tbody tr:last-child td { border-bottom: none; }

/* ====== Forms ========================================================== */
.form-label { font-weight: 600; font-size: var(--text-sm); color: var(--ink-soft); margin-bottom: var(--space-1); }
.form-control, .form-select {
    border-radius: var(--radius-sm); border: 1px solid var(--line); padding: var(--space-2) var(--space-3); font-size: var(--text-md);
    background: #fff; transition: border-color .15s, box-shadow .15s;
}
.form-control:hover, .form-select:hover { border-color: var(--brand-300); }
.form-control:focus, .form-select:focus {
    border-color: var(--brand-400); box-shadow: 0 0 0 4px var(--brand-100);
}
/* Browsers paint their own pale-blue over an autofilled field and ignore background-color;
   a full-bleed inset shadow is the only way to keep the field on-palette. */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:active {
    -webkit-text-fill-color: var(--ink);
    -webkit-box-shadow: 0 0 0 1000px var(--card) inset;
    caret-color: var(--ink);
    transition: background-color 5000s ease-in-out 0s;
}
.form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--ink);
    -webkit-box-shadow: 0 0 0 1000px var(--card) inset, 0 0 0 4px var(--brand-100);
}

.input-icon { position: relative; }
/* direct child only — a trailing action button carries its own icon that must not be
   dragged to the left edge by this rule */
.input-icon > i { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--muted-2); font-size: var(--text-xl); pointer-events: none; }
.input-icon .form-control { padding-left: var(--space-10); }
.input-icon--action .form-control { padding-right: var(--space-12); }
.input-icon__action {
    position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
    width: 32px; height: 32px; display: grid; place-items: center;
    padding: 0; border: none; border-radius: var(--radius-xs); background: transparent;
    color: var(--muted-2); line-height: 1; cursor: pointer;
    transition: color .15s, background .15s;
}
.input-icon__action i { font-size: var(--text-xl); }
.input-icon__action:hover { color: var(--ink-soft); background: var(--surface); }
.input-icon__action:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 1px; color: var(--ink-soft); }

/* ====== Auth pages ===================================================== */
.auth-wrap { display: grid; grid-template-columns: 1.05fr .95fr; min-height: 100vh; }
.auth-brand {
    position: relative; color: #fff;
    background: linear-gradient(160deg, #2a2069 0%, #1a1545 50%, #0e0b26 100%);
    padding: clamp(32px, 4.8vh, 56px) clamp(28px, 4vw, 56px);
    display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-6);
    /* clip, not hidden: both contain the glow blobs, but `hidden` makes the panel a scroll
       container, which lets a short viewport crop the copy instead of growing the row */
    overflow: hidden;
    overflow: clip;
}
.auth-brand::before, .auth-brand::after {
    content: ""; position: absolute; border-radius: 50%; filter: blur(10px); opacity: .55;
}
.auth-brand::before { width: 360px; height: 360px; background: radial-gradient(circle, rgba(129,140,248,.5), transparent 65%); top: -90px; right: -80px; }
.auth-brand::after { width: 320px; height: 320px; background: radial-gradient(circle, rgba(245,158,11,.32), transparent 65%); bottom: -100px; left: -60px; }
.auth-brand > * { position: relative; z-index: 1; }
.auth-brand__logo { display: flex; align-items: center; gap: var(--space-3); font-weight: 700; font-size: var(--text-2xl); }
/* the global h1–h5 rule paints headings ink-dark; on this dark panel that is invisible */
.auth-brand__headline {
    color: #fff; font-size: clamp(27px, 2.5vw, 34px); font-weight: 720;
    line-height: 1.18; letter-spacing: -.02em; max-width: 460px;
}
.auth-brand__lead { color: #c5c9e6; font-size: var(--text-base); max-width: 420px; margin-top: var(--space-3); }
.auth-feature { display: flex; align-items: center; gap: var(--space-3); margin-top: clamp(12px, 1.7vh, 16px); color: #d7daf0; font-size: var(--text-md); }
.auth-feature i { color: var(--brand-300); font-size: var(--text-2xl); }
.auth-brand__legal { color: var(--sidebar-ink-dim); font-size: var(--text-sm); }

.auth-form-side { display: flex; align-items: center; justify-content: center; padding: clamp(28px, 5vh, 48px) 24px; background: var(--card); }
.auth-card { width: 100%; max-width: 410px; }
.auth-card h2 { font-size: var(--text-3xl); margin-bottom: var(--space-1); }
.auth-card .muted { color: var(--muted); margin-bottom: var(--space-6); }
/* the brand panel is hidden below 768px, so the card carries the mark and legal line there */
.auth-card__mark { display: none; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); font-weight: 700; font-size: var(--text-2xl); }
.auth-card__legal { display: none; margin: var(--space-6) 0 0; text-align: center; color: var(--muted-2); font-size: var(--text-xs); }

/* ====== Utilities ====================================================== */
.text-muted-2 { color: var(--muted) !important; }
.divider { height: 1px; background: var(--line-soft); margin: var(--space-4) 0; }
.soft-scroll::-webkit-scrollbar { height: 8px; width: 8px; }
.soft-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--radius-xs); }

.sidebar-backdrop { display: none; }

/* ====== Responsive ===================================================== */
@media (max-width: 992px) {
    .sidebar { transform: translateX(-100%); }
    .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-lg); }
    .main { margin-left: 0; }
    .menu-toggle { display: grid; }
    .topbar__search { display: none; }
    .sidebar-backdrop.show { display: block; position: fixed; inset: 0; background: rgba(15,23,42,.45); z-index: 1035; }
}
@media (max-width: 768px) {
    .auth-wrap { grid-template-columns: 1fr; }
    .auth-brand { display: none; }
    .auth-card__mark, .auth-card__legal { display: flex; }
    .auth-card__legal { display: block; }
    .content { padding: var(--space-5) var(--space-4) var(--space-8); }
    .topbar { padding: 0 var(--space-4); }
    .user-chip__name, .user-chip__role { display: none; }
}

/* ====== Status banners ================================================= */
.status-banner {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); margin-bottom: var(--space-4);
    font-size: var(--text-md); font-weight: 500; border: 1px solid transparent;
}
.status-banner i { font-size: var(--text-xl); }
.status-banner__close { margin-left: auto; background: none; border: 0; font-size: var(--text-3xl); line-height: 1; color: inherit; opacity: .55; cursor: pointer; }
.status-banner__close:hover { opacity: 1; }
.status-banner--success { background: var(--success-soft); color: #047857; border-color: #a7f3d0; }
.status-banner--error { background: var(--danger-soft); color: #b91c1c; border-color: #fecaca; }
.status-banner--warning { background: var(--warning-soft); color: #b45309; border-color: #fde68a; }
.status-banner--info { background: var(--info-soft); color: #1d4ed8; border-color: #bfdbfe; }

/* ====== List toolbar =================================================== */
.list-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }

/* Bootstrap ships .form-select and .form-control at width:100%. As a flex item that resolves against
   the toolbar, not the control, so every filter claims a full row of its own and a three-filter bar
   renders as three stacked bars. In a toolbar a filter is as wide as its content and no wider; the
   cap keeps a select from stretching to its longest option when a tenant has 400 groups. */
.list-toolbar .form-select,
.list-toolbar .form-control { width: auto; max-width: 100%; }
.list-toolbar .form-select { max-width: 260px; }
.list-toolbar .form-check { margin-bottom: 0; }

/* ====== DataTables polish ============================================= */
.dt-container .dt-search { margin-bottom: var(--space-1); }
.dt-container .dt-search input {
    border-radius: var(--radius-sm) !important; border: 1px solid var(--line) !important;
    padding: var(--space-2) var(--space-3) !important; min-width: 240px; font-size: var(--text-sm);
}
.dt-container .dt-search input:focus { border-color: var(--brand-400) !important; box-shadow: 0 0 0 4px var(--brand-100) !important; outline: none; }
.dt-container .dt-info { color: var(--muted); font-size: var(--text-xs); padding-top: var(--space-3); }
.dt-container .dt-paging { padding-top: var(--space-2); }
.dt-container .pagination { margin: 0; gap: var(--space-1); }
.dt-container .page-link { border-radius: var(--radius-xs) !important; border: 1px solid var(--line); color: var(--ink-soft); padding: var(--space-1) var(--space-3); }
.dt-container .active > .page-link { background: var(--primary); border-color: var(--primary); color: #fff; }
.dt-container .page-link:hover { background: var(--surface); }

table.dataTable { border-collapse: separate !important; border-spacing: 0; width: 100% !important; }
table.dataTable thead th {
    text-align: left; font-size: var(--text-xs); font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line) !important; background: var(--surface);
}
table.dataTable tbody td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--line-soft) !important; font-size: var(--text-md); vertical-align: middle; }
table.dataTable tbody tr:hover td { background: var(--brand-50); }
table.dataTable.no-footer { border-bottom: 0 !important; }

/* ====== Row actions =================================================== */
.row-actions { display: inline-flex; gap: var(--space-1); }
.action-btn {
    width: 36px; height: 36px; border-radius: var(--radius-xs); display: inline-grid; place-items: center;
    border: 1px solid var(--line); background: #fff; color: var(--ink-soft); cursor: pointer; font-size: var(--text-base);
}
.action-btn:hover { background: var(--surface); border-color: var(--brand-200); color: var(--primary); }
.action-btn--danger:hover { color: var(--danger); border-color: #fecaca; background: var(--danger-soft); }
.action-btn[disabled] { opacity: .4; cursor: not-allowed; }

/* ====== Cell helpers ================================================== */
.cell-title { font-weight: 600; color: var(--ink); }
.cell-sub { font-size: var(--text-sm); color: var(--muted); }

/* A ledger row's description: the sentence, then the coordinates under it. Two lines rather than one
   long one so a row stays the same height whatever the member is called — a single flowing line wraps
   after a long name and the page loses its rhythm. See LedgerDescription in the Application layer. */
.ledger-desc { font-size: var(--text-md); color: var(--ink); line-height: 1.35; }
.ledger-desc__sub { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }
.chip { display: inline-flex; align-items: center; gap: var(--space-1); padding: 3px var(--space-2); border-radius: var(--radius-xs); font-size: var(--text-xs); font-weight: 600; background: var(--brand-50); color: var(--brand-700); }
.chip-stack { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* A settings block holding two ways of doing one thing — the reminder that goes out on a rolling
   window OR on a fixed day of the month. Boxed rather than loose in the cell because the choice is
   between the rows: left unboxed they read as two independent settings, and an operator who set the
   send day would go on expecting the lead-days field to apply as well. The inactive row is dimmed,
   not hidden, so the mode not chosen is still legible as the alternative it is. */
.send-mode {
    display: flex; flex-direction: column; gap: var(--space-2);
    margin-top: var(--space-2); padding: var(--space-3);
    border: 1px solid var(--line-soft); border-radius: var(--radius-xs);
    /* Translucent grey rather than a surface token: it has to sit a shade off whatever is behind it in
       both themes, and the light and dark surfaces sit on opposite sides of every fixed colour. */
    background: rgba(148,163,184,.06);
}
.send-mode__row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.send-mode__row .form-check-input { margin-top: 0; flex: none; }
.send-mode__row input[type="number"] { width: 88px; }
.send-mode__row.is-muted label, .send-mode__row.is-muted .cell-sub { opacity: .62; }

/* ====== Forms ========================================================= */
.form-section { margin-bottom: var(--space-2); }
.form-section__title { font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: var(--space-1) 0 var(--space-3); }
.form-card { max-width: 1680px; }   /* forms fill the available width; capped so they don't stretch absurdly on ultra-wide screens */
.required:after { content: " *"; color: var(--danger); }

/* ====== Permission matrix ============================================= */
.perm-group { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0; margin-bottom: var(--space-3); overflow: hidden; }
.perm-group__head {
    display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4);
    background: var(--surface); border-bottom: 1px solid var(--line-soft);
}
.perm-group__head .form-check { margin: 0; }
.perm-group__title { font-weight: 650; }
.perm-group__count { margin-left: auto; font-size: var(--text-xs); color: var(--muted); }
.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-4); }
.perm-item { display: flex; align-items: flex-start; gap: var(--space-2); }
.perm-item label { font-size: var(--text-sm); cursor: pointer; }
.perm-item .perm-desc { font-size: var(--text-xs); color: var(--muted); }

/* ====== Empty state =================================================== */
.empty-state { text-align: center; padding: var(--space-12) var(--space-5); color: var(--muted); }
.empty-state i { font-size: var(--text-5xl); color: var(--muted-2); }

/* ====== Misc ========================================================== */
.form-switch .form-check-input { width: 2.6em; height: 1.4em; cursor: pointer; }
.form-switch .form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.section-divider { display: flex; align-items: center; gap: var(--space-3); color: var(--muted); font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; margin: var(--space-2) 0 var(--space-4); }
.section-divider::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }

/* ====== Analytics / reports =========================================== */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--space-4); }
.mini-stat { display: flex; flex-direction: column; gap: 2px; }
.mini-stat__label { font-size: var(--text-xs); font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.mini-stat__value { font-size: var(--text-2xl); font-weight: 720; letter-spacing: -.02em; }
.mini-stat__sub { font-size: var(--text-xs); color: var(--muted); }

/* A form control held at its current value — shown, readable, but not editable. Deliberately NOT the
   `disabled` attribute: a disabled control posts nothing, and these fields still have to come back
   with the form so validation passes. The server ignores them either way. */
.field-locked,
.field-locked:focus {
    background: var(--surface) !important;
    color: var(--muted);
    cursor: not-allowed;
    box-shadow: none !important;
    border-color: var(--line-soft) !important;
}
.field-locked-wrap { position: relative; }
.field-locked-wrap > .field-locked-badge {
    position: absolute; top: 0; right: 0;
    font-size: var(--text-xs); color: var(--muted);
}

/* horizontal progress meter used in efficiency tables */
.meter { height: 8px; border-radius: var(--radius-xs); background: var(--line-soft); overflow: hidden; min-width: 90px; }
.meter > span { display: block; height: 100%; border-radius: var(--radius-xs); background: linear-gradient(90deg, var(--brand-400), var(--brand-600)); }
.meter--good > span { background: linear-gradient(90deg, #34d399, #10b981); }
.meter--warn > span { background: linear-gradient(90deg, #fbbf24, #f59e0b); }
.meter--bad  > span { background: linear-gradient(90deg, #f87171, #ef4444); }

.report-canvas-wrap { position: relative; }

/* print letterhead — hidden on screen, shown on paper */
.print-only { display: none; }
.print-header__row { display: flex; justify-content: space-between; align-items: flex-start; }
.print-header__brand { font-size: var(--text-2xl); font-weight: 750; color: var(--ink); }
.print-header__title { font-size: var(--text-base); font-weight: 650; color: var(--brand-700); }
.print-header__logo { font-weight: 800; color: var(--brand-600); letter-spacing: -.02em; }
.print-header__meta { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }
.print-header__sep { margin: 0 var(--space-1); }

/* ====== Print ========================================================= */
@media print {
    /* @page, with one sign, not two. The doubled sign made this a parse error, so the margins
       never applied and every report has printed with browser defaults. The original also asked
       for A4 landscape; that is deliberately left out, because the notices, receipts and staff
       letters have been laid out against portrait for months. Add it per report where a wide
       register actually needs it. */
    @page { margin: 14mm 12mm; }
    html, body { background: #fff !important; }
    body { font-size: var(--text-xs); }
    /* Two selector-less print-color-adjust declarations used to sit here. A declaration cannot
       live directly in a media block, so it was a parse error, and CSS error recovery swallowed
       the rule below it as part of the bad prelude — printouts silently lost every background
       fill. Verified in the DOM: 13 rules parsed where 14 were written. */
    * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }

    .sidebar, .sidebar-backdrop, .topbar, .menu-toggle, .no-print,
    .dt-container .dt-search, .dt-container .dt-paging, .dt-container .dt-length,
    .dt-container .dt-info { display: none !important; }

    .main { margin-left: 0 !important; }
    .content { padding: 0 !important; }

    .print-only { display: block !important; }
    .print-header { border-bottom: 2px solid var(--brand-600); padding-bottom: var(--space-2); margin-bottom: var(--space-4); }

    .card { box-shadow: none !important; border: 1px solid #d7dae6 !important; break-inside: avoid; }
    .stat-card { box-shadow: none !important; border: 1px solid #d7dae6 !important; }
    .card, .stat-card, table { break-inside: avoid; }
    canvas { max-width: 100% !important; }
    a[href]:after { content: ""; }   /* don't print URLs after links */
    .crumbs, .rowmenu__btn { display: none !important; }
}

/* ==========================================================================
   Provider letterhead — printed quotations & invoices (software-provider header)
   ========================================================================== */
.doc-letterhead {
    display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-6);
    padding-bottom: var(--space-4); margin-bottom: var(--space-5); border-bottom: 2px solid var(--brand-600);
}
.doc-letterhead__brand { display: flex; align-items: center; gap: var(--space-3); }
.doc-letterhead__logo { width: 48px; height: 48px; flex: 0 0 48px; }
.doc-letterhead__logo-img { width: 48px; height: 48px; flex: 0 0 48px; object-fit: contain; border-radius: var(--radius-sm); }
.doc-letterhead__brandname { font-size: var(--text-3xl); font-weight: 800; letter-spacing: -.02em; color: var(--brand-700); line-height: 1.1; }
.doc-letterhead__tagline { font-size: var(--text-xs); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
.doc-letterhead__contact { text-align: right; font-size: var(--text-xs); color: var(--muted); line-height: 1.6; max-width: 280px; }
.doc-letterhead__ids { margin-top: 3px; font-weight: 600; color: var(--ink-soft); }
.doc-letterhead__sep { margin: 0 var(--space-1); color: var(--muted-2); }

/* Bill-to / document parties block */
.doc-parties { display: flex; justify-content: space-between; gap: var(--space-6); flex-wrap: wrap; margin-bottom: var(--space-4); }
.doc-party__label { font-size: var(--text-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: var(--space-1); }
.doc-party__name { font-weight: 700; color: var(--ink); }
.doc-party__line { font-size: var(--text-xs); color: var(--muted); }
.doc-meta { text-align: right; }
.doc-meta__row { font-size: var(--text-xs); color: var(--muted); }
.doc-meta__row strong { color: var(--ink); }

@media print {
    /* Vendor documents print portrait, unlike the landscape analytics reports. */
    .doc-print-page { }
    .doc-letterhead { break-inside: avoid; }
    .doc-parties { break-inside: avoid; }
}

/* ==========================================================================
   Enterprise UI components (breadcrumbs · KPI cards · row-action menu · pills)
   ========================================================================== */

/* Breadcrumbs in the topbar */
.crumbs { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--muted); margin: 0 0 2px; line-height: 1; }
.crumbs a { color: var(--muted); display: inline-flex; align-items: center; gap: var(--space-1); }
.crumbs a:hover { color: var(--primary); }
.crumbs .sep { color: var(--muted-2); font-size: var(--text-2xs); }
.crumbs .current { color: var(--ink-soft); font-weight: 600; }

/* KPI cards row (list-page metrics) */
.kpi-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-4); }
.kpi {
    background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--radius);
    box-shadow: var(--shadow-xs); padding: var(--space-4) var(--space-4); display: flex; flex-direction: column; gap: var(--space-2);
    transition: transform .15s, box-shadow .15s;
}
.kpi:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi__top { display: flex; align-items: center; gap: var(--space-2); }
.kpi__icon { width: 36px; height: 36px; border-radius: var(--radius-sm); display: grid; place-items: center; font-size: var(--text-xl); flex: 0 0 36px; }
.kpi__label { font-size: var(--text-xs); font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.kpi__value { font-size: var(--text-3xl); font-weight: 730; letter-spacing: -.02em; line-height: 1.1; }
.kpi__sub { font-size: var(--text-xs); color: var(--muted); }

/* Row-action overflow menu (⋯) */
.rowmenu { position: relative; display: inline-block; text-align: left; }
.rowmenu__btn {
    width: 36px; height: 36px; border-radius: var(--radius-xs); border: 1px solid var(--line); background: #fff;
    color: var(--ink-soft); cursor: pointer; display: inline-grid; place-items: center; font-size: var(--text-xl); line-height: 0;
}
.rowmenu__btn:hover, .rowmenu.open .rowmenu__btn { background: var(--surface); border-color: var(--brand-200); color: var(--primary); }
.rowmenu__list {
    position: absolute; right: 0; top: calc(100% + 5px); min-width: 190px; background: #fff;
    border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: var(--space-1); z-index: 70; display: none;
}
.rowmenu.open .rowmenu__list { display: block; animation: menuIn .12s ease; }
@keyframes menuIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.rowmenu__item {
    display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: var(--space-2) var(--space-2); border-radius: var(--radius-xs);
    font-size: var(--text-sm); font-weight: 500; color: var(--ink-soft); background: none; border: 0; text-align: left;
    cursor: pointer; text-decoration: none;
}
.rowmenu__item:hover { background: var(--surface); color: var(--primary); }
.rowmenu__item i { width: 16px; text-align: center; color: var(--muted); font-size: var(--text-base); }
.rowmenu__item:hover i { color: var(--primary); }
.rowmenu__item--danger { color: var(--danger); }
.rowmenu__item--danger i { color: var(--danger); }
.rowmenu__item--danger:hover { background: var(--danger-soft); color: #b91c1c; }
.rowmenu__divider { height: 1px; background: var(--line-soft); margin: var(--space-1) var(--space-1); }

/* Status pills (dot + label) */
.pill { display: inline-flex; align-items: center; gap: var(--space-1); padding: 3px var(--space-3); border-radius: var(--radius-pill); font-size: var(--text-xs); font-weight: 600; }
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill-green { background: var(--success-soft); color: #047857; }
.pill-gray { background: #eef1f6; color: var(--muted); }
.pill-red { background: var(--danger-soft); color: #b91c1c; }
.pill-amber { background: var(--warning-soft); color: #b45309; }
.pill-blue { background: var(--info-soft); color: #1d4ed8; }
.pill-violet { background: var(--brand-50); color: var(--brand-700); }

/* Page toolbar (title + actions row used above content) */
.page-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
.page-toolbar__title { font-size: var(--text-2xl); font-weight: 680; margin: 0; }
.page-toolbar__sub { font-size: var(--text-sm); color: var(--muted); margin: 0; }

/* Numeric / money helpers */
.mono { font-variant-numeric: tabular-nums; }
.amount-pos { color: var(--success); }
.amount-neg { color: var(--danger); }

/* Slightly tighter, cleaner data rows for dense enterprise tables */
.table-premium tbody td, table.dataTable tbody td { padding-top: var(--space-3); padding-bottom: var(--space-3); }
.table-premium tbody tr, table.dataTable tbody tr { transition: background .12s; }

/* ==========================================================================
   Usability layer — command palette · toasts · shortcuts · nav · dark mode
   ========================================================================== */

/* ---- kbd hint chip ---- */
.kbd {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 19px; padding: 0 var(--space-1); font-size: var(--text-2xs); font-weight: 600;
    font-family: inherit; color: var(--muted); background: var(--surface);
    border: 1px solid var(--line); border-bottom-width: 2px; border-radius: var(--radius-xs);
    line-height: 1; white-space: nowrap;
}

/* ---- Topbar search → palette trigger ---- */
.topbar__search { cursor: text; user-select: none; font-family: inherit; transition: border-color .15s, background .15s; }
.topbar__search:hover { border-color: var(--brand-200); background: #fff; }
.topbar__search-placeholder { flex: 1 1 auto; text-align: left; font-size: var(--text-sm); }
.topbar__search .kbd { margin-left: var(--space-1); }
.topbar__search-mobile { display: none; }

/* ---- Notifications dropdown ---- */
.notif-menu { border-radius: var(--radius); border-color: var(--line); min-width: 300px; padding: 0; overflow: hidden; }
.notif-menu__head { padding: var(--space-3) var(--space-4); font-weight: 650; border-bottom: 1px solid var(--line-soft); }
.notif-menu__empty { padding: var(--space-6) var(--space-4); text-align: center; color: var(--muted); }
.notif-menu__empty i { font-size: var(--text-3xl); color: var(--muted-2); display: block; margin-bottom: var(--space-2); }
.notif-menu__foot {
    display: flex; align-items: center; justify-content: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-4); border-top: 1px solid var(--line-soft); font-weight: 600; font-size: var(--text-sm);
}
.notif-menu__foot:hover { background: var(--surface); }

/* ====== Command palette ================================================ */
.cmdk { position: fixed; inset: 0; z-index: 1090; display: flex; align-items: flex-start; justify-content: center; }
.cmdk[hidden] { display: none; }
.cmdk__backdrop { position: absolute; inset: 0; background: rgba(15, 19, 36, .55); backdrop-filter: blur(2px); animation: fadeIn .15s ease; }
.cmdk__panel {
    position: relative; width: min(640px, calc(100vw - 32px)); margin-top: 11vh;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-lg); overflow: hidden; animation: popIn .16s cubic-bezier(.2, .8, .3, 1);
}
.cmdk__search { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-4); border-bottom: 1px solid var(--line-soft); }
.cmdk__search > i { font-size: var(--text-2xl); color: var(--muted); }
.cmdk__search input { flex: 1 1 auto; border: 0; outline: none; background: transparent; font-size: var(--text-lg); color: var(--ink); }
.cmdk__results { max-height: min(56vh, 440px); overflow-y: auto; padding: var(--space-2); }
.cmdk__group-label { font-size: var(--text-2xs); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-2); padding: var(--space-2) var(--space-3) var(--space-1); }
.cmdk__item {
    display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
    cursor: pointer; color: var(--ink-soft); text-decoration: none;
}
.cmdk__item-icon { width: 32px; height: 32px; flex: 0 0 32px; border-radius: var(--radius-xs); display: grid; place-items: center; font-size: var(--text-lg); background: var(--brand-50); color: var(--brand-600); }
.cmdk__item-body { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.cmdk__item-label { font-size: var(--text-md); font-weight: 550; }
.cmdk__item-sub { font-size: var(--text-xs); color: var(--muted-2); margin-top: 1px; }
.cmdk__item-section { font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
.cmdk__item.is-active { background: var(--brand-50); }
.cmdk__item.is-active .cmdk__item-icon { background: var(--brand-600); color: #fff; }
.cmdk__item.is-active .cmdk__item-section { color: var(--brand-600); }
.cmdk__empty { text-align: center; color: var(--muted); padding: var(--space-8) var(--space-4); }
.cmdk__empty i { font-size: var(--text-4xl); color: var(--muted-2); display: block; margin-bottom: var(--space-2); }
.cmdk__foot { display: flex; gap: var(--space-4); padding: var(--space-2) var(--space-4); border-top: 1px solid var(--line-soft); font-size: var(--text-xs); color: var(--muted); background: var(--surface); }
.cmdk__foot .kbd { margin-right: 3px; }

/* ====== Shortcuts modal ================================================ */
.shortcuts {
    position: relative; width: min(620px, calc(100vw - 32px)); margin-top: 12vh;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-lg);
    animation: popIn .16s cubic-bezier(.2, .8, .3, 1); overflow: hidden;
}
.shortcuts__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--line-soft); font-weight: 680; font-size: var(--text-lg); }
.shortcuts__body { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2) var(--space-8); padding: var(--space-4) var(--space-5) var(--space-5); }
.shortcuts__group-title { font-size: var(--text-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin: var(--space-1) 0 var(--space-2); }
.shortcuts__row { display: flex; align-items: center; justify-content: space-between; padding: var(--space-1) 0; font-size: var(--text-sm); border-bottom: 1px solid var(--line-soft); }
.shortcuts__row > span:last-child { display: inline-flex; gap: var(--space-1); }
@media (max-width: 600px) { .shortcuts__body { grid-template-columns: 1fr; } }

/* ====== Toasts ========================================================= */
.toast-stack { position: fixed; top: 18px; right: 18px; z-index: 1100; display: flex; flex-direction: column; gap: var(--space-3); width: min(360px, calc(100vw - 32px)); pointer-events: none; }
.toast-item {
    display: flex; align-items: flex-start; gap: var(--space-3); pointer-events: auto;
    background: var(--card); border: 1px solid var(--line); border-left: 4px solid var(--muted-2);
    border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: var(--space-3) var(--space-3);
    animation: toastIn .26s cubic-bezier(.2, .8, .3, 1);
}
.toast-item.is-leaving { animation: toastOut .22s ease forwards; }
.toast-item__icon { font-size: var(--text-2xl); line-height: 1.3; }
.toast-item__body { flex: 1 1 auto; min-width: 0; }
.toast-item__title { font-weight: 650; font-size: var(--text-md); }
.toast-item__msg { font-size: var(--text-sm); color: var(--muted); margin-top: 1px; overflow-wrap: anywhere; }
.toast-item__close { background: none; border: 0; color: var(--muted-2); font-size: var(--text-lg); cursor: pointer; padding: 2px; line-height: 1; }
.toast-item__close:hover { color: var(--ink); }
.toast-item--success { border-left-color: var(--success); }
.toast-item--success .toast-item__icon { color: var(--success); }
.toast-item--error { border-left-color: var(--danger); }
.toast-item--error .toast-item__icon { color: var(--danger); }
.toast-item--info { border-left-color: var(--info); }
.toast-item--info .toast-item__icon { color: var(--info); }
.toast-item--warning { border-left-color: var(--warning); }
.toast-item--warning .toast-item__icon { color: var(--warning); }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: translateY(-8px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes toastIn { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(16px); } }

/* ====== Sidebar — collapsible sections ================================ */
.nav-section__label--toggle { display: flex; align-items: center; cursor: pointer; user-select: none; border-radius: var(--radius-xs); transition: color .15s; }
.nav-section__label--toggle:hover { color: var(--sidebar-ink); }
.nav-section__chevron { margin-left: auto; font-size: var(--text-xs); transition: transform .2s ease; }
.nav-section.collapsed .nav-section__chevron { transform: rotate(-90deg); }
.nav-section__items { overflow: hidden; transition: max-height .26s ease, opacity .2s ease; max-height: 1200px; opacity: 1; }
.nav-section.collapsed .nav-section__items { max-height: 0; opacity: 0; }

/* ---- Categorised Reports menu (3-level nested sections) -------------- */
/* The parent wrap holds several sub-categories, so it needs more headroom. */
.nav-section--reports > .nav-section__items { max-height: 3000px; }
.nav-section .nav-section { margin-top: 0; }
/* Level-2 sub-category headers read as rows, not tiny uppercase labels. */
.nav-section .nav-section > .nav-section__label {
    text-transform: none; letter-spacing: 0;
    font-size: var(--text-xs); font-weight: 600;
    color: var(--sidebar-ink);
    padding: var(--space-2) var(--space-3); margin: 1px 0; border-radius: var(--radius-sm);
}
.nav-section .nav-section > .nav-section__label:hover { background: rgba(255,255,255,.06); color: #fff; }
/* Level-3 report links indented under their sub-category. */
.nav-section .nav-section .nav-item { padding-left: var(--space-8); font-size: var(--text-sm); }

/* ====== Sidebar — rail (collapsed) mode, desktop only ================= */
.nav-rail-toggle { display: grid; }
@media (min-width: 993px) {
    html.nav-rail { --sidebar-w: 78px; }
    html.nav-rail .sidebar__brand { justify-content: center; padding: var(--space-5) 0 var(--space-4); }
    html.nav-rail .sidebar__brand-text { display: none; }
    html.nav-rail .nav-section__label { display: none; }
    html.nav-rail .nav-section { margin-top: var(--space-1); padding-top: var(--space-2); border-top: 1px solid rgba(255, 255, 255, .07); }
    html.nav-rail .sidebar__nav > .nav-section:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
    html.nav-rail .nav-item { justify-content: center; padding: var(--space-3) 0; margin: 3px 0; }
    html.nav-rail .nav-item span { display: none; }
    html.nav-rail .nav-item i { width: auto; }
    html.nav-rail .nav-item.active::before { display: none; } /* centered icon + bg is enough in rail */
    html.nav-rail .nav-section.collapsed .nav-section__items { max-height: 1200px; opacity: 1; }
    /* Nested report sub-sections collapse to a flat icon list in rail mode. */
    html.nav-rail .nav-section .nav-section { margin-top: 0; padding-top: 0; border-top: 0; }
    html.nav-rail .nav-section .nav-section .nav-item { padding-left: 0; }
}

/* ====== Focus visibility (a11y polish) ================================ */
:focus-visible { outline: 2px solid var(--brand-400); outline-offset: 2px; }
.nav-item:focus-visible { outline-offset: -2px; }
.cmdk__item:focus-visible { outline: none; }

@media (max-width: 992px) {
    .nav-rail-toggle { display: none; }
    .topbar__search-mobile { display: grid; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ====== Dark theme ===================================================== */
html[data-theme="dark"] {
    --ink: #e7ebf6;
    --ink-soft: #c6cde1;
    --muted: #98a2be;
    --muted-2: #6e7795;
    --line: #2b3350;
    --line-soft: #232a44;
    --surface: #0d1222;
    --card: #161d33;
    --brand-50: #1f2748;
    --brand-100: #2b356099;
    --success-soft: rgba(16, 185, 129, .16);
    --danger-soft: rgba(239, 68, 68, .16);
    --warning-soft: rgba(245, 158, 11, .16);
    --info-soft: rgba(59, 130, 246, .16);
    --accent-soft: rgba(245, 158, 11, .16);
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, .45), 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-md: 0 6px 18px -4px rgba(0, 0, 0, .55), 0 2px 6px -2px rgba(0, 0, 0, .4);
    --shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, .7);
    color-scheme: dark;
}
html[data-theme="dark"] body { background: var(--surface); }
html[data-theme="dark"] .topbar { background: rgba(15, 20, 38, .82); }
html[data-theme="dark"] .topbar__search:hover { background: var(--card); }
html[data-theme="dark"] .icon-btn,
html[data-theme="dark"] .btn-ghost,
html[data-theme="dark"] .action-btn,
html[data-theme="dark"] .rowmenu__btn,
html[data-theme="dark"] .theme-toggle,
html[data-theme="dark"] .color-scheme-btn,
html[data-theme="dark"] .topbar__search { background: var(--card); color: var(--ink-soft); }
html[data-theme="dark"] .icon-btn:hover,
html[data-theme="dark"] .btn-ghost:hover,
html[data-theme="dark"] .action-btn:hover,
html[data-theme="dark"] .theme-toggle:hover,
html[data-theme="dark"] .color-scheme-btn:hover,
html[data-theme="dark"] .rowmenu__btn:hover { background: #1d2541; }
html[data-theme="dark"] .color-scheme-dropdown { background: var(--card); border-color: var(--line); }
html[data-theme="dark"] .color-scheme-option { color: var(--ink-soft); }
html[data-theme="dark"] .color-scheme-option:hover { background: #1d2541; }
html[data-theme="dark"] .color-scheme-option.active { background: #1d2541; color: var(--brand-300); }
html[data-theme="dark"] .form-control,
html[data-theme="dark"] .form-select { background: #10162a; border-color: var(--line); color: var(--ink); }
html[data-theme="dark"] .form-control::placeholder { color: var(--muted-2); }
html[data-theme="dark"] .form-check-input { background-color: #10162a; border-color: var(--line); }
html[data-theme="dark"] .dropdown-menu { background: var(--card); border-color: var(--line); }
html[data-theme="dark"] .dropdown-item { color: var(--ink-soft); }
html[data-theme="dark"] .dropdown-item:hover,
html[data-theme="dark"] .dropdown-item:focus { background: #1d2541; color: var(--ink); }
html[data-theme="dark"] .dropdown-divider { border-color: var(--line); }
html[data-theme="dark"] .modal-content { background: var(--card); border-color: var(--line); color: var(--ink); }
html[data-theme="dark"] .modal-header,
html[data-theme="dark"] .modal-footer { border-color: var(--line); }
html[data-theme="dark"] .btn-close { filter: invert(1) grayscale(1) brightness(1.6); }
html[data-theme="dark"] .table { color: var(--ink-soft); --bs-table-bg: transparent; --bs-table-color: var(--ink-soft); }
html[data-theme="dark"] code { color: var(--brand-300); }
html[data-theme="dark"] .btn-soft { color: var(--brand-300); border-color: var(--brand-100); }
html[data-theme="dark"] .btn-soft:hover { color: #fff; background: var(--brand-100); }
html[data-theme="dark"] .chip { color: var(--brand-300); }
/* --brand-50 flips dark but --brand-200/700 do not, so a hovered preset would otherwise put a dark
   indigo on a dark indigo. Same substitution the chip above makes, for the same reason. */
html[data-theme="dark"] .stmt-preset:hover { border-color: var(--brand-400); color: var(--brand-300); }
html[data-theme="dark"] .cmdk__item-icon { color: var(--brand-300); }
html[data-theme="dark"] .badge-success, html[data-theme="dark"] .pill-green { color: #6ee7b7; }
html[data-theme="dark"] .badge-danger, html[data-theme="dark"] .pill-red { color: #fca5a5; }
html[data-theme="dark"] .badge-warning, html[data-theme="dark"] .pill-amber { color: #fcd34d; }
html[data-theme="dark"] .badge-info, html[data-theme="dark"] .pill-blue { color: #93c5fd; }
html[data-theme="dark"] .scheme-card__note { color: #93c5fd; }
html[data-theme="dark"] .pill-violet { color: var(--brand-300); }
html[data-theme="dark"] .badge-muted, html[data-theme="dark"] .pill-gray { background: #222a44; color: var(--muted); }
html[data-theme="dark"] .status-banner--success { background: rgba(16, 185, 129, .14); color: #6ee7b7; border-color: rgba(16, 185, 129, .3); }
html[data-theme="dark"] .status-banner--error { background: rgba(239, 68, 68, .14); color: #fca5a5; border-color: rgba(239, 68, 68, .3); }
html[data-theme="dark"] .status-banner--warning { background: rgba(245, 158, 11, .14); color: #fcd34d; border-color: rgba(245, 158, 11, .3); }
html[data-theme="dark"] .status-banner--info { background: rgba(59, 130, 246, .14); color: #93c5fd; border-color: rgba(59, 130, 246, .3); }

/* ====== Dashboard liquidity cards (cash / bank / total) =============== */
.balance-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: var(--space-4); margin: var(--space-4) 0 2px; }
.balance-card { border-radius: var(--radius); padding: var(--space-4) var(--space-5); border: 1px solid transparent; box-shadow: var(--shadow-xs); transition: transform .15s, box-shadow .15s; }
.balance-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.balance-card__label { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .045em; display: flex; align-items: center; gap: var(--space-2); }
.balance-card__label i { font-size: var(--text-base); }
.balance-card__value { font-size: var(--text-4xl); font-weight: 760; letter-spacing: -.02em; margin: var(--space-2) 0 var(--space-1); font-variant-numeric: tabular-nums; }
.balance-card__value.is-neg { color: var(--danger) !important; }
.balance-card__sub { font-size: var(--text-xs); font-weight: 500; opacity: .9; }

.balance-card--cash { background: linear-gradient(135deg, #fdf4cf, #fbe7a6); border-color: #f1d486; color: #97650c; }
.balance-card--cash .balance-card__value { color: #7a4906; }
.balance-card--bank { background: linear-gradient(135deg, #e8f0fe, #d3e2fc); border-color: #b4ccf5; color: #1d4ed8; }
.balance-card--bank .balance-card__value { color: #1e3a8a; }
.balance-card--total { background: linear-gradient(135deg, #dafae8, #bfeecf); border-color: #95ddb6; color: #047857; }
.balance-card--total .balance-card__value { color: #065f46; }

html[data-theme="dark"] .balance-card--cash { background: rgba(245, 158, 11, .13); border-color: rgba(245, 158, 11, .30); color: #fcd34d; }
html[data-theme="dark"] .balance-card--cash .balance-card__value { color: #fde68a; }
html[data-theme="dark"] .balance-card--bank { background: rgba(59, 130, 246, .14); border-color: rgba(59, 130, 246, .30); color: #93c5fd; }
html[data-theme="dark"] .balance-card--bank .balance-card__value { color: #bfdbfe; }
html[data-theme="dark"] .balance-card--total { background: rgba(16, 185, 129, .14); border-color: rgba(16, 185, 129, .30); color: #6ee7b7; }
html[data-theme="dark"] .balance-card--total .balance-card__value { color: #a7f3d0; }

/* ====== Import result panel =========================================== */
.import-errors { margin-bottom: var(--space-4); border-color: #fecaca; }
.import-errors .card-header { background: var(--danger-soft); border-bottom-color: #fecaca; }
.import-errors__list { margin: 0; padding-left: var(--space-4); max-height: 260px; overflow-y: auto; }
.import-errors__list li { font-size: var(--text-sm); color: var(--ink-soft); padding: 2px 0; }
html[data-theme="dark"] .import-errors { border-color: rgba(239, 68, 68, .35); }
html[data-theme="dark"] .import-errors .card-header { background: rgba(239, 68, 68, .14); border-bottom-color: rgba(239, 68, 68, .3); }

/* ====== Scheme card / brochure (FixedSchedule catalogue) ============== */
.scheme-card { max-width: 720px; margin: 0 auto; background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--radius); box-shadow: var(--shadow-md); overflow: hidden; }
.scheme-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-5) var(--space-6); color: #fff; background: linear-gradient(135deg, var(--brand-600), var(--brand-800)); }
.scheme-card__sub { font-size: var(--text-sm); opacity: .9; font-weight: 600; }
.scheme-card__value { font-size: var(--text-4xl); font-weight: 780; letter-spacing: -.02em; margin: 2px 0 var(--space-1); }
.scheme-card__meta { font-size: var(--text-xs); opacity: .92; }
.scheme-card__badge { background: rgba(255, 255, 255, .18); border: 1px solid rgba(255, 255, 255, .3); color: #fff; padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); font-size: var(--text-xs); font-weight: 700; white-space: nowrap; }
.scheme-card__body { padding: var(--space-2) var(--space-2) var(--space-3); }
.scheme-table { border-collapse: separate; border-spacing: 0; }
.scheme-table thead th { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line); }
.scheme-table tbody td { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); border-bottom: 1px solid var(--line-soft); }
.scheme-table tbody tr:nth-child(even) td { background: var(--surface); }
.scheme-table tfoot td { padding: var(--space-3) var(--space-3); font-size: var(--text-md); border-top: 2px solid var(--brand-200); }
.scheme-card__foot { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-3) var(--space-3) var(--space-1); font-size: var(--text-xs); color: var(--muted); font-weight: 600; }
.scheme-card__note { display: flex; align-items: flex-start; gap: var(--space-2); margin: var(--space-3) var(--space-3) 0; padding: var(--space-2) var(--space-3); font-size: var(--text-xs); line-height: 1.45; font-weight: 600; color: #1d4ed8; background: var(--info-soft); border-radius: var(--radius-sm); }
.scheme-card__note i { font-size: var(--text-base); line-height: 1.2; }
/* Company letterhead at the top of the card: logo (or the initial badge), legal name, address, contact line.
   The markup has always been in _SchemeCard.cshtml; these rules were never written, so it printed as plain
   left-aligned text. */
.scheme-card__letterhead { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; padding: var(--space-5) var(--space-6) var(--space-4); border-bottom: 1px solid var(--line-soft); }
.scheme-card__logo { display: block; height: 56px; max-width: 200px; object-fit: contain; margin-bottom: var(--space-2); }
.scheme-card__brandmark { display: grid; place-items: center; width: 52px; height: 52px; margin-bottom: var(--space-2); border-radius: var(--radius-sm); color: #fff; font-size: var(--text-2xl); font-weight: 780; background: linear-gradient(135deg, var(--brand-500), var(--brand-700)); box-shadow: var(--shadow-sm); }
.scheme-card__coname { font-size: var(--text-xl); font-weight: 750; letter-spacing: -.01em; color: var(--ink); line-height: 1.25; }
.scheme-card__coaddr { font-size: var(--text-sm); color: var(--muted); max-width: 46ch; line-height: 1.4; }
.scheme-card__cocontact { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-1) var(--space-4); margin-top: var(--space-1); font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
/* Pooled-draw card: what a member pays in and what they receive, at a glance. */
.scheme-card__payout { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); margin: var(--space-3) var(--space-3) 0; }
.scheme-card__payout > div { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); padding: var(--space-3); text-align: center; }
.scheme-card__payout-label { font-size: var(--text-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.scheme-card__payout-value { font-size: var(--text-2xl); font-weight: 750; font-variant-numeric: tabular-nums; margin-top: 2px; }
.scheme-card__payout-sub { font-size: var(--text-2xs); color: var(--muted); margin-top: 2px; }
.scheme-card__payout > div.is-key { background: var(--success-soft); border-color: #a7f3d0; }
.scheme-card__payout > div.is-key .scheme-card__payout-value { color: #047857; }
html[data-theme="dark"] .scheme-card__payout > div.is-key { background: rgba(16, 185, 129, .14); border-color: rgba(16, 185, 129, .3); }
html[data-theme="dark"] .scheme-card__payout > div.is-key .scheme-card__payout-value { color: #6ee7b7; }

/* ====== CRM — pipeline Kanban board ================================== */
.kanban { display: flex; gap: var(--space-3); overflow-x: auto; padding: 2px 2px var(--space-3); align-items: flex-start; }
.kanban__col { flex: 0 0 286px; max-width: 286px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); display: flex; flex-direction: column; max-height: calc(100vh - 240px); }
.kanban__col-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-3) var(--space-3); border-bottom: 1px solid var(--line); }
.kanban__col-head .k-title { font-weight: 700; font-size: var(--text-sm); display: flex; align-items: center; gap: var(--space-2); }
.kanban__col-head .k-count { font-size: var(--text-2xs); font-weight: 700; color: var(--muted); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 1px var(--space-2); }
.kanban__col-sub { padding: 0 var(--space-3) var(--space-2); font-size: var(--text-xs); color: var(--muted); font-weight: 600; }
.kanban__col-body { padding: var(--space-2); overflow-y: auto; flex: 1; min-height: 80px; }
.kanban__col.drop-hover { outline: 2px dashed var(--brand-400); outline-offset: -5px; background: var(--brand-50); }
.kanban__card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-3) var(--space-3); margin-bottom: var(--space-2); box-shadow: var(--shadow-xs); cursor: grab; transition: transform .12s, box-shadow .12s; text-decoration: none; display: block; color: inherit; }
.kanban__card:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); border-color: var(--brand-200); }
.kanban__card:active { cursor: grabbing; }
.kanban__card.dragging { opacity: .45; }
.kanban__card-name { font-weight: 650; font-size: var(--text-sm); color: var(--ink); }
.kanban__card-meta { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
.kanban__card-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-1); margin-top: var(--space-2); }
.kanban__empty { font-size: var(--text-xs); color: var(--muted-2); text-align: center; padding: var(--space-3) var(--space-1); }

/* ====== CRM — activity timeline ===================================== */
.timeline { position: relative; padding-left: var(--space-6); margin: var(--space-1) 0; }
.timeline__item { position: relative; padding: 0 0 var(--space-4); }
.timeline__item:last-child { padding-bottom: 2px; }
.timeline__item::before { content: ""; position: absolute; left: -18px; top: 3px; width: 11px; height: 11px; border-radius: 50%; background: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50); z-index: 1; }
.timeline__item::after { content: ""; position: absolute; left: -13px; top: 14px; bottom: 0; width: 2px; background: var(--line); }
.timeline__item:last-child::after { display: none; }
.timeline__item.is-due::before { background: var(--warning); box-shadow: 0 0 0 3px var(--warning-soft); }
.timeline__item.is-overdue::before { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }
.timeline__head { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.timeline__title { font-weight: 650; font-size: var(--text-sm); }
.timeline__time { font-size: var(--text-xs); color: var(--muted); }
.timeline__body { font-size: var(--text-sm); color: var(--ink-soft); margin-top: 3px; white-space: pre-wrap; }

/* ====== CRM — detail key/value list + tabs ========================== */
.detail-list { margin: 0; }
.detail-list > div { display: flex; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--line-soft); }
.detail-list > div:last-child { border-bottom: 0; }
.detail-list dt { flex: 0 0 130px; margin: 0; font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
.detail-list dd { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
.nav-tabs { border-bottom: 1px solid var(--line); gap: 2px; }
.nav-tabs .nav-link { border: none; border-bottom: 2px solid transparent; color: var(--muted); font-weight: 600; font-size: var(--text-sm); padding: var(--space-2) var(--space-3); background: none; }
.nav-tabs .nav-link:hover { color: var(--ink); border-bottom-color: var(--line); }
.nav-tabs .nav-link.active { color: var(--brand-600); border-bottom-color: var(--brand-600); background: none; }
html[data-theme="dark"] .nav-tabs .nav-link.active { color: var(--brand-300); border-bottom-color: var(--brand-400); }

/* ====== Report filters (built by js/report-filters.js) =============== */
/* One recessed strip above the table: search, column dropdowns and the amount
   threshold on the left, the live row count and Clear pushed right by the spacer.
   Every control here is a Bootstrap .form-control/.form-select, which is width:100%
   by default — each needs an explicit width or the row stacks into a column. */
.report-filters {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    transition: background .15s, border-color .15s;
}
.report-filters.is-filtered { background: var(--brand-50); border-color: var(--brand-200); }

.report-filters__search { position: relative; flex: 1 1 210px; min-width: 168px; max-width: 300px; }
.report-filters__search > i {
    position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
    font-size: var(--text-sm); color: var(--muted-2); pointer-events: none;
}
.report-filters__search input { width: 100%; padding-left: var(--space-8); }

/* auto-width so a select is only as wide as its longest value, capped so one long
   facet ("Description") can't push the count chip onto its own line */
.report-filters__facet { flex: 0 1 auto; width: auto; min-width: 116px; max-width: 210px; }

.report-filters__num { display: inline-flex; align-items: center; gap: var(--space-2); }
.report-filters__num-label { font-size: var(--text-xs); font-weight: 600; color: var(--muted); white-space: nowrap; }
.report-filters__num input { width: 118px; }

.report-filters__spacer { flex: 1 1 auto; }

.report-filters__count {
    font-size: var(--text-xs); font-weight: 650; color: var(--muted); white-space: nowrap;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill);
    padding: 3px var(--space-3); font-variant-numeric: tabular-nums;
}
.report-filters__count.is-filtered { color: var(--brand-700); border-color: var(--brand-200); }

/* the DataTables variant carries dropdowns only — it sits above DataTables' own toolbar */
.report-filters--dt { margin-bottom: var(--space-2); }

/* Filtered-out rows and cards. !important so a row keeps its hidden state through
   .table-premium's own tbody rules and on to the printout. */
.report-filters__hidden { display: none !important; }

/* Off-page rather than filtered out. Kept separate from __hidden so that print can bring
   these back: a printed report is the whole filtered set, not whichever page was on screen.
   Rows the filter excluded stay excluded on paper, which is the point of filtering. */
.report-filters__paged-out { display: none !important; }

@media print {
    .report-filters__paged-out { display: table-row !important; }
}

/* ====== Report pager (built by js/report-filters.js) ================= */

.report-pager {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: var(--space-2) var(--space-3);
    margin-top: var(--space-2); padding-top: var(--space-2);
    border-top: 1px solid var(--line-soft);
}

.report-pager__info { font-size: var(--text-xs); font-weight: 600; color: var(--muted); }

.report-pager__nav { display: inline-flex; align-items: center; gap: var(--space-1); }
.report-pager__pages { display: inline-flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }

.report-pager__btn {
    min-width: 32px; height: 32px; padding: 0 var(--space-2);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--text-sm); font-weight: 600; line-height: 1;
    color: var(--ink-soft); background: var(--surface);
    border: 1px solid var(--line-soft); border-radius: var(--radius-xs);
    cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease;
}

/* Rendered as <a> by the server pager and <button> by the client one — both look the same. */
a.report-pager__btn { text-decoration: none; }
.report-pager__btn:hover:not(:disabled):not(.is-current):not(.is-disabled) { background: var(--brand-50); border-color: var(--brand-200); }
.report-pager__btn:disabled, .report-pager__btn.is-disabled { opacity: .45; cursor: default; }

.report-pager__btn.is-current {
    color: #fff; background: var(--primary); border-color: var(--primary); cursor: default;
}

.report-pager__gap { padding: 0 2px; color: var(--muted); font-size: var(--text-sm); }

.report-pager__size { display: inline-flex; align-items: center; gap: var(--space-2); }
.report-pager__size-label { font-size: var(--text-xs); font-weight: 600; color: var(--muted); white-space: nowrap; }
.report-pager__size select { width: auto; min-width: 74px; }

tr.report-filters__empty > td, .report-filters__empty-list {
    padding: var(--space-5) var(--space-4); text-align: center; font-style: italic; color: var(--muted); font-size: var(--text-sm);
}
.table-premium tbody tr.report-filters__empty:hover { background: none; }
/* the injected empty row is structurally last, so hand its borderless-last-row
   treatment back to the last real row */
.table-premium tbody tr:has(+ tr.report-filters__empty) td { border-bottom: none; }

/* Totals recomputed over the visible rows only — flagged so a filtered footer is never
   read as the report's grand total. */
.table-premium tfoot.is-filtered td, table.dataTable tfoot.is-filtered td {
    box-shadow: inset 0 2px 0 var(--brand-300);
}

/* Printed under the report so a filtered page explains itself on paper. */
.report-filters__applied { font-size: var(--text-xs); font-weight: 600; color: var(--muted); margin-bottom: var(--space-2); }
.report-filters__applied:empty { display: none !important; }

/* A running-balance column pauses while a filter hides rows — every figure in it is the one above
   plus this row's movement, so a hidden row makes the column step by an amount that isn't on
   screen. !important beats the .fw-semibold/.amount-neg the cell was rendered with; the figure
   itself is held on the cell and comes straight back when the filter is cleared. */
.report-filters__paused { color: var(--muted) !important; font-weight: 400 !important; font-style: italic; }

.report-filters__lock {
    display: flex; align-items: flex-start; gap: var(--space-2);
    margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
    background: var(--warning-soft); border: 1px solid #fcd9a0; border-radius: var(--radius-sm);
    font-size: var(--text-sm); line-height: 1.45; color: #8a5a09;
}
.report-filters__lock::before { content: "⚠"; line-height: 1.35; }

html[data-theme="dark"] .report-filters__lock { background: #3a2c10; border-color: #6b5320; color: #fcd34d; }

html[data-theme="dark"] .report-filters.is-filtered { border-color: var(--brand-100); }
html[data-theme="dark"] .report-filters__count.is-filtered { color: var(--brand-300); border-color: var(--brand-100); }

/* ====== Searchable picker (combobox) ==================================
   Upgrades a long <select> into a type-to-filter control. The native <select>
   stays in the DOM as the posted value, so model binding and jQuery-validation
   keep working untouched — it is only moved out of sight (1×1, not display:none,
   because unobtrusive validation skips fields it considers hidden).           */
.picker { position: relative; }
.picker__native {
    position: absolute; left: 0; bottom: 0; width: 1px; height: 1px;
    opacity: 0; pointer-events: none; border: 0; padding: 0; margin: 0;
}
.picker__control { position: relative; }
.picker__input { padding-right: var(--space-10); cursor: text; text-overflow: ellipsis; }
.picker__caret {
    position: absolute; right: 13px; top: 50%; transform: translateY(-50%);
    font-size: var(--text-sm); color: var(--muted-2); pointer-events: none; transition: transform .15s ease;
}
.picker.is-open .picker__caret { transform: translateY(-50%) rotate(180deg); }
.picker__clear {
    position: absolute; right: 32px; top: 50%; transform: translateY(-50%);
    border: 0; background: transparent; color: var(--muted-2); font-size: var(--text-sm);
    line-height: 1; padding: var(--space-1); border-radius: var(--radius-xs); cursor: pointer; display: none;
}
.picker.has-value .picker__clear { display: block; }
.picker__clear:hover { color: var(--danger); background: var(--danger-soft); }

.picker__menu {
    position: absolute; z-index: 1080; left: 0; right: 0; top: calc(100% + 5px);
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md); padding: var(--space-1); max-height: 280px; overflow-y: auto;
    animation: menuIn .13s ease;
}
.picker__menu[hidden] { display: none; }
/* A picker inside a modal/offcanvas can be clipped by the parent's overflow;
   the menu is short enough that flipping it above the field is the better fix. */
.picker.is-up .picker__menu { top: auto; bottom: calc(100% + 5px); }

.picker__option {
    display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-xs); font-size: var(--text-md); color: var(--ink); cursor: pointer;
}
.picker__option-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker__option-tick { font-size: var(--text-sm); color: var(--brand-600); visibility: hidden; }
.picker__option[aria-selected="true"] .picker__option-tick { visibility: visible; }
.picker__option.is-active { background: var(--brand-50); }
.picker__option.is-disabled { opacity: .45; cursor: not-allowed; }
.picker__note { padding: var(--space-4) var(--space-3); text-align: center; font-size: var(--text-sm); color: var(--muted); }
.picker__note i { display: block; font-size: var(--text-3xl); color: var(--muted-2); margin-bottom: var(--space-1); }

html[data-theme="dark"] .picker__option.is-active { background: #1d2541; }
html[data-theme="dark"] .picker__option-tick { color: var(--brand-300); }

/* ====== Busy submit buttons ===========================================
   A form that is on its way to the server disables its submit control and says
   so. In an app that posts money this is not decoration: a second click on
   "Generate receipt" is a second receipt, a second journal and doubled cash.  */
.btn.is-busy { pointer-events: none; opacity: .72; }
/* the spinner stands in for the button's own icon while the post is in flight */
.btn.is-busy > i { display: none; }
.btn.is-busy > .btn-spinner {
    display: inline-block; width: 13px; height: 13px; margin-right: var(--space-2);
    vertical-align: -2px; border: 2px solid currentColor; border-right-color: transparent;
    border-radius: 50%; animation: btnSpin .6s linear infinite;
}
@keyframes btnSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .btn.is-busy > .btn-spinner { animation-duration: 2s; }
    .picker__menu { animation: none; }
}

/* ====== Action inbox (topbar bell) ====================================
   The bell reports work that is actually waiting on this user — a mobile receipt
   nobody approved, a refund nobody released — rather than the fixed "all caught
   up" placeholder it used to show. Filled by initActionInbox() in chitpro.js.  */
.notif-menu { min-width: 340px; }
.notif-menu__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.notif-menu__loading { padding: var(--space-5) var(--space-4); text-align: center; color: var(--muted); font-size: var(--text-sm); }
.notif-menu__loading .btn-spinner {
    display: inline-block; width: 13px; height: 13px; margin-right: var(--space-2); vertical-align: -2px;
    border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
    animation: btnSpin .6s linear infinite;
}

.inbox__btn { position: relative; overflow: visible; }
.inbox__badge {
    position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 var(--space-1);
    border-radius: var(--radius-xs); background: var(--danger); color: #fff; border: 2px solid var(--card);
    font-size: var(--text-2xs); font-weight: 700; line-height: 14px; text-align: center;
}
.inbox__badge[hidden] { display: none; }

.inbox__refresh {
    border: 0; background: transparent; color: var(--muted-2); font-size: var(--text-sm);
    padding: 3px var(--space-1); border-radius: var(--radius-xs); cursor: pointer; line-height: 1;
}
.inbox__refresh:hover { background: var(--surface); color: var(--ink-soft); }
.inbox__refresh.is-spinning i { display: inline-block; animation: btnSpin .7s linear infinite; }

.inbox__list { max-height: min(60vh, 420px); overflow-y: auto; padding: var(--space-1); }
.inbox__list[hidden] { display: none; }
.inbox__row {
    display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm); color: var(--ink); text-decoration: none;
}
.inbox__row:hover { background: var(--surface); color: var(--ink); }
.inbox__row-icon {
    width: 34px; height: 34px; flex: 0 0 34px; border-radius: var(--radius-sm);
    display: grid; place-items: center; font-size: var(--text-lg);
}
.inbox__row-body { flex: 1 1 auto; min-width: 0; }
.inbox__row-label { font-size: var(--text-sm); font-weight: 600; }
.inbox__row-hint { font-size: var(--text-xs); color: var(--muted-2); margin-top: 1px; }
.inbox__row-count {
    flex: 0 0 auto; min-width: 26px; height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-xs);
    font-size: var(--text-xs); font-weight: 700; display: grid; place-items: center;
}
.inbox__row--danger  .inbox__row-icon { background: var(--danger-soft);  color: var(--danger); }
.inbox__row--warning .inbox__row-icon { background: var(--warning-soft); color: var(--warning); }
.inbox__row--info    .inbox__row-icon { background: var(--brand-50);     color: var(--brand-600); }
.inbox__row--danger  .inbox__row-count { background: var(--danger-soft);  color: var(--danger); }
.inbox__row--warning .inbox__row-count { background: var(--warning-soft); color: var(--warning); }
.inbox__row--info    .inbox__row-count { background: var(--brand-50);     color: var(--brand-600); }

html[data-theme="dark"] .inbox__badge { border-color: var(--card); }
html[data-theme="dark"] .inbox__row:hover { background: #1d2541; }
html[data-theme="dark"] .inbox__refresh:hover { background: #1d2541; }
html[data-theme="dark"] .inbox__row--info .inbox__row-icon,
html[data-theme="dark"] .inbox__row--info .inbox__row-count { color: var(--brand-300); }

/* ====== Registers: figures, filter bars, sticky headers ================ */
/* Money has to line up column to column or a register is unreadable at a glance, so every figure on
   a data surface asks Inter for its tabular figures. Scoped to tables and stat values rather than
   set on body, because running prose still reads better with proportional ones. */
.table-premium tbody td,
.table-premium tfoot td,
table.dataTable tbody td,
table.dataTable tfoot td { font-variant-numeric: tabular-nums; }

/* A filter row reads as one control surface rather than three loose widgets adrift on the page. */
.filter-bar {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
    background: var(--card);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-xs);
    padding: var(--space-2) var(--space-3);
}
.filter-bar__label {
    font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--muted-2); padding-right: 2px;
}
.filter-bar .form-select, .filter-bar .form-control { border-radius: var(--radius-xs); }
.filter-bar .form-check { margin-bottom: 0; }
.filter-bar__sep { width: 1px; align-self: stretch; background: var(--line-soft); margin: 1px 2px; }

/* ---- Statement filters: two tiers, one surface -------------------------------
   The top row decides which transactions are READ out of the ledger; the bottom row which of those
   are SHOWN. Only the top one can move a closing balance, so they are drawn as two rows of one card
   divided by a rule — near enough to read as one control surface, separate enough that the division
   is visible. Bootstrap's full-width form controls are overridden here for the same reason as in
   .list-toolbar: as flex items they would each claim a row of their own. */
.stmt-filters__row { display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--space-2); }
.stmt-filters__row--narrow {
    align-items: center;
    margin-top: var(--space-3); padding-top: var(--space-3);
    border-top: 1px solid var(--line-soft);
}
.stmt-filters__row .filter-bar__label { padding-bottom: var(--space-2); }   /* drop to the control's baseline, not the label's */
.stmt-filters__row--narrow .filter-bar__label { padding-bottom: 0; }
/* The General Ledger and the Day Book set their period in their own toolbars, so the narrow row is a
   card of its own there. The divider exists to separate it from a period row above it; with nothing
   above, it would read as a stray line across the top of the card. */
.stmt-filters__row--narrow:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.stmt-filters__row .form-select,
.stmt-filters__row .form-control { width: auto; max-width: 100%; border-radius: var(--radius-xs); }
.stmt-filters__row .form-select { max-width: 260px; }

.stmt-presets { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.stmt-preset {
    display: inline-flex; align-items: center; padding: var(--space-2) var(--space-3);
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    background: var(--card); color: var(--ink-soft);
    font-size: var(--text-xs); font-weight: 600; text-decoration: none; white-space: nowrap;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.stmt-preset:hover { background: var(--brand-50); border-color: var(--brand-200); color: var(--brand-700); }
.stmt-preset.is-active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

/* Min and max are one question, so they are drawn as one control: the rupee sign is stated once and
   the focus ring lands on the pair rather than on whichever box was clicked. */
.stmt-range {
    display: inline-flex; align-items: center; gap: var(--space-1);
    border: 1px solid var(--line); border-radius: var(--radius-xs);
    background: var(--card); padding: 0 var(--space-2);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.stmt-range:focus-within { border-color: var(--brand-400); box-shadow: 0 0 0 4px var(--brand-100); }
.stmt-range__label { font-size: var(--text-sm); font-weight: 600; color: var(--muted-2); }
.stmt-range__dash { color: var(--muted-2); }
.stmt-range .form-control {
    width: 96px; border: 0; background: transparent; padding-left: 2px; padding-right: 2px;
    box-shadow: none !important;
}
.stmt-search { min-width: 200px; }

/* What is narrowing the rows, and the one click that lifts each. A filter nobody can see is a filter
   somebody will read a total through. */
.stmt-chips { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.chip--clear { text-decoration: none; gap: var(--space-2); transition: background .15s ease, color .15s ease; }
.chip--clear i { font-size: 9px; opacity: .6; }
.chip--clear:hover { background: var(--danger-soft); color: var(--danger); }
.chip--clear:hover i { opacity: 1; }
.stmt-chips__count { font-size: var(--text-xs); font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.stmt-chips__reset { font-size: var(--text-xs); font-weight: 600; }

/* One number is usually the reason anyone opened a page like this. The hero card gives it the room
   and the tiles beside it stay legible without competing for the same weight. */
.stat-card--hero { padding: var(--space-5) var(--space-6); height: 100%; }
.stat-card--hero::before {
    content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 4px;
    background: linear-gradient(180deg, var(--danger), #fb923c);
}
.stat-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.stat-card--hero .stat-card__icon { margin-bottom: 0; width: 52px; height: 52px; font-size: var(--text-3xl); }
.stat-card--hero .stat-card__value { font-size: var(--text-5xl); line-height: 1.05; margin: var(--space-2) 0 var(--space-2); }
.stat-card__facts { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); }
.stat-card__fact { font-size: var(--text-xs); color: var(--muted); font-weight: 600; }
.stat-card__fact b { color: var(--ink-soft); font-weight: 700; font-variant-numeric: tabular-nums; }

.stat-card--tile { padding: var(--space-4); height: 100%; }
.stat-card--tile .stat-card__icon { width: 34px; height: 34px; font-size: var(--text-xl); border-radius: var(--radius-sm); margin-bottom: var(--space-2); }
.stat-card--tile .stat-card__value { font-size: var(--text-3xl); margin: 2px 0 var(--space-1); }
.stat-card--tile .stat-card__trend { display: block; font-size: var(--text-xs); line-height: 1.35; }

/* A 50-row page of a register runs several screens deep, and the column labels are the only thing
   that makes row 40 readable. Sticky resolves against the nearest scrollport, so this works only
   while nothing between the table and the page establishes one — which is why .table-sticky REPLACES
   .table-responsive instead of sitting inside it, and takes the horizontal scroll back only on the
   narrow screens where the table genuinely cannot fit. */
.table-sticky { position: relative; }
.table-sticky .table-premium thead th {
    position: sticky; top: var(--topbar-h); z-index: 5;
    background: var(--surface);
    box-shadow: 0 1px 0 var(--line), 0 10px 14px -14px rgba(16, 24, 40, .55);
}
@media (max-width: 1199.98px) {
    .table-sticky { overflow-x: auto; }
}
@media print {
    .table-sticky { overflow: visible; }
    .table-sticky .table-premium thead th { position: static; box-shadow: none; }
}

/* An absent value is not a value: it stays quiet rather than reading as data. */
.cell-empty { color: var(--muted-2); }

/* A status pill earns its colour twice — once in the fill, once in a dot that survives a mono print. */
.badge-dot { display: inline-flex; align-items: center; gap: var(--space-1); }
.badge-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 6px; }

/* ====== Touch targets ================================================== */
/* 36-40px is comfortable under a mouse and too small under a finger. Every platform guideline puts
   the floor at 44px, and ChitPro installs as a PWA, so on a coarse pointer the row actions, the
   topbar icons and the pager buttons all grow to it. Behind the media query on purpose: the dense
   desktop register should not pay for a phone. */
@media (pointer: coarse) {
    .action-btn,
    .rowmenu__btn,
    .icon-btn,
    .theme-toggle,
    .color-scheme-btn { width: 44px; height: 44px; }
    .report-pager__btn { min-width: 44px; height: 44px; }
    .form-check-input { width: 22px; height: 22px; }
}

/* ===================================================================================
   Chit Ticket Register
   A 14-column per-ticket register: denser rows, a ticket chip, and three link colours
   that say where a figure goes — prize register, collection screen, arrears.
   =================================================================================== */
.table-compact tbody td { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }
.table-compact thead th { padding: var(--space-2) var(--space-3); }

/* A cancelled ticket still carries real arrears, so it stays in the register rather than being
   dropped — tinted instead, so it never reads as a live ticket. */
.row-cancelled td { background: var(--warning-soft); }
.table-premium tbody tr.row-cancelled:hover td { background: var(--warning-soft); filter: brightness(.98); }

.ticket-chip {
    display: inline-grid; place-items: center; min-width: 26px; height: 26px; padding: 0 var(--space-2);
    border-radius: var(--radius-xs); background: var(--surface); border: 1px solid var(--line-soft);
    color: var(--ink-soft); font-weight: 700; font-size: var(--text-xs); font-variant-numeric: tabular-nums;
}

/* Never a zero: a ticket that has not won shows a word, so it can never be summed into the
   Payment total. */
.not-taken { color: var(--muted-2); font-style: italic; font-size: var(--text-xs); }

.link-prize, .link-coll, .link-due {
    font-weight: 600; text-decoration: none; border-bottom: 1px dashed transparent;
    font-variant-numeric: tabular-nums;
}
.link-prize { color: #b45309; border-bottom-color: var(--warning); }
.link-coll  { color: var(--brand-600); border-bottom-color: var(--brand-200); }
.link-due   { color: #b91c1c; border-bottom-color: var(--danger); }
.link-prize:hover, .link-coll:hover, .link-due:hover { border-bottom-style: solid; }

.badge-violet { background: #f3e8ff; color: #7e22ce; }

html[data-theme="dark"] .link-prize { color: #fcd34d; }
html[data-theme="dark"] .link-coll  { color: var(--brand-300); }
html[data-theme="dark"] .link-due   { color: #fca5a5; }
html[data-theme="dark"] .badge-violet { background: rgba(126, 34, 206, .18); color: #d8b4fe; }
html[data-theme="dark"] .ticket-chip { background: #222a44; border-color: transparent; }

/* On paper the link colours are noise and the row tint costs ink; keep only the cancelled
   row distinguishable, by rule rather than by fill. */
@media print {
    .link-prize, .link-coll, .link-due { color: var(--ink); border-bottom: none; }
    .row-cancelled td { background: none; border-top: 1px solid var(--ink-soft); }
}

/* ==========================================================================
   Account groups — the tree rows on Cash & Bank, Trial Balance, Balance Sheet
   --------------------------------------------------------------------------
   A group is a heading with a subtotal on it, never a real account, so it is
   drawn as a heading: tinted, bold, with a caret. Children carry an indent and
   a guide so the eye can follow which heading a row belongs to.

   Only ever applied to tables that are NOT sorted, searched or paginated in the
   browser. A tree whose rows the browser can reorder or hide is a tree that will
   eventually print a subtotal above rows that are not its own — the Chart of
   Accounts is a DataTable for exactly that reason and shows its hierarchy in a
   column instead.
   ========================================================================== */
.table-premium tbody tr.acct-group > td,
.bs-table tbody tr.acct-group > td {
    background: var(--brand-50);
    border-top: 1px solid var(--brand-200);
    border-bottom: 1px solid var(--brand-100);
}
.table-premium tbody tr.acct-group:hover > td { background: var(--brand-100); }

.acct-group__name {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-weight: 700; color: var(--brand-800); letter-spacing: -.005em;
}
.acct-group__total { font-weight: 700; color: var(--brand-800); }

/* The caret is a button so the group is reachable by keyboard, not just by mouse. */
.acct-group__toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; padding: 0; flex: 0 0 auto;
    background: none; border: 0; border-radius: var(--radius-sm);
    color: var(--brand-600); cursor: pointer;
}
.acct-group__toggle:hover { background: var(--brand-200); }
.acct-group__toggle:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 1px; }
.acct-group__toggle::before {
    content: ""; width: 0; height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent; border-bottom: 4px solid transparent;
    transform: rotate(90deg); transition: transform .15s ease;
}
.acct-group.is-collapsed .acct-group__toggle::before,
.acct-parent.is-collapsed .acct-group__toggle::before { transform: rotate(0deg); }

/* A REAL account that heads others. Deliberately not styled like a heading: it is an ordinary
   row that happens to have a caret, because it still holds its own money, still opens a
   statement and is still posted to. Only the subtotal beside its name marks it out. */
.acct-parent__rollup {
    margin-left: var(--space-2); padding-left: var(--space-2);
    border-left: 1px solid var(--border);
    color: var(--brand-700); font-variant-numeric: tabular-nums;
}

/* Indent + guide. The guide stops halfway down the last child so the line ends at the
   row it belongs to rather than running on past the group. */
.table-premium tbody tr.acct-child > td:first-child,
.bs-table tbody tr.acct-child > td:first-child { position: relative; padding-left: 34px; }
.table-premium tbody tr.acct-child > td:first-child::before,
.bs-table tbody tr.acct-child > td:first-child::before {
    content: ""; position: absolute; left: 14px; top: 0; bottom: 0;
    border-left: 1px solid var(--line);
}
.table-premium tbody tr.acct-child > td:first-child::after,
.bs-table tbody tr.acct-child > td:first-child::after {
    content: ""; position: absolute; left: 14px; top: 50%; width: 11px;
    border-top: 1px solid var(--line);
}
.table-premium tbody tr.acct-child--last > td:first-child::before,
.bs-table tbody tr.acct-child--last > td:first-child::before { bottom: 50%; }

/* Depth 2+ — rare, but a tree that silently flattens past one level is a lie. */
.table-premium tbody tr.acct-child--d2 > td:first-child { padding-left: 54px; }
.table-premium tbody tr.acct-child--d2 > td:first-child::before { left: 34px; }
.table-premium tbody tr.acct-child--d2 > td:first-child::after { left: 34px; }
.table-premium tbody tr.acct-child--d3 > td:first-child { padding-left: 74px; }
.table-premium tbody tr.acct-child--d3 > td:first-child::before { left: 54px; }
.table-premium tbody tr.acct-child--d3 > td:first-child::after { left: 54px; }

/* Narrowed view: the tree stops being a tree.
   A filter hides rows by predicate, so a group can keep its heading while losing most of its
   children — leaving an indent and a guide pointing at a parent that is no longer on screen, under
   a subtotal for rows the reader cannot see. Rather than pretend, the structure steps aside while a
   filter is active: headings are hidden and children un-indent, so a narrowed report reads as what
   it actually is — a flat list of the rows that matched. Clearing the filter restores the tree. */
.table-premium.is-tree-flat tbody tr.acct-group,
.bs-table.is-tree-flat tbody tr.acct-group { display: none; }
.table-premium.is-tree-flat tbody tr.acct-child > td:first-child,
.bs-table.is-tree-flat tbody tr.acct-child > td:first-child { padding-left: var(--space-4); }
.table-premium.is-tree-flat tbody tr.acct-child > td:first-child::before,
.table-premium.is-tree-flat tbody tr.acct-child > td:first-child::after,
.bs-table.is-tree-flat tbody tr.acct-child > td:first-child::before,
.bs-table.is-tree-flat tbody tr.acct-child > td:first-child::after { display: none; }

html[data-theme="dark"] .table-premium tbody tr.acct-group > td,
html[data-theme="dark"] .bs-table tbody tr.acct-group > td {
    background: rgba(99, 102, 241, .14);
    border-top-color: rgba(99, 102, 241, .34);
    border-bottom-color: rgba(99, 102, 241, .18);
}
html[data-theme="dark"] .table-premium tbody tr.acct-group:hover > td { background: rgba(99, 102, 241, .22); }
html[data-theme="dark"] .acct-group__name,
html[data-theme="dark"] .acct-group__total { color: var(--brand-300); }
html[data-theme="dark"] .acct-group__toggle { color: var(--brand-300); }
html[data-theme="dark"] .acct-group__toggle:hover { background: rgba(99, 102, 241, .28); }

/* On paper: keep the structure, drop the fill. A collapsed group still prints its children —
   a printed statement that silently omits rows because someone folded them on screen is a
   statement that does not tie. */
@media print {
    .table-premium tbody tr.acct-group > td,
    .bs-table tbody tr.acct-group > td {
        background: none;
        border-top: 1px solid var(--ink-soft);
        border-bottom: none;
    }
    .acct-group__name, .acct-group__total { color: var(--ink); }
    .acct-group__toggle { display: none; }
    tr.acct-child[hidden] { display: table-row !important; }
}

/* ====== Cash-flow matrix ================================================
   The cash book pivoted: rows are heads, columns are days. Three things have to stay put while a
   thirty-day month scrolls sideways — the head name, the position as on today, and the column
   headers — so all three are sticky. The two horizontal offsets are MEASURED by
   cash-flow-matrix.js, never written here: head names are as long as the tenant typed them.
   ======================================================================== */
.cfm-wrap {
    overflow: auto;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--shadow-sm);
    max-height: calc(100vh - 220px);
}
.cfm {
    --cfm-l2: 236px;
    --cfm-l3: 372px;
    border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%;
    font-variant-numeric: tabular-nums; font-size: var(--text-md);
}
.cfm th, .cfm td { white-space: nowrap; padding: var(--space-2) var(--space-3); }

.cfm thead th {
    position: sticky; top: 0; z-index: 4;
    background: var(--surface); color: var(--muted);
    font-size: var(--text-xs); font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; text-align: right;
    border-bottom: 1px solid var(--line); vertical-align: bottom;
}
.cfm thead th .cfm__dow { display: block; font-size: var(--text-2xs); font-weight: 600; letter-spacing: .06em; color: var(--muted-2); }
.cfm thead th .cfm__dom { display: block; font-size: var(--text-md); font-weight: 700; letter-spacing: 0; color: var(--ink-soft); text-transform: none; }
.cfm thead th.is-sunday .cfm__dom, .cfm thead th.is-sunday .cfm__dow { color: var(--danger); }
.cfm thead th.is-future .cfm__dom, .cfm thead th.is-future .cfm__dow { opacity: .5; }
/* Where the posted figures stop. Without it the reader counts stripes to find today. */
.cfm thead th.is-today { background: var(--brand-50); box-shadow: inset 0 -3px 0 var(--brand-500); }
.cfm thead th.is-today .cfm__dom { color: var(--brand-700); }

.cfm .c-head { position: sticky; left: 0;             z-index: 3; min-width: 236px; text-align: left; }
.cfm .c-ason { position: sticky; left: var(--cfm-l2); z-index: 3; min-width: 136px; }
.cfm .c-fcst { position: sticky; left: var(--cfm-l3); z-index: 3; min-width: 112px; border-right: 2px solid var(--line); }
.cfm thead .c-head, .cfm thead .c-ason, .cfm thead .c-fcst { z-index: 6; }
.cfm tbody .c-head, .cfm tbody .c-ason, .cfm tbody .c-fcst { background: var(--card); }
/* "As on" is the figure quoted out of this sheet in a meeting — it gets the accent. */
.cfm .c-ason { background: #fffaf0 !important; font-weight: 650; }
.cfm thead .c-ason { background: var(--warning-soft) !important; color: #b45309; }
.cfm thead .c-ason small { display: block; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0; text-transform: none; }
.cfm .c-fcst { color: var(--muted); }

.cfm td.n { text-align: right; border-bottom: 1px solid var(--line-soft); }
.cfm td.n.is-neg { color: var(--danger); }
.cfm td.nil { color: var(--muted-2); }
/* A day that has not happened yet is blank, not zero — it was never counted.
   background-IMAGE, never the shorthand: the hatch has to composite over whatever colour the row
   already set. As a shorthand it out-specifies .cfm-row--closing (three classes to two) and wipes the
   band out from under its own white text, which renders the closing balance invisible on every future
   day — the one figure a reader looks forward to find. */
.cfm td.n.is-future { background-image: repeating-linear-gradient(135deg, transparent, transparent 6px, rgba(148,163,184,.10) 6px, rgba(148,163,184,.10) 12px); }
.cfm tr.cfm-row--closing td.n.is-future { background-image: repeating-linear-gradient(135deg, transparent, transparent 6px, rgba(255,255,255,.10) 6px, rgba(255,255,255,.10) 12px); }
.cfm tbody tr:hover td { background: var(--brand-50); }
.cfm tbody tr:hover td.c-ason { background: #fdf0d5 !important; }

.cfm tr.cfm-row--closing td { background: var(--brand-800); color: #fff; font-weight: 700; border-bottom: none; }
.cfm tr.cfm-row--closing td.c-ason { background: var(--brand-900) !important; color: #fff; }
.cfm tr.cfm-row--closing td.is-neg { color: #fca5a5; }
.cfm tr.cfm-row--closing:hover td { background: var(--brand-800); }
.cfm tr.cfm-row--closing:hover td.c-ason { background: var(--brand-900) !important; }

.cfm tr.cfm-row--net td { background: #eef1f6; font-weight: 650; color: var(--ink-soft); }
.cfm tr.cfm-row--net td.c-ason { background: #ece9dd !important; }
.cfm tr.cfm-row--net:hover td { background: #e6eaf1; }

.cfm tr.cfm-row--opening td { background: var(--success-soft); font-weight: 650; color: #065f46; }
.cfm tr.cfm-row--opening td.c-ason { background: #cfeddd !important; }
.cfm tr.cfm-row--opening:hover td { background: #c6f0de; }

.cfm tr.cfm-row--in td { background: #ecfdf5; font-weight: 700; color: #047857; border-top: 1px solid var(--line); }
.cfm tr.cfm-row--in td.c-ason { background: #e3f6e5 !important; }
.cfm tr.cfm-row--out td { background: #fff1f2; font-weight: 700; color: #b91c1c; border-top: 1px solid var(--line); }
.cfm tr.cfm-row--out td.c-ason { background: #fbeade !important; }

.cfm td.c-head { color: var(--ink-soft); }
.cfm tr.cfm-row--leaf td.c-head { padding-left: var(--space-6); font-weight: 500; }
.cfm__tag {
    font-size: var(--text-2xs); font-weight: 700; color: var(--muted-2);
    border: 1px solid var(--line); border-radius: var(--radius-xs);
    padding: 0 5px; margin-left: var(--space-2); text-transform: uppercase;
}
.cfm tr.cfm-row--quiet td.c-head { color: var(--muted); }

.cfm-months { display: flex; gap: var(--space-1); flex-wrap: wrap; align-items: center; }
.cfm-months a {
    font-size: var(--text-md); font-weight: 650; color: var(--muted);
    padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill);
    border: 1px solid transparent; font-variant-numeric: tabular-nums;
}
.cfm-months a:hover { background: var(--brand-50); color: var(--brand-700); }
.cfm-months a.is-active { background: var(--brand-600); color: #fff; box-shadow: 0 6px 14px -6px rgba(79,70,229,.7); }

html[data-theme="dark"] .cfm thead th.is-today { background: rgba(99,102,241,.2); }
html[data-theme="dark"] .cfm thead th.is-today .cfm__dom { color: var(--brand-300); }
html[data-theme="dark"] .cfm .c-ason { background: #2a2416 !important; }
html[data-theme="dark"] .cfm thead .c-ason { background: #3a3118 !important; color: var(--warning); }
html[data-theme="dark"] .cfm tbody tr:hover td.c-ason { background: #342c1a !important; }
html[data-theme="dark"] .cfm tr.cfm-row--net td { background: #1b2033; color: var(--ink-soft); }
html[data-theme="dark"] .cfm tr.cfm-row--net td.c-ason { background: #2b2a24 !important; }
html[data-theme="dark"] .cfm tr.cfm-row--net:hover td { background: #212741; }
html[data-theme="dark"] .cfm tr.cfm-row--opening td { background: rgba(16,185,129,.16); color: #6ee7b7; }
html[data-theme="dark"] .cfm tr.cfm-row--opening td.c-ason { background: rgba(16,185,129,.24) !important; }
html[data-theme="dark"] .cfm tr.cfm-row--opening:hover td { background: rgba(16,185,129,.24); }
html[data-theme="dark"] .cfm tr.cfm-row--in td { background: rgba(16,185,129,.12); color: #6ee7b7; }
html[data-theme="dark"] .cfm tr.cfm-row--in td.c-ason { background: rgba(16,185,129,.2) !important; }
html[data-theme="dark"] .cfm tr.cfm-row--out td { background: rgba(239,68,68,.12); color: #fca5a5; }
html[data-theme="dark"] .cfm tr.cfm-row--out td.c-ason { background: rgba(239,68,68,.2) !important; }
html[data-theme="dark"] .cfm tr.cfm-row--closing td { background: var(--brand-700); }
html[data-theme="dark"] .cfm tr.cfm-row--closing td.c-ason { background: var(--brand-800) !important; }
html[data-theme="dark"] .cfm tr.cfm-row--closing:hover td { background: var(--brand-700); }

/* On paper the sticky columns become ordinary ones: a fixed cell painted over a scrolled page is a
   browser-window trick, and the printer has no window to scroll. */
@media print {
    .cfm-wrap { max-height: none; overflow: visible; border: none; box-shadow: none; }
    .cfm thead th, .cfm .c-head, .cfm .c-ason, .cfm .c-fcst { position: static; }
    .cfm { font-size: var(--text-xs); }
    .cfm th, .cfm td { padding: 3px var(--space-2); }
    .cfm td.n.is-future, .cfm tr.cfm-row--closing td.n.is-future { background-image: none; }
}

/* ====== Conveyance: the approval route and a claim's audit trail ======================================
   A claim climbs a route of levels (reporting manager → … → accounts). The stepper shows where it is and
   who has stood at each rung; the trail is the append-only account of everything done to it. */
.route-stepper { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.route-step {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
    background: var(--line-soft); color: var(--muted);
    font-size: var(--text-md); font-weight: 600; line-height: 1.25;
}
.route-step small { display: block; font-size: var(--text-xs); font-weight: 500; opacity: .9; }
.route-step.is-done { background: var(--success-soft); color: #047857; }
.route-step.is-current { background: var(--brand-600); color: #fff; }
.route-step.is-stopped { background: var(--danger-soft); color: #b91c1c; }
.route-step.is-sent-back { background: var(--warning-soft); color: #b45309; }
.route-arrow { color: var(--muted-2); font-size: var(--text-xs); }

.trail-item { display: flex; gap: var(--space-3); margin-bottom: var(--space-4); }
.trail-item:last-child { margin-bottom: 0; }
.trail-dot {
    width: 28px; height: 28px; border-radius: 50%; flex: none;
    display: inline-flex; align-items: center; justify-content: center; font-size: var(--text-sm);
    background: var(--brand-50); color: var(--brand-600);
}
.trail-dot.is-ok { background: var(--success-soft); color: #047857; }
.trail-dot.is-no { background: var(--danger-soft); color: #b91c1c; }
.trail-dot.is-warn { background: var(--warning-soft); color: #b45309; }

html[data-theme="dark"] .route-step { background: rgba(148,163,184,.12); }
html[data-theme="dark"] .route-step.is-done { background: rgba(16,185,129,.16); color: #6ee7b7; }
html[data-theme="dark"] .route-step.is-stopped { background: rgba(239,68,68,.16); color: #fca5a5; }
html[data-theme="dark"] .route-step.is-sent-back { background: rgba(245,158,11,.16); color: #fcd34d; }
html[data-theme="dark"] .trail-dot { background: rgba(99,102,241,.2); color: var(--brand-300); }
html[data-theme="dark"] .trail-dot.is-ok { background: rgba(16,185,129,.18); color: #6ee7b7; }
html[data-theme="dark"] .trail-dot.is-no { background: rgba(239,68,68,.18); color: #fca5a5; }
html[data-theme="dark"] .trail-dot.is-warn { background: rgba(245,158,11,.18); color: #fcd34d; }

/* ==========================================================================
   Hold-draw page (pooled-draw schemes) — Pages/Operations/Auctions/Draw.cshtml
   ========================================================================== */
.draw-pick { border: 1px solid var(--line-soft); border-radius: var(--radius-sm); max-height: 340px; overflow: auto; }
.draw-pick table { margin: 0; }
.draw-pick tbody tr { cursor: pointer; }
.draw-pick tbody tr.is-company { cursor: default; }
.draw-pick tbody tr.is-picked { background: var(--brand-50); }
.draw-pick tbody tr.is-picked td:first-child { box-shadow: inset 3px 0 0 var(--primary); }
.draw-pick .form-check-input { cursor: pointer; }
.draw-count { display: inline-flex; align-items: baseline; gap: var(--space-2); }
.draw-count__n { font-size: var(--text-4xl); font-weight: 730; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.draw-sum { display: flex; justify-content: space-between; align-items: baseline; padding: var(--space-2) 0; }
.draw-sum__v { font-weight: 650; font-variant-numeric: tabular-nums; }
.draw-sum--short .draw-sum__v, .draw-sum--short span:first-child { color: #b45309; }
html[data-theme="dark"] .draw-sum--short .draw-sum__v, html[data-theme="dark"] .draw-sum--short span:first-child { color: #fcd34d; }

/* ====== Branch switcher (topbar) ======================================= */
/* Pick a branch once and every list and report narrows to it — see _BranchSwitcher.cshtml. Neutral while
   the whole company is in view; tinted the moment a branch is picked, because a narrowed screen that looks
   like the normal one is how "where did my members go?" calls start. */
.branch-switch {
    display: flex; align-items: center; gap: var(--space-2);
    height: 40px; padding: 0 var(--space-3); border-radius: var(--radius-sm);
    border: 1px solid var(--line); background: #fff; color: var(--ink-soft);
    cursor: pointer; font-family: inherit; text-align: left;
    transition: background .15s, border-color .15s;
}
.branch-switch:hover { background: var(--surface); border-color: var(--brand-200); }
.branch-switch > i:first-child { font-size: var(--text-lg); color: var(--muted); }
.branch-switch__text { display: block; min-width: 0; }
.branch-switch__label { display: block; font-size: var(--text-2xs); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); line-height: 1.1; }
.branch-switch__value { display: block; font-size: var(--text-sm); font-weight: 620; line-height: 1.2; white-space: nowrap; max-width: 170px; overflow: hidden; text-overflow: ellipsis; }
.branch-switch .bi-chevron-down { font-size: var(--text-xs); color: var(--muted-2); }
.branch-switch--on { background: var(--brand-50); border-color: var(--brand-200); color: var(--brand-800); }
.branch-switch--on > i:first-child, .branch-switch--on .branch-switch__label { color: var(--brand-600); }
.branch-switch--locked { cursor: default; }
.branch-switch--locked:hover { background: var(--brand-50); border-color: var(--brand-200); }

.branch-menu { min-width: 280px; padding: var(--space-2); border-radius: var(--radius-sm); border-color: var(--line); }
.branch-menu__head { font-size: var(--text-2xs); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); padding: var(--space-1) var(--space-2) var(--space-2); }
.branch-menu .dropdown-item { display: flex; align-items: center; gap: var(--space-2); border-radius: var(--radius-xs); padding: var(--space-2); font-size: var(--text-md); }
.branch-menu .dropdown-item code { margin-left: auto; font-size: var(--text-xs); color: var(--muted); background: var(--surface); padding: 1px 6px; border-radius: 6px; }
.branch-menu .dropdown-item .bi-check2 { color: var(--primary); visibility: hidden; }
.branch-menu .dropdown-item.is-current { background: var(--brand-50); color: var(--brand-800); font-weight: 600; }
.branch-menu .dropdown-item.is-current .bi-check2 { visibility: visible; }
.branch-menu__foot { font-size: var(--text-xs); color: var(--muted); padding: var(--space-2) var(--space-2) var(--space-1); border-top: 1px solid var(--line-soft); margin-top: var(--space-1); }

/* The one-line reminder on a page the switcher narrowed (and its neutral twin on reports that can't be). */
.branch-scope {
    display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    padding: var(--space-2) var(--space-3); margin-bottom: var(--space-4);
    border: 1px solid var(--brand-200); background: var(--brand-50); color: var(--brand-800);
    border-radius: var(--radius-sm); font-size: var(--text-sm);
}
.branch-scope > span { flex: 1 1 220px; min-width: 0; }   /* icon and sentence stay on one line; the link wraps */
.branch-scope i { color: var(--brand-600); }
.branch-scope a { margin-left: auto; color: var(--brand-700); font-weight: 600; text-decoration: none; }
.branch-scope a:hover { text-decoration: underline; }
.branch-scope--company { border-color: var(--line); background: var(--card); color: var(--muted); }
.branch-scope--company i { color: var(--muted); }

html[data-theme="dark"] .branch-switch { background: var(--card); color: var(--ink-soft); }
html[data-theme="dark"] .branch-switch:hover { background: #1d2541; }
html[data-theme="dark"] .branch-switch--on,
html[data-theme="dark"] .branch-switch--locked:hover { background: var(--brand-50); border-color: var(--brand-400); color: var(--brand-300); }
html[data-theme="dark"] .branch-switch--on > i:first-child,
html[data-theme="dark"] .branch-switch--on .branch-switch__label { color: var(--brand-300); }
html[data-theme="dark"] .branch-menu .dropdown-item.is-current { color: var(--brand-300); }
html[data-theme="dark"] .branch-scope { border-color: var(--brand-400); color: var(--ink); }
html[data-theme="dark"] .branch-scope i, html[data-theme="dark"] .branch-scope a { color: var(--brand-300); }
html[data-theme="dark"] .branch-scope--company { border-color: var(--line); color: var(--muted); }
html[data-theme="dark"] .branch-scope--company i { color: var(--muted); }

/* Phone width: the icon alone (tinted when a branch is picked) — the scope line under the bar names it. */
@media (max-width: 768px) {
    .branch-switch { width: 40px; padding: 0; justify-content: center; }
    .branch-switch__text, .branch-switch .bi-chevron-down { display: none; }
}

/* Phone width: the topbar already ran ~140px past a 375px screen (breadcrumb + subtitle + four controls)
   before the switcher joined it. The breadcrumb and subtitle are the expendable part on a phone; the
   title keeps its line and truncates rather than pushing the controls off the edge. */
@media (max-width: 576px) {
    .topbar { gap: var(--space-2); }
    .topbar .crumbs, .topbar__subtitle { display: none; }
    .topbar > div:has(> .topbar__title) { min-width: 0; flex: 0 1 auto; }
    .topbar__title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--text-xl); }
}
