/* ==========================================================================
   hub-theme.css - the hub's theme layer (core look)

   Loaded AFTER vendors.min.css, app.min.css and poppins.css and BEFORE custom.css,
   data-tables.css and hub-tables.css:
       vendors.min.css, app.min.css, poppins.css, hub-theme.css, custom.css,
       data-tables.css, hub-tables.css, then the per-page $pageStyles.

   What it is: the hub's Inspinia 4.0.1 (Bootstrap 5.3.8, variables --ins-*) re-skinned to
   the reference admin look. It is a port of the reference's own the reference stylesheet overlay onto the hub's
   tokens, plus the bridge pieces the hub needs (Poppins, --bs-* aliases, modern-skin parity,
   chrome helpers, toast, wide-table cue, Choices fix).

   Rules of the file
     * Component CSS here is skin-independent. Only section 3 is scoped to
       html[data-skin="modern"] (the skin the chrome switches the hub to).
     * Palette = reference as rendered: indigo #5e6cc1 buttons (from the modern skin), teal
       #1ab394 links / input focus / checkboxes, slate #23303c sidebar, #f7f6f7 page,
       white cards with a 1px #e7e9eb border and 10px radius. Re-tune everything from the
       --hub-* tokens in section 1.
     * No new brand strings. No dark mode (the hub has no toggle).
     * Deliberate differences from reference are commented where they occur: sidebar spacing and
       wrapping labels (section 5), select arrow room and input-group borders (section 11), the
       neutral wallet chips and the bell badge (section 5).
     * Not here: DataTables chrome (.dt-container ...) and the legacy-class aliases
       (.txn-table, .status-badge ...) - those live in hub-tables.css. The login look lives in
       hub-auth.css (auth layout only).

   Contents
     1  Tokens (--hub-*), --bs-* alias bridge, --role-accent defaults, typeface
     2  Base: small text, headings helper, transitions
     3  Modern-skin parity (values the reference's 5.0.0 theme has that the hub's 4.0.1 lacks)
     4  Modals
     5  Sidebar polish, topbar helpers (bell, wallet chips, count badges), content padding
     6  Cards, page title / breadcrumb, page-title actions
     7  Stat tiles
     8  Filter card, filter-bar button heights
     9  Tables: dark head, table-neo and its cell helpers, key/value table
    10  Pills, row-action buttons, soft-button repair
    11  Forms (labels, inputs, groups, file, checks, Choices)
    12  Tabs (house underline tabs, .svc-tabs)
    13  Pagination (non-DataTables)
    14  Alerts, empty state, progress, avatars, misc helpers
    15  Toast stack (.hub-toast-*)
    16  Wide-table scroll cue (.fin-x-*)
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
    /* ink / neutrals (darkest to lightest) */
    --hub-ink: #1d2939;              /* stat values, page title, form text */
    --hub-ink-2: #1f2a3d;            /* names, mobile numbers, amounts */
    --hub-label: #344054;            /* form labels */
    --hub-td: #3f4a5a;               /* table cell text */
    --hub-th: #5b6472;               /* table head text */
    --hub-muted: #626c80;            /* secondary ink, id-link, tabs, input-group addon. Was #667085 (4.4:1 on the pale grey/red surfaces); 5.3:1 on white, 4.65:1 on the palest tint */
    --hub-stat-label: #626c80;       /* was #8a92a6 (3.1:1) */
    --hub-sub: #626c80;              /* sub-lines, placeholders. Was #98a2b3 (2.6:1) */
    --hub-faint: #6a7385;            /* "muted amount" (dash / zero). Was #c0c6d0 (1.7:1); 4.8:1, still set apart by its lighter weight */

    /* borders and surfaces */
    --hub-border: #e7e9eb;           /* card / tile / dropdown border (= --ins-border-color) */
    --hub-input-border: #cfd4dc;
    --hub-input-border-hover: #b3bac5;
    --hub-input-disabled-bg: #f2f4f7;
    --hub-input-disabled-border: #e4e7ec;
    --hub-divider: #f0f2f6;          /* table row divider */
    --hub-head-bg: #eef1f6;          /* table head */
    --hub-head-border: #e8ecf3;
    --hub-row-hover: #f7faff;
    --hub-surface-alt: #f9fafb;      /* input-group addon */

    /* accents */
    --hub-link: #1ab394;             /* teal: links, input focus, checkboxes */
    --hub-focus: #1ab394;
    --hub-focus-ring: rgba(26, 179, 148, .14);
    --hub-invalid: #f04438;
    --hub-invalid-ring: rgba(240, 68, 56, .12);
    --hub-invalid-text: #d92d20;
    --hub-svc-tab-active: #704dff;   /* .svc-tabs. Was #7c5cff (4.0:1 on the page grey); 4.7:1 */

    /* status pill inks (on their own tint: green 3.1, info 3.3, orange 2.7, red 3.8, blue 4.4, grey 4.4 -> all 4.65:1 or better;
       the old values stay as comments so a retune knows where it started). hub-tables.css (--tn-*-ink) and custom.css (.newsbar-*)
       read these, so the pills, chips and news bars cannot drift apart. */
    --hub-pill-green-ink: #087c57;   /* was #0a9d6e */
    --hub-pill-blue-ink: #2966d2;    /* was #2f6bd6 */
    --hub-pill-info-ink: #0d7595;    /* was #1090b8 */
    --hub-pill-orange-ink: #9c5f07;  /* was #d5820a */
    --hub-pill-red-ink: #c92c2c;     /* was #d64545 */
    --hub-pill-grey-ink: #626c80;    /* was #667085 */
    --hub-pill-purple-ink: #6b4ee0;  /* unchanged (4.7:1) */

    /* text colours for the utilities and alerts (.text-success ... on white, alert text on its 15% tint over the page grey):
       the vendor tones are 2.2 / 3.2 / 1.7 / 3.4:1 on white and 2.6-4.4:1 in alerts. All 4.6:1 or better. */
    --hub-text-success: #09783d;
    --hub-text-danger: #c0282d;
    --hub-text-warning: #8a6100;
    --hub-text-info: #0a6f8c;

    /* dark table head */

    /* elevation and shape */
    --hub-card-shadow: 0 1px 2px rgba(16, 24, 40, .04);
    --hub-tile-shadow-hover: 0 6px 16px rgba(16, 24, 40, .08);
    --hub-radius-card: 10px;
    --hub-radius-input: 6px;

    /* toast accents */
    --hub-toast-success: #12b76a;
    --hub-toast-error: #f04438;
    --hub-toast-info: #2e90fa;
    --hub-toast-warning: #f79009;

    /* soft-button label inks and the solid-green button (WCAG AA, 4.5:1 or better on the 15% tint of the
       same hue; the vendor prints the bright theme colour on its own tint: 1.5-3.9:1) */
    --hub-soft-primary-ink: #475191;
    --hub-soft-secondary-ink: #156aaa;
    --hub-soft-success-ink: #0a7a40;
    --hub-soft-info-ink: #0a6f8c;
    --hub-soft-warning-ink: #8a6100;
    --hub-soft-danger-ink: #c0282d;
    --hub-soft-purple-ink: #485499;
    --hub-success-solid: #0b7d44;         /* white label on it: 5.2:1 (was #13ca6d, 2.2:1) */
    --hub-success-solid-hover: #086a39;

    /* typeface: Poppins is self-hosted by poppins.css. app.min.css used to @import it from
       Google together with eight other families; setting the variable here keeps the hub on
       Poppins whichever skin the chrome selects. */
    --ins-font-sans-serif: "Poppins", sans-serif;
}

/* --bs-* alias bridge ------------------------------------------------------------------
   Inspinia 4.0.1 emits only --ins-* variables. Fifty-six places in the hub's views, page
   styles and scripts read var(--bs-x, #fallback) and so always rendered the fallback
   (Bootstrap blue #0d6efd and friends). Aliasing them makes those uses follow the theme.
   NOTE --bs-body-bg maps to the CARD surface (--ins-secondary-bg, white), not to the page
   background, because every one of those views uses it as "the white card colour". */
:root {
    --bs-primary: var(--ins-primary);

    --bs-success: var(--ins-success);

    --bs-warning: var(--ins-warning);

    --bs-danger: var(--ins-danger);

    --bs-body-bg: var(--ins-secondary-bg);

    --bs-border-color-translucent: var(--ins-border-color-translucent);

}

/* Role accents ---------------------------------------------------------------------------
   The buyer-blue / seller-orange identity is retired: one palette for every role. Six view
   files read var(--role-accent*) with NO fallback, so the variables stay defined and now
   point at the reference primary. The body.role-theme-* selectors are (0,1,1) and therefore
   beat the legacy `.role-theme-buyer{...}` / `.role-theme-seller{...}` blocks at the top of
   custom.css whatever the load order. */
:root,
body.role-theme-admin,
body.role-theme-guest,
body.role-theme-buyer,
body.role-theme-seller {
    --role-accent-soft: #eff0f9;
    --role-accent-border: #ccd1ec;
    --role-accent-text: var(--ins-primary-text-emphasis);
}

/* ==========================================================================
   2. BASE
   ========================================================================== */
/* 5.0.0 theme value; 4.0.1 shipped .75em (9.75px), too small to read in tables. */
small, .small { font-size: .85em; }

/* Bootstrap's .text-muted / .text-body-secondary print --ins-secondary-color (#9ba6b7): 2.5:1 on white, used for record
   counts, hints, "per page", dates and timestamps on nearly every page. On the light surfaces they use the hub's muted ink
   (5.0:1 on white). The dark sidebar keeps the vendor tone (5.5:1 on #23303c). */
.text-muted,
.text-body-secondary { color: var(--hub-muted) !important; }
.sidenav-menu .text-muted,
.sidenav-menu .text-body-secondary { color: var(--ins-secondary-color) !important; }
/* page footer: the vendor mixes its emphasis colour at 75% (#797985, 4.3:1) */
.footer { color: var(--hub-muted); }

/* Smooth focus/hover on interactive controls */
.btn, .side-nav-link, .dropdown-item { transition: all .15s ease; }

.tabular-nums { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   3. MODERN-SKIN PARITY
   The hub's bundled `modern` skin already carries the reference's colours, font, radius, card
   shadow and heading weight (primary #5e6cc1, page #f7f6f7, text #4c4c5c, sidebar #23303c,
   white topbar, Poppins 13px, headings 500). Only the values below differ between
   Inspinia 4.0.1 (hub) and 5.0.0 (reference), so they are overridden here and nowhere else.
   ========================================================================== */
html[data-skin="modern"] {
    --ins-font-sans-serif: "Poppins", sans-serif;
    --ins-sidenav-item-gap: 9px;
    --ins-sidenav-item-padding-y: 8px;
    /* 5.0.0 points the link variables at the primary; the rgb pair (which the `a` rule
       actually reads) stays teal, so plain links are teal and .btn-link is indigo. */
    --ins-link-color: var(--ins-primary);
    --ins-link-hover-color: var(--ins-primary-text-emphasis);
    /* inline <code> is the vendor pink #ff679b (2.7:1 on white) */
    --ins-code-color: #c0306e;
}

html[data-skin="modern"] .dropdown-menu { border-radius: var(--ins-border-radius); }


/* ==========================================================================
   4. MODALS
   ========================================================================== */
/* Scrollable modals whose header/body/footer are wrapped in a <form>.
   Bootstrap's .modal-dialog-scrollable expects .modal-content to be a flex column whose
   DIRECT children are .modal-header/.modal-body/.modal-footer. With a <form> in between,
   the form becomes the only flex item, never shrinks below its content, grows past
   .modal-content's max-height and the footer (Cancel / Save) is clipped with no scrollbar.
   Making the form itself a shrinkable flex column restores the normal behaviour. Scoped to
   the direct-child <form> only, so formless scrollable modals are untouched. */
.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/* ==========================================================================
   5. SIDEBAR POLISH, LOGO, TOPBAR HELPERS, FOOTER, CONTENT PADDING
   ========================================================================== */

/* logo sizing: hub logos are PNG (142x40, ratio 3.55:1). reference forces its 6:1 wordmark to
   15px; that would make the hub logo tiny, so the sidebar keeps the theme's own 26px
   (--ins-logo-lg-height) and the login logo height is set in hub-auth.css. */

/* topbar helpers used by the new chrome ------------------------------------------------ */
.app-topbar .topbar-menu .topbar-item .topbar-link { height: 100%; padding: 0 6px; }
.app-topbar .topbar-menu .topbar-item .topbar-link .topbar-link-icon { font-size: 22px; }
.app-topbar .topbar-menu .topbar-item .dropdown { height: 100%; }
.app-topbar .topbar-menu .topbar-item .topbar-badge { top: 9px; right: -1px; }
/* The hub's bell keeps its legacy hooks (.top-bell-btn / .top-bell-badge) next to the reference
   classes. custom.css still styles those two as a bordered white button and a red 18px pill and
   loads after this file, so the reference look is restated here with higher specificity. */
.app-topbar .topbar-menu .topbar-item .top-bell-btn {
    border: 0;
    background-color: transparent;
    color: var(--ins-topbar-item-color);
}
.app-topbar .topbar-menu .topbar-item .top-bell-btn:hover,
.app-topbar .topbar-menu .topbar-item .top-bell-btn:focus {
    color: var(--ins-topbar-item-hover-color);
    background-color: transparent;
}
.app-topbar .topbar-menu .topbar-item .topbar-badge.top-bell-badge {
    min-width: 1rem;
    height: 1rem;
    padding: 0 .1rem;
    border-radius: var(--ins-badge-border-radius);
    font-size: var(--ins-badge-font-size);
    font-weight: var(--ins-badge-font-weight);
    box-shadow: none;
    pointer-events: none;           /* clicks pass through to the bell link */
}
/* Wallet chips (Buyer / Seller balance): neutral on every role, the blue/orange role tints are
   retired. They are disabled .btn elements, whose :disabled colours otherwise win over the
   legacy .top-wallet-btn-* tints in custom.css and render a dark outline. The mode switch and
   the mode badge (.top-mode-*) keep their tint on purpose. */
.app-topbar .top-wallet-btn,
.app-topbar .top-wallet-btn:disabled {
    color: var(--hub-ink);
    background-color: var(--ins-tertiary-bg);
    border: 1px solid var(--hub-border);
    border-radius: 6px;
    font-size: 12px;
    font-weight: 600;
    padding: .35rem .65rem;
}
/* the mode switch select sits in the 65px topbar: keep it compact next to the chips instead of
   inheriting the 40px form-control height */
.app-topbar .top-mode-select { min-height: 32px; padding-top: .25rem; padding-bottom: .25rem; font-size: 12.5px; }
.sidenav-toggle-button { flex: none; }
.sidenav-toggle-button i,
.sidenav-toggle-button svg { font-size: 22px; }

/* sidebar count badges (data-attn) and automation operator rows. Moved here from the seller
   menu's inline <style> so the buyer and admin menus get the same pills. */
.op-av {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 500;
    line-height: 1;
    flex: 0 0 auto;
    background: rgba(135, 150, 170, .2);
}
.side-nav-link.active .op-av { background: rgba(135, 150, 170, .32); }
.op-badge {
    margin-left: auto;
    min-width: 20px;
    text-align: center;
    padding: 1px 7px;
    border-radius: 9px;
    font-size: 11px;
    line-height: 1.5;
    background: rgba(135, 150, 170, .22);
}
.attn-badge {
    margin-left: auto;
    min-width: 20px;
    text-align: center;
    padding: 1px 7px;
    border-radius: 9px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.5;
    background: var(--ins-danger);
    color: #fff;
}
.side-nav .side-nav-title i { font-size: 13px; opacity: .7; }

/* sidebar "on hover" ring button (hidden unless data-sidenav-size=on-hover[-active]) */
.button-on-hover { font-size: 18px; right: 10px; padding-block: 0; }

/* breathing room below the sticky topbar on every page */
.content-page > .container-fluid {
    padding-top: 1.5rem;
    padding-bottom: 1.75rem;
}
@media (max-width: 767.98px) {
    .content-page > .container-fluid { padding-top: 1rem; }
}

/* ==========================================================================
   6. CARDS, PAGE TITLE, BREADCRUMB
   ========================================================================== */
.card {
    --ins-card-border-radius: var(--hub-radius-card);
    --ins-card-inner-border-radius: calc(var(--hub-radius-card) - 1px);
    border: 1px solid var(--ins-border-color, #e7e9eb);
    border-radius: var(--hub-radius-card);
    box-shadow: var(--hub-card-shadow);
}
.card .card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--ins-border-color, #e7e9eb);
    padding-top: .85rem;
    padding-bottom: .85rem;
}
.card .card-title { font-size: 15px; font-weight: 600; }

/* reference has no page title: the title lives in the first card header
   (<h5 class="card-title mb-0"><i class="ti ti-..."></i> Title</h5>). An optional right-aligned
   action row sits above the cards. */
.page-title-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }

/* dormant-but-available title + breadcrumb styles (pages with no top card) */

/* ==========================================================================
   7. STAT TILES - KPI card with a coloured icon square and a bottom accent bar
   Markup: .stat-tile.tile-{teal|blue|cyan|orange|red|dark|purple}[.tile-soft]
             > .stat-body > (.stat-label .stat-value [.stat-exact] .stat-foot[.dot]) + .stat-icon
             + .stat-accent
   ========================================================================== */
.stat-tile {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--ins-border-color, #e7e9eb);
    border-radius: var(--hub-radius-card);
    background: #fff;
    height: 100%;
    box-shadow: var(--hub-card-shadow);
    transition: box-shadow .15s ease, transform .15s ease;
}
.stat-tile:hover { box-shadow: var(--hub-tile-shadow-hover); transform: translateY(-1px); }
.stat-tile .stat-body { padding: 1rem 1.1rem 1.15rem; }
.stat-tile .stat-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--hub-stat-label);
}
/* Kept modest on purpose: money tiles carry large figures (30 cr+ daily volumes), so an
   oversized number would overflow a narrow tile. */
.stat-tile .stat-value { font-size: 20px; font-weight: 700; color: var(--hub-ink); line-height: 1.2; }
/* neutralise a per-view fs-3 on the value so every tile matches */
/* Long figures (9,92,82,07,506.07) must never split mid-number or run under the icon: the text column may
   shrink (min-width:0), the value stays on one line and hub-ui.js lowers its font-size ONLY when it does not
   fit (min 11px). Without JS the tile simply clips at its edge. Labels may break anywhere. */
.stat-tile .stat-body > div:first-child { min-width: 0; flex: 1 1 auto; }
.stat-tile .stat-label { overflow-wrap: anywhere; }
.stat-tile .stat-value { white-space: nowrap; }
.stat-tile .stat-body > .stat-icon { margin-left: .5rem; }
@media (max-width: 575.98px) {
    .stat-tile .stat-body { padding: .85rem .85rem 1rem; }
    /* two tiles per row leaves ~87px for the text: the decorative icon gives way to the number */
    .stat-tile .stat-body > .stat-icon { display: none; }
}
/* exact figure under a compact headline value, e.g. 99.63 L over 99,63,266.24 */
.stat-tile .stat-icon {
    width: 46px;
    height: 46px;
    border-radius: 11px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 22px;
    flex-shrink: 0;
    background: var(--hub-tile, #1ab394);
}
.stat-tile .stat-foot {
    font-size: 12px;
    color: var(--hub-sub);
    margin-top: .5rem;
    display: flex;
    align-items: center;
}
.stat-tile .stat-foot .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 6px;
    background: var(--hub-tile, #1ab394);
}
.stat-tile .stat-accent {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 3px;
    width: 100%;
    background: var(--hub-tile, #1ab394);
}
.tile-teal   { --hub-tile: #1ab394; --hub-tile-soft-bg: #e3f8f3; --hub-tile-soft-fg: #0f9c7c; }
.tile-blue   { --hub-tile: #3a86ff; --hub-tile-soft-bg: #e8f0fe; --hub-tile-soft-fg: #2f6bd6; }
.tile-cyan   { --hub-tile: #17c1d6; --hub-tile-soft-bg: #e1f7fa; --hub-tile-soft-fg: #128a9b; }
.tile-orange { --hub-tile: #f5a623; --hub-tile-soft-bg: #fdf1e3; --hub-tile-soft-fg: #d5820a; }
.tile-red    { --hub-tile: #ef5350; --hub-tile-soft-bg: #fdeaea; --hub-tile-soft-fg: #d64545; }
.tile-dark   { --hub-tile: #3a4656; --hub-tile-soft-bg: #eef0f3; --hub-tile-soft-fg: #3a4656; }
.tile-purple { --hub-tile: #7c5cff; --hub-tile-soft-bg: #efeaff; --hub-tile-soft-fg: #6b4ee0; }

/* soft-icon variant (opt-in): light tinted circle with a coloured glyph */
.tile-soft .stat-icon {
    border-radius: 50%;
    background: var(--hub-tile-soft-bg, #e3f8f3);
    color: var(--hub-tile-soft-fg, #0f9c7c);
}

/* ==========================================================================
   8. FILTER PANEL
   ========================================================================== */
.filter-card .card-header { font-weight: 600; }
.filter-card .form-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--hub-muted);
    margin-bottom: .25rem;
}
/* A six-per-row filter column (col-md-2 / col-lg-2 / col-xl-2) is only 127-146px wide between 992 and 1150px, narrower than a date
   input (156px) or a placeholder such as "Enter customer number". From tablet width such a column never gets narrower than 10.75rem
   (the control inside keeps 164px); the row wraps instead. A date field in a filter card gives back 4px of padding on each side (the
   picker icon no longer overlaps "mm/dd/yyyy" in a 150px phone column) and a placeholder that is still too long ends in an ellipsis. */
@media (min-width: 768px) {
    .filter-card .row > :is(.col-md-2, .col-lg-2, .col-xl-2) { min-width: 10.75rem; }
}
.filter-card input[type="date"].form-control { padding-left: .5rem; padding-right: .5rem; }
.filter-card input.form-control { text-overflow: ellipsis; }

/* Filter bars: action buttons match the input height. The native date control adds its own
   picker affordance, so a Filter button beside a From/To input sat visibly short. This is the
   EXACT expression the theme gives .form-control-sm, so the button and the input agree.
   line-height must be forced back to 1.5: the theme sets .btn-sm{line-height:normal}.
   Kept narrow on purpose (filter cards and any <form class="row">), not applied to .btn-sm
   globally. */
.filter-card .btn,
form.row .btn {
    /* 40px = the global .form-control height (section 11), so Search/Reset line up with their inputs */
    min-height: 40px;
    line-height: 1.5;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ==========================================================================
   9. TABLES - dark head, table-neo and cell helpers
   (DataTables chrome, the .txn-table / .data-table aliases and pagers: hub-tables.css)
   ========================================================================== */

/* action buttons inside tables */

/* TABLE-NEO: the list/report table. Works WITH Bootstrap's .table (collapsed borders). */
.table.table-neo { margin: 0; }
.table.table-neo > thead > tr > th {
    background: var(--hub-head-bg);
    color: var(--hub-th);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    /* All-caps labels have no descenders; a tight line-height keeps the label optically
       centred instead of top-heavy. */
    line-height: 1.15;
    padding: .72rem 1rem;
    border-top: 0;
    border-bottom: 2px solid var(--hub-head-border);
    white-space: nowrap;
    vertical-align: middle;
}
.table.table-neo > tbody > tr > td {
    padding: .8rem 1rem;
    border-top: 0;
    border-bottom: 1px solid var(--hub-divider);
    vertical-align: middle;
    font-size: 13px;
    color: var(--hub-td);
}
.table.table-neo > tbody > tr:last-child > td { border-bottom: 0; }
.table.table-neo > tbody > tr:hover > td { background: var(--hub-row-hover); }
/* totals row */
.table.table-neo > tfoot > tr > td,
.table.table-neo > tfoot > tr > th {
    background: #f4f6fa;
    border-top: 2px solid #e3e7ee;
    padding: .8rem 1rem;
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* cell helpers (all scoped to .table-neo) */
.table-neo .u-name { font-weight: 600; color: var(--hub-ink-2); text-decoration: none; }
.table-neo .u-name:hover { text-decoration: underline; }
.table-neo .u-sub { font-size: 11px; color: var(--hub-sub); display: block; margin-top: 1px; }
.table-neo .u-mobile { font-weight: 700; color: var(--hub-ink-2); letter-spacing: .01em; }
.table-neo .u-amt { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--hub-ink-2); }
.table-neo .u-amt.muted { color: var(--hub-faint); font-weight: 400; }
/* Caps a long primary-cell value (reference id, long name) to a fixed width with an ellipsis
   so table-nowrap does not stretch the column and the table with it. Opt-in per cell; always
   keep the full value in title="". */
.table-neo .cell-trunc {
    display: inline-block;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}
.table-neo .cell-trunc-sm { max-width: 110px; }
.table-neo .id-link { font-size: 11px; font-weight: 500; color: var(--hub-muted); text-decoration: none; }
.table-neo .id-link:hover { color: var(--hub-ink-2); text-decoration: underline; }
/* charge / commission / TDS stacked in one cell */

/* KEY / VALUE table for detail pages (hub extension): label column on the left.
   <table class="table table-kv mb-0"><tr><th>Label</th><td>Value</td></tr>...</table> */
.table.table-kv { margin: 0; }
.table.table-kv > tbody > tr > th {
    width: 220px;
    max-width: 40%;
    background: var(--hub-surface-alt);
    color: var(--hub-muted);
    font-size: 12px;
    font-weight: 600;
    padding: .65rem 1rem;
    vertical-align: top;
    border-bottom: 1px solid var(--hub-divider);
}
.table.table-kv > tbody > tr > td {
    padding: .65rem 1rem;
    font-size: 13px;
    color: var(--hub-td);
    border-bottom: 1px solid var(--hub-divider);
    word-break: break-word;
}
.table.table-kv > tbody > tr:last-child > th,
.table.table-kv > tbody > tr:last-child > td { border-bottom: 0; }

/* ==========================================================================
   10. PILLS, ROW ACTIONS, SOFT-BUTTON REPAIR
   Status tone map used by the transaction tables:
     success -> green, pending -> orange, failed -> red, reversed -> grey, submitted -> info,
     debited -> blue, initiated -> grey
   ========================================================================== */
.pill {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    padding: .22rem .6rem;
    border-radius: 999px;
    line-height: 1.4;
    white-space: nowrap;
}
.pill-green  { background: #e6f7f1; color: var(--hub-pill-green-ink); }
.pill-blue   { background: #e8f0fe; color: var(--hub-pill-blue-ink); }
.pill-info   { background: #e4f4fb; color: var(--hub-pill-info-ink); }
.pill-orange { background: #fdf1e3; color: var(--hub-pill-orange-ink); }
.pill-red    { background: #fdeaea; color: var(--hub-pill-red-ink); }
.pill-grey   { background: #eef1f5; color: var(--hub-pill-grey-ink); }
.pill-purple { background: #efeaff; color: var(--hub-pill-purple-ink); }

/* compact row action buttons */
.act-btns { display: inline-flex; gap: .35rem; justify-content: flex-end; }
.act-btns .btn { padding: .3rem .7rem; font-size: 12px; font-weight: 600; border-radius: 7px; line-height: 1.3; }
/* square icon-only row action (the label lives in title + aria-label) */
.act-btns .btn-icon {
    width: 30px;
    height: 30px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.act-btns .btn-icon i { font-size: 15px; line-height: 1; }

/* VENDOR THEME BUG, fixed here (app.css must not be hand-edited): every disabled
   .btn-soft-* variant sets its text colour AND its background to the same solid theme colour,
   so a disabled soft button is an invisible icon on its own background. General fix for every
   disabled soft button; wins at equal specificity through load order, no !important. */
.btn[class*="btn-soft-"]:disabled,
.btn[class*="btn-soft-"].disabled {
    color: #97a3b5;
    background-color: var(--hub-head-bg);
    border-color: transparent;
}

/* Soft buttons: label in a dark ink of the same hue (the vendor prints the bright theme colour on a 15% tint
   of itself: warning 1.55:1, success 1.9:1, info 2.0:1, danger 2.7:1, secondary 3.0:1, purple 3.7:1, primary
   4.0:1). Hover keeps the "solid on hover" idea but fills with the ink, because white on the bright colour is
   1.7-3.5:1 for warning/success/info/secondary/danger. Primary and purple keep the vendor hover (white on the
   theme colour is 4.8 / 4.5:1). Variables only, so every .btn-soft-* in the hub follows. */
.btn-soft-primary   { --ins-btn-color: var(--hub-soft-primary-ink); }
.btn-soft-purple    { --ins-btn-color: var(--hub-soft-purple-ink); }
.btn-soft-secondary { --ins-btn-color: var(--hub-soft-secondary-ink); --ins-btn-hover-bg: var(--hub-soft-secondary-ink); --ins-btn-hover-border-color: var(--hub-soft-secondary-ink); --ins-btn-active-bg: var(--hub-soft-secondary-ink); --ins-btn-active-border-color: var(--hub-soft-secondary-ink); }
.btn-soft-success   { --ins-btn-color: var(--hub-soft-success-ink); --ins-btn-hover-bg: var(--hub-soft-success-ink); --ins-btn-hover-border-color: var(--hub-soft-success-ink); --ins-btn-active-bg: var(--hub-soft-success-ink); --ins-btn-active-border-color: var(--hub-soft-success-ink); }
.btn-soft-info      { --ins-btn-color: var(--hub-soft-info-ink); --ins-btn-hover-bg: var(--hub-soft-info-ink); --ins-btn-hover-border-color: var(--hub-soft-info-ink); --ins-btn-active-bg: var(--hub-soft-info-ink); --ins-btn-active-border-color: var(--hub-soft-info-ink); }
.btn-soft-warning   { --ins-btn-color: var(--hub-soft-warning-ink); --ins-btn-hover-bg: var(--hub-soft-warning-ink); --ins-btn-hover-border-color: var(--hub-soft-warning-ink); --ins-btn-active-bg: var(--hub-soft-warning-ink); --ins-btn-active-border-color: var(--hub-soft-warning-ink); }

/* Solid orange (Vi mPower transfer button): same look as the solid primary and success buttons; white label, darker hover. */
.btn-orange {
    --ins-btn-bg: #c2410c;
    --ins-btn-border-color: #c2410c;
    --ins-btn-hover-bg: #9a3412;
    --ins-btn-hover-border-color: #9a3412;
    --ins-btn-active-bg: #9a3412;
    --ins-btn-active-border-color: #9a3412;
    --ins-btn-disabled-bg: #c2410c;
    --ins-btn-disabled-border-color: #c2410c;
}
.btn-soft-danger    { --ins-btn-color: var(--hub-soft-danger-ink); --ins-btn-hover-bg: var(--hub-soft-danger-ink); --ins-btn-hover-border-color: var(--hub-soft-danger-ink); --ins-btn-active-bg: var(--hub-soft-danger-ink); --ins-btn-active-border-color: var(--hub-soft-danger-ink); }

/* Solid green (Export / Download / Approve): white label on the vendor #13ca6d is 2.2:1. A darker green keeps the
   DUEPE green look and reads at 5.2:1; the hover is darker still. */
.btn-success {
    --ins-btn-bg: var(--hub-success-solid);
    --ins-btn-border-color: var(--hub-success-solid);
    --ins-btn-hover-bg: var(--hub-success-solid-hover);
    --ins-btn-hover-border-color: var(--hub-success-solid-hover);
    --ins-btn-active-bg: var(--hub-success-solid-hover);
    --ins-btn-active-border-color: var(--hub-success-solid-hover);
    --ins-btn-disabled-bg: var(--hub-success-solid);
    --ins-btn-disabled-border-color: var(--hub-success-solid);
}

/* ==========================================================================
   11. FORMS - clearly bordered fields (the theme's default border is too faint for a
   data-entry app). Applies app-wide.
   ========================================================================== */
.form-label {
    font-weight: 600;
    font-size: 12.5px;
    color: var(--hub-label);
    margin-bottom: .375rem;
}
.form-control,
.form-select {
    border: 1px solid var(--hub-input-border);
    background-color: #fff;
    color: var(--hub-ink);
    border-radius: var(--hub-radius-input);
    padding: .5rem .75rem;
    min-height: 40px;
    font-size: 13.5px;
    box-shadow: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
/* keep room for the select arrow (the shorthand above would reset the theme's 2.31rem) */
.form-select { padding-right: 2.31rem; }
.form-select[multiple],
.form-select[size]:not([size="1"]) { padding-right: .75rem; }
.form-control::placeholder { color: var(--hub-sub); opacity: 1; }
.form-control:hover:not(:disabled):not([readonly]):not(:focus),
.form-select:hover:not(:disabled):not(:focus) { border-color: var(--hub-input-border-hover); }
.form-control:focus,
.form-select:focus {
    border-color: var(--hub-focus);
    box-shadow: 0 0 0 3px var(--hub-focus-ring);
    background-color: #fff;
    color: var(--hub-ink);
}
.form-control:disabled,
.form-control[readonly],
.form-select:disabled {
    background-color: var(--hub-input-disabled-bg);
    color: var(--hub-muted);
    border-color: var(--hub-input-disabled-border);
}
.form-control.is-invalid,
.form-select.is-invalid { border-color: var(--hub-invalid); }
.form-control.is-invalid:focus { box-shadow: 0 0 0 3px var(--hub-invalid-ring); }
.invalid-feedback { font-size: 12px; color: var(--hub-invalid-text); }
.form-text { font-size: 12px; color: var(--hub-muted); }

/* input-group affixes (icons) sit flush and subtle */
.input-group-text {
    background-color: var(--hub-surface-alt);
    border: 1px solid var(--hub-input-border);
    color: var(--hub-muted);
}
/* reference drops the left border on EVERY control in a group, which also strips it from a control
   that comes first (input + button). Dropping it only after an addon keeps the icon-prefix
   look and leaves every other group alone. */
.input-group > .input-group-text + .form-control,
.input-group > .input-group-text + .form-select { border-left: 0; }
.input-group > .input-group-text + .form-control { padding-left: .625rem; }

/* file inputs */
.form-control[type=file] { padding: .35rem .6rem; }
.form-control[type=file]::file-selector-button {
    background-color: var(--hub-input-disabled-bg);
    border: 0;
    border-right: 1px solid var(--hub-input-border);
    color: var(--hub-label);
    padding: .45rem .75rem;
    margin: -.35rem .6rem -.35rem -.6rem;
    border-radius: 0;
}

/* checkboxes / switches: teal (reference renders them teal next to indigo buttons) */
.form-check-input:checked { background-color: var(--hub-focus); border-color: var(--hub-focus); }

/* Choices.js (searchable selects). reference ships these looking wrong (transparent background,
   a #4c4c5c border) because its page-level override reads undefined variables; the hub's
   theme already defines the pieces, so this only aligns them with the 40px inputs. Several
   theme rules are !important, hence the !important here. */
.choices { margin-bottom: 0; }
.choices__inner {
    background-color: #fff;
    border-color: var(--hub-input-border);
    border-radius: var(--hub-radius-input) !important;
    min-height: 40px;
    font-size: 13.5px;
    color: var(--hub-ink);
}
.choices__inner:hover { border-color: var(--hub-input-border-hover); }
.is-focused .choices__inner,
.is-open .choices__inner {
    border-color: var(--hub-focus);
    box-shadow: 0 0 0 3px var(--hub-focus-ring);
}
/* single select: centre the value in the 40px box and keep clear of the arrow */
.choices[data-type*="select-one"] .choices__inner {
    display: flex;
    align-items: center;
    padding-right: 28px !important;
}
.choices[data-type*="select-one"] .choices__list--single { flex: 1 1 auto; min-width: 0; }
.choices[data-type*="select-one"]::after { top: 50%; right: 11.5px; }
.choices__list--dropdown, .choices__list[aria-expanded] { z-index: 1065; }
.choices__list--single .choices__item {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.choices.is-open .choices__list--single .choices__item { overflow: visible; }

/* ==========================================================================
   12. TABS
   ========================================================================== */
/* House underline tabs, applied to the existing Bootstrap `nav nav-tabs card-header-tabs`
   markup (no markup change). Detail pages, operator details, tabbed cards. */

/* Service / category tab bar (switchers above a page). ul.nav.svc-tabs > li.nav-item > a.nav-link */
.svc-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    list-style: none;
    padding: 0;
    margin: 0 0 1.25rem;
    border-bottom: 1px solid var(--hub-input-disabled-border);
}
.svc-tabs .nav-item { margin-bottom: -1px; }
.svc-tabs .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 11px 20px;
    font-weight: 500;
    font-size: .9rem;
    line-height: 1.2;
    color: var(--hub-muted);
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    white-space: nowrap;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.svc-tabs .nav-link i { font-size: 1.05rem; opacity: .9; }
.svc-tabs .nav-link:hover { color: var(--hub-ink); border-bottom-color: var(--hub-input-border); }
.svc-tabs .nav-link.active {
    color: var(--hub-svc-tab-active);
    border-bottom-color: var(--hub-svc-tab-active);
    background: transparent;
}
@media (max-width: 575.98px) {
    .svc-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .svc-tabs .nav-link { padding: 10px 14px; }
}

/* ==========================================================================
   13. PAGINATION (Bootstrap pagers outside DataTables)
   Right-aligned, opposite the "Showing x-y of z" text on the left. DataTables' own pager is
   styled in hub-tables.css.
   ========================================================================== */
.card-body > .pagination,
.card-footer > .pagination,
nav[aria-label] > .pagination {
    justify-content: flex-end !important;
    margin-bottom: 0;
}
@media (max-width: 575.98px) {
    .card-body > .pagination,
    .card-footer > .pagination,
    nav[aria-label] > .pagination { justify-content: flex-start !important; }
}

/* ==========================================================================
   14. ALERTS, EMPTY STATE, PROGRESS, AVATARS, MISC
   Alerts keep the theme's 15%-tint look; pattern:
     <div class="alert alert-warning d-flex align-items-center" role="alert">
         <i class="ti ti-alert-triangle me-1"></i> text</div>
   Progress: the theme already ships .progress-sm (5px), .progress-md (8px), .progress-lg.
   ========================================================================== */
/* Text colours on pale surfaces. Alert text is the vendor "text emphasis" tone on a 15% tint of the same hue (success 3.3:1, info 3.2,
   warning 2.6, danger 4.4); the .text-* utilities and .badge-soft-* labels print the bright theme colour (success 2.2:1 on white,
   danger 3.2, warning 1.7, info 2.0). Darker inks of the same hue, all 4.6:1 or better. */
.alert-success { --ins-alert-color: var(--hub-text-success); --ins-alert-link-color: var(--hub-text-success); }
.alert-danger  { --ins-alert-color: var(--hub-text-danger);  --ins-alert-link-color: var(--hub-text-danger); }
.alert-warning { --ins-alert-color: var(--hub-text-warning); --ins-alert-link-color: var(--hub-text-warning); }
.alert-info    { --ins-alert-color: var(--hub-text-info);    --ins-alert-link-color: var(--hub-text-info); }
.text-success { color: var(--hub-text-success) !important; }
.text-danger  { color: var(--hub-text-danger) !important; }
.text-warning { color: var(--hub-text-warning) !important; }
.text-info    { color: var(--hub-text-info) !important; }
.badge-soft-success { --ins-badge-color: var(--hub-text-success); }
.badge-soft-danger  { --ins-badge-color: var(--hub-text-danger); }
.badge-soft-warning { --ins-badge-color: var(--hub-text-warning); }
.badge-soft-info    { --ins-badge-color: var(--hub-text-info); }
.badge-soft-primary { --ins-badge-color: var(--hub-soft-primary-ink); }

/* Card / panel empty state (a table row uses partials/dt_empty.php instead):
   <div class="hub-empty"><i class="ti ti-inbox"></i><div class="hub-empty-title">...</div>
   <div class="hub-empty-text">...</div></div> */
.hub-empty { text-align: center; padding: 2.5rem 1rem; }
.hub-empty > .ti { display: block; font-size: 2.25rem; line-height: 1; color: var(--hub-sub); opacity: .7; margin-bottom: .6rem; }
.hub-empty-title { font-weight: 600; font-size: 14px; color: var(--hub-ink); margin-bottom: .2rem; }
.hub-empty-text { font-size: 12px; color: var(--hub-muted); margin: 0 auto; max-width: 28rem; }

/* initial-letter avatar: <span class="hub-avatar">A</span> (32px) / .hub-avatar-lg (44px) */
.hub-avatar {
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ins-primary);
    color: #fff;
    font-weight: 600;
    font-size: 13px;
    line-height: 1;
    text-transform: uppercase;
}
.hub-avatar-lg { width: 44px; height: 44px; flex-basis: 44px; font-size: 16px; }

/* amount colour conventions inside tables: -negative / +positive */

/* Small helpers that replace the inline style="" attributes views carry today (new inline
   style attributes are not allowed; use these instead). */
.min-w-0 { min-width: 0; }
.w-input-sm { width: 140px; max-width: 100%; }     /* quick-search / compact filter control */
.w-input-md { width: 180px; max-width: 100%; }
.w-input-lg { width: 230px; max-width: 100%; }
.w-input-xl { width: 300px; max-width: 100%; }
.scroll-y-sm { max-height: 14rem; overflow-y: auto; }
.scroll-y-md { max-height: 22rem; overflow-y: auto; }
.scroll-y-lg { max-height: 32rem; overflow-y: auto; }
                /* row-action dropdown menu */

/* ==========================================================================
   15. TOAST STACK
   Built by hub-toast.js (container #hub-toast-stack, created on demand). The class names are
   .hub-toast-* so they cannot collide with the per-console Bootstrap toast containers
   (#appToastContainer, #opsToastWrap, #purToastWrap), which stay as they are.
   z-index 1090 matches those containers: above modals (1055), below the pending-alert
   overlay (2200). Success 5s, info/warning 6s, error stays until dismissed.
   ========================================================================== */
.hub-toast-stack {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1090;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    width: min(24rem, calc(100vw - 2rem));
    pointer-events: none;
}
/* desktop: sit just below the 65px topbar so the bell / user menu / Log Out stay reachable */
@media (min-width: 576px) {
    .hub-toast-stack { top: 4.75rem; }
}
/* bottom-centred on phones: a top-right stack overlaps the mobile topbar controls */
@media (max-width: 575.98px) {
    .hub-toast-stack { top: auto; bottom: 1rem; left: 1rem; right: 1rem; width: auto; }
}
.hub-toast {
    --hub-toast-accent: #6b7280;
    pointer-events: auto;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    padding: .8rem .9rem;
    border-radius: .6rem;
    background: #fff;
    color: #1f2937;
    border: 1px solid rgba(0, 0, 0, .1);
    border-left: 3px solid var(--hub-toast-accent);
    box-shadow: 0 8px 24px rgba(16, 24, 40, .14), 0 2px 6px rgba(16, 24, 40, .08);
    transform: translateX(8%);
    opacity: 0;
    transition: transform .22s cubic-bezier(.22, 1, .36, 1), opacity .22s ease;
}
.hub-toast.is-in { transform: translateX(0); opacity: 1; }
.hub-toast.is-out { transform: translateX(8%); opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .hub-toast { transition: opacity .01ms; transform: none; }
    .hub-toast.is-in, .hub-toast.is-out { transform: none; }
}
.hub-toast--success { --hub-toast-accent: var(--hub-toast-success); }
.hub-toast--error   { --hub-toast-accent: var(--hub-toast-error); }
.hub-toast--info    { --hub-toast-accent: var(--hub-toast-info); }
.hub-toast--warning { --hub-toast-accent: var(--hub-toast-warning); }
.hub-toast__icon { flex: 0 0 auto; line-height: 1.2; font-size: 1.05rem; color: var(--hub-toast-accent); }
.hub-toast__body { flex: 1 1 auto; min-width: 0; font-size: .875rem; line-height: 1.45; overflow-wrap: anywhere; }
.hub-toast__link { display: block; width: fit-content; margin-top: .3rem; font-weight: 600; color: var(--hub-toast-accent); text-decoration: none; }
.hub-toast__link:hover { text-decoration: underline; color: var(--hub-toast-accent); }
.hub-toast__close {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    cursor: pointer;
    padding: 0 .1rem;
    line-height: 1;
    font-size: 1.1rem;
    opacity: .5;
    color: inherit;
}
.hub-toast__close:hover { opacity: 1; }
/* only auto-dismissing toasts get a progress bar: its absence is the cue that this one is
   waiting for you */
.hub-toast__bar {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 100%;
    background: var(--hub-toast-accent);
    opacity: .55;
    transform-origin: left center;
}
@media print { .hub-toast-stack { display: none; } }

/* ==========================================================================
   16. WIDE-TABLE SCROLL CUE
   hub-ui.js sets .fin-x-start / .fin-x-mid / .fin-x-end on every .table-responsive that
   overflows horizontally (no class = it fits = no shadow). Inset shadows rather than the usual
   four-gradient trick because the card surface colour is not exposed as one background.
   ========================================================================== */
.table-responsive {
    scrollbar-width: thin;
    scrollbar-color: rgba(138, 150, 156, .45) transparent;
    transition: box-shadow .15s ease;
}
.table-responsive.fin-x-start { box-shadow: inset -12px 0 10px -10px rgba(16, 24, 40, .35); }
.table-responsive.fin-x-mid {
    box-shadow: inset 12px 0 10px -10px rgba(16, 24, 40, .35), inset -12px 0 10px -10px rgba(16, 24, 40, .35);
}
.table-responsive.fin-x-end { box-shadow: inset 12px 0 10px -10px rgba(16, 24, 40, .35); }
.table-responsive::-webkit-scrollbar { height: 9px; }
.table-responsive::-webkit-scrollbar-track { background: transparent; }
.table-responsive::-webkit-scrollbar-thumb { background: rgba(138, 150, 156, .45); border-radius: 6px; }
.table-responsive::-webkit-scrollbar-thumb:hover { background: rgba(138, 150, 156, .7); }
@media (hover: none) { .table-responsive { -webkit-overflow-scrolling: touch; } }
@media (prefers-reduced-motion: reduce) { .table-responsive { transition: none; } }

/* ==========================================================================
   18. KEYBOARD FOCUS - the vendor stylesheet sets `button, a { outline: none !important }`, which leaves
   keyboard users with no visible focus on links and buttons. :focus-visible only fires for keyboard
   navigation, so mouse users see no change.
   ========================================================================== */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--hub-focus) !important;
    outline-offset: 2px;
}
.sidenav-menu a:focus-visible,
.sidenav-menu button:focus-visible {
    outline-color: #8ad7c8 !important;
    outline-offset: -2px;
    border-radius: 6px;
}
