/* ==========================================================================
   LeadBox app styles.

   Design language is adapted (not imported) from the Brevibot HQ dashboard:
   deep navy canvas, surface-step cards, one cyan-violet accent used sparingly,
   red reserved for danger. Same token approach: CSS custom properties, dark as
   the default with a full light theme, [data-theme] on <html> switches them,
   the OS preference is the default (set by the boot script in index.html).

   This app is MOBILE-FIRST. The base styles target a phone: a fixed bottom tab
   bar, single-column content, big touch targets. At >=900px we switch to a left
   sidebar and multi-column layouts. There must be no horizontal scroll at any
   width, and every tap target is at least 44px.

   House rule: no em dashes anywhere (copy, comments, strings). Commas and colons
   instead. Aiden may extend this file, so sections are labelled and commented.
   ========================================================================== */

/* ----------------------------------------------------------------- tokens -- */
:root {
  --canvas: #0a0d16;
  --canvas-2: #0b0e1a;
  --card: #11151f;
  --card-2: #131826;
  --card-3: #182034;
  --border: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.11);
  --text: #e8ecf4;
  --text-muted: #8b94a7;
  --text-dim: #5c6579;
  --accent: #22d3ee;
  --accent-2: #8b5cf6;
  --accent-grad: linear-gradient(135deg, #22d3ee, #8b5cf6);
  --accent-soft: rgba(34, 211, 238, 0.12);
  --ok: #22c55e;
  --ok-soft: rgba(34, 197, 94, 0.13);
  --warn: #f59e0b;
  --warn-soft: rgba(245, 158, 11, 0.13);
  --danger: #f87171;
  --danger-strong: #ef4444;
  --danger-soft: rgba(239, 68, 68, 0.12);
  --info: #60a5fa;
  --info-soft: rgba(96, 165, 250, 0.13);
  --violet-soft: rgba(139, 92, 246, 0.14);
  --shadow-card: none;
  --shadow-pop: 0 18px 50px rgba(0, 0, 0, 0.5);
  --glow: 0 0 24px rgba(34, 211, 238, 0.18);
  --radius: 14px;
  --radius-lg: 18px;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", Inter, "Segoe UI", Roboto, sans-serif;

  /* Lead status palette. Each status maps to a chip colour, reused everywhere
     (list chips, filter chips, detail selector, charts). */
  --st-new: #22d3ee;
  --st-contacted: #60a5fa;
  --st-quoted: #f59e0b;
  --st-won: #22c55e;
  --st-lost: #f87171;
  --st-spam: #8b94a7;

  /* Safe-area insets. Default to 0 so non-notched devices are unaffected. The
     env() values kick in on iPhones with a notch/home indicator. */
  --sa-top: env(safe-area-inset-top, 0px);
  --sa-bottom: env(safe-area-inset-bottom, 0px);
  --sa-left: env(safe-area-inset-left, 0px);
  --sa-right: env(safe-area-inset-right, 0px);

  /* Height of the mobile bottom tab bar (excluding the safe-area padding). */
  --tabbar-h: 58px;
}

[data-theme="light"] {
  --canvas: #eef1f7;
  --canvas-2: #e9edf5;
  --card: #ffffff;
  --card-2: #f4f6fb;
  --card-3: #eceff7;
  --border: rgba(20, 30, 60, 0.07);
  --border-strong: rgba(20, 30, 60, 0.13);
  --text: #111827;
  --text-muted: #6b7280;
  --text-dim: #9aa2b1;
  --accent: #6d5ef2;
  --accent-2: #8b5cf6;
  --accent-grad: linear-gradient(135deg, #6d5ef2, #8b5cf6);
  --accent-soft: rgba(109, 94, 242, 0.1);
  --ok: #16a34a;
  --ok-soft: rgba(22, 163, 74, 0.11);
  --warn: #d97706;
  --warn-soft: rgba(217, 119, 6, 0.12);
  --danger: #dc2626;
  --danger-strong: #dc2626;
  --danger-soft: rgba(220, 38, 38, 0.09);
  --info: #2563eb;
  --info-soft: rgba(37, 99, 235, 0.09);
  --violet-soft: rgba(109, 94, 242, 0.1);
  --shadow-card: 0 8px 30px rgba(20, 30, 60, 0.08);
  --shadow-pop: 0 24px 60px rgba(20, 30, 60, 0.18);
  --glow: none;
  --st-new: #6d5ef2;
  --st-contacted: #2563eb;
  --st-quoted: #d97706;
  --st-won: #16a34a;
  --st-lost: #dc2626;
  --st-spam: #6b7280;
}

/* ------------------------------------------------------------------- base -- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background:
    radial-gradient(1100px 700px at 85% -10%, rgba(139, 92, 246, 0.09), transparent 60%),
    radial-gradient(900px 600px at -10% 110%, rgba(34, 211, 238, 0.05), transparent 55%),
    var(--canvas);
  background-attachment: fixed;
  min-height: 100vh;
  /* Prevent the whole page from ever scrolling sideways. */
  overflow-x: hidden;
  -webkit-tap-highlight-color: transparent;
}
[data-theme="light"] body {
  background:
    radial-gradient(1100px 700px at 85% -10%, rgba(109, 94, 242, 0.07), transparent 60%),
    var(--canvas);
  background-attachment: fixed;
}
h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -0.015em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }
img { display: block; }
::selection { background: rgba(139, 92, 246, 0.35); }

.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.grad-text {
  background: var(--accent-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

@keyframes pulse-dot { 0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.5); } 50% { box-shadow: 0 0 0 5px rgba(34, 197, 94, 0); } }
@keyframes fade-up { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Accessible focus ring, used everywhere via :focus-visible. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

/* ------------------------------------------------------------------ boot -- */
/* Shown before app.js has decided which view to render. Replaced on first paint. */
.boot {
  min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; color: var(--text-muted);
}
.boot-mark {
  width: 54px; height: 54px; border-radius: 16px;
  background: var(--accent-grad);
  display: grid; place-items: center;
  color: #fff; font-weight: 800; font-size: 26px;
  box-shadow: var(--glow);
}
.boot-text { font-size: 13.5px; }

/* =========================================================== app shell === */
/* On desktop the shell is a two-column grid: sidebar + main. On mobile the
   sidebar becomes a fixed bottom tab bar and main is full width. */
.app-shell { min-height: 100vh; }

.layout { min-height: 100vh; }

/* --- sidebar (desktop) / hidden on mobile ------------------------------- */
.sidebar {
  display: none; /* mobile: hidden, replaced by the bottom tab bar */
}

/* --- main content column ------------------------------------------------ */
.main {
  min-width: 0;
  /* Room for the fixed bottom tab bar plus the iPhone home indicator. */
  padding:
    calc(16px + var(--sa-top))
    calc(16px + var(--sa-right))
    calc(var(--tabbar-h) + var(--sa-bottom) + 24px)
    calc(16px + var(--sa-left));
}

/* --- app header (title + theme toggle) ---------------------------------- */
.appbar {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 18px;
}
.appbar-title { min-width: 0; flex: 1; }
.appbar-title h1 { font-size: 22px; letter-spacing: -0.02em; }
.appbar-title .sub { color: var(--text-muted); font-size: 13px; margin-top: 2px; }
.appbar-actions { display: flex; align-items: center; gap: 8px; flex: none; }

.icon-btn {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 12px;
  border: 1px solid var(--border-strong); background: var(--card);
  color: var(--text-muted); cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.icon-btn:hover { color: var(--text); border-color: var(--text-dim); }
.icon-btn svg { width: 20px; height: 20px; }

/* --- bottom tab bar (mobile) -------------------------------------------- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex;
  padding-bottom: var(--sa-bottom);
  background: color-mix(in srgb, var(--canvas-2) 88%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
}
.tabbar a {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; height: var(--tabbar-h);
  color: var(--text-dim); font-size: 10.5px; font-weight: 600;
  position: relative;
  transition: color 160ms ease;
}
.tabbar a svg { width: 22px; height: 22px; opacity: 0.9; }
.tabbar a span { letter-spacing: 0.01em; }
.tabbar a[aria-current="page"] { color: var(--accent); }
.tabbar a[aria-current="page"] svg { opacity: 1; }
/* Little pip above the active tab. */
.tabbar a[aria-current="page"]::before {
  content: ""; position: absolute; top: 6px;
  width: 5px; height: 5px; border-radius: 99px; background: var(--accent);
}

/* Brand row shown at the very bottom of the scrollable content on mobile. */
.brand-foot {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  margin-top: 26px; padding-top: 18px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
}
.brand-foot .powered-label { font-size: 11px; color: var(--text-dim); }
.brand-foot .brevibot-logo { height: 18px; width: auto; color: var(--text); }
.brand-foot:hover { color: var(--text); }

/* ------------------------------------------------------------------ cards -- */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.card-pad { padding: 18px 18px; }
.card-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.micro-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted);
}
.card-link { font-size: 13px; font-weight: 600; color: var(--accent); padding: 6px 0; }
.card-link:hover { text-decoration: underline; }
.lift { transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease; }
.lift:active { transform: scale(0.995); }

.stack { display: flex; flex-direction: column; gap: 14px; }
.section-gap { margin-top: 18px; }
.divider { height: 1px; background: var(--border); margin: 12px 0; }
.row { display: flex; align-items: center; gap: 10px; }
.spacer { flex: 1; }

/* ------------------------------------------------------------------ stats -- */
.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.stat {
  padding: 16px 16px; display: flex; flex-direction: column; gap: 3px;
  position: relative; overflow: hidden;
}
.stat-value {
  font-size: 30px; font-weight: 750; letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.stat-value.grad {
  background: var(--accent-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.stat-label { font-size: 12.5px; color: var(--text-muted); font-weight: 550; }
.stat-note { font-size: 11.5px; color: var(--text-dim); }

/* ------------------------------------------------------------------ chips -- */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 600;
  padding: 3px 9px; border-radius: 99px;
  background: var(--card-2); color: var(--text-muted);
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip .chip-dot { width: 6px; height: 6px; border-radius: 99px; background: currentColor; flex: none; }
/* Small inline variant, e.g. the "This device" marker in the device list. */
.chip-sm { font-size: 10.5px; padding: 1px 7px; vertical-align: 2px; }

/* Status chips: colour comes from the per-status token via a data attribute.
   We tint background and text off the same hue for a soft badge look. */
.chip.status { color: var(--sc, var(--text-muted)); background: color-mix(in srgb, var(--sc, var(--text-muted)) 15%, transparent); }
.st-new { --sc: var(--st-new); }
.st-contacted { --sc: var(--st-contacted); }
.st-quoted { --sc: var(--st-quoted); }
.st-won { --sc: var(--st-won); }
.st-lost { --sc: var(--st-lost); }
.st-spam { --sc: var(--st-spam); }

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px;
  border: 1px solid var(--border-strong);
  background: var(--card-2); color: var(--text);
  font-size: 14px; font-weight: 600;
  padding: 9px 16px; border-radius: 12px;
  cursor: pointer;
  transition: transform 140ms ease, background 140ms ease, border-color 140ms ease, filter 140ms ease;
}
.btn:hover { border-color: var(--text-dim); }
.btn:active { transform: scale(0.98); }
.btn.primary {
  background: var(--accent-grad); border-color: transparent; color: #fff;
  box-shadow: 0 4px 18px rgba(109, 94, 242, 0.35);
}
.btn.primary:hover { filter: brightness(1.08); }
.btn.danger { background: var(--danger-soft); border-color: transparent; color: var(--danger); }
.btn.ok { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.btn.ghost { background: transparent; }
.btn.sm { min-height: 38px; padding: 7px 13px; font-size: 13px; border-radius: 10px; }
.btn.block { width: 100%; }
.btn:disabled { opacity: 0.5; cursor: default; transform: none; filter: none; }
.btn svg { width: 18px; height: 18px; flex: none; }

/* Inline spinner for loading buttons. */
.spinner {
  width: 16px; height: 16px; border-radius: 99px;
  border: 2px solid rgba(255, 255, 255, 0.4); border-top-color: #fff;
  animation: spin 0.7s linear infinite; flex: none;
}
.btn:not(.primary) .spinner { border-color: var(--border-strong); border-top-color: var(--accent); }

/* ------------------------------------------------------------ form inputs -- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-size: 13px; font-weight: 600; color: var(--text); }
.input, textarea.input, select.input {
  width: 100%; font-family: inherit; font-size: 16px; /* 16px avoids iOS zoom on focus */
  background: var(--card-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: 12px;
  padding: 12px 14px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.input:focus, textarea.input:focus, select.input:focus {
  outline: none; border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.input::placeholder, textarea.input::placeholder { color: var(--text-dim); }
textarea.input { resize: vertical; min-height: 90px; line-height: 1.5; }
.input.bad { border-color: color-mix(in srgb, var(--danger-strong) 60%, transparent); }
.field-err { font-size: 12.5px; color: var(--danger); }

/* Search box with a leading icon. */
.search {
  position: relative; margin-bottom: 14px;
}
.search svg { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--text-dim); pointer-events: none; }
.search .input { padding-left: 42px; }

/* --------------------------------------------------------------- filters -- */
/* Horizontally scrollable chip row for status filters. Never wraps, never
   pushes the page wide (it scrolls inside itself). */
.filter-scroll {
  display: flex; gap: 8px; overflow-x: auto; margin-bottom: 14px;
  padding-bottom: 4px; scrollbar-width: none;
  /* Bleed to the screen edges so the last chip is reachable, then pad back. */
  margin-left: calc(-1 * (16px + var(--sa-left))); margin-right: calc(-1 * (16px + var(--sa-right)));
  padding-left: calc(16px + var(--sa-left)); padding-right: calc(16px + var(--sa-right));
}
.filter-scroll::-webkit-scrollbar { display: none; }
.filter-chip {
  flex: none;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600;
  border: 1px solid var(--border-strong); border-radius: 99px;
  background: transparent; color: var(--text-muted);
  padding: 8px 14px; cursor: pointer; white-space: nowrap;
  transition: color 150ms ease, background 150ms ease, border-color 150ms ease;
}
.filter-chip .cnt {
  font-size: 11.5px; font-variant-numeric: tabular-nums;
  background: var(--card-2); color: var(--text-muted);
  border-radius: 99px; padding: 0 7px; min-width: 20px; text-align: center;
}
.filter-chip.on { background: var(--card); color: var(--text); border-color: var(--text-dim); }
.filter-chip.on .cnt { background: var(--accent-soft); color: var(--accent); }

/* --------------------------------------------------------------- lead list -- */
.lead-list { display: flex; flex-direction: column; gap: 10px; }
.lead-card {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px; cursor: pointer;
}
.lead-avatar {
  width: 42px; height: 42px; border-radius: 13px; flex: none;
  display: grid; place-items: center;
  background: var(--card-2); border: 1px solid var(--border-strong);
  color: var(--accent); font-weight: 700; font-size: 16px;
  text-transform: uppercase;
}
.lead-body { flex: 1; min-width: 0; }
.lead-top { display: flex; align-items: center; gap: 8px; }
.lead-name { font-weight: 650; font-size: 15px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-time { font-size: 12px; color: var(--text-dim); flex: none; }
.lead-snippet {
  font-size: 13px; color: var(--text-muted); margin-top: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lead-meta { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.lead-contact { font-size: 12px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --------------------------------------------------------------- lead detail -- */
.detail-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 16px; }
.detail-name { font-size: 21px; letter-spacing: -0.02em; }
.detail-sub { color: var(--text-muted); font-size: 13.5px; margin-top: 3px; }

/* Big Call / WhatsApp / Email action row. */
.actions-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.action-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-height: 72px; border-radius: var(--radius);
  border: 1px solid var(--border-strong); background: var(--card);
  color: var(--text); font-size: 12.5px; font-weight: 600;
  cursor: pointer; text-align: center;
  transition: transform 140ms ease, border-color 140ms ease, background 140ms ease;
}
.action-btn svg { width: 22px; height: 22px; }
.action-btn:active { transform: scale(0.97); }
.action-btn.call { color: var(--info); }
.action-btn.wa { color: var(--ok); }
.action-btn.email { color: var(--accent-2); }
[data-theme="light"] .action-btn.email { color: #6d5ef2; }
.action-btn.disabled {
  opacity: 0.45; cursor: default; color: var(--text-dim);
  pointer-events: none;
}
.action-hint { font-size: 11px; color: var(--text-dim); font-weight: 500; }

/* Status selector: the six statuses as tappable pills. */
.status-select { display: flex; flex-wrap: wrap; gap: 8px; }
.status-opt {
  font-size: 13px; font-weight: 600;
  border: 1px solid var(--border-strong); border-radius: 99px;
  background: transparent; color: var(--text-muted);
  padding: 8px 14px; cursor: pointer; min-height: 40px;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 150ms ease, background 150ms ease, border-color 150ms ease;
}
.status-opt .chip-dot { width: 7px; height: 7px; border-radius: 99px; background: var(--sc, var(--text-dim)); flex: none; }
.status-opt.on {
  color: var(--sc); background: color-mix(in srgb, var(--sc) 15%, transparent);
  border-color: color-mix(in srgb, var(--sc) 45%, transparent);
}

/* Notes autosave indicator. */
.save-state { font-size: 12px; color: var(--text-dim); display: inline-flex; align-items: center; gap: 6px; min-height: 18px; }
.save-state.saving { color: var(--text-muted); }
.save-state.saved { color: var(--ok); }

/* Meta block on the detail page. */
.meta-list { display: flex; flex-direction: column; gap: 0; }
.meta-row { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.meta-row:last-child { border-bottom: 0; }
.meta-row .k { color: var(--text-muted); flex: none; width: 96px; }
.meta-row .v { color: var(--text); min-width: 0; word-break: break-word; }

.message-box {
  font-size: 14.5px; line-height: 1.6; color: var(--text);
  white-space: pre-wrap; word-break: break-word;
}

/* ------------------------------------------------------------------ charts -- */
/* Inline SVG bar charts drawn by js/charts.js. We keep the styling here so the
   JS only sets geometry and class names. */
.chart { width: 100%; display: block; overflow: visible; }
.chart .bar { transition: height 300ms ease, y 300ms ease; }
.chart .bar-new { fill: var(--accent); }
.chart .bar-accept { fill: var(--ok); }
.chart .bar-reject { fill: var(--danger); }
.chart .bar-visit { fill: var(--accent-2); }
[data-theme="light"] .chart .bar-visit { fill: #6d5ef2; }
.chart .axis { fill: var(--text-dim); font-size: 10px; font-variant-numeric: tabular-nums; }
.chart .grid { stroke: var(--border); stroke-width: 1; }
/* Axis labels live in HTML under the (stretched) SVG so they never distort. */
.chart-wrap { display: block; }
.chart-axis { display: flex; justify-content: space-between; margin-top: 6px; padding: 0 1px; }
.chart-axis.one { justify-content: center; }
.chart-axis span { font-size: 11px; color: var(--text-dim); font-variant-numeric: tabular-nums; line-height: 1; }
.chart-legend { display: flex; gap: 14px; margin-top: 10px; flex-wrap: wrap; }
.chart-legend .lg { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); }
.chart-legend .sw { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* Top-list rows (top pages / referrers / countries on analytics). */
.rank-list { display: flex; flex-direction: column; gap: 2px; }
.rank-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.rank-row:last-child { border-bottom: 0; }
.rank-row .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-row .count { font-variant-numeric: tabular-nums; color: var(--text-muted); font-weight: 600; flex: none; }

/* --------------------------------------------------------------- setup rows -- */
.setup-row { display: flex; align-items: flex-start; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--border); }
.setup-row:last-child { border-bottom: 0; }
.setup-row .body { flex: 1; min-width: 0; }
.setup-row .name { font-size: 14px; font-weight: 600; }
.setup-row .sub { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; line-height: 1.5; }
.setup-row .action { flex: none; }

.device-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.device-row:last-child { border-bottom: 0; }
.device-icon { width: 36px; height: 36px; border-radius: 11px; flex: none; display: grid; place-items: center; background: var(--card-2); border: 1px solid var(--border); color: var(--text-muted); }
.device-icon svg { width: 18px; height: 18px; }
.device-body { flex: 1; min-width: 0; }
.device-name { font-size: 13.5px; font-weight: 600; }
.device-sub { font-size: 12px; color: var(--text-dim); }

/* Numbered install steps. */
.steps { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; counter-reset: step; }
.step { display: flex; gap: 12px; align-items: flex-start; font-size: 13.5px; color: var(--text-muted); line-height: 1.5; }
.step .n {
  flex: none; width: 24px; height: 24px; border-radius: 99px;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  background: var(--accent-soft); color: var(--accent);
}
.step b { color: var(--text); font-weight: 650; }

.callout {
  font-size: 13px; line-height: 1.55; color: var(--text-muted);
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
  border-radius: var(--radius); padding: 12px 14px; margin-top: 12px;
}
.callout strong { color: var(--text); font-weight: 650; }
.callout.warn { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 32%, transparent); }

/* ------------------------------------------------------------- empty state -- */
.empty {
  padding: 40px 20px; text-align: center; color: var(--text-dim);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.empty .e-ico {
  width: 52px; height: 52px; border-radius: 16px; margin-bottom: 4px;
  display: grid; place-items: center;
  background: var(--card-2); border: 1px solid var(--border);
  color: var(--text-muted);
}
.empty .e-ico svg { width: 26px; height: 26px; }
.empty .e-title { font-size: 15px; font-weight: 600; color: var(--text); }
.empty .e-sub { font-size: 13px; max-width: 320px; line-height: 1.55; }

/* Skeleton loading placeholder. */
.skeleton {
  background: linear-gradient(90deg, var(--card-2), var(--card-3), var(--card-2));
  background-size: 200% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
  border-radius: 10px;
}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.sk-line { height: 14px; margin: 8px 0; }
.sk-card { height: 78px; margin-bottom: 10px; border-radius: var(--radius); }

/* --------------------------------------------------------------- login -- */
.login-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: calc(24px + var(--sa-top)) 20px calc(24px + var(--sa-bottom));
}
.login-card {
  width: 100%; max-width: 380px;
  padding: 28px 24px 24px;
}
.login-brand { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-bottom: 22px; text-align: center; }
.login-mark {
  width: 56px; height: 56px; border-radius: 16px;
  background: var(--accent-grad);
  display: grid; place-items: center;
  color: #fff; font-weight: 800; font-size: 27px;
  box-shadow: var(--glow);
}
.login-title { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; }
.login-sub { font-size: 13px; color: var(--text-muted); }
.login-foot { display: flex; align-items: center; justify-content: center; gap: 7px; margin-top: 22px; color: var(--text-muted); }
.login-foot .powered-label { font-size: 11px; color: var(--text-dim); }
.login-foot .brevibot-logo { height: 17px; width: auto; color: var(--text); }
.login-err {
  font-size: 13px; color: var(--danger); text-align: center;
  background: var(--danger-soft); border-radius: 10px; padding: 9px 12px;
  margin-bottom: 14px;
}

/* ------------------------------------------------------------------ toast -- */
.toast {
  position: fixed; left: 50%;
  bottom: calc(var(--tabbar-h) + var(--sa-bottom) + 16px);
  transform: translateX(-50%) translateY(90px);
  max-width: calc(100vw - 32px);
  background: var(--card); border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-pop); border-radius: 12px;
  padding: 12px 18px; font-size: 13.5px; font-weight: 600;
  z-index: 90; transition: transform 260ms cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
}
.toast.show { transform: translateX(-50%) translateY(0); }
.toast.err { border-color: color-mix(in srgb, var(--danger-strong) 50%, transparent); color: var(--danger); }

/* ======================================================= desktop layout === */
/* At >=900px we switch to the HQ style: fixed left sidebar, wider content,
   multi-column grids, and the tab bar is hidden. */
@media (min-width: 900px) {
  .layout { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }

  .tabbar { display: none; }

  .sidebar {
    display: flex; flex-direction: column; gap: 4px;
    position: sticky; top: 0; height: 100vh;
    padding:
      calc(20px + var(--sa-top)) 14px calc(16px + var(--sa-bottom))
      calc(14px + var(--sa-left));
    border-right: 1px solid var(--border);
    background: color-mix(in srgb, var(--canvas-2) 72%, transparent);
    backdrop-filter: blur(14px);
    z-index: 40;
  }
  .side-logo { display: flex; align-items: center; gap: 10px; padding: 4px 8px 18px; }
  .side-logo .mark {
    width: 34px; height: 34px; border-radius: 10px;
    background: var(--accent-grad);
    display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 15px;
    box-shadow: var(--glow); flex: none;
  }
  .side-logo .name { font-weight: 700; font-size: 15.5px; letter-spacing: -0.01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .side-logo .tag { font-size: 11px; color: var(--text-muted); letter-spacing: 0.1em; text-transform: uppercase; margin-top: -2px; }

  .side-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
  .side-nav a {
    display: flex; align-items: center; gap: 11px;
    padding: 10px 12px; border-radius: 10px;
    color: var(--text-muted); font-weight: 500; font-size: 14px;
    transition: background 160ms ease, color 160ms ease;
  }
  .side-nav a svg { width: 18px; height: 18px; flex: none; opacity: 0.85; }
  .side-nav a:hover { background: var(--card-2); color: var(--text); }
  .side-nav a[aria-current="page"] { background: var(--accent-soft); color: var(--text); font-weight: 600; }
  .side-nav a[aria-current="page"] svg { color: var(--accent); opacity: 1; }

  .side-foot { display: flex; flex-direction: column; gap: 12px; padding: 12px 8px 0; border-top: 1px solid var(--border); }
  .side-foot .powered-link { display: flex; align-items: center; gap: 7px; color: var(--text-muted); transition: color 150ms ease; }
  .side-foot .powered-link:hover { color: var(--text); }
  .side-foot .powered-label { font-size: 11px; color: var(--text-dim); }
  .side-foot .brevibot-logo { height: 18px; width: auto; color: var(--text); }

  /* The mobile brand footer is redundant on desktop (it lives in the sidebar). */
  .brand-foot { display: none; }

  /* The appbar theme toggle exists for mobile, where the sidebar (and its
     toggle) is hidden. On desktop the sidebar toggle is visible, so hide the
     appbar one rather than showing two controls that do the same thing. */
  .appbar-actions { display: none; }

  .main {
    padding:
      calc(26px + var(--sa-top)) 32px calc(48px + var(--sa-bottom)) 32px;
    max-width: 1080px;
  }
  .appbar-title h1 { font-size: 26px; }

  .stat-grid { grid-template-columns: repeat(4, 1fr); }

  /* Two-column layouts for the overview and analytics. Children need
     min-width: 0 or a long unbreakable lead name expands its grid track past
     the viewport instead of letting the row's own ellipsis truncation work. */
  .grid-2 { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; align-items: start; }
  .grid-2-even { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
  .grid-2 > *, .grid-2-even > * { min-width: 0; }

  /* Overview: the chart is a full-width band above the latest-leads card (see
     overview.js), so give it a bit more height than the mobile default. */
  #chartCard .chart { min-height: 190px; height: 190px; }

  .toast { bottom: 26px; }

  .actions-row { max-width: 520px; }
}

/* Mid widths: keep 2-up stats readable. */
@media (min-width: 600px) and (max-width: 899px) {
  .stat-grid { grid-template-columns: repeat(4, 1fr); }
}

/* On single-column (mobile/tablet) the grid helpers are just stacks. */
@media (max-width: 899px) {
  .grid-2, .grid-2-even { display: flex; flex-direction: column; gap: 14px; }
}
