/* =========================================================================
   Dibi Tech — Tabler brand overrides + polish (loaded AFTER tabler.min.css)
   ========================================================================= */

/* Inter (local, no Google Fonts fetch) */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/tabler/fonts/inter/inter-latin.woff2') format('woff2');
}

:root {
    --tblr-primary: #1FA855;            /* WhatsApp green */
    --tblr-primary-rgb: 31, 168, 85;
    --tblr-primary-darker: #178D43;
    --tblr-link-color: #1FA855;
    --tblr-link-color-rgb: 31, 168, 85;
    --dt-slate: #111B21;                /* WhatsApp dark slate */

    /* Elevation system — use these exclusively for box-shadows */
    --elevation-1: 0 1px 2px 0 rgba(15, 23, 42, 0.04), 0 1px 1px 0 rgba(15, 23, 42, 0.03);
    --elevation-2: 0 1px 3px 0 rgba(15, 23, 42, 0.06), 0 1px 2px 0 rgba(15, 23, 42, 0.04);
    --elevation-3: 0 4px 12px -2px rgba(15, 23, 42, 0.08), 0 2px 4px -1px rgba(15, 23, 42, 0.04);
    --elevation-4: 0 12px 32px -8px rgba(15, 23, 42, 0.12), 0 4px 8px -2px rgba(15, 23, 42, 0.06);

    /* Transition standard */
    --transition-fast:   100ms ease;
    --transition-base:   150ms ease;
    --transition-smooth: 250ms ease-out;
}

/* Sidebar: dark slate (Tabler beta20 themes the navbar via data-bs-theme="dark") */
.navbar-vertical[data-bs-theme="dark"] {
    background-color: var(--dt-slate) !important;
    border-color: #1d2c34 !important;
}
.navbar-vertical[data-bs-theme="dark"] .navbar-brand-text { color: #fff; font-weight: 600; }
.navbar-vertical[data-bs-theme="dark"] .navbar-brand-subtitle { color: #8a96a3; font-size: .75rem; }
.navbar-vertical[data-bs-theme="dark"] .navbar-brand a { color: #fff; }

/* Primary buttons + links use brand green */
.btn-primary {
    --tblr-btn-bg: #1FA855;
    --tblr-btn-border-color: #1FA855;
    --tblr-btn-hover-bg: #178D43;
    --tblr-btn-hover-border-color: #178D43;
    --tblr-btn-active-bg: #178D43;
    --tblr-btn-active-border-color: #178D43;
}
a { color: #1FA855; }
.text-primary { color: #1FA855 !important; }

/* -------------------------------------------------------------------------
   TIER 1 — sidebar bug fixes
   Tabler beta20 ships NO .nav-header rule, so style it ourselves: a small
   light-on-dark uppercase section label that stays INSIDE the sidebar.
   ------------------------------------------------------------------------- */
.navbar-vertical .navbar-nav .nav-header,
.navbar-vertical[data-bs-theme="dark"] .nav-header {
    display: block;
    width: 100%;
    color: rgba(255, 255, 255, 0.42);
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 1rem 1rem 0.25rem;
    margin: 0;
}
/* Bug 2 — no horizontal scrollbar; clip long labels */
.navbar-vertical { overflow-x: hidden; }
.navbar-vertical .nav-link { overflow: hidden; }
.navbar-vertical .nav-link-icon svg { max-width: 1.25rem; max-height: 1.25rem; }
/* Bug 3 — badge must not eat the label ("Get Started" → "Ne…") */
.navbar-vertical .nav-link-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.navbar-vertical .nav-link .badge {
    flex: 0 0 auto;
    font-size: 0.625rem;
    padding: 0.125rem 0.375rem;
}

/* Number inputs: no spinner arrows (convention).
   Declared once here because every layout loads this file — do NOT repeat it
   per view. Select dropdown arrows are deliberately left alone. */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { display: none; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }

/* Tag chip / status badge / quality dot */
.tag-chip { display: inline-flex; align-items: center; padding: .125rem .5rem; font-size: .75rem; border-radius: 999px; margin-right: .25rem; margin-bottom: .25rem; }
.status-badge { font-size: .75rem; font-weight: 500; padding: .25rem .625rem; border-radius: 4px; }
.quality-dot { display:inline-block; width:.6rem; height:.6rem; border-radius:50%; }
.quality-dot.green { background:#2FB344; } .quality-dot.yellow { background:#F76707; } .quality-dot.red { background:#D63939; }

/* Page fade-in */
body.page-loading .page-body { opacity: 0; }
.page-body { transition: opacity .18s ease-in; }

/* -------------------------------------------------------------------------
   TIER 2 — elevation system (apply only to these surfaces)
   ------------------------------------------------------------------------- */
.card { box-shadow: var(--elevation-2); }
.card:hover { box-shadow: var(--elevation-3); }
.dropdown-menu { box-shadow: var(--elevation-4); }
.modal-content { box-shadow: var(--elevation-4); }
.btn { box-shadow: var(--elevation-1); }
.btn:hover { box-shadow: var(--elevation-2); }

/* TIER 2 — micro-interactions (selective, never bouncy) */
.btn { transition: transform var(--transition-base), box-shadow var(--transition-base), background-color var(--transition-base); }
.btn:not(:disabled):hover { transform: translateY(-1px); }
.btn:not(:disabled):active { transform: translateY(0); }
.card { transition: transform var(--transition-smooth), box-shadow var(--transition-smooth); }
.card.card-interactive:hover { transform: translateY(-2px); box-shadow: var(--elevation-3); cursor: pointer; }
.nav-link { transition: background-color var(--transition-base), color var(--transition-base); }
.form-control, .form-select { transition: border-color var(--transition-base), box-shadow var(--transition-base); }
.table-hover tbody tr { transition: background-color var(--transition-fast); }

/* TIER 2 — typography hierarchy */
h1, .h1 { font-weight: 700; letter-spacing: -0.02em; }
h2, .h2 { font-weight: 700; letter-spacing: -0.015em; }
h3, .h3 { font-weight: 600; letter-spacing: -0.01em; }
h4, .h4 { font-weight: 600; }
.page-title { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.015em; }
.page-pretitle { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--tblr-secondary); margin-bottom: 0.25rem; }
.card-title { font-size: 0.9375rem; font-weight: 600; margin-bottom: 0; }
body { line-height: 1.55; }
.text-muted { color: #64748b !important; }
.stat-card-value { font-size: 1.875rem; font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; }

/* TIER 2 — breathing room */
.page-body { padding-top: 2rem; padding-bottom: 2rem; }
@media (min-width: 1200px) { .page-body { padding-top: 2.5rem; padding-bottom: 2.5rem; } }
.page-header { margin-bottom: 1.75rem; }
.card-body { padding: 1.25rem 1.5rem; }
.card-header { padding: 1rem 1.5rem; }
@media (min-width: 768px) {
    .card-body { padding: 1.5rem 1.75rem; }
    .card-header { padding: 1.125rem 1.75rem; }
}

/* TIER 2 — stat cards as visual heroes */
.stat-card { transition: transform var(--transition-smooth), box-shadow var(--transition-smooth); }
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--elevation-3); }
.stat-card .subheader { margin-bottom: 0; }

/* TIER 2 — topbar + wallet chip + notification bell */
.navbar:not(.navbar-vertical) { background: #ffffff; border-bottom: 1px solid rgba(15, 23, 42, 0.06); box-shadow: var(--elevation-1); }
.wallet-chip {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.375rem 0.875rem; background: rgba(31, 168, 85, 0.08); color: #1FA855;
    border-radius: 999px; font-size: 0.8125rem; font-weight: 600; text-decoration: none;
    transition: background var(--transition-base);
}
.wallet-chip:hover { background: rgba(31, 168, 85, 0.14); color: #1FA855; }
.wallet-chip svg { width: 16px; height: 16px; }
.btn-notifications {
    width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; color: #64748b;
    transition: background var(--transition-base), color var(--transition-base);
}
.btn-notifications:hover { background: #f1f5f9; color: #0f172a; }

/* TIER 2 — form polish */
.form-label { font-weight: 500; font-size: 0.8125rem; color: #334155; margin-bottom: 0.375rem; }
.form-hint { color: #64748b; font-size: 0.75rem; margin-top: 0.375rem; }
.form-control, .form-select { border-color: rgba(15, 23, 42, 0.12); color: #0f172a; font-size: 0.875rem; }
.form-control:hover:not(:focus):not(:disabled),
.form-select:hover:not(:focus):not(:disabled) { border-color: rgba(15, 23, 42, 0.2); }
.form-control:focus, .form-select:focus { border-color: #1FA855; box-shadow: 0 0 0 3px rgba(31, 168, 85, 0.15); }
.form-label .required { color: #d63939; font-weight: 600; margin-left: 0.125rem; }
.form-section { padding-bottom: 1.5rem; margin-bottom: 1.5rem; border-bottom: 1px solid rgba(15, 23, 42, 0.06); }
.form-section:last-child { padding-bottom: 0; margin-bottom: 0; border-bottom: none; }

/* TIER 2 — loading skeletons (charts + search dropdown only) */
.skeleton {
    background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
    background-size: 200% 100%; animation: skeleton-loading 1.4s ease-in-out infinite;
    border-radius: 4px; color: transparent; user-select: none;
}
.skeleton-line { height: 1em; }
.skeleton-line.w-50 { width: 50%; } .skeleton-line.w-75 { width: 75%; }
@keyframes skeleton-loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* =========================================================================
   TIER 3 — surface refresh (2026)

   Everything above styles Tabler's classes; so does this. The point is that a
   page gets the new look by existing, not by opting in — there is no per-page
   <style> block anywhere in the app, and there must not be one.

   The named components at the bottom (.kpi-tile, .seg-nav, .chip, .field-label)
   are the opt-in half: pages that have KPIs, tabbed filters or filter chips use
   them, pages that don't simply never mention them.
   ========================================================================= */
:root {
    --surface-line: rgba(15, 23, 42, 0.07);
    --surface-hair: #f1f5f9;
    --surface-sunk: #e9eef4;
    --ink: #0f172a;
    --ink-soft: #334155;
    --ink-muted: #64748b;
    --ink-faint: #94a3b8;
    --brand: #1FA855;
    --brand-dark: #178D43;
    --radius-card: 16px;
    --radius-control: 11px;
    --lift: 0 1px 2px rgba(15, 23, 42, 0.04), 0 12px 28px -20px rgba(15, 23, 42, 0.45);
    --lift-hi: 0 2px 4px rgba(15, 23, 42, 0.05), 0 20px 36px -22px rgba(15, 23, 42, 0.55);
}

/* ---- Surfaces ---------------------------------------------------------- */
.card {
    border-radius: var(--radius-card);
    border: 1px solid var(--surface-line);
    box-shadow: var(--lift);
}
/* TIER 2 bumped the shadow on hover for EVERY card, which reads as noise on a
   page of six static panels. Only cards that are actually clickable move now. */
.card:hover { box-shadow: var(--lift); }
.card.card-interactive:hover,
a.card:hover { box-shadow: var(--lift-hi); border-color: rgba(15, 23, 42, 0.13); }
.card-header, .card-footer { background: transparent; border-color: var(--surface-line); }
.modal-content { border: 0; border-radius: 18px; }
.dropdown-menu { border-radius: 14px; border: 1px solid var(--surface-line); padding: 0.35rem; }
.dropdown-item { border-radius: 9px; }
.alert { border-radius: 12px; }

/* ---- Tables ------------------------------------------------------------ */
.table > thead > tr > th {
    background: #fbfcfe;
    border-top: 0;
    border-bottom: 1px solid var(--surface-line);
    padding: 0.8rem 0.85rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ink-faint);
    white-space: nowrap;
}
.table > tbody > tr > td {
    padding: 0.9rem 0.85rem;
    border-bottom: 1px solid var(--surface-hair);
    vertical-align: middle;
}
.table > tbody > tr:last-child > td { border-bottom: 0; }
.card-table > :not(caption) > * > *:first-child { padding-left: 1.25rem; }
.card-table > :not(caption) > * > *:last-child { padding-right: 1.25rem; }
.table > tbody > tr { transition: background-color var(--transition-fast); }
.table > tbody > tr:hover > * {
    --tblr-table-bg-state: rgba(31, 168, 85, 0.04);
    --bs-table-bg-state: rgba(31, 168, 85, 0.04);
}
/* Money and dates only line up in a column if their digits are one width. */
.num, .table .num { font-variant-numeric: tabular-nums; }

/* ---- Controls ---------------------------------------------------------- */
.form-control, .form-select {
    border-radius: var(--radius-control);
    border-color: transparent;
    background-color: var(--surface-hair);
    color: var(--ink);
    box-shadow: none;
}
.form-control::placeholder { color: var(--ink-faint); }
.form-control:hover:not(:focus):not(:disabled):not([readonly]),
.form-select:hover:not(:focus):not(:disabled) { background-color: var(--surface-sunk); border-color: transparent; }
.form-control:focus, .form-select:focus { background-color: #fff; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(31, 168, 85, 0.15); }
.form-control:disabled, .form-control[readonly] { background-color: #eef2f7; color: var(--ink-muted); }
.input-group-text { background-color: var(--surface-sunk); border-color: transparent; color: var(--ink-soft); }
.form-check-input:checked { background-color: var(--brand); border-color: var(--brand); }
.form-check-input:focus { box-shadow: 0 0 0 3px rgba(31, 168, 85, 0.15); }

/* Inside a filter bar every control is the same height whatever it is, so the
   selects, the search box and the Apply button share one baseline. */
.filter-bar .form-control, .filter-bar .form-select, .filter-bar .btn { height: 42px; }
.filter-bar .btn { padding-inline: 1.1rem; }

/* A small uppercase label for filter bars — quieter than .form-label, which
   stays the label style for real forms. */
.field-label {
    display: block;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 0.4rem;
}

/* ---- Buttons ----------------------------------------------------------- */
.btn { border-radius: 10px; font-weight: 600; box-shadow: none; }
.btn:hover { box-shadow: none; }
/* The 1px hop on every button hover is the single most dated thing in the UI. */
.btn:not(:disabled):hover, .btn:not(:disabled):active { transform: none; }
.btn-primary { box-shadow: 0 8px 18px -10px rgba(31, 168, 85, 0.95); }
.btn-primary:hover { box-shadow: 0 10px 22px -10px rgba(31, 168, 85, 1); }
.btn-soft {
    background: rgba(31, 168, 85, 0.09);
    color: var(--brand);
    border: 1px solid transparent;
}
.btn-soft:hover { background: rgba(31, 168, 85, 0.15); color: var(--brand-dark); }

/* ---- Badges + pagination ----------------------------------------------- */
.badge { border-radius: 999px; font-weight: 600; font-size: 0.6875rem; padding: 0.32rem 0.6rem; letter-spacing: 0.01em; }
.pagination { gap: 0.25rem; margin: 0; }
.page-link { border: 0; border-radius: 10px; color: var(--ink-soft); font-weight: 600; }
.page-link:hover { background: var(--surface-hair); color: var(--ink); }
.page-item.active .page-link { background: var(--brand); color: #fff; }
.page-item.disabled .page-link { color: var(--ink-faint); }

/* ---- KPI tile (x-stat-card renders this) ------------------------------- */
.kpi-tile {
    position: relative;
    overflow: hidden;
    height: 100%;
    display: block;
    color: inherit;
    text-decoration: none;
    transition: transform var(--transition-smooth), box-shadow var(--transition-smooth),
                border-color var(--transition-base), background-color var(--transition-base);
}
.kpi-tile::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 3px;
    background: var(--tone, var(--brand));
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.22s ease;
}
a.kpi-tile:hover { transform: translateY(-2px); color: inherit; }
a.kpi-tile:hover::after, .kpi-tile.is-on::after { transform: scaleX(1); }
.kpi-tile.is-on { border-color: var(--tone, var(--brand)); background: var(--tone-wash, rgba(31, 168, 85, 0.05)); }
.kpi-tile__body { display: flex; align-items: center; gap: 0.875rem; padding: 1.125rem 1.25rem; }
.kpi-tile__icon {
    flex: 0 0 auto; width: 42px; height: 42px; border-radius: 12px;
    display: grid; place-items: center;
    background: var(--tone-soft, rgba(31, 168, 85, 0.12));
    color: var(--tone, var(--brand));
}
.kpi-tile__main { min-width: 0; }
.kpi-tile__label {
    display: flex; align-items: center; gap: 0.3rem;
    font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-muted);
}
.kpi-tile__value {
    font-size: 1.75rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15;
    color: var(--ink); font-variant-numeric: tabular-nums;
}
.kpi-tile__hint { font-size: 0.75rem; color: var(--ink-faint); margin-top: 0.15rem; }

/* ---- Segmented tab strip (filter that is one click, with live counts) --- */
.seg-nav { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; padding: 0.25rem; background: var(--surface-hair); border-radius: 999px; }
.seg-nav__item {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.4rem 0.85rem; border-radius: 999px;
    font-size: 0.8125rem; font-weight: 600; color: var(--ink-soft);
    text-decoration: none; white-space: nowrap;
    transition: background-color var(--transition-base), color var(--transition-base), box-shadow var(--transition-base);
}
.seg-nav__item:hover { color: var(--ink); background: rgba(255, 255, 255, 0.75); }
.seg-nav__item.is-on { background: #fff; color: var(--ink); box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08), 0 4px 10px -6px rgba(15, 23, 42, 0.5); }
.seg-nav__count { font-size: 0.6875rem; font-weight: 700; padding: 0.05rem 0.4rem; border-radius: 999px; background: rgba(15, 23, 42, 0.06); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.seg-nav__item.is-on .seg-nav__count { background: rgba(31, 168, 85, 0.14); color: var(--brand); }

/* ---- Applied-filter chips ---------------------------------------------- */
.chip {
    display: inline-flex; align-items: center; gap: 0.45rem;
    padding: 0.32rem 0.45rem 0.32rem 0.7rem; border-radius: 999px;
    background: #fff; border: 1px solid var(--surface-line);
    font-size: 0.75rem; font-weight: 600; color: var(--ink-soft);
}
.chip__label { color: var(--ink-muted); font-weight: 400; }
.chip__x {
    display: inline-grid; place-items: center; width: 17px; height: 17px;
    border-radius: 50%; background: rgba(15, 23, 42, 0.06); color: var(--ink-muted);
    text-decoration: none; font-size: 0.85rem; line-height: 0;
}
.chip__x:hover { background: rgba(225, 29, 72, 0.12); color: #e11d48; }

/* ---- Hero panel (the client dashboard's greeting band) ----------------- */
.hero-panel {
    position: relative;
    overflow: hidden;
    color: #fff;
    border-radius: var(--radius-card);
    background: linear-gradient(135deg, #111B21 0%, #16323b 48%, #1a7a45 130%);
    box-shadow: var(--lift-hi);
}
/* A soft brand bloom in the top-right, so the panel is not a flat slab. */
.hero-panel::after {
    content: "";
    position: absolute;
    right: -90px;
    top: -140px;
    width: 340px;
    height: 340px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(31, 168, 85, 0.38), transparent 70%);
    pointer-events: none;
}
.hero-panel__body { position: relative; padding: 1.5rem 1.75rem; }
.hero-panel__eyebrow { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255, 255, 255, 0.55); }
.hero-panel__title { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; margin: 0.15rem 0 0; color: #fff; }
.hero-panel__meta { color: rgba(255, 255, 255, 0.72); font-size: 0.875rem; }
.hero-panel .badge-glass { background: rgba(255, 255, 255, 0.14); color: #fff; border: 1px solid rgba(255, 255, 255, 0.16); }
.hero-stat {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.13);
    border-radius: 12px;
    padding: 0.7rem 1rem;
    min-width: 128px;
}
.hero-stat__label { font-size: 0.625rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255, 255, 255, 0.6); }
.hero-stat__value { font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; }
.btn-glass { background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff; }
.btn-glass:hover { background: rgba(255, 255, 255, 0.22); color: #fff; }

/* ---- Quick actions ----------------------------------------------------- */
.quick-action {
    display: flex; align-items: center; gap: 0.75rem; height: 100%;
    padding: 0.85rem 1rem; border-radius: 12px;
    border: 1px solid var(--surface-line); background: #fff;
    color: var(--ink); text-decoration: none;
    transition: transform var(--transition-base), border-color var(--transition-base), background-color var(--transition-base);
}
.quick-action:hover { border-color: var(--brand); background: rgba(31, 168, 85, 0.05); color: var(--ink); transform: translateY(-1px); }
.quick-action__icon {
    flex: 0 0 auto; width: 36px; height: 36px; border-radius: 10px;
    display: grid; place-items: center; background: rgba(31, 168, 85, 0.11); color: var(--brand);
}
.quick-action__title { font-weight: 600; font-size: 0.875rem; line-height: 1.2; }
.quick-action__sub { font-size: 0.75rem; color: var(--ink-faint); }

/* ---- Row identity ------------------------------------------------------ */
.row-avatar {
    flex: 0 0 auto; width: 36px; height: 36px; border-radius: 11px;
    display: grid; place-items: center; color: #fff; font-weight: 600; font-size: 0.8125rem;
    background: linear-gradient(135deg, #34c46f, #178f47);
    box-shadow: 0 5px 12px -7px rgba(23, 143, 71, 0.95);
}
.row-title { font-weight: 600; color: var(--ink); text-decoration: none; }
.row-title:hover { color: var(--brand); }
.row-sub { font-size: 0.75rem; color: var(--ink-faint); }
.row-date { font-size: 0.8125rem; color: var(--ink-soft); }
.row-danger { color: #e11d48; font-weight: 600; }

/* =========================================================================
   WhatsApp phone preview — the showpiece (template builder + show)
   ========================================================================= */
.phone-preview { position: sticky; top: 1rem; max-width: 320px; margin: 0 auto; }
.phone-frame {
    background: #1a1a1a; border-radius: 42px; padding: 14px; position: relative;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.05) inset,
        0 30px 60px -15px rgba(15, 23, 42, 0.25), 0 12px 20px -8px rgba(15, 23, 42, 0.15);
}
.phone-frame::before {
    content: ''; position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
    width: 90px; height: 22px; background: #1a1a1a; border-radius: 0 0 16px 16px; z-index: 2;
}
.phone-screen {
    background: #e5ddd5; border-radius: 30px; min-height: 540px; overflow: hidden;
    background-image:
        radial-gradient(circle at 20% 10%, rgba(255,255,255,0.4) 0%, transparent 30%),
        radial-gradient(circle at 80% 90%, rgba(255,255,255,0.2) 0%, transparent 30%);
}
.wa-chat-header { background: #075e54; color: #fff; padding: 30px 16px 12px; display: flex; align-items: center; gap: 10px; }
.wa-chat-header .wa-avatar, .wa-avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: linear-gradient(135deg, #25d366, #1fa855);
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 600; font-size: 0.875rem; box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.wa-chat-header .wa-name, .wa-name { font-weight: 500; font-size: 0.9rem; }
.wa-chat-header .wa-online, .wa-online { color: rgba(255,255,255,0.7); font-size: 0.7rem; }
.wa-chat-body { padding: 16px 12px; min-height: 440px; }
.wa-bubble {
    background: #fff; border-radius: 8px; padding: 8px 10px 6px; margin-bottom: 4px; max-width: 85%;
    box-shadow: 0 1px 0.5px rgba(0,0,0,0.13); font-size: 0.8125rem; line-height: 1.4; color: #303030;
    position: relative; word-wrap: break-word;
}
.wa-bubble-header { font-weight: 600; margin-bottom: 4px; color: #1fa855; white-space: pre-wrap; word-break: break-word; }
.wa-bubble-body { white-space: pre-wrap; word-break: break-word; }
.wa-bubble-footer { color: #667781; font-size: 0.6875rem; margin-top: 4px; }
.wa-bubble-time { color: #667781; font-size: 0.625rem; text-align: right; margin-top: 2px; }
.wa-bubble-buttons { margin-top: 6px; }
.wa-bubble-button {
    display: block; background: #fff; color: #00a5f4; text-align: center; padding: 8px;
    border-radius: 8px; border: 1px solid #e0e0e0; margin-top: 4px; font-size: 0.8125rem; font-weight: 500; cursor: default;
}
.wa-media-ph {
    background: linear-gradient(135deg, #f0f0f0, #e0e0e0); color: #999; padding: 40px 20px;
    text-align: center; font-size: 0.75rem; border-radius: 6px; font-weight: 600; letter-spacing: 0.05em; margin-bottom: 6px;
}
/* A REAL file chosen for a media header. The block above is the EMPTY state:
   40px of padding is right for the word "IMAGE" and far too much once there is
   something to look at, which is why a picked document filled a third of the
   phone. Drawn the way WhatsApp draws it instead — media cropped to a banner,
   a document as a compact named row with its first page above it. */
.wa-media-file {
    display: block; width: 100%; max-height: 200px; object-fit: cover;
    border-radius: 6px; margin-bottom: 6px; background: #000;
}
/* pointer-events:none — this is a thumbnail, not a reader. Without it the
   browser's PDF viewer takes the scroll wheel whenever the cursor crosses it. */
.wa-doc-page {
    display: block; width: 100%; height: 150px; border: 0;
    border-radius: 6px 6px 0 0; background: #fff; pointer-events: none;
}
.wa-doc-card {
    display: flex; align-items: center; gap: 8px;
    background: #f5f6f6; border-radius: 6px; padding: 8px 10px; margin-bottom: 6px;
}
.wa-doc-card.has-page { border-radius: 0 0 6px 6px; }
.wa-doc-icon {
    flex: 0 0 auto; width: 26px; height: 26px; border-radius: 4px;
    background: #d64542; color: #fff; font-size: 8px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; letter-spacing: 0;
}
.wa-doc-name {
    min-width: 0; font-size: 0.75rem; color: #3b4a54; font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A {{n}} slot in a preview that the user hasn't filled in yet — shows the
   template's sample value until they type over it. */
.wa-var-ph {
    background: #fff3cd; border-bottom: 1px dashed #d0a300; color: #8a6100;
    border-radius: 3px; padding: 0 2px;
}

#save-indicator { position:fixed; right:1rem; bottom:1rem; z-index:1056; }

/* =========================================================================
   Global mobile fit + performance polish (site-wide, loaded after Tabler).
   Small-screen safety nets so every page — dashboard, contacts, templates,
   billing, campaigns, admin — is comfortable on a phone without editing each
   view. Page-scoped styles (e.g. the Inbox) still override these.
   ========================================================================= */

/* Nothing should force the page to scroll sideways on a phone. (max-width only —
   no global height:auto, so fixed-size avatars/logos keep their dimensions.) */
img, svg, video, canvas, iframe { max-width: 100%; }
pre { max-width: 100%; overflow-x: auto; }
/* Long unbroken strings (API tokens, URLs, phone numbers) wrap, not overflow. */
td, th, dd, .card-text, .text-break-any { overflow-wrap: anywhere; }

@media (max-width: 767.98px) {
    /* Bare tables (NOT already inside .table-responsive — those aren't direct
       children of .card-body) scroll sideways instead of stretching the card
       off-screen. */
    .card-body > .table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .table-responsive { -webkit-overflow-scrolling: touch; }

    /* A little more usable width for content on small phones. */
    .card-body { padding: 1rem 1.05rem; }

    /* Toolbars / action rows wrap instead of overflowing. */
    .btn-list { flex-wrap: wrap; }

    /* Comfortable tap targets (leave small + icon buttons as designed). */
    .btn:not(.btn-sm):not(.btn-icon):not(.btn-close) { min-height: 40px; }
}

/* iOS zooms the whole page when you focus an input under 16px. Keeping inputs
   at 16px on phones means tapping a field never zooms or reflows the layout. */
@media (max-width: 575.98px) {
    .form-control, .form-select, .form-control-sm, .form-select-sm { font-size: 16px; }
}

/* Keep the top bar reachable while scrolling long pages on phones/tablets. */
@media (max-width: 991.98px) {
    .page > header.navbar { position: sticky; top: 0; z-index: 1030; background-color: var(--tblr-navbar-bg, #ffffff); }
}

/* Honour "reduce motion" — also smoother on low-end phones. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}


/* ── Wallet top-up: picking a route, and picking a bank ────────────────────
   Two levels of tab on one screen. Drawn as plain nav links they read as
   headings rather than choices — a customer looking at the page could not tell
   the second option was there, let alone clickable. Both levels are therefore
   real pickable surfaces with an unmistakable selected state.

   Every colour derives from --tblr-primary / --tblr-primary-rgb, which the
   layout stamps on <html> from the resolved brand. A literal here would show
   our green on a partner's white-labelled hostname. */

.topup-routes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: .75rem;
    border-bottom: 0;
}
.topup-routes .nav-item { display: flex; }

.topup-route {
    position: relative;
    display: flex;
    align-items: center;
    gap: .75rem;
    width: 100%;
    padding: .875rem 1rem;
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    border-radius: 12px;
    background: var(--tblr-bg-surface, #fff);
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.topup-route:hover {
    border-color: var(--tblr-primary);
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .07);
}
/* The selected route: brand border, a soft ring, and a tinted ground. Three
   cues rather than one, because a single 1px border change is exactly what
   went unnoticed before. */
.topup-route.active {
    border-color: var(--tblr-primary);
    background: rgba(var(--tblr-primary-rgb), .045);
    box-shadow: 0 0 0 2px rgba(var(--tblr-primary-rgb), .18);
}

.topup-route-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9px;
    background: var(--tblr-bg-surface-secondary, #f1f3f5);
    color: var(--tblr-secondary, #667382);
    transition: background .15s ease, color .15s ease;
}
.topup-route.active .topup-route-icon {
    background: var(--tblr-primary);
    color: #fff;
}

/* min-width:0 so a long label ellipsises instead of forcing the card wider
   than its grid column. */
.topup-route-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.topup-route-title { font-weight: 600; font-size: .875rem; color: var(--tblr-body-color, #182433); }
.topup-route-sub { font-size: .75rem; color: var(--tblr-secondary, #667382); }

/* Pushed to the far edge so the two cards' badges line up with each other. */
.topup-route-badge { margin-left: auto; flex: 0 0 auto; }

/* The tick sits in the flow after the badge and keeps its space when hidden:
   visibility, not display. Absolutely positioning it in the corner put it on
   top of the badge on a narrow screen, and display:none made both badges jump
   sideways as the selection moved between the cards. */
.topup-route-check {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    visibility: hidden;
    color: var(--tblr-primary);
}
.topup-route.active .topup-route-check { visibility: visible; }

/* ── The bank picker inside the offline route ─────────────────────────── */

.bank-picker { display: flex; flex-wrap: wrap; gap: .5rem; border-bottom: 0; }

.bank-chip {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .4375rem .75rem;
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    border-radius: 999px;
    background: var(--tblr-bg-surface, #fff);
    color: var(--tblr-secondary, #667382);
    font-size: .8125rem;
    font-weight: 500;
    text-decoration: none;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.bank-chip:hover { border-color: var(--tblr-primary); color: var(--tblr-primary); }
.bank-chip.active {
    border-color: var(--tblr-primary);
    background: var(--tblr-primary);
    color: #fff;
}
/* The dot is the unselected chip's only colour, so it survives the fill
   inverting when the chip becomes active. */
.bank-chip-dot { width: .5rem; height: .5rem; border-radius: 50%; background: currentColor; opacity: .45; }
.bank-chip.active .bank-chip-dot { opacity: 1; background: #fff; }

/* -------------------------------------------------------------------------
   TIER 3 — THE APP SHELL
   The frame every screen sits inside: the sidebar and the top bar.

   The panel is installed as a desktop app, where there is no browser chrome
   around it — the shell IS the application window as far as the person using
   it is concerned. Tabler ships no active state for a vertical nav link, so
   the current page was indicated by nothing but the text, and a sidebar where
   every row looks identical reads as a list of links rather than as somewhere
   you are.

   Built on the tokens already defined above rather than new values, so this
   stays one design rather than two.
   ------------------------------------------------------------------------- */

/* --- Sidebar rows: geometry first, so a highlight has room to be a shape --- */
.navbar-vertical .navbar-nav > .nav-item > .nav-link {
    margin: 0.0625rem 0.5rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    color: rgba(255, 255, 255, 0.72);
    font-weight: 500;
    transition: background-color var(--transition-base), color var(--transition-base);
}
.navbar-vertical .navbar-nav > .nav-item > .nav-link .nav-link-icon {
    color: rgba(255, 255, 255, 0.55);
    transition: color var(--transition-base);
}

/* Hover: a surface appears under the cursor, so the row is obviously a target. */
.navbar-vertical .navbar-nav > .nav-item > .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.07);
    color: #fff;
}
.navbar-vertical .navbar-nav > .nav-item > .nav-link:hover .nav-link-icon { color: #fff; }

/*
 | THE CURRENT PAGE. A tinted pill in the brand green with a solid accent down
 | its leading edge — the accent is what still separates it at a glance for
 | someone who cannot distinguish the tint from the sidebar behind it, which a
 | background-colour-only state does not.
 */
.navbar-vertical .navbar-nav > .nav-item.active > .nav-link,
.navbar-vertical .navbar-nav > .nav-item > .nav-link.active {
    background-color: rgba(31, 168, 85, 0.18);
    color: #fff;
    font-weight: 600;
    box-shadow: inset 3px 0 0 0 #1FA855;
}
.navbar-vertical .navbar-nav > .nav-item.active > .nav-link .nav-link-icon,
.navbar-vertical .navbar-nav > .nav-item > .nav-link.active .nav-link-icon { color: #2FD07A; }

/* --- Sidebar scrollbar: present when needed, never a grey slab --- */
.navbar-vertical .navbar-collapse { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.18) transparent; }
.navbar-vertical .navbar-collapse::-webkit-scrollbar { width: 6px; }
.navbar-vertical .navbar-collapse::-webkit-scrollbar-track { background: transparent; }
.navbar-vertical .navbar-collapse::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 3px; }
.navbar-vertical .navbar-collapse::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.3); }

/*
 | --- The top bar stays put ---
 | On a long screen — Contacts, Campaigns, a template list — scrolling used to
 | carry the wallet balance and the account menu off the top, so the only way
 | back to them was to scroll all the way up. In a window with no browser
 | chrome that is the app's entire header disappearing.
 |
 | Translucent rather than solid so content passing underneath is still
 | legible as motion, with a plain-colour fallback first for the browsers that
 | do not support backdrop-filter.
 */
@media (min-width: 992px) {
    .page > .navbar:not(.navbar-vertical) {
        position: sticky;
        top: 0;
        z-index: 1020;
        background: #ffffff;
        background: rgba(255, 255, 255, 0.86);
        backdrop-filter: saturate(180%) blur(10px);
        -webkit-backdrop-filter: saturate(180%) blur(10px);
    }
}

/*
 | --- Keyboard focus ---
 | One ring, in the brand colour, on everything. The browser default is a thin
 | outline that vanishes against a dark sidebar, which makes tabbing through
 | the app a guessing game.
 */
.btn:focus-visible,
.nav-link:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.dropdown-item:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(31, 168, 85, 0.28);
}
.navbar-vertical .nav-link:focus-visible { box-shadow: 0 0 0 3px rgba(47, 208, 122, 0.45); }

/*
 | --- Back / forward ---
 | Disabled has to look unavailable rather than broken: at the start of a
 | session both are dead by definition, and a control that looks pressable and
 | does nothing teaches people the app ignores them.
 */
#navHistory .btn { box-shadow: none; }
#navHistory .btn:not(:disabled):hover { background-color: #f1f5f9; color: #0f172a; transform: none; }
#navHistory .btn:disabled { opacity: 0.32; box-shadow: none; transform: none; }

/*
 | --- Sidebar badges: in the row, not hanging off its corner ---
 | Tabler styles a .nav-link .badge as a notification DOT: position:absolute,
 | pinned to the top-right and translated further out still, which is right for
 | a numeric bubble on an icon and wrong for a word. The overflow:hidden added
 | above (to kill a horizontal scrollbar) then clips whatever overhangs, so the
 | "New" beside Team Chat has been rendering as "Ne" — cut off mid-word, which
 | reads as a broken page rather than a label.
 |
 | Put back in the flex row, where ms-auto can do its job and push it to the
 | end. Nothing overhangs, so nothing is clipped, and a longer word or a "99+"
 | count simply takes the space it needs.
 */
/* Four classes, deliberately: Tabler's own rule is
   `.navbar .navbar-nav .nav-link .badge`, so a three-class selector loses to it
   on specificity and silently does nothing. This matches it and wins on order,
   because app.css is loaded after tabler.min.css. */
.navbar-vertical .navbar-nav .nav-link .badge {
    position: static;
    transform: none;
    margin-left: auto;
    flex: 0 0 auto;
    align-self: center;
}
