/* ==========================================================================
   Kaastro Pay — design system
   Follows the supplied app mockups: dark balance card with a green glow,
   a row of four action tiles, an 8-tile service grid, and a five-tab bottom
   nav. Emerald primary, dark mode via [data-bs-theme="dark"] on <html>.
   ========================================================================== */

/* Self-hosted. Nothing in this app may reference a CDN: a third-party
   origin is an availability dependency we do not control, and an @import
   is a render-blocking fetch two levels deep. */
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/vendor/fonts/plus-jakarta-sans-latin-400-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/vendor/fonts/plus-jakarta-sans-latin-500-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/vendor/fonts/plus-jakarta-sans-latin-600-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/vendor/fonts/plus-jakarta-sans-latin-700-normal.woff2') format('woff2');
}
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('/vendor/fonts/plus-jakarta-sans-latin-800-normal.woff2') format('woff2');
}

:root {
    /* One colour, three strengths.

       The brand is lemon. Full-strength lemon (#B2FB0C) is 15.7:1 on the dark
       ground and 1.3:1 on white, so light mode steps the same hue down until it
       passes: --primary-color for icons and UI accents, --primary-dark for text
       and links. Nothing else in the product is green. */
    --lemon: #B2FB0C;
    --lemon-hover: #C4FF3A;
    --lemon-dark: #9FE00A;
    --lemon-ink: #0B1A02;
    --lemon-soft: rgba(178, 251, 12, 0.14);
    --lemon-edge: rgba(178, 251, 12, 0.45);

    /* Light mode: lemon darkened to carry on white. 3.5:1 and 5.2:1. */
    --primary-color: #6B9700;
    --primary-light: #EDF7CE;
    --primary-dark: #557800;
    --primary-soft: rgba(107, 151, 0, 0.10);
    --bg-body: #F7F8F5;
    --bg-card: #ffffff;
    --bg-sunk: #F2F3EE;
    --text-main: #171A14;
    --text-muted: #6A6F63;
    --border-color: #E5E7E1;

    --up: #557800;
    --down: #ef4444;
    --warn: #f59e0b;
    --info: #0ea5e9;
    --purple: #8b5cf6;

    /* The balance card keeps one look in both themes — it is the app's
       signature surface in the mockups and inverting it loses that. */
    --hero-bg: #141A08;
    --hero-edge: rgba(178, 251, 12, 0.28);
    --hero-text: #F2F3EC;
    --hero-dim: rgba(234, 245, 240, 0.66);

    --radius-lg: 1rem;
    --radius-md: 0.75rem;
    --radius-sm: 0.5rem;
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.08), 0 2px 4px -2px rgb(0 0 0 / 0.06);
    --shadow-lg: 0 10px 30px -12px rgb(0 0 0 / 0.18);
    --transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    --sidebar-w: 258px;
    --tabbar-h: 64px;
}

[data-bs-theme="dark"] {
    /* A neutral near-black, not a tinted one: lemon only reads as the brand
       when the ground it sits on is colourless. On this ground lemon runs at
       full strength — 15.7:1 — so no stepped-down variant is needed. */
    --primary-color: #B2FB0C;
    --primary-dark: #C4FF3A;
    --primary-light: rgba(178, 251, 12, 0.18);
    --primary-soft: rgba(178, 251, 12, 0.12);
    --lemon-soft: rgba(178, 251, 12, 0.14);
    --lemon-edge: rgba(178, 251, 12, 0.38);
    --bg-body: #0A0A0A;
    --bg-card: #141414;
    --bg-sunk: #1C1C1C;
    --text-main: #F5F5F5;
    --text-muted: #8E8E8E;
    --border-color: #242424;
    /* Positive figures run full lemon here; the light-mode value is far too
       dark to read against #0A0A0A. */
    --up: #B2FB0C;
    /* The balance card is the one surface allowed to carry the lemon glow. */
    --hero-bg: #151C09;
    --hero-edge: rgba(178, 251, 12, 0.30);
    --hero-text: #FFFFFF;
    --hero-dim: rgba(255, 255, 255, 0.62);
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.5);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.6), 0 2px 4px -2px rgb(0 0 0 / 0.5);
    --shadow-lg: 0 10px 30px -12px rgb(0 0 0 / 0.9);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
    font-family: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    background-color: var(--bg-body);
    color: var(--text-main);
    font-size: 0.92rem;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

a { text-decoration: none; }
.cursor-pointer { cursor: pointer; }
.text-primary-k { color: var(--primary-dark) !important; }
[data-bs-theme="dark"] .text-primary-k { color: var(--primary-color) !important; }
.text-up { color: var(--up) !important; }
.text-down { color: var(--down) !important; }
.num, .tabnum { font-variant-numeric: tabular-nums; }
.min-w-0, .min-width-0 { min-width: 0; }

/* ============================ Shell ============================ */

.sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--sidebar-w);
    background: var(--bg-card);
    border-right: 1px solid var(--border-color);
    padding: 1.5rem 0.85rem;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    z-index: 1030;
}

.brand-logo {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0 0.5rem 0.25rem;
    color: var(--text-main);
}
.brand-mark {
    width: 34px; height: 34px; flex: none;
    border-radius: 10px;
    background: var(--primary-color);
    color: #fff;
    display: grid; place-items: center;
    font-weight: 800; font-size: 1.1rem;
    letter-spacing: -0.04em;
}
.brand-text { line-height: 1.1; min-width: 0; }
.brand-text b { font-size: 1rem; font-weight: 800; letter-spacing: -0.02em; display: block; }
.brand-text small {
    font-size: 0.62rem; color: var(--text-muted); font-weight: 700;
    letter-spacing: 0.1em; text-transform: uppercase;
}

.sidebar .nav-section {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em;
    color: var(--text-muted); font-weight: 700;
    padding: 0 0.75rem; margin: 1.25rem 0 0.4rem;
}

.sidebar .nav-link, .offcanvas-sidebar .nav-link {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-weight: 600; font-size: 0.855rem;
    transition: var(--transition);
    margin-bottom: 1px;
}
.sidebar .nav-link i, .offcanvas-sidebar .nav-link i { width: 18px; text-align: center; font-size: 0.9rem; }
.sidebar .nav-link:hover, .offcanvas-sidebar .nav-link:hover { background: var(--bg-sunk); color: var(--text-main); }
.sidebar .nav-link.active, .offcanvas-sidebar .nav-link.active { background: var(--primary-soft); color: var(--primary-dark); }
[data-bs-theme="dark"] .sidebar .nav-link.active,
[data-bs-theme="dark"] .offcanvas-sidebar .nav-link.active { color: var(--primary-color); }
.sidebar .nav-link .badge, .offcanvas-sidebar .nav-link .badge { margin-left: auto; font-size: 0.6rem; }
.sidebar-footer { margin-top: auto; padding-top: 0.75rem; }

.offcanvas-sidebar { width: 272px !important; background: var(--bg-card); }
.offcanvas-sidebar .nav-section {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em;
    color: var(--text-muted); font-weight: 700; padding: 0 0.75rem; margin: 1.1rem 0 0.4rem;
}

.main-content {
    margin-left: var(--sidebar-w);
    padding: 1.25rem 1.5rem 3rem;
    min-height: 100vh;
    max-width: 100%;
}

.top-navbar {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 0.7rem 1rem;
    margin-bottom: 1.25rem;
    gap: 0.5rem;
}
.page-title { font-size: 1.1rem; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.page-sub { font-size: 0.78rem; color: var(--text-muted); margin: 0; }

.icon-btn {
    width: 38px; height: 38px; flex: none;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    color: var(--text-main);
    cursor: pointer;
    transition: var(--transition);
}
.icon-btn:hover { background: var(--primary-light); color: var(--primary-dark); }

/* ==========================================================================
   Mobile tab bar — the app's primary navigation under lg. Floating pill with
   a raised centre action, the way a real wallet app does it.
   ========================================================================== */

.tabbar {
    position: fixed;
    left: 12px; right: 12px;
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    z-index: 1035;
    display: flex;
    align-items: flex-end;
    height: var(--tabbar-h);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 20px;
    box-shadow: 0 -2px 10px -6px rgba(0,0,0,.12), 0 12px 30px -14px rgba(0,0,0,.3);
    padding: 0 4px;
}
[data-bs-theme="dark"] .tabbar {
    box-shadow: 0 12px 34px -14px rgba(0,0,0,.9);
    background: #141a17;
}

.tabbar a {
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px;
    color: var(--text-muted);
    font-size: 0.62rem; font-weight: 700; letter-spacing: -0.01em;
    padding: 0 2px;
    position: relative;
    transition: color .18s ease;
}
.tabbar a span {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabbar a .tb-ico {
    width: 30px; height: 30px; border-radius: 10px;
    display: grid; place-items: center; font-size: 1rem;
    transition: background .18s ease, color .18s ease, transform .18s ease;
}
.tabbar a.active { color: var(--primary-dark); }
.tabbar a.active .tb-ico {
    background: var(--primary-light);
    color: var(--primary-dark);
    transform: translateY(-1px);
}
[data-bs-theme="dark"] .tabbar a.active { color: var(--primary-color); }
[data-bs-theme="dark"] .tabbar a.active .tb-ico { color: var(--primary-color); }

/* the raised centre action */
.tabbar a.tb-fab {
    flex: 0 0 68px;
    justify-content: flex-end;
    padding-bottom: 7px;
}
/* Lemon, like every other primary action and like the mockups. Brand green
   is for icons, links and positive figures; a thing you press is lemon. */
.tabbar a.tb-fab .tb-ico {
    width: 50px; height: 50px; border-radius: 17px;
    background: var(--lemon);
    color: var(--lemon-ink);
    font-size: 1.15rem;
    margin-top: -26px;
    border: 4px solid var(--bg-body);
    box-shadow: 0 8px 18px -8px rgba(178, 251, 12, .9);
}
.tabbar a.tb-fab.active .tb-ico,
.tabbar a.tb-fab .tb-ico { color: var(--lemon-ink); transform: none; }
.tabbar a.tb-fab.active { color: var(--primary-dark); }
[data-bs-theme="dark"] .tabbar a.tb-fab .tb-ico { border-color: var(--bg-body); }

/* unread dot on a tab */
.tabbar a .tb-dot {
    position: absolute; top: 7px; left: 50%; margin-left: 8px;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--down); border: 1.5px solid var(--bg-card);
}

/* ==================== Balance card (from the mockups) ==================== */

.balance-card {
    position: relative; overflow: hidden;
    /* The mockup's green deepens to the right, under the lemon glow. */
    background: linear-gradient(115deg, var(--hero-bg) 40%, #1F3309 100%);
    border: 1px solid var(--hero-edge);
    border-radius: var(--radius-lg);
    color: var(--hero-text);
    padding: 1.15rem 1.25rem;
}
.balance-card::after {
    content: ""; position: absolute;
    top: -70px; right: -50px; width: 220px; height: 220px;
    background: radial-gradient(closest-side, rgba(178, 251, 12, .30), transparent);
    pointer-events: none;
}
.balance-card > * { position: relative; z-index: 1; }
.bc-label {
    font-size: 0.75rem; color: var(--hero-dim); font-weight: 600;
    display: flex; align-items: center; gap: 0.45rem;
}
.bc-amount {
    font-size: clamp(1.65rem, 7vw, 2.05rem);
    font-weight: 800; letter-spacing: -0.035em; line-height: 1.12;
    margin: 0.3rem 0 0;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}
.bc-chip {
    background: rgba(178, 251, 12, .18);
    border: 1px solid rgba(178, 251, 12, .4);
    color: #B2FB0C;
    border-radius: 99px; padding: 2px 11px;
    font-size: 0.68rem; font-weight: 800; letter-spacing: .03em;
    white-space: nowrap;
}
.bc-sub-label { font-size: 0.68rem; color: var(--hero-dim); font-weight: 600; margin-top: 0.55rem; }
.bc-sub-value { font-size: 0.95rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.bc-link {
    color: #B2FB0C; font-size: 0.74rem; font-weight: 800;
    display: inline-flex; align-items: center; gap: 0.3rem;
}
.bc-link:hover { color: #C4FF3A; }

/* The two lines a customer copies from Home: the Kaastro Pay ID other
   customers pay by, and the bank account a transfer lands in. The copy
   buttons are lemon, the one colour on the card that means "press", and
   36px square so a thumb finds them. */
.bc-lines { margin-top: 0.75rem; }
.bc-line {
    display: flex; align-items: center; gap: 0.6rem;
    min-height: 42px;
    font-size: 0.8rem; font-weight: 600;
    color: var(--hero-text);
}
.bc-line + .bc-line { border-top: 1px solid rgba(255, 255, 255, 0.12); }
.bc-line > i { flex: none; width: 16px; text-align: center; color: var(--hero-dim); }
.bc-val {
    flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.bc-line.is-pending { color: var(--hero-dim); font-size: 0.76rem; }
.bc-line.is-pending .bc-link { flex: none; }
.bc-copy {
    flex: none; width: 36px; height: 36px; margin-right: -8px;
    display: grid; place-items: center;
    background: none; border: 0; border-radius: 10px;
    color: var(--lemon); font-size: 1rem;
    transition: var(--transition);
}
.bc-copy:hover { background: rgba(178, 251, 12, 0.12); color: var(--lemon-hover); }
.bc-copy:focus-visible { outline: 2px solid var(--lemon); outline-offset: 1px; }

/* four action tiles, the row under the balance card */
.action-row {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
}
.action-tile {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.7rem 0.35rem;
    display: flex; flex-direction: column; align-items: center; gap: 0.45rem;
    color: var(--text-main);
    font-size: 0.72rem; font-weight: 700; text-align: center;
    transition: var(--transition);
    min-width: 0;
}
.action-tile span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.action-tile:hover { border-color: var(--primary-color); color: var(--text-main); transform: translateY(-2px); }

/* 4 × 2 service grid */
.service-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.65rem 0.4rem;
}
.service-tile {
    display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
    color: var(--text-main); font-size: 0.7rem; font-weight: 600; text-align: center;
    min-width: 0;
}
.service-tile span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.service-tile:hover { color: var(--primary-dark); }
[data-bs-theme="dark"] .service-tile:hover { color: var(--primary-color); }
.service-tile .qa-icon { transition: var(--transition); }
.service-tile:hover .qa-icon { transform: translateY(-2px); }
.service-badge {
    position: absolute; top: -4px; right: -8px;
    background: var(--down); color: #fff;
    font-size: 0.52rem; font-weight: 800; letter-spacing: .04em;
    padding: 1px 5px; border-radius: 99px; text-transform: uppercase;
}

/* icon chips */
.qa-icon {
    width: 46px; height: 46px; border-radius: 15px;
    display: grid; place-items: center; font-size: 1rem;
    flex: none; position: relative;
}
.qa-icon.sm { width: 34px; height: 34px; border-radius: 11px; font-size: 0.78rem; }
.qa-icon.lg { width: 54px; height: 54px; border-radius: 18px; font-size: 1.25rem; }
.qa-green  { background: var(--primary-light); color: var(--primary-dark); }
.qa-red    { background: rgba(239,68,68,0.12);  color: #dc2626; }
.qa-blue   { background: rgba(14,165,233,0.12); color: #0284c7; }
.qa-purple { background: rgba(139,92,246,0.12); color: #7c3aed; }
.qa-amber  { background: rgba(245,158,11,0.13); color: #b45309; }
.qa-slate  { background: var(--bg-sunk);        color: var(--text-muted); }
[data-bs-theme="dark"] .qa-green  { color: var(--primary-color); }
[data-bs-theme="dark"] .qa-red    { color: #f87171; }

/* In dark the mockups drop the blue/purple/amber accents entirely: every
   neutral action icon is one green on one sunk tile. Colour is reserved for
   meaning — red for failure, amber for a warning you must read. The classes
   stay so light mode and the back-office keep their existing variety. */
[data-bs-theme="dark"] .qa-blue,
[data-bs-theme="dark"] .qa-purple,
[data-bs-theme="dark"] .qa-amber {
    background: var(--primary-light);
    color: var(--primary-color);
}
[data-bs-theme="dark"] .qa-amber.qa-warn { background: rgba(245,158,11,0.14); color: #fbbf24; }

/* ============================ Cards ============================ */

.card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.card-title { font-size: 0.95rem; font-weight: 700; letter-spacing: -0.01em; margin: 0; }

.section-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.75rem; margin-bottom: 0.7rem;
}
.section-head h2 { font-size: 0.98rem; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.section-head a { font-size: 0.76rem; font-weight: 800; white-space: nowrap; }

.portfolio-card {
    background: var(--bg-card); border: 1px solid var(--border-color);
    border-radius: var(--radius-lg); padding: 1.15rem 1.25rem;
}
.portfolio-card .pc-amount {
    font-size: 1.5rem; font-weight: 800; letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}

.stat-tile {
    background: var(--bg-card); border: 1px solid var(--border-color);
    border-radius: var(--radius-lg); padding: 0.95rem 1rem; height: 100%;
}
.stat-tile .st-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.stat-tile .st-label {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--text-muted); font-weight: 700; line-height: 1.3;
}
.stat-tile .st-icon { width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center; font-size: 0.78rem; flex: none; }
.stat-tile .st-value {
    font-size: clamp(1.1rem, 3.4vw, 1.35rem); font-weight: 800; letter-spacing: -0.03em;
    margin: 0.45rem 0 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.stat-tile .st-delta { font-size: 0.72rem; font-weight: 700; }
.stat-tile .st-note { font-size: 0.71rem; color: var(--text-muted); line-height: 1.35; }

/* ============================ Rows ============================ */

.asset-icon {
    width: 38px; height: 38px; flex: none; border-radius: 50%;
    display: grid; place-items: center; font-weight: 800; font-size: 0.7rem; color: #fff;
    letter-spacing: -0.02em;
}
.asset-icon.sm { width: 30px; height: 30px; font-size: 0.58rem; }
.asset-icon.lg { width: 46px; height: 46px; font-size: 0.82rem; }

.asset-row {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.7rem 0; border-bottom: 1px solid var(--border-color);
    min-width: 0;
}
.asset-row:last-child { border-bottom: none; }
.asset-row .ar-name { font-weight: 700; font-size: 0.86rem; line-height: 1.25; }
.asset-row .ar-sub { font-size: 0.73rem; color: var(--text-muted); line-height: 1.3; }
.asset-row .ar-right { margin-left: auto; text-align: right; white-space: nowrap; }
.asset-row .ar-amt { font-weight: 700; font-size: 0.86rem; font-variant-numeric: tabular-nums; }

.tx-row {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.65rem 0; border-bottom: 1px solid var(--border-color);
    min-width: 0;
}
.tx-row:last-child { border-bottom: none; }
.tx-icon { width: 36px; height: 36px; flex: none; border-radius: 12px; display: grid; place-items: center; font-size: 0.78rem; }
.tx-in   { background: var(--primary-light); color: var(--primary-dark); }
.tx-out  { background: rgba(239,68,68,0.12); color: #dc2626; }
.tx-swap { background: rgba(139,92,246,0.12); color: #7c3aed; }
[data-bs-theme="dark"] .tx-in { color: var(--primary-color); }
[data-bs-theme="dark"] .tx-out { color: #f87171; }
[data-bs-theme="dark"] .tx-swap { color: #a78bfa; }
.tx-meta { min-width: 0; flex: 1; }
.tx-meta b { display: block; font-size: 0.83rem; font-weight: 700; line-height: 1.25;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tx-meta small { font-size: 0.71rem; color: var(--text-muted); display: block;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tx-amt-col { margin-left: auto; text-align: right; white-space: nowrap; flex: none; }
.tx-amt-col .amt { font-weight: 700; font-size: 0.83rem; display: block; font-variant-numeric: tabular-nums; }
.tx-amt-col small { font-size: 0.68rem; color: var(--text-muted); }

.day-label {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: var(--text-muted); font-weight: 800; margin: 1rem 0 0.2rem;
}

/* ============================ Pills ============================ */

.pill {
    display: inline-flex; align-items: center; gap: 0.3rem;
    font-size: 0.67rem; font-weight: 700; letter-spacing: 0.02em;
    padding: 0.18rem 0.55rem; border-radius: 99px; white-space: nowrap;
    border: 1px solid transparent; line-height: 1.5;
}
.pill i { font-size: 0.52rem; }
.pill-success    { background: rgba(178, 251, 12, 0.12); color: #557800; border-color: rgba(178, 251, 12, 0.3); }
.pill-pending    { background: rgba(245,158,11,0.13); color: #b45309; border-color: rgba(245,158,11,0.32); }
.pill-confirming { background: rgba(14,165,233,0.12); color: #0369a1; border-color: rgba(14,165,233,0.3); }
.pill-processing { background: rgba(99,102,241,0.12); color: #4338ca; border-color: rgba(99,102,241,0.3); }
.pill-failed,
.pill-rejected   { background: rgba(239,68,68,0.12);  color: #b91c1c; border-color: rgba(239,68,68,0.3); }
.pill-danger     { background: rgba(239,68,68,0.12);  color: #b91c1c; border-color: rgba(239,68,68,0.3); }
.pill-warn       { background: rgba(245,158,11,0.13); color: #b45309; border-color: rgba(245,158,11,0.32); }
.pill-manual     { background: rgba(139,92,246,0.13); color: #6d28d9; border-color: rgba(139,92,246,0.3); }
.pill-neutral    { background: var(--bg-sunk);        color: var(--text-muted); border-color: var(--border-color); }
[data-bs-theme="dark"] .pill-success    { color: #B2FB0C; }
[data-bs-theme="dark"] .pill-pending    { color: #fbbf24; }
[data-bs-theme="dark"] .pill-confirming { color: #38bdf8; }
[data-bs-theme="dark"] .pill-processing { color: #a5b4fc; }
[data-bs-theme="dark"] .pill-failed,
[data-bs-theme="dark"] .pill-rejected   { color: #f87171; }
[data-bs-theme="dark"] .pill-manual     { color: #c4b5fd; }
[data-bs-theme="dark"] .pill-danger     { color: #f87171; }
[data-bs-theme="dark"] .pill-warn       { color: #fbbf24; }

.tier-badge {
    display: inline-block; font-size: 0.61rem; font-weight: 800;
    padding: 1px 7px; border-radius: 99px; letter-spacing: 0.03em; white-space: nowrap;
}
.tier-0 { background: var(--bg-sunk); color: var(--text-muted); }
.tier-1 { background: rgba(14,165,233,0.14); color: #0369a1; }
.tier-2 { background: rgba(139,92,246,0.14); color: #6d28d9; }
.tier-3 { background: var(--primary-light); color: var(--primary-dark); }
[data-bs-theme="dark"] .tier-1 { color: #38bdf8; }
[data-bs-theme="dark"] .tier-2 { color: #c4b5fd; }
[data-bs-theme="dark"] .tier-3 { color: var(--primary-color); }

/* ============================ Forms ============================ */

.form-label { font-size: 0.77rem; font-weight: 700; color: var(--text-main); margin-bottom: 0.35rem; }
.form-control, .form-select {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    color: var(--text-main);
    border-radius: var(--radius-md);
    padding: 0.6rem 0.85rem;
    font-size: 0.88rem;
    font-weight: 500;
}
.form-control:focus, .form-select:focus {
    background: var(--bg-card); color: var(--text-main);
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--primary-soft);
}
.form-control::placeholder { color: var(--text-muted); opacity: 0.75; }
.form-control:disabled, .form-control[readonly] { background: var(--bg-sunk); }
.form-text { font-size: 0.72rem; color: var(--text-muted); }
.input-group-text { background: var(--bg-sunk); border-color: var(--border-color); color: var(--text-muted); font-size: 0.84rem; }

.btn { font-weight: 700; font-size: 0.87rem; border-radius: var(--radius-md); padding: 0.6rem 1.1rem; transition: var(--transition); }
.btn-primary {
    background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink);
    box-shadow: 0 6px 16px -8px rgba(178, 251, 12, .8);
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background: var(--lemon-hover) !important; border-color: var(--lemon-hover) !important;
    color: var(--lemon-ink) !important;
}
.btn-primary:disabled {
    background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink);
    opacity: 0.4; box-shadow: none;
}
.btn-outline-primary { color: var(--primary-dark); border-color: var(--lemon-dark); }
.btn-outline-primary:hover { background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink); }
.btn-soft { background: var(--bg-sunk); border: 1px solid var(--border-color); color: var(--text-main); }
.btn-soft:hover { background: var(--border-color); color: var(--text-main); }
.btn-sm { font-size: 0.77rem; padding: 0.35rem 0.7rem; }
.btn-lg { font-size: 0.95rem; padding: 0.75rem 1.4rem; }

.amount-box {
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.8rem 0.9rem;
}
.amount-box .ab-label { font-size: 0.7rem; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; }
.amount-box input {
    background: transparent; border: none; outline: none; width: 100%; min-width: 0;
    font-size: clamp(1.15rem, 5vw, 1.45rem); font-weight: 800; color: var(--text-main);
    letter-spacing: -0.03em; padding: 0.15rem 0 0;
    font-variant-numeric: tabular-nums;
}
.amount-box input::placeholder { color: var(--text-muted); opacity: 0.4; }
.amount-box .ab-side {
    display: flex; align-items: center; gap: 0.35rem;
    background: var(--bg-card); border: 1px solid var(--border-color);
    border-radius: 99px; padding: 0.22rem 0.6rem 0.22rem 0.28rem;
    font-weight: 700; font-size: 0.8rem; white-space: nowrap; cursor: pointer;
    flex: none;
}
.swap-flip {
    width: 36px; height: 36px; border-radius: 12px;
    background: var(--bg-card); border: 2px solid var(--bg-body);
    box-shadow: var(--shadow-md);
    display: grid; place-items: center; color: var(--primary-dark);
    cursor: pointer; transition: var(--transition);
}
.swap-flip:hover { transform: rotate(180deg); }
[data-bs-theme="dark"] .swap-flip { color: var(--primary-color); }

.summary-rows { background: var(--bg-sunk); border-radius: var(--radius-md); padding: 0.8rem 0.95rem; }
.summary-rows .sr {
    display: flex; justify-content: space-between; align-items: baseline; gap: 0.85rem;
    padding: 0.3rem 0; font-size: 0.82rem;
}
.summary-rows .sr span:first-child { color: var(--text-muted); font-weight: 500; flex: none; }
.summary-rows .sr span:last-child { font-weight: 700; text-align: right; overflow-wrap: anywhere; }
.summary-rows .sr.total { border-top: 1px dashed var(--border-color); margin-top: 0.3rem; padding-top: 0.5rem; font-size: 0.9rem; }

.seg { display: inline-flex; background: var(--bg-sunk); border: 1px solid var(--border-color);
    border-radius: 99px; padding: 3px; gap: 2px; max-width: 100%; overflow-x: auto; }
.seg button {
    border: none; background: transparent; color: var(--text-muted);
    font-size: 0.78rem; font-weight: 700; padding: 0.32rem 0.85rem; border-radius: 99px;
    transition: var(--transition); cursor: pointer; white-space: nowrap;
}
.seg button.active { background: var(--bg-card); color: var(--primary-dark); box-shadow: var(--shadow-sm); }
[data-bs-theme="dark"] .seg button.active { color: var(--primary-color); }

.stepper { display: flex; align-items: center; gap: 0.4rem; }
.stepper .stp { display: flex; align-items: center; gap: 0.4rem; font-size: 0.75rem; font-weight: 700; color: var(--text-muted); white-space: nowrap; }
.stepper .stp .n { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
    background: var(--bg-sunk); border: 1px solid var(--border-color); font-size: 0.66rem; flex: none; }
.stepper .stp.on { color: var(--primary-dark); }
.stepper .stp.on .n { background: var(--primary-color); border-color: var(--primary-color); color: #fff; }
.stepper .stp.done .n { background: var(--primary-light); border-color: var(--primary-color); color: var(--primary-dark); }
[data-bs-theme="dark"] .stepper .stp.on { color: var(--primary-color); }
.stepper .line { flex: 1; height: 1px; background: var(--border-color); min-width: 8px; }

.qr-box {
    background: #fff; border: 1px solid var(--border-color);
    border-radius: var(--radius-md); padding: 0.7rem;
    display: inline-grid; place-items: center;
}
.address-box {
    background: var(--bg-sunk); border: 1px dashed var(--border-color);
    border-radius: var(--radius-md); padding: 0.65rem 0.8rem;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 0.76rem; word-break: break-all; line-height: 1.5;
}

.net-opt {
    display: flex; align-items: center; gap: 0.65rem;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    padding: 0.6rem 0.8rem; cursor: pointer; transition: var(--transition);
    background: var(--bg-card); width: 100%; text-align: left; color: var(--text-main);
    min-width: 0;
}
.net-opt:hover { border-color: var(--primary-color); }
.net-opt.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.net-opt .no-name { font-weight: 700; font-size: 0.84rem; line-height: 1.25; display: block; }
.net-opt .no-sub { font-size: 0.71rem; color: var(--text-muted); display: block; line-height: 1.3; }
.net-opt > span:nth-child(2) { min-width: 0; flex: 1; }
.net-opt .no-check { margin-left: auto; color: var(--primary-dark); opacity: 0; flex: none; }
.net-opt.selected .no-check { opacity: 1; }
[data-bs-theme="dark"] .net-opt .no-check { color: var(--primary-color); }

.k-alert {
    display: flex; gap: 0.65rem; align-items: flex-start;
    border-radius: var(--radius-md); padding: 0.7rem 0.85rem;
    font-size: 0.79rem; line-height: 1.45; border: 1px solid transparent;
}
.k-alert i { margin-top: 2px; flex: none; }
/* <b> stays inline, because it is an inline element and mid-sentence emphasis
   ("send only <b>USDT</b> on <b>TRC20</b>") has to read as one sentence. An
   alert that opens with a heading marks it explicitly with .hd. */
.k-alert b { font-weight: 800; }
.k-alert b.hd { display: block; margin-bottom: 2px; }
.k-warn   { background: rgba(245,158,11,0.10); border-color: rgba(245,158,11,0.35); color: #92400e; }
.k-info   { background: rgba(14,165,233,0.09); border-color: rgba(14,165,233,0.3);  color: #075985; }
.k-danger { background: rgba(239,68,68,0.09);  border-color: rgba(239,68,68,0.3);   color: #991b1b; }
.k-ok     { background: var(--primary-soft);   border-color: rgba(178, 251, 12, 0.35); color: #4A6800; }
[data-bs-theme="dark"] .k-warn { color: #fcd34d; }
[data-bs-theme="dark"] .k-info { color: #7dd3fc; }
[data-bs-theme="dark"] .k-danger { color: #fca5a5; }
[data-bs-theme="dark"] .k-ok { color: #C4FF3A; }

/* ============================ Tables ============================ */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.k-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; min-width: 640px; }
table.k-table thead th {
    text-align: left; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--text-muted); font-weight: 800; padding: 0.6rem 0.8rem;
    border-bottom: 1px solid var(--border-color); background: var(--bg-sunk); white-space: nowrap;
}
table.k-table tbody td { padding: 0.65rem 0.8rem; border-bottom: 1px solid var(--border-color); vertical-align: middle; }
table.k-table tbody tr:last-child td { border-bottom: none; }
table.k-table tbody tr:hover { background: var(--bg-sunk); }
table.k-table .t-strong { font-weight: 700; }
table.k-table .t-mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.73rem; color: var(--text-muted); }

/* --- DataTables, themed to match --- */
table.dataTable { width: 100% !important; border-collapse: collapse !important; font-size: 0.82rem; }
table.dataTable thead th {
    text-align: left; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--text-muted) !important; font-weight: 800; padding: 0.65rem 0.8rem !important;
    border-bottom: 1px solid var(--border-color) !important;
    background: var(--bg-sunk) !important; white-space: nowrap;
}
table.dataTable tbody td {
    padding: 0.65rem 0.8rem !important;
    border-bottom: 1px solid var(--border-color) !important;
    color: var(--text-main); vertical-align: middle;
}
table.dataTable tbody tr { background: var(--bg-card) !important; }
table.dataTable tbody tr:hover { background: var(--bg-sunk) !important; }
table.dataTable.no-footer { border-bottom: none !important; }
table.dataTable.dt-nowrap > thead > tr > th,
table.dataTable.dt-nowrap > tbody > tr > td { white-space: nowrap; }
table.dataTable.dt-nowrap > tbody > tr.child > td { white-space: normal; }

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate { color: var(--text-muted) !important; font-size: 0.79rem; }
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
    background: var(--bg-card) !important; border: 1px solid var(--border-color) !important;
    color: var(--text-main) !important; border-radius: var(--radius-sm);
    padding: 0.3rem 0.6rem; font-size: 0.82rem;
}
.dataTables_wrapper .dataTables_filter input:focus {
    outline: none; border-color: var(--primary-color) !important;
    box-shadow: 0 0 0 3px var(--primary-soft);
}
/* --- pagination ---
   DataTables' Bootstrap 5 integration renders
     <li class="paginate_button page-item"><a class="page-link">1</a></li>
   so .paginate_button is the LI, not the button. Styling both it and the
   .page-link inside drew one button inside another. The box belongs to the
   anchor; the li is stripped back to a plain list item. Legacy DataTables
   markup, where .paginate_button is itself the anchor, still gets the box. */
.dataTables_wrapper .dataTables_paginate {
    padding-top: 0.85rem !important;
    display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; align-items: center;
}
.dataTables_wrapper .dataTables_paginate .pagination { gap: 4px; margin: 0; flex-wrap: wrap; }
.dataTables_wrapper .dataTables_paginate li.paginate_button {
    background: none !important;
    border: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
    min-width: 0;
    height: auto;
}
.dataTables_wrapper .dataTables_paginate a.paginate_button,
.dataTables_wrapper .dataTables_paginate .page-item .page-link {
    min-width: 34px; height: 34px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 0.55rem !important;
    margin: 0 !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 9px !important;
    background: var(--bg-card) !important;
    color: var(--text-main) !important;
    font-size: 0.8rem; font-weight: 700;
    line-height: 1;
    transition: var(--transition);
    box-shadow: none !important;
}
.dataTables_wrapper .dataTables_paginate a.paginate_button:hover,
.dataTables_wrapper .dataTables_paginate .page-item:not(.disabled):not(.active) .page-link:hover {
    background: var(--primary-soft) !important;
    border-color: var(--primary-color) !important;
    color: var(--primary-dark) !important;
}
[data-bs-theme="dark"] .dataTables_wrapper .dataTables_paginate a.paginate_button:hover,
[data-bs-theme="dark"] .dataTables_wrapper .dataTables_paginate .page-item:not(.disabled):not(.active) .page-link:hover {
    color: var(--primary-color) !important;
}
.dataTables_wrapper .dataTables_paginate a.paginate_button.current,
.dataTables_wrapper .dataTables_paginate a.paginate_button.current:hover,
.dataTables_wrapper .dataTables_paginate .page-item.active .page-link {
    background: var(--primary-color) !important;
    border-color: var(--primary-color) !important;
    color: #0B1A02 !important;
    box-shadow: 0 4px 10px -5px rgba(178, 251, 12, .9) !important;
}
.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled,
.dataTables_wrapper .dataTables_paginate a.paginate_button.disabled:hover,
.dataTables_wrapper .dataTables_paginate .page-item.disabled .page-link {
    background: var(--bg-sunk) !important;
    border-color: var(--border-color) !important;
    color: var(--text-muted) !important;
    opacity: .5; cursor: not-allowed;
}
.dataTables_wrapper .dataTables_paginate .ellipsis {
    color: var(--text-muted); padding: 0 4px; font-weight: 700;
}
.dataTables_wrapper .dataTables_info { padding-top: 0.95rem !important; font-weight: 600; }
@media (max-width: 575.98px) {
    .dataTables_wrapper .dataTables_paginate { justify-content: center; }
    .dataTables_wrapper .dataTables_info { text-align: center; }
}

table.dataTable > tbody > tr.child ul.dtr-details { width: 100%; }
table.dataTable > tbody > tr.child span.dtr-title { color: var(--text-muted); font-weight: 700; min-width: 92px; }
/* The expand control: a small round + that flips to a − when open. */
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control { position: relative; padding-left: 30px !important; }
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before {
    content: "+" !important;
    position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
    width: 17px; height: 17px; border-radius: 50%;
    background: var(--primary-color) !important;
    color: #fff !important; border: none !important; box-shadow: none !important;
    font-size: 12px !important; font-weight: 700; line-height: 17px !important;
    text-align: center; margin: 0 !important; display: block;
}
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td.dtr-control:before {
    content: "−" !important; background: var(--text-muted) !important;
}
.dt-empty { text-align: center; color: var(--text-muted); padding: 1.5rem 0; }

.empty-state { text-align: center; padding: 2.2rem 1rem; color: var(--text-muted); }
.empty-state i { font-size: 1.9rem; opacity: 0.35; display: block; margin-bottom: 0.55rem; }
.empty-state p { font-size: 0.84rem; margin: 0; }

.chart-holder { position: relative; width: 100%; }
.card canvas, .chart-holder canvas { display: block; width: 100%; }

.filterbar { display: flex; flex-wrap: wrap; gap: 0.45rem; align-items: center; }
.chip-btn {
    border: 1px solid var(--border-color); background: var(--bg-card); color: var(--text-muted);
    font-size: 0.75rem; font-weight: 700; border-radius: 99px; padding: 0.28rem 0.75rem;
    cursor: pointer; transition: var(--transition); white-space: nowrap;
}
.chip-btn:hover { border-color: var(--primary-color); color: var(--primary-dark); }
.chip-btn.active { background: var(--primary-soft); border-color: var(--primary-color); color: var(--primary-dark); }
[data-bs-theme="dark"] .chip-btn.active, [data-bs-theme="dark"] .chip-btn:hover { color: var(--primary-color); }

.sys-banner {
    display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
    border-radius: var(--radius-md); padding: 0.7rem 0.95rem; margin-bottom: 1rem;
    font-size: 0.81rem; border: 1px solid;
}
.sys-banner b { font-weight: 800; }
.sys-panic { background: rgba(239,68,68,0.10); border-color: rgba(239,68,68,0.35); color: #991b1b; }
.sys-shift { background: rgba(245,158,11,0.10); border-color: rgba(245,158,11,0.35); color: #92400e; }
.sys-kyc   { background: rgba(14,165,233,0.09); border-color: rgba(14,165,233,0.3);  color: #075985; }
[data-bs-theme="dark"] .sys-panic { color: #fca5a5; }
[data-bs-theme="dark"] .sys-shift { color: #fcd34d; }
[data-bs-theme="dark"] .sys-kyc { color: #7dd3fc; }

/* ============================ Overlays ============================ */

.modal-content { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-lg); }
.modal-header, .modal-footer { border-color: var(--border-color); }
.modal-title { font-size: 0.98rem; font-weight: 800; }

.pin-dots { display: flex; gap: 0.55rem; justify-content: center; }
.pin-dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--border-color); }
.pin-dot.filled { background: var(--primary-color); border-color: var(--primary-color); }
.pin-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; max-width: 260px; margin: 0 auto; }
.pin-keys button {
    background: var(--bg-sunk); border: 1px solid var(--border-color); color: var(--text-main);
    border-radius: var(--radius-md); padding: 0.68rem 0; font-size: 1.05rem; font-weight: 700; cursor: pointer;
    transition: var(--transition);
}
.pin-keys button:hover { background: var(--primary-soft); border-color: var(--primary-color); }

.receipt { background: var(--bg-sunk); border: 1px dashed var(--border-color); border-radius: var(--radius-md); padding: 0.95rem; }
.receipt .rc-amt { font-size: 1.4rem; font-weight: 800; letter-spacing: -0.03em; overflow-wrap: anywhere; }

.divider-text { display: flex; align-items: center; gap: 0.7rem; color: var(--text-muted); font-size: 0.74rem; font-weight: 600; }
.divider-text::before, .divider-text::after { content: ""; flex: 1; height: 1px; background: var(--border-color); }

.dropdown-menu { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.dropdown-item { color: var(--text-main); font-size: 0.84rem; font-weight: 600; border-radius: var(--radius-sm); }
.dropdown-item:hover { background: var(--bg-sunk); color: var(--text-main); }
.dropdown-divider { border-color: var(--border-color); }

.nav-tabs { border-bottom-color: var(--border-color); flex-wrap: nowrap; overflow-x: auto; }
.nav-tabs .nav-link {
    color: var(--text-muted); font-weight: 700; font-size: 0.84rem;
    border: none; border-bottom: 2px solid transparent; white-space: nowrap;
}
.nav-tabs .nav-link.active { color: var(--primary-dark); background: transparent; border-bottom-color: var(--primary-color); }
[data-bs-theme="dark"] .nav-tabs .nav-link.active { color: var(--primary-color); }

.accordion-item { background: transparent; border-color: var(--border-color); }
.accordion-button { background: transparent; color: var(--text-main); font-size: 0.86rem; font-weight: 700; }
.accordion-button:not(.collapsed) { background: var(--primary-soft); color: var(--primary-dark); box-shadow: none; }
.accordion-button:focus { box-shadow: none; border-color: var(--border-color); }
[data-bs-theme="dark"] .accordion-button:not(.collapsed) { color: var(--primary-color); }
[data-bs-theme="dark"] .accordion-button::after { filter: invert(1) grayscale(1) brightness(1.6); }
.accordion-body { color: var(--text-muted); font-size: 0.83rem; }

.progress { background: var(--bg-sunk); }
hr { border-color: var(--border-color); opacity: 1; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--bg-body); }
::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 99px; }

/* ============================ Responsive ============================ */

@media (max-width: 1199.98px) {
    :root { --sidebar-w: 232px; }
}

@media (max-width: 991.98px) {
    .main-content { margin-left: 0; padding: 0.85rem 0.85rem 1.75rem; }
    /* Only the user portal has a bottom tab bar, so only it reserves room. */
    body[data-portal="user"] .main-content { padding-bottom: calc(var(--tabbar-h) + 2rem); }
    .top-navbar { padding: 0.6rem 0.75rem; margin-bottom: 0.85rem; }
    .page-title { font-size: 1rem; }
    .page-sub { display: none; }
}

@media (max-width: 575.98px) {
    body { font-size: 0.9rem; }
    /* 0.75rem, not 0.7rem: a Bootstrap .row reaches 12px (0.75rem) out into
       this padding, and 0.7rem left it 0.8px short, so every phone page
       scrolled sideways by a fraction of a pixel. */
    .main-content { padding: 0.75rem 0.75rem 1.5rem; }
    body[data-portal="user"] .main-content { padding-bottom: calc(var(--tabbar-h) + 1.75rem); }
    .card { border-radius: 0.85rem; }
    .balance-card { padding: 1rem; }
    .action-row { gap: 0.4rem; }
    .action-tile { padding: 0.6rem 0.2rem; font-size: 0.67rem; }
    .action-tile .qa-icon { width: 40px; height: 40px; font-size: 0.9rem; border-radius: 13px; }
    .service-grid { gap: 0.6rem 0.25rem; }
    .service-tile { font-size: 0.65rem; }
    .service-tile .qa-icon { width: 42px; height: 42px; font-size: 0.92rem; }
    .stat-tile { padding: 0.8rem 0.85rem; }
    .stat-tile .st-icon { display: none; }
    .summary-rows { padding: 0.7rem 0.8rem; }
    .summary-rows .sr { font-size: 0.79rem; }
    .modal-dialog { margin: 0.5rem; }
    .filterbar { gap: 0.35rem; }
    .chip-btn { font-size: 0.72rem; padding: 0.25rem 0.65rem; }
    .dataTables_wrapper .dataTables_filter { width: 100%; text-align: left !important; margin-bottom: 0.5rem; }
    .dataTables_wrapper .dataTables_filter input { width: 100%; margin-left: 0 !important; }
    .dataTables_wrapper .dataTables_length { display: none; }
    .qr-box { padding: 0.5rem; }
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ==========================================================================
   Brand artwork — the supplied logo replaces the lettermark everywhere.
   The wordmark's "PAY" is near-white, so on light grounds it gets a hairline
   shadow to stay legible.
   ========================================================================== */

.brand-logo { gap: 0.5rem; flex-wrap: wrap; }
/* The sidebar flips between light and dark, and the wordmark's "PAY" is
   near-white — legible on one, invisible on the other. Both variants ship and
   CSS picks the right one, which replaces an earlier drop-shadow outline that
   only ever made the white text look fuzzy. */
.brand-img { height: 38px; display: block; max-width: 100%; }
.brand-img > img { height: 100%; width: auto; max-width: 100%; display: block; }
.brand-img > .bi-dark { display: none; }
[data-bs-theme="dark"] .brand-img > .bi-light { display: none; }
[data-bs-theme="dark"] .brand-img > .bi-dark { display: block; }
/* Pages that still use a bare <img class="brand-img"> keep sizing correctly. */
img.brand-img { height: 38px; width: auto; }
.brand-tag {
    font-size: 0.58rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--text-muted); border-left: 1px solid var(--border-color);
    padding-left: 0.5rem; line-height: 1;
}
.sidebar .brand-logo { padding-bottom: 0.5rem; }

/* ============================ Notifications ============================ */

.notif-row {
    display: flex; gap: 0.75rem; padding: 0.85rem 0;
    border-bottom: 1px solid var(--border-color); min-width: 0;
    position: relative;
}
.notif-row:last-child { border-bottom: none; }
.notif-row.unread::before {
    content: ""; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
    width: 6px; height: 6px; border-radius: 50%; background: var(--primary-color);
}
.notif-row .nr-body { min-width: 0; flex: 1; }
.notif-row .nr-title { font-size: 0.86rem; font-weight: 700; line-height: 1.3; }
.notif-row .nr-text { font-size: 0.79rem; color: var(--text-muted); line-height: 1.45; }
.notif-row .nr-time { font-size: 0.71rem; color: var(--text-muted); white-space: nowrap; }

/* ============================ Receipt ============================ */

.receipt-sheet {
    background: #ffffff; color: #171A14;
    border-radius: 14px; padding: 1.5rem 1.35rem;
    border: 1px solid #E5E7E1;
}
.receipt-sheet .rs-logo { height: 34px; width: auto; display: block; margin: 0 auto 0.25rem; }
.receipt-sheet .rs-tag {
    text-align: center; font-size: 0.62rem; font-weight: 800;
    letter-spacing: 0.14em; text-transform: uppercase; color: #6A6F63;
}
.receipt-sheet .rs-div { border-top: 1px dashed #cfd8d4; margin: 1rem 0; }
.receipt-sheet .rs-amt { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.03em; text-align: center; }
.receipt-sheet .rs-sub { text-align: center; font-size: 0.78rem; color: #6A6F63; }
.receipt-sheet .rs-row {
    display: flex; justify-content: space-between; gap: 1rem;
    font-size: 0.79rem; padding: 0.3rem 0;
}
.receipt-sheet .rs-row span:first-child { color: #6A6F63; flex: none; }
.receipt-sheet .rs-row span:last-child { font-weight: 700; text-align: right; overflow-wrap: anywhere; }
.receipt-sheet .rs-foot {
    text-align: center; font-size: 0.68rem; color: #8a9a93; line-height: 1.5; margin-top: 0.5rem;
}
.receipt-sheet .rs-stamp {
    display: inline-block; border: 2px solid #6B9700; color: #557800;
    border-radius: 8px; padding: 2px 10px; font-size: 0.68rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.08em; transform: rotate(-3deg);
}

/* ============================ Bills ============================ */

.biller-tile {
    display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    padding: 0.8rem 0.4rem; background: var(--bg-card); color: var(--text-main);
    font-size: 0.74rem; font-weight: 700; text-align: center;
    transition: var(--transition); width: 100%; min-width: 0;
}
.biller-tile:hover { border-color: var(--primary-color); transform: translateY(-2px); }
.biller-tile.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.biller-tile span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.amount-chip {
    border: 1.5px solid var(--border-color); background: var(--bg-card);
    color: var(--text-main); border-radius: var(--radius-md);
    padding: 0.5rem 0.25rem; font-size: 0.84rem; font-weight: 700;
    width: 100%; transition: var(--transition);
}
.amount-chip:hover { border-color: var(--primary-color); }
.amount-chip.selected { border-color: var(--primary-color); background: var(--primary-soft); color: var(--primary-dark); }
[data-bs-theme="dark"] .amount-chip.selected { color: var(--primary-color); }

/* ==================== Deposit method chooser ==================== */

.method-card {
    display: flex; gap: 0.85rem; align-items: flex-start;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-lg);
    padding: 1rem; background: var(--bg-card); color: var(--text-main);
    text-align: left; width: 100%; transition: var(--transition); min-width: 0;
}
.method-card:hover { border-color: var(--primary-color); transform: translateY(-2px); }
.method-card.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.method-card .mc-title {
    font-size: 0.95rem; font-weight: 800; letter-spacing: -0.015em;
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
}
.method-card .mc-desc { font-size: 0.81rem; color: var(--text-muted); line-height: 1.5; margin-top: 0.25rem; }
.method-card .mc-meta { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.6rem; }
.method-card .mc-body { min-width: 0; flex: 1; }

/* ==========================================================================
   Review drawer — the full record behind a queue row, with copiable fields.
   ========================================================================== */

.rv-head {
    display: flex; align-items: flex-start; gap: 0.85rem;
    padding-bottom: 0.9rem; margin-bottom: 0.9rem;
    border-bottom: 1px solid var(--border-color);
}
.rv-amount {
    font-size: 1.45rem; font-weight: 800; letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums; overflow-wrap: anywhere; line-height: 1.15;
}
.rv-sub { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.15rem; }

.rv-user {
    display: flex; align-items: center; gap: 0.7rem;
    background: var(--bg-sunk); border: 1px solid var(--border-color);
    border-radius: var(--radius-md); padding: 0.7rem 0.85rem; margin-bottom: 1rem;
}
.rv-user-name { font-size: 0.9rem; font-weight: 700; line-height: 1.2; }
.rv-user-sub { font-size: 0.74rem; color: var(--text-muted); margin-top: 2px; }

.rv-group { margin-bottom: 1.1rem; }
.rv-group:last-child { margin-bottom: 0; }
.rv-title {
    font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.11em;
    font-weight: 800; color: var(--text-muted); margin-bottom: 0.4rem;
}
.rv-row {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 0.9rem;
    padding: 0.42rem 0; border-bottom: 1px solid var(--border-color); font-size: 0.83rem;
}
.rv-row:last-child { border-bottom: none; }
.rv-k { color: var(--text-muted); font-weight: 500; flex: none; max-width: 45%; }
.rv-v {
    font-weight: 700; text-align: right; overflow-wrap: anywhere;
    display: inline-flex; align-items: flex-start; gap: 0.35rem; justify-content: flex-end;
    min-width: 0;
}
.rv-v.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.76rem; font-weight: 600; }
.rv-copy {
    flex: none; width: 22px; height: 22px; border-radius: 6px;
    border: 1px solid var(--border-color); background: var(--bg-card);
    color: var(--text-muted); font-size: 0.62rem; cursor: pointer;
    display: grid; place-items: center; transition: var(--transition);
}
.rv-copy:hover { border-color: var(--primary-color); color: var(--primary-dark); background: var(--primary-soft); }
[data-bs-theme="dark"] .rv-copy:hover { color: var(--primary-color); }

/* ==========================================================================
   Stat strip — scrolls sideways on mobile instead of eating the whole screen.
   ========================================================================== */

/* Wraps to as many rows as it needs rather than squeezing seven tiles into
   one. Under md it becomes a swipeable strip instead. */
.stat-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); gap: 0.6rem; }
.stat-strip > * { min-width: 0; }

@media (max-width: 767.98px) {
    .stat-strip {
        display: flex;
        gap: 0.55rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 2px;
        margin-inline: -0.75rem;
        padding-inline: 1rem;
        scroll-padding-inline: 1rem;
    }
    .stat-strip::-webkit-scrollbar { display: none; }
    .stat-strip > * { flex: 0 0 60%; scroll-snap-align: start; }
    .stat-strip .stat-tile { height: 100%; }
}

.strip-dots { display: flex; gap: 5px; justify-content: center; margin-top: 0.5rem; }
.strip-dots span {
    width: 6px; height: 6px; border-radius: 99px; background: var(--border-color);
    transition: var(--transition);
}
.strip-dots span.on { width: 18px; background: var(--primary-color); }
@media (min-width: 768px) { .strip-dots { display: none; } }

/* Date-range and export controls */
.range-bar {
    display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: flex-end;
}
.range-bar .rb-field { min-width: 150px; flex: 1 1 150px; }
.range-bar label { font-size: 0.7rem; font-weight: 700; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .08em; display: block; margin-bottom: 0.25rem; }

/* Document cards on the KYC review page */
.doc-card {
    position: relative; border: 1px solid var(--border-color);
    border-radius: var(--radius-md); overflow: hidden; cursor: pointer;
    background: var(--bg-sunk); transition: var(--transition);
}
.doc-card:hover { border-color: var(--primary-color); transform: translateY(-2px); }
.doc-card img { width: 100%; height: 150px; object-fit: cover; display: block; }
.doc-card .doc-meta { padding: 0.5rem 0.65rem; }
.doc-card .doc-meta b { display: block; font-size: 0.8rem; font-weight: 700; line-height: 1.25; }
.doc-card .doc-meta span { font-size: 0.71rem; color: var(--text-muted); }
.doc-card .doc-zoom {
    position: absolute; top: 8px; right: 8px;
    width: 26px; height: 26px; border-radius: 8px;
    background: rgba(0,0,0,.55); color: #fff;
    display: grid; place-items: center; font-size: 0.68rem;
}

/* A document that was never uploaded. It shows AS missing rather than as a
   broken image, because a broken image reads as our bug and this reads as the
   customer's outstanding step. */
.doc-card.is-missing {
    background: var(--bg-sunk);
    border: 1px dashed var(--border-color);
    cursor: default;
}
.doc-card.is-missing:hover { transform: none; border-color: var(--border-color); }

/* Sticky commit bar for editable admin pages */
.save-bar {
    position: sticky; bottom: 0; z-index: 5;
    display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
    margin: 1rem -0.25rem -0.25rem;
    padding: 0.7rem 0.9rem;
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    transition: var(--transition);
}
.save-bar.dirty {
    background: var(--primary-soft);
    border-color: var(--primary-color);
}
.save-bar .sb-note { font-size: 0.79rem; color: var(--text-muted); font-weight: 600; }
.save-bar.dirty .sb-note { color: var(--primary-dark); }
[data-bs-theme="dark"] .save-bar.dirty .sb-note { color: var(--primary-color); }

/* Permission rows in the agent form */
.perm-row {
    display: flex; align-items: flex-start; gap: 0.65rem;
    border: 1px solid var(--border-color); border-radius: var(--radius-md);
    padding: 0.55rem 0.7rem; cursor: pointer; transition: var(--transition);
    background: var(--bg-card);
}
.perm-row:hover { border-color: var(--primary-color); }
.perm-row:has(input:checked) { border-color: var(--primary-color); background: var(--primary-soft); }
.perm-label { display: block; font-size: 0.84rem; font-weight: 700; line-height: 1.25; }
.perm-desc { display: block; font-size: 0.74rem; color: var(--text-muted); line-height: 1.35; }

/* ==========================================================================
   Install, update and offline surfaces
   ========================================================================== */

.install-steps { display: grid; gap: 0.5rem; }
.install-step {
    display: flex; align-items: flex-start; gap: 0.7rem;
    border: 1px solid var(--border-color); border-radius: var(--radius-md);
    padding: 0.65rem 0.75rem; background: var(--bg-card);
}
.install-step .is-n {
    width: 22px; height: 22px; flex: none; border-radius: 50%;
    background: var(--lemon); color: var(--lemon-ink);
    display: grid; place-items: center; font-size: 0.68rem; font-weight: 800;
}
.install-step .is-ico {
    width: 30px; height: 30px; flex: none; border-radius: 9px;
    background: var(--bg-sunk); color: var(--text-main);
    display: grid; place-items: center; font-size: 0.78rem;
}
.install-step b { display: block; font-size: 0.85rem; font-weight: 700; line-height: 1.3; }
.install-step span span,
.install-step > span:last-child > span { display: block; font-size: 0.76rem; color: var(--text-muted); line-height: 1.4; }

.update-bar, .offline-bar {
    position: fixed; left: 12px; right: 12px; z-index: 1060;
    display: flex; align-items: center; gap: 0.6rem;
    border-radius: 14px; padding: 0.65rem 0.85rem;
    font-size: 0.82rem; font-weight: 600;
    box-shadow: 0 14px 34px -14px rgba(0, 0, 0, .6);
}
.update-bar {
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--bg-card); border: 1px solid var(--primary-color); color: var(--text-main);
    flex-wrap: wrap;
}
.offline-bar {
    top: calc(12px + env(safe-area-inset-top, 0px));
    background: #3f2a10; border: 1px solid var(--warn); color: #fcd34d;
    justify-content: center;
}
/* The user portal's tab bar already owns the bottom edge on mobile. */
body[data-portal="user"] .update-bar { bottom: calc(var(--tabbar-h) + 22px); }
@media (min-width: 576px) {
    .update-bar, .offline-bar { left: auto; right: 16px; max-width: 420px; }
    .offline-bar { left: 50%; right: auto; transform: translateX(-50%); }
}

/* "Get the app" row inside the portals */
.install-cta {
    display: flex; align-items: center; gap: 0.8rem;
    background: var(--hero-bg); border: 1px solid var(--hero-edge);
    border-radius: var(--radius-lg); padding: 0.9rem 1rem; color: var(--hero-text);
    flex-wrap: wrap;
}
.install-cta img { width: 44px; height: 44px; border-radius: 13px; flex: none; }
.install-cta b { display: block; font-size: 0.92rem; font-weight: 800; letter-spacing: -0.015em; }
.install-cta span { font-size: 0.79rem; color: var(--hero-dim); line-height: 1.45; display: block; }


/* ==========================================================================
   Lemon accents — everything that reads as a primary action.
   White is unreadable on #B2FB0C, so each of these sets its own ink.
   ========================================================================== */

.btn-install, .btn-lemon {
    background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink);
    font-weight: 800;
    box-shadow: 0 6px 16px -8px rgba(178, 251, 12, .8);
}
.btn-install:hover, .btn-lemon:hover,
.btn-install:focus, .btn-lemon:focus {
    background: var(--lemon-hover); border-color: var(--lemon-hover); color: var(--lemon-ink);
}

/* Raised centre action in the mobile tab bar */
.tabbar a.tb-fab .tb-ico {
    background: var(--lemon);
    color: var(--lemon-ink);
    box-shadow: 0 8px 18px -8px rgba(178, 251, 12, .95);
}
.tabbar a.tb-fab.active .tb-ico { color: var(--lemon-ink); }

.progress-bar { background-color: var(--lemon) !important; }

/* Checkboxes and switches: bright fill needs a dark glyph */
.form-check-input:checked { background-color: var(--lemon); border-color: var(--lemon); }
.form-check-input:checked[type="checkbox"] {
    --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%230B1A02' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}
.form-check-input:checked[type="radio"] {
    --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%230B1A02'/%3e%3c/svg%3e");
}
.form-check-input:focus { border-color: var(--lemon-dark); box-shadow: 0 0 0 3px var(--lemon-soft); }

.form-control:focus, .form-select:focus {
    border-color: var(--lemon-dark);
    box-shadow: 0 0 0 3px var(--lemon-soft);
}

.stepper .stp.on .n { background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink); }
.pin-dot.filled { background: var(--lemon); border-color: var(--lemon); }

.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover,
.dataTables_wrapper .dataTables_paginate .page-item.active .page-link {
    background: var(--lemon) !important;
    border-color: var(--lemon) !important;
    color: var(--lemon-ink) !important;
    box-shadow: 0 4px 10px -5px rgba(178, 251, 12, .9) !important;
}
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before {
    background: var(--lemon) !important;
    color: var(--lemon-ink) !important;
}

/* The balance card's "Fund" is an action, so it takes the lemon. */
.bc-link { color: var(--lemon); }
.bc-link:hover { color: var(--lemon-hover); }

.strip-dots span.on { background: var(--lemon); }
.seg button.active { color: var(--lemon-ink); background: var(--lemon); box-shadow: none; }
[data-bs-theme="dark"] .seg button.active { color: var(--lemon-ink); }

.save-bar.dirty { background: var(--lemon-soft); border-color: var(--lemon-dark); }
.save-bar.dirty .sb-note { color: var(--primary-dark); }

/* ==========================================================================
   Money-flow surfaces — from the app mockups
   ========================================================================== */

.how-strip { background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.8rem 0.9rem; }
.how-strip .hs-title { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .1em; color: var(--text-muted); margin-bottom: 0.6rem; }
.how-strip .hs-row { display: flex; align-items: center; gap: 0.4rem; }
.how-strip .hs-step {
    flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
    background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    padding: 0.55rem 0.3rem; font-size: 0.68rem; font-weight: 700; text-align: center; line-height: 1.25;
}
.how-strip .hs-step i { font-size: 0.9rem; color: var(--primary-dark); }
[data-bs-theme="dark"] .how-strip .hs-step i { color: var(--primary-color); }
.how-strip .hs-sep { color: var(--text-muted); font-size: 0.6rem; flex: none; }

/* Account details card */
.acct-card { background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.9rem; }
.acct-card .ac-top { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.75rem; font-size: 0.9rem; }
.acct-card .ac-field { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; padding: 0.45rem 0; border-top: 1px solid var(--border-color); font-size: 0.8rem; color: var(--text-muted); flex-wrap: wrap; }
.acct-card .ac-val { font-weight: 800; color: var(--text-main); font-variant-numeric: tabular-nums; text-align: right; }

/* ---------------------------------------------------------------------------
   Pay-into card — the account a customer sends money to.

   Built on the balance card rather than on .acct-card, because on the direct
   rail this IS the screen: there is no amount to enter and nothing to submit,
   so the account number is the only thing on it and has to carry the page. A
   row in a grey box does not.

   The account number is set large, tabular and selectable: it gets copied,
   read aloud down a phone, and typed into a banking app.
--------------------------------------------------------------------------- */
.pay-card {
    position: relative; overflow: hidden;
    background: var(--hero-bg);
    border: 1px solid var(--hero-edge);
    border-radius: var(--radius-lg);
    color: var(--hero-text);
    padding: 1.35rem 1.25rem 1.15rem;
}
.pay-card::after {
    content: ""; position: absolute;
    top: -80px; right: -60px; width: 250px; height: 250px;
    background: radial-gradient(closest-side, rgba(178, 251, 12, .30), transparent);
    pointer-events: none;
}
.pay-card > * { position: relative; z-index: 1; }
.pay-card .pc-bank {
    display: flex; align-items: center; gap: 0.55rem;
    font-size: 0.9rem; font-weight: 800; letter-spacing: -0.01em;
}
.pay-card .pc-bank i { color: var(--lemon); }
.pay-card .pc-label {
    font-size: 0.72rem; color: var(--hero-dim); font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.09em;
    margin-top: 1rem;
}
.pay-card .pc-number {
    font-size: clamp(1.7rem, 8vw, 2.1rem); font-weight: 800;
    letter-spacing: 0.04em; line-height: 1.1;
    font-variant-numeric: tabular-nums;
    /* Selectable on purpose: copy is one tap, but some people still drag. */
    user-select: all; -webkit-user-select: all;
    word-break: break-all;
}
.pay-card .pc-name { font-size: 0.92rem; font-weight: 700; margin-top: 0.1rem; }
.pay-card .pc-note {
    font-size: 0.76rem; color: var(--hero-dim); line-height: 1.5;
    margin-top: 0.85rem; padding-top: 0.75rem;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.pay-card .pc-actions { display: flex; gap: 0.5rem; margin-top: 1rem; }
.pay-card .pc-btn {
    flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
    border-radius: var(--radius-md); padding: 0.6rem 0.5rem;
    font-size: 0.82rem; font-weight: 700;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.16);
    color: var(--hero-text);
    transition: var(--transition);
}
.pay-card .pc-btn:hover { background: rgba(255, 255, 255, 0.2); color: var(--hero-text); }
.pay-card .pc-btn.is-primary {
    background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink);
}
.pay-card .pc-btn.is-primary:hover { background: var(--lemon-hover); color: var(--lemon-ink); }

/* ---------------------------------------------------------------------------
   Receipt upload — the proof behind a manual deposit.
--------------------------------------------------------------------------- */
.receipt-drop {
    position: relative;
    display: block; width: 100%; cursor: pointer;
    border: 1.5px dashed var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-sunk); padding: 1.15rem 0.9rem; text-align: center;
    transition: var(--transition);
}
.receipt-drop:hover { border-color: var(--primary-color); background: var(--primary-soft); }
/* Visually hidden, NOT display:none: a hidden input cannot be reached with
   the keyboard, so a keyboard user could never open the file picker. The
   focus ring is drawn on the drop zone around it instead. */
.receipt-drop input[type="file"],
.photo-tile .pt-input {
    position: absolute; width: 1px; height: 1px; opacity: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.receipt-drop:focus-within,
.photo-tile:has(.pt-input:focus-visible) .pt-target,
.photo-tile:has(.pt-input:focus-visible) .pt-photo {
    border-color: var(--primary-color);
    outline: 2px solid var(--primary-color); outline-offset: 2px;
}
.photo-tile { position: relative; }
.receipt-drop .rd-ico { font-size: 1.5rem; color: var(--text-muted); display: block; margin-bottom: 0.4rem; }
.receipt-drop .rd-title { font-size: 0.86rem; font-weight: 700; display: block; }
.receipt-drop .rd-sub { font-size: 0.74rem; color: var(--text-muted); display: block; margin-top: 0.15rem; }
.receipt-drop.is-invalid { border-color: var(--down); }

/* The chosen file, once there is one. */
.receipt-chosen {
    display: flex; align-items: center; gap: 0.65rem;
    border: 1px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); padding: 0.6rem 0.75rem;
}
.receipt-chosen img {
    width: 46px; height: 46px; object-fit: cover; border-radius: var(--radius-sm); flex: none;
}
.receipt-chosen .rc-file { min-width: 0; }
.receipt-chosen .rc-name {
    font-size: 0.83rem; font-weight: 700; display: block;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.receipt-chosen .rc-size { font-size: 0.73rem; color: var(--text-muted); }

/* ---------------------------------------------------------------------------
   KYC uploads — the same dashed target, at the size an ID deserves.

   A document upload gets more room than a receipt because the customer is
   being asked for three of them in a row, and a 46px row of filenames gives
   no way to tell the front from the back from a blurred thumb over the lens.
--------------------------------------------------------------------------- */
.receipt-drop.drop-lg { padding: 1.6rem 1rem; }
.receipt-drop.drop-lg .rd-ico { font-size: 1.9rem; margin-bottom: 0.55rem; }

/* Dragging a file anywhere over the zone lights it up, so it reads as a drop
   target rather than as a button that happens to have a dashed border. */
.receipt-drop.is-dragging {
    border-color: var(--primary-color); background: var(--primary-soft);
    border-style: solid;
}

.receipt-chosen .rc-thumb {
    width: 54px; height: 54px; object-fit: cover;
    border-radius: var(--radius-sm); flex: none;
    border: 1px solid var(--border-color);
}

.drop-progress { font-size: 0.76rem; color: var(--text-muted); margin-top: 0.35rem; }

/* ---------------------------------------------------------------------------
   Country flags.

   SVG images, never emoji: Windows ships no glyph for a regional-indicator
   pair, so every emoji flag in this application rendered as two letters in a
   box on Chrome, Edge and Firefox on Windows. The rounded corner and hairline
   border stop a white flag (Nigeria's centre band) from dissolving into a
   white card.
--------------------------------------------------------------------------- */
.kp-flag {
    display: inline-block; vertical-align: -0.16em;
    border-radius: 3px; border: 1px solid var(--border-color);
    object-fit: cover; flex: none; background: var(--bg-sunk);
}
.kp-flag-sm { width: 18px; height: 13px; }
.kp-flag-md { width: 24px; height: 17px; }
.kp-flag-lg { width: 34px; height: 24px; }
.kp-flag-xl { width: 46px; height: 32px; }

/* A market whose flag file has not landed yet still reads as a country. */
.kp-flag-fallback {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.58rem; font-weight: 800; letter-spacing: -0.02em;
    color: var(--text-muted); border-radius: 3px;
}
.kp-flag-lg.kp-flag-fallback,
.kp-flag-xl.kp-flag-fallback { font-size: 0.72rem; }

.kp-flag-name { margin-left: 0.4rem; }

/* ---------------------------------------------------------------------------
   Bill providers — networks, discos and TV packages.

   Tiles rather than a <select>, because a network is recognised by its colour
   long before its name is read, and an <option> cannot carry a logo at all.
--------------------------------------------------------------------------- */
.net-grid {
    display: grid; gap: 0.5rem;
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
}
.net-tile {
    display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--text-main);
    padding: 0.7rem 0.4rem; cursor: pointer; transition: var(--transition);
    min-width: 0;
}
.net-tile:hover { border-color: var(--primary-color); }
.net-tile.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.net-tile .nt-logo {
    width: 40px; height: 40px; border-radius: 11px; flex: none;
    object-fit: contain; background: var(--bg-sunk);
}
.net-tile .nt-initial {
    display: grid; place-items: center;
    background: var(--text-muted); color: #fff;
    font-size: 1.05rem; font-weight: 800;
}
.net-tile .nt-name {
    font-size: 0.72rem; font-weight: 700; line-height: 1.2; text-align: center;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Data bundles.

   A row each, not a grid of chips: a bundle is three facts — how much data,
   for how long, for how much — and three facts do not fit legibly into half
   a phone's width.
--------------------------------------------------------------------------- */
.plan-list { display: grid; gap: 0.4rem; max-height: 320px; overflow-y: auto; }
.plan-row {
    display: flex; align-items: center; gap: 0.75rem; width: 100%;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--text-main);
    padding: 0.65rem 0.8rem; cursor: pointer; text-align: left;
    transition: var(--transition);
}
.plan-row:hover { border-color: var(--primary-color); }
.plan-row.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.plan-row .pr-body { min-width: 0; flex: 1; }
.plan-row .pr-name {
    display: block; font-size: 0.84rem; font-weight: 700; line-height: 1.25;
}
.plan-row .pr-sub { display: block; font-size: 0.72rem; color: var(--text-muted); }
.plan-row .pr-price {
    font-size: 0.86rem; font-weight: 800; flex: none;
    font-variant-numeric: tabular-nums;
}

/* The document-type chooser. Two columns on a phone, because four stacked
   full-width rows push the upload itself below the fold. */
.doc-types { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; }
.doc-type {
    display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem;
    border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--text-main);
    padding: 0.7rem 0.75rem; text-align: left; cursor: pointer;
    transition: var(--transition); min-width: 0; width: 100%;
}
.doc-type:hover { border-color: var(--primary-color); }
.doc-type.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.doc-type i { font-size: 1.05rem; color: var(--text-muted); }
.doc-type.selected i { color: var(--primary-dark); }
[data-bs-theme="dark"] .doc-type.selected i { color: var(--primary-color); }
.doc-type .dt-name { font-size: 0.82rem; font-weight: 700; line-height: 1.25; }
.doc-type .dt-sub { font-size: 0.71rem; color: var(--text-muted); line-height: 1.3; }

/* Balance strip above an amount field */
.bal-strip { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.6rem 0.85rem; }
.bal-strip span:first-child { font-size: 0.72rem; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; }
.bal-strip b { font-size: 1.15rem; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; margin-left: auto; }

/* Read-only asset/network chip */
.pill-select { display: flex; align-items: center; gap: 0.4rem; background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.5rem 0.7rem; font-size: 0.82rem; min-width: 0; overflow: hidden; }
.pill-select span.text-muted { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; }

/* Tier lock badge */
.tier-lock { width: 104px; height: 104px; margin: 0 auto; border-radius: 28px; display: grid; place-items: center; gap: 2px; background: var(--bg-sunk); border: 2px solid var(--lemon); box-shadow: 0 0 34px -8px var(--lemon-edge); }
.tier-lock i { font-size: 1.9rem; color: var(--lemon); }
.tier-lock span { font-size: 0.62rem; font-weight: 900; letter-spacing: .13em; color: var(--lemon); }

/* Verification checklist row */
.chk-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.55rem 0; border-bottom: 1px solid var(--border-color); font-size: 0.85rem; font-weight: 600; }
.chk-row:last-child { border-bottom: none; }
.chk-row i { font-size: 0.95rem; color: var(--text-muted); flex: none; }
.chk-row i.done { color: var(--primary-dark); }
[data-bs-theme="dark"] .chk-row i.done { color: var(--primary-color); }

/* Favourites row */
.fav-row { display: flex; gap: 0.75rem; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.fav-row::-webkit-scrollbar { display: none; }
.fav-chip { flex: none; width: 68px; background: none; border: none; padding: 0; display: flex; flex-direction: column; align-items: center; gap: 0.35rem; color: var(--text-main); font-size: 0.72rem; font-weight: 700; }
.fav-chip span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fav-av { position: relative; display: block; }
.fav-av img { width: 54px; height: 54px; border-radius: 50%; object-fit: cover; border: 2px solid var(--primary-color); }
.fav-av i { position: absolute; right: -2px; bottom: -2px; font-size: 0.8rem; color: var(--primary-dark); background: var(--bg-card); border-radius: 50%; }
[data-bs-theme="dark"] .fav-av i { color: var(--primary-color); }
/* Customers do not upload photos of each other, so the favourites strip shows
   an initials disc. It takes the same ring as the photo it stands in for, or
   the row reads as two different kinds of thing. */
.fav-av .avatar-initials { width: 54px; height: 54px; font-size: 1.15rem; border: 2px solid var(--primary-color); }

/* Three-across figure row */
/* A three-up figure row (Money In / Out / Net, Crypto Deposited / Received /
   Rate). The labels are different lengths, so a one-line label next to a
   two-line one used to push its value down and break the row. Each cell is a
   column that pins the value to the bottom, which lines every value up on one
   baseline however the labels wrap. */
/* A three-up figure row (Money In / Out / Net, Crypto Deposited / Received /
   Rate). Labels and values are different lengths, so a wrapping label or a
   wrapping figure used to shove one column out of line with the other two.

   The wrapper divs are display:contents, which drops them out of the layout
   and lets the labels share one grid row and the values another. Every value
   then starts on the same line however anything above it wraps — which no
   amount of per-cell alignment can guarantee. */
.flow-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: auto;
    column-gap: 0.75rem;
    row-gap: 0;
}
.flow-3 > div { display: contents; }
.flow-3 span {
    grid-row: 1;
    display: block;
    font-size: 0.66rem;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    line-height: 1.3;
    align-self: end;
}
.flow-3 b {
    grid-row: 2;
    display: block;
    font-size: clamp(0.84rem, 2.8vw, 1rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
    padding-top: 0.2rem;
    align-self: start;
    /* break-word, not anywhere: "anywhere" happily splits "+₦2,591,060.00"
       after the sign. This only breaks when the figure genuinely cannot fit. */
    overflow-wrap: break-word;
}
/* The divider runs down both rows, so it reads as one continuous rule rather
   than two stubs — which is why row-gap is 0 and the spacing is padding. */
.flow-3 > div + div > span,
.flow-3 > div + div > b {
    padding-left: 0.75rem;
    border-left: 1px solid var(--border-color);
}
@media (max-width: 340px) {
    .flow-3 { grid-template-columns: 1fr 1fr; }
}

/* QR scanner */
.scanner { position: relative; border-radius: var(--radius-lg); overflow: hidden; background: #0b0f0d; aspect-ratio: 1 / 1; display: grid; place-items: center; }
.scanner .sc-hint { color: rgba(255,255,255,.35); font-size: 0.8rem; display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
.scanner .sc-hint i { font-size: 1.6rem; }
.sc-frame { position: absolute; inset: 14%; }
.sc-frame .c { position: absolute; width: 34px; height: 34px; border: 3px solid var(--lemon); }
.sc-frame .tl { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 10px 0 0 0; }
.sc-frame .tr { top: 0; right: 0; border-left: 0; border-bottom: 0; border-radius: 0 10px 0 0; }
.sc-frame .bl { bottom: 0; left: 0; border-right: 0; border-top: 0; border-radius: 0 0 0 10px; }
.sc-frame .br { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 10px 0; }
.sc-line { position: absolute; left: 6%; right: 6%; height: 2px; background: var(--lemon); box-shadow: 0 0 14px 2px var(--lemon-edge); animation: scanSweep 2.6s ease-in-out infinite; }
@keyframes scanSweep { 0%,100% { top: 8%; } 50% { top: 90%; } }
@media (prefers-reduced-motion: reduce) { .sc-line { animation: none; top: 50%; } }

/* ==========================================================================
   Home screen — greeting, tier banner, the slides, the two-rate board
   ========================================================================== */

.greet { font-size: 1rem; color: var(--text-muted); font-weight: 600; margin: 0 0 0.85rem; }

/* Four actions get a caption line under the label */
.action-tile small {
    display: block; font-size: 0.62rem; color: var(--text-muted);
    font-weight: 600; line-height: 1.2; margin-top: -2px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Home slides: the carousel under the balance card.

   NEUTRAL NAMES ON PURPOSE. Ad blockers hide any element whose class or id
   reads like advertising and block any image whose address does, so nothing
   here is called that, and the images come from /media/slides/{id}. A
   blocked slide does not look blocked; it looks like a broken Home.

   An admin's image slide is cropped to 12:5, the 1200 × 500 the Ads page asks
   for, at any width. The built-in text slides are the mockup's banner: deep
   green in both themes, like the balance card above them. The dots sit in a
   notch cut into the bottom edge, painted in the page colour so it reads as
   a notch on either ground.
--------------------------------------------------------------------------- */
.home-slides { position: relative; }
.hs-frame {
    display: block; position: relative; overflow: hidden;
    aspect-ratio: 12 / 5;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    background: var(--bg-sunk);
}
.hs-img { display: block; width: 100%; height: 100%; object-fit: cover; }
a.hs-frame:focus-visible, .hs-btn:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }

.hs-card {
    position: relative; overflow: hidden;
    display: flex; align-items: center;
    /* Fits the longest built-in slide on a 360px phone, so the carousel does
       not change height, and the tiles under it jump, as it turns. */
    min-height: 180px;
    padding: 1.1rem 1.15rem 1.6rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--hero-edge);
    background:
        radial-gradient(90% 120% at 88% 40%, rgba(178, 251, 12, 0.22), transparent 60%),
        linear-gradient(120deg, #0D1505 0%, #152408 55%, #203A0B 100%);
    color: #fff;
}
.hs-copy { position: relative; z-index: 1; min-width: 0; max-width: 62%; }
.hs-title {
    display: block;
    font-size: clamp(1.08rem, 4.8vw, 1.4rem); font-weight: 800;
    letter-spacing: -0.03em; line-height: 1.15;
}
.hs-accent { display: block; color: var(--lemon); }
.hs-line { display: block; margin-top: 0.4rem; font-size: 0.78rem; line-height: 1.4; color: rgba(255, 255, 255, 0.78); }
.hs-btn {
    display: inline-flex; align-items: center; gap: 0.45rem;
    margin-top: 0.75rem; padding: 0.45rem 1rem;
    border-radius: 99px;
    background: var(--lemon); color: var(--lemon-ink);
    font-size: 0.8rem; font-weight: 800;
    box-shadow: 0 8px 18px -10px rgba(178, 251, 12, 0.9);
    transition: var(--transition);
}
.hs-btn:hover { background: var(--lemon-hover); color: var(--lemon-ink); }
.hs-btn i { font-size: 0.66rem; }

/* The art: an orb carrying the money's symbol or the service's icon, with
   three coins or chips around it. Sized from the card, clear of the words. */
.hs-art {
    position: absolute; top: 50%; right: -4px;
    width: 40%; max-width: 190px; aspect-ratio: 1;
    transform: translateY(-50%);
    pointer-events: none;
}
.hs-orb {
    position: absolute; inset: 16%;
    display: grid; place-items: center;
    border-radius: 50%;
    border: 2px solid var(--lemon);
    background: radial-gradient(circle at 35% 30%, #2E500D, #0E1805 72%);
    box-shadow: 0 0 30px -6px rgba(178, 251, 12, 0.6), inset 0 0 18px rgba(178, 251, 12, 0.22);
    color: var(--lemon);
    font-size: clamp(1.7rem, 8vw, 2.5rem); font-weight: 800; line-height: 1;
}
.hs-orb.is-long { font-size: clamp(1.05rem, 5vw, 1.5rem); }
.hs-coin-1, .hs-coin-2, .hs-coin-3 { position: absolute; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45)); }
.hs-coin-1 { top: 2%; left: 6%; }
.hs-coin-2 { bottom: 6%; left: 0; }
.hs-coin-3 { top: 10%; right: 8%; }
.hs-chip {
    width: 34px; height: 34px; border-radius: 50%;
    display: grid; place-items: center;
    background: #1A2C0A; border: 1px solid var(--lemon-edge);
    color: var(--lemon); font-size: 0.8rem;
}

/* The dots, in their notch. `.carousel` is repeated for weight: Bootstrap's
   dark theme paints every indicator black with a four-part selector. */
.home-slides .hs-dots {
    left: 50%; right: auto; bottom: -1px;
    transform: translateX(-50%);
    margin: 0; padding: 6px 12px 5px; gap: 7px;
    background: var(--bg-body);
    border-radius: 12px 12px 0 0;
}
.home-slides.carousel .hs-dots [data-bs-target] {
    width: 7px; height: 7px; margin: 0;
    border: 0; border-radius: 50%;
    background: var(--text-muted); opacity: 0.45;
}
/* Stepped-down lemon on the light page, where full lemon is 1.3:1. */
.home-slides.carousel .hs-dots [data-bs-target].active { background: var(--primary-color); opacity: 1; }

/* The two rates that matter */
.rate-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.rate-box {
    background: var(--bg-sunk); border: 1px solid var(--border-color);
    border-radius: var(--radius-md); padding: 0.8rem 0.85rem; min-width: 0;
}
.rate-box .rb-ico { width: 30px; height: 30px; border-radius: 10px; font-size: 0.72rem; margin-bottom: 0.45rem; }
.rate-box .rb-label {
    display: block; font-size: 0.66rem; color: var(--text-muted);
    font-weight: 700; text-transform: uppercase; letter-spacing: .05em; line-height: 1.3;
}
/* Sized to hold a six-figure Naira rate on a 360px screen without wrapping. */
.rate-box b {
    display: block; font-size: clamp(0.95rem, 3.5vw, 1.15rem); font-weight: 800;
    letter-spacing: -0.02em; margin-top: 0.15rem; font-variant-numeric: tabular-nums;
    line-height: 1.2; overflow-wrap: anywhere;
}
.rate-box .ar-sub { font-size: 0.68rem; line-height: 1.35; }
@media (max-width: 380px) { .rate-pair { grid-template-columns: 1fr; } }

/* ======================= Contacts & beneficiaries =======================
   The mockups lead with a rail of favourite faces, then fall back to a
   list. Both share one avatar treatment: a green ring, and a check badge
   for a name the bank or the platform has already verified. */

.kp-avatar {
    position: relative;
    flex: 0 0 auto;
    width: 44px; height: 44px;
    border-radius: 50%;
    display: grid; place-items: center;
    overflow: visible;
    font-weight: 800; font-size: 0.9rem;
    background: var(--primary-light);
    color: var(--primary-dark);
}
[data-bs-theme="dark"] .kp-avatar { color: var(--primary-color); }
.kp-avatar img {
    width: 100%; height: 100%;
    border-radius: 50%;
    object-fit: cover;
}
.kp-avatar.ring { box-shadow: 0 0 0 2px var(--bg-card), 0 0 0 4px var(--primary-color); }
.kp-avatar.lg { width: 60px; height: 60px; font-size: 1.1rem; }
.kp-avatar.sm { width: 34px; height: 34px; font-size: 0.75rem; }
.kp-avatar .av-check {
    position: absolute; right: -2px; bottom: -2px;
    width: 16px; height: 16px; border-radius: 50%;
    background: var(--primary-color); color: #0B1A02;
    display: grid; place-items: center;
    font-size: 0.5rem;
    border: 2px solid var(--bg-card);
}
.kp-avatar.lg .av-check { width: 19px; height: 19px; font-size: 0.58rem; }

/* Horizontal rail of favourites. Scrolls rather than wraps, so the row
   height never changes as favourites are added. */
.fav-rail {
    display: flex; gap: 0.9rem;
    overflow-x: auto;
    padding-bottom: 0.35rem;
    scrollbar-width: none;
}
.fav-rail::-webkit-scrollbar { display: none; }
.fav-rail .fav {
    flex: 0 0 auto;
    width: 68px;
    display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
    background: none; border: none; padding: 0;
    color: var(--text-main);
    text-decoration: none;
}
.fav-rail .fav .fav-name {
    font-size: 0.72rem; font-weight: 600;
    max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fav-rail .fav-add .kp-avatar {
    background: var(--bg-sunk);
    color: var(--text-muted);
    border: 1px dashed var(--border-color);
}

/* A contact line that is tappable in full — the whole row is the target,
   not just the name. */
.contact-row {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--border-color);
    background: none; border-left: 0; border-right: 0; border-top: 0;
    width: 100%; text-align: left;
    color: var(--text-main); text-decoration: none;
}
.contact-row:last-child { border-bottom: none; }
.contact-row:hover { color: var(--text-main); }
.contact-row:hover .cr-name { color: var(--primary-dark); }
[data-bs-theme="dark"] .contact-row:hover .cr-name { color: var(--primary-color); }
.contact-row .cr-name { font-weight: 700; font-size: 0.86rem; line-height: 1.25; }
.contact-row .cr-sub { font-size: 0.73rem; color: var(--text-muted); line-height: 1.3; }
.contact-row .cr-star { color: var(--lemon); font-size: 0.8rem; }

/* Search field with a leading icon, used above every contact list. */
.kp-search { position: relative; }
.kp-search i {
    position: absolute; left: 0.85rem; top: 50%; transform: translateY(-50%);
    color: var(--text-muted); font-size: 0.85rem;
}
.kp-search input { padding-left: 2.4rem; }

@media (max-width: 575.98px) {
    .fav-rail .fav { width: 62px; }
    .kp-avatar { width: 40px; height: 40px; }
}

/* Sheet — a modal that behaves like a bottom sheet on a phone, which is how
   every "pick one of these" moment is drawn in the mockups. */
.kp-sheet .modal-content {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
}
.kp-sheet .modal-header { border-bottom: 1px solid var(--border-color); padding: 0.9rem 1.1rem; }
.kp-sheet .modal-title { font-size: 0.95rem; font-weight: 800; }
.kp-sheet .modal-body { padding: 1.1rem; }

@media (max-width: 575.98px) {
    .kp-sheet .modal-dialog {
        margin: 0;
        position: absolute;
        bottom: 0; left: 0; right: 0;
        max-width: none;
    }
    .kp-sheet .modal-content {
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        border-bottom: none;
    }
    /* A grab handle, so the sheet reads as draggable even though the dismiss
       is the close button and the backdrop. */
    .kp-sheet .modal-header::before {
        content: '';
        position: absolute; top: 0.45rem; left: 50%; transform: translateX(-50%);
        width: 36px; height: 4px; border-radius: 2px;
        background: var(--border-color);
    }
    .kp-sheet .modal-header { padding-top: 1.2rem; }
}

/* ==================== Result screens & progress tracks ====================
   Every flow in the mockups ends on the same shape: a haloed icon, the amount
   in full, a status pill, then the detail rows. Making it one component keeps
   a successful deposit, a sent transfer and a paid bill visually identical,
   which is what makes the app feel like one product. */

.result-hero { text-align: center; padding: 0.5rem 0 0.25rem; }
.result-hero .rh-ico {
    width: 84px; height: 84px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    display: grid; place-items: center;
    font-size: 2rem;
    background: var(--primary-light);
    color: var(--primary-dark);
    box-shadow: 0 0 0 10px var(--primary-soft);
}
[data-bs-theme="dark"] .result-hero .rh-ico { color: var(--primary-color); }
.result-hero.is-wait .rh-ico {
    background: rgba(245,158,11,0.14); color: #b45309;
    box-shadow: 0 0 0 10px rgba(245,158,11,0.07);
}
[data-bs-theme="dark"] .result-hero.is-wait .rh-ico { color: #fbbf24; }
.result-hero.is-fail .rh-ico {
    background: rgba(239,68,68,0.13); color: #dc2626;
    box-shadow: 0 0 0 10px rgba(239,68,68,0.07);
}
[data-bs-theme="dark"] .result-hero.is-fail .rh-ico { color: #f87171; }
.result-hero .rh-amt {
    font-size: 1.85rem; font-weight: 800; line-height: 1.1;
    font-variant-numeric: tabular-nums;
    word-break: break-word;
}
.result-hero .rh-sub { font-size: 0.83rem; color: var(--text-muted); margin-top: 0.35rem; }

/* A vertical track. Each step is done / active / pending, and the connecting
   line fills only as far as the flow has actually got — a half-filled line is
   the clearest way to say "still working". */
.track { position: relative; margin: 0.25rem 0; }
.track .tk {
    position: relative;
    display: flex; gap: 0.7rem;
    padding: 0 0 1.05rem 0;
}
.track .tk:last-child { padding-bottom: 0; }
.track .tk .tk-dot {
    flex: 0 0 auto;
    width: 18px; height: 18px; border-radius: 50%;
    display: grid; place-items: center;
    font-size: 0.5rem;
    background: var(--bg-sunk);
    border: 2px solid var(--border-color);
    color: transparent;
    z-index: 1;
}
/* The line lives on the dot, not the row, so it always starts dead centre. */
.track .tk:not(:last-child) .tk-dot::after {
    content: '';
    position: absolute;
    top: 18px; bottom: -2px; left: 8px;
    width: 2px;
    background: var(--border-color);
}
.track .tk.done .tk-dot {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: #0B1A02;
}
.track .tk.done:not(:last-child) .tk-dot::after { background: var(--primary-color); }
.track .tk.on .tk-dot {
    background: transparent;
    border-color: var(--lemon);
    box-shadow: 0 0 0 4px var(--lemon-soft);
}
.track .tk-body { padding-top: 0; min-width: 0; }
.track .tk-title { font-size: 0.82rem; font-weight: 700; line-height: 1.3; }
.track .tk.pending .tk-title { color: var(--text-muted); font-weight: 600; }
.track .tk-sub { font-size: 0.72rem; color: var(--text-muted); line-height: 1.35; }
.track .tk.on .tk-sub { color: var(--lemon-dark); font-weight: 600; }
[data-bs-theme="dark"] .track .tk.on .tk-sub { color: var(--lemon); }

/* Countdown — the alternative-transfer window and the rate-quote timer. */
.countdown {
    display: flex; align-items: center; justify-content: center; gap: 0.5rem;
    padding: 0.7rem;
    border-radius: var(--radius-md);
    background: rgba(245,158,11,0.10);
    border: 1px solid rgba(245,158,11,0.32);
    font-variant-numeric: tabular-nums;
    font-weight: 800; font-size: 1.15rem;
    color: #b45309;
}
[data-bs-theme="dark"] .countdown { color: #fbbf24; }
.countdown.is-out { background: rgba(239,68,68,0.10); border-color: rgba(239,68,68,0.32); color: #dc2626; }
[data-bs-theme="dark"] .countdown.is-out { color: #f87171; }
.countdown i { font-size: 0.9rem; }

/* Confirmation counter for a crypto deposit in flight. */
.conf-meter { margin-top: 0.75rem; }
.conf-meter .cm-top {
    display: flex; justify-content: space-between; align-items: baseline;
    font-size: 0.78rem; margin-bottom: 0.4rem;
}
.conf-meter .cm-n { font-weight: 800; font-variant-numeric: tabular-nums; }
.conf-meter .cm-bar { height: 6px; border-radius: 3px; background: var(--bg-sunk); overflow: hidden; }
.conf-meter .cm-fill {
    height: 100%; border-radius: 3px;
    background: var(--lemon);
    transition: width 0.5s ease;
}

/* A small labelled figure with an icon — the "Fees Paid / Transactions" pair.
   Grid rather than flex so the label and the value sit on the same two rows in
   every tile, which keeps the values on one baseline across the pair. */
.figure-tile {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 0.7rem;
    row-gap: 0.1rem;
    padding: 0.85rem 0.95rem;
    height: 100%;
}
.figure-tile .qa-icon { grid-row: 1 / span 2; }
.figure-tile .ft-label {
    grid-column: 2;
    font-size: 0.68rem;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    line-height: 1.3;
    align-self: end;
}
.figure-tile .ft-value {
    grid-column: 2;
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
    align-self: start;
    overflow-wrap: anywhere;
}
@media (max-width: 400px) {
    .figure-tile { column-gap: 0.55rem; padding: 0.75rem 0.8rem; }
    .figure-tile .ft-value { font-size: 0.92rem; }
}

/* Contact row extras: how the contact got here, and the two row actions. */
.contact-row .cr-how {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.05rem 0.4rem;
    border-radius: 5px;
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    font-size: 0.64rem;
    font-weight: 700;
    color: var(--text-muted);
    white-space: nowrap;
}
.contact-row a { color: inherit; text-decoration: none; min-width: 0; }
.contact-row .cr-fav {
    background: none; border: 0; padding: 0.25rem 0.35rem;
    line-height: 1; flex: none; border-radius: 7px;
}
.contact-row .cr-fav:hover { background: var(--bg-sunk); }
.contact-row .cr-fav .fa-star { color: var(--lemon); font-size: 0.82rem; }
.contact-row .cr-fav .far.fa-star { color: var(--text-muted); }

/* ========================== Attachments ==========================
   The evidence field shared by every support surface and the escalation
   dialog. A dashed target that reads as droppable, then a compact list of
   what has been attached. */

.kp-attach-drop {
    display: flex; align-items: center; gap: 0.7rem;
    width: 100%; text-align: left;
    padding: 0.75rem 0.9rem;
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-sunk);
    color: var(--text-main);
    transition: var(--transition);
}
.kp-attach-drop:hover {
    border-color: var(--primary-color);
    background: var(--primary-soft);
}
.kp-attach-drop > i { font-size: 1rem; color: var(--primary-dark); flex: none; }
[data-bs-theme="dark"] .kp-attach-drop > i { color: var(--primary-color); }
.kp-attach-drop b { display: block; font-size: 0.83rem; font-weight: 700; }
.kp-attach-drop small { display: block; font-size: 0.71rem; color: var(--text-muted); line-height: 1.35; }

.kp-attach-list:not(:empty) { margin-top: 0.5rem; display: grid; gap: 0.4rem; }
.kp-attach-item {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-card);
}
.kp-attach-item .ai-name { font-size: 0.79rem; font-weight: 600; }
.kp-attach-item .ai-size { font-size: 0.69rem; color: var(--text-muted); }
.kp-attach-item .ai-x {
    margin-left: auto; flex: none;
    background: none; border: 0; padding: 0.2rem 0.35rem;
    border-radius: 6px; color: var(--text-muted); line-height: 1;
}
.kp-attach-item .ai-x:hover { background: rgba(239,68,68,0.12); color: #dc2626; }
[data-bs-theme="dark"] .kp-attach-item .ai-x:hover { color: #f87171; }

/* A number with a minus and a plus either side — the manual rate editor. */
.rate-step { display: flex; align-items: center; gap: 0.25rem; }
.rate-step .form-control { text-align: center; min-width: 96px; font-variant-numeric: tabular-nums; font-weight: 700; }
.rate-step .btn { flex: none; width: 30px; padding: 0; }

/* Stepper on a narrow screen. The labels are nowrap, so three long ones used
   to eat the whole row and collapse the connecting line to its 8px minimum —
   the line visibly jumping about between steps. Below 380px only the current
   step keeps its label; the others are just their numbered dot, which leaves
   the line room to stay even. */
@media (max-width: 379.98px) {
    .stepper .stp:not(.on) { font-size: 0; gap: 0; }
    .stepper .stp:not(.on) .n { font-size: 0.66rem; }
    .stepper .line { min-width: 14px; }
}

/* Stacked variant of the figure row. Three money figures reading down the
   card, each label sitting directly above its value — which is how you read
   a statement, and it gives the numbers room to be large without competing
   for column width. */
.flow-stack { display: grid; gap: 0; }
.flow-stack > div {
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--border-color);
}
.flow-stack > div:first-child { padding-top: 0; }
.flow-stack > div:last-child { border-bottom: none; padding-bottom: 0; }
.flow-stack span {
    display: block;
    font-size: 0.68rem;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    line-height: 1.3;
}
.flow-stack b {
    display: block;
    margin-top: 0.15rem;
    font-size: clamp(1.05rem, 4.4vw, 1.35rem);
    font-weight: 800;
    letter-spacing: -0.025em;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    overflow-wrap: break-word;
}

/* Date range control: the presets, From and To on one line on every page.
   Where the screen is too narrow the line scrolls sideways rather than
   stacking. */
.daterange {
    display: flex; flex-wrap: nowrap; gap: 0.6rem; align-items: center; justify-content: space-between;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 2px;
}
.daterange::-webkit-scrollbar { display: none; }
.daterange .dr-presets { display: flex; flex-wrap: nowrap; gap: 0.4rem; flex: none; }
.daterange .dr-presets .chip-btn { white-space: nowrap; }
.daterange .dr-fields { display: flex; align-items: center; gap: 0.4rem; flex-wrap: nowrap; flex: none; white-space: nowrap; }
.daterange .dr-lab {
    font-size: 0.68rem; font-weight: 700; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: .05em; margin: 0;
}
.daterange input[type="date"] {
    background: var(--bg-card); border: 1px solid var(--border-color);
    color: var(--text-main); border-radius: var(--radius-sm);
    font-size: 0.78rem; width: auto; min-width: 132px;
}
/* The native picker glyph is black-on-black in dark mode. */
[data-bs-theme="dark"] .daterange input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(1) opacity(.6);
}
.figure-tile .ft-sub {
    grid-column: 2;
    font-size: 0.68rem;
    color: var(--text-muted);
    line-height: 1.3;
}
/* With a subtitle the tile needs a third row, and the icon spans all of it. */
.figure-tile:has(.ft-sub) { grid-template-rows: auto auto auto; }
.figure-tile:has(.ft-sub) .qa-icon { grid-row: 1 / span 3; }
@media (max-width: 575.98px) {
    .daterange { justify-content: flex-start; }
    .daterange input[type="date"] { min-width: 118px; }
}

/* ===================== Spending caps =====================
   A labelled bar per category. The fill changes tone as it approaches the
   cap, so "close to the limit" is visible without reading the percentage. */
.cap-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.65rem 0; border-bottom: 1px solid var(--border-color); }
.cap-row:last-child { border-bottom: none; }
.cap-bar { height: 6px; border-radius: 3px; background: var(--bg-sunk); overflow: hidden; }
.cap-fill {
    height: 100%; border-radius: 3px;
    background: var(--lemon);
    transition: width .45s ease, background .3s;
}
.cap-fill.is-warn { background: #f59e0b; }
.cap-fill.is-over { background: #ef4444; }

/* ======================= Rewards & referrals =======================
   The rewards balance is the reason anyone opens this page, so it gets the
   one saturated surface and a piece of artwork behind the figure. */
.reward-hero {
    position: relative; overflow: hidden;
    background: linear-gradient(150deg, #4A6800 0%, #2E4200 60%, #1B2800 100%);
    border-color: rgba(178, 251, 12, .35);
    color: #fff;
}
.reward-hero .rh-body { position: relative; z-index: 1; }
.reward-hero .rh-label {
    font-size: .68rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; color: rgba(255,255,255,.65);
}
.reward-hero .rh-amt {
    font-size: clamp(1.7rem, 6vw, 2.2rem); font-weight: 800;
    letter-spacing: -.03em; line-height: 1.1; margin-top: .2rem;
    font-variant-numeric: tabular-nums;
}
.reward-hero .rh-sub { font-size: .8rem; color: rgba(255,255,255,.7); margin-top: .35rem; }
.reward-hero .rh-sub b { color: #fff; }
.reward-hero .rh-art {
    position: absolute; right: -8px; bottom: -18px;
    font-size: 6.5rem; color: rgba(178,251,12,.16);
    transform: rotate(-12deg); pointer-events: none;
}

/* The referral code, sized to be read aloud over a phone call. */
.code-box {
    display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    background: var(--bg-sunk); border: 1px dashed var(--border-color);
    border-radius: var(--radius-md); padding: .7rem .85rem;
    font-size: 1.05rem; font-weight: 800; letter-spacing: .12em;
}

/* Numbered how-it-works list, also used by the promo sheet. */
.hp-num-list .num-step { display: flex; gap: .7rem; padding: .5rem 0; }
.hp-num-list .num-step .n {
    width: 24px; height: 24px; border-radius: 50%; flex: none;
    background: var(--primary-light); color: var(--primary-dark);
    display: grid; place-items: center; font-size: .72rem; font-weight: 800;
}
[data-bs-theme="dark"] .hp-num-list .num-step .n { color: var(--primary-color); }
.hp-num-list .num-step b { display: block; font-size: .84rem; font-weight: 700; }
.hp-num-list .num-step span span { display: block; font-size: .75rem; color: var(--text-muted); line-height: 1.4; }

.hp-check-row { display: flex; align-items: flex-start; gap: .55rem; padding: .3rem 0; font-size: .84rem; }
.hp-check-row i { margin-top: 3px; font-size: .8rem; }

.promo-row { display: flex; align-items: center; gap: .8rem; padding: .8rem 0; border-bottom: 1px solid var(--border-color); }
.promo-row:last-child { border-bottom: none; }

/* ============================== Live chat ==============================
   A transcript that scrolls inside its own box, so the compose row stays
   put and the page does not grow with every message. */
.chat-log {
    max-height: 380px; min-height: 260px; overflow-y: auto;
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.85rem;
    display: flex; flex-direction: column; gap: 0.6rem;
}
.chat-msg { display: flex; flex-direction: column; max-width: 82%; }
.chat-msg.me { align-self: flex-end; align-items: flex-end; }
.chat-msg.them { align-self: flex-start; align-items: flex-start; }
.chat-msg .bubble {
    padding: 0.55rem 0.75rem;
    border-radius: 14px;
    font-size: 0.83rem; line-height: 1.45;
}
.chat-msg.them .bubble {
    background: var(--bg-card); border: 1px solid var(--border-color);
    border-bottom-left-radius: 4px;
}
.chat-msg.me .bubble {
    background: var(--primary-soft); border: 1px solid var(--primary-color);
    border-bottom-right-radius: 4px;
}
.chat-msg .bubble.ref {
    background: var(--bg-card); border: 1px dashed var(--border-color);
    font-weight: 700; font-size: 0.78rem;
}
.chat-msg .at { font-size: 0.65rem; color: var(--text-muted); margin-top: 0.2rem; }

.chat-compose { display: flex; align-items: center; gap: 0.45rem; }
.chat-compose .form-control { flex: 1 1 auto; min-width: 0; }
.chat-compose .btn { width: 42px; padding: 0.5rem 0; }

/* Help tiles carry a caption under the label. */
.help-tile { text-align: center; }
.help-tile small {
    display: block; font-size: 0.66rem; color: var(--text-muted);
    line-height: 1.3; margin-top: 0.15rem; font-weight: 500;
}

/* =================== Market insight (admin countries) ===================
   A canvas bar chart can only fit a country code under each bar, so the
   legend beside it carries the name and the actual figure. */
.chart-legend { display: grid; gap: 0.45rem; }
.chart-legend .cl-row {
    display: grid; grid-template-columns: 22px minmax(0, 1fr) 2.2fr auto;
    align-items: center; gap: 0.6rem; font-size: 0.8rem;
}
.chart-legend .cl-flag { font-size: 1rem; }
.chart-legend .cl-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-legend .cl-bar { height: 6px; border-radius: 3px; background: var(--bg-sunk); overflow: hidden; }
.chart-legend .cl-bar > span { display: block; height: 100%; border-radius: 3px; background: var(--lemon); }
.chart-legend .cl-val { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* The fastest-growing market panel. */
.top-market .tm-head { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.9rem; }
.top-market .tm-flag { font-size: 2rem; line-height: 1; }
.top-market .tm-name { font-size: 1.05rem; font-weight: 800; letter-spacing: -0.02em; }
.top-market .tm-growth {
    font-size: clamp(1.8rem, 6vw, 2.4rem); font-weight: 800;
    letter-spacing: -0.03em; line-height: 1; color: var(--up);
    font-variant-numeric: tabular-nums;
}

/* A labelled bar used for growth per market and service mix. */
.growth-row {
    display: grid; grid-template-columns: minmax(0, 1.1fr) 1.4fr auto;
    align-items: center; gap: 0.6rem;
    padding: 0.32rem 0; font-size: 0.79rem;
}
.growth-row > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.growth-row .growth-bar { height: 6px; border-radius: 3px; background: var(--bg-sunk); overflow: hidden; }
.growth-row .growth-bar > span { display: block; height: 100%; border-radius: 3px; background: var(--lemon); }
.growth-row b { font-variant-numeric: tabular-nums; white-space: nowrap; }

@media (max-width: 575.98px) {
    .chart-legend .cl-row { grid-template-columns: 20px minmax(0, 1fr) auto; }
    .chart-legend .cl-bar { display: none; }
    .growth-row { grid-template-columns: minmax(0, 1fr) auto; }
    .growth-row .growth-bar { display: none; }
}

/* ===================== Users page controls =====================
   Country and sort sit on one row and wrap together; the presets sit under
   them so a narrow screen never squeezes a select down to nothing. */
.u-controls { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: flex-end; }
.u-controls .uc-field { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; flex: 1 1 200px; }
.u-controls .uc-field .form-label { margin: 0; font-size: 0.7rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.u-controls .uc-presets { display: flex; flex-wrap: wrap; gap: 0.4rem; flex: 1 1 100%; }
@media (min-width: 992px) {
    .u-controls .uc-presets { flex: 0 1 auto; margin-left: auto; }
}

/* ==========================================================================
   Auth shell and PIN / code entry
   Shared by the login, register and verify screens, and by the transaction
   PIN prompt inside the app — one set of boxes, one behaviour.
   ========================================================================== */

.auth-body {
    min-height: 100vh;
    min-height: 100dvh;
    background: var(--bg-body);
    color: var(--text-main);
    margin: 0;
}

.auth-body .sub {
    color: var(--text-muted);
    font-size: .88rem;
}

.auth-body h1 {
    font-size: 1.45rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin-bottom: .25rem;
}

/* A link that is really a button. Keeps keyboard and screen-reader semantics
   correct without inheriting the browser's button chrome. */
.btn-link-plain {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    cursor: pointer;
    text-decoration: none;
}
.btn-link-plain:hover { text-decoration: underline; }

/* The boxes SHRINK to their container rather than carrying a fixed width:
   six fixed-width boxes plus their gaps overflow the auth card on a narrow
   phone, and the row then scrolls sideways under the customer's thumb. */
.pin-row {
    display: flex;
    gap: .5rem;
    width: 100%;
}

.pin-box {
    flex: 1 1 0;
    min-width: 0;
    aspect-ratio: 1 / 1;
    max-height: 3.4rem;
    text-align: center;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--text-main);
    background: var(--bg-sunk);
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-md);
    outline: none;
    transition: var(--transition);
}

.pin-box:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--primary-soft);
}

.pin-box.is-invalid {
    border-color: var(--down);
}

/* Alpine hides these before it boots; without x-cloak they flash on load. */
[x-cloak] { display: none !important; }

/* ==========================================================================
   Not-yet-built screens, and the avatar
   ========================================================================== */

/* A screen that has no page behind it yet is shown greyed rather than linked
   to a 404. An operator who sees "Soon" learns the roadmap; one who lands on
   an error learns the product is unreliable. */
.nav-link.is-soon,
.action-tile.is-soon,
.service-tile.is-soon,
.tabbar .is-soon {
    opacity: .45;
    cursor: not-allowed;
    pointer-events: none;
}

.nav-link.is-soon { position: relative; }

.soon-tag {
    margin-left: auto;
    font-size: .58rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: .05rem .38rem;
}

/* Initials rather than a stock photograph: a real account has a name long
   before it has a picture, and a missing image file is a broken avatar on
   every row of every staff table. */
.avatar-initials {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    font-size: .85rem;
    font-weight: 800;
    color: #0B1A02;
    line-height: 1;
}

/* ==========================================================================
   Filter chips and the crypto address block
   ========================================================================== */

.chip-row {
    display: flex;
    gap: .4rem;
    overflow-x: auto;
    padding-bottom: .2rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.chip-row::-webkit-scrollbar { display: none; }

/* A deposit address is long, case-sensitive, and unrecoverable if it is
   mistyped — so it is shown whole, monospaced, and broken anywhere rather
   than truncated with an ellipsis the customer might copy. */
.addr-box {
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: .85rem 1rem;
}

.addr-label {
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: .35rem;
}

.addr-value {
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--text-main);
    word-break: break-all;
}

/* ==========================================================================
   KYC document step — photo tiles

   The customer is asked for three photographs in a row. Each gets a tile
   the photo then FILLS, because the whole point of a picture of an ID is
   that they can see which side they attached; a row of filenames cannot
   show them a thumb over the lens.
   ========================================================================== */

.kyc-head { display: flex; align-items: flex-start; gap: .85rem; margin-bottom: 1.1rem; }
.kyc-head .qa-icon { width: 46px; height: 46px; font-size: 1.15rem; flex: none; }

.kyc-section { margin-bottom: 1.15rem; }
.kyc-label {
    display: flex; align-items: center; gap: .5rem;
    font-size: .84rem; font-weight: 700; margin-bottom: .55rem;
}
.kyc-num {
    width: 20px; height: 20px; border-radius: 50%; flex: none;
    display: grid; place-items: center;
    background: var(--primary-color); color: #0B1A02;
    font-size: .64rem; font-weight: 800;
}
.kyc-count { font-size: .72rem; font-weight: 600; color: var(--text-muted); }

.photo-grid { display: grid; gap: .65rem; grid-template-columns: 1fr; }
.photo-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 480px) { .photo-grid.two { grid-template-columns: 1fr; } }

.photo-tile { min-width: 0; }

/* The empty target. Built on .receipt-drop so drag-and-drop keeps working. */
.photo-tile .pt-target {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 1.586 / 1;          /* the ratio of an ID card */
    padding: .75rem;
    margin: 0;
}
.photo-tile .pt-idle, .photo-tile .pt-busy {
    display: flex; flex-direction: column; align-items: center; gap: .25rem; width: 100%;
}
.photo-tile .pt-ico {
    width: 42px; height: 42px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--bg-card); border: 1px solid var(--border-color);
    color: var(--text-muted); font-size: 1.05rem; margin-bottom: .2rem;
}
.photo-tile .pt-target:hover .pt-ico { color: var(--primary-dark); border-color: var(--primary-color); }
[data-bs-theme="dark"] .photo-tile .pt-target:hover .pt-ico { color: var(--primary-color); }
.photo-tile .pt-title { font-size: .84rem; font-weight: 700; }
.photo-tile .pt-hint { font-size: .71rem; color: var(--text-muted); text-align: center; line-height: 1.3; }

.photo-tile .pt-bar {
    display: block; width: 70%; height: 6px; border-radius: 999px;
    background: var(--border-color); overflow: hidden; margin: .3rem 0 .1rem;
}
.photo-tile .pt-bar-fill { display: block; height: 100%; background: var(--primary-color); transition: width .2s linear; }

.photo-tile.is-invalid .pt-target { border-color: var(--down); }
.photo-tile.is-failed .pt-target { border-color: var(--down); border-style: solid; }

/* The photo, once there is one. */
.photo-tile .pt-photo {
    position: relative; overflow: hidden;
    aspect-ratio: 1.586 / 1;
    border-radius: var(--radius-md);
    border: 1.5px solid var(--primary-color);
    background: var(--bg-sunk);
    display: grid; place-items: center;
}
.photo-tile .pt-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-tile .pt-check {
    position: absolute; top: .45rem; right: .45rem;
    width: 24px; height: 24px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--primary-color); color: #0B1A02; font-size: .66rem;
    box-shadow: 0 0 0 2px var(--bg-card);
}
.photo-tile .pt-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: .45rem; }
.photo-tile .pt-name { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.photo-tile .pt-name b { font-size: .8rem; }
.photo-tile .pt-name small { font-size: .7rem; color: var(--text-muted); }

/* The selfie is a face, not a card: a round frame beside its tips. */
.selfie-row { display: flex; align-items: center; gap: 1rem; }
.photo-tile.shape-selfie { width: 150px; flex: none; }
.photo-tile.shape-selfie .pt-target,
.photo-tile.shape-selfie .pt-photo { aspect-ratio: 1 / 1; border-radius: 50%; }
.photo-tile.shape-selfie .pt-target { padding: .6rem; }
.photo-tile.shape-selfie .pt-hint { display: none; }
/* Far enough in that the badge and its ring sit inside the round clip. */
.photo-tile.shape-selfie .pt-check { top: auto; bottom: 1.25rem; right: 1.25rem; }
.photo-tile.shape-selfie .pt-foot { flex-direction: column; align-items: center; text-align: center; }
@media (max-width: 480px) {
    .selfie-row { flex-direction: column; align-items: stretch; }
    .photo-tile.shape-selfie { width: 150px; margin: 0 auto; }
}

/* The three things that get a photo rejected, said before the photo is taken. */
.tips-strip {
    list-style: none; margin: .6rem 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: .35rem .9rem;
    font-size: .72rem; color: var(--text-muted); font-weight: 600;
}
.tips-strip li { display: flex; align-items: center; gap: .35rem; }
.tips-strip li i { color: var(--primary-dark); font-size: .75rem; width: 14px; text-align: center; }
[data-bs-theme="dark"] .tips-strip li i { color: var(--primary-color); }
.tips-strip.vertical { flex-direction: column; gap: .45rem; margin: 0; flex: 1; min-width: 0; }

/* ==========================================================================
   Onboarding progress — one line, however many steps

   Replaces a row of labelled dots that could not wrap and spilled out of the
   auth card at six steps. The count and the current step are text, the path
   is a segmented bar, and the next step is named underneath.
   ========================================================================== */

.ob-progress { width: 100%; }
.ob-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    margin-bottom: .45rem; min-width: 0;
}
.ob-count {
    font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    color: var(--primary-dark); white-space: nowrap; flex: none;
}
[data-bs-theme="dark"] .ob-count { color: var(--primary-color); }
.ob-name {
    font-size: .8rem; font-weight: 700; color: var(--text-main);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right;
}
.ob-bar { list-style: none; margin: 0; padding: 0; display: flex; gap: 4px; }
.ob-seg {
    flex: 1 1 0; height: 6px; border-radius: 999px;
    background: var(--border-color);
    transition: var(--transition);
}
.ob-seg.done { background: var(--primary-color); }
/* Half filled: "you are here", distinct from done in both themes (in dark
   mode the primary colour and the lemon are the same value). */
.ob-seg.on { background: linear-gradient(90deg, var(--primary-color) 50%, var(--border-color) 50%); }
.ob-next { margin-top: .4rem; font-size: .72rem; color: var(--text-muted); font-weight: 600; }

/* ---------------------------------------------------------------------------
   kyc-docs: the single-file drop (proof of address).

   The input sits outside the empty/filled branches (see upload-drop.blade.php)
   so it survives the morph that swaps the file in — hidden the same way as
   the photo tile's, and the focus ring drawn on the drop zone for it.
--------------------------------------------------------------------------- */
.upload-drop { position: relative; }
.upload-drop .ud-input {
    position: absolute; width: 1px; height: 1px; opacity: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.upload-drop:has(.ud-input:focus-visible) .receipt-drop,
.upload-drop:has(.ud-input:focus-visible) .receipt-chosen {
    border-color: var(--primary-color);
    outline: 2px solid var(--primary-color); outline-offset: 2px;
}
.upload-drop .ud-idle, .upload-drop .ud-busy {
    display: flex; flex-direction: column; align-items: center; gap: .2rem; width: 100%;
}
.upload-drop .ud-bar {
    display: block; width: 70%; max-width: 260px; height: 6px; border-radius: 999px;
    background: var(--border-color); overflow: hidden; margin: .35rem 0 .1rem;
}
.upload-drop .ud-bar-fill { display: block; height: 100%; background: var(--primary-color); transition: width .2s linear; }
.upload-drop.is-invalid .receipt-chosen { border-color: var(--down); }

/* ==========================================================================
   Crypto deposits — the manual bank receipt upload on the deposit screen.

   The same behaviour as .photo-tile: the file input sits outside the
   empty/chosen branches (so the morph cannot remove it mid-upload), is
   visually hidden but keyboard-reachable, and the drop zone shows real upload
   progress instead of a bare spinner.
   ========================================================================== */
.receipt-upload { position: relative; }
.receipt-upload .ru-input {
    position: absolute; width: 1px; height: 1px; opacity: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.receipt-upload:has(.ru-input:focus-visible) .receipt-drop,
.receipt-upload:has(.ru-input:focus-visible) .receipt-chosen {
    border-color: var(--primary-color);
    outline: 2px solid var(--primary-color); outline-offset: 2px;
}
.receipt-upload .ru-busy { display: flex; flex-direction: column; align-items: center; gap: .25rem; }
.receipt-upload .ru-bar {
    display: block; width: 70%; height: 6px; border-radius: 999px;
    background: var(--border-color); overflow: hidden; margin: .3rem 0 .1rem;
}
.receipt-upload .ru-bar-fill { display: block; height: 100%; background: var(--primary-color); transition: width .2s linear; }

/* ==========================================================================
   Bill payments (Paybeta) — provider logo tile, provider picker, bundle
   cards, verified-holder card, token box. Appended by the bills feature.
   ========================================================================== */

.field-error { color: var(--down); font-size: 0.78rem; }
[data-bs-theme="dark"] .field-error { color: #f87171; }
.bill-ico { background: var(--bg-sunk); border-color: var(--border-color); color: var(--text-muted); }

/* Category tabs: four across even at 360px, so the label shrinks rather than
   the row wrapping into a 2x2 block that pushes the form below the fold. */
.bill-tab { padding: 0.65rem 0.2rem; gap: 0.35rem; font-size: 0.68rem; }
.bill-tab .qa-icon { width: 34px; height: 34px; font-size: 0.85rem; }

/* Provider mark: a fixed white tile so any logo reads the same in both
   themes; the brand initial on the brand colour when there is no logo. */
.pv-logo {
    position: relative; flex: none; display: inline-grid; place-items: center;
    width: 40px; height: 40px; border-radius: 12px; overflow: hidden;
    background: #fff;
    border: 2px solid color-mix(in srgb, var(--pv-accent, #0B3D2E) 45%, transparent);
}
.pv-logo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.pv-logo .pv-initial { display: none; font-weight: 800; font-size: 1rem; line-height: 1; color: var(--pv-ink, #fff); }
.pv-logo.no-logo { background: var(--pv-accent, #0B3D2E); }
.pv-logo.no-logo .pv-initial { display: block; }
.pv-logo.pv-sm { width: 28px; height: 28px; border-radius: 9px; border-width: 1.5px; }
.pv-logo.pv-sm .pv-initial { font-size: 0.78rem; }
.pv-logo.pv-lg { width: 56px; height: 56px; border-radius: 16px; }
.pv-logo.pv-lg .pv-initial { font-size: 1.35rem; }

.pv-picker { min-width: 0; }
.pv-picker .dropdown { width: 100%; }
.pv-toggle {
    display: flex; align-items: center; gap: 0.6rem; width: 100%; min-width: 0;
    background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md);
    color: var(--text-main); padding: 0.55rem 0.75rem; text-align: left; transition: var(--transition);
}
.pv-toggle:hover, .pv-toggle[aria-expanded="true"] { border-color: var(--primary-color); }
.pv-toggle .pv-name { font-weight: 700; font-size: 0.88rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-toggle .pv-placeholder { color: var(--text-muted); font-size: 0.86rem; }
.pv-toggle .pv-caret { margin-left: auto; font-size: 0.75rem; color: var(--text-muted); flex: none; }
.pv-menu { width: 100%; max-height: 300px; overflow-y: auto; padding: 0.3rem; }
.pv-item {
    display: flex; align-items: center; gap: 0.6rem; border-radius: var(--radius-sm);
    padding: 0.5rem 0.55rem; color: var(--text-main); font-size: 0.86rem; font-weight: 600;
}
.pv-item .pv-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-item:hover, .pv-item:focus { background: var(--bg-sunk); color: var(--text-main); }
.pv-item.active, .pv-item:active { background: var(--primary-soft); color: var(--text-main); }
.pv-item:disabled { opacity: 0.55; cursor: not-allowed; }
.pv-item .pv-badge { margin-left: auto; font-size: 0.6rem; flex: none; }
.pv-item .pv-check { margin-left: auto; color: var(--primary-dark); flex: none; }
[data-bs-theme="dark"] .pv-item .pv-check { color: var(--primary-color); }
.pv-stale { font-size: 0.74rem; color: var(--text-muted); margin-top: 0.35rem; }
.pv-stale .btn-link { color: var(--primary-dark); font-size: 0.74rem; font-weight: 700; text-decoration: none; }
[data-bs-theme="dark"] .pv-stale .btn-link { color: var(--primary-color); }

/* Loading skeletons: the shape of what is coming, not a spinner. */
@keyframes kp-shimmer { 0% { background-position: -200px 0; } 100% { background-position: 200px 0; } }
.plan-skel span, .pv-skel-logo, .pv-skel-line {
    background: linear-gradient(90deg, var(--bg-sunk) 0, var(--border-color) 40%, var(--bg-sunk) 80%);
    background-size: 400px 100%; animation: kp-shimmer 1.2s linear infinite;
}
.pv-skel {
    display: flex; align-items: center; gap: 0.6rem; height: 46px; padding: 0 0.75rem;
    border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--bg-sunk);
}
.pv-skel-logo { width: 28px; height: 28px; border-radius: 9px; flex: none; }
.pv-skel-line { height: 10px; border-radius: 6px; width: 45%; }
.plan-skel { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
.plan-skel span { display: block; height: 84px; border-radius: var(--radius-md); }

/* Data bundles as cards: size, price, validity, the three facts people
   compare, big enough to compare at a glance. */
.bundle-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; max-height: 360px; overflow-y: auto; padding: 2px; }
.bundle-card {
    position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.2rem;
    min-width: 0; border: 1.5px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--text-main); padding: 0.75rem 0.3rem; transition: var(--transition);
}
.bundle-card:hover { border-color: var(--primary-color); }
.bundle-card.selected { border-color: var(--primary-color); background: var(--primary-soft); }
.bundle-card .bc-size { font-size: 1.05rem; font-weight: 800; line-height: 1.1; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bundle-card .bc-price { font-size: 0.8rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.bundle-card .bc-validity { font-size: 0.68rem; color: var(--text-muted); }
.bundle-card .bc-check { position: absolute; top: 6px; right: 6px; font-size: 0.8rem; color: var(--primary-dark); }
[data-bs-theme="dark"] .bundle-card .bc-check { color: var(--primary-color); }
.bucket-tabs button { font-size: 0.76rem; }

/* The verified meter or smart-card holder. */
.holder-card {
    display: flex; align-items: center; gap: 0.7rem; min-width: 0;
    background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.7rem 0.8rem;
}
.holder-card .hc-ico {
    width: 36px; height: 36px; border-radius: 50%; flex: none; display: grid; place-items: center;
    background: var(--primary-soft); color: var(--primary-dark); border: 1px solid var(--primary-color);
}
[data-bs-theme="dark"] .holder-card .hc-ico { color: var(--primary-color); }
.holder-card .hc-body { min-width: 0; flex: 1; line-height: 1.3; }
.holder-card .hc-body b { display: block; font-size: 0.88rem; overflow-wrap: anywhere; }
.holder-card .hc-body small { display: block; font-size: 0.72rem; color: var(--text-muted); overflow-wrap: anywhere; }
.holder-card .hc-body .hc-ok { color: var(--up); font-weight: 700; }
.holder-card .hc-check { color: var(--up); font-size: 1.15rem; flex: none; }

.confirm-amt { font-size: 1.9rem; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; }
.result-hero .rh-title { font-size: 1rem; font-weight: 800; margin-bottom: 0.25rem; }

/* The prepaid token: the purchase itself, so it is the loudest thing. */
.token-box { background: var(--bg-sunk); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: 0.75rem 0.9rem; }
.token-box .tb-head { display: flex; justify-content: space-between; align-items: center; font-size: 0.72rem; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
.token-box .tb-head .btn-link { color: var(--primary-dark); text-decoration: none; font-size: 0.76rem; text-transform: none; letter-spacing: 0; }
[data-bs-theme="dark"] .token-box .tb-head .btn-link { color: var(--primary-color); }
.token-box .tb-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.1rem; font-weight: 800;
    color: var(--primary-dark); letter-spacing: 0.04em; margin-top: 0.2rem; overflow-wrap: anywhere;
}
[data-bs-theme="dark"] .token-box .tb-value { color: var(--primary-color); }

@media (max-width: 380px) {
    .bundle-card { padding: 0.65rem 0.2rem; }
    .bundle-card .bc-size { font-size: 0.95rem; }
    .bill-tab { font-size: 0.64rem; }
}

/* ==========================================================================
   Support chat — WhatsApp-style thread

   Customer on the right in the brand tint, support on the left on the card
   colour, a tail on the first bubble of each run, time and ticks tucked in
   the corner. The log scrolls inside the card so the composer stays put.
   ========================================================================== */

.wa-chat { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.wa-head {
    display: flex; align-items: center; gap: .65rem;
    padding: .8rem 1rem; border-bottom: 1px solid var(--border-color);
    background: var(--bg-card);
}
.wa-title { font-weight: 800; font-size: .92rem; line-height: 1.2; }
.wa-status { font-size: .72rem; color: var(--text-muted); }
.wa-online { font-size: .72rem; font-weight: 700; color: var(--up); white-space: nowrap; display: inline-flex; align-items: center; gap: .3rem; }
.wa-online i { font-size: .45rem; }

.wa-body {
    height: min(58vh, 520px); min-height: 280px;
    overflow-y: auto; overscroll-behavior: contain;
    padding: .9rem .8rem 1rem;
    display: flex; flex-direction: column; gap: .15rem;
    background-color: var(--bg-sunk);
    /* A faint dotted pattern, like the chat wallpaper people expect. */
    background-image: radial-gradient(color-mix(in srgb, var(--text-muted) 16%, transparent) 1px, transparent 1.2px);
    background-size: 18px 18px;
}

.wa-day { display: flex; justify-content: center; margin: .6rem 0 .45rem; }
.wa-day span {
    font-size: .68rem; font-weight: 700; color: var(--text-muted);
    background: var(--bg-card); border: 1px solid var(--border-color);
    padding: .15rem .6rem; border-radius: 999px;
}

.wa-row { display: flex; margin-top: .1rem; }
.wa-row.first { margin-top: .5rem; }
.wa-row.me { justify-content: flex-end; }
.wa-row.them { justify-content: flex-start; }

.wa-bubble {
    position: relative; max-width: min(78%, 420px);
    padding: .4rem .55rem .3rem; border-radius: 12px;
    font-size: .86rem; line-height: 1.4; color: var(--text-main);
    box-shadow: 0 1px 1px rgb(0 0 0 / 0.06);
    overflow-wrap: anywhere;
}
.wa-row.them .wa-bubble { background: var(--bg-card); border: 1px solid var(--border-color); }
.wa-row.me .wa-bubble { background: var(--primary-light); }
[data-bs-theme="dark"] .wa-row.me .wa-bubble { background: #1E3A10; color: #F2F7E8; }

/* The tail, only on the first bubble of a run. */
.wa-row.first.them .wa-bubble { border-top-left-radius: 3px; }
.wa-row.first.me .wa-bubble { border-top-right-radius: 3px; }
.wa-row.first .wa-bubble::before {
    content: ""; position: absolute; top: 0; width: 10px; height: 12px;
}
.wa-row.first.them .wa-bubble::before {
    left: -8px; background: var(--bg-card);
    clip-path: polygon(100% 0, 0 0, 100% 100%);
}
.wa-row.first.me .wa-bubble::before {
    right: -8px; background: var(--primary-light);
    clip-path: polygon(0 0, 100% 0, 0 100%);
}
[data-bs-theme="dark"] .wa-row.first.me .wa-bubble::before { background: #1E3A10; }

.wa-text { white-space: pre-wrap; }
.wa-meta {
    display: flex; justify-content: flex-end; align-items: center; gap: .25rem;
    font-size: .64rem; color: var(--text-muted); margin-top: .1rem;
}
[data-bs-theme="dark"] .wa-row.me .wa-meta { color: #A9B89A; }
.wa-meta .wa-read { color: #34B7F1; }

/* Photos inside a bubble: one big, or a small grid. */
.wa-media { margin: -.15rem -.3rem .3rem; }
.wa-media.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px; }
.wa-thumb { display: block; border-radius: 9px; overflow: hidden; background: var(--bg-sunk); max-height: 280px; }
.wa-media.grid .wa-thumb { aspect-ratio: 1 / 1 !important; }
.wa-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* A document card. */
.wa-doc {
    display: flex; align-items: center; gap: .55rem; margin-bottom: .3rem;
    padding: .5rem .6rem; border-radius: 9px; text-decoration: none; color: inherit;
    background: color-mix(in srgb, var(--text-main) 6%, transparent);
    min-width: 200px; max-width: 100%;
}
.wa-doc:hover { background: color-mix(in srgb, var(--text-main) 10%, transparent); color: inherit; }
.wa-doc-ico { width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center; background: var(--bg-card); color: var(--primary-dark); flex: none; }
[data-bs-theme="dark"] .wa-doc-ico { color: var(--primary-color); }
.wa-doc-name { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; flex: 1; }
.wa-doc-name b { font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-doc-name small { font-size: .68rem; color: var(--text-muted); }
.wa-doc-get { color: var(--text-muted); font-size: .8rem; }

/* The tray above the composer. */
.wa-tray {
    display: flex; gap: .5rem; overflow-x: auto; padding: .55rem .8rem .2rem;
    border-top: 1px solid var(--border-color); background: var(--bg-card);
}
.wa-chip {
    position: relative; flex: none; display: flex; align-items: center; gap: .45rem;
    max-width: 220px; padding: .35rem 1.9rem .35rem .5rem;
    border: 1px solid var(--border-color); border-radius: 10px; background: var(--bg-sunk);
}
.wa-chip-img { width: 38px; height: 38px; object-fit: cover; border-radius: 7px; flex: none; }
.wa-chip-ico { width: 38px; height: 38px; border-radius: 7px; display: grid; place-items: center; background: var(--bg-card); color: var(--primary-dark); flex: none; }
[data-bs-theme="dark"] .wa-chip-ico { color: var(--primary-color); }
.wa-chip-name { min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.wa-chip-name b { font-size: .74rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-chip-name small { font-size: .66rem; color: var(--text-muted); }
.wa-chip-x {
    position: absolute; top: .25rem; right: .25rem; width: 22px; height: 22px; border-radius: 50%;
    border: 0; background: transparent; color: var(--text-muted); display: grid; place-items: center;
}
.wa-chip-x:hover, .wa-chip-x:focus-visible { background: var(--border-color); color: var(--text-main); }

.wa-progress { height: 3px; background: var(--border-color); }
.wa-progress-fill { display: block; height: 100%; background: var(--primary-color); transition: width .2s linear; }
.wa-error { padding: .35rem 1rem 0; font-size: .76rem; color: var(--down); background: var(--bg-card); }

/* The composer: clip, rounded box, round send. */
.wa-compose {
    position: relative;
    display: flex; align-items: flex-end; gap: .45rem;
    padding: .6rem .7rem; background: var(--bg-card); border-top: 1px solid var(--border-color);
}
.wa-file { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; clip-path: inset(50%); }
.wa-attach {
    flex: none; width: 40px; height: 40px; border-radius: 50%; margin: 0;
    display: grid; place-items: center; cursor: pointer; color: var(--text-muted);
    transition: var(--transition);
}
.wa-attach:hover { background: var(--bg-sunk); color: var(--text-main); }
.wa-compose:has(.wa-file:focus-visible) .wa-attach { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.wa-input {
    flex: 1 1 auto; min-width: 0; resize: none; max-height: 120px;
    padding: .55rem .9rem; border-radius: 20px; line-height: 1.35; font-size: .88rem;
    border: 1px solid var(--border-color); background: var(--bg-sunk); color: var(--text-main);
    outline: none;
}
.wa-input:focus { border-color: var(--primary-color); box-shadow: 0 0 0 3px var(--primary-soft); }
.wa-send {
    flex: none; width: 42px; height: 42px; border-radius: 50%; border: 0;
    display: grid; place-items: center;
    background: var(--lemon); color: var(--lemon-ink); font-size: .95rem;
    transition: var(--transition);
}
.wa-send:disabled { opacity: .45; cursor: not-allowed; }
.wa-foot { margin: 0; padding: .1rem 1rem .75rem; text-align: center; font-size: .7rem; color: var(--text-muted); background: var(--bg-card); }

@media (max-width: 575.98px) {
    /* Leave room for the bottom tab bar, and give the thread the screen. */
    .wa-body { height: calc(100dvh - 330px); min-height: 260px; }
    .wa-bubble { max-width: 86%; }
}

/* ==========================================================================
   Bootstrap speaks the app's palette.

   Bootstrap draws its own components (tables, offcanvas, form checks,
   popovers, links, anything a view reaches for without a Kaastro class) from
   its own --bs-* variables, and in dark mode those are Bootstrap's blue-grey
   #212529, not this app's neutral near-black. That is where the odd
   grey-blue table body and the default-blue links came from. Pointing the
   Bootstrap variables at the app's tokens fixes every such component in
   both themes at once, instead of one class at a time.
   ========================================================================== */
:root,
[data-bs-theme="light"],
[data-bs-theme="dark"] {
    --bs-body-bg: var(--bg-body);
    --bs-body-color: var(--text-main);
    --bs-emphasis-color: var(--text-main);
    --bs-heading-color: inherit;
    --bs-secondary-color: var(--text-muted);
    --bs-tertiary-color: var(--text-muted);
    --bs-secondary-bg: var(--bg-sunk);
    --bs-tertiary-bg: var(--bg-sunk);
    --bs-border-color: var(--border-color);
    --bs-border-color-translucent: var(--border-color);
    --bs-link-color: var(--primary-dark);
    --bs-link-hover-color: var(--primary-color);
    /* Bootstrap paints <a> from the -rgb triplet, which cannot be derived
       from a hex token, so it is written out per theme. */
    --bs-link-color-rgb: 85, 120, 0;
    --bs-link-hover-color-rgb: 107, 151, 0;
}
[data-bs-theme="dark"] {
    --bs-link-color: var(--primary-color);
    --bs-link-hover-color: var(--lemon-hover);
    --bs-link-color-rgb: 178, 251, 12;
    --bs-link-hover-color-rgb: 196, 255, 58;
}

/* Table cells take the row's ground, not Bootstrap's body colour. */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-main);
    --bs-table-border-color: var(--border-color);
    --bs-table-hover-bg: var(--bg-sunk);
    --bs-table-hover-color: var(--text-main);
    --bs-table-striped-bg: var(--bg-sunk);
    --bs-table-striped-color: var(--text-main);
    --bs-table-active-bg: var(--bg-sunk);
}

/* A text button reads as a link in the brand colour, never Bootstrap blue. */
.btn-link {
    --bs-btn-color: var(--primary-dark);
    --bs-btn-hover-color: var(--primary-color);
    --bs-btn-active-color: var(--primary-color);
    --bs-btn-disabled-color: var(--text-muted);
    font-weight: 700;
    text-decoration: none;
}
.btn-link:hover { text-decoration: underline; }
[data-bs-theme="dark"] .btn-link {
    --bs-btn-color: var(--primary-color);
    --bs-btn-hover-color: var(--lemon-hover);
    --bs-btn-active-color: var(--lemon-hover);
}
.btn-link.text-muted { --bs-btn-color: var(--text-muted); --bs-btn-hover-color: var(--text-main); }

.offcanvas { --bs-offcanvas-bg: var(--bg-card); --bs-offcanvas-color: var(--text-main); }
.popover { --bs-popover-bg: var(--bg-card); --bs-popover-border-color: var(--border-color); --bs-popover-body-color: var(--text-main); }
.list-group { --bs-list-group-bg: var(--bg-card); --bs-list-group-color: var(--text-main); --bs-list-group-border-color: var(--border-color); }
.form-select option { background: var(--bg-card); color: var(--text-main); }

/* The browser's autofill paints a pale-blue slab into a dark form. An inset
   shadow is the only thing that can cover it; the colour transition keeps it
   from flashing back. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-text-fill-color: var(--text-main);
    -webkit-box-shadow: 0 0 0 1000px var(--bg-card) inset;
    box-shadow: 0 0 0 1000px var(--bg-card) inset;
    caret-color: var(--text-main);
    transition: background-color 9999s ease-out 0s;
}
.pin-box:-webkit-autofill,
.amount-box input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--bg-sunk) inset;
    box-shadow: 0 0 0 1000px var(--bg-sunk) inset;
}

/* A theme switch is instant everywhere. Buttons carry a colour transition
   for hover, and without this they faded through a muddy grey for a quarter
   of a second while every card beside them had already switched. */
.kp-theme-switching *,
.kp-theme-switching *::before,
.kp-theme-switching *::after { transition: none !important; }

/* An unticked box or switch reads as a control on the dark ground too. */
.form-check-input { background-color: var(--bg-sunk); border-color: color-mix(in srgb, var(--text-muted) 55%, transparent); }

/* Toasts (backoffice.js). In dark the "dark" toast was a near-black box on a
   near-black page; it is lifted off the page instead. On a phone the stack
   sits above the wallet's tab bar rather than under it. */
#kpToasts .toast { border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
[data-bs-theme="dark"] #kpToasts .toast.text-bg-dark {
    background-color: #262626 !important;
    border: 1px solid #333333 !important;
}
@media (max-width: 991.98px) {
    body[data-portal="user"] #kpToasts { bottom: calc(var(--tabbar-h) + 14px) !important; }
}

/* The tab bar sits on the same card colour as every other surface. */
[data-bs-theme="dark"] .tabbar { background: var(--bg-card); }

/* ---------------------------------------------------------------------------
   The receipt, in the theme it is looked at in.

   On screen it follows the theme — a white sheet in the middle of the dark
   app was the brightest thing on the phone. The PNG a customer downloads is
   still the white paper receipt: the download renders a copy in the light
   theme (see receipt.blade.php).
--------------------------------------------------------------------------- */
.receipt-sheet .rs-logo.brand-img { height: 34px; width: auto; display: flex; justify-content: center; margin: 0 auto 0.25rem; }
.receipt-sheet .rs-logo.brand-img > img { height: 100%; }
.receipt-sheet .rs-stamp.is-wait { border-color: #b45309; color: #b45309; }
[data-bs-theme="dark"] .receipt-sheet {
    background: var(--bg-sunk);
    color: var(--text-main);
    border-color: var(--border-color);
}
[data-bs-theme="dark"] .receipt-sheet .rs-tag,
[data-bs-theme="dark"] .receipt-sheet .rs-sub,
[data-bs-theme="dark"] .receipt-sheet .rs-row span:first-child,
[data-bs-theme="dark"] .receipt-sheet .rs-foot { color: var(--text-muted); }
[data-bs-theme="dark"] .receipt-sheet .rs-div { border-top-color: var(--border-color); }
[data-bs-theme="dark"] .receipt-sheet .rs-stamp { border-color: var(--lemon); color: var(--lemon); }
[data-bs-theme="dark"] .receipt-sheet .rs-stamp.is-wait { border-color: #fbbf24; color: #fbbf24; }

/* ==========================================================================
   Working… — every Livewire action shows that it is in flight.

   Livewire 4 puts data-loading on the element that started a request (the
   clicked button, or a form's submit button) and takes it off when the
   answer lands. While it is there the element cannot be pressed again, so a
   double tap sends one payment, not two; a button gets a spinner where its
   icon was. A button with its own loading state (a wire:loading text such as
   "Signing in…", or its own spinning icon) keeps that instead of getting a
   second spinner: Livewire shows those with an inline style, which a rule
   here cannot hide, so the global spinner is the one that stands aside.
   ========================================================================== */
@keyframes kp-spin { to { transform: rotate(360deg); } }

[data-loading] { pointer-events: none; cursor: progress; }
[data-loading]:not(.btn):not(button) { opacity: .6; transition: opacity .15s; }
.btn[data-loading], button[data-loading] { opacity: .8; }

.btn[data-loading]:not(:has([wire\:loading], .fa-spin))::before,
.chip-btn[data-loading]:not(:has(.fa-spin))::before,
.seg button[data-loading]:not(:has(.fa-spin))::before,
.btn-link-plain[data-loading]:not(:has(.fa-spin))::before,
.pc-btn[data-loading]:not(:has(.fa-spin))::before,
.icon-btn[data-loading]:not(:has(.fa-spin))::before,
.wa-send[data-loading]:not(:has(.fa-spin))::before {
    content: "";
    display: inline-block;
    width: 0.95em; height: 0.95em;
    margin-right: 0.45em;
    vertical-align: -0.14em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: kp-spin .7s linear infinite;
    flex: none;
}
/* The spinner takes the place of a leading icon rather than sitting beside it. */
.btn[data-loading]:not(:has([wire\:loading], .fa-spin)) > i:first-child,
.pc-btn[data-loading]:not(:has(.fa-spin)) > i:first-child,
.icon-btn[data-loading]:not(:has(.fa-spin)) > i,
.wa-send[data-loading]:not(:has(.fa-spin)) > i { display: none; }
.icon-btn[data-loading]::before,
.wa-send[data-loading]::before { margin-right: 0; }

@media (prefers-reduced-motion: reduce) {
    /* Still says "working" without spinning: a dashed ring holds still. */
    [data-loading]::before { animation: none !important; border-style: dashed; }
}

/* ==========================================================================
   Pager — the numbered page buttons under a Livewire list, in the same
   shape as the back-office tables' pager.
   ========================================================================== */
.kp-pager {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 0.6rem; margin-top: 1rem;
}
.kp-pager .kp-pager-info { font-size: 0.79rem; font-weight: 600; color: var(--text-muted); }
.kp-pager ul { display: flex; flex-wrap: wrap; gap: 4px; list-style: none; margin: 0; padding: 0; }
.kp-pager .pg {
    min-width: 34px; height: 34px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 0.55rem;
    border: 1px solid var(--border-color); border-radius: 9px;
    background: var(--bg-card); color: var(--text-main);
    font-size: 0.8rem; font-weight: 700; line-height: 1;
    transition: var(--transition);
}
.kp-pager button.pg:hover { background: var(--primary-soft); border-color: var(--primary-color); color: var(--primary-dark); }
[data-bs-theme="dark"] .kp-pager button.pg:hover { color: var(--primary-color); }
.kp-pager .pg.is-current {
    background: var(--lemon); border-color: var(--lemon); color: var(--lemon-ink);
    box-shadow: 0 4px 10px -5px rgba(178, 251, 12, .9);
}
.kp-pager .pg:disabled { background: var(--bg-sunk); color: var(--text-muted); opacity: .5; cursor: not-allowed; }
.kp-pager .pg.is-gap { background: none; border-color: transparent; color: var(--text-muted); min-width: 20px; padding: 0; }
/* A page number is too narrow for a spinner beside it, so it swaps in. */
.kp-pager .pg[data-loading] { font-size: 0; }
.kp-pager .pg[data-loading]::before {
    content: ""; width: 0.8rem; height: 0.8rem;
    border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
    animation: kp-spin .7s linear infinite;
}
.kp-pager .pg[data-loading] > i { display: none; }
@media (max-width: 575.98px) {
    .kp-pager { justify-content: center; }
    .kp-pager .kp-pager-info { width: 100%; text-align: center; }
}

/* ==========================================================================
   Password field with an eye (<x-password-input>).
   ========================================================================== */
.pw-field { position: relative; }
.pw-field .form-control { padding-right: 2.9rem; }
/* Bootstrap's invalid icon sits where the eye is; the red border says it. */
.pw-field .form-control.is-invalid { background-image: none; padding-right: 2.9rem; }
.pw-field .pw-eye {
    position: absolute; top: 1px; right: 1px; bottom: 1px;
    width: 2.6rem;
    display: grid; place-items: center;
    background: none; border: 0;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    color: var(--text-muted);
    font-size: 0.9rem;
    cursor: pointer;
    transition: color .15s;
}
.pw-field .pw-eye:hover { color: var(--text-main); }
.pw-field .pw-eye:focus-visible { outline: 2px solid var(--primary-color); outline-offset: -3px; }

/* ==========================================================================
   PIN boxes (<x-pin-boxes>) — four digits, sized like the sign-in PIN.
   ========================================================================== */
.pin-row.pin-boxes { max-width: 15.25rem; }
.pin-row.pin-boxes .pin-box { font-size: 1.35rem; }
.pin-row.pin-boxes.mx-auto { margin-left: auto; margin-right: auto; }

/* ==========================================================================
   Profile › Security — one setting per card, stacked.
   ========================================================================== */
.sec-card { padding: 1rem 1.1rem; }
.sec-card + .sec-card { margin-top: 0.75rem; }
.sec-head { display: flex; align-items: flex-start; gap: 0.75rem; min-width: 0; }
.sec-head .qa-icon { flex: none; }
.sec-head .sec-text { min-width: 0; flex: 1; }
.sec-head .sec-title { font-size: 0.92rem; font-weight: 800; letter-spacing: -0.01em; line-height: 1.3; }
.sec-head .sec-sub { font-size: 0.76rem; color: var(--text-muted); line-height: 1.4; margin-top: 0.1rem; }
.sec-head .sec-aside { flex: none; margin-left: auto; align-self: center; }
.sec-body { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--border-color); }
.sec-field + .sec-field { margin-top: 0.85rem; }
.sec-field .form-label { display: block; }
.sec-body .form-control, .sec-body .pw-field { max-width: 26rem; }
.sec-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 1rem; }
@media (min-width: 576px) { .sec-card { padding: 1.15rem 1.35rem; } }

/* ==========================================================================
   Rewards — the referral counts, one figure per line.
   ========================================================================== */
.stat-stack { display: grid; gap: 0.5rem; }
.stat-line {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "icon label value" "icon sub value";
    align-items: center;
    column-gap: 0.75rem; row-gap: 0.1rem;
    padding: 0.75rem 0.9rem;
    background: var(--bg-sunk);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
}
.stat-line .qa-icon { grid-area: icon; }
.stat-line .sl-label {
    grid-area: label; align-self: end;
    font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-muted); line-height: 1.3;
}
.stat-line .sl-sub { grid-area: sub; align-self: start; font-size: 0.75rem; color: var(--text-muted); line-height: 1.35; }
.stat-line .sl-value {
    grid-area: value; text-align: right; white-space: nowrap;
    font-size: 1.2rem; font-weight: 800; letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Notifications — each notice in full, unread ones tinted.
   ========================================================================== */
.notif-list { margin: 0 -0.6rem; }
.notif-list .notif-row {
    align-items: flex-start;
    padding: 0.85rem 0.6rem;
    border-radius: var(--radius-md);
    transition: background .2s;
}
.notif-list .notif-row + .notif-row { margin-top: 2px; }
.notif-list .notif-row.unread { background: var(--primary-soft); border-bottom-color: transparent; }
.notif-list .notif-row.unread::before { left: 0.2rem; top: 1.4rem; transform: none; }
.notif-row .nr-open {
    display: block; min-width: 0; flex: 1;
    color: inherit; text-decoration: none; text-align: left;
    background: none; border: 0; padding: 0;
}
.notif-row .nr-open:hover .nr-title { color: var(--primary-dark); }
[data-bs-theme="dark"] .notif-row .nr-open:hover .nr-title { color: var(--primary-color); }
/* A notice from the admin can run to 2,000 characters over several
   paragraphs; its line breaks are kept. */
.notif-row .nr-text { overflow-wrap: anywhere; white-space: pre-line; }
.notif-row .nr-time { margin-top: 0.2rem; display: block; }
.notif-row .nr-side { flex: none; display: flex; align-items: center; gap: 0.4rem; align-self: center; }
.notif-row.unread .nr-title::after {
    content: "New"; margin-left: 0.4rem; vertical-align: 0.1em;
    font-size: 0.58rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--primary-dark);
}
[data-bs-theme="dark"] .notif-row.unread .nr-title::after { color: var(--primary-color); }
.tx-warn { background: rgba(245, 158, 11, 0.13); color: #b45309; }
.tx-info { background: var(--bg-sunk); color: var(--text-muted); }
[data-bs-theme="dark"] .tx-warn { color: #fbbf24; }

/* ==========================================================================
   Insights chart — a canvas with a date axis and a tap-to-read value.
   ========================================================================== */
.flow-chart { position: relative; height: 170px; margin-top: 1rem; touch-action: pan-y; }
.flow-chart canvas { display: block; width: 100%; height: 100%; }
.flow-chart .chart-tip {
    position: absolute; top: 0; transform: translateX(-50%);
    background: var(--bg-card); color: var(--text-main);
    border: 1px solid var(--border-color); border-radius: 8px;
    padding: 0.2rem 0.5rem; box-shadow: var(--shadow-md);
    font-size: 0.72rem; font-weight: 700; white-space: nowrap;
    pointer-events: none; font-variant-numeric: tabular-nums;
}
.flow-chart .chart-tip small { display: block; font-size: 0.64rem; font-weight: 600; color: var(--text-muted); }
.flow-chart .chart-empty {
    position: absolute; inset: 0; display: grid; place-items: center;
    font-size: 0.8rem; color: var(--text-muted); text-align: center; pointer-events: none;
}
.donut-holder { position: relative; height: 150px; }
.donut-holder canvas { display: block; width: 100%; height: 100%; }

/* ==========================================================================
   "Choose how to …" — the first screen of Deposit and Withdraw.

   A big heading, then every option as a card in a two-column grid — two
   columns on a phone too, as the design has it — then one or two note
   strips. A card (x-option-card) is one button: a round icon, the name,
   its code, one line on what it does, and a lime arrow in a dark circle.
   Built on the theme tokens only: the dark theme matches the mockups, and
   the light one is the same layout on white cards. At 320px each card is
   about 140px wide, so names and lines wrap rather than overflow.
   ========================================================================== */
.opt-head { margin: 0.25rem 0 1rem; }
.opt-head h2 {
    font-size: clamp(1.45rem, 6.4vw, 1.95rem); font-weight: 800;
    letter-spacing: -0.035em; line-height: 1.15; margin: 0 0 0.35rem;
}
.opt-head p { font-size: 0.86rem; line-height: 1.45; color: var(--text-muted); margin: 0; }

.opt-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }

.opt-card {
    display: flex; flex-direction: column; align-items: flex-start;
    width: 100%; height: 100%; min-width: 0; padding: 1rem;
    background: var(--bg-card); color: var(--text-main);
    border: 1px solid var(--border-color); border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm); text-align: left; transition: var(--transition);
}
.opt-card:hover { border-color: var(--primary-color); }
.opt-card:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.opt-card .oc-icon { display: block; width: 48px; height: 48px; margin-bottom: 0.8rem; flex: none; }
/* The flag, cropped to the same circle as a coin. */
.opt-card .oc-icon .kp-flag {
    display: block; width: 48px; height: 48px;
    border-radius: 50%; object-fit: cover; font-size: 0.8rem;
}
.opt-card .oc-title {
    display: block; max-width: 100%;
    font-size: 1.02rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.25;
    overflow-wrap: anywhere;
}
.opt-card .oc-code { display: block; margin-top: 0.15rem; font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }
/* The foot stacks (owner decision, 2026-10-02): the rate, then what tapping
   does, each small and on its own line, then the arrow alone on the last
   line, so a figure never squeezes against it in a two-column grid. */
.opt-card .oc-foot { display: flex; flex-direction: column; align-items: stretch; gap: 0.55rem; width: 100%; margin-top: auto; padding-top: 0.6rem; }
.opt-card .oc-text { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; }
/* The rate here, leading the foot of the card: the figure a customer
   compares coins by, so it is the heavier line. */
.opt-card .oc-value {
    font-size: 0.78rem; font-weight: 700; line-height: 1.3; overflow-wrap: anywhere;
    font-variant-numeric: tabular-nums;
    color: var(--text-main);
}
.opt-card .oc-line {
    font-size: 0.74rem; line-height: 1.35; overflow-wrap: anywhere;
    color: color-mix(in srgb, var(--text-main) 74%, var(--bg-card));
}
.opt-card .oc-go {
    align-self: flex-end;
    flex: none; width: 34px; height: 34px; border-radius: 50%;
    display: grid; place-items: center; font-size: 0.8rem;
    background: color-mix(in srgb, var(--text-main) 8%, var(--bg-card));
    color: var(--primary-dark); transition: var(--transition);
}
[data-bs-theme="dark"] .opt-card .oc-go { color: var(--lemon); }
.opt-card:hover .oc-go { background: var(--primary-color); color: #fff; }
[data-bs-theme="dark"] .opt-card:hover .oc-go { color: var(--lemon-ink); }

/* Open: a tick after the line. Locked: an amber pill before it. */
.opt-card .oc-state { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.74rem; font-weight: 700; line-height: 1.2; }
.opt-card .oc-state.is-open { color: var(--primary-dark); }
.opt-card .oc-state.is-open i { font-size: 1.05rem; color: var(--primary-color); }
[data-bs-theme="dark"] .opt-card .oc-state.is-open,
[data-bs-theme="dark"] .opt-card .oc-state.is-open i { color: var(--lemon); }
.opt-card .oc-lock {
    width: 26px; height: 26px; border-radius: 50%; flex: none;
    display: grid; place-items: center; font-size: 0.68rem;
    background: rgba(245, 158, 11, 0.14); color: #b45309;
}
.opt-card .oc-pill {
    padding: 0.18rem 0.6rem; border-radius: 99px; font-size: 0.74rem; font-weight: 700;
    background: rgba(245, 158, 11, 0.14); color: #b45309;
}
[data-bs-theme="dark"] .opt-card .oc-lock,
[data-bs-theme="dark"] .opt-card .oc-pill { background: rgba(245, 158, 11, 0.16); color: #fbbf24; }

/* Working… on a card: the arrow turns into the spinner. A one-network coin
   can take a moment while its address is made. */
.opt-card[data-loading] .oc-go i { display: none; }
.opt-card[data-loading] .oc-go::before {
    content: ""; width: 0.95em; height: 0.95em; border-radius: 50%;
    border: 2px solid currentColor; border-right-color: transparent;
    animation: kp-spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .opt-card[data-loading] .oc-go::before { animation: none; border-style: dashed; }
}

/* A note under the grid: an icon, a hairline, one sentence. */
.note-strip {
    display: flex; align-items: center; gap: 0.85rem;
    padding: 0.8rem 1rem; border: 1px solid; border-radius: var(--radius-lg);
    font-size: 0.8rem; line-height: 1.45;
}
.note-strip .ns-icon { flex: none; font-size: 1.1rem; }
.note-strip .ns-text { flex: 1; min-width: 0; padding-left: 0.85rem; border-left: 1px solid; }
.note-strip b { font-weight: 800; }
.note-strip b.hd { display: block; margin-bottom: 2px; }
.note-strip.is-info {
    background: var(--primary-soft); border-color: rgba(107, 151, 0, 0.22);
    color: var(--text-main);
}
.note-strip.is-info .ns-icon { color: var(--primary-color); }
.note-strip.is-info .ns-text { border-left-color: rgba(107, 151, 0, 0.25); }
[data-bs-theme="dark"] .note-strip.is-info {
    background: rgba(178, 251, 12, 0.045); border-color: rgba(178, 251, 12, 0.14);
    color: color-mix(in srgb, var(--text-main) 82%, var(--bg-card));
}
[data-bs-theme="dark"] .note-strip.is-info .ns-text { border-left-color: rgba(255, 255, 255, 0.14); }
.note-strip.is-warn { background: rgba(245, 158, 11, 0.08); border-color: rgba(245, 158, 11, 0.35); color: #92400e; }
.note-strip.is-warn .ns-icon { color: #d97706; }
.note-strip.is-warn .ns-text { border-left-color: rgba(245, 158, 11, 0.35); }
[data-bs-theme="dark"] .note-strip.is-warn { background: rgba(245, 158, 11, 0.07); border-color: rgba(245, 158, 11, 0.3); color: #fbbf24; }
[data-bs-theme="dark"] .note-strip.is-warn .ns-icon { color: #f59e0b; }

/* Withdraw: the balance, with the eye that hides it. */
.opt-balance {
    display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
    margin-bottom: 0.75rem; padding: 0.95rem 1.1rem;
    background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
[data-bs-theme="dark"] .opt-balance {
    background: linear-gradient(120deg, rgba(178, 251, 12, 0.06), rgba(178, 251, 12, 0.015) 60%), var(--bg-card);
    border-color: rgba(178, 251, 12, 0.12);
}
.opt-balance .ob-label { display: block; font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }
.opt-balance .ob-amount {
    font-size: clamp(1.35rem, 6vw, 1.75rem); font-weight: 800; letter-spacing: -0.03em;
    line-height: 1.2; font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.opt-balance .ob-code { margin-left: 0.2rem; font-size: 0.82rem; font-weight: 600; letter-spacing: 0; color: var(--text-muted); }
.opt-balance .ob-eye {
    flex: none; width: 40px; height: 40px; border-radius: 50%;
    display: grid; place-items: center; font-size: 1.15rem;
    background: none; border: 0; color: var(--text-muted);
}
.opt-balance .ob-eye:hover { color: var(--text-main); }
.opt-balance .ob-eye:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }

.opt-note { margin: 0.75rem 0 0; font-size: 0.8rem; line-height: 1.45; color: var(--text-muted); }
.opt-foot { margin: 0.75rem 0 0; text-align: center; font-size: 0.74rem; color: var(--text-muted); }

/* The deposit network step, in the same cards: each network with its coin. */
.net-head { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; }
.net-list { display: grid; gap: 0.55rem; }
.net-list .net-opt { gap: 0.75rem; padding: 0.75rem 0.9rem; border-radius: var(--radius-lg); }
.net-list .net-opt:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.net-list .net-opt .no-name { font-size: 0.88rem; }
.net-list .net-opt .no-check { font-size: 1.1rem; }

@media (max-width: 359.98px) {
    .opt-grid { gap: 0.6rem; }
    .opt-card { padding: 0.8rem; }
    .opt-card .oc-go { width: 30px; height: 30px; }
}

/* ------------------------------------------------------------------------
   KaastroPay Business
   ------------------------------------------------------------------------ */

/* Quick actions: equal, compact tiles; none stands out from the others. */
.biz-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 0.5rem; }
.biz-action {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.3rem;
    padding: 0.6rem 0.35rem; min-height: 64px;
    background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md);
    color: var(--text-main); text-decoration: none; text-align: center;
    font-size: 0.72rem; font-weight: 600; line-height: 1.2;
}
.biz-action i {
    width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
    background: var(--primary-soft); color: var(--primary-dark); font-size: 0.8rem;
}
.biz-action:hover { border-color: var(--primary-color); color: var(--text-main); }

/* Small figures under the balance. */
.biz-mini-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
.biz-mini {
    background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-md);
    padding: 0.5rem 0.65rem; min-width: 0;
}
.biz-mini span { display: block; font-size: 0.6rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.biz-mini b { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.74rem; font-weight: 700; font-variant-numeric: tabular-nums; }

/* A business's logo, or its initials where it has none. */
.biz-logo {
    width: 44px; height: 44px; border-radius: 12px; flex: none; overflow: hidden;
    display: grid; place-items: center; background: #6B9700; color: #fff; font-weight: 700; font-size: 0.85rem;
}
.biz-logo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.biz-logo.lg { width: 64px; height: 64px; border-radius: 16px; font-size: 1.1rem; }

/* ---------------------------------------------------------------------------
   In-store QR (Business\StoreQr): the business's permanent shop QR card.
   The card stays light in both themes because it is printed and stuck to a
   counter; Print QR prints the card alone (the print block below).
   --------------------------------------------------------------------------- */
.shop-qr-head { text-align: center; margin-bottom: 1rem; }
.shop-qr-head h2 { font-size: 1.15rem; font-weight: 800; margin: 0 0 0.25rem; }
.shop-qr-head p { font-size: 0.82rem; color: var(--text-muted); margin: 0; }
.shop-qr-card {
    background: #ffffff; color: #0f172a; text-align: center;
    border: 1px solid var(--border-color); border-radius: 22px;
    padding: 1.25rem 1.1rem 1rem; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.08);
}
.shop-qr-card .shop-qr-brand { height: 28px; width: auto; margin-bottom: 0.9rem; }
.shop-qr-biz {
    display: flex; align-items: center; gap: 0.75rem; text-align: left;
    background: #f4f8ec; border: 1px solid #e1e9d2; border-radius: 14px; padding: 0.65rem 0.75rem;
}
.shop-qr-biz .sq-name { font-weight: 700; font-size: 0.98rem; color: #0f172a; }
.shop-qr-biz .sq-tick { color: #6B9700; font-size: 0.85rem; margin-left: 0.2rem; }
.shop-qr-biz .sq-mid { font-size: 0.74rem; color: #64748b; }
.shop-qr-code {
    position: relative; display: inline-grid; place-items: center; margin: 1rem 0 0.6rem;
    padding: 12px; background: #ffffff; border: 1px solid #e5e7eb; border-radius: 16px;
}
.shop-qr-code .sq-qr { width: 216px; height: 216px; }
.shop-qr-code .sq-qr img, .shop-qr-code .sq-qr canvas { display: block; width: 100%; height: 100%; }
.shop-qr-code .sq-mark {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: 46px; height: 46px; padding: 4px; background: #ffffff; border-radius: 10px;
}
.shop-qr-cta { font-size: 1.45rem; font-weight: 800; letter-spacing: 0.02em; line-height: 1.2; }
.shop-qr-hint { font-size: 0.8rem; color: #64748b; }
.shop-qr-accept { border-top: 1px solid #e5e7eb; margin-top: 0.9rem; padding-top: 0.7rem; }
.shop-qr-accept .sq-label { font-size: 0.72rem; font-weight: 600; color: #64748b; margin-bottom: 0.4rem; }
.shop-qr-accept .sq-coins { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.5rem 1.2rem; }
.shop-qr-accept .sq-coins span { display: inline-flex; align-items: center; gap: 0.35rem; font-weight: 700; font-size: 0.82rem; }
.shop-qr-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; margin-top: 1rem; }
.shop-qr-more {
    display: flex; align-items: center; gap: 0.5rem; margin: 1.1rem 0 0.5rem;
    color: var(--primary-dark); font-size: 0.82rem; font-weight: 700; text-decoration: none; white-space: nowrap;
}
[data-bs-theme="dark"] .shop-qr-more { color: var(--primary-color); }
.shop-qr-more::before, .shop-qr-more::after { content: ""; flex: 1; height: 1px; background: var(--border-color); }
.shop-qr-more:hover { text-decoration: underline; }
@media (max-width: 380px) {
    .shop-qr-code .sq-qr { width: 184px; height: 184px; }
    .shop-qr-actions { grid-template-columns: 1fr; }
}
@media print {
    body:has(.shop-qr-card) * { visibility: hidden !important; }
    body:has(.shop-qr-card) .shop-qr-card, body:has(.shop-qr-card) .shop-qr-card * { visibility: visible !important; }
    body:has(.shop-qr-card) .shop-qr-card {
        position: absolute; left: 50%; top: 12mm; transform: translateX(-50%);
        width: 110mm; border: 1px solid #d1d5db; box-shadow: none;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
}

/* Checkout: the coin, then its network. */
.coin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 0.5rem; }
.coin-card {
    position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.35rem;
    padding: 0.8rem 0.5rem 0.7rem; border-radius: var(--radius-md);
    border: 1.5px solid var(--border-color); background: var(--bg-card); color: var(--text-main);
    text-align: center; line-height: 1.2;
}
.coin-card .cc-sym { font-weight: 800; font-size: 0.9rem; }
.coin-card .cc-name { font-size: 0.68rem; color: var(--text-muted); }
.coin-card .cc-tick {
    position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; border-radius: 50%;
    display: none; place-items: center; font-size: 0.6rem;
    background: var(--primary-color); color: #0a0a0a;
}
.coin-card.on { border-color: var(--primary-color); background: var(--primary-soft); }
.coin-card.on .cc-tick { display: grid; }
.coin-card:focus-visible, .chain-card:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }

.chain-list { display: grid; gap: 0.45rem; }
.chain-card {
    display: flex; align-items: center; gap: 0.7rem; width: 100%;
    padding: 0.6rem 0.75rem; border-radius: var(--radius-md);
    border: 1.5px solid var(--border-color); background: var(--bg-card); color: var(--text-main); text-align: left;
}
.chain-card .ch-name { display: block; font-weight: 700; font-size: 0.86rem; line-height: 1.25; }
.chain-card .ch-sub { display: block; font-size: 0.7rem; color: var(--text-muted); }
.chain-card .ch-tag { margin-left: auto; font-size: 0.64rem; font-weight: 700; padding: 0.15rem 0.45rem; border-radius: 999px; background: var(--primary-soft); color: var(--primary-dark); }
.chain-card .ch-radio {
    margin-left: auto; width: 18px; height: 18px; border-radius: 50%; flex: none;
    border: 2px solid var(--border-color);
}
.chain-card .ch-tag + .ch-radio { margin-left: 0.5rem; }
.chain-card.on { border-color: var(--primary-color); background: var(--primary-soft); }
.chain-card.on .ch-radio { border-color: var(--primary-color); box-shadow: inset 0 0 0 4px var(--bg-card); background: var(--primary-color); }
.pick-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 0.4rem; }
