/* ==========================================================================
   Umoja Chama — Design System
   White background, glassmorphism buttons with gradients & soft shadows.
   ========================================================================== */

:root {
    /* Tell the browser which scheme to paint ITS controls for. Left to say
       "light dark", it follows the operating system instead, so a Windows
       machine in dark mode drew black boxes over a white page. */
    color-scheme: light;

    --bg: #ffffff;
    --surface: #ffffff;
    --surface-alt: #f7f8fc;
    --border: #e7e9f3;
    --text: #14162b;
    --text-muted: #5f6478;
    --text-soft: #63687e;

    /* Colours that are safe to use AS TEXT on a light surface.
       The vivid brand colours below are for fills and borders only —
       most of them are far too light to read as text on white. */
    --t-brand:   #5442d6;
    --t-info:    #0b6f94;
    --t-success: #0d6b49;
    --t-warn:    #7d4e00;
    --t-danger:  #c01a37;
    --t-in:      #0d6b49;
    --t-out:     #9a3d0a;

    /* "Earnings by source" accents — readable on a light page */
    --sc1: #a3610a; --sc2: #0b6f94; --sc3: #0d6b49;
    --sc4: #5442d6; --sc5: #a81f63; --sc6: #1d4ed8;

    --brand-1: #6d5efc;
    --brand-2: #46c9ff;
    --brand-3: #22d3a8;
    --brand-4: #ff6fa0;
    --warn: #ffb020;
    --danger: #ff5470;
    --success: #1fb178;

    --grad-primary: linear-gradient(135deg, #6d5efc 0%, #2563eb 100%);
    /* decorative only — never put text on this one */
    --grad-accent: linear-gradient(135deg, #6d5efc 0%, #46c9ff 100%);
    /* used for gradient-filled TEXT, so both stops must read on the page */
    --grad-text: linear-gradient(135deg, #5442d6 0%, #1d4ed8 100%);
    --grad-success: linear-gradient(135deg, #0c855d 0%, #065f46 100%);
    --grad-warn: linear-gradient(135deg, #a36907 0%, #7c4708 100%);
    --grad-danger: linear-gradient(135deg, #c81e43 0%, #9f1239 100%);
    --grad-dark: linear-gradient(135deg, #21243b 0%, #3a3f66 100%);

    --shadow-sm: 0 2px 8px rgba(20, 22, 43, 0.06);
    --shadow-md: 0 8px 24px rgba(20, 22, 43, 0.10);
    --shadow-lg: 0 16px 48px rgba(20, 22, 43, 0.14);
    --shadow-glow: 0 8px 30px rgba(109, 94, 252, 0.35);

    --radius-sm: 10px;
    --radius-md: 16px;
    --radius-lg: 24px;
    --radius-pill: 999px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
html { scroll-behavior: smooth; }

::selection { background: rgba(109,94,252,.22); }

/* Custom scrollbar for a premium feel */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #d7d9ea; border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: #b9bcda; }

@media (prefers-reduced-motion: no-preference) {
    @keyframes fadeInUp {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
    }
    .card, .card-glass, .card-gradient, .auth-card, .stat-card {
        animation: fadeInUp .45s ease both;
    }
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    line-height: 1.5;
}

a { color: var(--t-brand); text-decoration: none; }
h1, h2, h3, h4 { margin: 0 0 .5em; letter-spacing: -0.02em; }
p { margin: 0 0 1em; color: var(--text-muted); }

img { max-width: 100%; display: block; }

.container {
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 24px;
}

/* ---------------- Navbar ---------------- */
.navbar {
    position: sticky;
    top: 0;
    z-index: 50;
    background: rgba(255, 255, 255, 0.75);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
}
.navbar .inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 24px;
    max-width: 1180px;
    margin: 0 auto;
}
.brand {
    font-weight: 800;
    font-size: 1.25rem;
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text);
}
.brand .dot {
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--grad-primary);
    box-shadow: 0 0 0 4px rgba(109,94,252,.15);
}
.nav-links { display: flex; align-items: center; gap: 8px; }
.nav-links a.nav-link {
    padding: 8px 14px;
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    font-weight: 600;
    font-size: .92rem;
}
.nav-links a.nav-link:hover { background: var(--surface-alt); color: var(--text); }

/* ---------------- Buttons: glass + gradient + shadow ---------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: none;
    cursor: pointer;
    font-weight: 700;
    font-size: .95rem;
    padding: 12px 24px;
    border-radius: var(--radius-pill);
    transition: transform .15s ease, box-shadow .2s ease, filter .2s ease;
    text-decoration: none;
    white-space: nowrap;
}
.btn:active { transform: translateY(1px) scale(.98); }

.btn-primary {
    background: var(--grad-primary);
    color: #fff;
    box-shadow: var(--shadow-glow);
}
.btn-primary:hover { filter: brightness(1.07); box-shadow: 0 12px 36px rgba(109,94,252,.45); transform: translateY(-1px); }

.btn-success {
    background: var(--grad-success);
    color: #fff;
    box-shadow: 0 8px 24px rgba(31,177,120,.35);
}
.btn-success:hover { filter: brightness(1.07); transform: translateY(-1px); }

.btn-warn { background: var(--grad-warn); color: #fff; box-shadow: 0 8px 24px rgba(255,138,61,.35); }
.btn-warn:hover { filter: brightness(1.06); transform: translateY(-1px); }

.btn-danger { background: var(--grad-danger); color: #fff; box-shadow: 0 8px 24px rgba(255,84,112,.35); }
.btn-danger:hover { filter: brightness(1.06); transform: translateY(-1px); }

.btn-dark { background: var(--grad-dark); color: #fff; box-shadow: 0 8px 24px rgba(33,36,59,.35); }

.btn-glass {
    background: rgba(255,255,255,0.55);
    color: var(--text);
    border: 1px solid rgba(255,255,255,0.6);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: var(--shadow-sm);
}
.btn-glass:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }

.btn-outline {
    background: transparent;
    color: var(--t-brand);
    border: 1.5px solid var(--t-brand);
}
.btn-outline:hover { background: rgba(109,94,252,.10); }

.btn-sm { padding: 7px 16px; font-size: .82rem; }
.btn-lg { padding: 16px 32px; font-size: 1.05rem; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; filter: grayscale(.3); }

/* ---------------- Glass cards ---------------- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 28px;
}
.card-glass {
    background: rgba(255,255,255,0.6);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid rgba(255,255,255,0.7);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 28px;
}
.card-gradient {
    border-radius: var(--radius-lg);
    padding: 28px;
    color: #fff;
    background: var(--grad-primary);
    box-shadow: var(--shadow-glow);
    position: relative;
    overflow: hidden;
}
.card-gradient::after {
    content: '';
    position: absolute; inset: 0;
    background: radial-gradient(circle at 85% 15%, rgba(255,255,255,.25), transparent 55%);
}

/* ---------------- Forms ---------------- */
.form-group { margin-bottom: 18px; }
label { display: block; font-weight: 600; font-size: .88rem; margin-bottom: 6px; color: var(--text); }
.hint { font-size: .8rem; color: var(--text-soft); margin-top: 4px; }

/* Every text-like field, however it is written in the HTML.
   Listing input[type=text] alone was a trap: an attribute selector matches the
   ATTRIBUTE, so a plain <input name="site_name"> — which is a text box as far
   as the browser is concerned — matched nothing and fell back to the browser's
   own styling. Hence input:not([type]) below.

   This was written as one long :not() chain instead, which worked but cost us
   something invisible: every :not() adds to a selector's specificity, so the
   chain of ten outranked .input-icon > .icon ~ input and silently killed the
   padding that keeps text clear of the leading icon. Naming the types we want
   keeps each selector at a plain (0,1,1) so the icon rules win normally. */
input[type=text], input[type=tel], input[type=email], input[type=password],
input[type=number], input[type=search], input[type=url], input[type=date],
input[type=datetime-local], input[type=month], input[type=time],
input[type=week], input:not([type]),
select, textarea {
    width: 100%;
    padding: 12px 16px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    /* 16px: anything smaller makes iOS Safari zoom in when the field is tapped */
    font-size: 16px;
    min-height: 46px;
    background: var(--surface-alt);
    color: var(--text);
    transition: border-color .15s, box-shadow .15s;
    font-family: inherit;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--t-brand);
    box-shadow: 0 0 0 4px rgba(109,94,252,.18);
    background: var(--surface);
}
::placeholder { color: var(--text-soft); opacity: 1; }
textarea { resize: vertical; min-height: 90px; }

.radio-group, .checkbox-group { display: flex; flex-wrap: wrap; gap: 10px; }
.radio-pill {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 16px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-pill);
    cursor: pointer;
    font-size: .9rem;
    font-weight: 600;
    background: var(--surface-alt);
    transition: all .15s;
}
.radio-pill input { accent-color: var(--brand-1); }
.radio-pill:has(input:checked) {
    border-color: var(--t-brand);
    background: rgba(109,94,252,.12);
    color: var(--t-brand);
}
.radio-pill { min-height: 44px; }

/* ---------------- Alerts ---------------- */
.alert {
    padding: 14px 18px;
    border-radius: var(--radius-sm);
    margin-bottom: 18px;
    font-size: .9rem;
    font-weight: 600;
}
.alert-success { background: rgba(13,107,73,.10); color: var(--t-success); border: 1px solid rgba(13,107,73,.28); }
.alert-error { background: rgba(192,26,55,.10); color: var(--t-danger); border: 1px solid rgba(192,26,55,.28); }
.alert-info { background: rgba(11,111,148,.10); color: var(--t-info); border: 1px solid rgba(11,111,148,.28); }
.alert-warn { background: rgba(125,78,0,.10); color: var(--t-warn); border: 1px solid rgba(125,78,0,.28); }

/* ---------------- Badges ---------------- */
.badge {
    display: inline-block;
    padding: 4px 12px;
    border-radius: var(--radius-pill);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
}
.badge-success { background: rgba(13,107,73,.12); color: var(--t-success); }
.badge-warn { background: rgba(125,78,0,.12); color: var(--t-warn); }
.badge-danger { background: rgba(192,26,55,.12); color: var(--t-danger); }
.badge-muted { background: var(--surface-alt); color: var(--text-muted); }
.badge-brand { background: rgba(84,66,214,.12); color: var(--t-brand); }

/* ---------------- Tables ---------------- */
.table-wrap { overflow-x: auto; border-radius: var(--radius-md); border: 1px solid var(--border); }
table { width: 100%; border-collapse: collapse; font-size: .88rem; }
th, td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
th { background: var(--surface-alt); font-weight: 700; color: var(--text-muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; }
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-alt); }

/* ---------------- Hero ---------------- */
.hero {
    padding: 90px 0 70px;
    text-align: center;
    background:
        radial-gradient(circle at 15% 20%, rgba(109,94,252,.10), transparent 45%),
        radial-gradient(circle at 85% 10%, rgba(70,201,255,.10), transparent 40%);
}
.hero h1 { font-size: clamp(2.1rem, 4.5vw, 3.4rem); max-width: 780px; margin: 0 auto .3em; }
.hero .gradient-text {
    color: var(--t-brand);
    background: var(--grad-text);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.hero p.lead { font-size: 1.15rem; max-width: 620px; margin: 0 auto 2em; }
.hero-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

.features-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 20px;
    margin: 50px 0;
}
.features-grid .card,
.grid-3 > .card-glass {
    transition: transform .2s ease, box-shadow .2s ease;
}
.features-grid .card:hover,
.grid-3 > .card-glass:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
}
.feature-icon {
    width: 48px; height: 48px;
    border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary);
    color: #fff;
    font-size: 1.3rem;
    margin-bottom: 14px;
    box-shadow: var(--shadow-glow);
}

/* ---------------- Layout: app shell ---------------- */
.app-shell { display: flex; min-height: 100vh; }
.sidebar {
    width: 250px;
    flex-shrink: 0;
    background: var(--grad-dark);
    color: #fff;
    padding: 24px 16px;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}
.sidebar .brand { color: #fff; padding: 0 8px 24px; }
.sidebar-link {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    color: rgba(255,255,255,.86);
    font-weight: 600;
    font-size: .9rem;
    margin-bottom: 4px;
    transition: all .15s;
}
.sidebar-link:hover { background: rgba(255,255,255,.08); color: #fff; }
.sidebar-link.active { background: rgba(255,255,255,.14); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); }
.sidebar-section { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: rgba(255,255,255,.62); margin: 18px 8px 8px; font-weight: 700; }

.main-content { flex: 1; padding: 32px; min-width: 0; }
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 26px; flex-wrap: wrap; gap: 12px; }
.page-header h1 { font-size: 1.5rem; margin: 0; }
.page-header p { margin: 2px 0 0; }

/* ---------------- Stats grid ---------------- */
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; margin-bottom: 26px; }
.stat-card { }
.stat-label { font-size: .8rem; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .03em; }
.stat-value { font-size: 1.9rem; font-weight: 800; margin-top: 6px; font-variant-numeric: tabular-nums; }
/* The decimals are part of the number, not a footnote: same size, same
   weight, same colour, so a growing balance reads as one figure. */
.stat-value .decimals { font-size: 1em; opacity: 1; }

/* ---------------- Progress steps (registration wizard) ---------------- */
.steps { display: flex; justify-content: center; gap: 8px; margin-bottom: 34px; }
.step-dot {
    width: 34px; height: 34px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: .85rem;
    background: var(--surface-alt);
    color: var(--text-soft);
    border: 2px solid var(--border);
}
.step-dot.active { background: var(--grad-primary); color: #fff; border-color: transparent; box-shadow: var(--shadow-glow); }
.step-dot.done { background: var(--grad-success); color: #fff; border-color: transparent; }
.step-line { width: 40px; height: 2px; background: var(--border); align-self: center; margin-top: 16px; }

.auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    background:
        radial-gradient(circle at 10% 10%, rgba(109,94,252,.08), transparent 40%),
        radial-gradient(circle at 90% 90%, rgba(70,201,255,.08), transparent 40%);
}
.auth-card { width: 100%; max-width: 460px; }
.auth-card.wide { max-width: 620px; }

footer.site-footer { border-top: 1px solid var(--border); padding: 36px 0; margin-top: 60px; }
footer.site-footer .inner { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; color: var(--text-soft); font-size: .85rem; }

.locked-banner {
    display: flex; align-items: center; gap: 10px;
    background: rgba(125,78,0,.10);
    border: 1px solid rgba(125,78,0,.28);
    color: var(--t-warn);
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    font-size: .85rem;
    font-weight: 600;
}

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }

/* ---------------- Mobile nav toggle (hamburger) ---------------- */
.mobile-nav-toggle {
    display: none;
    position: fixed;
    top: 14px;
    left: 16px;
    z-index: 120;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    border: none;
    background: rgba(255,255,255,0.8);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: var(--shadow-md);
    font-size: 1.15rem;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(20,22,43,.4);
    z-index: 99;
}
.sidebar-backdrop.open { display: block; }

@media (max-width: 900px) {
    .grid-2, .grid-3 { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed;
        left: -270px;
        top: 0;
        z-index: 100;
        transition: left .25s ease;
        box-shadow: var(--shadow-lg);
        width: 260px;
    }
    .sidebar.open { left: 0; }
    .main-content { padding: 20px 16px 40px; }
    .mobile-nav-toggle { display: flex; }
    .page-header { padding-top: 44px; }
}

@media (max-width: 600px) {
    .container { padding: 0 16px; }
    .card, .card-glass, .card-gradient { padding: 18px; border-radius: var(--radius-md); }
    .hero { padding: 60px 0 44px; }
    .hero h1 { font-size: 1.85rem; }
    .hero p.lead { font-size: 1rem; }
    .hero-actions { flex-direction: column; align-items: stretch; }
    .hero-actions .btn { width: 100%; }
    .btn-lg { padding: 14px 22px; font-size: 1rem; }
    .navbar .inner { padding: 12px 16px; }
    .brand { font-size: 1.05rem; }
    .stats-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
    .stat-value { font-size: 1.5rem; }
    .steps { gap: 4px; }
    .step-dot { width: 28px; height: 28px; font-size: .75rem; }
    .step-line { width: 20px; margin-top: 13px; }
    table { font-size: .8rem; }
    th, td { padding: 10px 12px; }
    .grid-3 > div .form-group { min-width: 0; }
    .page-header h1 { font-size: 1.25rem; }
    .mpesa-modal { padding: 20px !important; }
}

@media (max-width: 420px) {
    .stats-grid { grid-template-columns: 1fr; }
}

/* ---------------- Icons ---------------- */
.icon {
    flex-shrink: 0;
    vertical-align: middle;
    display: inline-block;
}
.btn .icon, .sidebar-link .icon, .nav-link .icon { margin-top: -1px; }
.sidebar-link { display: flex; align-items: center; gap: 10px; }
h3 .icon { vertical-align: -3px; margin-right: 6px; color: var(--t-brand); }

/* ---------------- Inputs with a leading icon ---------------- */
.input-icon { position: relative; display: flex; align-items: center; }
.input-icon > .icon {
    position: absolute;
    left: 14px;
    color: var(--text-soft);
    pointer-events: none;
}
.input-icon > .icon ~ input { padding-left: 42px; }
.input-icon input { width: 100%; }
.input-icon:focus-within > .icon { color: var(--t-brand); }

.pw-toggle {
    position: absolute;
    right: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px; height: 34px;
    border: none;
    background: transparent;
    color: var(--text-soft);
    border-radius: 8px;
    cursor: pointer;
}
.pw-toggle:hover { color: var(--text); background: rgba(20,22,43,.05); }

/* ---------------- Announcements ---------------- */
/* The admin's list of posted notices.
   A plain .activity-item puts the text and the buttons on one flex line. The
   buttons do not shrink, so on a phone the text was squeezed to zero width
   and vanished entirely. Here the row wraps instead: the words keep a real
   minimum width, and the buttons drop onto their own line when there is not
   room beside them. */
.announce-row { flex-wrap: wrap; align-items: flex-start; }
.announce-row .activity-body { flex: 1 1 200px; min-width: 0; }
.announce-row .announce-actions { flex: 1 1 100%; }
@media (min-width: 640px) {
    .announce-row .announce-actions { flex: 0 0 auto; }
}

.notice {
    display: flex; align-items: flex-start; gap: 13px; flex-wrap: wrap;
    padding: 16px 18px;
    border-radius: var(--radius-md);
    border: 1.5px solid var(--border);
    background: var(--surface);
    margin-bottom: 18px;
}
.notice-icon { display: flex; flex-shrink: 0; margin-top: 1px; color: var(--t-brand); }
.notice-body { flex: 1 1 260px; min-width: 0; }
.notice-title { font-size: 1rem; font-weight: 800; margin: 0 0 3px; color: var(--text); }
.notice-text { margin: 0; font-size: .89rem; line-height: 1.5; color: var(--text-soft); }
.notice-btn {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 11px 17px; min-height: 44px;
    border-radius: var(--radius-pill);
    background: var(--t-brand); color: #fff;
    font-weight: 700; font-size: .87rem;
    text-decoration: none; flex-shrink: 0;
}
.notice-btn:hover { filter: brightness(1.08); }
.notice-btn .icon { flex-shrink: 0; }
.notice-info    { border-color: rgba(109,94,252,.35); background: rgba(109,94,252,.07); }
.notice-success { border-color: rgba(13,107,73,.30); background: rgba(13,107,73,.07); }
.notice-success .notice-icon { color: var(--t-success); }
.notice-warn    { border-color: rgba(125,78,0,.32); background: rgba(125,78,0,.08); }
.notice-warn .notice-icon { color: var(--t-warn); }

/* ---------------- Currency switch ---------------- */
/* Reads as a two-state switch: the currency you are in, then the one a tap
   would take you to. */
.cur-toggle {
    display: inline-flex; align-items: center; gap: 1px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-pill);
    overflow: hidden;
    font-size: .72rem; font-weight: 800; letter-spacing: .02em;
    min-height: 38px;
    text-decoration: none;
    background: var(--surface-alt);
}
.cur-toggle .cur-on,
.cur-toggle .cur-off { padding: 0 9px; line-height: 35px; }
/* White on the dark theme's lighter brand purple only reaches 2.35:1, so the
   active half takes near-black text there instead (7.6:1). */
.cur-toggle .cur-on  { background: var(--t-brand); color: #fff; }
html[data-theme="dark"] .cur-toggle .cur-on { color: #14162b; }
@media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]) .cur-toggle .cur-on { color: #14162b; }
}
.cur-toggle .cur-off { color: var(--text-soft); }
.cur-toggle:hover .cur-off { color: var(--text); }
@media (pointer: coarse) { .cur-toggle { min-height: 44px; }
    .cur-toggle .cur-on, .cur-toggle .cur-off { line-height: 41px; } }

/* ---------------- Withdrawal fee preview ---------------- */
/* Shown under the amount box: what the fee comes to and what actually
   reaches the member, updated as they type. */
.fee-box {
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    padding: 13px 15px;
    margin-bottom: 14px;
}
.fee-rule {
    display: flex; align-items: flex-start; gap: 8px;
    font-size: .82rem; color: var(--text-soft); line-height: 1.45;
}
.fee-rule .icon { flex-shrink: 0; margin-top: 2px; }
.fee-rule strong { color: var(--text); }
.fee-split {
    display: flex; flex-wrap: wrap; gap: 10px 26px;
    margin-top: 11px; padding-top: 11px;
    border-top: 1px solid var(--border);
}
.fee-split > div { display: flex; flex-direction: column; gap: 2px; min-width: 110px; }
.fee-k {
    font-size: .7rem; font-weight: 800; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-soft);
}
.fee-v { font-size: 1.05rem; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text); }
.fee-net { color: var(--t-success); }
.fee-box.fee-warn { border-color: var(--t-danger); }
.fee-box.fee-warn .fee-net { color: var(--t-danger); }

/* ---------------- Password strength meter ---------------- */
/* Four bars that fill as the password gets harder to guess. It advises and
   never blocks — a short password is still accepted. */
.pw-meter { margin-top: 8px; }
.pw-bars { display: flex; gap: 5px; }
.pw-bars > span {
    flex: 1;
    height: 5px;
    border-radius: 3px;
    background: var(--border);
    transition: background .18s ease;
}
.pw-text {
    margin-top: 6px;
    font-size: .78rem;
    font-weight: 600;
    color: var(--text-soft);
    min-height: 1.1em;
    line-height: 1.35;
}
.pw-level-1 .pw-bars > span:nth-child(-n+1) { background: var(--t-danger); }
.pw-level-2 .pw-bars > span:nth-child(-n+2) { background: var(--t-warn); }
.pw-level-3 .pw-bars > span:nth-child(-n+3) { background: var(--t-brand); }
.pw-level-4 .pw-bars > span                 { background: var(--t-success); }
.pw-level-1 .pw-text { color: var(--t-danger); }
.pw-level-2 .pw-text { color: var(--t-warn); }
.pw-level-3 .pw-text { color: var(--t-brand); }
.pw-level-4 .pw-text { color: var(--t-success); }

/* Keep the password out from under the eye button. The class on the input is
   what does the work: :has() is only a safety net for markup that forgets it,
   and it is missing on older Android browsers, which is exactly where a
   dropped rule would go unnoticed. */
/* 60px = the button's 44px touch target + its 8px offset from the edge + an
   8px gap, so a long password never slides under it on a phone. */
.input-icon input.has-toggle { padding-right: 60px; }
.input-icon:has(.pw-toggle) input { padding-right: 60px; }

.checkbox-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-weight: 500;
    font-size: .9rem;
    color: var(--text-muted);
    cursor: pointer;
}
.checkbox-row input[type=checkbox] {
    width: 18px; height: 18px;
    accent-color: var(--brand-1);
    margin-top: 1px;
    flex-shrink: 0;
}

/* ---------------- Auth badge ---------------- */
.auth-badge {
    width: 48px; height: 48px;
    border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary);
    color: #fff;
    margin-bottom: 16px;
    box-shadow: var(--shadow-glow);
}

/* ---------------- Toast notifications ---------------- */
.toast-host {
    position: fixed;
    top: 16px; right: 16px;
    z-index: 300;
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: min(380px, calc(100vw - 32px));
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 13px 14px;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    transform: translateX(120%);
    opacity: 0;
    transition: transform .28s cubic-bezier(.22,1,.36,1), opacity .28s ease;
    pointer-events: auto;
}
.toast.show { transform: translateX(0); opacity: 1; }
.toast-msg { margin: 0; font-size: .88rem; font-weight: 600; color: var(--text); flex: 1; line-height: 1.45; }
.toast-icon { display: flex; flex-shrink: 0; margin-top: 1px; }
.toast-close {
    border: none; background: transparent; cursor: pointer;
    color: var(--text-soft); padding: 2px; border-radius: 6px;
    display: flex; flex-shrink: 0;
}
.toast-close:hover { color: var(--text); }
.toast-success .toast-icon { color: var(--t-success); }
.toast-success { border-left: 3px solid var(--success); }
.toast-error .toast-icon { color: var(--t-danger); }
.toast-error { border-left: 3px solid var(--danger); }
.toast-warn .toast-icon { color: var(--t-warn); }
.toast-warn { border-left: 3px solid var(--warn); }
.toast-info .toast-icon { color: var(--t-info); }
.toast-info { border-left: 3px solid var(--brand-2); }

@media (max-width: 600px) {
    .toast-host { top: auto; bottom: 16px; left: 16px; right: 16px; max-width: none; }
    .toast { transform: translateY(140%); }
    .toast.show { transform: translateY(0); }
}

/* ---------------- Alerts get icons too ---------------- */
.alert { display: flex; align-items: flex-start; gap: 10px; }
.alert .icon { flex-shrink: 0; margin-top: 1px; }

/* ---------------- Button loading state ---------------- */
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
    content: '';
    position: absolute;
    width: 17px; height: 17px;
    border: 2px solid rgba(255,255,255,.45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btnSpin .6s linear infinite;
}
.btn-glass.is-loading::after, .btn-outline.is-loading::after {
    border-color: rgba(20,22,43,.25); border-top-color: var(--brand-1);
}
@keyframes btnSpin { to { transform: rotate(360deg); } }

/* ---------------- Plan cards ---------------- */
.plan-card { display: flex; flex-direction: column; transition: transform .2s ease, box-shadow .2s ease; }
.plan-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.plan-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.plan-icon {
    width: 42px; height: 42px;
    border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary);
    color: #fff;
    box-shadow: var(--shadow-glow);
}
.plan-rate { display: flex; align-items: baseline; gap: 6px; margin: 14px 0 10px; }
.plan-rate-value {
    font-size: 1.9rem; font-weight: 800; letter-spacing: -.02em;
    color: var(--t-brand);
    background: var(--grad-text);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
}
/* If background-clip:text is not supported, the solid colour above shows instead */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .plan-rate-value, .hero .gradient-text { -webkit-text-fill-color: currentColor; }
}
.plan-facts { list-style: none; padding: 0; margin: 0 0 18px; }
.plan-facts li {
    display: flex; align-items: center; gap: 8px;
    font-size: .85rem; color: var(--text-muted);
    padding: 5px 0;
}
.plan-facts .icon { color: var(--t-brand); }
.plan-card form { margin-top: auto; }

/* ---------------- Empty states ---------------- */
.empty-icon { color: var(--text-soft); margin-bottom: 12px; opacity: .7; }
.empty-state h3 { margin-bottom: 6px; color: var(--text); }

/* ---------------- Prose (terms page) ---------------- */
.prose p { color: var(--text-muted); line-height: 1.75; margin-bottom: 1.1em; }

/* ---------------- M-Pesa payment modal ---------------- */
.mpesa-modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(20, 22, 43, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
    z-index: 200;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}
.mpesa-modal-backdrop.open { opacity: 1; pointer-events: auto; }
.mpesa-modal {
    width: 100%;
    max-width: 400px;
    position: relative;
    text-align: center;
    background: rgba(255,255,255,0.92);
    transform: translateY(10px) scale(.98);
    transition: transform .2s ease;
}
.mpesa-modal-backdrop.open .mpesa-modal { transform: translateY(0) scale(1); }
.mpesa-modal-icon {
    width: 56px; height: 56px;
    margin: 0 auto 10px;
    border-radius: 16px;
    background: var(--grad-success);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.6rem;
    box-shadow: 0 8px 24px rgba(31,177,120,.35);
}
.mpesa-close {
    position: absolute; top: 12px; right: 14px;
    background: none; border: none; font-size: 1.4rem;
    color: var(--text-soft); cursor: pointer; line-height: 1;
}
.mpesa-close:hover { color: var(--text); }

.empty-state { text-align: center; padding: 50px 20px; color: var(--text-soft); }
.mb-0 { margin-bottom: 0; } .mt-2 { margin-top: 16px; }
.flex { display: flex; } .items-center { align-items: center; } .justify-between { justify-content: space-between; }
.gap-2 { gap: 8px; } .gap-3 { gap: 12px; }
.text-muted { color: var(--text-muted); } .text-sm { font-size: .85rem; }
.w-full { width: 100%; }

/* =====================================================================
   SIMPLE MEMBER EXPERIENCE — colourful containers, big actions
   ===================================================================== */

/* ---- Member top bar (members don't get the admin sidebar) ---- */
.member-shell { min-height: 100vh; display: flex; flex-direction: column; background: #fff; }
.member-topbar {
    position: sticky; top: 0; z-index: 50;
    background: rgba(255,255,255,.82);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
}
.member-topbar .inner {
    max-width: 780px; margin: 0 auto;
    padding: 12px 18px;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.member-main {
    flex: 1;
    width: 100%; max-width: 780px;
    margin: 0 auto;
    padding: 20px 18px 110px;   /* bottom padding clears the mobile nav */
}
.avatar-chip {
    display: flex; align-items: center; gap: 9px;
    padding: 5px 12px 5px 5px;
    border-radius: var(--radius-pill);
    background: var(--surface-alt);
    border: 1px solid var(--border);
    font-weight: 700; font-size: .84rem; color: var(--text);
}
.avatar-circle {
    width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary); color: #fff;
    font-size: .8rem; font-weight: 800;
}

/* ---- Mobile bottom navigation ---- */
.bottom-nav {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 60;
    display: flex;
    background: rgba(255,255,255,.94);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid var(--border);
    padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
    box-shadow: 0 -4px 20px rgba(20,22,43,.06);
}
.bottom-nav a {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 6px 2px;
    color: var(--text-soft);
    font-size: .68rem; font-weight: 700;
    border-radius: 12px;
}
.bottom-nav a.active { color: var(--t-brand); background: rgba(84,66,214,.10); }
.bottom-nav a:active { transform: scale(.94); }

/* ---- Colourful containers ---- */
.tile {
    position: relative; overflow: hidden;
    border-radius: var(--radius-lg);
    padding: 18px;
    color: #fff;
    box-shadow: var(--shadow-md);
}
.tile::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 88% 12%, rgba(255,255,255,.14), transparent 58%);
    pointer-events: none;
}
.tile > * { position: relative; z-index: 1; }
.tile-label { font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; opacity: .9; }
.tile-value { font-size: 1.45rem; font-weight: 800; margin-top: 6px; letter-spacing: -.02em; }
.tile-foot { font-size: .75rem; opacity: .85; margin-top: 4px; }
.tile-icon {
    width: 36px; height: 36px; border-radius: 11px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
    margin-bottom: 10px;
}

.tile-violet  { background: linear-gradient(135deg, #5b21b6 0%, #7c3aed 100%); }
.tile-emerald { background: linear-gradient(135deg, #065f46 0%, #0c855d 100%); }
.tile-amber   { background: linear-gradient(135deg, #7c4708 0%, #a36907 100%); }
.tile-rose    { background: linear-gradient(135deg, #9f1239 0%, #c81e43 100%); }
.tile-sky     { background: linear-gradient(135deg, #075985 0%, #0b7caf 100%); }
.tile-indigo  { background: linear-gradient(135deg, #3730a3 0%, #4f46e5 100%); }
.tile-teal    { background: linear-gradient(135deg, #0f766e 0%, #0e8376 100%); }

/* ---- Hero balance card ---- */
.balance-card {
    position: relative; overflow: hidden;
    border-radius: var(--radius-lg);
    padding: 24px;
    color: #fff;
    background: linear-gradient(135deg, #5b4bf5 0%, #7c5cfc 45%, #22d3ee 100%);
    box-shadow: 0 16px 44px rgba(91,75,245,.38);
    margin-bottom: 18px;
}
.balance-card::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 85% 8%, rgba(255,255,255,.3), transparent 55%);
}
.balance-card > * { position: relative; z-index: 1; }
.balance-label { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; opacity: .92; }
.balance-amount {
    font-size: clamp(1.9rem, 8vw, 2.7rem);
    font-weight: 800; letter-spacing: -.02em;
    margin-top: 8px; font-variant-numeric: tabular-nums;
    display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
.balance-amount .cur { font-size: .5em; font-weight: 700; opacity: .9; }
.balance-amount .decimals { font-size: 1em; opacity: 1; }
.balance-meta {
    display: flex; align-items: center; gap: 7px;
    margin-top: 12px; font-size: .8rem;
    background: rgba(255,255,255,.16);
    padding: 7px 12px; border-radius: var(--radius-pill);
    width: fit-content; max-width: 100%;
}

/* ---- Two big actions ---- */
.action-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px; }
.action-btn {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px;
    padding: 20px 12px;
    border: none; cursor: pointer;
    border-radius: var(--radius-lg);
    color: #fff; font-weight: 800; font-size: 1rem;
    text-decoration: none;
    transition: transform .15s ease, box-shadow .2s ease, filter .2s ease;
}
.action-btn:active { transform: scale(.97); }
.action-deposit  { background: linear-gradient(135deg, #065f46 0%, #0c855d 100%); box-shadow: 0 10px 28px rgba(6,95,70,.42); }
.action-deposit:hover  { filter: brightness(1.06); transform: translateY(-2px); }
.action-withdraw { background: linear-gradient(135deg, #7c4708 0%, #a36907 100%); box-shadow: 0 10px 28px rgba(124,71,8,.42); }
.action-withdraw:hover { filter: brightness(1.06); transform: translateY(-2px); }
.action-btn .action-icon {
    width: 44px; height: 44px; border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.24);
}
.action-btn.is-locked { background: linear-gradient(135deg, #475569 0%, #64748b 100%); box-shadow: none; cursor: not-allowed; }

/* ---- Quick amount chips ---- */
.amount-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.amount-chip {
    padding: 9px 16px; border-radius: var(--radius-pill);
    border: 1.5px solid var(--border); background: var(--surface-alt);
    font-weight: 700; font-size: .86rem; cursor: pointer; color: var(--text);
    transition: all .15s;
}
.amount-chip:hover { border-color: var(--t-brand); color: var(--t-brand); }
.amount-chip.selected { background: var(--grad-primary); color: #fff; border-color: transparent; box-shadow: var(--shadow-glow); }

/* ---- Activity list ---- */
.activity-item {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}
.activity-item:last-child { border-bottom: none; }
.activity-icon {
    width: 38px; height: 38px; border-radius: 12px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
}
.activity-in  { background: rgba(13,107,73,.12); color: var(--t-in); }
.activity-out { background: rgba(154,61,10,.12); color: var(--t-out); }
.activity-body { flex: 1; min-width: 0; }
.activity-title { font-weight: 700; font-size: .89rem; }
.activity-sub { font-size: .76rem; color: var(--text-soft); }
.activity-amount { font-weight: 800; font-size: .92rem; white-space: nowrap; }
.amount-in  { color: var(--t-in); }
.amount-out { color: var(--t-out); }

/* ---- Activation screen ----------------------------------------------
   One card, one screen. The whole thing has to fit on the shortest phone
   in use (320x480 with the browser chrome taking a bite) WITHOUT the
   member scrolling to find the button, because a payment screen they have
   to hunt around is a payment that does not happen. Every size below is
   sized from that constraint, not from what looks generous on a desktop.
   -------------------------------------------------------------------- */
.act-main { display: flex; align-items: center; justify-content: center; padding-bottom: 28px; }
.act-wrap { width: 100%; max-width: 400px; margin: 0 auto; }

.act-card {
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

/* The gradient carries white text, so both ends stay dark enough for it. */
.act-top {
    text-align: center; color: #fff;
    padding: 16px 16px 14px;
    background: var(--grad-primary);
}
.act-badge {
    width: 40px; height: 40px; border-radius: 13px; margin: 0 auto 8px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
}
.act-kicker {
    font-size: .7rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .07em; opacity: .92;
}
.act-fee {
    font-size: clamp(1.7rem, 9vw, 2.2rem); font-weight: 800;
    letter-spacing: -.02em; line-height: 1.1; margin: 4px 0 2px;
    overflow-wrap: anywhere;
}
.act-sub { font-size: .82rem; opacity: .92; }

.act-body { padding: 14px 16px 16px; }

.act-perks { list-style: none; padding: 0; margin: 0 0 14px; }
.act-perks li {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 7px 0; font-size: .85rem; line-height: 1.45;
    color: var(--text-muted);
}
.act-perks li + li { border-top: 1px solid var(--border); }
.act-perks .icon { flex-shrink: 0; margin-top: 2px; color: var(--t-brand); }
.act-perks strong { color: var(--text); }

.act-note {
    font-size: .78rem; line-height: 1.5; text-align: center;
    color: var(--text-soft); margin: 10px 0 0;
}

.act-foot {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; flex-wrap: wrap;
    padding: 10px 16px; font-size: .78rem;
    color: var(--text-soft);
    border-top: 1px solid var(--border);
    background: var(--surface-alt);
}
.act-foot strong { color: var(--text); }

/* Very short screens: give the button back the room the decoration took. */
@media (max-height: 600px) {
    .act-badge { display: none; }
    .act-top { padding: 12px 14px 11px; }
    .act-perks li { padding: 5px 0; }
}

@media (min-width: 720px) {
    .bottom-nav { display: none; }
    .member-main { padding-bottom: 40px; }
}
@media (max-width: 380px) {
    .action-btn { padding: 16px 8px; font-size: .92rem; }
}

/* =====================================================================
   DARK THEME  (default for the member/admin app; toggleable)
   ===================================================================== */
:root {
    --glass-bg: rgba(255,255,255,0.6);
    --glass-border: rgba(255,255,255,0.7);
    --nav-bg: rgba(255,255,255,0.82);
    --toast-bg: rgba(255,255,255,0.94);
    --chip-bg: var(--surface-alt);
}

html[data-theme="dark"] {
    color-scheme: dark;

    --bg: #0a0c14;
    --surface: #131726;
    --surface-alt: #1a1f33;
    --border: #262c42;
    --text: #eef1f8;
    --text-muted: #aeb6cf;
    --text-soft: #98a1bd;

    /* Text-safe colours for the dark surfaces */
    --t-brand:   #a99dff;
    --t-info:    #6fd5ff;
    --t-success: #4ade9f;
    --t-warn:    #ffc44d;
    --t-danger:  #ff8fa3;
    --t-in:      #4ade9f;
    --t-out:     #ffa76b;

    /* the same accents, lifted for the dark page */
    --sc1: #ffc44d; --sc2: #67d8f0; --sc3: #4ade9f;
    --sc4: #a99dff; --sc5: #ff8fbd; --sc6: #7fb0ff;

    --glass-bg: rgba(26,31,51,0.72);
    --glass-border: rgba(255,255,255,0.07);
    --nav-bg: rgba(10,12,20,0.86);
    --toast-bg: rgba(26,31,51,0.96);
    --chip-bg: #1a1f33;

    --shadow-sm: 0 2px 8px rgba(0,0,0,.28);
    --shadow-md: 0 8px 26px rgba(0,0,0,.4);
    --shadow-lg: 0 18px 50px rgba(0,0,0,.55);
    --grad-dark: linear-gradient(180deg, #111527 0%, #0d101d 100%);
    --grad-text: linear-gradient(135deg, #a99dff 0%, #6fd5ff 100%);
}

/* Theme-aware surfaces (these used to be hardcoded white) */
.card-glass { background: var(--glass-bg); border-color: var(--glass-border); }
.navbar, .member-topbar { background: var(--nav-bg); }
.toast { background: var(--toast-bg); }
.bottom-nav { background: var(--nav-bg); }
.mobile-nav-toggle { background: var(--glass-bg); color: var(--text); }
.amount-chip { background: var(--chip-bg); }
.avatar-chip { background: var(--chip-bg); }

html[data-theme="dark"] .btn-glass {
    background: rgba(255,255,255,.07);
    border-color: rgba(255,255,255,.1);
    color: var(--text);
}
html[data-theme="dark"] .btn-glass:hover { background: rgba(255,255,255,.12); }
html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: #2b3350; }
html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: #3a446a; }
html[data-theme="dark"] .hero {
    background:
        radial-gradient(circle at 15% 20%, rgba(109,94,252,.20), transparent 45%),
        radial-gradient(circle at 85% 10%, rgba(34,211,238,.14), transparent 40%);
}
html[data-theme="dark"] .auth-shell {
    background:
        radial-gradient(circle at 10% 10%, rgba(109,94,252,.18), transparent 42%),
        radial-gradient(circle at 90% 90%, rgba(34,211,238,.12), transparent 42%);
}
html[data-theme="dark"] th { background: var(--surface-alt); }
html[data-theme="dark"] tbody tr:hover { background: rgba(255,255,255,.03); }
html[data-theme="dark"] .pw-toggle:hover { background: rgba(255,255,255,.07); }

/* Theme toggle button */
.icon-btn {
    width: 40px; height: 40px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--surface-alt);
    color: var(--text-muted);
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
    transition: all .15s;
}
.icon-btn:hover { color: var(--text); border-color: var(--t-brand); }
.theme-moon { display: none; }
html[data-theme="dark"] .theme-sun { display: none; }
html[data-theme="dark"] .theme-moon { display: block; }

/* =====================================================================
   APP DASHBOARD  (sidebar + greeting banner + big stat cards)
   ===================================================================== */
.app-topbar {
    position: sticky; top: 0; z-index: 55;
    background: var(--nav-bg);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--border);
}
.app-topbar .inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; padding: 12px 22px;
}
.app-topbar .brand-mark {
    width: 36px; height: 36px; border-radius: 11px;
    background: var(--grad-primary); color: #fff;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-glow);
}
.topbar-title {
    padding-left: 16px; margin-left: 14px;
    border-left: 1px solid var(--border);
    font-weight: 700; color: var(--text-muted); font-size: .95rem;
}
.topbar-actions { display: flex; align-items: center; gap: 10px; }

/* Sidebar tuned for the dark shell */
html[data-theme="dark"] .sidebar { background: var(--grad-dark); border-right: 1px solid var(--border); }
html[data-theme="dark"] .sidebar-link { color: var(--text-muted); }
html[data-theme="dark"] .sidebar-link:hover { background: rgba(255,255,255,.05); color: var(--text); }
html[data-theme="dark"] .sidebar-link.active {
    background: linear-gradient(135deg, rgba(109,94,252,.22), rgba(34,211,238,.14));
    color: #fff; box-shadow: inset 0 0 0 1px rgba(109,94,252,.28);
}

/* Greeting banner */
.greet-banner {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    padding: 20px 22px; margin-bottom: 20px;
    border-radius: var(--radius-lg);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
}
html[data-theme="dark"] .greet-banner {
    background: linear-gradient(120deg, #10142a 0%, #0d1020 100%);
    border-color: rgba(109,94,252,.22);
}
.greet-left { display: flex; align-items: center; gap: 14px; }
.greet-icon {
    width: 46px; height: 46px; border-radius: 14px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary); color: #fff;
    box-shadow: var(--shadow-glow);
}
.greet-title { font-size: 1.22rem; font-weight: 800; margin: 0; }
.greet-title .name {
    background: linear-gradient(135deg, #34d399, #22d3ee);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.greet-sub { font-size: .86rem; color: var(--text-muted); margin: 2px 0 0; }

/* Four big colourful stat cards */
.bigstat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 16px; margin-bottom: 22px;
}
.bigstat {
    position: relative; overflow: hidden;
    border-radius: var(--radius-lg);
    padding: 20px;
    color: #fff;
    min-height: 150px;
    display: flex; flex-direction: column; justify-content: space-between;
    box-shadow: var(--shadow-md);
}
.bigstat::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 92% 8%, rgba(255,255,255,.22), transparent 55%);
    pointer-events: none;
}
.bigstat > * { position: relative; z-index: 1; }
.bigstat-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.bigstat-label {
    font-size: .74rem; font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; opacity: .95;
}
.bigstat-badge {
    width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
}
.bigstat-value {
    font-size: 1.85rem; font-weight: 800; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; margin: 14px 0 4px;
    line-height: 1.1; word-break: break-word;
}
.bigstat-value .decimals { font-size: 1em; opacity: 1; }
.bigstat-foot { font-size: .78rem; opacity: .9; }

.bigstat-green  { background: linear-gradient(140deg, #065f46 0%, #0c855d 100%); }
.bigstat-blue   { background: linear-gradient(140deg, #1d4ed8 0%, #2563eb 100%); }
.bigstat-red    { background: linear-gradient(140deg, #9f1239 0%, #c81e43 100%); }
.bigstat-purple { background: linear-gradient(140deg, #5b21b6 0%, #7c3aed 100%); }

/* "Balance by source" panel */
.panel {
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    padding: 22px;
    margin-bottom: 20px;
}
.panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.panel-icon {
    width: 40px; height: 40px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: var(--grad-primary); color: #fff;
    box-shadow: var(--shadow-glow);
}
.panel-title { font-size: 1.08rem; font-weight: 800; margin: 0; }

.source-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.source-card {
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-alt);
    padding: 16px;
}
.source-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.source-label {
    font-size: .7rem; font-weight: 800; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-muted);
}
.source-value { font-size: 1.32rem; font-weight: 800; letter-spacing: -.02em; }
.source-foot { font-size: .74rem; color: var(--text-soft); margin-top: 4px; }
.source-c1 { color: var(--sc1); } .source-c2 { color: var(--sc2); } .source-c3 { color: var(--sc3); }
.source-c4 { color: var(--sc4); } .source-c5 { color: var(--sc5); } .source-c6 { color: var(--sc6); }

/* Bonus highlight strip */
.bonus-strip {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 16px 18px; margin-bottom: 20px;
    border-radius: var(--radius-lg);
    background: linear-gradient(120deg, #5b21b6 0%, #7c3aed 55%, #b01e6e 100%);
    color: #fff; box-shadow: 0 12px 34px rgba(124,58,237,.38);
}
.bonus-strip .bonus-icon {
    width: 42px; height: 42px; border-radius: 13px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
}
.bonus-amount { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; }

@media (max-width: 900px) {
    .app-topbar .inner { padding: 10px 14px 10px 62px; }
    .topbar-title { display: none; }
}
@media (max-width: 600px) {
    .bigstat-grid { grid-template-columns: 1fr 1fr; gap: 11px; }
    .bigstat { min-height: 128px; padding: 14px; }
    .bigstat-value { font-size: 1.22rem; margin: 10px 0 3px; }
    .bigstat-label { font-size: .64rem; }
    .bigstat-badge { width: 28px; height: 28px; }
    .bigstat-foot { font-size: .68rem; }
    .greet-title { font-size: 1.05rem; }
    .panel { padding: 16px; }
    .source-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .source-card { padding: 12px; }
    .source-value { font-size: 1.05rem; }
}
@media (max-width: 400px) {
    .source-grid { grid-template-columns: 1fr; }
}

/* =====================================================================
   FIVE WALLETS + REFERRALS
   ===================================================================== */
.wallet-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 14px; margin-bottom: 20px;
}
.wallet-card {
    position: relative; overflow: hidden;
    border-radius: var(--radius-lg);
    padding: 18px; color: #fff;
    box-shadow: var(--shadow-md);
    display: flex; flex-direction: column;
}
.wallet-card::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 90% 8%, rgba(255,255,255,.24), transparent 58%);
    pointer-events: none;
}
.wallet-card > * { position: relative; z-index: 1; }
.wallet-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.wallet-icon {
    width: 38px; height: 38px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
}
.wallet-pill {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 10px; border-radius: var(--radius-pill);
    background: rgba(255,255,255,.2);
    font-size: .66rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
}
.wallet-label { font-size: .74rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; opacity: .95; }
.wallet-amount { font-size: 1.42rem; font-weight: 800; letter-spacing: -.02em; margin: 5px 0 3px; word-break: break-word; }
.wallet-sub { font-size: .76rem; opacity: .88; }
.wallet-note {
    display: flex; align-items: center; gap: 5px;
    font-size: .72rem; opacity: .92; margin-top: 8px;
    background: rgba(255,255,255,.16);
    padding: 5px 9px; border-radius: 8px;
}
.wallet-card .btn-glass {
    background: rgba(255,255,255,.2);
    border-color: rgba(255,255,255,.28);
    color: #fff; margin-top: auto;
}
.wallet-card .btn-glass:hover { background: rgba(255,255,255,.3); }
.wallet-card .btn-glass:disabled { background: rgba(255,255,255,.12); color: rgba(255,255,255,.65); }

.wallet-green  { background: linear-gradient(140deg, #065f46 0%, #0c855d 100%); }
.wallet-blue   { background: linear-gradient(140deg, #1d4ed8 0%, #2563eb 100%); }
.wallet-purple { background: linear-gradient(140deg, #6d28d9 0%, #8b3ef0 100%); }
.wallet-amber  { background: linear-gradient(140deg, #7c4708 0%, #a36907 100%); }
.wallet-rose   { background: linear-gradient(140deg, #9f1239 0%, #c81e43 100%); }

/* ---- Referral page ---- */
.referral-hero {
    border-radius: var(--radius-lg);
    padding: 24px; margin-bottom: 20px;
    background: linear-gradient(135deg, #3730a3 0%, #6d28d9 50%, #b01e6e 100%);
    box-shadow: 0 16px 42px rgba(124,58,237,.38);
    position: relative; overflow: hidden;
}
.referral-hero::after {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 88% 10%, rgba(255,255,255,.26), transparent 55%);
    pointer-events: none;
}
.referral-hero > * { position: relative; z-index: 1; }
.referral-badge {
    width: 56px; height: 56px; border-radius: 17px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22); color: #fff; margin-bottom: 14px;
}
.referral-code-box {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    background: rgba(255,255,255,.16);
    border-radius: var(--radius-md);
    padding: 12px 16px; margin-bottom: 10px; color: #fff;
}
.referral-code {
    font-size: 1.5rem; font-weight: 800; letter-spacing: .12em;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
}
.referral-link-box { display: flex; gap: 8px; align-items: center; }
.referral-link-box input {
    flex: 1; min-width: 0;
    background: rgba(255,255,255,.16);
    border: 1px solid rgba(255,255,255,.22);
    color: #fff; font-size: .82rem; padding: 10px 12px;
}
.referral-link-box input:focus { background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.4); box-shadow: none; }
.referral-hero .btn-glass {
    background: rgba(255,255,255,.22); border-color: rgba(255,255,255,.3); color: #fff;
}
.referral-hero .btn-glass:hover { background: rgba(255,255,255,.32); }

@media (max-width: 600px) {
    .wallet-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .wallet-card { padding: 13px; }
    .wallet-amount { font-size: 1.05rem; }
    .wallet-sub, .wallet-note { font-size: .67rem; }
    .wallet-icon { width: 32px; height: 32px; }
    .referral-code { font-size: 1.15rem; }
    .referral-link-box { flex-direction: column; align-items: stretch; }
}
@media (max-width: 380px) {
    .wallet-grid { grid-template-columns: 1fr; }
}

/* =====================================================================
   RESPONSIVE + READABILITY LAYER
   Added last so it wins. Everything here is about the page working on a
   real phone and every piece of text being readable in both themes.
   ===================================================================== */

/* ---- 1. Nothing may ever push the page sideways ---- */
html, body { max-width: 100%; overflow-x: hidden; }
* { min-width: 0; }
p, li, td, th, label, h1, h2, h3, h4, .stat-value, .tile-value, .bigstat-value {
    overflow-wrap: break-word;
    word-break: break-word;
}
/* Long unbroken strings (phone numbers, referral links, M-Pesa receipts) */
.breakable, .ref-link, code, pre { overflow-wrap: anywhere; }

/* ---- 2. Type that scales with the screen instead of jumping ---- */
h1 { font-size: clamp(1.35rem, 1.05rem + 1.5vw, 1.9rem); }
h2 { font-size: clamp(1.15rem, 0.98rem + 0.9vw, 1.5rem); }
h3 { font-size: clamp(1rem, 0.94rem + 0.4vw, 1.15rem); }
.page-header h1 { font-size: clamp(1.25rem, 1.05rem + 1vw, 1.6rem); }
.stat-value { font-size: clamp(1.4rem, 1.1rem + 1.4vw, 1.9rem); }
.tile-value { font-size: clamp(1.2rem, 1rem + 1vw, 1.5rem); }
.bigstat-value { font-size: clamp(1.4rem, 1.1rem + 1.6vw, 2rem); }

/* The live balance is the biggest number on the site — keep it on one line.
   The decimals are full size now, so the longest the figure ever gets is
   about 18 characters ("KSh 1,165,098.1234").

   Sizing it off the VIEWPORT was wrong, and clipped the last digits on every
   desktop: the cards sit in a grid, so a wider screen fits more of them per
   row and each card gets NARROWER while a vw-based font grows. The worst case
   was not a phone at all — it was a 560px window, where the card is 227px
   wide. What matters is the width of the card, so that is what it measures
   against; 10cqi is a tenth of the card, which leaves the longest figure
   comfortably inside it. The plain clamp is the fallback for browsers with no
   container-query support, and errs small on purpose. */
#liveBalance {
    font-size: clamp(1.15rem, .75rem + 1.6vw, 1.7rem);
    line-height: 1.15;
    white-space: nowrap;
}
.bigstat { container-type: inline-size; }
@supports (width: 1cqi) {
    #liveBalance { font-size: clamp(1.15rem, 10cqi, 2.6rem); }
}
#liveBalance .decimals { font-size: 1em; opacity: 1; }

/* Body text never drops below a comfortable reading size */
body { font-size: clamp(0.95rem, 0.92rem + 0.15vw, 1rem); }
.hint, small { font-size: .82rem; }

/* ---- 3. Touch targets: 44px is the smallest a thumb can hit reliably ---- */
@media (pointer: coarse) {
    .btn { min-height: 46px; }
    .btn-sm { min-height: 42px; padding: 9px 16px; font-size: .85rem; }
    .nav-link { min-height: 44px; display: inline-flex; align-items: center; }
    .sidebar-link { min-height: 46px; }
    .icon-btn { width: 44px; height: 44px; }
    .pw-toggle { width: 44px; height: 44px; }
    .toast-close { width: 34px; height: 34px; }
    .amount-chip { min-height: 44px; }
    /* a link sitting on its own line gets room around it */
    .stack-link, .auth-foot a, .page-header a { padding: 6px 2px; display: inline-block; }
}
.pw-toggle { display: inline-flex; align-items: center; justify-content: center; }
.toast-close { display: inline-flex; align-items: center; justify-content: center; }

/* Stop the grey flash on tap, keep the focus ring for keyboards */
a, button, .btn, .radio-pill, .amount-chip { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--t-brand); outline-offset: 2px; border-radius: 4px; }

/* ---- 4. Full-height shells that cope with the mobile address bar ---- */
.app-shell { min-height: 100vh; min-height: 100dvh; }
.auth-shell { min-height: 100vh; min-height: 100dvh; }
.sidebar { height: 100vh; height: 100dvh; }

/* ---- 5. Safe areas on notched phones ---- */
@supports (padding: max(0px)) {
    .main-content { padding-left: max(16px, env(safe-area-inset-left));
                    padding-right: max(16px, env(safe-area-inset-right)); }
    .bottom-nav { padding-bottom: max(8px, env(safe-area-inset-bottom)); }
}

/* ---- 6. Tables: scrollable, and obviously so ---- */
.table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    position: relative;
}
/* a soft fade on the right edge says "there is more this way" */
.table-wrap::after {
    content: '';
    position: sticky; right: 0; top: 0;
    float: right;
    width: 26px; height: 100%;
    margin-left: -26px;
    background: linear-gradient(to left, var(--surface), transparent);
    pointer-events: none;
}
@media (min-width: 901px) { .table-wrap::after { display: none; } }
.table-wrap table { min-width: 560px; }

/* ---- 7. Grids step down gradually instead of collapsing at once ---- */
@media (max-width: 1100px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px)  { .grid-3, .grid-2 { grid-template-columns: 1fr; } }
.wallet-grid, .bigstat-grid, .tile-grid, .stats-grid, .features-grid, .plans-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}

/* ---- 8. Phone layout ---- */
@media (max-width: 600px) {
    .main-content { padding: 16px 16px 108px; }
    .page-header { padding-top: 46px; align-items: flex-start; }
    .card, .card-glass, .card-gradient { padding: 16px; }
    .bigstat, .tile, .wallet-card { padding: 16px; }
    .table-wrap table { min-width: 480px; }
    th, td { padding: 11px 12px; }
    .badge { font-size: .68rem; padding: 3px 9px; }
    /* buttons sitting side by side wrap into a full-width stack */
    .btn-row, .page-header .flex, form .flex.gap-2 { flex-wrap: wrap; }
    .form-actions .btn, .btn-stack .btn { width: 100%; }
    .steps { flex-wrap: wrap; }
}

@media (max-width: 380px) {
    .main-content { padding: 14px 12px 104px; }
    .card, .card-glass { padding: 14px; }
    .btn { padding: 12px 18px; font-size: .9rem; }
    .btn-lg { padding: 14px 20px; font-size: .95rem; }
    .bottom-nav a { font-size: .62rem; }
    .avatar-chip span:not(.avatar-circle) { display: none; }
}

/* ---- 9. The admin forms are dense — give them room to breathe ---- */
@media (max-width: 760px) {
    .grid-3 .form-group, .grid-2 .form-group { margin-bottom: 14px; }
    .admin-inline-form { flex-direction: column; align-items: stretch; }
    .admin-inline-form input { width: 100% !important; }
}

/* ---- 10. Dark-mode surfaces that were still hardcoded light ---- */
html[data-theme="dark"] .navbar { background: var(--nav-bg); }
html[data-theme="dark"] .bottom-nav { background: var(--nav-bg); }
html[data-theme="dark"] .btn-glass { background: rgba(255,255,255,.09); }
html[data-theme="dark"] .card-gradient::after,
html[data-theme="dark"] .tile::after { opacity: .6; }
html[data-theme="dark"] ::selection { background: rgba(169,157,255,.30); }
html[data-theme="dark"] .table-wrap::after {
    background: linear-gradient(to left, var(--surface), transparent);
}

/* ---- 11. Printing a statement should not print the furniture ---- */
@media print {
    .sidebar, .bottom-nav, .mobile-nav-toggle, .toast-host, .btn, .topbar-actions { display: none !important; }
    .main-content { padding: 0; }
    body { background: #fff; color: #000; }
}

/* ---- 12. Surfaces that were still pinned to white in dark mode ---- */
/* Each of these showed light text on a white panel once the theme flipped. */
.member-shell { background: var(--bg); }
.mpesa-modal  { background: var(--toast-bg); color: var(--text); }
.mpesa-modal h3, .mpesa-modal p, .mpesa-modal div { color: inherit; }
.mpesa-modal p { color: var(--text-muted); }
.mobile-nav-toggle { background: var(--glass-bg); color: var(--text); border: 1px solid var(--glass-border); }
html[data-theme="dark"] .mpesa-modal-backdrop { background: rgba(0,0,0,.72); }
html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: #2b3350; }

/* The glass buttons that sit ON a coloured card are always on a dark fill,
   so they keep white text in both themes. */
/* NOTE: only the cards that are ALWAYS a dark colour fill belong here.
   The greeting banner is white in light mode, so it is deliberately not
   in this list — white text on it would vanish. */
.wallet-card .btn-glass, .card-gradient .btn-glass, .tile .btn-glass,
.bigstat .btn-glass, .bonus-strip .btn-glass,
.referral-hero .btn-glass, .hero-card .btn-glass {
    color: #fff;
    background: rgba(255,255,255,.20);
    border-color: rgba(255,255,255,.34);
}
.wallet-card .btn-glass:hover, .card-gradient .btn-glass:hover,
.tile .btn-glass:hover,
.bonus-strip .btn-glass:hover, .referral-hero .btn-glass:hover { background: rgba(255,255,255,.30); }

/* The greeting banner follows the page: a plain card in light mode,
   a dark gradient in dark mode. Its button follows suit. */
.greet-banner .btn-glass {
    color: var(--text);
    background: var(--surface-alt);
    border: 1px solid var(--border);
}
.greet-banner .btn-glass:hover { background: var(--border); }
html[data-theme="dark"] .greet-banner .btn-glass {
    color: #fff;
    background: rgba(255,255,255,.10);
    border-color: rgba(255,255,255,.18);
}
html[data-theme="dark"] .greet-banner .btn-glass:hover { background: rgba(255,255,255,.18); }
.wallet-card .btn-glass:disabled { background: rgba(255,255,255,.14); color: rgba(255,255,255,.75); }

/* ---- 13. Anything a thumb has to hit gets a real hit area ---- */
.toast-close { width: 40px; height: 40px; margin: -8px -8px -8px 0; }
.brand { padding: 6px 0; min-height: 44px; }
.sidebar .brand { min-height: 0; }
/* a link inside a sentence still needs somewhere to land on a phone */
.auth-foot a, .auth-card p a, .form-foot a {
    display: inline-block; padding: 11px 4px; min-height: 44px;
    line-height: 22px; vertical-align: middle;
}

/* ---- 14. Last pass: the pieces the page-by-page check turned up ---- */

/* A glass button sitting on a coloured card must stay white, and the
   dark-theme rule for .btn-glass is more specific, so match it here. */
html[data-theme="dark"] .wallet-card .btn-glass,
html[data-theme="dark"] .card-gradient .btn-glass,
html[data-theme="dark"] .tile .btn-glass,
html[data-theme="dark"] .bigstat .btn-glass,
html[data-theme="dark"] .bonus-strip .btn-glass,
html[data-theme="dark"] .referral-hero .btn-glass {
    color: #fff;
    background: rgba(255,255,255,.20);
    border-color: rgba(255,255,255,.34);
}
/* "Locked" buttons still have to be readable, just obviously inactive */
.wallet-card .btn-glass:disabled,
html[data-theme="dark"] .wallet-card .btn-glass:disabled {
    background: rgba(0,0,0,.22);
    color: #fff;
    border-color: rgba(255,255,255,.30);
    opacity: 1;
}

/* Small links printed on a coloured card ("Review", "Withdraw separately") */
.bigstat-foot a, .tile-foot a, .wallet-foot a {
    color: #fff;
    display: inline-block;
    padding: 9px 4px;
    min-height: 40px;
    line-height: 22px;
    font-weight: 700;
}

/* Small buttons stay comfortable to click with a mouse too */
.btn-sm { min-height: 36px; }
.amount-chip { min-height: 40px; }
.pw-toggle { min-height: 40px; min-width: 40px; }
.nav-link { min-height: 40px; display: inline-flex; align-items: center; }

/* ---- 15. Touch sizing, kept LAST so nothing above can undercut it ----
   Everything a finger has to hit is at least 44px tall on a touch screen.
   On a mouse the smaller sizes from above still apply. */
@media (pointer: coarse) {
    .btn { min-height: 46px; }
    .btn-sm { min-height: 44px; padding: 10px 16px; font-size: .85rem; }
    .btn-lg { min-height: 52px; }
    .amount-chip { min-height: 44px; }
    .pw-toggle, .icon-btn { min-width: 44px; min-height: 44px; }
    .toast-close { min-width: 44px; min-height: 44px; }
    .nav-link, .sidebar-link { min-height: 46px; }
    .radio-pill { min-height: 46px; }
    .bigstat-foot a, .tile-foot a, .wallet-foot a { min-height: 44px; line-height: 24px; }
    /* short text links standing on their own line */
    a.text-sm, .text-sm > a, .activity-head a, .section-head a, .card-head a {
        display: inline-flex; align-items: center; gap: 4px;
        padding: 11px 6px; min-height: 44px; line-height: 22px;
    }
    /* table action buttons get a little breathing room between them */
    td .flex.gap-2 { gap: 10px; row-gap: 10px; }
}

/* ---- 16. The top bar has to survive a narrow phone ----
   Name, page title and three controls do not fit side by side on a small
   screen, so the least important parts step aside instead of being clipped. */
.app-topbar .inner { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1 1 auto; overflow: hidden; }
.topbar-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.brand-word { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.avatar-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 90px; }

@media (max-width: 900px) {
    /* the page title already sits in the page header below */
    .topbar-title { display: none; }
}
@media (max-width: 620px) {
    .avatar-name { display: none; }
    .avatar-chip { padding: 5px; }
    .brand-word { max-width: 34vw; }
}
@media (max-width: 560px) {
    /* Inside the app the top bar now carries the bell, the currency switch,
       the theme button and the avatar, which leaves the site name a sliver —
       "U..." tells nobody anything. The mark alone identifies the site, and
       the page name is in the header right below. The public pages keep the
       full name, because there is room there. */
    .app-topbar .brand-word { display: none; }
    .topbar-actions { gap: 6px; }
}

/* ---- 17. Tables become cards on a phone ----
   A seven-column admin table cannot be read on a 360px screen, and side-to-
   side scrolling hides half the row. Below 760px each row becomes its own
   card and every value is printed next to its column name. */
@media (max-width: 760px) {
    .table-wrap {
        overflow: visible;
        border: none;
        background: none;
    }
    .table-wrap::after { display: none; }
    .table-wrap table { min-width: 0; width: 100%; font-size: .9rem; }
    /* Hidden outright: an off-screen thead still reserves its full width and
       pushes the page sideways. Every cell carries its own visible label. */
    .table-wrap thead { display: none; }
    .table-wrap table, .table-wrap tbody, .table-wrap tr, .table-wrap td { display: block; width: 100%; }

    .table-wrap tbody tr {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-sm);
        margin-bottom: 12px;
        padding: 4px 2px;
        overflow: hidden;
    }
    .table-wrap tbody tr:hover { background: var(--surface); }

    .table-wrap td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 14px;
        padding: 11px 14px;
        border-bottom: 1px solid var(--border);
        white-space: normal;
        text-align: right;
        min-width: 0;
    }
    .table-wrap tr td:last-child { border-bottom: none; }

    .table-wrap td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 88px;
        text-align: left;
        font-size: .7rem;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--text-muted);
    }
    /* the actions cell reads better stacked under its own heading */
    .table-wrap td[data-label="Actions"] { flex-direction: column; align-items: stretch; text-align: left; }
    .table-wrap td[data-label="Actions"]::before { flex: none; margin-bottom: 8px; }
    .table-wrap td[data-label="Actions"] .flex { flex-wrap: wrap; gap: 8px; }
    .table-wrap td[data-label="Actions"] .btn { flex: 1 1 auto; }

    /* rows that span the whole table (empty states, inline edit forms) */
    .table-wrap td[colspan] { text-align: center; border-bottom: none; }
    .table-wrap td[colspan] .grid-3 { grid-template-columns: 1fr; }
    .table-wrap .empty-state { padding: 26px 14px; }

    /* inline "set bonus" style forms inside a cell */
    .table-wrap td form.flex { flex-wrap: wrap; justify-content: flex-end; }
    .table-wrap td input[type=number] { width: 100% !important; max-width: 160px; }
}

/* ---- 18. Commission rules (Admin > Referrals) ---- */
.rule-list { display: flex; flex-direction: column; gap: 10px; }
.rule-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    padding: 14px 16px;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.rule-name { display: flex; flex-direction: column; gap: 2px; min-width: 190px; flex: 1 1 220px; }
.rule-help { font-size: .8rem; color: var(--text-muted); }
.rule-paid { font-size: .74rem; font-weight: 700; color: var(--t-success); }
.rule-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rule-controls select { width: auto; min-width: 150px; }
.rule-controls input[type=number] { width: 120px; }
.rule-controls .radio-pill { white-space: nowrap; }

@media (max-width: 640px) {
    .rule-row { flex-direction: column; align-items: stretch; gap: 12px; }
    .rule-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
    .rule-controls select { grid-column: 1 / -1; width: 100%; min-width: 0; }
    .rule-controls input[type=number] { width: 100%; }
    .rule-controls .radio-pill { justify-content: center; }
}

/* ---- 19. "You earn" list on the member referral page ---- */
.earn-list { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 7px; }
.earn-list li {
    display: flex; align-items: flex-start; gap: 8px;
    color: #fff; font-size: .88rem; font-weight: 600;
}
.earn-list li .icon { flex-shrink: 0; margin-top: 3px; opacity: .9; }

/* ---- 20. Paging and search on the admin lists ---- */
.pager {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    margin-top: 16px; padding-top: 14px;
    border-top: 1px solid var(--border);
}
.pager-count { font-size: .84rem; color: var(--text-muted); }
.pager-links { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pager-page { font-size: .84rem; font-weight: 700; color: var(--text-muted); white-space: nowrap; }

.search-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.search-form input[type=search] { width: 230px; min-height: 40px; }

@media (max-width: 600px) {
    .pager { flex-direction: column; align-items: stretch; gap: 10px; }
    .pager-links { justify-content: space-between; }
    .search-form { width: 100%; }
    .search-form input[type=search] { width: 100%; flex: 1 1 100%; }
}

/* ---- 21. Status tabs above a list ---- */
.filter-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.filter-tab {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 15px; min-height: 40px;
    border-radius: var(--radius-pill);
    background: var(--surface-alt);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: .85rem; font-weight: 700;
}
.filter-tab:hover { color: var(--text); border-color: var(--t-brand); }
.filter-tab.active { background: var(--grad-primary); color: #fff; border-color: transparent; }
.filter-count {
    /* a lighter chip so the muted count text still clears 4.5:1 on it */
    background: rgba(0,0,0,.06); border-radius: var(--radius-pill);
    padding: 1px 8px; font-size: .76rem;
    color: var(--text);
}
html[data-theme="dark"] .filter-count { background: rgba(255,255,255,.10); }
.filter-tab.active .filter-count { background: rgba(255,255,255,.26); color: #fff; }
@media (pointer: coarse) { .filter-tab { min-height: 44px; } }

/* ---- 22. Managing one member ---- */
.back-link {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: .84rem; font-weight: 700; color: var(--text-muted);
    margin-bottom: 6px; padding: 4px 0;
}
.back-link:hover { color: var(--t-brand); }
.member-link { color: inherit; display: block; }
.member-link:hover strong { color: var(--t-brand); }

.danger-zone {
    border: 1.5px solid rgba(192,26,55,.35);
    background: linear-gradient(180deg, rgba(192,26,55,.05), transparent 60%);
}
html[data-theme="dark"] .danger-zone {
    border-color: rgba(255,143,163,.30);
    background: linear-gradient(180deg, rgba(255,143,163,.07), transparent 60%);
}
.danger-zone h3 { color: var(--t-danger); }
.impact-list { margin: 0 0 18px; padding-left: 20px; color: var(--text-muted); font-size: .88rem; }
.impact-list li { margin-bottom: 5px; }

/* ---- 23. "You are viewing as ..." ---- */
.viewing-as {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 12px 18px; margin: 0 0 18px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, #7c4708 0%, #a36907 100%);
    color: #fff;
    box-shadow: var(--shadow-md);
}
.viewing-as-icon {
    width: 34px; height: 34px; border-radius: 10px; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.22);
}
.viewing-as-text { flex: 1 1 240px; font-size: .9rem; font-weight: 600; line-height: 1.45; }
.viewing-as-sub { display: block; font-size: .8rem; font-weight: 500; opacity: .92; }
.viewing-as .btn-glass {
    background: rgba(255,255,255,.20);
    border-color: rgba(255,255,255,.34);
    color: #fff;
}
.viewing-as .btn-glass:hover { background: rgba(255,255,255,.32); }

@media (max-width: 600px) {
    .viewing-as { padding: 12px 14px; gap: 10px; }
    .viewing-as .btn-glass { width: 100%; justify-content: center; }
}

/* ---- 24. Touch sizing for the member page, after everything above ---- */
@media (pointer: coarse) {
    .back-link { min-height: 44px; padding: 10px 2px; }
    /* a member's name in a table is how you open their page, so it needs room */
    .table-wrap td a, .member-link { display: inline-block; padding: 10px 2px; min-height: 44px; }
    .table-wrap td .btn { min-height: 44px; }
}

/* ==========================================================================
   25. APPEARANCE — presets, glass and density
   --------------------------------------------------------------------------
   Three independent switches, all set by the admin (see app/Core/Theme.php)
   and written onto <html> before the first paint:

       data-preset    which colours the site is built from
       data-glass     frosted surfaces on or off
       data-density   compact or comfortable spacing

   --grad-primary is deliberately DARKER than the swatch on the Appearance
   page. Buttons made from it carry white text, and white on the lighter end
   of these gradients measured 3.6:1 — under the 4.5:1 that small text needs.
   The swatch shows the family; the button uses a shade that can be read.

   A PRESET NEVER TOUCHES THE MEANING COLOURS. Green is money in and red is
   money out in every preset, because a member who has learned that should
   not have it moved under them. Only the brand — sidebar, buttons, links,
   highlights — changes.

   Each preset sets the same six variables twice: once for the light page and
   once for the dark one. The two are genuinely different colours, not one
   colour at two opacities, because a violet that reads well on white is
   invisible on near-black.

       --brand-1/2     the two ends of the brand gradient (fills)
       --grad-primary  carries WHITE TEXT, so both ends must be dark enough
       --grad-accent   decorative only, never has text on it
       --grad-text     used as gradient-filled text, so both ends must read
       --t-brand       the brand colour when it is TEXT on the page
       --shadow-glow   the coloured glow under a primary button
   ========================================================================== */

/* ---- Indigo (default) ---------------------------------------------------- */
html[data-preset="indigo"] {
    --brand-1: #6d5efc; --brand-2: #46c9ff;
    --grad-primary: linear-gradient(135deg, #6d5efc 0%, #2563eb 100%);
    --grad-accent:  linear-gradient(135deg, #6d5efc 0%, #46c9ff 100%);
    --grad-text:    linear-gradient(135deg, #5442d6 0%, #1d4ed8 100%);
    --t-brand: #5442d6;
    --shadow-glow: 0 8px 30px rgba(109, 94, 252, .35);
}
html[data-preset="indigo"][data-theme="dark"] {
    --t-brand: #a99dff;
    --grad-text: linear-gradient(135deg, #a99dff 0%, #6fd5ff 100%);
}

/* ---- Ocean --------------------------------------------------------------- */
html[data-preset="ocean"] {
    --brand-1: #06b6d4; --brand-2: #38bdf8;
    --grad-primary: linear-gradient(135deg, #0e7490 0%, #075985 100%);
    --grad-accent:  linear-gradient(135deg, #06b6d4 0%, #38bdf8 100%);
    --grad-text:    linear-gradient(135deg, #0b6a86 0%, #075985 100%);
    --t-brand: #0b6a86;
    --shadow-glow: 0 8px 30px rgba(8, 145, 178, .35);
}
html[data-preset="ocean"][data-theme="dark"] {
    --t-brand: #67d8f0;
    --grad-text: linear-gradient(135deg, #67d8f0 0%, #7fb0ff 100%);
}

/* ---- Forest -------------------------------------------------------------- */
html[data-preset="forest"] {
    --brand-1: #10b981; --brand-2: #34d399;
    --grad-primary: linear-gradient(135deg, #047857 0%, #065f46 100%);
    --grad-accent:  linear-gradient(135deg, #10b981 0%, #34d399 100%);
    --grad-text:    linear-gradient(135deg, #05715a 0%, #065f46 100%);
    --t-brand: #05715a;
    --shadow-glow: 0 8px 30px rgba(5, 150, 105, .35);
}
html[data-preset="forest"][data-theme="dark"] {
    --t-brand: #4ade9f;
    --grad-text: linear-gradient(135deg, #4ade9f 0%, #67d8f0 100%);
}

/* ---- Sunset -------------------------------------------------------------- */
html[data-preset="sunset"] {
    --brand-1: #f97316; --brand-2: #fb7185;
    --grad-primary: linear-gradient(135deg, #c2410c 0%, #9f1239 100%);
    --grad-accent:  linear-gradient(135deg, #f97316 0%, #fb7185 100%);
    --grad-text:    linear-gradient(135deg, #b03d0a 0%, #9f1239 100%);
    --t-brand: #b03d0a;
    --shadow-glow: 0 8px 30px rgba(234, 88, 12, .35);
}
html[data-preset="sunset"][data-theme="dark"] {
    --t-brand: #ffb27a;
    --grad-text: linear-gradient(135deg, #ffb27a 0%, #ff8fbd 100%);
}

/* ---- Royal --------------------------------------------------------------- */
html[data-preset="royal"] {
    --brand-1: #c084fc; --brand-2: #a855f7;
    --grad-primary: linear-gradient(135deg, #7e22ce 0%, #5b21b6 100%);
    --grad-accent:  linear-gradient(135deg, #c084fc 0%, #a855f7 100%);
    --grad-text:    linear-gradient(135deg, #7029c9 0%, #5b21b6 100%);
    --t-brand: #7029c9;
    --shadow-glow: 0 8px 30px rgba(147, 51, 234, .35);
}
html[data-preset="royal"][data-theme="dark"] {
    --t-brand: #d0a8ff;
    --grad-text: linear-gradient(135deg, #d0a8ff 0%, #a99dff 100%);
}

/* ---- Graphite ------------------------------------------------------------ */
html[data-preset="graphite"] {
    --brand-1: #94a3b8; --brand-2: #64748b;
    --grad-primary: linear-gradient(135deg, #475569 0%, #1e293b 100%);
    --grad-accent:  linear-gradient(135deg, #94a3b8 0%, #64748b 100%);
    --grad-text:    linear-gradient(135deg, #414d63 0%, #1e293b 100%);
    --t-brand: #414d63;
    --shadow-glow: 0 8px 30px rgba(71, 85, 105, .3);
}
html[data-preset="graphite"][data-theme="dark"] {
    --t-brand: #b9c4d8;
    --grad-text: linear-gradient(135deg, #b9c4d8 0%, #98a1bd 100%);
}

/* ==========================================================================
   GLASS
   --------------------------------------------------------------------------
   Frosted, slightly translucent surfaces. backdrop-filter is the expensive
   part — on an older phone it is the difference between a smooth scroll and
   a stuttering one — so the admin can switch it off and get plain solid
   surfaces instead.

   Browsers without backdrop-filter simply see the background colour, which
   is why every glass surface sets one rather than relying on the blur.
   ========================================================================== */
/* Only the NEUTRAL surfaces are made of glass. The coloured tiles are not:
   they carry white text on their own gradient, and a background shorthand
   here wiped that gradient out, leaving white text on a white card. */
html[data-glass="on"] .card,
html[data-glass="on"] .panel,
html[data-glass="on"] .fee-box {
    background: var(--glass-bg, var(--surface));
    border-color: var(--glass-border, var(--border));
    -webkit-backdrop-filter: blur(14px) saturate(1.25);
    backdrop-filter: blur(14px) saturate(1.25);
}
html[data-glass="on"] .card-glass {
    -webkit-backdrop-filter: blur(18px) saturate(1.3);
    backdrop-filter: blur(18px) saturate(1.3);
}
/* A soft wash of the brand colour behind everything, so the glass has
   something to be glass in FRONT of. Fixed, so it does not scroll away. */
html[data-glass="on"] body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(900px 600px at 12% -10%, color-mix(in srgb, var(--brand-1) 22%, transparent), transparent 60%),
        radial-gradient(800px 560px at 108% 8%, color-mix(in srgb, var(--brand-2) 18%, transparent), transparent 62%);
}
/* color-mix is recent. Where it is missing the rule above is dropped and the
   page simply has no wash, which is exactly the "off" look. */

html[data-glass="off"] .card,
html[data-glass="off"] .panel,
html[data-glass="off"] .card-glass,
html[data-glass="off"] .fee-box {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
html[data-glass="off"] .card,
html[data-glass="off"] .panel,
html[data-glass="off"] .card-glass {
    background: var(--surface);
}

/* Someone who has asked their device for less motion and less effect gets
   the plain version regardless of the setting. */
@media (prefers-reduced-transparency: reduce) {
    html .card, html .panel, html .card-glass, html .fee-box {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    html body::before { display: none; }
}

/* ==========================================================================
   DENSITY — compact by default
   --------------------------------------------------------------------------
   Compact is the default because the people using this most are admins
   working through a queue and members checking a balance; both want to see
   more at once and scroll less. Nothing here shrinks a tap target: the
   44px minimums in section 3 still apply underneath.
   ========================================================================== */
html[data-density="compact"] .main-content { padding: 20px 22px 28px; }
html[data-density="compact"] .page-header { margin-bottom: 16px; gap: 8px; }
html[data-density="compact"] .page-header h1 { font-size: 1.32rem; }
html[data-density="compact"] .page-header p { font-size: .84rem; }

html[data-density="compact"] .card { padding: 18px; }
html[data-density="compact"] .card-glass { padding: 18px; }
html[data-density="compact"] .panel { padding: 15px; margin-bottom: 14px; }
html[data-density="compact"] .panel-head { margin-bottom: 10px; padding-bottom: 10px; }
html[data-density="compact"] .panel-title { font-size: .98rem; }
html[data-density="compact"] .tile { padding: 13px; }
html[data-density="compact"] .tile-value { margin-top: 2px; }
html[data-density="compact"] .tile-foot { font-size: .72rem; }

html[data-density="compact"] .stats-grid { gap: 12px; margin-bottom: 16px; }
html[data-density="compact"] .bigstat-grid { gap: 12px; margin-bottom: 14px; }
html[data-density="compact"] .bigstat { padding: 16px; }
html[data-density="compact"] .wallet-grid { gap: 12px; margin-bottom: 16px; }
html[data-density="compact"] .wallet-card { padding: 14px; }
html[data-density="compact"] .form-group { margin-bottom: 13px; }
html[data-density="compact"] .grid-2, html[data-density="compact"] .grid-3 { gap: 12px; }

html[data-density="compact"] th,
html[data-density="compact"] td { padding: 8px 11px; }
html[data-density="compact"] .activity-item { padding: 9px 0; }
html[data-density="compact"] .alert { padding: 11px 14px; margin-bottom: 12px; }
html[data-density="compact"] h3 { margin-bottom: 10px; font-size: 1rem; }
html[data-density="compact"] .greet-banner { padding: 14px 16px; margin-bottom: 14px; }
html[data-density="compact"] .sidebar-link { padding-top: 8px; padding-bottom: 8px; }
html[data-density="compact"] .sidebar-section { margin: 12px 0 5px; }

/* On a phone the gutter matters more than the gaps: keep 16px at the sides
   so nothing touches the screen edge, and take the space out of the middle. */
@media (max-width: 720px) {
    html[data-density="compact"] .main-content { padding: 14px 16px 96px; }
    html[data-density="compact"] .panel { padding: 13px; }
    html[data-density="compact"] .card, html[data-density="compact"] .card-glass { padding: 15px; }
}

/* ==========================================================================
   Income page
   ========================================================================== */
/* Numbers line up on the right and share one digit width, so a column of
   money can be scanned down without the eye hunting. */
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-tight th, .table-tight td { padding: 7px 10px; font-size: .86rem; }
.table-tight tbody tr:hover { background: var(--surface-alt); }
.row-total td { border-top: 1.5px solid var(--border); background: var(--surface-alt); }

/* A bar behind the day, so a good day is visible without reading a number. */
.spark {
    display: block; height: 3px; margin-top: 4px;
    background: var(--border); border-radius: 2px; overflow: hidden;
}
.spark > span { display: block; height: 100%; background: var(--grad-accent); }

/* Segmented control: 7 / 30 / 90 days. */
/* A segmented control. It wraps rather than overflowing: three items with
   words like "Administrators" are 9px too wide for a 320px screen, and a
   row that pushes the page sideways is worse than one that takes two lines. */
.seg { display: inline-flex; flex-wrap: wrap; max-width: 100%;
       background: var(--surface-alt); border: 1px solid var(--border);
       border-radius: var(--radius-md); padding: 3px; gap: 2px; }
.seg-item {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 6px 13px; border-radius: var(--radius-pill);
    font-size: .8rem; font-weight: 700; color: var(--text-soft); text-decoration: none;
    min-height: 34px;
}
.seg-item:hover { color: var(--text); }
.seg-item.is-on { background: var(--grad-primary); color: #fff; }
@media (pointer: coarse) { .seg-item { min-height: 44px; padding: 6px 16px; } }
@media (max-width: 420px) {
    .seg { width: 100%; }
    .seg-item { flex: 1 1 auto; padding: 6px 10px; font-size: .78rem; }
}

/* ---- Appearance page: the preset chooser ---- */
.theme-grid {
    display: grid; gap: 10px; margin-top: 12px;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.theme-card {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 13px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    cursor: pointer;
    min-height: 60px;
}
.theme-card:hover { border-color: var(--t-brand); }
.theme-card.is-on { border-color: var(--t-brand); box-shadow: 0 0 0 3px rgba(109,94,252,.16); }
/* The radio itself does the work for the keyboard and for screen readers;
   the card is the visible control, so the input sits under it rather than
   being hidden outright, which would take it out of the tab order. */
.theme-card input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.theme-card:focus-within { border-color: var(--t-brand); box-shadow: 0 0 0 3px rgba(109,94,252,.16); }
.theme-swatch {
    width: 42px; height: 42px; border-radius: 11px; flex-shrink: 0;
    border: 1px solid rgba(0,0,0,.08);
}
.theme-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.theme-name { font-weight: 700; font-size: .92rem; color: var(--text); }
.theme-note { font-size: .76rem; color: var(--text-soft); line-height: 1.35; }
.theme-tick { display: none; color: var(--t-brand); flex-shrink: 0; }
.theme-card.is-on .theme-tick { display: inline-flex; }

/* ==========================================================================
   26. LESS SCROLLING ON A PHONE
   --------------------------------------------------------------------------
   A wide table becomes a stack of label/value rows on a phone, and each cell
   costs about 42px. Seven columns over thirty days is nine thousand pixels —
   fifteen screens of scrolling to read one month.

   So the secondary columns are dropped below 720px and the important ones
   stay. Nothing is lost: the full table is there on any wider screen, and
   the figures that answer the question at a glance — what came in, what was
   kept — are the ones that remain.
   ========================================================================== */
@media (max-width: 720px) {
    .hide-sm { display: none !important; }

    /* Tighter stacked rows. The 44px tap-target minimum still applies to
       anything you can actually press; these are read, not pressed. */
    html[data-density="compact"] .table-wrap td {
        padding: 6px 12px;
        font-size: .85rem;
    }
    /* The label sits BESIDE the value in most cells, so this basis is a
       width. The Actions cell is the exception — it stacks, so there the
       same property would be a HEIGHT, and setting it made that one cell
       76px tall and the whole page longer in "compact" than in
       "comfortable". It keeps its own automatic size. */
    html[data-density="compact"] .table-wrap td[data-label]:not([data-label="Actions"])::before {
        flex-basis: 76px;
    }
    html[data-density="compact"] .table-wrap td[data-label]::before {
        font-size: .66rem;
    }
    html[data-density="compact"] .table-wrap tr { margin-bottom: 10px; }
    html[data-density="compact"] .table-tight td { padding: 5px 11px; }
}

/* ==========================================================================
   27. MORE COLOUR
   --------------------------------------------------------------------------
   Two-colour gradients on the surfaces that were flat, all built from the
   chosen preset so the whole site stays one family and changing the preset
   changes everything at once.

   THE RULE EVERY ONE OF THESE FOLLOWS: a gradient either sits BEHIND text
   that is white, in which case both ends must be dark enough to read white
   on, or it is decorative and carries no text at all. The tinted glass
   below is the third kind — a wash so faint the ordinary page colours still
   read on it — which is why those use small percentages.
   ========================================================================== */

/* ---- Glass with a tint of the theme, rather than plain grey ---- */
html[data-glass="on"] .panel,
html[data-glass="on"] .card {
    background-image:
        linear-gradient(135deg,
            color-mix(in srgb, var(--brand-1) 7%, transparent) 0%,
            color-mix(in srgb, var(--brand-2) 5%, transparent) 100%);
}
html[data-glass="on"] .card-glass {
    background-image:
        linear-gradient(135deg,
            color-mix(in srgb, var(--brand-1) 9%, transparent) 0%,
            color-mix(in srgb, var(--brand-2) 6%, transparent) 100%);
}

/* A hairline of colour along the top of every panel. Decorative only. */
.panel, .card-glass { position: relative; overflow: hidden; }
.panel::before, .card-glass::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 2px;
    background: var(--grad-accent);
    opacity: .75;
    pointer-events: none;
}

/* ---- The round icon on a panel head, and the sidebar mark ---- */
.panel-icon, .brand-mark, .auth-badge, .tile-icon {
    background-image: var(--grad-primary);
    color: #fff;
}

/* ---- Sidebar: a wash of colour OVER the dark base, not instead of it ----
   Replacing the background outright lifted it to a mid grey and the white
   links fell to 2.9:1 — unreadable. The colour goes on as a faint layer
   above the dark colour instead, so the base stays as dark as it was and
   only the hue changes. */
/* NOT position:relative here. The sidebar is already positioned — sticky on
   a desktop, fixed and slid off-screen on a phone — and setting it again in
   a later rule overrode the fixed one, so on a 320px screen the sidebar
   stopped hiding and pushed the whole page 248px sideways.
   isolation on its own makes the stacking context the wash below needs. */
.sidebar { isolation: isolate; }
.sidebar::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(170deg,
        var(--brand-1) 0%, transparent 55%, var(--brand-2) 100%);
    opacity: .18;
}
.sidebar-link.active {
    background-image: var(--grad-primary);
    color: #fff;
}

/* ---- The active item in the bottom bar on a phone ---- */
.bottom-nav .nav-item.active .nav-icon {
    background-image: var(--grad-primary);
    color: #fff;
}

/* ---- Badges get a soft two-colour fill ---- */
.badge-brand {
    background-image: linear-gradient(135deg,
        color-mix(in srgb, var(--brand-1) 22%, transparent),
        color-mix(in srgb, var(--brand-2) 16%, transparent));
}

/* ---- The big numbers, painted with the theme ---- */
/* Only where the text is large and bold: a gradient fill on small text is
   hard to read, and a browser that cannot do it falls back to the solid
   colour set just above. */
.bigstat-value, .stat-value {
    color: var(--t-brand);
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
    .stat-value {
        background-image: var(--grad-text);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
    }
}
/* The bigstat cards already sit on their own coloured gradient, so their
   value stays plain white — a gradient on a gradient reads as mud. */
.bigstat .bigstat-value { color: #fff; -webkit-text-fill-color: #fff; }

/* ---- Progress and meters ---- */
/* The spark bar on the income page follows the theme. The password meter
   does NOT: its four bars mean weak-to-strong, and painting them all with
   the brand gradient made an empty meter look full before anything had
   been typed. It keeps its own colours, set in section 24. */
.spark > span { background-image: var(--grad-accent); }

/* ---- Buttons already use --grad-primary; give the quiet ones an edge ---- */
.btn-glass {
    background-image: linear-gradient(135deg,
        color-mix(in srgb, var(--brand-1) 12%, transparent),
        color-mix(in srgb, var(--brand-2) 8%, transparent));
}

/* Where color-mix is missing the whole declaration is dropped and the
   surface keeps the plain background it had before, which is a perfectly
   good page — just a quieter one. */

/* ---- Mail check: one row per link in the chain ---- */
.check-row { display: flex; gap: 11px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.check-row:last-child { border-bottom: none; }
.check-mark { flex-shrink: 0; display: flex; margin-top: 1px; }
.check-ok   .check-mark { color: var(--t-success); }
.check-warn .check-mark { color: var(--t-warn); }
.check-bad  .check-mark { color: var(--t-danger); }
.check-body { min-width: 0; flex: 1; }
.check-label { font-weight: 700; font-size: .9rem; color: var(--text); }
.check-detail { font-size: .84rem; color: var(--text-soft); margin-top: 2px; line-height: 1.5;
                word-break: break-word; }
.check-fix { font-size: .82rem; color: var(--t-brand); margin-top: 5px; line-height: 1.5; }
.check-fix .icon { vertical-align: -2px; }
