:root {
  color-scheme: light;
  /* Neutral foundation: cool slate rather than warm off-white/cream - the
     enterprise-standard ground for a data-dense product. Card surfaces are
     pure white so they lift off the slate page-plane without needing extra
     shadow to read as "layered". */
  --surface-1:      #ffffff;
  --page-plane:     #f8fafc; /* slate-50 */
  --text-primary:   #0f172a; /* slate-900 */
  --text-secondary: #475569; /* slate-600 */
  --text-muted:     #64748b; /* slate-500 - AA-legible on white, unlike slate-400 */
  --gridline:       #e2e8f0; /* slate-200 */
  --baseline:       #cbd5e1; /* slate-300 */
  --border:         #e2e8f0; /* slate-200 - subtle, low-contrast, solid (not alpha-black) */
  --series-1:       #2a78d6; /* blue - also the single interactive accent, see --accent below */
  --series-2:       #eb6834; /* orange */
  --series-3:       #1baf7a; /* aqua */
  --series-4:       #eda100; /* yellow */
  --series-5:       #e87ba4; /* magenta */
  --series-6:       #008300; /* green */
  --series-7:       #4a3aa7; /* violet */
  --series-8:       #e34948; /* red */
  /* Canonical interactive accent - one purposeful color, used for primary
     buttons, links, focus rings, active nav state, progress bar. Aliased to
     --series-1 rather than a new hex so every existing rgba(42,120,214,…)
     reference (buttons, glows, icon gradients) stays in family with zero
     rewrite risk. */
  --accent:         var(--series-1);
  --accent-rgb:      42,120,214;

  /* Sidebar / app-shell palette - a deep slate rather than pure black reads
     less "default dark mode" and more "designed enterprise product". */
  --sidebar-bg:      #12141c;
  --sidebar-bg-alt:  #191c26;
  --sidebar-border:  rgba(255,255,255,0.07);
  --sidebar-text:    #b7bac4;
  --sidebar-text-dim:#7d818e;
  --sidebar-active:  #ffffff;

  --shadow-sm: 0 1px 2px rgba(15,23,42,0.05), 0 1px 1px rgba(15,23,42,0.03);
  --shadow-md: 0 4px 10px rgba(15,23,42,0.07), 0 1px 2px rgba(15,23,42,0.04);
  --shadow-lg: 0 12px 28px rgba(15,23,42,0.11), 0 2px 6px rgba(15,23,42,0.05);
  --shadow-xl: 0 20px 48px rgba(15,23,42,0.16), 0 4px 12px rgba(15,23,42,0.07);
  /* Standardized 6-12px radius scale - every card/input/button/modal in the
     app draws from these four steps, nothing bespoke. */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 12px;

  /* Second surface tone - just a hair darker than --surface-1, used for
     table headers / subtle panels so a "card" reads as layered rather than
     flat-on-flat. */
  --surface-2: #f1f5f9; /* slate-100 */
  --accent-grad: linear-gradient(135deg, #2a78d6 0%, #4a3aa7 100%);

  /* Strict type scale - every size below already existed ad hoc across the
     app; naming them here makes the scale explicit and gives new UI (nav
     groups, breadcrumbs, skeletons, command palette) a fixed set to draw
     from instead of picking new px values. */
  --text-xs:   11px;
  --text-sm:   12.5px;
  --text-base: 13.5px;
  --text-md:   15px;
  --text-lg:   17px;
  --text-xl:   19px;
  --text-2xl:  24px;
  --text-3xl:  30px;

  /* Sidebar rail widths: collapsed = icon-only, expanded = hover-revealed
     overlay with labels; a header pin toggle can also lock it open. See
     .sidebar rules below. */
  --sidebar-w-collapsed: 72px;
  --sidebar-w-expanded: 252px;
  --sidebar-transition: 0.24s cubic-bezier(0.22, 0.85, 0.32, 1);

  /* Status palette - reserved for state (good/warning/danger/info), never
     reused as a categorical series color. Light values are the pastel
     tints this app already used inline; naming them lets dark mode swap in
     desaturated-for-dark equivalents from one place instead of hunting down
     every literal hex. */
  --status-success-bg: #e9f7ef; --status-success-fg: #0d6b3f;
  --status-danger-bg:  #fdeceb; --status-danger-fg:  #a1322f;
  --status-warning-bg: #fff7e6; --status-warning-fg: #8a5a00;
  --status-info-bg:    #e6f2ff; --status-info-fg:    #14487f;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --status-success-bg: rgba(47,211,154,0.16); --status-success-fg: #6fe3b7;
    --status-danger-bg:  rgba(242,113,111,0.16); --status-danger-fg: #f7a3a1;
    --status-warning-bg: rgba(242,183,58,0.16);  --status-warning-fg:#f2c766;
    --status-info-bg:    rgba(91,156,240,0.16);  --status-info-fg:  #a8c9f5;
  }
}
:root[data-theme="dark"] {
  --status-success-bg: rgba(47,211,154,0.16); --status-success-fg: #6fe3b7;
  --status-danger-bg:  rgba(242,113,111,0.16); --status-danger-fg: #f7a3a1;
  --status-warning-bg: rgba(242,183,58,0.16);  --status-warning-fg:#f2c766;
  --status-info-bg:    rgba(91,156,240,0.16);  --status-info-fg:  #a8c9f5;
}

/* =========================================================================
   Dark mode - auto (prefers-color-scheme) unless the user has explicitly
   chosen a theme (data-theme="light"|"dark" on <html>, set by the header
   toggle and persisted client-side; see shared.js initTheme()). Every token
   above gets a dark-surface-appropriate value here; component rules never
   hardcode a light-only color, they read the token, so this block alone
   re-themes the whole app. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --surface-1:      #161b26;
    --page-plane:     #0d1117;
    --surface-2:      #1c2230;
    --text-primary:   #e6e9f0;
    --text-secondary: #a3acc2;
    --text-muted:     #767f96;
    --gridline:       #262d3d;
    --baseline:       #333c50;
    --border:         #262d3d;
    --series-1:       #3b82f6;
    --series-2:       #ea580c;
    --series-3:       #059669;
    --series-4:       #d97706;
    --series-5:       #ec4899;
    --series-6:       #16a34a;
    --series-7:       #8b5cf6;
    --series-8:       #ef4444;
    --accent:         var(--series-1);
    --accent-rgb:      59,130,246;
    --accent-grad: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.24), 0 1px 1px rgba(0,0,0,0.16);
    --shadow-md: 0 4px 10px rgba(0,0,0,0.32), 0 1px 2px rgba(0,0,0,0.2);
    --shadow-lg: 0 12px 28px rgba(0,0,0,0.4), 0 2px 6px rgba(0,0,0,0.24);
    --shadow-xl: 0 20px 48px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.3);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1:      #161b26;
  --page-plane:     #0d1117;
  --surface-2:      #1c2230;
  --text-primary:   #e6e9f0;
  --text-secondary: #a3acc2;
  --text-muted:     #767f96;
  --gridline:       #262d3d;
  --baseline:       #333c50;
  --border:         #262d3d;
  --series-1:       #5b9cf0;
  --series-2:       #ff9761;
  --series-3:       #2fd39a;
  --series-4:       #f2b73a;
  --series-5:       #f2a0c0;
  --series-6:       #3fbf5f;
  --series-7:       #9384e8;
  --series-8:       #f2716f;
  --accent:         var(--series-1);
  --accent-rgb:      91,156,240;
  --accent-grad: linear-gradient(135deg, #5b9cf0 0%, #9384e8 100%);
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.24), 0 1px 1px rgba(0,0,0,0.16);
  --shadow-md: 0 4px 10px rgba(0,0,0,0.32), 0 1px 2px rgba(0,0,0,0.2);
  --shadow-lg: 0 12px 28px rgba(0,0,0,0.4), 0 2px 6px rgba(0,0,0,0.24);
  --shadow-xl: 0 20px 48px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.3);
}
/* .kpi-meter and the other pastel status backgrounds below now read the
   --status-*-bg tokens (defined above) instead of hardcoded hex, so their
   dark-mode variant comes for free from the token override - no per-
   component dark rule needed. */

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", -apple-system, "SF Pro Text", system-ui, "Segoe UI", sans-serif;
  background: var(--page-plane);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* =========================================================================
   App shell: fixed sidebar + main content column. Used by every
   authenticated page (dashboard / admin / audit log).
   ========================================================================= */
.app-shell {
  min-height: 100vh;
}

/* Collapsed by default (icon rail); on desktop, hovering the rail expands it
   as a floating overlay (fixed position, higher z-index + shadow) rather
   than pushing page content - .app-main's margin-left only ever reserves
   the *collapsed* width, so nothing reflows while the rail is expanding. */
.sidebar {
  width: var(--sidebar-w-collapsed);
  background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-bg-alt) 100%);
  color: var(--sidebar-text);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  padding: 20px 12px;
  z-index: 30;
  overflow: hidden;
  transition: width var(--sidebar-transition), box-shadow var(--sidebar-transition);
}
@media (min-width: 901px) {
  .sidebar:hover {
    width: var(--sidebar-w-expanded);
    box-shadow: var(--shadow-xl);
    z-index: 36;
  }
  /* Deliberately NOT pushing .app-main's margin-left on hover (only .pinned
     does that, below) - hover-expand is a pure floating overlay, matching
     the comment above .sidebar. An earlier version of this rule pushed the
     whole content column over on every hover, which fought the width
     transition above (two properties animating on two different elements)
     and read as janky/"not smooth" - removing it made the sidebar itself
     the only thing that moves on hover. */
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 4px 22px;
}
.brand-mark {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--accent-grad);
  color: #fff;
  font-weight: 800;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(42,120,214,0.45);
}
.brand-name {
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.sidebar-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: 9px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--sidebar-text);
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
.sidebar-link svg { width: 18px; height: 18px; flex-shrink: 0; opacity: 0.85; }
.sidebar-link:hover { background: rgba(255,255,255,0.07); color: #fff; }
.sidebar-link.active {
  background: rgba(255,255,255,0.10);
  color: var(--sidebar-active);
  box-shadow: inset 2px 0 0 var(--series-1);
}
.sidebar-link.active svg { opacity: 1; }

/* Label text (and anything else that should only appear once the rail is
   expanded) fades/widens in on hover rather than reflowing the icon
   column - the icon's x-position never moves. */
.sidebar-fade {
  opacity: 0;
  width: 0;
  overflow: hidden;
  white-space: nowrap;
  display: inline-block;
  transition: opacity 0.12s ease, width var(--sidebar-transition);
}
.sidebar:hover .sidebar-fade { opacity: 1; width: 150px; }
.sidebar-brand .sidebar-fade { width: 0; }
.sidebar:hover .sidebar-brand .sidebar-fade { width: 130px; }

.app-main {
  margin-left: var(--sidebar-w-collapsed);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  transition: margin-left var(--sidebar-transition);
}

/* Pinned sidebar - the manual "collapsible nav" control (brand-row button),
   independent of the hover-preview above. Pinning locks the rail at the
   expanded width and reserves that width in .app-main permanently, rather
   than only while hovering; the preference is remembered client-side (see
   shared.js initSidebar()). */
.sidebar.pinned {
  width: var(--sidebar-w-expanded);
}
.sidebar.pinned .sidebar-fade { opacity: 1; width: 150px; }
.sidebar.pinned .sidebar-brand .sidebar-fade { width: 130px; }
.sidebar.pinned + .app-main { margin-left: var(--sidebar-w-expanded); }
/* A pinned rail shouldn't also grow further on hover - it's already at its
   max width - and shouldn't push .app-main a second time. */
@media (min-width: 901px) {
  .sidebar.pinned:hover { box-shadow: none; }
  .sidebar.pinned:hover + .app-main { margin-left: var(--sidebar-w-expanded); }
}

/* Sidebar footer pin/expand-collapse toggle. Previously a small 26px icon
   button squeezed into the top brand row (opacity:0 until hovering, so it
   was effectively invisible AND, once revealed, gave no visible feedback if
   clicked while already hover-expanded - easy to conclude it "did nothing").
   Replaced with a full nav-row button in the footer position (where the
   Profile link used to be - Profile is still reachable via the topbar's
   profile dropdown) using the same .sidebar-link/.sidebar-footer-link
   layout as every other nav item, so it's exactly as easy to see and click.
   Only the chevron-rotation behavior below is specific to this button. */
.sidebar-pin-btn { cursor: pointer; border: none; background: transparent; width: 100%; text-align: left; font: inherit; }
.sidebar-pin-btn svg { transition: transform 0.15s ease; }
.sidebar.pinned .sidebar-pin-btn svg { transform: rotate(180deg); }

/* Nested nav groups (Analytics / Workspace) with a chevron toggle - the
   "clean dropdown chevrons" grouping. Only meaningful once the rail shows
   labels (hover-expanded or pinned); collapsed it's just a stack of icons
   same as before, so no group header renders visually in that state. */
.sidebar-group { display: flex; flex-direction: column; }
.sidebar-group + .sidebar-group { margin-top: 10px; }
.sidebar-group-label {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  border: none;
  background: none;
  padding: 6px 10px 4px;
  cursor: pointer;
  color: var(--sidebar-text-dim);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sidebar-group-label .sidebar-fade { flex: 1; text-align: left; }
.sidebar-group-chevron { width: 12px; height: 12px; flex-shrink: 0; opacity: 0; transition: opacity 0.12s ease, transform 0.15s ease; }
.sidebar:hover .sidebar-group-chevron, .sidebar.pinned .sidebar-group-chevron { opacity: 1; }
.sidebar-group.collapsed .sidebar-group-chevron { transform: rotate(-90deg); }
.sidebar-group-items { display: flex; flex-direction: column; gap: 2px; }
.sidebar-group.collapsed .sidebar-group-items { display: none; }
/* Collapsed rail (icon-only, not hovering/pinned): groups have no visible
   header, and a collapsed group's icons must still show (the "collapsed"
   state only means "chevron closed while labels are visible"). */
.sidebar:not(:hover):not(.pinned) .sidebar-group-label { padding-bottom: 0; }
.sidebar:not(:hover):not(.pinned) .sidebar-group.collapsed .sidebar-group-items { display: flex; }

.sidebar-footer-link { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--sidebar-border); }

/* =========================================================================
   Breadcrumbs - one row under the topbar on every app-shell page, derived
   from the active nav item + its group (see shared.js renderBreadcrumbs()).
   Hidden site-wide per user request (redundant with the topbar title +
   sidebar's own active-link highlight) - renderBreadcrumbs() still runs and
   populates #breadcrumbs, this just keeps it out of view everywhere rather
   than deleting the underlying logic.
   ========================================================================= */
.breadcrumbs {
  display: none;
  align-items: center;
  gap: 6px;
  padding: 14px 32px 0;
  font-size: 12.5px;
  color: var(--text-muted);
}
.breadcrumbs:empty { display: none; }
.breadcrumb-item { color: var(--text-muted); }
.breadcrumb-item:last-child { color: var(--text-secondary); font-weight: 600; }
.breadcrumb-sep { color: var(--baseline); font-size: 11px; }
@media (max-width: 900px) { .breadcrumbs { padding-left: 16px; padding-right: 16px; } }

/* =========================================================================
   Theme toggle - three-state switch (light / auto / dark) living in the
   topbar next to the profile menu. See shared.js initTheme().
   ========================================================================= */
.theme-toggle {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  flex-shrink: 0;
}
.theme-toggle-btn {
  width: 26px;
  height: 26px;
  border: none;
  background: none;
  border-radius: 999px;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, color 0.15s ease;
}
.theme-toggle-btn svg { width: 14px; height: 14px; }
.theme-toggle-btn:hover { color: var(--text-primary); }
.theme-toggle-btn[aria-pressed="true"] { background: var(--surface-1); color: var(--accent); box-shadow: var(--shadow-sm); }

/* =========================================================================
   Top bar - present on every authenticated page (dashboard / admin / audit /
   roles / profile). Page title + page-specific primary action on the left/
   middle, profile avatar/name/role -> dropdown menu on the right. Replaces
   the old sidebar-footer user-card (profile is no longer in the nav rail).
   ========================================================================= */
.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 64px;
  flex-shrink: 0;
  padding: 0 32px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar-title { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; margin: 0; white-space: nowrap; }
.topbar-actions { display: flex; align-items: center; gap: 8px; flex: 1; }

.profile-menu { position: relative; margin-left: auto; flex-shrink: 0; }
.profile-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid transparent;
  background: none;
  padding: 5px 8px 5px 5px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.profile-trigger:hover, .profile-trigger[aria-expanded="true"] { background: var(--surface-2); border-color: var(--border); }
.profile-trigger .user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--accent-grad);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 2px 6px rgba(42,120,214,0.3);
}
.profile-trigger-text { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; }
.profile-trigger-text .user-name {
  font-size: 13px;
  font-weight: 650;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
}
.profile-chevron { width: 14px; height: 14px; color: var(--text-muted); flex-shrink: 0; transition: transform 0.12s ease; }
.profile-trigger[aria-expanded="true"] .profile-chevron { transform: rotate(180deg); }

.profile-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 210px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 6px;
  z-index: 40;
}
.profile-dropdown-item {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s ease;
}
.profile-dropdown-item:hover { background: var(--surface-2); }
.profile-dropdown-item.danger { color: var(--series-8); }
.profile-dropdown-item.danger:hover { background: var(--status-danger-bg); }
.profile-dropdown-divider { height: 1px; background: var(--gridline); margin: 5px 2px; }

@media (max-width: 900px) {
  .topbar { padding: 0 16px 0 64px; }
  .topbar-title { font-size: 15px; }
}
@media (max-width: 640px) {
  .profile-trigger-text { display: none; }
  .topbar-title { flex-shrink: 1; overflow: hidden; text-overflow: ellipsis; }
}

.content { max-width: 1680px; width: 100%; margin: 0 auto; padding: 28px 32px 40px; }
/* Dashboard opts into full-screen width - a proper "fills the workspace"
   enterprise dashboard feel, rather than capping out mid-screen on wide
   monitors like the narrower admin/audit/roles/profile pages do. */
.content--full { max-width: none; }

.sidebar-toggle {
  display: none;
  position: fixed;
  top: 16px;
  left: 16px;
  z-index: 45;
  width: 38px;
  height: 38px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.sidebar-toggle svg { width: 18px; height: 18px; }
.sidebar-backdrop { display: none; }

@media (max-width: 900px) {
  .sidebar {
    width: 252px;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    z-index: 40;
  }
  .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-xl); }
  .sidebar .sidebar-fade { opacity: 1; width: 150px; }
  .sidebar .sidebar-brand .sidebar-fade { width: 130px; }
  .sidebar-toggle { display: flex; }
  .sidebar-backdrop.open {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(11,11,15,0.45);
    z-index: 39;
  }
  .app-main { margin-left: 0; }
  .content { padding: 20px 16px 32px 16px; }
}

/* =========================================================================
   Dashboard toolbar (date nav + range tabs + KPI stat, one consolidated row)
   ========================================================================= */
.dashboard-toolbar {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.period-nav { display: flex; align-items: center; gap: 14px; }
.icon-btn {
  border: 1px solid var(--border);
  background: var(--surface-1);
  border-radius: 8px;
  width: 34px;
  height: 34px;
  font-size: 15px;
  cursor: pointer;
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
  transition: background 0.12s ease, box-shadow 0.12s ease;
}
.icon-btn:hover { background: var(--gridline); }
.period-label { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 150px; }
#periodLabel { font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
.link-btn { border: none; background: transparent; color: var(--series-1); font-size: 12px; padding: 0; cursor: pointer; text-align: left; font-weight: 500; }
.link-btn:hover { text-decoration: underline; }

.range-tabs { display: flex; gap: 3px; background: var(--gridline); border-radius: 9px; padding: 3px; }
.range-tab {
  border: none;
  background: transparent;
  padding: 7px 15px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
.range-tab[aria-selected="true"] {
  background: var(--surface-1);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}

.stat-tiles { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.stat-tile {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 22px;
  box-shadow: var(--shadow-md);
  position: relative;
  overflow: hidden;
}
.stat-tile::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--accent-grad);
}
.stat-tile-compare::before { background: linear-gradient(135deg, #1baf7a 0%, #0d8f80 100%); }
.stat-tile-compare .stat-icon { background: linear-gradient(135deg, #1baf7a 0%, #0d8f80 100%); box-shadow: 0 3px 10px rgba(27,175,122,0.35); }
.stat-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--accent-grad);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 3px 10px rgba(42,120,214,0.35);
}
.stat-icon svg { width: 18px; height: 18px; }
.stat-value { font-size: 24px; font-weight: 800; font-variant-numeric: proportional-nums; letter-spacing: -0.01em; line-height: 1.1; }
.stat-label { font-size: 11px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.delta-badge {
  margin-left: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}
.delta-badge.up { background: var(--status-success-bg); color: var(--status-success-fg); }
.delta-badge.down { background: var(--status-danger-bg); color: var(--status-danger-fg); }
.delta-badge.flat { background: var(--surface-2); color: var(--text-muted); }

/* =========================================================================
   KPIs page - card grid, conversion-rate meters, compare row, drill-down
   ========================================================================= */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 22px;
}
@media (max-width: 1280px) {
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .kpi-grid { grid-template-columns: 1fr; }
}
.kpi-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  text-align: left;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px 16px;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease;
  overflow: hidden;
}
.kpi-card::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px transparent;
  transition: box-shadow 0.14s ease;
}
.kpi-card:hover, .kpi-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
  border-color: rgba(42,120,214,0.35);
  outline: none;
}
.kpi-card:hover::after, .kpi-card:focus-visible::after {
  box-shadow: inset 0 0 0 1px rgba(42,120,214,0.25);
}
.kpi-card:active { transform: translateY(0); }
/* All 7 cards are the same width (uniform grid) - 4 per row, wrapping to 3
   on the second row. Rate cards carry a bit more content (meter + "N of M"
   line) but stay legible at this width; keeping every card uniform reads
   as a cleaner grid than mixing spans for an odd count like 7. */

.kpi-icon {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  box-shadow: var(--shadow-sm);
  margin-bottom: 4px;
}
.kpi-icon svg { width: 20px; height: 20px; }
.kpi-icon-total { background: var(--accent-grad); }
.kpi-icon-mql { background: linear-gradient(135deg, #eb6834 0%, #c9501f 100%); }
.kpi-icon-icpl { background: linear-gradient(135deg, #4a3aa7 0%, #35297d 100%); }
.kpi-icon-sql { background: linear-gradient(135deg, #eda100 0%, #c98600 100%); }
.kpi-icon-opp { background: linear-gradient(135deg, #2a78d6 0%, #1c5aa3 100%); }
.kpi-icon-won { background: linear-gradient(135deg, #1baf7a 0%, #0d8f80 100%); }
.kpi-icon-rate { background: linear-gradient(135deg, #1baf7a 0%, #0d8f80 100%); }

.kpi-label { font-size: 12.5px; font-weight: 650; color: var(--text-secondary); }
.kpi-value { font-size: 30px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.1; font-variant-numeric: proportional-nums; }
.kpi-sub { font-size: 12px; color: var(--text-muted); }
.kpi-cta {
  margin-top: auto;
  padding-top: 8px;
  font-size: 12px;
  font-weight: 650;
  color: var(--series-1);
}

.kpi-compare { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.kpi-compare-label { font-size: 11.5px; color: var(--text-muted); }
.kpi-compare .delta-badge { margin-left: 0; }

.kpi-meter {
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--status-info-bg); /* lighter step of the same blue ramp as the fill - state reads across the whole bar */
  overflow: hidden;
  margin: 2px 0;
}
.kpi-meter-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #2a78d6 0%, #1baf7a 100%);
  width: 0%;
  transition: width 0.4s ease;
}

.kpi-drilldown {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 18px 20px;
  margin-bottom: 20px;
}
.kpi-drilldown-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.kpi-drilldown-title { font-size: 17px; font-weight: 750; margin: 0 0 2px; }
.kpi-drilldown-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* =========================================================================
   KPIs page analytics (2026-09-03f) - auto-generated insight chips, the
   trend chart (line/area, SVG drawn in kpis.js), the lifecycle/deal-stage
   "funnel" bar list, and the Brand/Source/Industry/Country breakdown widgets.
   All share the same .chart-card / .bar-list visual language as the rest of
   the KPIs page (same surface, border, radius, shadow tokens as .kpi-card).
   ========================================================================= */
.kpi-insights {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}
.kpi-insights:empty { display: none; margin: 0; }
.insight-chip {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-size: 13px;
  color: var(--text-secondary);
  box-shadow: var(--shadow-sm);
}
.insight-chip-up { border-left-color: var(--status-success-fg); }
.insight-chip-down { border-left-color: var(--status-danger-fg); }
.insight-chip-icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--text-muted);
}
.insight-chip-up .insight-chip-icon { color: var(--status-success-fg); }
.insight-chip-down .insight-chip-icon { color: var(--status-danger-fg); }
.insight-chip-icon svg { width: 100%; height: 100%; }
.insight-chip-text { line-height: 1.45; }

.chart-card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px 16px;
  margin-bottom: 20px;
}
.chart-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.chart-card-title { font-size: 15.5px; font-weight: 700; margin: 0 0 2px; }

.trend-metric-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  background: var(--surface-2);
  border-radius: var(--radius-md);
  padding: 3px;
}
.trend-metric-tab {
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  padding: 6px 10px;
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.trend-metric-tab:hover { color: var(--text-primary); }
.trend-metric-tab[aria-selected="true"] {
  background: var(--surface-1);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}

.chart-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.chart-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); }
.chart-legend-swatch { width: 14px; height: 2px; border-radius: 1px; display: inline-block; }
.chart-legend-swatch-dashed {
  background: none;
  height: 0;
  border-top: 2px dashed;
}

.chart-wrap { position: relative; width: 100%; }
.trend-svg { display: block; width: 100%; height: 260px; overflow: visible; }
.trend-grid { stroke: var(--gridline); stroke-width: 1; }
.trend-axis-label { fill: var(--text-muted); font-size: 10.5px; font-family: inherit; }
.trend-crosshair { stroke: var(--border); stroke-width: 1; }
.trend-hover-dot { stroke: var(--surface-1); stroke-width: 2; }
.chart-empty {
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
  padding: 40px 0;
}

.chart-tooltip {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 8px 10px;
  font-size: 12px;
  min-width: 150px;
  transform: translateY(-100%);
}
.chart-tooltip-title { font-weight: 700; color: var(--text-primary); margin-bottom: 4px; }
.chart-tooltip-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 1px 0; }
.chart-tooltip-key { display: inline-flex; align-items: center; gap: 6px; color: var(--text-secondary); }
.chart-tooltip-key-line { width: 10px; height: 2px; border-radius: 1px; display: inline-block; }
.chart-tooltip-val { font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; }

.analytics-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 900px) {
  .analytics-grid { grid-template-columns: 1fr; }
}

.bar-list { display: flex; flex-direction: column; gap: 10px; }
.bar-row {
  display: grid;
  grid-template-columns: 132px 1fr 52px 44px;
  align-items: center;
  gap: 10px;
}
.bar-row-label {
  font-size: 12.5px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-row-track {
  height: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}
.bar-row-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 0.4s ease;
}
.bar-row-value {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-primary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.bar-row-pct {
  font-size: 11.5px;
  color: var(--text-muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 560px) {
  .bar-row { grid-template-columns: 84px 1fr 40px; }
  .bar-row-pct { display: none; }
}

/* =========================================================================
   Custom date range + comparison controls (dashboard "Custom" tab)
   ========================================================================= */
.custom-range-bar {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 18px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-sm);
}
.custom-range-group { display: flex; align-items: center; gap: 8px; }
.custom-range-group-label { font-size: 12px; font-weight: 650; color: var(--text-muted); }
.custom-range-sep { color: var(--text-muted); }
.custom-range-bar input[type="date"] {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface-1);
  font-size: 13px;
  color: var(--text-primary);
}
.compare-toggle { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 550; color: var(--text-secondary); cursor: pointer; }
.compare-toggle input { width: auto; margin: 0; }

/* =========================================================================
   Calendar date-range picker - trigger pill + popover, used by the
   Dashboard's Custom range/Compare range and Audit Log's From/To filter
   (see initDateRangePicker in shared.js). The real <input type="date">
   this replaces stays in the DOM (class="hidden") as the source of truth.
   ========================================================================= */
.daterange-picker { position: relative; display: inline-flex; }
.daterange-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--text-primary);
  font-family: inherit;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.daterange-trigger:hover { border-color: var(--accent); }
.daterange-trigger[aria-expanded="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.14); }
.daterange-trigger > svg { width: 16px; height: 16px; color: var(--text-muted); flex-shrink: 0; }
.daterange-trigger-field { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; line-height: 1.2; }
.daterange-trigger-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.daterange-trigger-value { font-size: 13px; font-weight: 650; color: var(--text-primary); white-space: nowrap; }
.daterange-trigger-sep { color: var(--text-muted); }

.daterange-popover {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 120;
  width: 300px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 14px;
}
.daterange-popover.hidden { display: none; }
.daterange-popover-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.daterange-nav-btn { width: 28px; height: 28px; font-size: 13px; }
.daterange-month-label { font-size: 13.5px; font-weight: 700; color: var(--text-primary); }
.daterange-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 4px;
}
.daterange-weekdays span {
  text-align: center;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  padding: 4px 0;
}
.daterange-days { display: grid; grid-template-columns: repeat(7, 1fr); }
.daterange-day {
  position: relative;
  height: 34px;
  border: none;
  background: transparent;
  color: var(--text-primary);
  font-size: 12.5px;
  font-weight: 550;
  cursor: pointer;
  z-index: 1;
}
.daterange-day-overflow { color: var(--text-muted); opacity: 0.4; cursor: default; }
.daterange-day:not(.daterange-day-overflow):not(.is-range-start):not(.is-range-end):hover::before {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 999px;
  background: var(--surface-2);
  z-index: -1;
}
.daterange-day.is-today { color: var(--accent); font-weight: 750; }
.daterange-day.is-in-range::after {
  content: '';
  position: absolute;
  inset: 3px -1px;
  background: rgba(var(--accent-rgb), 0.14);
  z-index: -2;
}
.daterange-day.is-range-start::after, .daterange-day.is-range-end::after {
  content: '';
  position: absolute;
  inset: 3px 0;
  background: rgba(var(--accent-rgb), 0.14);
  z-index: -2;
}
.daterange-day.is-range-start::after { left: 50%; }
.daterange-day.is-range-end::after { right: 50%; }
.daterange-day.is-range-start.is-range-end::after { display: none; }
.daterange-day.is-range-start::before, .daterange-day.is-range-end::before {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 999px;
  background: var(--accent);
  z-index: -1;
}
.daterange-day.is-range-start, .daterange-day.is-range-end { color: #fff; font-weight: 700; }
.daterange-popover-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--gridline);
}

.period-switch { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.range-tabs-sm { padding: 2px; }
.range-tabs-sm .range-tab { padding: 5px 12px; font-size: 12.5px; }

/* =========================================================================
   Search + filter toolbar, filter panel, buttons, banners
   ========================================================================= */
.filter-toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.search-wrap { position: relative; flex: 1; min-width: 260px; }
.search-icon { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-muted); pointer-events: none; }
.premium-search {
  width: 100%;
  padding: 11px 38px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
  font-size: 14px;
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.premium-search:focus {
  outline: none;
  border-color: var(--series-1);
  box-shadow: 0 0 0 3px rgba(42,120,214,0.14);
}
.premium-search::-webkit-search-cancel-button { display: none; }
.search-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  border: none;
  background: var(--surface-2);
  border-radius: 999px;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.search-clear svg { width: 11px; height: 11px; }
.search-clear:hover { background: var(--gridline); color: var(--text-primary); }

.filter-toggle-btn { display: flex; align-items: center; gap: 7px; }
.filter-toggle-btn svg { width: 15px; height: 15px; }
.filter-toggle-btn[aria-expanded="true"] { background: var(--surface-2); border-color: var(--series-1); color: var(--series-1); }
.filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--series-1);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}

/* Page-size select in the filter toolbar (Dashboard only) - was a totally
   unstyled native <select>, which looked out of place next to the Filters
   button and export menu. Custom chevron via a data-URI background image
   since appearance:none drops the native one; color matched to
   --text-muted's two values (light vs dark/auto) below. */
#pageSizeSelect {
  appearance: none;
  -webkit-appearance: none;
  padding: 9px 32px 9px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background-color: var(--surface-1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' 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");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 14px;
  font-size: 13.5px;
  font-weight: 550;
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
#pageSizeSelect:hover { border-color: var(--accent); }
#pageSizeSelect:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.16);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #pageSizeSelect {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23767f96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] #pageSizeSelect {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23767f96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.filter-panel {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-sm);
}
.filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
}
.filter-field { display: flex; flex-direction: column; gap: 5px; }
.filter-field label { font-size: 11px; font-weight: 650; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-muted); }
.filter-field select {
  appearance: none;
  -webkit-appearance: none;
  padding: 9px 30px 9px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background-color: var(--surface-1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' 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");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 13px;
  font-size: 13.5px;
  color: var(--text-primary);
  cursor: pointer;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .filter-field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23767f96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] .filter-field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23767f96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.filter-panel-actions { display: flex; justify-content: flex-end; align-items: center; gap: 14px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--gridline); }

/* One glow-ring focus treatment for every text/select/date input in the
   app, instead of a harsh outline - subtle colored ring + matching border,
   never a hard black rectangle. */
.form-field input:focus, .form-field select:focus,
.filter-field select:focus, .custom-range-bar input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.16);
}
.primary-btn {
  border: none;
  background: var(--accent);
  color: #fff;
  padding: 9px 18px;
  border-radius: var(--radius-md);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(var(--accent-rgb),0.25);
  transition: background 0.15s ease, transform 0.05s ease, box-shadow 0.15s ease;
}
.primary-btn:hover { background: #256abf; box-shadow: 0 2px 8px rgba(var(--accent-rgb),0.32); }
.primary-btn:active { transform: translateY(1px); }
.primary-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18); }

.banner {
  background: var(--status-warning-bg);
  border: 1px solid var(--series-4);
  color: var(--text-primary);
  padding: 11px 16px;
  border-radius: var(--radius-md);
  font-size: 13px;
  margin-bottom: 18px;
}

/* =========================================================================
   Data tables (dashboard leads table + admin/audit tables share this look)
   ========================================================================= */
.table-wrap, .data-table-wrap {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  overflow: auto;
  box-shadow: var(--shadow-lg);
  position: relative;
}
table, .data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th, .data-table thead th {
  text-align: left;
  padding: 13px 16px;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--gridline);
  white-space: nowrap;
  position: sticky;
  top: 0;
  background: var(--surface-2);
  cursor: pointer;
}
thead th:hover, .data-table thead th:hover { color: var(--text-primary); }
tbody td, .data-table tbody td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--gridline);
  vertical-align: top;
  max-width: 240px;
  overflow-wrap: break-word;
}
.data-table tbody td { vertical-align: middle; max-width: 320px; overflow: hidden; }
.data-table td.nowrap, .data-table td.nowrap * { white-space: nowrap; }
/* Left accent bar on hover, applied to the first cell (not <tr>) - border
   support on <tr> itself is inconsistent across browsers under
   border-collapse. A matching transparent border reserves the same space on
   the header's first cell so header/body columns stay pixel-aligned either
   way. */
thead th:first-child, .data-table thead th:first-child { border-left: 3px solid transparent; }
tbody td:first-child, .data-table tbody td:first-child { border-left: 3px solid transparent; }
tbody tr, .data-table tbody tr { transition: background 0.1s ease; }
tbody tr:hover, .data-table tbody tr:hover { background: var(--surface-2); }
tbody tr:hover td:first-child, .data-table tbody tr:hover td:first-child { border-left-color: var(--series-1); }
tbody tr:last-child td, .data-table tbody tr:last-child td { border-bottom: none; }
.empty-state, .error-state {
  text-align: center;
  color: var(--text-muted);
  padding: 40px !important;
}
.error-state { color: var(--series-8); }

.muted { color: var(--text-muted); }

.brand-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
  color: #fff;
  white-space: nowrap;
  letter-spacing: 0.01em;
}

/* Landing Page cell: an "Open" chip-button (new tab) plus a copy-to-clipboard
   icon button, instead of a bare link - see app.js renderRows(). */
.link-actions { display: flex; align-items: center; gap: 6px; }
.btn-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--status-info-bg);
  color: var(--accent);
  font-size: 12px;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.12s ease;
}
.btn-chip:hover { filter: brightness(0.96); }
.btn-chip svg { width: 12px; height: 12px; }
.icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.icon-chip:hover { background: var(--surface-2); color: var(--text-primary); }
.icon-chip svg { width: 13px; height: 13px; }
.icon-chip.copied { background: #e9f7ef; border-color: var(--series-3); color: #0d6b3f; }

/* Keeps long free-text (Requirements) from ballooning row height, and long
   URLs (Landing Page) from forcing an extra-wide column - full value is
   still reachable via the native title tooltip on hover. */
.clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.truncate-1 {
  display: inline-block;
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

/* Requirements (Single Line) - the concise HubSpot-generated summary shown
   as the primary Requirements-cell text when a lead has one (see
   app.js renderRows). Deliberately not clamped like the full free-text
   fallback - it's short by design. */
.req-single {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 550;
}

/* =========================================================================
   Source column (badge + drill-down subtext + history-popover trigger)
   ========================================================================= */
.source-cell { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.source-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
  color: #fff;
  white-space: nowrap;
  letter-spacing: 0.01em;
  flex-shrink: 0;
}
.source-detail {
  font-size: 12px;
  color: var(--text-muted);
  max-width: 150px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.source-history-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-muted);
  cursor: pointer;
  flex-shrink: 0;
  padding: 0;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.source-history-btn:hover { background: var(--surface-2); color: var(--series-1); border-color: rgba(42,120,214,0.35); }
.source-history-btn svg { width: 13px; height: 13px; }

/* Single reusable flyout, repositioned + re-filled per row via JS (see
   app.js openSourcePopover) rather than one instance per row. */
.source-popover {
  position: fixed;
  z-index: 60;
  width: 300px;
  max-width: calc(100vw - 24px);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 4px 0 8px;
}
.source-popover-arrow {
  position: absolute;
  width: 11px;
  height: 11px;
  background: var(--surface-1);
  transform: rotate(45deg);
}
.source-popover.arrow-top .source-popover-arrow { top: -5.5px; box-shadow: -2px -2px 3px -2px rgba(15,15,10,0.08); }
.source-popover.arrow-bottom .source-popover-arrow { bottom: -5.5px; box-shadow: 2px 2px 3px -2px rgba(15,15,10,0.08); }
.source-popover-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--gridline);
  margin-bottom: 6px;
}
.source-popover-close {
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  transition: background 0.12s ease, color 0.12s ease;
}
.source-popover-close:hover { background: var(--surface-2); color: var(--text-primary); }
.source-popover-close svg { width: 13px; height: 13px; }
.source-popover-body { padding: 2px 14px 4px; display: flex; flex-direction: column; gap: 14px; }
.source-popover-section-title {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--series-1);
  margin-bottom: 8px;
}
.source-popover-field { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 3px 0; font-size: 12.5px; }
.source-popover-field-label { color: var(--text-muted); flex-shrink: 0; }
.source-popover-field-value { color: var(--text-primary); font-weight: 550; text-align: right; overflow-wrap: anywhere; }

/* Kept for the audit-log page's simpler Prev/Next-only pagination. */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 18px;
  font-size: 13px;
  color: var(--text-secondary);
}

/* =========================================================================
   Dashboard pagination - result count + numbered pages, not just Prev/Next.
   ========================================================================= */
.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 18px;
  flex-wrap: wrap;
}
.pagination-info { font-size: 13px; color: var(--text-secondary); }
.pagination-controls { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.pagination-pages { display: flex; align-items: center; gap: 4px; }
.page-btn {
  min-width: 32px;
  height: 32px;
  padding: 0 6px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.page-btn:hover { background: var(--surface-2); color: var(--text-primary); }
.page-btn.active { background: var(--series-1); color: #fff; box-shadow: 0 1px 2px rgba(42,120,214,0.25); }
.page-btn.ellipsis { cursor: default; color: var(--text-muted); }
.page-btn.ellipsis:hover { background: none; }

@media (max-width: 640px) {
  .stat-tiles { margin-left: 0; }
  .dashboard-toolbar { flex-wrap: wrap; }
  .pagination-bar { justify-content: center; }
  .pagination-controls { margin-left: 0; }
}

/* =========================================================================
   Role / status chips
   ========================================================================= */
.role-badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  /* Fallback for role names with no inline color (e.g. historical audit-log
     snapshots of a role that has since been renamed or deleted) - roles are
     fully dynamic now, so most badges set their own background/color inline
     from the role's `color` field (see shared.js paintRoleBadge) rather than
     relying on a name-keyed class here. */
  background: var(--gridline);
  color: var(--text-secondary);
}

.status-pill { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 10.5px; font-weight: 650; white-space: nowrap; }
.status-pill.active { background: var(--status-success-bg); color: var(--status-success-fg); }
.status-pill.inactive { background: var(--gridline); color: var(--text-muted); }

/* =========================================================================
   Buttons - three tiers.
   Primary   (.btn-primary): solid accent, the one main action on a view.
   Secondary (.btn, unqualified): outlined/subtle-gray, alternative actions -
             this is the pre-existing default .btn look, kept as-is so every
             current call site (many) becomes "secondary" for free.
   Tertiary  (.btn-tertiary / .btn-link): text-only, low-priority actions
             like "Cancel". .btn-link is the pre-existing alias, kept.
   All three share the same 150ms micro-interaction: a small background/
   border shift on hover, a 1px "press" on active, driven by var(--accent).
   ========================================================================= */
.btn {
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-primary);
  padding: 8px 14px;
  border-radius: var(--radius-md);
  font-size: 13px;
  font-weight: 550;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.05s ease;
}
.btn:hover { background: var(--surface-2); border-color: var(--baseline); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(var(--accent-rgb), 0.3); }
.btn-primary:hover { background: #256abf; border-color: #256abf; box-shadow: 0 2px 8px rgba(var(--accent-rgb), 0.35); }
:root[data-theme="dark"] .btn-primary:hover { filter: brightness(1.1); background: var(--accent); border-color: var(--accent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn-primary:hover { filter: brightness(1.1); background: var(--accent); border-color: var(--accent); }
}

.btn-danger { background: var(--surface-1); border-color: var(--series-8); color: var(--series-8); }
.btn-danger:hover { background: var(--status-danger-bg); }

.btn-tertiary { border: none; background: none; box-shadow: none; color: var(--text-secondary); }
.btn-tertiary:hover { background: var(--surface-2); color: var(--text-primary); }

.btn-sm { padding: 4px 10px; font-size: 12px; border-radius: var(--radius-sm); }
.btn-link { border: none; background: none; color: var(--accent); cursor: pointer; font-size: 13px; padding: 0; font-weight: 500; transition: opacity 0.15s ease; }
.btn-link:hover { text-decoration: underline; }
.btn-link:active { opacity: 0.7; }

/* Contextual button spinner (see shared.js setButtonBusy()) - swaps the
   label for an inline spinner without touching layout width, so a button
   mid-action doesn't jump size. */
.btn-spinner {
  display: inline-block;
  width: 13px;
  height: 13px;
  border-radius: 999px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  opacity: 0.85;
  animation: btn-spin 0.6s linear infinite;
  vertical-align: -2px;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn[data-busy="true"] { cursor: progress; pointer-events: none; }
.btn[data-busy="true"] .btn-label-text { visibility: hidden; }
.btn[data-busy="true"] { position: relative; }
.btn[data-busy="true"] .btn-spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }

/* =========================================================================
   Auth pages shared bits (brand lockup, form fields) - the .auth-shell /
   .auth-card / hero layout itself is defined further down, alongside the
   split-hero treatment.
   ========================================================================= */
.auth-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 22px; }
.auth-brand .brand-mark { box-shadow: 0 3px 10px rgba(42,120,214,0.35); }
.auth-brand .brand-name { color: var(--text-primary); }
.auth-card h1 { font-size: 19px; margin: 0 0 4px; letter-spacing: -0.01em; }
.auth-card p.subtitle { color: var(--text-secondary); font-size: 13px; margin: 0 0 22px; }
.form-field { margin-bottom: 16px; }
.form-field label { display: block; font-size: 13px; font-weight: 550; margin-bottom: 6px; color: var(--text-secondary); }
.form-field input, .form-field select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  font-size: 14px;
  color: var(--text-primary);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.form-error {
  background: var(--status-danger-bg);
  border: 1px solid var(--series-8);
  color: var(--status-danger-fg);
  padding: 9px 13px;
  border-radius: 8px;
  font-size: 13px;
  margin-bottom: 16px;
}
.form-success {
  background: var(--status-success-bg);
  border: 1px solid var(--series-3);
  color: var(--status-success-fg);
  padding: 9px 13px;
  border-radius: 8px;
  font-size: 13px;
  margin-bottom: 16px;
}
.full-width { width: 100%; }

/* =========================================================================
   Admin / audit pages
   ========================================================================= */
.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; gap: 12px; flex-wrap: wrap; }
.page-header h2 { font-size: 19px; margin: 0; letter-spacing: -0.01em; }
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; }

.modal-overlay {
  position: fixed; inset: 0; background: rgba(11,11,15,0.50);
  display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 50;
  backdrop-filter: blur(1px);
}
.modal {
  background: var(--surface-1); border-radius: var(--radius-lg); padding: 26px; width: 100%; max-width: 520px;
  max-height: 85vh; overflow: auto; box-shadow: var(--shadow-lg);
}
.modal h3 { margin: 0 0 16px; font-size: 16px; letter-spacing: -0.01em; }
.modal-footer { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
.hidden { display: none !important; }

/* "Please wait, preparing your report" overlay (see shared.js's
   showWaitOverlay/hideWaitOverlay, 2026-09-03i) - shown for Dashboard/KPIs
   fetches that might take a while now that a large custom date range gets
   auto-split into smaller chunks server-side for an exact count, instead of
   silently returning a truncated subset. Modeled on .modal-overlay/.modal
   above (same backdrop/card/shadow treatment) but with a higher z-index so
   it can appear over an already-open filter panel or drill-down modal. */
.wait-overlay {
  position: fixed; inset: 0; z-index: 70; padding: 24px;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 40%, rgba(var(--accent-rgb),0.16), rgba(11,11,15,0.55) 60%);
  backdrop-filter: blur(3px);
  animation: wait-overlay-backdrop-in 0.25s ease both;
}
.wait-overlay.is-leaving { animation: wait-overlay-backdrop-out 0.16s ease both; }
@keyframes wait-overlay-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes wait-overlay-backdrop-out { from { opacity: 1; } to { opacity: 0; } }

.wait-overlay-card {
  position: relative;
  background: var(--surface-1); /* fallback for browsers without color-mix() */
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 34px 38px 30px;
  box-shadow: var(--shadow-xl), 0 0 0 1px rgba(var(--accent-rgb),0.05);
  display: flex; flex-direction: column; align-items: center;
  gap: 16px; max-width: 380px; text-align: center;
  animation: wait-overlay-card-in 0.32s cubic-bezier(0.22, 0.9, 0.32, 1.15) both;
}
.wait-overlay.is-leaving .wait-overlay-card { animation: wait-overlay-card-out 0.16s ease both; }
@keyframes wait-overlay-card-in {
  from { opacity: 0; transform: translateY(6px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes wait-overlay-card-out {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.97); }
}

.wait-overlay-ring-wrap { position: relative; width: 72px; height: 72px; display: flex; align-items: center; justify-content: center; }
.wait-overlay-ring { transform: rotate(-90deg); }
.wait-overlay-ring-track { fill: none; stroke: var(--border); stroke-width: 5; }
.wait-overlay-ring-fill {
  fill: none; stroke-width: 5; stroke-linecap: round;
  stroke-dasharray: 188.5; stroke-dashoffset: 188.5;
  transition: stroke-dashoffset 0.7s cubic-bezier(0.22, 0.85, 0.32, 1);
  filter: drop-shadow(0 0 5px rgba(var(--accent-rgb),0.45));
}
.wait-overlay-grad-a { stop-color: var(--series-1); }
.wait-overlay-grad-b { stop-color: var(--series-7); }
/* Indeterminate mode (no real chunk data yet): a short arc chases around the
   ring continuously, rather than the ring reading as "stuck" while the
   overlay waits for its first real data point (usually well under a
   second). Determinate mode drops the spin and lets stroke-dashoffset above
   animate to reflect real, cumulative chunk progress instead. */
.wait-overlay-ring-wrap.is-indeterminate .wait-overlay-ring {
  animation: wait-ring-spin 1s linear infinite;
}
.wait-overlay-ring-wrap.is-indeterminate .wait-overlay-ring-fill {
  stroke-dasharray: 47 141.5; stroke-dashoffset: 0; transition: none;
}
@keyframes wait-ring-spin { to { transform: rotate(270deg); } }
.wait-overlay-ring-pulse {
  position: absolute; width: 10px; height: 10px; border-radius: 999px;
  background: var(--accent-grad);
  animation: wait-ring-pulse 1.6s ease-in-out infinite;
}
@keyframes wait-ring-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

.wait-overlay-text {
  font-size: 14.5px; font-weight: 600; color: var(--text-primary); line-height: 1.45;
  min-height: 2.9em; display: flex; align-items: center; justify-content: center;
}
.wait-overlay-meta {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.wait-overlay-count:not(:empty)::before { content: '·'; margin-right: 8px; color: var(--border); }

.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 6px;
  max-height: 220px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  background: var(--surface-2);
}
.checkbox-grid label { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 400; margin: 0; }
.section-title { font-size: 12.5px; font-weight: 650; margin: 20px 0 8px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.03em; }

/* Roles page permission checkboxes - one per row (unlike the multi-column
   Brand-grant checkbox-grid) since each permission carries a longer
   description that needs room to wrap. */
.permission-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: var(--surface-2);
}
.permission-grid label { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; font-weight: 400; margin: 0; line-height: 1.4; }
.permission-grid input[type="checkbox"] { margin-top: 2px; width: auto; flex-shrink: 0; }

.filter-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.meta-line { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

.timezone-note {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: -6px 0 16px;
}
.timezone-note svg { width: 14px; height: 14px; flex-shrink: 0; stroke: var(--text-muted); }
.timezone-note b { color: var(--text-secondary); font-weight: 650; }

/* =========================================================================
   Profile page
   ========================================================================= */
.profile-grid {
  display: grid;
  grid-template-columns: minmax(260px, 340px) 1fr;
  gap: 20px;
  align-items: start;
}
@media (max-width: 800px) {
  .profile-grid { grid-template-columns: 1fr; }
}
.profile-card, .access-card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.profile-card-header {
  padding: 32px 26px 24px;
  background: var(--accent-grad);
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
}
.profile-avatar {
  width: 72px;
  height: 72px;
  border-radius: 999px;
  background: rgba(255,255,255,0.16);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.35);
  color: #fff;
  font-size: 26px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.profile-card-header h2 { margin: 4px 0 0; font-size: 18px; letter-spacing: -0.01em; }
.profile-card-header .profile-email { font-size: 13px; opacity: 0.85; }
.profile-fields { padding: 20px 26px 26px; display: flex; flex-direction: column; gap: 16px; }
.profile-field { display: flex; flex-direction: column; gap: 3px; }
.profile-field .profile-field-label { font-size: 11px; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.profile-field .profile-field-value { font-size: 14px; color: var(--text-primary); font-weight: 550; }
.profile-actions { padding: 0 26px 26px; }

.access-card { padding: 26px; }
.access-card h3 { margin: 0 0 4px; font-size: 15px; letter-spacing: -0.01em; }
.access-card .meta-line { margin-bottom: 20px; }
.access-section { margin-bottom: 22px; }
.access-section:last-child { margin-bottom: 0; }
.access-section .section-title { margin: 0 0 10px; }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.access-chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 13px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.access-empty {
  padding: 16px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  color: var(--text-muted);
  font-size: 13px;
  background: var(--surface-2);
}
.access-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  font-size: 13px;
  font-weight: 500;
}
.access-banner.dim { background: var(--surface-2); color: var(--text-secondary); }
.access-banner svg { width: 18px; height: 18px; flex-shrink: 0; }

/* =========================================================================
   Auth pages (login / change password) - split hero + form card
   ========================================================================= */
.auth-shell {
  min-height: 100vh;
  display: flex;
  background: var(--page-plane);
}
.auth-hero {
  flex: 1.1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 22px;
  padding: 60px 64px;
  color: #fff;
  background:
    radial-gradient(circle at 20% 20%, rgba(255,255,255,0.10), transparent 45%),
    radial-gradient(circle at 85% 80%, rgba(255,255,255,0.08), transparent 40%),
    var(--accent-grad);
  position: relative;
  overflow: hidden;
}
.auth-hero h2 { font-size: 30px; margin: 0; letter-spacing: -0.02em; line-height: 1.25; max-width: 420px; }
.auth-hero p { font-size: 14.5px; margin: 0; opacity: 0.85; max-width: 380px; line-height: 1.55; }
.auth-hero-points { display: flex; flex-direction: column; gap: 14px; margin-top: 12px; }
.auth-hero-point { display: flex; align-items: flex-start; gap: 12px; font-size: 13.5px; opacity: 0.92; max-width: 380px; line-height: 1.4; }
.auth-hero-point svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; }
.auth-hero .auth-brand { margin-bottom: 8px; }
.auth-hero .auth-brand .brand-name { color: #fff; }
.auth-hero .brand-mark { background: rgba(255,255,255,0.18); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,0.3); }

.auth-form-panel {
  flex: 1;
  min-width: 380px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 34px;
  box-shadow: var(--shadow-lg);
}
@media (max-width: 900px) {
  .auth-hero { display: none; }
  .auth-form-panel { flex: 1; padding: 24px; }
}

/* =========================================================================
   Premium loading states
   ========================================================================= */

/* Top-of-viewport progress bar (see shared.js progressBar.start()/done()) -
   an ultra-thin, high-velocity indicator for page transitions and data
   fetches, replacing full-screen spinners. Indeterminate: races to ~78%
   then holds until done() sweeps it to 100% and fades. */
#topProgressBar {
  position: fixed;
  top: 0; left: 0;
  height: 2.5px;
  width: 0%;
  background: var(--accent);
  box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.6);
  z-index: 999;
  opacity: 0;
  transition: width 0.25s ease, opacity 0.2s ease;
}
#topProgressBar.active { opacity: 1; }
#topProgressBar.done { width: 100% !important; transition: width 0.15s ease, opacity 0.3s ease 0.15s; opacity: 0; }

/* Skeleton blocks - shimmering placeholders shaped like the incoming
   content (table rows, KPI cards, form fields), not a generic spinner.
   .skeleton is the shimmer surface; .skeleton-text/.skeleton-block/
   .skeleton-circle are shape helpers composed inside it. */
@keyframes skeleton-shimmer {
  0% { background-position: -300px 0; }
  100% { background-position: 300px 0; }
}
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--gridline) 37%, var(--surface-2) 63%);
  background-size: 600px 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius-sm);
}
.skeleton-text { height: 12px; border-radius: 4px; }
.skeleton-text.w-100 { width: 100%; }
.skeleton-text.w-70 { width: 70%; }
.skeleton-text.w-50 { width: 50%; }
.skeleton-text.w-30 { width: 30%; }
.skeleton-circle { border-radius: 999px; flex-shrink: 0; }
.skeleton-block { border-radius: var(--radius-md); }

/* Table skeleton row - mirrors a real <tr>'s padding so the swap-in from
   skeleton to real data doesn't jump the layout. */
.skeleton-row td { padding: 13px 16px; }
.skeleton-row .skeleton-text { margin: 2px 0; }

/* KPI-card skeleton - same box, icon, label and value slots as a real
   .kpi-card, just shimmering instead of numbered. */
.kpi-card.is-skeleton { cursor: default; pointer-events: none; }
.kpi-card.is-skeleton:hover { transform: none; box-shadow: var(--shadow-sm); border-color: var(--border); }

/* =========================================================================
   Phase 2 - advanced tables: draggable column resize
   ========================================================================= */
thead th, .data-table thead th { position: relative; }
.col-resize-handle {
  position: absolute;
  top: 0; right: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  z-index: 3;
  touch-action: none;
}
.col-resize-handle::after {
  content: '';
  position: absolute;
  top: 4px; bottom: 4px; right: 3px;
  width: 2px;
  border-radius: 2px;
  background: transparent;
  transition: background 0.12s ease;
}
.col-resize-handle:hover::after, body.col-resizing .col-resize-handle.active::after { background: var(--accent); }
body.col-resizing { cursor: col-resize !important; }
body.col-resizing * { user-select: none !important; }

/* =========================================================================
   Phase 2 - export menu (CSV / Excel split button), used on every advanced
   table (Leads, KPI drilldown, Users, Roles, Audit Log).
   ========================================================================= */
.export-menu { position: relative; display: inline-flex; }
.export-menu-chevron { width: 12px; height: 12px; margin-left: 2px; transition: transform 0.12s ease; }
.export-menu-btn[aria-expanded="true"] .export-menu-chevron { transform: rotate(180deg); }
.export-menu-list {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 6px;
  z-index: 40;
}
.export-menu-list.hidden { display: none; }
.export-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s ease;
}
.export-menu-item:hover { background: var(--surface-2); }
.export-menu-item svg { width: 15px; height: 15px; color: var(--text-muted); flex-shrink: 0; }

/* =========================================================================
   Phase 2 - command palette (Cmd/Ctrl+K)
   ========================================================================= */
.cmd-palette-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  flex-shrink: 0;
}
.cmd-palette-trigger:hover { background: var(--surface-1); border-color: var(--accent); color: var(--text-primary); }
.cmd-palette-trigger svg { width: 15px; height: 15px; }
.cmd-palette-trigger kbd {
  font-size: 10.5px;
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--text-muted);
  background: var(--surface-1);
}
@media (max-width: 900px) { .cmd-palette-trigger { display: none; } }

.cmd-palette-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 200;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
}
.cmd-palette-overlay.hidden { display: none; }
.cmd-palette {
  width: min(560px, 92vw);
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}
.cmd-palette-input-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--gridline);
  flex-shrink: 0;
}
.cmd-palette-input-wrap svg { width: 18px; height: 18px; color: var(--text-muted); flex-shrink: 0; }
.cmd-palette-input-wrap input {
  flex: 1;
  border: none;
  outline: none;
  background: none;
  font-size: 15px;
  color: var(--text-primary);
  font-family: inherit;
}
.cmd-palette-input-wrap kbd {
  font-size: 11px;
  font-family: inherit;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 6px;
}
.cmd-palette-results { overflow-y: auto; padding: 8px; }
.cmd-section-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 10px 10px 4px;
}
.cmd-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.cmd-item svg { width: 16px; height: 16px; color: var(--text-muted); flex-shrink: 0; }
.cmd-item-label { font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.cmd-item-sublabel { font-size: 12px; color: var(--text-muted); margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.cmd-item.active, .cmd-item:hover { background: var(--surface-2); }
.cmd-empty { padding: 34px 10px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* =========================================================================
   Phase 2 - notifications bell (session-local action history)
   ========================================================================= */
.notif-bell-wrap { position: relative; flex-shrink: 0; }
.notif-bell-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.notif-bell-btn:hover, .notif-bell-btn[aria-expanded="true"] { background: var(--surface-2); border-color: var(--border); }
.notif-bell-btn svg { width: 19px; height: 19px; }
.notif-badge {
  position: absolute;
  top: 3px; right: 4px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--series-8);
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.notif-badge.hidden { display: none; }
.notif-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 320px;
  max-height: 400px;
  overflow-y: auto;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 6px;
  z-index: 40;
}
.notif-dropdown.hidden { display: none; }
.notif-dropdown-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); padding: 8px 10px 6px; }
.notif-item { display: flex; flex-direction: column; gap: 2px; padding: 9px 10px; border-radius: 8px; }
.notif-item:hover { background: var(--surface-2); }
.notif-item-message { font-size: 13px; color: var(--text-primary); font-weight: 500; }
.notif-item-time { font-size: 11px; color: var(--text-muted); }
.notif-empty { padding: 26px 10px; text-align: center; color: var(--text-muted); font-size: 13px; }

.notif-toast-wrap {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 340px;
}
.notif-toast {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  animation: notif-toast-in 0.2s ease;
}
.notif-toast.leaving { animation: notif-toast-out 0.18s ease forwards; }
@keyframes notif-toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes notif-toast-out { from { opacity: 1; } to { opacity: 0; transform: translateY(-6px); } }
