@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');
/* =============================================================================
   Lab-Driver · Design System v3 — Light Mode
   Clean, medical-professional. White base, soft pastel aurora, gradient accents.
   ============================================================================= */

/* Inter via Google Fonts (was rsms.me — a slow single-origin host that
   render-blocked every page behind a DNS+TLS+CSS+font serial chain).
   Google Fonts resolves in a fraction of the time and display=swap paints
   text immediately in the fallback font while Inter streams in. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');

:root {
  /* Background */
  --bg-0: #ffffff;
  --bg-1: #f8fafc;
  --bg-2: #f1f5f9;

  /* Surfaces */
  --surface-0: #ffffff;
  --surface-glass: rgba(255, 255, 255, 0.85);
  --surface-1: #f8fafc;
  --surface-2: #f1f5f9;
  --surface-3: #e2e8f0;
  --border: rgba(15, 23, 42, 0.08);
  --border-strong: rgba(15, 23, 42, 0.14);

  /* Text */
  --text: #0b1026;
  --text-dim: #475569;
  --text-faint: #64748b;
  --text-ghost: #94a3b8;

  /* Brand accents — still vibrant, just tuned for light bg */
  --a-cyan: #0ea5e9;
  --a-blue: #4f46e5;
  --a-violet: #7c3aed;
  --a-pink: #ec4899;
  --a-emerald: #10b981;
  --a-amber: #f59e0b;

  /* Semantic */
  --success: #10b981;
  --success-glow: rgba(16, 185, 129, 0.28);
  --danger: #e11d48;
  --danger-glow: rgba(225, 29, 72, 0.25);
  --warn: #f59e0b;
  --info: #0ea5e9;

  /* Gradients */
  --grad-primary: linear-gradient(135deg, #6366f1 0%, #7c3aed 50%, #ec4899 100%);
  --grad-cool:    linear-gradient(135deg, #0ea5e9 0%, #6366f1 100%);
  --grad-warm:    linear-gradient(135deg, #ec4899 0%, #f59e0b 100%);
  --grad-mint:    linear-gradient(135deg, #10b981 0%, #06b6d4 100%);

  /* Radii */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;

  /* Shadow (matters more on light) */
  --shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.05);
  --shadow-2: 0 4px 12px rgba(15, 23, 42, 0.06), 0 10px 24px rgba(15, 23, 42, 0.06);
  --shadow-3: 0 20px 48px rgba(15, 23, 42, 0.12), 0 4px 16px rgba(15, 23, 42, 0.06);
  --glow-primary: 0 0 40px rgba(99, 102, 241, 0.28);
  --glow-accent:  0 0 40px rgba(124, 58, 237, 0.22);

  /* Timing */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* =============================================================================
   DARK THEME — Lab Carriers only
   =============================================================================
   Opt-in via <html data-theme="dark">. Nothing below applies unless that
   attribute is set, so every page renders exactly as it does today until a
   user turns it on.

   THIS ONLY REACHES COLOURS THAT GO THROUGH THE TOKENS. Roughly half the
   colour in this app is hardcoded hex inside individual pages (~6,950
   occurrences across 94 files), and 17 pages do not link this stylesheet at
   all. Those keep their light colours regardless. Pages are converted to
   tokens one at a time; docs/FILE_MAP_WEB.md records which are done.

   marvin-site/ has its OWN styles.css and is deliberately NOT affected.

   Values are chosen for contrast, not by inverting the light set:
     - surfaces step UP in lightness as they stack, the reverse of light mode,
       because on a dark ground elevation reads as lighter
     - accents are lifted a step; the light-mode blues and violets go muddy
     - shadows carry little weight on dark, so borders do the separating
   ========================================================================== */
[data-theme="dark"] {
  --bg-0: #0b1020;
  --bg-1: #10162a;
  --bg-2: #161d33;

  --surface-0: #141b2e;
  --surface-glass: rgba(26, 34, 56, 0.85);
  --surface-1: #1a2238;
  --surface-2: #202942;
  --surface-3: #2a3450;
  --border: rgba(226, 232, 240, 0.10);
  --border-strong: rgba(226, 232, 240, 0.18);

  /* Not pure white — #e8edf7 avoids the halo pure white gives on dark. */
  --text: #e8edf7;
  --text-dim: #b2bdd4;
  --text-faint: #8b98b4;
  /* #64718d measured 2.94:1 on --surface-2 — below even the 3:1 large-text
     floor. Ghost text is placeholders and disabled states; it should be
     quiet, not unreadable. #7885a2 keeps it quiet at 3.89:1 worst case. */
  --text-ghost: #7885a2;

  --a-cyan: #38bdf8;
  --a-blue: #818cf8;
  --a-violet: #a78bfa;
  --a-pink: #f472b6;
  --a-emerald: #34d399;
  --a-amber: #fbbf24;

  --success: #34d399;
  --success-glow: rgba(52, 211, 153, 0.30);
  --danger: #fb7185;
  --danger-glow: rgba(251, 113, 133, 0.28);
  --warn: #fbbf24;
  --info: #38bdf8;

  --grad-primary: linear-gradient(135deg, #818cf8 0%, #a78bfa 50%, #f472b6 100%);
  --grad-cool:    linear-gradient(135deg, #38bdf8 0%, #818cf8 100%);
  --grad-warm:    linear-gradient(135deg, #f472b6 0%, #fbbf24 100%);
  --grad-mint:    linear-gradient(135deg, #34d399 0%, #22d3ee 100%);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.30);
  --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.42), 0 10px 24px rgba(0, 0, 0, 0.34);
  --shadow-3: 0 20px 48px rgba(0, 0, 0, 0.55), 0 4px 16px rgba(0, 0, 0, 0.35);
  --glow-primary: 0 0 40px rgba(129, 140, 248, 0.26);
  --glow-accent:  0 0 40px rgba(167, 139, 250, 0.22);

  color-scheme: dark;   /* native scrollbars, form controls, date pickers */
}

/* The pastel aurora is tuned for a white page; on dark it turns into muddy
   smears. Dim it rather than remove it, so the background keeps some depth. */
[data-theme="dark"] body::before { opacity: 0.35; }

/* The top bar is a translucent white pane in light mode. Left alone it stays a
   pale veil on a dark page, carrying near-white text — the same hardcoded-
   surface / themed-ink mismatch that made the nav dropdown unreadable. Pages
   with their own chrome (body.lc-neo on dispatch-overview, lax-home) override
   this anyway; these two rules cover everything that does not. */
[data-theme="dark"] .topbar { background: rgba(20, 27, 46, 0.72); }
[data-theme="dark"] .topbar-collapse { background: rgba(20, 27, 46, 0.96); }

/* Theme toggle in the shared top bar (injected by mountTopBar in app.js). */
.__themeBtn {
  padding: 0; width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; line-height: 1;
}
.__themeIcon { font-size: 15px; line-height: 1; }

/* Colour is the ONE thing that should transition here. Animating `all` makes
   every layout property on the page animate on the theme flip, which looks
   like the whole UI is melting. */
html { transition: background-color .22s var(--ease-out), color .22s var(--ease-out); }
body, .card, .panel, header, nav, aside, table, td, th, input, select, textarea, button {
  transition: background-color .22s var(--ease-out),
              color .22s var(--ease-out),
              border-color .22s var(--ease-out);
}
@media (prefers-reduced-motion: reduce) {
  html, body, .card, .panel, header, nav, aside, table, td, th,
  input, select, textarea, button { transition: none; }
}

* { box-sizing: border-box; }
*::selection { background: rgba(99, 102, 241, 0.22); color: var(--text); }

html, body {
  margin: 0; padding: 0;
  min-height: 100vh;
  font-family: 'Poppins', system-ui, -apple-system, sans-serif;
  font-feature-settings: 'cv11', 'ss01', 'ss03';
  letter-spacing: -0.005em;
  color: var(--text);
  background: var(--bg-0);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------- Aurora background (soft pastel, drifts slowly) ---------- */
body::before {
  content: "";
  position: fixed;
  inset: -20%;
  z-index: -2;
  background:
    radial-gradient(closest-side at 15% 8%,  rgba(124, 58, 237, 0.14), transparent 70%),
    radial-gradient(closest-side at 85% 10%, rgba(14, 165, 233, 0.14),  transparent 70%),
    radial-gradient(closest-side at 50% 90%, rgba(236, 72, 153, 0.10),  transparent 70%),
    radial-gradient(closest-side at 10% 80%, rgba(16, 185, 129, 0.10),  transparent 70%),
    linear-gradient(160deg, #ffffff, #f8fafc 55%, #eef2ff);
  animation: auroraDrift 40s ease-in-out infinite alternate;
}

body::after {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(rgba(15, 23, 42, 0.05) 1px, transparent 1px);
  background-size: 28px 28px;
  mask-image: radial-gradient(ellipse at 50% 30%, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse at 50% 30%, #000 30%, transparent 75%);
}

@keyframes auroraDrift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(3%, -2%) scale(1.05); }
  100% { transform: translate(-2%, 2%) scale(1.02); }
}

/* ---------- Typography ---------- */
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
h1 { font-size: clamp(28px, 3.2vw, 38px); line-height: 1.1; }
h2 { font-size: 20px; line-height: 1.25; }
h3 { font-size: 16px; line-height: 1.3; }
p  { line-height: 1.55; }
code, pre {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
}
code {
  background: rgba(99, 102, 241, 0.08);
  padding: 2px 6px;
  border-radius: 6px;
  color: #4338ca;
  border: 1px solid rgba(99, 102, 241, 0.12);
}

a { color: var(--a-blue); text-decoration: none; transition: color 0.15s ease; }
a:hover { color: var(--a-violet); }

/* ---------- Top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px clamp(16px, 3vw, 32px);
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 50;
}
.topbar .brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; letter-spacing: -0.01em;
  color: var(--text);
}
.topbar .brand .logo {
  width: 56px; height: 38px; border-radius: 0;
  background: url('logo.png') center/contain no-repeat;
  font-size: 0;
  text-indent: -9999px;
  flex: 0 0 auto;
}
.topbar .brand .logo::after { content: none; }
.topbar nav { display: flex; gap: 4px; }
.topbar nav a {
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 10px;
  transition: all 0.15s var(--ease-out);
}
.topbar nav a:hover {
  color: var(--text);
  background: var(--surface-2);
  text-decoration: none;
}
.topbar nav a.active {
  color: var(--text);
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--border);
}
.topbar .user {
  display: flex; align-items: center; gap: 12px;
  color: var(--text-dim); font-size: 13px;
}

/* ---------- Hidden attribute (browser default — restored with !important
     because various .btn / .field / .grid rules use display:flex/grid/inline-block
     and beat the UA [hidden] rule on specificity) ---------- */
[hidden] { display: none !important; }

/* ---------- Page container ---------- */
.container {
  max-width: 1240px;
  margin: 0 auto;
  padding: 32px clamp(16px, 3vw, 32px) 64px;
}
.container.narrow { max-width: 760px; }
.container.wide { max-width: 1400px; }

/* ---------- Page header ---------- */
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 28px;
  flex-wrap: wrap;
}
.page-header h1 { font-size: 28px; }
.page-header .subtitle {
  color: var(--text-dim);
  font-size: 15px;
  margin-top: 6px;
  max-width: 600px;
}

/* ---------- Cards ---------- */
.card {
  background: var(--surface-glass);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 24px;
  box-shadow: var(--shadow-2);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  position: relative;
}
.card + .card { margin-top: 20px; }
.card h2 { margin-bottom: 4px; }
.card .card-desc {
  color: var(--text-dim);
  font-size: 14px;
  margin-top: 0;
  margin-bottom: 18px;
}

/* ---------- Forms ---------- */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 680px) {
  .form-grid { grid-template-columns: 1fr; }
}
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field.full { grid-column: 1 / -1; }
.field label {
  font-size: 11px;
  color: var(--text-faint);
  font-weight: 700;
}
.field input,
.field select,
.field textarea {
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: 13px 15px;
  color: var(--text);
  font-family: inherit;
  font-size: 15px;
  outline: none;
  transition: all 0.2s var(--ease-out);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--text-ghost); }
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--a-blue);
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12);
}
.field textarea { min-height: 96px; resize: vertical; }
.field .hint {
  font-size: 12.5px;
  color: var(--text-faint);
  line-height: 1.4;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 11px 18px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-strong);
  cursor: pointer;
  color: var(--text);
  background: var(--surface-0);
  text-decoration: none;
  transition: all 0.18s var(--ease-out);
  position: relative;
  overflow: hidden;
  white-space: nowrap;
  box-shadow: var(--shadow-1);
}
.btn:hover:not(:disabled) {
  background: var(--surface-1);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn:active:not(:disabled) { transform: translateY(0); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn.primary {
  background: var(--grad-primary);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 16px rgba(99, 102, 241, 0.28), inset 0 1px 0 rgba(255,255,255,0.25);
}
.btn.primary:hover:not(:disabled) {
  box-shadow: 0 10px 24px rgba(99, 102, 241, 0.38), inset 0 1px 0 rgba(255,255,255,0.3);
  transform: translateY(-1px);
  filter: brightness(1.04);
}
.btn.success {
  background: var(--grad-mint);
  color: #ffffff;
  border-color: transparent;
  box-shadow: 0 6px 16px rgba(16, 185, 129, 0.28), inset 0 1px 0 rgba(255,255,255,0.25);
}
.btn.success:hover:not(:disabled) { filter: brightness(1.05); }
.btn.danger {
  background: linear-gradient(135deg, #e11d48, #ec4899);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 16px rgba(225, 29, 72, 0.28), inset 0 1px 0 rgba(255,255,255,0.25);
}
.btn.ghost {
  background: transparent;
  border-color: var(--border-strong);
  box-shadow: none;
  color: var(--text-dim);
}
.btn.ghost:hover:not(:disabled) { background: var(--surface-1); border-color: var(--border-strong); color: var(--text); }

.btn.lg { padding: 14px 22px; font-size: 15px; }
.btn.xl { padding: 16px 28px; font-size: 16px; border-radius: var(--r-lg); }
.btn.block { width: 100%; }

/* Shine animation on primary CTAs */
.btn.primary::before,
.btn.success::before {
  content: "";
  position: absolute;
  top: 0; left: -100%;
  width: 100%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent);
  transition: left 0.6s var(--ease-out);
}
.btn.primary:hover::before,
.btn.success:hover::before { left: 100%; }

.btn-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 24px;
  flex-wrap: wrap;
}
.btn-row .spacer { flex: 1; }

/* ---------- Stepper ---------- */
.stepper {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 26px;
  counter-reset: step;
}
.stepper .step {
  flex: 1;
  padding: 12px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 13px;
  font-weight: 500;
  text-align: center;
  background: var(--surface-0);
  transition: all 0.25s var(--ease-out);
  position: relative;
}
.stepper .step.active {
  color: #312e81;
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.10), rgba(124, 58, 237, 0.10));
  border-color: rgba(99, 102, 241, 0.35);
  font-weight: 600;
  box-shadow: 0 6px 14px rgba(99, 102, 241, 0.12);
}
.stepper .step.done {
  color: #065f46;
  border-color: rgba(16, 185, 129, 0.32);
  background: rgba(16, 185, 129, 0.08);
}

/* ---------- Banners ---------- */
.banner {
  padding: 13px 16px;
  border-radius: var(--r-md);
  font-size: 14px;
  margin: 14px 0;
  border: 1px solid var(--border);
  display: flex; align-items: flex-start; gap: 10px;
  animation: slideDown 0.3s var(--ease-out);
}
.banner::before {
  font-weight: 700;
  flex-shrink: 0;
  font-size: 14px;
}
.banner.error {
  background: rgba(225, 29, 72, 0.08);
  border-color: rgba(225, 29, 72, 0.28);
  color: #9f1239;
}
.banner.error::before { content: "⚠"; color: var(--danger); }
.banner.success {
  background: rgba(16, 185, 129, 0.10);
  border-color: rgba(16, 185, 129, 0.30);
  color: #065f46;
}
.banner.success::before { content: "✓"; color: var(--success); }
.banner.info {
  background: rgba(14, 165, 233, 0.10);
  border-color: rgba(14, 165, 233, 0.30);
  color: #0c4a6e;
}
.banner.info::before { content: "ℹ"; color: var(--info); }

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

/* ---------- Chips ---------- */
.chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface-0);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  color: var(--text-dim);
  user-select: none;
  transition: all 0.18s var(--ease-out);
  box-shadow: var(--shadow-1);
}
.chip:hover { background: var(--surface-1); color: var(--text); transform: translateY(-1px); }
.chip.active {
  color: #fff;
  border-color: transparent;
  background: var(--grad-cool);
  box-shadow: 0 4px 14px rgba(14, 165, 233, 0.32);
}

/* ---------- Toggle row ---------- */
.toggle-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  user-select: none;
  transition: all 0.18s var(--ease-out);
  font-size: 14px;
  color: var(--text);
}
.toggle-row:hover { background: var(--surface-1); border-color: var(--border-strong); }
.toggle-row input[type="checkbox"] {
  width: 20px; height: 20px; accent-color: var(--a-blue); margin: 0;
}

/* ---------- KPI tiles ---------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 28px;
}
@media (max-width: 960px) { .kpi-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .kpi-row { grid-template-columns: 1fr; } }

.kpi {
  position: relative;
  padding: 20px 22px;
  border-radius: var(--r-lg);
  background: var(--surface-0);
  border: 1px solid var(--border);
  overflow: hidden;
  transition: transform 0.25s var(--ease-out), box-shadow 0.2s, border-color 0.2s;
  min-height: 110px;
  box-shadow: var(--shadow-1);
}
.kpi:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-2);
}
.kpi::before {
  content: "";
  position: absolute;
  top: -30%; right: -20%;
  width: 180px; height: 180px;
  background: var(--grad-primary);
  filter: blur(60px);
  opacity: 0.18;
  pointer-events: none;
  transition: opacity 0.3s;
}
.kpi:hover::before { opacity: 0.28; }
.kpi .kpi-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-faint);
}
.kpi .kpi-value {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-top: 4px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.kpi .kpi-sub {
  font-size: 12.5px;
  color: var(--text-dim);
  margin-top: 6px;
}
.kpi.success::before { background: var(--grad-mint); }
.kpi.warn::before    { background: var(--grad-warm); }
.kpi.cool::before    { background: var(--grad-cool); }
.kpi.violet::before  { background: linear-gradient(135deg, #9466ff, #ec4899); }
.kpi.amber::before   { background: linear-gradient(135deg, #f59e0b, #ec4899); }

/* Clickable tiles (when tile has a linkTo) */
.kpi.clickable { cursor: pointer; }
.kpi.clickable:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2), 0 12px 28px rgba(99, 102, 241, 0.18);
  border-color: rgba(99, 102, 241, 0.32);
}
.kpi.clickable .open-arrow {
  position: absolute;
  bottom: 14px; right: 16px;
  width: 26px; height: 26px;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--text-faint);
  background: var(--surface-1);
  border: 1px solid var(--border);
  transition: all 0.2s var(--ease-out);
  z-index: 1;
}
.kpi.clickable:hover .open-arrow {
  background: var(--grad-primary);
  color: #fff;
  transform: translateX(2px);
  border-color: transparent;
}

/* Tile in edit mode — overlay with remove + edit buttons */
.kpi.editing { cursor: grab; outline: 2px dashed var(--a-violet); outline-offset: 2px; }
.kpi .tile-actions {
  position: absolute;
  top: 10px; right: 10px;
  display: none;
  gap: 6px;
  z-index: 2;
}
.kpi.editing .tile-actions { display: inline-flex; }
.kpi .tile-actions button {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  cursor: pointer;
  display: grid; place-items: center;
  color: var(--text-dim);
  box-shadow: var(--shadow-1);
}
.kpi .tile-actions button:hover { color: var(--text); background: var(--surface-1); }
.kpi .tile-actions button.danger { color: var(--danger); }
.kpi .tile-actions button.danger:hover { background: rgba(225, 29, 72, 0.08); }

/* "Add tile" placeholder — looks like a tile but dashed */
.kpi.add-tile {
  border-style: dashed;
  background: transparent;
  cursor: pointer;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  color: var(--text-faint);
  transition: all 0.2s var(--ease-out);
  min-height: 110px;
  box-shadow: none;
}
.kpi.add-tile::before { display: none; }
.kpi.add-tile:hover { color: var(--a-blue); border-color: var(--a-blue); background: rgba(99, 102, 241, 0.04); }
.kpi.add-tile .plus { font-size: 28px; line-height: 1; margin-bottom: 4px; font-weight: 300; }

/* Modal */
.modal-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.4);
  backdrop-filter: blur(4px);
  z-index: 100;
  align-items: center; justify-content: center;
  padding: 20px;
  overflow-y: auto;            /* scroll the OVERLAY when modal is taller than viewport */
  -webkit-overflow-scrolling: touch;
}
.modal-overlay.open { display: flex; animation: fadeIn 0.2s var(--ease-out); }
.modal-card {
  max-width: 520px; width: 100%;
  padding: 28px;
  animation: rise 0.3s var(--ease-out);
  margin: auto;                /* with align-items: center + overflow scroll,
                                  short content centers, tall content scrolls cleanly */
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.kpi .kpi-icon {
  position: absolute;
  top: 18px; right: 18px;
  width: 34px; height: 34px;
  border-radius: 10px;
  background: var(--surface-1);
  display: grid; place-items: center;
  color: var(--text);
  border: 1px solid var(--border);
}

/* ---------- Tables ---------- */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.search {
  position: relative;
  flex: 1;
  max-width: 420px;
  min-width: 240px;
}
.search input {
  width: 100%;
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: 12px 14px 12px 42px;
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  outline: none;
  transition: all 0.2s var(--ease-out);
  box-shadow: var(--shadow-1);
}
.search input:focus {
  border-color: var(--a-blue);
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12);
}
.search input::placeholder { color: var(--text-ghost); }
.search svg {
  position: absolute;
  top: 50%; left: 14px;
  transform: translateY(-50%);
  color: var(--text-faint);
}

.table-wrap {
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-1);
}
table.clients {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
table.clients th,
table.clients td {
  text-align: left;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.clients th {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-faint);
  background: var(--surface-1);
  position: sticky; top: 0;
}
table.clients tr { transition: background 0.15s; }
table.clients tr:last-child td { border-bottom: none; }
table.clients tr:hover td { background: var(--surface-1); }
table.clients .muted { color: var(--text-faint); }
table.clients .row-actions { display: flex; gap: 6px; justify-content: flex-end; }
table.clients .row-actions .btn { padding: 7px 12px; font-size: 12.5px; }

.avatar {
  width: 32px; height: 32px;
  border-radius: 10px;
  display: inline-grid; place-items: center;
  color: #fff;
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.5px;
  flex-shrink: 0;
  margin-right: 10px;
  vertical-align: middle;
  border: 1px solid rgba(255,255,255,0.25);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), var(--shadow-1);
}

/* ---------- Status pills ---------- */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  border: 1px solid;
}
.status-pill::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 6px currentColor;
}
.status-pill.approved,
.status-pill.active,
.status-pill.delivered { background: rgba(16, 185, 129, 0.12); color: #047857; border-color: rgba(16, 185, 129, 0.32); }
.status-pill.pending   { background: rgba(245, 158, 11, 0.12); color: #b45309; border-color: rgba(245, 158, 11, 0.32); }
.status-pill.in-progress,
.status-pill.assigned,
.status-pill.accepted  { background: rgba(14, 165, 233, 0.12); color: #0369a1; border-color: rgba(14, 165, 233, 0.32); }
.status-pill.inactive,
.status-pill.cancelled { background: rgba(225, 29, 72, 0.10); color: #9f1239; border-color: rgba(225, 29, 72, 0.28); }

/* ---------- Auth pages ---------- */
.auth-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 440px;
  padding: 40px 32px;
  animation: rise 0.5s var(--ease-out);
  background: var(--surface-0);
  box-shadow: var(--shadow-3);
  border-color: var(--border);
}
@keyframes rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
.auth-card .auth-logo {
  width: 68px; height: 68px; border-radius: 18px;
  margin: 0 auto 18px;
  background: var(--grad-primary);
  display: grid; place-items: center;
  font-weight: 900; font-size: 28px; color: #fff;
  box-shadow: var(--glow-primary), inset 0 2px 0 rgba(255,255,255,0.3);
  position: relative;
  overflow: hidden;
  animation: breathe 4s ease-in-out infinite;
}
.auth-card .auth-logo.client {
  background: var(--grad-mint);
  color: #ffffff;
  box-shadow: 0 0 36px var(--success-glow), inset 0 2px 0 rgba(255,255,255,0.35);
}
.auth-card .auth-logo::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 30% 20%, rgba(255,255,255,0.45), transparent 55%);
}
@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.04); }
}
.auth-card h1 {
  font-size: 26px;
  margin: 0 0 6px;
  text-align: center;
}
.auth-card .subtitle {
  color: var(--text-dim);
  font-size: 14px;
  margin: 0 auto 24px;
  text-align: center;
  max-width: 320px;
}
.auth-card .btn.primary,
.auth-card .btn.success { width: 100%; margin-top: 14px; padding: 14px 20px; font-size: 15px; }
.auth-footnote {
  margin-top: 18px;
  font-size: 12.5px;
  color: var(--text-faint);
  text-align: center;
  line-height: 1.6;
}

/* ---------- Loader + misc ---------- */
.loader {
  display: inline-block;
  width: 16px; height: 16px;
  border: 2px solid rgba(15, 23, 42, 0.15);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.empty {
  padding: 60px 24px;
  text-align: center;
  color: var(--text-dim);
}
.empty .big {
  font-size: 48px;
  margin-bottom: 12px;
  opacity: 0.75;
}

.kv {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 10px 18px;
  font-size: 14px;
}
.kv dt { color: var(--text-faint); font-weight: 500; }
.kv dd { margin: 0; color: var(--text); }

/* =============================================================================
   LANDING PAGE
   ============================================================================= */

.landing-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px clamp(20px, 5vw, 56px);
  position: absolute; top: 0; left: 0; right: 0; z-index: 20;
}
.landing-nav .brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; color: var(--text);
  text-decoration: none;
}
.landing-nav .brand .logo {
  width: 64px; height: 42px; border-radius: 0;
  background: url('logo.png') center/contain no-repeat;
  font-size: 0;
  text-indent: -9999px;
  flex: 0 0 auto;
}
.landing-nav .nav-links {
  display: flex; gap: 8px; align-items: center;
}

.hero {
  position: relative;
  padding: 120px clamp(20px, 5vw, 56px) 80px;
  max-width: 1240px;
  margin: 0 auto;
  text-align: center;
}
.hero .eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-dim);
  margin-bottom: 28px;
  box-shadow: var(--shadow-1);
  animation: rise 0.6s var(--ease-out);
}
.hero .eyebrow .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 12px var(--success-glow);
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(0.85); }
}

.hero h1.hero-title {
  font-size: clamp(40px, 6.5vw, 74px);
  line-height: 1.04;
  letter-spacing: -0.035em;
  font-weight: 800;
  margin: 0 auto;
  max-width: 900px;
  animation: rise 0.7s var(--ease-out) 0.05s both;
}
.hero h1.hero-title .grad {
  background: var(--grad-primary);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  display: inline-block;
}
.hero .hero-sub {
  margin: 22px auto 0;
  max-width: 640px;
  font-size: clamp(16px, 1.8vw, 19px);
  line-height: 1.55;
  color: var(--text-dim);
  animation: rise 0.7s var(--ease-out) 0.1s both;
}
.hero-cta {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 36px;
  flex-wrap: wrap;
  animation: rise 0.7s var(--ease-out) 0.15s both;
}
.hero-meta {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-top: 30px;
  color: var(--text-faint);
  font-size: 13px;
  flex-wrap: wrap;
  animation: rise 0.7s var(--ease-out) 0.2s both;
}
.hero-meta > span { display: inline-flex; align-items: center; gap: 6px; }

/* Floating preview card */
.hero-preview {
  position: relative;
  max-width: 1080px;
  margin: 60px auto 0;
  padding: 10px;
  border-radius: var(--r-xl);
  background: var(--surface-0);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-3), 0 40px 80px rgba(99, 102, 241, 0.12);
  animation: rise 0.9s var(--ease-out) 0.3s both;
  overflow: hidden;
}
.hero-preview::before {
  content: "";
  position: absolute;
  top: -1px; left: 10%; right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(124, 58, 237, 0.35), transparent);
}
.hero-preview-inner {
  border-radius: calc(var(--r-xl) - 8px);
  background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
  overflow: hidden;
  border: 1px solid var(--border);
}
.hero-preview-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-1);
}
.hero-preview-bar .traffic { display: flex; gap: 6px; }
.hero-preview-bar .traffic i {
  width: 12px; height: 12px; border-radius: 50%; display: inline-block;
}
.hero-preview-bar .traffic i:nth-child(1) { background: #ff6a5a; }
.hero-preview-bar .traffic i:nth-child(2) { background: #fbc02d; }
.hero-preview-bar .traffic i:nth-child(3) { background: #34c759; }
.hero-preview-bar .url {
  margin-left: 12px;
  font-size: 12px;
  color: var(--text-faint);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.hero-preview img,
.hero-preview .hero-preview-body {
  display: block; width: 100%;
}
.hero-preview-body {
  padding: 24px;
  background: var(--bg-1);
}

/* Section */
section.pg {
  max-width: 1240px;
  margin: 0 auto;
  padding: 80px clamp(20px, 5vw, 56px);
}
.section-head {
  text-align: center;
  max-width: 720px;
  margin: 0 auto 52px;
}
.section-head .eyebrow-txt {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  color: var(--a-blue);
  margin-bottom: 14px;
}
.section-head h2 {
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.12;
  letter-spacing: -0.03em;
}
.section-head p {
  margin-top: 14px;
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1.6;
}

/* Feature grid */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
@media (max-width: 960px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .feature-grid { grid-template-columns: 1fr; } }
.feature {
  padding: 28px;
  border-radius: var(--r-lg);
  background: var(--surface-0);
  border: 1px solid var(--border);
  position: relative;
  overflow: hidden;
  transition: all 0.25s var(--ease-out);
  box-shadow: var(--shadow-1);
}
.feature:hover {
  transform: translateY(-3px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-2);
}
.feature .fi {
  width: 48px; height: 48px;
  border-radius: 12px;
  background: var(--grad-cool);
  display: grid; place-items: center;
  color: #fff;
  margin-bottom: 18px;
  box-shadow: 0 8px 18px rgba(14, 165, 233, 0.28);
}
.feature:nth-child(2) .fi { background: var(--grad-mint); color: #ffffff; box-shadow: 0 8px 18px rgba(16, 185, 129, 0.28); }
.feature:nth-child(3) .fi { background: var(--grad-warm); box-shadow: 0 8px 18px rgba(236, 72, 153, 0.28); }
.feature:nth-child(4) .fi { background: linear-gradient(135deg, #7c3aed, #ec4899); box-shadow: 0 8px 18px rgba(124, 58, 237, 0.26); }
.feature:nth-child(5) .fi { background: linear-gradient(135deg, #f59e0b, #ec4899); box-shadow: 0 8px 18px rgba(245, 158, 11, 0.26); }
.feature:nth-child(6) .fi { background: var(--grad-primary); box-shadow: 0 8px 18px rgba(124, 58, 237, 0.26); }
.feature h3 {
  font-size: 18px;
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}
.feature p {
  font-size: 14.5px;
  color: var(--text-dim);
  line-height: 1.55;
  margin: 0;
}

/* How-it-works */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  counter-reset: step;
}
@media (max-width: 760px) { .steps { grid-template-columns: 1fr; } }
.step-card {
  padding: 28px;
  border-radius: var(--r-lg);
  background: var(--surface-0);
  border: 1px solid var(--border);
  position: relative;
  counter-increment: step;
  box-shadow: var(--shadow-1);
}
.step-card::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  top: 22px; right: 24px;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.02em;
  background: var(--grad-primary);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  opacity: 0.55;
}
.step-card h3 { font-size: 17px; margin-bottom: 8px; }
.step-card p { font-size: 14.5px; color: var(--text-dim); margin: 0; line-height: 1.55; }

/* Big CTA */
.big-cta {
  margin: 80px auto;
  max-width: 1080px;
  padding: 60px clamp(24px, 5vw, 56px);
  text-align: center;
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(124, 58, 237, 0.08), rgba(236, 72, 153, 0.06));
  border: 1px solid var(--border-strong);
  box-shadow: 0 30px 60px rgba(99, 102, 241, 0.10);
  position: relative;
  overflow: hidden;
}
.big-cta::before {
  content: "";
  position: absolute; inset: -60%;
  background: radial-gradient(closest-side, rgba(124, 58, 237, 0.18), transparent 70%);
  animation: auroraDrift 20s ease-in-out infinite alternate;
  z-index: -1;
}
.big-cta h2 { font-size: clamp(28px, 4vw, 40px); letter-spacing: -0.03em; line-height: 1.15; }
.big-cta p { margin: 14px auto 28px; max-width: 520px; color: var(--text-dim); font-size: 16px; }

/* Footer */
footer.site-footer {
  padding: 48px clamp(20px, 5vw, 56px) 60px;
  border-top: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 13px;
  text-align: center;
}
footer.site-footer .brand-line {
  display: inline-flex; align-items: center; gap: 10px;
  margin-bottom: 14px; color: var(--text-dim);
}
footer.site-footer .brand-line .logo {
  width: 40px; height: 26px; border-radius: 0;
  background: url('logo.png') center/contain no-repeat;
  font-size: 0;
  text-indent: -9999px;
}

/* =============================================================================
   Upload page — hero, progress pills, numbered sections, big dropzone
   ============================================================================= */

.upload-hero {
  text-align: center;
  padding: 16px 0 44px;
  max-width: 700px;
  margin: 0 auto;
}
.upload-hero .hero-icon {
  width: 84px; height: 84px;
  margin: 0 auto 22px;
  border-radius: 24px;
  background: var(--grad-primary);
  display: grid; place-items: center;
  color: #ffffff;
  box-shadow:
    0 20px 40px rgba(124, 58, 237, 0.28),
    inset 0 2px 0 rgba(255, 255, 255, 0.3);
  animation: breathe 4s ease-in-out infinite;
  position: relative;
  overflow: hidden;
}
.upload-hero .hero-icon::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.5), transparent 55%);
}
.upload-hero .hero-icon svg { position: relative; z-index: 1; }
.upload-hero h1 {
  font-size: clamp(30px, 4vw, 44px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.08;
  margin-bottom: 14px;
}
.upload-hero h1 .grad {
  background: var(--grad-primary);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.upload-hero p {
  color: var(--text-dim);
  font-size: 17px;
  margin: 0 auto;
  max-width: 540px;
  line-height: 1.5;
}
.upload-hero p code { font-size: 14px; }

/* Progress pills */
.progress-pills {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 30px 0 4px;
  flex-wrap: wrap;
}
.progress-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 16px 7px 9px;
  border-radius: 999px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-faint);
  box-shadow: var(--shadow-1);
  transition: all 0.3s var(--ease-out);
}
.progress-pill.current {
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.10), rgba(124, 58, 237, 0.10));
  border-color: rgba(99, 102, 241, 0.32);
  color: #312e81;
  box-shadow: 0 4px 14px rgba(99, 102, 241, 0.16);
}
.progress-pill.done {
  color: #065f46;
  border-color: rgba(16, 185, 129, 0.32);
  background: rgba(16, 185, 129, 0.08);
}
.progress-pill .num {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-faint);
  font-weight: 800;
  font-size: 11px;
  flex-shrink: 0;
}
.progress-pill.current .num { background: var(--grad-primary); color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,0.3); }
.progress-pill.done .num    { background: var(--grad-mint);    color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,0.3); }

/* Numbered section header (used inside a .card) */
.section-head-row {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.section-head-row .spacer { flex: 1; }
.section-head-row h2 { margin: 0; font-size: 18px; letter-spacing: -0.01em; }
.section-head-row p  { margin: 2px 0 0; color: var(--text-dim); font-size: 13.5px; }
.section-num {
  display: inline-grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 13px;
  background: var(--grad-primary);
  color: #ffffff;
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -0.01em;
  flex-shrink: 0;
  box-shadow: 0 6px 14px rgba(99, 102, 241, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  position: relative;
  overflow: hidden;
}
.section-num::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 28% 22%, rgba(255,255,255,0.4), transparent 60%);
  pointer-events: none;
}
.section-num.mint { background: var(--grad-mint); box-shadow: 0 6px 14px rgba(16, 185, 129, 0.28), inset 0 1px 0 rgba(255,255,255,0.3); }
.section-num.warm { background: var(--grad-warm); box-shadow: 0 6px 14px rgba(236, 72, 153, 0.28), inset 0 1px 0 rgba(255,255,255,0.3); }

/* Floating "Back" link */
.back-floating {
  position: absolute;
  top: 22px;
  left: clamp(16px, 3vw, 32px);
  z-index: 5;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  border-radius: var(--r-md);
  background: var(--surface-0);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  color: var(--text-dim);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  transition: all 0.15s var(--ease-out);
}
.back-floating:hover {
  color: var(--text);
  background: var(--surface-1);
  text-decoration: none;
  transform: translateX(-2px);
}

/* =============================================================================
   Big dropzone — hero-level visual
   ============================================================================= */
.uploader {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 60px 36px;
  text-align: center;
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.025), rgba(236, 72, 153, 0.02));
  border: 2px dashed var(--border-strong);
  border-radius: var(--r-lg);
  cursor: pointer;
  transition: all 0.25s var(--ease-out);
  overflow: hidden;
  color: var(--text);
}
.uploader input[type="file"] { display: none; }
.uploader::before {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle at 18% 20%, rgba(99, 102, 241, 0.10), transparent 50%),
    radial-gradient(circle at 82% 80%, rgba(236, 72, 153, 0.08), transparent 50%);
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
}
.uploader:hover {
  border-color: var(--a-blue);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.uploader:hover::before { opacity: 1; }
.uploader.dragging {
  border-color: var(--a-violet);
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.06), rgba(124, 58, 237, 0.06));
  transform: scale(1.005);
  box-shadow: 0 20px 50px rgba(124, 58, 237, 0.18);
}
.uploader.dragging::before { opacity: 1; }

.uploader .upload-ill {
  position: relative;
  width: 96px; height: 96px;
  border-radius: 26px;
  background: var(--grad-primary);
  display: grid; place-items: center;
  color: #fff;
  box-shadow:
    0 18px 40px rgba(124, 58, 237, 0.3),
    inset 0 2px 0 rgba(255, 255, 255, 0.3);
  overflow: hidden;
  transition: transform 0.35s var(--ease-out);
}
.uploader:hover .upload-ill { transform: translateY(-4px) scale(1.02); }
.uploader .upload-ill::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 30% 22%, rgba(255,255,255,0.45), transparent 60%);
}
.uploader .upload-ill svg { position: relative; z-index: 1; animation: bob 2.8s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}

.uploader h3 {
  font-size: 22px;
  letter-spacing: -0.02em;
  font-weight: 700;
  margin: 6px 0 0;
}
.uploader h3 .file-chosen {
  background: var(--grad-primary);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.uploader .sub {
  color: var(--text-dim);
  font-size: 14.5px;
  margin: 0;
}
.uploader .type-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  background: var(--surface-0);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--text-faint);
  font-weight: 500;
  box-shadow: var(--shadow-1);
  margin-top: 4px;
}
.uploader .type-hint .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 6px var(--success-glow);
}

/* Info chip row — used to show required columns as pretty pills */
.col-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 20px;
}
.col-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  background: var(--surface-0);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-family: 'Poppins', system-ui, sans-serif;
}
.col-chip.req {
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(124, 58, 237, 0.08));
  border-color: rgba(99, 102, 241, 0.30);
  color: #4338ca;
}
.col-chip.req::before {
  content: "•";
  color: var(--a-violet);
  font-size: 16px;
  line-height: 0;
  margin-right: -2px;
}

/* Preview table (upload page) */
.preview-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.preview-table th, .preview-table td {
  padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.preview-table th {
  font-size: 11px;
  color: var(--text-faint); background: var(--surface-1);
}
.preview-table tr.bad td { background: rgba(225, 29, 72, 0.04); }
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700;
  border: 1px solid;
}
.badge.pickup   { background: rgba(99, 102, 241, 0.10); color: #4338ca; border-color: rgba(99, 102, 241, 0.30); }
.badge.delivery { background: rgba(16, 185, 129, 0.12); color: #047857; border-color: rgba(16, 185, 129, 0.32); }
.badge.err      { background: rgba(225, 29, 72, 0.10); color: #9f1239; border-color: rgba(225, 29, 72, 0.28); }
.badge.ok       { background: rgba(16, 185, 129, 0.12); color: #047857; border-color: rgba(16, 185, 129, 0.32); }
.geo-progress {
  height: 6px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; margin: 10px 0;
  position: relative;
}
.geo-progress > div {
  height: 100%; background: var(--grad-primary);
  transition: width 0.3s var(--ease-out);
  box-shadow: 0 0 10px rgba(124, 58, 237, 0.45);
}

/* Small utilities */
.text-dim    { color: var(--text-dim); }
.text-faint  { color: var(--text-faint); }
.text-center { text-align: center; }
.mt-0 { margin-top: 0 !important; }
.mt-1 { margin-top: 6px; }
.mt-2 { margin-top: 14px; }
.mt-3 { margin-top: 22px; }
.mb-0 { margin-bottom: 0 !important; }
.hide { display: none !important; }

/* =============================================================================
   Live toast — slides in from the top-right
   ============================================================================= */
#toastHost {
  position: fixed;
  top: 72px;
  right: 20px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  max-width: 380px;
}
.toast {
  pointer-events: auto;
  background: var(--surface-0);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
  padding: 14px 16px 14px 14px;
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: 12px;
  align-items: start;
  animation: toastIn 0.35s var(--ease-spring) both;
  transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.toast.hide {
  opacity: 0;
  transform: translateX(40px);
}
.toast .tico {
  width: 40px; height: 40px;
  border-radius: 12px;
  background: var(--grad-primary);
  color: #fff;
  display: grid; place-items: center;
  box-shadow: 0 6px 14px rgba(99, 102, 241, 0.28), inset 0 1px 0 rgba(255,255,255,0.3);
  flex-shrink: 0;
}
.toast .tbody {
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text);
  min-width: 0;
}
.toast .tbody .tt {
  font-weight: 700;
  font-size: 13.5px;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 2px;
}
.toast .tbody .ts {
  color: var(--text-dim);
  font-size: 13px;
}
.toast .tclose {
  background: transparent; border: 0; color: var(--text-faint);
  font-size: 16px; line-height: 1; cursor: pointer; padding: 2px 4px;
  border-radius: 6px;
}
.toast .tclose:hover { color: var(--text); background: var(--surface-1); }
.toast a.tlink {
  display: inline-block;
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--a-blue);
}
@keyframes toastIn {
  from { opacity: 0; transform: translateX(30px) scale(0.98); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}

/* Confetti-free but jubilant success state */
.celebrate {
  text-align: center; padding: 30px 20px;
}
.celebrate .check {
  width: 74px; height: 74px; margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--grad-mint);
  display: grid; place-items: center;
  color: #ffffff;
  font-size: 34px; font-weight: 900;
  box-shadow: 0 0 36px var(--success-glow), var(--shadow-2);
  animation: pop 0.5s var(--ease-spring);
}
.celebrate h3 { font-size: 22px; margin-bottom: 6px; }
.celebrate p { color: var(--text-dim); }
@keyframes pop {
  0% { transform: scale(0.3); opacity: 0; }
  60% { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); }
}

/* =============================================================================
   MOBILE RESPONSIVE PASS
   Breakpoints:
     ≤ 720px — phone / small tablet portrait
     ≤ 520px — phone (compact)
   ============================================================================= */

/* Hamburger button — hidden on desktop, shown on mobile */
.mobile-menu-toggle {
  display: none;
  width: 40px; height: 40px;
  border-radius: 10px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  cursor: pointer;
  color: var(--text);
  align-items: center; justify-content: center;
  padding: 0;
}
.mobile-menu-toggle:hover { background: var(--surface-2); }

/* On desktop, the "topbar-collapse" just flows inline */
.topbar-collapse {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: flex-end;     /* push .user to the right */
  gap: 16px;
  position: relative;            /* anchor the centered nav */
}
/* Nav centering — IN FLOW.
   ⚠️ This used to be `position:absolute; left:50%; transform:translate(-50%,-50%)`.
   An absolutely-positioned element is out of flow, so the nav occupied ZERO
   width in the flex row. `.user` (bell + name + theme + Logout) was then laid
   out as if the nav did not exist, and once the nav grew past the free space
   the two simply drew on top of each other — the bell landed on "Team" and
   the user's name on "Settings".
   Tightening gaps/padding (the @media 1800px block below) cannot fix that:
   flex cannot reserve space for something it does not measure.
   In-flow instead: nav is a shrinkable flex item that centers its own
   children, so it can never occupy the same pixels as .user. If the entries
   genuinely cannot fit, the nav scrolls horizontally rather than overlapping
   or clipping — every destination stays reachable. */
@media (min-width: 721px) {
  .topbar-collapse > nav {
    flex: 1 1 auto;
    min-width: 0;              /* without this a flex item refuses to shrink
                                  below its content width and overflows */
    justify-content: center;
    /* ⚠️ NO overflow here. `overflow-x: auto` forces overflow-y to compute to
       `auto` as well, which makes nav a clipping container — and
       `.nav-dropdown-menu` is absolutely positioned BELOW the nav box, so
       Billing / Ops silently stopped opening. Overlap is prevented by the
       in-flow flex above; cramped widths are handled by the hamburger
       breakpoint instead of by scrolling. */
  }
  .topbar-collapse > .user { flex: 0 0 auto; }
}

/* Prevent the topbar nav items from wrapping onto multiple lines at
   in-between widths — the abs-centered nav collides with the invoice
   search / user cluster otherwise, giving the "Overview / Command"
   staircase effect the user reported. */
.topbar nav a, .topbar nav .nav-dropdown-trigger {
  white-space: nowrap;
}

/* At tablet/laptop widths where every top-level nav entry doesn't fit
   alongside the invoice search box, hide the search so the nav has
   room to breathe. Users can still get the same behavior from the
   billing pages themselves (which have their own inline lookup). */
@media (max-width: 1500px) {
  .topbar-inv-search input { width: 150px !important; }
}
@media (max-width: 1280px) {
  .topbar-inv-search { display: none !important; }
}

/* Fix right-side cramping / overlap in the 1400-1800px range.
   Symptoms: the notification bell + its 1-count badge visually
   overlaps the adjacent Settings text, and the user cluster on the
   right (name + logout) gets pushed off-screen. Root cause: too many
   items in the right block with too little gap; the badge is
   absolutely positioned and its footprint isn't reserved by flex.
   Fix: tighten padding, widen gaps, and give the notification bell
   its own reserved column so the count badge floats without eating
   into the next item's clickable area. */
@media (max-width: 1800px) {
  .topbar { padding: 12px clamp(12px, 2vw, 24px); gap: 12px; }
  .topbar nav { gap: 2px; }
  .topbar nav a, .topbar nav .nav-dropdown-trigger { padding: 8px 10px; font-size: 13px; }
  .topbar .user { gap: 10px; }
  /* Give the bell breathing room so its badge doesn't overlap the
     Settings link to its right. */
  .topbar .user .notif-bell,
  .topbar .user [data-notif-bell],
  .topbar .user .lc-notif-bell { flex: 0 0 auto; margin-right: 6px; }
  /* Truncate very long usernames on narrow desktops so they don't
     push Logout off the visible edge.
     ⚠️ This rule was dead until now: app.js rendered a bare
     `<span>${name}</span>` with NO class, so neither selector ever matched
     and the full name kept its intrinsic width. The span now carries
     `.user-name` (with a title attribute, so the full name is still
     readable on hover once it ellipsises). */
  .topbar .user .user-name,
  .topbar .user .user__name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 1440px) {
  .topbar nav a, .topbar nav .nav-dropdown-trigger { padding: 6px 8px; font-size: 12.5px; }
  .topbar { gap: 8px; }
  .topbar .user { gap: 8px; }
}

/* ---------- ≤ 720px — Mobile ---------- */
@media (max-width: 720px) {
  /* Topbar: show hamburger, collapse nav/user into a drawer */
  .topbar {
    padding: 12px 16px;
    gap: 8px;
  }
  .topbar .brand span:last-child { font-size: 14px; }
  .topbar .topbar-portal-label { display: none; }  /* hide "· Admin" subtitle */
  .mobile-menu-toggle { display: grid; }

  .topbar-collapse {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    padding: 10px 12px 14px;
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(18px);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-2);
    z-index: 49;
    gap: 0;
  }
  .topbar-collapse.open { display: flex; animation: slideDown 0.22s var(--ease-out); }

  .topbar-collapse nav {
    flex-direction: column;
    gap: 2px;
    align-items: stretch;
  }
  .topbar-collapse nav a {
    padding: 12px 14px;
    font-size: 15px;
    border-radius: 10px;
  }

  .topbar-collapse .user {
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    flex-wrap: wrap;
    gap: 8px;
    font-size: 13px;
  }
  .topbar-collapse .user .topbar-sep { display: none; }
  .topbar-collapse .user button { margin-left: auto; }

  /* Container padding tightens */
  .container {
    padding: 20px 14px 48px;
  }

  /* Page headers stack vertically and action buttons become full-width rows */
  .page-header {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    margin-bottom: 20px;
  }
  .page-header h1 { font-size: 24px; }
  .page-header .subtitle { font-size: 14px; }
  .page-header > div:last-child {
    display: flex; flex-wrap: wrap; gap: 8px;
  }
  .page-header > div:last-child .btn { flex: 1 1 auto; min-width: 120px; }

  /* Cards breathe less */
  .card { padding: 18px 16px; border-radius: var(--r-md); }

  /* Modals: near-fullscreen on phones */
  .modal-overlay { padding: 0; }
  .modal-card {
    max-width: 100% !important;
    max-height: 100vh;
    min-height: 100vh;
    border-radius: 0 !important;
    padding: 20px 16px;
  }
  /* Sticky save bar in modals */
  .modal-card .btn-row[style*="sticky"] {
    margin: 20px -16px -20px !important;
    padding: 14px 16px !important;
  }

  /* Auth pages — full-height centered with no box */
  .auth-card {
    padding: 28px 20px;
    max-width: 100%;
    border-radius: var(--r-lg);
  }
  .auth-card h1 { font-size: 22px; }

  /* KPI tiles already wrap to 1-col at 520px; at 720px do 2-col */
  .kpi .kpi-value { font-size: 28px; }
  .kpi-row { gap: 10px; margin-bottom: 20px; }

  /* Tables: horizontal scroll with fade hint on the right edge */
  .table-wrap {
    position: relative;
    border-radius: var(--r-md);
  }
  .table-wrap::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 22px;
    pointer-events: none;
    background: linear-gradient(to right, transparent, rgba(255,255,255,0.6));
    border-radius: 0 var(--r-md) var(--r-md) 0;
  }
  table.clients, table.orders, table.preview-table {
    font-size: 12.5px;
  }
  table.clients th, table.clients td,
  table.orders  th, table.orders  td {
    padding: 10px 10px;
  }

  /* Button rows wrap and fill width */
  .btn-row {
    flex-wrap: wrap;
    gap: 8px;
  }
  .btn-row .spacer { width: 100%; order: -1; flex-basis: 100%; height: 0; }
  .btn-row .btn { flex: 1 1 auto; min-width: 140px; }

  /* Form grid already collapses at 680px (single column) */
  .field input, .field select, .field textarea {
    font-size: 16px;   /* prevents iOS auto-zoom on focus */
  }

  /* Toolbar (search + filter dropdowns) stacks nicely */
  .toolbar { gap: 8px; }
  .search { max-width: 100%; min-width: 0; }
  .toolbar .btn.ghost { padding: 9px 12px; font-size: 13px; }

  /* Back-floating button — compact position on mobile */
  .back-floating {
    top: 12px;
    left: 12px;
    padding: 6px 10px;
    font-size: 12px;
  }
  .back-floating svg { width: 12px; height: 12px; }

  /* Landing page tweaks */
  .landing-nav {
    padding: 16px 16px;
  }
  .landing-nav .brand span { font-size: 14px; }
  .hero {
    padding: 100px 16px 60px;
  }
  .hero h1.hero-title {
    font-size: clamp(32px, 8vw, 44px);
  }
  .hero-preview {
    margin-top: 40px;
    padding: 6px;
    border-radius: var(--r-lg);
  }
  .hero-preview-body { padding: 14px !important; }
  .hero-preview-body .kpi-row { grid-template-columns: repeat(2, 1fr) !important; gap: 8px !important; }
  .hero-preview-body > div[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
  }
  .hero-meta { gap: 12px; font-size: 12px; }
  .big-cta { margin: 40px 16px; padding: 40px 24px; }

  /* Feature grid already collapses nicely (2-col at 960, 1-col at 640) */

  /* Toast — fill width on mobile */
  #toastHost {
    top: 60px;
    right: 10px;
    left: 10px;
    max-width: none;
  }

  /* Tile editor modal actions stay visible */
  .modal-card .btn-row .btn { font-size: 14px; }

  /* Uploader on mobile */
  .uploader {
    padding: 36px 18px;
  }
  .uploader h3 { font-size: 18px; }
  .uploader .upload-ill { width: 72px; height: 72px; border-radius: 20px; }

  /* Stepper (multi-step forms) becomes a compact progress bar */
  .stepper { gap: 4px; margin-bottom: 16px; }
  .stepper .step { padding: 8px 6px; font-size: 11px; }

  /* Progress pills wrap */
  .progress-pills { gap: 6px; }
  .progress-pill { font-size: 12px; padding: 6px 12px 6px 8px; }

  /* Section-num badge smaller on mobile */
  .section-num { width: 40px; height: 40px; font-size: 15px; border-radius: 11px; }
  .section-head-row { gap: 12px; margin-bottom: 14px; }

  /* Avatars a bit smaller */
  .avatar { width: 28px; height: 28px; font-size: 11.5px; margin-right: 8px; }
}

/* ---------- ≤ 520px — very compact phones ---------- */
@media (max-width: 520px) {
  .topbar .brand span:last-child { display: none; }    /* just the "L" logo */
  .container { padding: 16px 12px 48px; }
  .card { padding: 16px 14px; }

  .btn.xl { padding: 12px 18px; font-size: 14px; }
  .btn.lg { padding: 11px 16px; }

  .hero { padding: 90px 14px 48px; }
  .hero h1.hero-title { font-size: clamp(28px, 9vw, 36px); }
  .hero .hero-sub { font-size: 15px; }

  .section-head h2 { font-size: 22px; }

  /* Stack KPI tiles in one column (already done via :520 rule above) */

  /* Hide long inline subtitles that get cramped */
  .hero-meta span:nth-child(n+3) { display: none; }

  /* Make the "user" strip in the mobile drawer wrap cleaner */
  .topbar-collapse .user > span:first-child { display: none; }   /* role label hidden — shown in portal name anyway */
}

/* ---------- ≥ 721px — desktop resets (defensive) ---------- */
@media (min-width: 721px) {
  .mobile-menu-toggle { display: none !important; }
  .topbar-collapse { display: flex !important; }
}

/* =============================================================================
   MOBILE CATCH-ALL — applies to every page using stock or ad-hoc classes
   =============================================================================
   This block lives at the bottom so it overrides earlier rules. The goal is to
   make the app *usable* on a phone even when a page-specific style block hasn't
   been mobile-audited individually. Per-page polish still belongs in the page's
   own <style> block — this is just the safety net.
   ============================================================================= */
@media (max-width: 720px) {

  /* ---- Tap targets — Apple HIG says 44×44 minimum, we settle for 40px ---- */
  button, .btn, a.btn, input[type="button"], input[type="submit"] {
    min-height: 40px;
  }

  /* ---- Inputs — 16px font prevents iOS Safari from auto-zooming on focus.
     The .field rule already does this, but ad-hoc inputs scattered across
     per-page <style> blocks miss it. ---- */
  input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="tel"], input[type="search"],
  input[type="date"], input[type="time"], input[type="url"],
  select, textarea {
    font-size: 16px !important;
  }

  /* ---- Generic table overflow — wrap any direct <table> in horizontal scroll
     when its parent is narrower than its content. The shared `.table-wrap`
     class still works as before; this is the fallback for raw tables. ---- */
  main table:not(.bare) {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  /* ---- Container is full-width on phone, edge-to-edge with breathing room.
     `.container.wide` and our DCL-fullwidth class both honor this. ---- */
  main.container, main.container.wide, main.container.full {
    max-width: 100% !important;
    padding-left: 14px;
    padding-right: 14px;
  }

  /* ---- Any 2/3/4-column CSS grid that didn't get its own media query —
     collapse to a single column. We can't catch every ad-hoc inline style,
     but most use class names that match these patterns. ---- */
  [class*="-grid"][style*="grid-template-columns"] { grid-template-columns: 1fr !important; }
  .grid, .row, .form-grid { grid-template-columns: 1fr !important; }

  /* ---- Hero sections shared by per-page <h1>/eyebrow patterns ---- */
  [class$="-hero"] {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 14px !important;
  }
  [class$="-hero"] h1 { font-size: clamp(24px, 8vw, 32px) !important; }

  /* ---- "Filters" toolbar — search + dropdowns on the same row become stacked ---- */
  [class*="-filters"], [class$="-filters"] {
    grid-template-columns: 1fr !important;
  }

  /* ---- Modals using a different class than .modal-card — make full-screen
     with proper inner scrolling. The flexbox + min-height:0 trick lets the
     body shrink below content size so overflow:auto actually triggers. ---- */
  [class*="modal-bg"][class*="open"] [class*="modal"]:not([class*="-foot"]):not([class*="-head"]):not([class*="-body"]):not([class*="-bg"]) {
    max-width: 100% !important;
    width: 100% !important;
    max-height: 100dvh !important;
    height: 100dvh !important;
    min-height: 0 !important;
    border-radius: 0 !important;
    display: flex !important;
    flex-direction: column !important;
  }
  /* Generic modal body — let it scroll inside the modal container. */
  [class*="modal-bg"][class*="open"] [class*="modal-body"],
  [class*="modal-bg"][class*="open"] [class*="-modal-body"] {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
  }
  [class*="modal-bg"][class*="open"] [class*="modal-head"],
  [class*="modal-bg"][class*="open"] [class*="-modal-head"],
  [class*="modal-bg"][class*="open"] [class*="modal-foot"],
  [class*="modal-bg"][class*="open"] [class*="-modal-foot"] {
    flex: 0 0 auto !important;
  }
  /* Sticky save bar on the foot so the action buttons stay visible. */
  [class*="modal-bg"][class*="open"] [class*="modal-foot"],
  [class*="modal-bg"][class*="open"] [class*="-modal-foot"] {
    position: sticky;
    bottom: 0;
    padding-bottom: max(12px, env(safe-area-inset-bottom)) !important;
  }

  /* ---- Page action button rows ---- */
  .action-row, .actions-row {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  .action-row .btn, .actions-row .btn { flex: 1 1 auto; min-width: 130px; }

  /* ---- Ad-hoc inline style="display:flex;gap:8px;" rows in headers — let them wrap ---- */
  .page-header > div, [class$="-hero"] > div {
    flex-wrap: wrap !important;
  }

  /* ============================================================================
     UNIVERSAL CLASS-PREFIX SWEEP
     Catches every page's per-page CSS without touching each file:
       .fl-kpis, .iv-kpis, .pf-kpis, .ah-kpis, .cv-kpis, .ct-kpis, .ad-kpis,
       .dt-kpis, .dx-kpis, .rx-kpis, .dv-kpis, .rd-kpis, .mv-kpis, .mc-kpis,
       .fa-kpis, .jh-kpis, .gm-kpis, .dcl-kpis, .cn-kpis, .dp-kpis, .tm-kpis…
     ============================================================================ */

  /* All KPI grids → 2 col on phone (was usually 4) */
  [class*="-kpis"],
  [class*="kpi-row"] {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
  }
  /* The actual KPI tile shrinks its number a bit for phone width */
  [class*="-kpis"] [class*="-kpi"] [class*="val"],
  [class*="-kpis"] [class*="-kpi"] .val,
  [class*="-kpis"] [class*="-kpi"] .v {
    font-size: 22px !important;
  }

  /* All form/page grids that are 2-col or 3-col on desktop → 1-col on phone.
     We exclude system grids (.feature-grid, .form-grid) which already have
     their own rules. */
  [class$="-grid"]:not(.form-grid):not(.feature-grid):not(.fleet-grid):not(.live-grid):not(.bh-grid):not(.charge-grid):not(.lane-grid):not(.stops-grid):not(.fa-grid) {
    grid-template-columns: 1fr !important;
    gap: 10px 12px !important;
  }

  /* Per-page card containers — tighter padding so content fits phone width */
  [class$="-card"]:not(.kpi):not(.bh-module) {
    padding: 14px !important;
  }

  /* Live Map / Fleet analytics layouts collapse to 1-col on phone */
  .live-grid, .fa-grid {
    grid-template-columns: 1fr !important;
  }

  /* Bill-to / customer-list / two-col bh-grid stays as 1-col on phone */
  .bh-grid, .lane-grid, .ec-grid { grid-template-columns: 1fr !important; }

  /* charge-grid (upload route pricing breakdown) → 2-col tight on phone */
  .charge-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 10px !important; }

  /* RxNovo stops → 1 per row instead of 5 */
  .stops-grid { grid-template-columns: 1fr !important; gap: 10px !important; }

  /* All "billing toolbar" rows (filter dropdowns + search + add buttons) wrap */
  [class*="-toolbar"], [class*="-controls"], [class*="-filters-row"] {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  [class*="-toolbar"] > *, [class*="-controls"] > * {
    flex: 1 1 auto;
  }
}

/* ---------- ≤ 380px — narrow phones (iPhone SE / Pixel 4a-class) ---------- */
@media (max-width: 380px) {
  /* All KPI grids drop to single column */
  [class*="-kpis"],
  [class*="kpi-row"] {
    grid-template-columns: 1fr !important;
  }
  [class*="-kpis"] [class*="-kpi"] [class*="val"],
  [class*="-kpis"] [class*="-kpi"] .val,
  [class*="-kpis"] [class*="-kpi"] .v {
    font-size: 24px !important;   /* slightly larger since each tile is wider */
  }
  /* charge-grid drops to 1-col on really narrow */
  .charge-grid { grid-template-columns: 1fr !important; }
}

/* ---------- ≤ 380px — narrow phones (e.g. iPhone SE, Pixel 4a) ---------- */
@media (max-width: 380px) {
  /* Hide eyebrow text on really tight viewports */
  .eyebrow, [class$="-hero"] .eyebrow {
    font-size: 10px !important;
    letter-spacing: 0.10em !important;
  }
  /* Even more compact h1 */
  [class$="-hero"] h1 { font-size: 22px !important; }
  /* Buttons can shrink slightly to fit two on a row */
  button, .btn { padding-left: 10px; padding-right: 10px; }
}

/* =================================================================
   MOBILE-FRIENDLY GLOBAL PATCH (added 2026-06-17)
   ----------------------------------------------------------------
   These rules sit at the end of styles.css so any page that already
   imports it picks them up. They target the most common breakage
   patterns we've seen on phones across this app:
     • Topbars that overflow
     • Containers with too much horizontal padding
     • Tables that don't scroll
     • Inputs that trigger iOS auto-zoom
     • Modals that don't fill the screen
     • Touch targets under 44pt
     • Grids that don't collapse below ~600px
   They're tuned to be additive — they only fire below 768px and
   only nudge values rather than redefining whole layouts. Higher-
   specificity page-level styles always win.
   ================================================================ */

/* ----- Universal — every viewport ----- */
/* Stop iOS Safari from auto-zooming when a user taps an input
   smaller than 16px. Cheap fix: bump every text input to 16px. */
input[type="text"], input[type="email"], input[type="tel"],
input[type="password"], input[type="number"], input[type="search"],
input[type="date"], input[type="time"], input[type="datetime-local"],
select, textarea {
  font-size: max(16px, 13.5px); /* never under 16 on touch devices */
}
/* Tap targets of 44pt are Apple's accessibility minimum. We don't
   force every button up to 44 (that breaks toolbars), but we do
   force any naked anchor/button inside a card to land there. */
@media (hover: none) and (pointer: coarse) {
  button, .btn, .icon-btn, a.btn, [role="button"] {
    min-height: 40px;
  }
}

/* ----- ≤ 1024 — tablets and below ----- */
@media (max-width: 1024px) {
  /* Containers with `wide` get too tight on smaller laptops. */
  .container.wide { padding-left: 18px; padding-right: 18px; }
  /* Most page-headers stack their CTA group below the title. */
  .page-header { flex-wrap: wrap; gap: 12px; }
}

/* ----- ≤ 768 — true mobile breakpoint ----- */
@media (max-width: 768px) {
  /* Topbar — let it wrap, hide non-essential brand subtitle so
     the right-hand nav fits. */
  #topbar { padding: 10px 14px !important; }
  #topbar > * { flex-wrap: wrap; }
  .topbar-subtitle, .brand .sub, .lc-brand .sub { display: none !important; }

  /* All containers shrink to phone padding. */
  .container, .container.wide, main.container, main {
    padding-left: 14px !important;
    padding-right: 14px !important;
  }

  /* Hero / page-header — typography clamps. */
  .page-header h1, [class$="-hero"] h1, .hero h1 { font-size: 26px !important; line-height: 1.15 !important; }
  .page-header .subtitle, [class$="-hero"] .sub, [class$="-hero"] .subtitle {
    font-size: 13px !important;
  }
  .page-header > div, .hero > div { width: 100%; }

  /* Tables — always horizontally scrollable on phones. The wrapper
     pattern lots of pages use is `<div class="table-wrap"><table>` so
     we target both that and bare tables in a card. */
  .table-wrap, .card table, .dp-card table, .bill-card table,
  .cd-list table, table.scroll {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  table { min-width: 600px; }
  /* But card-internal data tables that are designed for mobile can
     opt out by adding the .no-min class. */
  table.no-min { min-width: 0; }

  /* Modals — full-bleed on phones for the page-style modals we use. */
  .dp-modal-bg .dp-modal, .modal .modal-body, .bill-modal {
    max-width: 100% !important;
    margin: 0 !important;
    border-radius: 16px 16px 0 0 !important;
    max-height: 100vh !important;
  }
  .dp-modal-bg { padding: 0 !important; align-items: flex-end !important; }

  /* Grids that look great at 4 cols should collapse to 2 here. */
  .bill-kpis, .cd-kpis, .bp-kpis, .dp-kpis,
  [class$="-kpis"] { grid-template-columns: repeat(2, 1fr) !important; }
  .feature-grid, .ind-grid, .stat-grid, .why-grid,
  [class$="-cards"], [class$="-grid"] { grid-template-columns: 1fr !important; }

  /* Side-by-side two-column patterns (routes + map, form + preview)
     stack to a single column on phones. */
  .bp-tracker-split, .mb-form-pane + .mb-preview-pane,
  .ec-grid, .grid-2col, .bp-grid-2 {
    grid-template-columns: 1fr !important;
  }

  /* Drop floating button stacks to the bottom edge so they don't
     cover form content. */
  .floating-actions { right: 12px !important; bottom: 12px !important; }
}

/* ----- ≤ 480 — phone-sized ----- */
@media (max-width: 480px) {
  /* Topbar logo + brand text crunches further. */
  #topbar .brand .nm, #topbar .brand b { font-size: 14px !important; }
  #topbar .nav-link, #topbar .right .item { padding: 6px 8px !important; font-size: 12px !important; }

  /* Hero typography — smaller still. */
  .page-header h1, [class$="-hero"] h1, .hero h1 { font-size: 22px !important; }
  .page-header .subtitle { font-size: 12.5px !important; }

  /* KPI tiles drop to 1 column on really narrow screens. */
  .bill-kpis, .cd-kpis, .bp-kpis, .dp-kpis,
  [class$="-kpis"] { grid-template-columns: 1fr !important; }

  /* Action toolbars (search + filters) stack. */
  .toolbar, .cd-toolbar, .bill-toolbar, .dp-toolbar {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .toolbar > *, .cd-toolbar > *, .bill-toolbar > *, .dp-toolbar > * {
    width: 100% !important;
  }
}


/* =============================================================================
   Pearl hero-CTA button
   -----------------------------------------------------------------------------
   Reusable primary-action button inspired by the Uiverse "Pearl" pattern —
   layered inset shadows + a soft top gloss for that pressed-crystal look.
   Scaled down 60% from the original so it fits modal footers, toolbars, and
   inline "New" buttons without breaking layouts. Semantic color variants
   (orange for CNW, blue for Stripe/Pay, green for Save, red for Delete, etc.)
   preserve the operator's ability to scan by color while lifting the visual.

   Usage (single-line, minimal DOM):
     <button class="lc-pearl lc-pearl--orange">
       <span class="wrap">+ New order</span>
     </button>

   Color variants:
     lc-pearl--slate   (default dark)   lc-pearl--red     (destructive)
     lc-pearl--orange  (CNW / freight)  lc-pearl--purple  (accent)
     lc-pearl--blue    (Stripe / Pay)   lc-pearl--pink    (special)
     lc-pearl--green   (Save / Paid)    lc-pearl--ghost   (cancel / secondary)
   ============================================================================= */
.lc-pearl {
  --lc-pearl-bg: #0F172A;
  --lc-pearl-fg: rgba(255, 255, 255, 0.95);
  outline: none;
  cursor: pointer;
  border: 0;
  padding: 0;
  position: relative;
  border-radius: 100px;
  background-color: var(--lc-pearl-bg);
  color: var(--lc-pearl-fg);
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  transition: box-shadow 0.2s ease, transform 0.15s ease, background-color 0.2s ease;
  /* Toned-down desktop shadows — the earlier set produced a very
     pronounced 3D "pearl dome" that read as an oversized blob at
     admin-app sizes. Retains the signature glossy inset ring but the
     overall footprint is now closer to a normal iOS-style chip. */
  box-shadow:
    inset 0 0.10rem 0.28rem rgba(255, 255, 255, 0.22),
    inset 0 -0.04rem 0.12rem rgba(0, 0, 0, 0.45),
    inset 0 -0.12rem 0.32rem rgba(255, 255, 255, 0.20),
    0 0.4rem 0.55rem rgba(0, 0, 0, 0.14),
    0 0.15rem 0.3rem -0.2rem rgba(0, 0, 0, 0.32);
}
.lc-pearl .wrap {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: inherit;
  padding: 9px 18px;
  border-radius: inherit;
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  line-height: 1.15;
}
.lc-pearl .wrap::before,
.lc-pearl .wrap::after {
  content: "";
  position: absolute;
  transition: transform 0.3s ease, opacity 0.3s ease;
  pointer-events: none;
}
.lc-pearl .wrap::before {
  /* Small top-highlight instead of the giant reflection blob. */
  left: -10%;
  right: -10%;
  bottom: 50%;
  top: -60%;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.07);
}
.lc-pearl .wrap::after {
  /* Thin glossy top strip — kept subtle. */
  left: 6%;
  right: 6%;
  top: 12%;
  bottom: 55%;
  border-radius: 22px 22px 0 0;
  box-shadow: inset 0 4px 3px -4px rgba(255, 255, 255, 0.55);
  background: linear-gradient(180deg, rgba(255,255,255,0.18) 0%, rgba(0,0,0,0) 60%, rgba(0,0,0,0) 100%);
}
.lc-pearl:hover {
  box-shadow:
    inset 0 0.10rem 0.28rem rgba(255, 255, 255, 0.32),
    inset 0 -0.04rem 0.12rem rgba(0, 0, 0, 0.45),
    inset 0 -0.12rem 0.32rem rgba(255, 255, 255, 0.30),
    0 0.5rem 0.7rem rgba(0, 0, 0, 0.18),
    0 0.2rem 0.35rem -0.2rem rgba(0, 0, 0, 0.38);
}
.lc-pearl:hover .wrap::before { transform: translateY(-5%); }
.lc-pearl:hover .wrap::after  { opacity: 0.4; transform: translateY(5%); }
.lc-pearl:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 0.15rem 0.35rem rgba(255, 255, 255, 0.5),
    inset 0 -0.05rem 0.15rem rgba(0, 0, 0, 0.6),
    inset 0 -0.22rem 0.55rem rgba(255, 255, 255, 0.3),
    0 0.8rem 1rem rgba(0, 0, 0, 0.2),
    0 0.3rem 0.4rem -0.3rem rgba(0, 0, 0, 0.5);
}
.lc-pearl:disabled { opacity: 0.6; cursor: default; }

/* Compact variant — for use inline in dense toolbars / tables */
.lc-pearl.lc-pearl--sm .wrap { padding: 8px 16px; font-size: 12.5px; gap: 6px; }
.lc-pearl.lc-pearl--sm { border-radius: 999px; }

/* Full-width variant — matches modal footer save-button width */
.lc-pearl.lc-pearl--wide { width: 100%; justify-content: center; }
.lc-pearl.lc-pearl--wide .wrap { width: 100%; justify-content: center; }

/* Color variants — each keeps the inset gloss but on a colored base. */
.lc-pearl--slate  { --lc-pearl-bg: #0F172A; }
.lc-pearl--orange { --lc-pearl-bg: #EA580C; }
.lc-pearl--blue   { --lc-pearl-bg: #1E40AF; }
.lc-pearl--green  { --lc-pearl-bg: #059669; }
.lc-pearl--red    { --lc-pearl-bg: #B91C1C; }
.lc-pearl--purple { --lc-pearl-bg: #7C3AED; }
.lc-pearl--pink   { --lc-pearl-bg: #DB2777; }

/* Ghost — pearl gloss on a neutral base, for secondary/Cancel actions */
.lc-pearl--ghost {
  --lc-pearl-bg: #F8FAFC;
  --lc-pearl-fg: #334155;
  box-shadow:
    inset 0 0.15rem 0.5rem  rgba(15, 23, 42, 0.08),
    inset 0 -0.05rem 0.15rem rgba(15, 23, 42, 0.20),
    inset 0 -0.22rem 0.55rem rgba(255, 255, 255, 0.6),
    0 0.6rem 0.8rem rgba(15, 23, 42, 0.08),
    0 0.25rem 0.35rem -0.2rem rgba(15, 23, 42, 0.15);
}
.lc-pearl--ghost .wrap::before { background-color: rgba(15,23,42,0.05); }
.lc-pearl--ghost .wrap::after  {
  background: linear-gradient(180deg, rgba(15,23,42,0.08) 0%, rgba(0,0,0,0) 55%, rgba(0,0,0,0) 100%);
  box-shadow: inset 0 6px 5px -6px rgba(15,23,42,0.15);
}
.lc-pearl--ghost:hover {
  box-shadow:
    inset 0 0.15rem 0.35rem rgba(15, 23, 42, 0.10),
    inset 0 -0.05rem 0.15rem rgba(15, 23, 42, 0.20),
    inset 0 -0.22rem 0.55rem rgba(255, 255, 255, 0.75),
    0 0.75rem 0.95rem rgba(15, 23, 42, 0.10),
    0 0.3rem 0.4rem -0.2rem rgba(15, 23, 42, 0.18);
}

/* =============================================================================
   Pearl button — mobile calibration
   -----------------------------------------------------------------------------
   On phones the desktop-tuned Pearl reads as an oversized 3D blob because the
   inset white glows, ::before "reflection" blob, and drop shadow all scale off
   the button's dimensions — a wide flex-1 button on a 380px viewport gets
   proportionally huge highlights. These rules dampen the effect on <=640px
   so the button feels closer to a normal iOS pill: same identity, less bloat.
   ============================================================================= */
@media (max-width: 640px) {
  .lc-pearl {
    /* Softer inset ring + lighter drop shadow */
    box-shadow:
      inset 0 0.12rem 0.32rem rgba(255, 255, 255, 0.22),
      inset 0 -0.04rem 0.12rem rgba(0, 0, 0, 0.45),
      inset 0 -0.14rem 0.32rem rgba(255, 255, 255, 0.20),
      0 0.4rem 0.55rem rgba(0, 0, 0, 0.15),
      0 0.15rem 0.3rem -0.2rem rgba(0, 0, 0, 0.35);
  }
  .lc-pearl .wrap {
    padding: 10px 20px;
    font-size: 13px;
  }
  .lc-pearl.lc-pearl--sm .wrap {
    padding: 8px 16px;
    font-size: 12.5px;
  }
  /* Tone down the "pearl reflection" pseudo-elements — biggest culprit
     of the 3D-blob look on mobile. */
  .lc-pearl .wrap::before { opacity: 0.55; }
  .lc-pearl .wrap::after {
    opacity: 0.7;
    box-shadow: inset 0 4px 3px -4px rgba(255, 255, 255, 0.55);
  }
  .lc-pearl:hover {
    box-shadow:
      inset 0 0.12rem 0.32rem rgba(255, 255, 255, 0.28),
      inset 0 -0.04rem 0.12rem rgba(0, 0, 0, 0.45),
      inset 0 -0.14rem 0.32rem rgba(255, 255, 255, 0.28),
      0 0.5rem 0.7rem rgba(0, 0, 0, 0.18),
      0 0.2rem 0.35rem -0.2rem rgba(0, 0, 0, 0.40);
  }
}
