/* ═══════════════════════════════════════════════════════════════════════════════
   Arc Marketing · Admin / Portal Theme  (light, marketing-aligned)
   Tokens mirror arcmarketing.xyz so admin + portal + reseller views feel
   like one continuous product. Swapping these values reskins ~80% of the
   surface; the remaining 20% is per-view inline overrides we fix in HTML.
   ═══════════════════════════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=Bricolage+Grotesque:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap');

/* ── Reset & Variables ────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN-SYSTEM RULES — read this before touching colours.

   1. Pick from TOKENS, never raw hex / rgba in component selectors. Tokens
      auto-swap per theme; raw colours break dark mode silently.

   2. Surface ladder (use the *least* tinted variant that still reads):
        --bg          page background        (most muted)
        --bg-subtle   sub-panel inside card  (1 step elevated)
        --bg-card     solid card             (2 steps elevated, fully opaque)
      Cards MUST be opaque — semi-transparent surfaces let the body::before
      gradient bleed through and look washed-out. If you need translucent
      glass, use --sidebar (only the sticky nav uses it).

   3. Text vs surface — every text element references --text (body) or
      --muted (sublines), never raw colour. If the surface is var(--accent)
      filled, use `#fff` explicitly (the only exception to rule 1).

   4. Striped rows: ALWAYS `var(--row-stripe)`. Both themes define it.
      `nth-child(even) { background: #fdfbff }` is the classic foot-gun —
      it kills dark-mode text contrast.

   5. Borders should always be visible: 1px solid var(--border). On dark
      mode the alpha is 0.22, on light it's a flat colour — both read.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Sidebar width — single source of truth. `aside` sizes itself from it, main
     is inset by it, and full-screen overlays start after it (see --overlay-left
     further down). Change it here and the whole layout follows. */
  --sidebar-w: 260px;

  /* ── Surfaces (light) — softly tinted page, opaque white cards. ──────── */
  --bg:           #f6f1fc;           /* Page background — light purple tint */
  --bg-subtle:    #ede4f7;           /* Sub-panel / striped header */
  --bg-card:      #ffffff;           /* Solid card */
  --bg-input:     #ffffff;           /* Solid input */
  --row-stripe:   #faf6fd;           /* Even-row striping inside tables */
  --sidebar:      rgba(255, 255, 255, 0.92); /* Translucent sticky nav */
  --card:         #ffffff;           /* Alias for --bg-card (legacy selectors) */
  --card-solid:   #ffffff;
  --surface:      #f3eefe;
  --border:       #ddd2ee;
  --border-h:     #a855f7;
  /* ── Brand colours — same hex in both themes for brand consistency. ──── */
  --accent:       #6d28d9;
  --accent-h:     #4c1d95;
  --accent-glow:  rgba(109, 40, 217, 0.20);
  --accent-dim:   #f3e8ff;
  --accent-light: #f3e8ff;
  --purple:       #a855f7;
  --purple-dim:   rgba(168, 85, 247, 0.10);
  /* ── Semantic colours (light). ────────────────────────────────────────── */
  --green:        #16a34a;
  --green-dim:    #dcfce7;
  --red:          #dc2626;
  --red-dim:      #fee2e2;
  --amber:        #d97706;
  --amber-dim:    #fef3c7;
  --cyan:         #0ea5e9;
  --cyan-dim:     #e0f2fe;
  /* ── Text ─────────────────────────────────────────────────────────────── */
  --text:         #1a0a2e;
  --text-bright:  #1a0a2e;
  --fg:           #1a0a2e;
  --muted:        #5a4f70;
  --muted2:       #9088a3;
  --input-bg:     #ffffff;
  --input-border: #ddd2ee;
  --primary:      #6d28d9;
  /* ── Geometry — shadcn-style scale (calmer corners, tighter ring). ───── */
  --radius:       12px;
  --radius-sm:    9px;
  --radius-xs:    7px;
  --shadow-xs:    0 1px 2px rgba(26, 10, 46, 0.05);
  --shadow-sm:    0 1px 3px rgba(26, 10, 46, 0.07), 0 1px 2px rgba(26, 10, 46, 0.04);
  --shadow-md:    0 4px 16px rgba(26, 10, 46, 0.10);
  --shadow-lg:    0 18px 48px rgba(26, 10, 46, 0.22);
  --transition:   0.15s cubic-bezier(0.4, 0, 0.2, 1);
  --ring:         0 0 0 2px color-mix(in srgb, var(--accent) 32%, transparent);
}

/* ── Dark theme override ────────────────────────────────────────────────
   Applied when <html data-theme="dark">. sidebar.js sets this attribute
   from localStorage before paint to avoid a flash. Every token used by
   the rest of theme.css is redefined here so the same selectors auto-
   theme-switch — no per-rule duplication elsewhere.

   IMPORTANT: surface tokens are SOLID (no alpha) so cards don't show
   the body::before purple bloom through and read washed-out. Translucent
   glass is reserved for --sidebar where the blur effect is desired. */
html[data-theme="dark"] {
  /* ── Surfaces (dark) — solid slate-purple ladder. ─────────────────────── */
  --bg:           #0a0d18;           /* Deep slate-purple page */
  --bg-subtle:    #131729;           /* Sub-panel / striped header */
  --bg-card:      #1a1f33;           /* Solid card surface (NO alpha) */
  --bg-input:     #1a1f33;           /* Solid input */
  --row-stripe:   rgba(168, 85, 247, 0.04); /* Subtle purple wash for even rows */
  --sidebar:      rgba(10, 13, 24, 0.92);
  --card:         #1a1f33;           /* SOLID — alias for --bg-card */
  --card-solid:   #1a1f33;
  --surface:      #20253d;
  --border:       rgba(168, 85, 247, 0.22);
  --border-h:     rgba(168, 85, 247, 0.50);
  /* ── Brand — push purple a step lighter so it reads on dark cards. ─── */
  --accent:       #a855f7;
  --accent-h:     #c084fc;
  --accent-glow:  rgba(168, 85, 247, 0.32);
  --accent-dim:   rgba(168, 85, 247, 0.10);
  --accent-light: rgba(168, 85, 247, 0.12);
  --purple:       #c084fc;
  --purple-dim:   rgba(168, 85, 247, 0.08);
  /* ── Semantic — slightly desaturated for dark mode legibility. ──────── */
  --green:        #34d399;
  --green-dim:    rgba(52, 211, 153, 0.16);
  --red:          #f87171;
  --red-dim:      rgba(248, 113, 113, 0.16);
  --amber:        #fbbf24;
  --amber-dim:    rgba(251, 191, 36, 0.16);
  --cyan:         #22d3ee;
  --cyan-dim:     rgba(34, 211, 238, 0.14);
  /* ── Text ─────────────────────────────────────────────────────────────── */
  --text:         #f1f5f9;
  --text-bright:  #ffffff;
  --fg:           #f1f5f9;
  --muted:        #94a3b8;
  --muted2:       #64748b;
  --input-bg:     #1a1f33;
  --input-border: rgba(168, 85, 247, 0.28);
  --primary:      #a855f7;
  --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-sm:    0 2px 8px rgba(0, 0, 0, 0.30);
  --shadow-md:    0 8px 24px rgba(0, 0, 0, 0.40);
  --shadow-lg:    0 20px 50px rgba(0, 0, 0, 0.55);
  color-scheme:   dark;
}

/* Dark-mode body::before — much fainter than light mode so it never
   bleeds visibly through the solid cards. */
html[data-theme="dark"] body::before {
  background:
    radial-gradient(ellipse 70% 50% at 10% -10%, rgba(168, 85, 247, 0.05) 0%, transparent 70%),
    radial-gradient(ellipse 60% 40% at 90% 90%, rgba(168, 85, 247, 0.04) 0%, transparent 70%);
}
/* Sidebar toggle button — flip light→dark surface. */
html[data-theme="dark"] .sidebar-toggle {
  background: var(--bg-card);
  color: var(--fg);
}
html[data-theme="dark"] .sidebar-toggle:hover { background: var(--accent-light); }

/* ── Focus Rings ───────────────────────────────────────────────────────────── */
:where(a, button, input, select, textarea):focus { outline: none; }
:where(a, button, input, select, textarea):focus-visible {
  box-shadow: var(--ring);
  border-color: var(--accent);
}

html { color-scheme: light; }

/* ── Input placeholders ─────────────────────────────────────────────────
   One rule, both themes, predictable contrast across browsers. --muted2
   is the lighter of our two muted greys so the placeholder reads as a
   gentle hint rather than competing with real input values. */
input::placeholder, textarea::placeholder, select::placeholder {
  color: var(--muted2);
  opacity: 1; /* Firefox dims placeholders by default — flatten it. */
}

/* ── Scrollbar ────────────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(109, 40, 217, 0.18); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(109, 40, 217, 0.32); }

/* ── Body ─────────────────────────────────────────────────────────────────────── */
body {
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--text);
  display: flex;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  line-height: 1.4;
}

/* Subtle marketing-tinted mesh background — same character as the website
   hero, but very faint so admin data still pops.
   z-index MUST stay negative. It sits behind page content on its own rather
   than relying on <main> to out-stack it, which is what lets <main> avoid
   creating a stacking context — see the note on `main` below. Negative z-index
   still paints above the body's propagated canvas background, so the mesh
   remains visible. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 90% 60% at 10% -10%, rgba(109, 40, 217, 0.045) 0%, transparent 60%),
    radial-gradient(ellipse 70% 50% at 90% 90%, rgba(168, 85, 247, 0.04) 0%, transparent 50%);
  pointer-events: none;
  z-index: -1;
}

/* ── Sidebar ──────────────────────────────────────────────────────────────────── */
aside {
  width: var(--sidebar-w, 260px);
  background: var(--sidebar);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 28px 0;
  position: fixed;
  height: 100vh;
  overflow-y: auto;
  z-index: 50;
}

aside::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 1px;
  background: linear-gradient(to bottom, rgba(109,40,217,0.20), transparent 30%, transparent 70%, rgba(168,85,247,0.15));
}

.brand {
  padding: 0 24px 28px;
  border-bottom: 1px solid var(--border);
}

.brand-icon {
  width: 36px;
  height: 36px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  display: block;
  object-fit: contain;
  padding: 5px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-sm);
}

.brand-name {
  font-family: 'Bricolage Grotesque', sans-serif;
  font-weight: 800;
  font-size: 16px;
  letter-spacing: -0.3px;
  color: var(--text);
}
.brand-name::after {
  content: '';
}

.brand-tag {
  font-size: 11px;
  color: var(--muted);
  font-weight: 500;
  letter-spacing: 0.3px;
  margin-top: 2px;
}

/* ── Navigation ───────────────────────────────────────────────────────────────── */
nav { padding: 20px 14px; flex: 1; }

nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  color: var(--muted);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: all var(--transition);
  margin-bottom: 2px;
  position: relative;
}

nav a:hover {
  background: var(--accent-light);
  color: var(--accent);
}

nav a.active {
  background: linear-gradient(135deg, rgba(109,40,217,0.10), rgba(168,85,247,0.06));
  color: var(--accent);
  font-weight: 700;
  box-shadow: inset 0 0 0 1px rgba(109,40,217,0.18);
}

nav a.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  background: linear-gradient(to bottom, var(--accent), var(--purple));
  border-radius: 0 4px 4px 0;
}

.nav-section {
  padding: 14px 14px 6px;
  font-size: 10px;
  color: var(--muted2);
  text-transform: uppercase;
  letter-spacing: 1px;
  font-weight: 700;
}

.sidebar-footer {
  padding: 20px 24px;
  border-top: 1px solid var(--border);
}

/* Logout button — matched to the .theme-toggle button injected by
   sidebar.js so the sidebar footer reads as a consistent pair of pill
   actions. Keeps the red hover for destructive-action semantics. */
.logout-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  padding: 9px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: all .15s;
}

.logout-btn:hover {
  color: var(--red);
  border-color: var(--red);
  background: var(--red-dim);
}

/* ── Main Content ─────────────────────────────────────────────────────────────── */
/* Deliberately has NO z-index. Giving <main> one makes it a stacking context,
   which traps every descendant inside it — a modal declaring z-index: 9999 then
   still paints *below* the sidebar (z-index 50), because it is only 9999 within
   main's context. That is why several views' dialogs used to appear behind the
   nav. The mesh background handles its own layering (see body::before), so main
   does not need to out-stack anything. Keep it that way: if you add a z-index
   here, every in-page dialog goes back behind the sidebar. */
main {
  margin-left: var(--sidebar-w, 260px);
  flex: 1;
  padding: 36px 40px;
  max-width: 1360px;
  position: relative;
  transition: margin-left .25s ease, max-width .25s ease;
}

/* ── Page Header ──────────────────────────────────────────────────────────────── */
.page-header {
  margin-bottom: 32px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.page-header h1 {
  font-family: 'Bricolage Grotesque', sans-serif;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.8px;
  color: var(--text);
}

.page-header p {
  color: var(--muted);
  font-size: 14px;
  margin-top: 6px;
  font-weight: 400;
}

/* ── Cards ────────────────────────────────────────────────────────────────────── */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.card:hover {
  border-color: var(--border-h);
  box-shadow: var(--shadow-md);
}

.card-header {
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg-subtle);
}

.card-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.2px;
}

.card-body {
  padding: 20px 24px;
}

/* ── Small Layout Helpers ──────────────────────────────────────────────────── */
.ml-auto { margin-left: auto; }
.nowrap { white-space: nowrap; }

/* ── Inline Form Row (1 input + actions) ───────────────────────────────────── */
.inline-form {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
}

.inline-form .form-group { flex: 1; min-width: 260px; }

.input-mono { font-family: 'JetBrains Mono', monospace !important; }

/* ── Stat Cards ───────────────────────────────────────────────────────────────── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.stats-grid-2 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 30px;
}

.stat-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  transition: all var(--transition);
  position: relative;
  overflow: hidden;
}

.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(109,40,217,0.45), transparent);
  opacity: 0;
  transition: opacity var(--transition);
}

.stat-card:hover {
  border-color: var(--border-h);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.stat-card:hover::before {
  opacity: 1;
}

.stat-card.connected {
  border-color: var(--green);
  background: linear-gradient(135deg, var(--bg-card), var(--green-dim));
}

.stat-card.warn {
  border-color: var(--red);
  background: linear-gradient(135deg, var(--bg-card), var(--red-dim));
}

.stat-label {
  font-size: 11px;
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 12px;
}

.stat-value {
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -1px;
}

.stat-value.sm { font-size: 22px; letter-spacing: -0.5px; }
.stat-value.md { font-size: 20px; letter-spacing: -0.6px; }

.stat-card.plain {
  background: transparent;
  box-shadow: none;
  border-color: transparent;
  padding: 18px;
}

.metrics-card {
  padding: 16px;
  margin-top: 16px;
  margin-bottom: 24px;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.stat-icon { font-size: 18px; float: right; }
.stat-sub { font-size: 12px; color: var(--muted); margin-top: 6px; }

/* ── Color Utilities ──────────────────────────────────────────────────────────── */
.c-green   { color: var(--green); }
.c-accent  { color: var(--accent); }
.c-red     { color: var(--red); }
.c-amber   { color: var(--amber); }
.c-cyan    { color: var(--cyan); }
.c-muted   { color: var(--muted); }

/* ── Table ────────────────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; }

th {
  background: var(--bg-subtle);
  padding: 11px 18px;
  text-align: left;
  font-size: 10px;
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  border-bottom: 1px solid var(--border);
}

td {
  padding: 12px 18px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
  transition: background var(--transition), left .25s ease;
}

tbody tr:nth-child(even) td { background: var(--row-stripe); }

tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--accent-light); }

.td-muted { font-size: 12px; color: var(--muted); }
.td-nowrap { white-space: nowrap; }
.td-ellipsis {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
}

/* ── Dashboard Helpers ───────────────────────────────────────────────────────── */
.card-accent {
  border-color: var(--border-h);
  background: linear-gradient(135deg, var(--accent-dim), var(--purple-dim));
}

.dash-pass {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}

.dash-pass input {
  flex: 1;
  min-width: 180px;
  padding: 10px 14px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
}

.dash-pass-msg { margin-top: 10px; font-size: 13px; }

/* ── Badges ───────────────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2px;
  gap: 5px;
  /* CRM-style tonal chip: 1px border derived from the variant's own text
     colour, so every existing (and future) badge-* variant gets a matching
     border without per-variant rules. */
  border: 1px solid color-mix(in srgb, currentColor 28%, transparent);
}

.badge-success, .badge-on, .badge-ok, .badge-cr-ok, .badge-dlr-delivered, .b-delivered {
  background: var(--green-dim);
  color: var(--green);
}

.badge-failed, .badge-dlr-failed, .badge-dlr-not_delivered, .badge-cr-empty, .badge-empty, .b-not_delivered, .b-failed {
  background: var(--red-dim);
  color: var(--red);
}

.badge-blocked, .badge-off, .badge-cr-low {
  background: rgba(107, 122, 144, 0.12);
  color: var(--muted);
}

.badge-rejected, .badge-dlr-pending, .badge-low, .b-pending {
  background: var(--amber-dim);
  color: var(--amber);
}

.badge-global {
  background: var(--red-dim);
  color: var(--red);
}

.badge-user {
  background: var(--amber-dim);
  color: var(--amber);
}

.badge-aakash { background: var(--amber-dim); color: var(--amber); }
.badge-globalzms { background: rgba(109,40,217,0.12); color: var(--accent-h); }
.badge-sociair { background: var(--green-dim); color: var(--green); }
.badge-nestsms { background: rgba(236,72,153,0.12); color: #ec4899; }
.badge-sparrow { background: rgba(56,189,248,0.12); color: #38bdf8; }
.badge-custom { background: rgba(107,122,144,0.1); color: var(--muted); }

/* ── Buttons ──────────────────────────────────────────────────────────────────── */
.btn-primary {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  padding: 10px 20px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: all var(--transition);
  box-shadow: var(--shadow-xs);
  letter-spacing: 0.1px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

.btn-primary:hover {
  background: var(--accent-h);
  box-shadow: var(--shadow-sm);
}

.btn-primary:active { transform: scale(0.98); }

.btn-compact {
  padding: 8px 14px;
  font-size: 11px;
  border-radius: var(--radius-xs);
}

.btn-primary.btn-danger {
  background: var(--red);
  box-shadow: var(--shadow-xs);
}
.btn-primary.btn-danger:hover { background: color-mix(in srgb, var(--red) 85%, #000); }

.btn-primary.btn-warning {
  background: var(--amber);
  color: #ffffff;
  box-shadow: var(--shadow-xs);
}
.btn-primary.btn-warning:hover { background: color-mix(in srgb, var(--amber) 85%, #000); }

.btn-primary.btn-info {
  background: var(--cyan);
  color: #ffffff;
  box-shadow: var(--shadow-xs);
}
.btn-primary.btn-info:hover { background: color-mix(in srgb, var(--cyan) 85%, #000); }

.btn-secondary {
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 20px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: all var(--transition);
  box-shadow: var(--shadow-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

.btn-secondary:hover {
  background: var(--accent-light);
  border-color: var(--border-h);
  color: var(--accent);
}

.btn-sm {
  padding: 6px 12px;
  border-radius: var(--radius-xs);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: all var(--transition);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-decoration: none;
}

.btn-sm:hover { transform: translateY(-1px); opacity: 0.85; }

.btn-edit { background: rgba(109,40,217,0.15); color: var(--accent-h); }
.btn-del { background: var(--red-dim); color: var(--red); }
.btn-test { background: var(--green-dim); color: var(--green); }
.btn-topup { background: rgba(109,40,217,0.15); color: var(--accent-h); }
.btn-hist { background: var(--accent-light); color: var(--muted); border: 1px solid var(--border); }

.btn-solid-accent { background: var(--accent); color: #fff; border: none; }
.btn-solid-cyan { background: var(--cyan); color: #ffffff; border: none; }
.btn-solid-purple { background: var(--purple); color: #fff; border: none; }
.btn-solid-amber { background: var(--amber); color: #ffffff; border: none; }
.btn-solid-green { background: var(--green); color: #fff; border: none; }

.refresh-btn {
  font-size: 12px;
  color: var(--muted);
  background: var(--accent-light);
  border: 1px solid var(--border);
  padding: 7px 14px;
  border-radius: var(--radius-xs);
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: all var(--transition);
}

.refresh-btn:hover { color: var(--text); border-color: var(--border-h); }

/* ── Reusable card-grid components (used by admin + portal) ───────────────── */
.card {
  transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.card:hover {
  box-shadow: var(--shadow);
  border-color: var(--border-h);
}

/* Status pill with dot — e.g. Paid / Pending / Partial */
.status-pill {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 11px 4px 9px; border-radius: 20px;
  font-size: 11px; font-weight: 600;
  border: 1px solid transparent; flex: none;
}
.status-pill .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.status-pill.paid  { background: var(--green-dim); color: var(--green); border-color: rgba(52,211,153,.28); }
.status-pill.paid .dot  { background: var(--green); }
.status-pill.partial { background: var(--amber-dim); color: var(--amber); border-color: rgba(251,191,36,.28); }
.status-pill.partial .dot { background: var(--amber); }
.status-pill.pending { background: var(--red-dim); color: var(--red); border-color: rgba(248,113,113,.28); }
.status-pill.pending .dot { background: var(--red); }
.status-pill.on  { background: var(--green-dim); color: var(--green); border-color: rgba(52,211,153,.28); }
.status-pill.on .dot  { background: var(--green); box-shadow: 0 0 0 0 rgba(52,211,153,.5); }
.status-pill.off { background: rgba(107,122,144,0.10); color: var(--muted); border-color: var(--border); }
.status-pill.off .dot { background: var(--muted); }

/* Action buttons — icon + text, bordered, with hover lift */
.act-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 12px; font-weight: 600; line-height: 1;
  cursor: pointer; white-space: nowrap;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--bg-card, var(--card)); color: var(--text);
  transition: transform .15s, background .15s, border-color .15s, color .15s;
}
.act-btn:hover { border-color: var(--border-h); background: var(--accent-light); transform: translateY(-1px); }
.act-btn:active { transform: translateY(0); }
.act-btn:disabled { opacity: .4; cursor: not-allowed; transform: none; background: var(--bg-subtle); }
.act-btn.go      { color: var(--green); border-color: rgba(52,211,153,.30); }
.act-btn.go:hover{ background: var(--green-dim); border-color: var(--green); }
.act-btn.warn    { color: var(--amber); border-color: rgba(251,191,36,.30); }
.act-btn.warn:hover { background: var(--amber-dim); border-color: var(--amber); }
.act-btn.send    { color: var(--accent); border-color: var(--accent-light); }
.act-btn.send:hover { background: var(--accent-light); border-color: var(--accent); }
.act-btn.danger  { color: var(--red); border-color: rgba(248,113,113,.25); }
.act-btn.danger:hover { background: var(--red-dim); border-color: var(--red); }
.act-btn .ico { font-size: 13px; line-height: 1; }
.row-actions-sep { width: 1px; height: 20px; background: var(--border); margin: 0 1px; flex: none; }

/* Mini chip badge */
.chip-mini {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .3px;
  padding: 2px 8px; border-radius: 999px; vertical-align: middle;
  text-transform: uppercase;
  border: 1px solid color-mix(in srgb, currentColor 28%, transparent);
}

/* ── Chip (generic tonal pill — CRM badge tones) ─────────────────────────
   Usage: <span class="chip">…</span> with an optional tone class.
   Neutral by default; tones mirror the CRM's Badge variants. */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 600; line-height: 1.5;
  background: var(--bg-subtle); color: var(--muted);
  border: 1px solid var(--border);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip.brand   { background: var(--accent-dim); color: var(--accent);  border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.chip.success { background: var(--green-dim);  color: var(--green);   border-color: color-mix(in srgb, var(--green) 30%, transparent); }
.chip.danger  { background: var(--red-dim);    color: var(--red);     border-color: color-mix(in srgb, var(--red) 30%, transparent); }
.chip.gold    { background: var(--amber-dim);  color: var(--amber);   border-color: color-mix(in srgb, var(--amber) 30%, transparent); }
.chip.info    { background: var(--cyan-dim);   color: var(--cyan);    border-color: color-mix(in srgb, var(--cyan) 30%, transparent); }
.chip svg { flex: none; }

/* Interactive chips (toggles like weekday pickers) share the same body but
   advertise clickability and a brand-tinted "on" state. */
.chip-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 600; user-select: none; cursor: pointer;
  background: var(--bg-card); color: var(--muted);
  border: 1px solid var(--border);
  transition: all var(--transition);
}
.chip-toggle:hover { border-color: var(--border-h); color: var(--accent); background: var(--accent-light); }
.chip-toggle.on {
  background: var(--accent-dim); color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.btn-filter {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  padding: 9px 20px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  align-self: flex-end;
  white-space: nowrap;
  box-shadow: var(--shadow-xs);
  transition: all var(--transition);
}

.btn-filter:hover {
  background: var(--accent-h);
  box-shadow: var(--shadow-sm);
}

.btn-export {
  background: var(--accent-light);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 14px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-end;
  white-space: nowrap;
  transition: all var(--transition);
}

.btn-export:hover { color: var(--text); border-color: var(--border-h); }

/* ── Live Badge ───────────────────────────────────────────────────────────────── */
.live-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--green);
  font-weight: 600;
  padding: 6px 14px;
  background: rgba(52, 211, 153, 0.06);
  border-radius: 20px;
  border: 1px solid rgba(52, 211, 153, 0.12);
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  animation: pulse 2s ease-in-out infinite;
}

.pulse-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--green);
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.5); }
  50% { box-shadow: 0 0 0 6px rgba(52, 211, 153, 0); }
}

/* ── Forms ────────────────────────────────────────────────────────────────────── */
.form-card {
  background: var(--card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  margin-bottom: 28px;
  display: none;
  animation: slideDown 0.3s ease-out;
}

.form-card.open { display: block; }

@keyframes slideDown {
  from { opacity: 0; transform: translateY(-12px); }
  to { opacity: 1; transform: translateY(0); }
}

.form-card h2 {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 24px;
  letter-spacing: -0.2px;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-group label {
  font-size: 11px;
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.form-group input,
.form-group select,
.form-group textarea {
  padding: 10px 14px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  outline: none;
  transition: all var(--transition);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

.form-group textarea { resize: vertical; min-height: 60px; }
.form-full { grid-column: 1/-1; }

.form-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.form-section-title {
  font-size: 11px;
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  grid-column: 1/-1;
  border-top: 1px solid var(--border);
  padding-top: 18px;
  margin-top: 6px;
}

/* ── Filter Bar ───────────────────────────────────────────────────────────────── */
.filter-bar {
  background: var(--card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 22px;
  margin-bottom: 22px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-end;
}

.filter-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 130px;
}

.filter-group label {
  font-size: 10px;
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.filter-group input,
.filter-group select {
  padding: 9px 14px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  outline: none;
  transition: all var(--transition);
}

.filter-group input:focus,
.filter-group select:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

/* ── Inline Input (blacklist add form) ────────────────────────────────────────── */
.add-form {
  background: var(--card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 28px;
  display: flex;
  gap: 14px;
  align-items: flex-end;
  flex-wrap: wrap;
}

.filter-input {
  padding: 8px 14px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 12px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  outline: none;
  width: 240px;
  transition: all var(--transition);
}

.filter-input:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

/* ── Connection Status ────────────────────────────────────────────────────────── */
.conn-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
}

.cdot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}

.cdot-on {
  background: var(--green);
  animation: cpulse 2s ease-in-out infinite;
}

.cdot-off { background: #374151; }

@keyframes cpulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.5); }
  50% { box-shadow: 0 0 0 5px rgba(52, 211, 153, 0); }
}

/* ── IP & Bind Badges (connections) ───────────────────────────────────────────── */
.ip-badge {
  background: rgba(34, 211, 238, 0.08);
  color: var(--cyan);
  padding: 4px 10px;
  border-radius: 20px;
  font-weight: 500;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}

.bind-badge {
  padding: 4px 10px;
  border-radius: 20px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
}

.bind_transceiver { background: rgba(109,40,217,0.12); color: var(--accent-h); }
.bind_transmitter { background: var(--green-dim); color: var(--green); }
.bind_receiver { background: rgba(251,191,36,0.12); color: var(--amber); }

/* ── Toast ────────────────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 28px;
  right: 28px;
  padding: 14px 24px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 600;
  display: none;
  z-index: 9999;
  animation: toastIn 0.3s ease-out;
  box-shadow: 0 8px 32px rgba(26, 10, 46, 0.16);
  backdrop-filter: blur(12px);
}

@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px) scale(0.95); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.toast-ok {
  background: linear-gradient(135deg, rgba(52,211,153,0.9), rgba(34,197,94,0.9));
  color: #fff;
}

.toast-err {
  background: linear-gradient(135deg, rgba(248,113,113,0.9), rgba(239,68,68,0.9));
  color: #fff;
}

/* ── Success/Help Messages ─────────────────────────────────────────────────── */
.ok {
  background: var(--green-dim);
  border: 1px solid rgba(16, 185, 129, 0.25);
  color: var(--green);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 16px;
  display: none;
}

.help-text {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  display: block;
}

/* ── Error Messages ───────────────────────────────────────────────────────────── */
.err, .form-err {
  background: var(--red-dim);
  border: 1px solid rgba(248, 113, 113, 0.2);
  color: var(--red);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 16px;
  display: none;
}

.error-msg {
  background: var(--red-dim);
  border: 1px solid rgba(248, 113, 113, 0.2);
  color: var(--red);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  font-size: 13px;
  margin-bottom: 20px;
}

/* ── Code ─────────────────────────────────────────────────────────────────────── */
code {
  background: rgba(109, 40, 217, 0.08);
  padding: 3px 8px;
  border-radius: 6px;
  font-size: 12px;
  color: var(--accent-h);
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  border: 1px solid rgba(109, 40, 217, 0.1);
}

/* ── Empty State ──────────────────────────────────────────────────────────────── */
.empty {
  padding: 52px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
}

/* ── Pagination ───────────────────────────────────────────────────────────────── */
.pagination {
  padding: 18px 24px;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
  font-size: 13px;
  color: var(--muted);
}

.page-btn {
  background: var(--accent-light);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 14px;
  border-radius: var(--radius-xs);
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 12px;
  font-weight: 500;
  transition: all var(--transition);
}

.page-btn:hover { background: rgba(109, 40, 217, 0.08); border-color: var(--border-h); }
.page-btn:disabled { opacity: 0.3; cursor: default; pointer-events: none; }

/* ── Modal ────────────────────────────────────────────────────────────────────── */
.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(26, 10, 46, 0.55);
  backdrop-filter: blur(4px);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.modal-bg.open { display: flex; }

.modal {
  background: var(--card-solid);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  width: 440px;
  max-width: 95vw;
  box-shadow: var(--shadow-lg);
  animation: modalIn 0.25s ease-out;
}

@keyframes modalIn {
  from { opacity: 0; transform: scale(0.95) translateY(-10px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

.modal h3 {
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 24px;
  letter-spacing: -0.3px;
}

.modal-actions {
  display: flex;
  gap: 12px;
  margin-top: 12px;
}

.modal-err {
  color: var(--red);
  font-size: 12px;
  margin-top: 8px;
  display: none;
}

/* ── History Drawer ───────────────────────────────────────────────────────────── */
.hist-row td { background: var(--bg-subtle); padding: 0; }
.hist-inner { padding: 18px 22px; }
.hist-inner table { font-size: 12px; }
.hist-inner th { font-size: 10px; }
.hist-inner td { padding: 8px 12px; }

/* ── Analytics Controls ───────────────────────────────────────────────────────── */
.controls {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.ctrl-select, .ctrl-input {
  padding: 9px 14px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  outline: none;
  transition: all var(--transition);
}

.ctrl-select:focus, .ctrl-input:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

.btn-refresh {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  padding: 9px 20px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  box-shadow: var(--shadow-xs);
  transition: all var(--transition);
}

.btn-refresh:hover {
  background: var(--accent-h);
  box-shadow: var(--shadow-sm);
}

/* ── Charts ───────────────────────────────────────────────────────────────────── */
.charts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

.chart-card {
  background: var(--card);
  backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px;
}

.chart-full { grid-column: 1/-1; }

.chart-title {
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 22px;
  color: var(--text);
  letter-spacing: -0.2px;
}

.chart-wrap { position: relative; height: 240px; }

/* ── Route Breakdown Table ────────────────────────────────────────────────────── */
.route-table { width: 100%; border-collapse: collapse; margin-top: 12px; }
.route-table th { font-size: 10px; color: var(--muted); font-weight: 700; text-transform: uppercase; padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); letter-spacing: 0.5px; }
.route-table td { padding: 10px 12px; font-size: 13px; border-bottom: 1px solid var(--border); }
.route-table tr:last-child td { border-bottom: none; }

/* ── Actions Bar ──────────────────────────────────────────────────────────────── */
.action-bar, .actions { display: flex; gap: 8px; }

/* ── Test Result ──────────────────────────────────────────────────────────────── */
.test-result {
  margin-top: 14px;
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  display: none;
  white-space: pre-wrap;
  word-break: break-all;
  background: rgba(26, 10, 46, 0.12);
  border: 1px solid var(--border);
  color: var(--text);
  max-height: 140px;
  overflow-y: auto;
}

/* ── Login Page ───────────────────────────────────────────────────────────────── */
body.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  background-image:
    radial-gradient(ellipse at 30% 20%, rgba(109,40,217,0.12) 0%, transparent 60%),
    radial-gradient(ellipse at 70% 80%, rgba(168,85,247,0.08) 0%, transparent 50%);
}

body.login-page::before { display: none; }

.login-card {
  background: var(--card);
  backdrop-filter: blur(24px);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 52px 44px;
  width: 100%;
  max-width: 430px;
  box-shadow: 0 30px 80px rgba(26, 10, 46, 0.20);
  position: relative;
  overflow: hidden;
}

.login-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), var(--purple), transparent);
}

.login-card .logo {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 36px;
}

.login-card .logo-icon {
  width: 44px;
  height: 44px;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: 12px;
  display: block;
  object-fit: contain;
  padding: 6px;
  box-shadow: none;
}

.login-card .logo-text { font-size: 18px; font-weight: 800; }
.login-card .logo-sub { font-size: 12px; color: var(--muted); margin-top: 2px; font-weight: 500; }

.login-card h1 { font-size: 24px; font-weight: 800; letter-spacing: -0.5px; margin-bottom: 8px; color: var(--text-bright); }
.login-card p { font-size: 14px; color: var(--muted); margin-bottom: 32px; }

.login-card label {
  display: block;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 8px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.login-card input {
  width: 100%;
  padding: 13px 16px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: 10px;
  color: var(--text);
  font-size: 14px;
  outline: none;
  transition: all var(--transition);
  font-family: 'Plus Jakarta Sans', sans-serif;
}

.login-card input:focus {
  border-color: var(--accent);
  box-shadow: var(--ring);
}

.login-card .field { margin-bottom: 24px; }

.login-card button {
  width: 100%;
  padding: 14px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: all var(--transition);
  font-family: 'Plus Jakarta Sans', sans-serif;
  box-shadow: 0 4px 20px rgba(109, 40, 217, 0.25);
  margin-top: 4px;
}

.login-card button:hover {
  background: var(--accent-h);
  box-shadow: 0 6px 24px rgba(109, 40, 217, 0.35);
}

.login-card button:active { transform: scale(0.98); }

/* ── Page Load Animation ──────────────────────────────────────────────────────── */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

main { animation: fadeIn 0.4s ease-out; }

/* ── Misc ─────────────────────────────────────────────────────────────────────── */
.form-err { flex-basis: 100%; }

/* ── Sidebar Collapse + Mobile Responsive ─────────────────────────────────── */
/* Floating hamburger toggle. Injected by sidebar.js on every admin page so we
   don't have to edit each view's HTML. */
.sidebar-toggle {
  position: fixed;
  top: 14px; left: 14px;
  width: 40px; height: 40px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid var(--border);
  color: var(--accent);
  cursor: pointer;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow-sm);
  transition: background var(--transition), left .25s ease;
}
.sidebar-toggle:hover { background: var(--accent-light); }

.sidebar-backdrop {
  position: fixed; inset: 0;
  background: rgba(26, 10, 46, 0.50);
  z-index: 49;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
body.sidebar-open .sidebar-backdrop { opacity: 1; pointer-events: auto; }

aside { transition: transform .25s ease; }

/* ── Full-screen overlays vs. the sidebar ─────────────────────────────────────
   A dialog backdrop is `position: fixed; inset: 0`, so it spans the WHOLE
   viewport — including the 260px the sidebar occupies. Its flex-centred dialog
   therefore centres on the viewport, not on the content area, and ends up
   sitting under the nav.

   So when the sidebar is expanded, start overlays at its right edge: the dialog
   then centres in the space actually available and the nav stays visible and
   usable beside it. Collapsed (or on mobile, where the sidebar is itself an
   overlay) they go back to spanning everything.

   --overlay-left is read by the rules below; it is 0 unless a desktop-width
   viewport has the sidebar expanded. */
body { --overlay-left: 0px; }
@media (min-width: 901px) {
  body:not(.sidebar-collapsed) { --overlay-left: var(--sidebar-w, 260px); }
}

/* Covers both conventions in use: the two backdrop classes, and the inline
   `position:fixed;inset:0` form used across ~19 dialogs. The pair of attribute
   selectors is chained on purpose — matching `inset:0` alone would also catch
   absolutely-positioned fills inside cards and shove them sideways.
   `!important` is required to beat the inline `inset: 0`. */
.route-modal-backdrop,
.modal-overlay,
[style*="position:fixed"][style*="inset:0"],
[style*="position: fixed"][style*="inset: 0"] {
  left: var(--overlay-left) !important;
}

/* Exceptions that must keep covering the full viewport: the mobile nav scrim
   (it dims the page *for* the sidebar), and anything the sidebar itself renders
   — its combo-box menus are body-appended with computed coordinates. */
.sidebar-backdrop,
aside [style*="position:fixed"] {
  left: 0 !important;
}

/* Desktop collapse — hide sidebar, expand main. Toggle button stays visible. */
@media (min-width: 901px) {
  body.sidebar-collapsed aside { transform: translateX(-100%); }
  body.sidebar-collapsed main { margin-left: 0; max-width: 100%; }
  body.sidebar-collapsed .sidebar-toggle { left: 14px; }
  /* When expanded, float at the right edge of the 260 px sidebar */
  .sidebar-toggle { left: 222px; }
}

/* Mobile — sidebar slides in as overlay, main is full-width. */
@media (max-width: 900px) {
  .sidebar-toggle { left: 14px; }
  aside { transform: translateX(-100%); }
  body.sidebar-open aside { transform: translateX(0); }
  main {
    margin-left: 0 !important;
    padding: 64px 16px 24px;
    max-width: 100%;
  }
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 20px;
  }
  .page-header h1 { font-size: 20px; }
  .filter-bar, .form-actions {
    flex-wrap: wrap;
    gap: 8px;
  }
  /* Stat grids stack tighter */
  .stat-grid { grid-template-columns: 1fr 1fr !important; gap: 8px !important; }
  .form-grid, .fg { grid-template-columns: 1fr !important; gap: 12px !important; }
  /* Cards with horizontal content (lists, transaction rows) get a tiny inset */
  .card { padding: 14px; }
}

@media (max-width: 480px) {
  main { padding: 60px 10px 20px; }
  .stat-grid { grid-template-columns: 1fr !important; }
}

/* ═════════════════════════════════════════════════════════════════════════
   Comprehensive responsive defaults (added 2026-05).

   Most admin/portal views have lots of inline grid-template-columns,
   min-width values, and hardcoded modal sizes that don't collapse cleanly
   on phones. Rather than editing every file, these rules override the
   common offenders at small viewports — !important is intentional here
   because the things we're fighting are inline styles, which would
   otherwise win specificity.
   ═════════════════════════════════════════════════════════════════════════ */

/* Let flex/grid children shrink below their content size. Without this,
   long URLs / tokens / message-IDs inside an input or cell make the whole
   row blow out and trigger horizontal page scroll. */
input, textarea, select,
.form-group, .field, .fld,
.dg-row, .dg-val,
td, th { min-width: 0; }

/* Long unbroken strings inside content cards/badges wrap instead of
   pushing the container wider than the viewport. Code/pre are deliberately
   excluded — they have their own overflow-x: auto for horizontal scrolling
   so code formatting stays intact. */
.card, .section, .form-card, .vault-card, .archive-card, .doc-card,
.bill-row, .rank-card, .kpi, .stat-card, .result-banner,
.api-response, .api-key {
  min-width: 0;
  overflow-wrap: anywhere;
  word-wrap: break-word;
}
/* Inline code (not block) wraps. Block-level <pre> doesn't — it scrolls. */
:not(pre) > code { overflow-wrap: anywhere; word-wrap: break-word; }

/* Hard guarantee: nothing in <main> may exceed viewport width. Catches
   stray inline-width:600px modals/blocks before they force the page to
   scroll horizontally. */
main { overflow-x: hidden; }
main > * { max-width: 100%; }

@media (max-width: 768px) {
  /* Stat grids: snap to 2 cols regardless of inline grid-template-columns. */
  .stat-grid, .stats-grid {
    grid-template-columns: 1fr 1fr !important;
    gap: 10px !important;
  }
  /* Multi-column grids commonly authored with hardcoded repeat(N,1fr). */
  .bill-row { grid-template-columns: 1fr 1fr !important; }
  .rank-card { grid-template-columns: 40px 1fr !important; gap: 8px !important; }
  .grid-2, .topup-grid, .charts-grid { grid-template-columns: 1fr !important; }
  .docs-layout { grid-template-columns: 1fr !important; }
  /* Pay summary on invoice manager. */
  .pay-summary { grid-template-columns: 1fr !important; }
  /* Simulator's "1fr 2fr" panel split — stack on mobile. */
  .sim-layout, .two-pane { grid-template-columns: 1fr !important; }
  /* Action bars: wrap freely, full-width when stacked. */
  .form-actions, .modal-actions, .action-row {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  /* Filter bars / search bars: respect viewport even when inline min-width
     was set higher than the viewport width. .filter-group is flex-direction:
     column, so `flex: 1 1 140px` on its inputs becomes a 140px+ HEIGHT, not
     width — that's the bug we hit. Only flex-size direct .filter-bar
     children; for inputs inside a .filter-group, just unblock the min-width
     and let them be normal-height. */
  .filter-bar > input, .filter-bar > select {
    min-width: 0 !important;
    flex: 1 1 140px;
  }
  .filter-group input, .filter-group select { min-width: 0 !important; width: 100%; }
  /* form-group children carry inline min-width:200-250px from pre-mobile
     layouts in lots of pages. Drop the floor everywhere on phones so a
     single form-group never exceeds the viewport — but DON'T force each
     one to 100% width: that creates a tall stack of "card-like" rows.
     Instead use a flex-basis of ~150px so 2 fit per row on most phones
     (Status + DLR, From + To, etc.) and wrap naturally when they can't. */
  .form-group, .filter-group, .field, .fld { min-width: 0 !important; }
  .add-form .form-group,
  .filter-bar .form-group,
  .filter-bar .filter-group,
  .page-header .form-group {
    flex: 1 1 140px !important;
    max-width: 100% !important;
  }
  /* Inputs inside these go full-width within their cell. */
  .add-form input, .add-form select, .add-form textarea,
  .filter-bar input, .filter-bar select,
  .page-header .form-group input, .page-header .form-group select { width: 100%; }
  /* Page-header right-side flex rows (refresh + form-groups) wrap. */
  .page-header > div { flex-wrap: wrap; }
  /* Tighter table cell padding so 4–5 column tables still fit. */
  td, th { padding: 8px 10px !important; }
  /* Modals: full-width minus a tiny margin. Catches both convention
     (.modal) and the per-page "[id$=-modal] > div" pattern used in
     users.html / admin-billing.html / billing.html. */
  .modal,
  [id$="-modal"] > div,
  [id*="modal"] > div[style*="border-radius"] {
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
    padding: 18px !important;
  }
  /* Dashboard credits-popover: don't insist on being 340px wide. */
  .credits-popover {
    min-width: 0 !important;
    max-width: calc(100vw - 32px) !important;
    left: 0 !important;
  }
  /* Card header: title + actions stack rather than overflow. */
  .card-header { flex-wrap: wrap; gap: 8px; padding: 16px 18px; }
}

@media (max-width: 480px) {
  /* Single-column for everything stat-like. */
  .stat-grid, .stats-grid { grid-template-columns: 1fr !important; }
  .bill-row { grid-template-columns: 1fr !important; gap: 6px !important; }
  /* Page-header CTA buttons stretch to full-width when they wrap below
     the title — usually a "+ Add User" / "+ Add Route" pattern. */
  .page-header .btn-primary,
  .page-header .btn-secondary { width: 100%; }
  /* Card chrome: tighten further. */
  .card { padding: 12px !important; }
  .card-header { padding: 12px 14px !important; }
  /* Form inputs: bump font slightly so iOS doesn't auto-zoom on focus. */
  .form-group input, .form-group textarea, .form-group select,
  .fld input, .fld textarea, .fld select { font-size: 16px; }
  /* Modal: edge-to-edge minus 8px, no padding shock. */
  .modal,
  [id$="-modal"] > div { width: calc(100vw - 16px) !important; padding: 14px !important; }
}

/* ═════════════════════════════════════════════════════════════════════════════
   Premium primitives — added in 2026-05 design refresh.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Skeleton Loader ───────────────────────────────────────────────────────── */
@keyframes skeletonShimmer {
  0%   { background-position: -200px 0; }
  100% { background-position: calc(200px + 100%) 0; }
}
.skel {
  display: inline-block;
  background: linear-gradient(90deg,
    var(--accent-light) 0%,
    #ffffff 40%,
    var(--accent-light) 80%);
  background-size: 200px 100%;
  background-repeat: no-repeat;
  border-radius: 6px;
  animation: skeletonShimmer 1.4s ease-in-out infinite;
  vertical-align: middle;
}
.skel-line { display: block; height: 12px; width: 100%; margin: 6px 0; }
.skel-line.sm { height: 10px; width: 60%; }
.skel-line.lg { height: 18px; width: 40%; }
.skel-pill { display: inline-block; height: 20px; width: 70px; border-radius: 10px; }
.skel-circle { width: 32px; height: 32px; border-radius: 50%; display: inline-block; }
tr.skel-row td { padding: 14px 18px; }

/* ── Sticky Table Header ──────────────────────────────────────────────────── */
.table-sticky thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
}

/* ── Tabs ─────────────────────────────────────────────────────────────────── */
.tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: 18px;
  overflow-x: auto;
}
.tab {
  flex: 1;
  padding: 9px 16px;
  border-radius: var(--radius-xs);
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.2px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  white-space: nowrap;
  transition: all var(--transition);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.tab:hover { color: var(--text); }
.tab.active {
  /* shadcn segmented-control: the active tab is a raised card, not a tint. */
  background: var(--bg-card);
  color: var(--accent-h);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border);
}
.tab-panel { display: none; animation: fadeIn 0.25s ease-out; }
.tab-panel.active { display: block; }
.tab-count {
  background: rgba(109, 40, 217, 0.08);
  color: var(--muted);
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
}

/* ── Empty State (rich) ───────────────────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 64px 24px;
  color: var(--muted);
}
.empty-state .icon {
  font-size: 44px;
  margin-bottom: 14px;
  opacity: 0.7;
  display: block;
  filter: grayscale(0.2);
}
.empty-state .title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 6px;
}
.empty-state .desc {
  font-size: 13px;
  color: var(--muted);
  max-width: 320px;
  margin: 0 auto 16px;
  line-height: 1.5;
}

/* ── Sparkline ────────────────────────────────────────────────────────────── */
.spark {
  display: block;
  width: 100%;
  height: 32px;
  margin-top: 10px;
  opacity: 0.85;
}
.spark path.line { fill: none; stroke: var(--accent-h); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.spark path.area { fill: url(#sparkGrad); opacity: 0.35; }
.spark.green path.line { stroke: var(--green); }
.spark.red   path.line { stroke: var(--red); }
.spark.cyan  path.line { stroke: var(--cyan); }
.spark.amber path.line { stroke: var(--amber); }

/* ── KPI Card (premium variant of stat-card) ──────────────────────────────── */
.kpi {
  background: linear-gradient(160deg, var(--bg-card) 0%, var(--bg-subtle) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  position: relative;
  overflow: hidden;
  transition: all var(--transition);
}
.kpi:hover { border-color: var(--border-h); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi::after {
  content: '';
  position: absolute;
  top: 0; right: 0;
  width: 60px; height: 60px;
  background: var(--kpi-glow, var(--accent-glow));
  filter: blur(40px);
  opacity: 0.4;
  pointer-events: none;
}
.kpi-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.kpi-label { font-size: 11px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; }
.kpi-icon { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; background: var(--accent-light); }
.kpi-value { font-size: 28px; font-weight: 800; line-height: 1; letter-spacing: -0.7px; }
.kpi-value.sm { font-size: 18px; letter-spacing: -0.3px; }
.kpi-delta { font-size: 11px; color: var(--muted); margin-top: 6px; font-weight: 500; }
.kpi-delta.up { color: var(--green); }
.kpi-delta.down { color: var(--red); }
.kpi.accent { --kpi-glow: rgba(109,40,217,0.35); }
.kpi.green  { --kpi-glow: rgba(16,185,129,0.30); }
.kpi.red    { --kpi-glow: rgba(239,68,68,0.30); }
.kpi.amber  { --kpi-glow: rgba(245,158,11,0.30); }
.kpi.cyan   { --kpi-glow: rgba(6,182,212,0.30); }
.kpi.purple { --kpi-glow: rgba(168,85,247,0.30); }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}

/* ── Progress Bar ─────────────────────────────────────────────────────────── */
.progress {
  height: 6px;
  background: rgba(109, 40, 217, 0.06);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 8px;
}
.progress > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--purple));
  transition: width 0.4s ease;
}
.progress.green > span { background: linear-gradient(90deg, var(--green), #34d399); }
.progress.red > span { background: linear-gradient(90deg, var(--red), #f87171); }
.progress.amber > span { background: linear-gradient(90deg, var(--amber), #fbbf24); }

/* ── Section Group (for grouped settings) ─────────────────────────────────── */
.section-group { margin-bottom: 28px; }
.section-group-title {
  font-size: 11px;
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  margin: 0 0 12px 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.section-group-title::before {
  content: '';
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: linear-gradient(to bottom, var(--accent), var(--purple));
}

/* ── Copy Button (inline, for code blocks) ────────────────────────────────── */
.copy-btn {
  background: var(--accent-light);
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: all var(--transition);
}
.copy-btn:hover { color: var(--text); border-color: var(--border-h); background: rgba(109, 40, 217, 0.08); }
.copy-btn.copied { color: var(--green); border-color: rgba(16,185,129,0.3); background: rgba(16,185,129,0.06); }

/* ── Code block wrapper with copy button ──────────────────────────────────── */
.code-wrap { position: relative; }
.code-wrap .copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
}

/* ── TOC (table of contents, sticky on api docs) ──────────────────────────── */
.toc {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  position: sticky;
  top: 24px;
  align-self: flex-start;
  font-size: 13px;
}
.toc h4 { font-size: 11px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
.toc a {
  display: block;
  color: var(--muted);
  text-decoration: none;
  padding: 6px 8px;
  border-radius: 6px;
  margin-bottom: 2px;
  transition: all var(--transition);
}
.toc a:hover { color: var(--text); background: var(--bg-subtle); }
.toc a.active { color: var(--accent-h); background: rgba(109,40,217,0.08); font-weight: 600; }

/* ── Inline KPI (for tooltips, mini stats) ────────────────────────────────── */
.inline-kpi {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--accent-light);
  font-size: 12px;
}
.inline-kpi .v { font-weight: 700; color: var(--text); }
.inline-kpi .l { color: var(--muted); font-size: 10px; }

/* ── Universal table horizontal scroll ────────────────────────────────────── */
/* Tables anywhere will overflow into a scroll container created by sidebar.js
   so they never crush. Style the wrapper here. */
.table-scroll {
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
  margin: 0 -2px;
}
.table-scroll table { min-width: 100%; }
.table-scroll::-webkit-scrollbar { height: 10px; }
.table-scroll::-webkit-scrollbar-track { background: var(--bg-subtle); }
.table-scroll::-webkit-scrollbar-thumb { background: rgba(109, 40, 217, 0.18); border-radius: 6px; }
.table-scroll::-webkit-scrollbar-thumb:hover { background: rgba(109, 40, 217, 0.32); }
@media (max-width: 1100px) {
  .table-scroll table { min-width: 900px; }
  .table-scroll th, .table-scroll td { white-space: nowrap; }
}

/* ═════════════════════════════════════════════════════════════════════════════
   Form-control refresh — 2026-07 (styling aligned with the Chairlyo CRM's
   shadcn/new-york components: custom select chevrons, searchable comboboxes,
   icon search fields, calmer date inputs). Fonts and brand hue unchanged.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Native selects: replace the OS arrow with a Lucide chevron ──────────────
   Scoped to class-based selects whose background theme.css already owns —
   inline-styled selects keep their native arrow (their inline `background`
   would erase ours and leave no affordance at all). These longhands
   intentionally come AFTER the earlier `background:` shorthands. */
.form-group select,
.filter-group select,
.ctrl-select,
.dash-pass select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%235a4f70' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 15px;
  padding-right: 32px;
  cursor: pointer;
}
html[data-theme="dark"] .form-group select,
html[data-theme="dark"] .filter-group select,
html[data-theme="dark"] .ctrl-select,
html[data-theme="dark"] .dash-pass select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.form-group select:hover,
.filter-group select:hover,
.ctrl-select:hover { border-color: var(--border-h); }
select:disabled { opacity: 0.55; cursor: not-allowed; }

/* ── Inputs: gentle hover affordance (matches the CRM's border-input feel) ── */
.form-group input:hover:not(:focus),
.form-group textarea:hover:not(:focus),
.filter-group input:hover:not(:focus),
.ctrl-input:hover:not(:focus),
.filter-input:hover:not(:focus) { border-color: var(--border-h); }

/* ── Date / time fields ──────────────────────────────────────────────────── */
input[type="date"], input[type="time"],
input[type="datetime-local"], input[type="month"] {
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.55;
  border-radius: 4px;
  transition: opacity var(--transition);
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator,
input[type="month"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }

/* ── Checkboxes & radios: brand accent, consistent size ─────────────────── */
input[type="checkbox"], input[type="radio"] {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
  cursor: pointer;
}

/* ── Check row — a bordered, clickable checkbox tile that aligns with the
     height of sibling inputs (replaces ad-hoc inline-styled checkbox rows) ── */
.check-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
  user-select: none;
}
.check-row:hover { border-color: var(--border-h); }
.check-row:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-dim);
}
.check-row input[type="checkbox"] { width: 15px; height: 15px; margin: 0; flex: none; }
.check-row span { font-size: 13px; color: var(--text); line-height: 1.4; }

/* ── File inputs: styled picker button + dashed drop-zone feel ───────────── */
input[type="file"] {
  padding: 8px 10px;
  background: var(--input-bg);
  border: 1px dashed var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 12.5px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  cursor: pointer;
  transition: border-color var(--transition);
  width: 100%;
}
input[type="file"]:hover { border-color: var(--border-h); }
input[type="file"]::file-selector-button {
  background: var(--accent-light);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  border-radius: 7px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  font-family: 'Plus Jakarta Sans', sans-serif;
  cursor: pointer;
  margin-right: 12px;
  transition: all var(--transition);
}
input[type="file"]::file-selector-button:hover {
  background: var(--accent);
  color: #fff;
}

/* ── Form footer actions: separate from the field area ───────────────────── */
.form-actions {
  border-top: 1px solid var(--border);
  padding-top: 18px;
}

/* ── Icon search fields ──────────────────────────────────────────────────────
   sidebar.js adds .input-search-icon to inputs whose placeholder used the 🔍
   emoji (and strips the emoji). !important beats the inline `background:`/
   `padding:` most of those inputs carry. */
.input-search-icon {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239088a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: 12px center !important;
  background-size: 14px !important;
  padding-left: 36px !important;
}
html[data-theme="dark"] .input-search-icon {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E") !important;
}

/* Datalist-backed search-and-select fields (sidebar.js .dl-combo-input):
   right-side chevron so they read as dropdowns, not free-text inputs. */
.dl-combo-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239088a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 10px center !important;
  background-size: 15px !important;
  padding-right: 32px !important;
  cursor: pointer;
}
html[data-theme="dark"] .dl-combo-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important;
}

/* ── Searchable combobox (progressive enhancement of big <select>s) ─────────
   Markup built by sidebar.js:
     <button class="combo-trigger"><span class="combo-label">…</span> ⌄</button>
     <div class="combo-menu"> <div class="combo-search">🔍 <input></div>
       <ul class="combo-list"><li><button class="combo-opt">…✓</button></li></ul>
     </div>  (menu is portaled to <body> and fixed-positioned)               */
.combo-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  /* No width:100% — column containers (.form-group etc.) stretch flex
     children automatically, and inside horizontal filter rows the trigger
     should size to its label like a native select did. */
  min-width: 110px;
  max-width: 100%;
  padding: 10px 12px;
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--transition), box-shadow var(--transition);
  box-shadow: none;
}
.combo-trigger:hover { border-color: var(--border-h); }
.combo-trigger.open,
.combo-trigger:focus-visible { border-color: var(--accent); box-shadow: var(--ring); outline: none; }
.combo-trigger:disabled { opacity: 0.55; cursor: not-allowed; }
.combo-trigger .combo-label {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo-trigger .combo-label.placeholder { color: var(--muted2); }
.combo-trigger > svg { flex: none; color: var(--muted2); }

.combo-menu {
  position: fixed;
  z-index: 1000;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: comboIn 0.12s ease-out;
}
@keyframes comboIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.combo-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border-bottom: 1px solid var(--border);
  color: var(--muted2);
}
.combo-search input {
  flex: 1;
  min-width: 0;
  height: 38px;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
}
.combo-search input:focus,
.combo-search input:focus-visible { box-shadow: none; border: none; }
.combo-list {
  max-height: 260px;
  overflow-y: auto;
  padding: 4px;
  margin: 0;
  list-style: none;
}
.combo-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--text);
  font-size: 13px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  text-align: left;
  cursor: pointer;
}
.combo-opt .combo-opt-label {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo-opt.active { background: var(--accent-dim); color: var(--accent); }
.combo-opt > svg { flex: none; color: var(--accent); }
.combo-empty {
  padding: 22px 12px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
