/* Victory Lap Component Styles
 * ─────────────────────────────────────────────────────────────────────────
 * Phase 8 — Dark Mode Theme System
 * All component colors flow through CSS custom properties so the entire app
 * can be re-themed by toggling [data-theme="..."] on the <html> element.
 * Brand identity colors (navy #2F3A4E, gold #C19B65) remain constant; only
 * surface/background/text/border tokens flip between light and dark.
 * The boot script in main.py resolves "system" to "light"|"dark" before
 * paint, so this file only needs to handle two explicit themes.
 * ───────────────────────────────────────────────────────────────────────── */

:root,
:root[data-theme="light"] {
  color-scheme: light;
  /* Surfaces */
  --vl-bg-app: #f5f5f3;
  --vl-bg-primary: #ffffff;
  --vl-bg-secondary: #f8fafc;
  --vl-bg-tertiary: #f1f5f9;
  --vl-bg-card: #ffffff;
  --vl-bg-elevated: #ffffff;
  --vl-bg-input: #ffffff;
  --vl-bg-muted: #f1f5f9;
  --vl-bg-subtle: #f8fafc;
  --vl-bg-hover: #f8fafc;
  --vl-bg-selected: #dbeafe;
  --vl-bg-option-hover: #eff6ff;

  /* Text */
  --vl-text-primary: #1e293b;
  --vl-text-secondary: #475569;
  --vl-text-tertiary: #64748b;
  --vl-text-muted: #94a3b8;
  --vl-text-strong: #0f172a;
  --vl-text-on-accent: #f8fafc;
  --vl-text-on-dark: #f8fafc;
  --vl-text-link: #1d4ed8;
  --vl-text-disabled: #94a3b8;

  /* Borders */
  --vl-border: #e2e8f0;
  --vl-border-strong: #cbd5e1;
  --vl-border-subtle: #f1f5f9;
  --vl-border-input: #e2e8f0;
  --vl-border-focus: #2F3A4E;
  --vl-border-focus-ring: rgba(47, 58, 78, 0.10);

  /* Brand (constant across themes) */
  --vl-primary: #2F3A4E;
  --vl-primary-hover: #1e2533;
  --vl-primary-soft: rgba(47, 58, 78, 0.08);
  --vl-gold: #C19B65;
  --vl-gold-hover: #b88a52;

  /* Semantic
   * Two tokens per state so light backgrounds (buttons) and text on app-bg
   * can use different shades and both meet WCAG AA:
   *   --vl-{state}        → solid color for button bg / borders (white text reads on it)
   *   --vl-{state}-text   → readable color for text on the app background
   * In light mode they happen to match; in dark mode they diverge. */
  --vl-danger: #991b1b;
  --vl-danger-hover: #7f1d1d;
  --vl-danger-soft-bg: #fef2f2;
  --vl-danger-text: #991b1b;
  --vl-success: #166534;
  --vl-success-hover: #0f4427;
  --vl-success-soft-bg: #f0fdf4;
  --vl-success-text: #166534;
  --vl-warning: #d97706;
  --vl-warning-text: #b45309;
  --vl-info: #0c4a6e;
  --vl-info-text: #0c4a6e;

  /* Misc */
  --vl-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.10);
  --vl-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
  --vl-shadow-lg: 0 12px 28px -8px rgba(15, 23, 42, 0.18), 0 4px 12px -4px rgba(15, 23, 42, 0.08);
  --vl-shadow-xl: 0 25px 50px -12px rgba(15, 23, 42, 0.35);
  --vl-modal-backdrop: rgba(15, 23, 42, 0.55);
  --vl-scrollbar-thumb: #94a3b8;
  --vl-scrollbar-track: #f1f5f9;
  --vl-select-chevron: "%232F3A4E";

  /* Sidebar — navy by default (brand look) in both themes. */
  --vl-sidebar-bg: #1e2533;
  --vl-sidebar-fg: #e8e4df;
  --vl-sidebar-fg-muted: #c8d0dc;
  --vl-sidebar-fg-strong: #f8fafc;
  --vl-sidebar-border: rgba(193, 155, 101, 0.15);
  --vl-sidebar-btn-border: rgba(193, 155, 101, 0.12);
  --vl-sidebar-active-bg: #C19B65;
  --vl-sidebar-active-fg: #1e2533;

  /* ── Stacking order (z-index scale) ──────────────────────────────────────
   * Single source of truth for overlay layering. Higher = closer to the user.
   * Always reference these tokens (inline `z-index:var(--vl-z-…)`) rather than
   * Tailwind arbitrary `z-[1234]` classes: this app commits a pre-built
   * static/tailwind.css (no runtime build), so a `z-[…]` class that wasn't
   * present at the last rebuild silently resolves to `z-index:auto` and the
   * element renders behind its siblings.
   *
   *   sticky page header ........ 100    --vl-z-header
   *   slide-over panel backdrop .. 998    --vl-z-panel-backdrop
   *   slide-over filter panel .... 999    --vl-z-panel
   *   dropdowns / popover menus .. 1000   --vl-z-dropdown
   *   modal drawer (deal editor) . 9999   --vl-z-drawer
   *   modal stacked on a drawer .. 10001  --vl-z-drawer-modal
   *   global toast / notice ...... 10049  --vl-z-toast
   *   global app dialog .......... 10050  --vl-z-dialog
   *   destructive confirm ........ 10051  --vl-z-dialog-critical
   *   fullscreen takeover ........ 99999  --vl-z-fullscreen
   * ──────────────────────────────────────────────────────────────────────── */
  --vl-z-header: 100;
  --vl-z-panel-backdrop: 998;
  --vl-z-panel: 999;
  --vl-z-dropdown: 1000;
  --vl-z-drawer: 9999;
  --vl-z-drawer-modal: 10001;
  --vl-z-toast: 10049;
  --vl-z-dialog: 10050;
  --vl-z-dialog-critical: 10051;
  --vl-z-fullscreen: 99999;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  /* Surfaces */
  --vl-bg-app: #0b1320;
  --vl-bg-primary: #0f172a;
  --vl-bg-secondary: #111c30;
  --vl-bg-tertiary: #1a2540;
  --vl-bg-card: #16213a;
  --vl-bg-elevated: #1e293b;
  --vl-bg-input: #16213a;
  --vl-bg-muted: #1a2540;
  --vl-bg-subtle: #111c30;
  --vl-bg-hover: #1e293b;
  --vl-bg-selected: #1e3a8a;
  --vl-bg-option-hover: #1f2a44;

  /* Text */
  --vl-text-primary: #f1f5f9;
  --vl-text-secondary: #cbd5e1;
  --vl-text-tertiary: #94a3b8;
  --vl-text-muted: #64748b;
  --vl-text-strong: #f8fafc;
  --vl-text-on-accent: #f8fafc;
  --vl-text-on-dark: #f8fafc;
  --vl-text-link: #93c5fd;
  --vl-text-disabled: #475569;

  /* Borders */
  --vl-border: #2a3756;
  --vl-border-strong: #38476a;
  --vl-border-subtle: #1e2a44;
  --vl-border-input: #2a3756;
  --vl-border-focus: #C19B65;
  --vl-border-focus-ring: rgba(193, 155, 101, 0.18);

  /* Brand (slightly lifted for contrast on dark) */
  --vl-primary: #4a5b78;
  --vl-primary-hover: #5b6e8e;
  --vl-primary-soft: rgba(193, 155, 101, 0.08);
  --vl-gold: #C19B65;
  --vl-gold-hover: #d4ae78;

  /* Semantic
   * Two-tier so we can keep button backgrounds saturated (white text still
   * passes contrast) AND have legible text-on-app-bg colors. The earlier
   * single-token approach gave us light-red buttons with white text — which
   * failed WCAG (~1.3:1). Split below: --vl-danger / --vl-success stay solid
   * enough for white text in dark mode, while --vl-danger-text / --vl-success-text
   * are the lifted shades used for plain text on the dark app background. */
  --vl-danger: #dc2626;
  --vl-danger-hover: #b91c1c;
  --vl-danger-soft-bg: #3b0d12;
  --vl-danger-text: #fca5a5;
  --vl-success: #15803d;
  --vl-success-hover: #166534;
  --vl-success-soft-bg: #052e16;
  --vl-success-text: #6ee7b7;
  --vl-warning: #f59e0b;
  --vl-warning-text: #fcd34d;
  --vl-info: #0284c7;
  --vl-info-text: #7dd3fc;

  /* Misc */
  --vl-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.40);
  --vl-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.40);
  --vl-shadow-lg: 0 12px 28px -8px rgba(0, 0, 0, 0.60), 0 4px 12px -4px rgba(0, 0, 0, 0.40);
  --vl-shadow-xl: 0 25px 50px -12px rgba(0, 0, 0, 0.75);
  --vl-modal-backdrop: rgba(0, 0, 0, 0.70);
  --vl-scrollbar-thumb: #38476a;
  --vl-scrollbar-track: #1a2540;
  --vl-select-chevron: "%23cbd5e1";

  /* Sidebar — a touch darker than app bg in dark mode so it still reads as a rail. */
  --vl-sidebar-bg: #080d17;
  --vl-sidebar-fg: #e2e8f0;
  --vl-sidebar-fg-muted: #94a3b8;
  --vl-sidebar-fg-strong: #f8fafc;
  --vl-sidebar-border: rgba(193, 155, 101, 0.20);
  --vl-sidebar-btn-border: rgba(193, 155, 101, 0.10);
  --vl-sidebar-active-bg: #C19B65;
  --vl-sidebar-active-fg: #0b1320;
}

/* Theme switching is intentionally instant — applying a broad
 * `transition: background-color, color, border-color` to every element
 * would override per-component `transition: all` rules (e.g. .vl-btn
 * hover opacity), so we accept a one-frame flash on toggle in exchange
 * for not breaking existing micro-interactions. */

/* App background — flips with theme */
html[data-theme="dark"] body {
  background: var(--vl-bg-app) !important;
  color: var(--vl-text-primary);
}

/* ─────────────────────────────────────────────────────────────────────────
 * Button Base Styles
 * ───────────────────────────────────────────────────────────────────────── */
.vl-btn {
  border-radius: 4px;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.06em;
  font-weight: 600;
  padding: 0.5rem 1rem;
  border: 1px solid;
  cursor: pointer;
  transition: all 0.2s ease;
  display: inline-block;
  text-align: center;
}

.vl-btn:hover {
  opacity: 0.9;
}

.vl-btn:active {
  opacity: 0.85;
}

/* Extra-small button modifier. Pair with .vl-btn (+ a color variant) for
 * compact action buttons in dense rows / toolbars, e.g. the Files tab
 * Preview / Download / Confirm / Delete cluster. Declared after .vl-btn so
 * its padding/font win the same-specificity cascade. */
.vl-btn-xs {
  padding: 0.2rem 0.55rem;
  font-size: 11px;
  letter-spacing: 0.02em;
}
.vl-btn-xs svg {
  width: 0.8rem;
  height: 0.8rem;
}

/* Standalone modifier defaults.
 *
 * Many older callsites use the modifier classes (.vl-btn-primary,
 * .vl-btn-danger, .vl-btn-success, .vl-btn-secondary) WITHOUT the
 * .vl-btn base class, which left them rendering with browser-default
 * squared-off edges and no padding. We give those standalone usages
 * a matching-modal-button look (the same proportions as .vl-btn-ghost)
 * so they don't clash with the rest of the app.
 *
 * The :not(.vl-btn) guard means anywhere already using
 * `class="vl-btn vl-btn-primary"` keeps its existing 4px / uppercase
 * .vl-btn styling — no regression on the dozens of buttons that
 * already pair the two classes. */
.vl-btn-primary:not(.vl-btn),
.vl-btn-danger:not(.vl-btn),
.vl-btn-success:not(.vl-btn),
.vl-btn-secondary:not(.vl-btn) {
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  border: 1px solid;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  display: inline-block;
  text-align: center;
  transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
  line-height: 1.25;
}
.vl-btn-primary:not(.vl-btn):disabled,
.vl-btn-danger:not(.vl-btn):disabled,
.vl-btn-success:not(.vl-btn):disabled,
.vl-btn-secondary:not(.vl-btn):disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Primary Button — themed via --vl-primary (flips automatically in dark). */
.vl-btn-primary {
  background: var(--vl-primary);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-primary);
}

.vl-btn-primary:hover {
  background: var(--vl-primary-hover);
  border-color: var(--vl-primary-hover);
}

/* Danger Button — themed via --vl-danger */
.vl-btn-danger {
  background: var(--vl-danger);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-danger);
}

.vl-btn-danger:hover {
  background: var(--vl-danger-hover);
  border-color: var(--vl-danger-hover);
}

/* Danger Alternative — darker red variant, inherits --vl-danger-hover */
.vl-btn-danger-alt {
  background: var(--vl-danger-hover);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-danger-hover);
}

.vl-btn-danger-alt:hover {
  background: var(--vl-danger);
  border-color: var(--vl-danger);
}

/* Success Button — themed via --vl-success */
.vl-btn-success {
  background: var(--vl-success);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-success);
}

.vl-btn-success:hover {
  background: var(--vl-success-hover);
  border-color: var(--vl-success-hover);
}

/* Secondary Button — slate, themed via text-tertiary/secondary pair */
.vl-btn-secondary {
  background: var(--vl-text-tertiary);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-text-tertiary);
}

.vl-btn-secondary:hover {
  background: var(--vl-text-secondary);
  border-color: var(--vl-text-secondary);
}

/* Gold/Accent Button - #C19B65 */
.vl-btn-gold {
  background: #C19B65;
  color: #fff;
  border-color: #C19B65;
}

.vl-btn-gold:hover {
  background: #b88a52;
  border-color: #b88a52;
}

/* Gold Outline Button - Transparent with gold border */
.vl-btn-gold-outline {
  background: transparent;
  color: #C19B65;
  border-color: #C19B65;
}

.vl-btn-gold-outline:hover {
  background: #C19B6510;
}

/* Primary Outline Button - Transparent with navy border */
.vl-btn-primary-outline {
  background: transparent;
  color: var(--vl-primary);
  border-color: var(--vl-primary);
}

[data-theme="dark"] .vl-btn-primary-outline {
  color: #C19B65;
  border-color: #C19B65;
}

.vl-btn-primary-outline:hover {
  background: var(--vl-primary-soft);
}

/* Secondary Outline Button - Transparent with gray border */
.vl-btn-secondary-outline {
  background: transparent;
  color: #808284;
  border-color: #808284;
}

.vl-btn-secondary-outline:hover {
  background: #80828410;
}

[data-theme="dark"] .vl-btn-secondary-outline {
  color: var(--vl-text-secondary);
  border-color: var(--vl-border-strong);
}

/* Dark Blue Button - #0c4a6e */
.vl-btn-dark-blue {
  background: #0c4a6e;
  color: #f8fafc;
  border-color: #0c4a6e;
}

.vl-btn-dark-blue:hover {
  background: #082f47;
  border-color: #082f47;
}

/* Slate Button - #475569 */
.vl-btn-slate {
  background: #475569;
  color: #f8fafc;
  border-color: #475569;
}

.vl-btn-slate:hover {
  background: #334155;
  border-color: #334155;
}

/* Small Button Variant */
.vl-btn-sm {
  font-size: 11px;
  padding: 2px 10px;
  border-radius: 4px;
}

/* Large Button Variant */
.vl-btn-lg {
  font-size: 14px;
  padding: 0.75rem 1.5rem;
}

/* Block Button - Full Width */
.vl-btn-block {
  width: 100%;
  display: block;
}

/* ─────────────────────────────────────────────────────────────────────────
 * Input / Select / Label
 * ───────────────────────────────────────────────────────────────────────── */
.vl-input {
  border: 1px solid var(--vl-border-input);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  font-size: 14px;
  background-color: var(--vl-bg-input);
  color: var(--vl-text-primary);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  font-family: inherit;
}

.vl-input:focus {
  outline: none;
  border-color: var(--vl-border-focus);
  box-shadow: 0 0 0 3px var(--vl-border-focus-ring);
}

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

.vl-input:disabled {
  background-color: var(--vl-bg-muted);
  color: var(--vl-text-disabled);
  cursor: not-allowed;
}

.vl-select {
  border: 1px solid var(--vl-border-input);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  font-size: 14px;
  background-color: var(--vl-bg-input);
  color: var(--vl-text-primary);
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  font-family: inherit;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%232F3A4E' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 14l-7 7m0 0l-7-7m7 7V3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.5em 1.5em;
  padding-right: 2.5rem;
}

[data-theme="dark"] .vl-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23cbd5e1' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 14l-7 7m0 0l-7-7m7 7V3'/%3E%3C/svg%3E");
}

.vl-select:focus {
  outline: none;
  border-color: var(--vl-border-focus);
  box-shadow: 0 0 0 3px var(--vl-border-focus-ring);
}

.vl-select:disabled {
  background-color: var(--vl-bg-muted);
  color: var(--vl-text-disabled);
  cursor: not-allowed;
}

.vl-label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: var(--vl-text-secondary);
  margin-bottom: 0.375rem;
}

.vl-label-sm {
  font-size: 12px;
  color: var(--vl-text-tertiary);
}

/* 2026-04-17 — Muted styling for fields that the system maintains
 * automatically (currently just the Stage dropdown, which is date-driven
 * via stage_engine). Still editable, just visually down-weighted so admins
 * know at a glance that it's not expected input. No helper text — per
 * product direction we don't want extra messaging in the form. */
.vl-auto-field {
  background-color: var(--vl-bg-subtle, #f8fafc);
  color: var(--vl-text-secondary, #475569);
  font-style: italic;
}
.vl-auto-field:focus {
  font-style: normal;
}

/* ─────────────────────────────────────────────────────────────────────────
 * Card
 * ───────────────────────────────────────────────────────────────────────── */
.vl-card {
  background: var(--vl-bg-card);
  border: 1px solid var(--vl-border);
  border-radius: 16px;
  padding: 1.5rem;
  box-shadow: var(--vl-shadow-sm);
  transition: box-shadow 0.2s ease;
}

.vl-card:hover {
  box-shadow: var(--vl-shadow-md);
}

.vl-card-header {
  padding: 0 0 1rem 0;
  border-bottom: 1px solid var(--vl-border);
  margin-bottom: 1rem;
}

.vl-card-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--vl-text-primary);
  margin: 0;
}

[data-theme="light"] .vl-card-title,
:root:not([data-theme]) .vl-card-title {
  color: #2F3A4E;
}

.vl-card-subtitle {
  font-size: 13px;
  color: var(--vl-text-tertiary);
  margin-top: 0.25rem;
}

.vl-card-body {
  padding: 0;
}

.vl-card-footer {
  padding-top: 1rem;
  border-top: 1px solid var(--vl-border);
  margin-top: 1rem;
}

.vl-form-group {
  margin-bottom: 1.5rem;
}

.vl-form-group:last-child {
  margin-bottom: 0;
}

/* Field Error / Success */
.vl-input.vl-error,
.vl-select.vl-error {
  border-color: var(--vl-danger);
  background-color: var(--vl-danger-soft-bg);
}

.vl-input.vl-error:focus,
.vl-select.vl-error:focus {
  box-shadow: 0 0 0 3px rgba(153, 27, 27, 0.1);
}

.vl-error-text {
  font-size: 12px;
  color: var(--vl-danger-text);
  margin-top: 0.375rem;
}

.vl-input.vl-success,
.vl-select.vl-success {
  border-color: var(--vl-success);
  background-color: var(--vl-success-soft-bg);
}

.vl-input.vl-success:focus,
.vl-select.vl-success:focus {
  box-shadow: 0 0 0 3px rgba(22, 101, 52, 0.1);
}

.vl-success-text {
  font-size: 12px;
  color: var(--vl-success-text);
  margin-top: 0.375rem;
}

/* ─────────────────────────────────────────────────────────────────────────
 * Badges
 * ───────────────────────────────────────────────────────────────────────── */
.vl-badge {
  display: inline-block;
  padding: 0.25rem 0.625rem;
  background: var(--vl-bg-muted);
  color: var(--vl-text-secondary);
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.vl-badge-primary {
  background: #2F3A4E;
  color: #f8fafc;
}

.vl-badge-danger {
  background: #991b1b;
  color: #fff;
}

.vl-badge-success {
  background: #166534;
  color: #fff;
}

.vl-badge-gold {
  background: #C19B65;
  color: #fff;
}

/* Text Helper Styles */
.vl-text-muted {
  color: var(--vl-text-tertiary);
  font-size: 13px;
}

.vl-text-small {
  font-size: 12px;
}

.vl-text-error {
  color: var(--vl-danger-text);
}

.vl-text-success {
  color: var(--vl-success-text);
}

.vl-text-warning {
  color: var(--vl-warning-text);
}

/* Disabled */
.vl-btn:disabled,
.vl-input:disabled,
.vl-select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Responsive */
@media (max-width: 640px) {
  .vl-btn {
    padding: 0.5rem 0.75rem;
    font-size: 11px;
  }
  .vl-btn-lg {
    padding: 0.625rem 1rem;
    font-size: 13px;
  }
  .vl-input,
  .vl-select {
    font-size: 16px; /* Prevents zoom on iOS */
  }
  .vl-card {
    padding: 1rem;
  }
}

/* ───────────────────────────────────────────────────────────────────────
 * Phase 7C — VLSelect (custom cross-platform dropdown)
 * ─────────────────────────────────────────────────────────────────────── */
.vlx-select {
  position: relative;
  display: inline-block;
  min-width: 140px;
  font-family: inherit;
}

.vlx-select-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--vl-bg-input);
  border: 1px solid var(--vl-border-strong);
  border-radius: 8px;
  font-size: 14px;
  color: var(--vl-text-primary);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  font-family: inherit;
  min-height: 38px;
  line-height: 1.2;
}

.vlx-select-trigger:hover {
  border-color: var(--vl-text-tertiary);
  background: var(--vl-bg-hover);
}

.vlx-select.is-open .vlx-select-trigger,
.vlx-select-trigger:focus {
  outline: none;
  border-color: var(--vl-border-focus);
  box-shadow: 0 0 0 3px var(--vl-border-focus-ring);
}

.vlx-select-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.vlx-select-label.is-placeholder {
  color: var(--vl-text-muted);
}

.vlx-select-chevron {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: var(--vl-text-tertiary);
  transition: transform 0.15s ease;
}

.vlx-select.is-open .vlx-select-chevron {
  transform: rotate(180deg);
}

.vlx-select-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  z-index: 1000;
  background: var(--vl-bg-elevated);
  border: 1px solid var(--vl-border-strong);
  border-radius: 10px;
  box-shadow: var(--vl-shadow-lg);
  min-width: 100%;
  max-width: 320px;
  overflow: hidden;
}

.vlx-select-dropdown.hidden {
  display: none;
}

.vlx-select-search-wrap {
  padding: 8px;
  border-bottom: 1px solid var(--vl-border);
  background: var(--vl-bg-secondary);
}

.vlx-select-search {
  width: 100%;
  padding: 6px 10px;
  border: 1px solid var(--vl-border-strong);
  border-radius: 6px;
  font-size: 13px;
  font-family: inherit;
  background: var(--vl-bg-input);
  color: var(--vl-text-primary);
}

.vlx-select-search:focus {
  outline: none;
  border-color: var(--vl-border-focus);
  box-shadow: 0 0 0 2px var(--vl-border-focus-ring);
}

.vlx-select-options {
  max-height: 260px;
  overflow-y: auto;
  padding: 4px 0;
}

.vlx-select-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 8px 12px;
  font-size: 14px;
  color: var(--vl-text-primary);
  cursor: pointer;
  transition: background 0.1s ease;
  user-select: none;
}

.vlx-select-option:hover,
.vlx-select-option.vlx-select-active {
  background: var(--vl-bg-option-hover);
}

.vlx-select-option.is-selected {
  background: var(--vl-bg-selected);
  font-weight: 600;
  color: var(--vl-text-link);
}

[data-theme="dark"] .vlx-select-option.is-selected {
  color: #f1f5f9;
}

.vlx-select-option-main {
  flex: 1 1 auto;
  min-width: 0;
}

.vlx-select-option-sub {
  font-size: 11px;
  color: var(--vl-text-tertiary);
  margin-top: 2px;
}

.vlx-select-check {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: var(--vl-text-link);
}

.vlx-select-empty {
  padding: 12px;
  text-align: center;
  font-size: 13px;
  color: var(--vl-text-muted);
}

/* ───────────────────────────────────────────────────────────────────────
 * Phase 7A/7B — Saved Search bar + Export modal
 * ─────────────────────────────────────────────────────────────────────── */
.vl-saved-search-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.75rem;
  background: var(--vl-bg-secondary);
  border: 1px solid var(--vl-border);
  border-radius: 10px;
  margin-bottom: 0.75rem;
}

.vl-saved-search-bar .vl-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--vl-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-right: 0.25rem;
}

.vl-modal-backdrop {
  position: fixed;
  /* 2026-05-12 — explicit edge anchoring + viewport-unit sizing so the
     backdrop ALWAYS covers the full visible viewport regardless of where
     it lands in the DOM tree. Previously `inset: 0` alone was leaving a
     white strip on the right edge on wide displays — likely caused by an
     ancestor combination (overflow-hidden on `.app-modern`, `<main>`'s
     `lg:ml-[260px]` left margin, and the transactions view's
     `overflow-x:hidden` wrapper) interacting with how Chromium resolves
     `inset:0` on `position:fixed` when scrollbars are present. Using
     top/left/right/bottom: 0 PLUS `width:100vw; height:100vh` makes the
     layout unambiguous. `min-width/height` are belt-and-suspenders for
     the same reason. */
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  min-width: 100vw;
  min-height: 100vh;
  background: var(--vl-modal-backdrop);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  padding: 1rem;
}

.vl-modal {
  background: var(--vl-bg-elevated);
  border-radius: 14px;
  box-shadow: var(--vl-shadow-xl);
  max-width: 640px;
  width: 100%;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.vl-modal-header {
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--vl-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.vl-modal-title {
  font-weight: 700;
  font-size: 16px;
  color: var(--vl-text-strong);
}

.vl-modal-body {
  padding: 1rem 1.25rem;
  overflow-y: auto;
  flex: 1 1 auto;
  color: var(--vl-text-primary);
}

.vl-modal-footer {
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--vl-border);
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  background: var(--vl-bg-secondary);
}

.vl-export-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
}

@media (min-width: 640px) {
  .vl-export-cols {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.vl-export-cols label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 13px;
  color: var(--vl-text-primary);
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  cursor: pointer;
}

.vl-export-cols label:hover {
  background: var(--vl-bg-muted);
}

/* ───────────────────────────────────────────────────────────────────────
 * Phase 8 — Theme Toggle (segmented control)
 * ─────────────────────────────────────────────────────────────────────── */
.vl-theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 3px;
  background: var(--vl-bg-tertiary);
  border: 1px solid var(--vl-border);
  border-radius: 9999px;
}

.vl-theme-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 5px 10px;
  border: none;
  background: transparent;
  color: var(--vl-text-tertiary);
  border-radius: 9999px;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: background 0.15s ease, color 0.15s ease;
  font-family: inherit;
}

.vl-theme-toggle-btn:hover {
  color: var(--vl-text-primary);
}

.vl-theme-toggle-btn.is-active {
  background: var(--vl-bg-card);
  color: var(--vl-text-strong);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
}

[data-theme="dark"] .vl-theme-toggle-btn.is-active {
  background: var(--vl-gold);
  color: #1e2533;
}

.vl-theme-toggle-btn svg {
  width: 14px;
  height: 14px;
}

/* Compact icon-only toggle for nav bar */
.vl-theme-iconbtn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  color: #c8d0dc;
}

.vl-theme-iconbtn:hover {
  color: var(--vl-gold);
}

/* ───────────────────────────────────────────────────────────────────────
 * Phase 8 — Dark Mode Tailwind Utility Overrides
 * The app uses Tailwind v3 from a CDN with thousands of inline utility
 * classes. Rather than rewriting every component, we override the most
 * common surface/text/border utilities under [data-theme="dark"]. These
 * rules win against Tailwind's non-important rules through specificity.
 * ─────────────────────────────────────────────────────────────────────── */

/* ── Surface backgrounds ───────────────────────────────────────────────── */
html[data-theme="dark"] .bg-white { background-color: var(--vl-bg-card) !important; }
html[data-theme="dark"] .bg-slate-50 { background-color: var(--vl-bg-secondary) !important; }
html[data-theme="dark"] .bg-slate-100 { background-color: var(--vl-bg-tertiary) !important; }
html[data-theme="dark"] .bg-slate-200 { background-color: var(--vl-bg-muted) !important; }
html[data-theme="dark"] .bg-gray-50 { background-color: var(--vl-bg-secondary) !important; }
html[data-theme="dark"] .bg-gray-100 { background-color: var(--vl-bg-tertiary) !important; }
html[data-theme="dark"] .bg-gray-200 { background-color: var(--vl-bg-muted) !important; }

/* Soft semantic backgrounds → muted dark equivalents (preserve hue) */
html[data-theme="dark"] .bg-blue-50 { background-color: rgba(59, 130, 246, 0.10) !important; }
html[data-theme="dark"] .bg-blue-100 { background-color: rgba(59, 130, 246, 0.18) !important; }
html[data-theme="dark"] .bg-emerald-50 { background-color: rgba(16, 185, 129, 0.10) !important; }
html[data-theme="dark"] .bg-emerald-100 { background-color: rgba(16, 185, 129, 0.18) !important; }
html[data-theme="dark"] .bg-rose-50 { background-color: rgba(244, 63, 94, 0.10) !important; }
html[data-theme="dark"] .bg-rose-100 { background-color: rgba(244, 63, 94, 0.18) !important; }
html[data-theme="dark"] .bg-amber-50 { background-color: rgba(245, 158, 11, 0.10) !important; }
html[data-theme="dark"] .bg-amber-100 { background-color: rgba(245, 158, 11, 0.18) !important; }
html[data-theme="dark"] .bg-sky-50 { background-color: rgba(14, 165, 233, 0.10) !important; }
html[data-theme="dark"] .bg-sky-100 { background-color: rgba(14, 165, 233, 0.18) !important; }
html[data-theme="dark"] .bg-indigo-50 { background-color: rgba(99, 102, 241, 0.10) !important; }
html[data-theme="dark"] .bg-indigo-100 { background-color: rgba(99, 102, 241, 0.18) !important; }

/* ── Text colors ──────────────────────────────────────────────────────── */
html[data-theme="dark"] .text-slate-900 { color: var(--vl-text-strong) !important; }
html[data-theme="dark"] .text-slate-800 { color: var(--vl-text-primary) !important; }
html[data-theme="dark"] .text-slate-700 { color: var(--vl-text-secondary) !important; }
html[data-theme="dark"] .text-slate-600 { color: var(--vl-text-secondary) !important; }
html[data-theme="dark"] .text-slate-500 { color: var(--vl-text-tertiary) !important; }
html[data-theme="dark"] .text-slate-400 { color: var(--vl-text-muted) !important; }
html[data-theme="dark"] .text-gray-900 { color: var(--vl-text-strong) !important; }
html[data-theme="dark"] .text-gray-800 { color: var(--vl-text-primary) !important; }
html[data-theme="dark"] .text-gray-700 { color: var(--vl-text-secondary) !important; }
html[data-theme="dark"] .text-gray-600 { color: var(--vl-text-secondary) !important; }
html[data-theme="dark"] .text-gray-500 { color: var(--vl-text-tertiary) !important; }

/* Brand text — keep golfi-primary readable on dark.
 * 2026-05-22: Tailwind compiles `colors.golfi.primary` to the class
 * `.text-golfi-primary` (hyphen), NOT `.text-golfi.primary` (dot). The
 * original override targeted the dot version and never matched, so every
 * page title and KPI value (Agent Dashboard, Forecast headers, dollar
 * amounts in the metric cards, etc.) was rendering as #2F3A4E navy on the
 * dark app background — ~1.55:1 contrast, effectively invisible. Both
 * selectors are listed so we cover any stray dot-notation usages too. */
html[data-theme="dark"] .text-golfi-primary,
html[data-theme="dark"] .text-golfi\.primary { color: var(--vl-gold) !important; }

/* Soft semantic text — lift to lighter shades */
html[data-theme="dark"] .text-emerald-800 { color: #6ee7b7 !important; }
html[data-theme="dark"] .text-emerald-700 { color: #6ee7b7 !important; }
html[data-theme="dark"] .text-rose-800 { color: #fca5a5 !important; }
html[data-theme="dark"] .text-rose-700 { color: #fca5a5 !important; }
html[data-theme="dark"] .text-amber-800 { color: #fcd34d !important; }
html[data-theme="dark"] .text-amber-700 { color: #fcd34d !important; }
html[data-theme="dark"] .text-blue-800 { color: #93c5fd !important; }
html[data-theme="dark"] .text-blue-700 { color: #93c5fd !important; }
html[data-theme="dark"] .text-sky-800 { color: #7dd3fc !important; }
html[data-theme="dark"] .text-sky-700 { color: #7dd3fc !important; }
html[data-theme="dark"] .text-indigo-800 { color: #a5b4fc !important; }
html[data-theme="dark"] .text-indigo-700 { color: #a5b4fc !important; }

/* ── Borders ──────────────────────────────────────────────────────────── */
/* Tailwind's bare `.border` defaults to gray-200 — override under dark */
html[data-theme="dark"] .border { border-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-t { border-top-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-b { border-bottom-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-l { border-left-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-r { border-right-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-slate-100 { border-color: var(--vl-border-subtle) !important; }
html[data-theme="dark"] .border-slate-200 { border-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-slate-300 { border-color: var(--vl-border-strong) !important; }
html[data-theme="dark"] .border-gray-200 { border-color: var(--vl-border) !important; }
html[data-theme="dark"] .border-gray-300 { border-color: var(--vl-border-strong) !important; }
html[data-theme="dark"] .border-emerald-200 { border-color: rgba(16, 185, 129, 0.30) !important; }
html[data-theme="dark"] .border-rose-200 { border-color: rgba(244, 63, 94, 0.30) !important; }
html[data-theme="dark"] .border-amber-200 { border-color: rgba(245, 158, 11, 0.30) !important; }
html[data-theme="dark"] .border-blue-200 { border-color: rgba(59, 130, 246, 0.30) !important; }

/* Divide colors */
html[data-theme="dark"] .divide-slate-200 > :not([hidden]) ~ :not([hidden]) { border-color: var(--vl-border) !important; }
html[data-theme="dark"] .divide-slate-100 > :not([hidden]) ~ :not([hidden]) { border-color: var(--vl-border-subtle) !important; }
html[data-theme="dark"] .divide-gray-200 > :not([hidden]) ~ :not([hidden]) { border-color: var(--vl-border) !important; }

/* ─────────────────────────────────────────────────────────────────────────
 * Phase 8.1 — Extended Tailwind family coverage (2026-06-22)
 * The original bridge (above) covered slate/gray surfaces and the
 * emerald / rose / amber / blue / sky / indigo accent families. Several
 * families and shades the JS modules actually use were missed, which left
 * dark-on-dark text (especially red error/validation text and green status
 * text) and over-bright soft panels/badges in dark mode. This block extends
 * coverage to the red / green / violet / purple / yellow / orange families
 * plus the -500/-600/-900 text shades the app uses, mirroring the existing
 * approach: soft -50/-100/-200 backgrounds → low-alpha hue tints, dark accent
 * text → lifted light shades (≈ the family's -300), accent borders →
 * translucent hue.
 *
 * Saturated solid backgrounds (bg-*-500/600/700, bg-black, bg-slate-900) are
 * intentionally NOT overridden — those are buttons/markers/code surfaces that
 * carry white text and already read fine on dark; overriding them would risk
 * regressions. Decorative gradient stops (from-/to-/via-) are likewise left
 * alone. The lifted text shades below were contrast-checked against the dark
 * card surface (--vl-bg-card #16213a) for WCAG AA. */

/* ── RED — errors, validation, danger text/badges ──────────────────────── */
html[data-theme="dark"] .bg-red-50  { background-color: rgba(239, 68, 68, 0.10) !important; }
html[data-theme="dark"] .bg-red-100 { background-color: rgba(239, 68, 68, 0.18) !important; }
html[data-theme="dark"] .bg-red-200 { background-color: rgba(239, 68, 68, 0.26) !important; }
html[data-theme="dark"] .text-red-500,
html[data-theme="dark"] .text-red-600,
html[data-theme="dark"] .text-red-700,
html[data-theme="dark"] .text-red-800,
html[data-theme="dark"] .text-red-900 { color: #fca5a5 !important; }
html[data-theme="dark"] .border-red-200 { border-color: rgba(239, 68, 68, 0.30) !important; }
html[data-theme="dark"] .border-red-300 { border-color: rgba(239, 68, 68, 0.40) !important; }
html[data-theme="dark"] .border-red-400,
html[data-theme="dark"] .border-red-500,
html[data-theme="dark"] .border-red-600 { border-color: rgba(248, 113, 113, 0.55) !important; }

/* ── GREEN — status "active", success text/badges (app mixes green+emerald) */
html[data-theme="dark"] .bg-green-50  { background-color: rgba(34, 197, 94, 0.10) !important; }
html[data-theme="dark"] .bg-green-100 { background-color: rgba(34, 197, 94, 0.18) !important; }
html[data-theme="dark"] .text-green-600,
html[data-theme="dark"] .text-green-700,
html[data-theme="dark"] .text-green-800 { color: #86efac !important; }
html[data-theme="dark"] .border-green-200 { border-color: rgba(34, 197, 94, 0.30) !important; }
html[data-theme="dark"] .border-green-300,
html[data-theme="dark"] .border-green-400 { border-color: rgba(34, 197, 94, 0.42) !important; }

/* ── EMERALD — fill in -600 text + accent border (bg/-700/-800 above) ───── */
html[data-theme="dark"] .text-emerald-600 { color: #6ee7b7 !important; }
html[data-theme="dark"] .border-emerald-300 { border-color: rgba(16, 185, 129, 0.42) !important; }

/* ── VIOLET / PURPLE — AI / automation accents ─────────────────────────── */
html[data-theme="dark"] .bg-violet-50  { background-color: rgba(139, 92, 246, 0.12) !important; }
html[data-theme="dark"] .bg-violet-100 { background-color: rgba(139, 92, 246, 0.20) !important; }
html[data-theme="dark"] .bg-purple-50  { background-color: rgba(168, 85, 247, 0.12) !important; }
html[data-theme="dark"] .bg-purple-100 { background-color: rgba(168, 85, 247, 0.20) !important; }
html[data-theme="dark"] .text-violet-600,
html[data-theme="dark"] .text-violet-700,
html[data-theme="dark"] .text-violet-800,
html[data-theme="dark"] .text-purple-600,
html[data-theme="dark"] .text-purple-700,
html[data-theme="dark"] .text-purple-800 { color: #c4b5fd !important; }
html[data-theme="dark"] .border-violet-200,
html[data-theme="dark"] .border-purple-200 { border-color: rgba(139, 92, 246, 0.35) !important; }

/* ── YELLOW — warnings (app mixes amber + yellow) ──────────────────────── */
html[data-theme="dark"] .bg-yellow-50  { background-color: rgba(234, 179, 8, 0.10) !important; }
html[data-theme="dark"] .bg-yellow-100 { background-color: rgba(234, 179, 8, 0.18) !important; }
html[data-theme="dark"] .text-yellow-700,
html[data-theme="dark"] .text-yellow-800,
html[data-theme="dark"] .text-yellow-900 { color: #fde047 !important; }
html[data-theme="dark"] .border-yellow-300,
html[data-theme="dark"] .border-yellow-400 { border-color: rgba(234, 179, 8, 0.45) !important; }

/* ── ORANGE ────────────────────────────────────────────────────────────── */
html[data-theme="dark"] .bg-orange-50  { background-color: rgba(249, 115, 22, 0.10) !important; }
html[data-theme="dark"] .bg-orange-100 { background-color: rgba(249, 115, 22, 0.18) !important; }
html[data-theme="dark"] .text-orange-600,
html[data-theme="dark"] .text-orange-700,
html[data-theme="dark"] .text-orange-800 { color: #fdba74 !important; }
html[data-theme="dark"] .border-orange-300,
html[data-theme="dark"] .border-orange-400 { border-color: rgba(249, 115, 22, 0.42) !important; }

/* ── AMBER — fill in -500/-600/-900 text + accent borders (others above) ── */
html[data-theme="dark"] .text-amber-500,
html[data-theme="dark"] .text-amber-600,
html[data-theme="dark"] .text-amber-900 { color: #fcd34d !important; }
html[data-theme="dark"] .border-amber-300,
html[data-theme="dark"] .border-amber-400,
html[data-theme="dark"] .border-amber-600 { border-color: rgba(245, 158, 11, 0.42) !important; }

/* ── BLUE / SKY / INDIGO — fill in -600/-900 text + accent borders/rings ── */
html[data-theme="dark"] .text-blue-600,
html[data-theme="dark"] .text-blue-900 { color: #93c5fd !important; }
html[data-theme="dark"] .hover\:text-blue-900:hover { color: #bfdbfe !important; }
html[data-theme="dark"] .text-sky-900  { color: #7dd3fc !important; }
html[data-theme="dark"] .text-indigo-600 { color: #a5b4fc !important; }
html[data-theme="dark"] .bg-blue-200 { background-color: rgba(59, 130, 246, 0.26) !important; }
html[data-theme="dark"] .hover\:bg-blue-200:hover { background-color: rgba(59, 130, 246, 0.30) !important; }
html[data-theme="dark"] .border-blue-300 { border-color: rgba(59, 130, 246, 0.40) !important; }
html[data-theme="dark"] .border-blue-400,
html[data-theme="dark"] .border-blue-500,
html[data-theme="dark"] .border-blue-600 { border-color: rgba(96, 165, 250, 0.55) !important; }
html[data-theme="dark"] .border-sky-200 { border-color: rgba(14, 165, 233, 0.32) !important; }
html[data-theme="dark"] .border-indigo-200 { border-color: rgba(99, 102, 241, 0.35) !important; }
html[data-theme="dark"] .ring-indigo-300 { --tw-ring-color: rgba(99, 102, 241, 0.45) !important; }
html[data-theme="dark"] .ring-amber-400 { --tw-ring-color: rgba(245, 158, 11, 0.50) !important; }
html[data-theme="dark"] .ring-red-300   { --tw-ring-color: rgba(248, 113, 113, 0.50) !important; }

/* ── Light slate fills/dividers used as surfaces (not saturated buttons) ── */
/* bg-slate-300 is used for `w-px` vertical divider rules — a light gray bar
 * glares on dark, so render it like a themed border instead. */
html[data-theme="dark"] .bg-slate-300 { background-color: var(--vl-border-strong) !important; }
html[data-theme="dark"] .border-slate-400 { border-color: var(--vl-border-strong) !important; }
html[data-theme="dark"] .hover\:border-slate-400:hover,
html[data-theme="dark"] .hover\:border-slate-500:hover { border-color: var(--vl-border-strong) !important; }

/* Placeholder color */
html[data-theme="dark"] ::placeholder { color: var(--vl-text-muted) !important; }

/* Hover backgrounds (subtle slate hover patterns) */
html[data-theme="dark"] .hover\:bg-slate-50:hover { background-color: var(--vl-bg-hover) !important; }
html[data-theme="dark"] .hover\:bg-slate-100:hover { background-color: var(--vl-bg-tertiary) !important; }
html[data-theme="dark"] .hover\:bg-gray-50:hover { background-color: var(--vl-bg-hover) !important; }
html[data-theme="dark"] .hover\:bg-gray-100:hover { background-color: var(--vl-bg-tertiary) !important; }

/* Bare inputs/textareas/selects without vl-input class — make legible on dark */
html[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="submit"]):not([type="button"]),
html[data-theme="dark"] textarea,
html[data-theme="dark"] select {
  background-color: var(--vl-bg-input);
  color: var(--vl-text-primary);
  border-color: var(--vl-border-input);
}

/* App-shell helpers */
html[data-theme="dark"] .vl-grid-bg {
  opacity: 0.25 !important;
  background: radial-gradient(circle at 15% 15%, rgba(193,155,101,.12), transparent 35%),
              radial-gradient(circle at 85% 5%, rgba(47,58,78,.20), transparent 35%),
              linear-gradient(180deg, rgba(15,23,42,.92), rgba(11,19,32,.6)) !important;
}

/* ── Inline-style hardcoded color backstops (dark mode) ────────────────────
 * The JS modules render many ad-hoc elements with hardcoded hex colors via
 * inline `style="..."` attributes — e.g. `style="color:#0f172a"` on deal
 * popup text, `style="background:#f8fafc"` on inline cards. Those would
 * otherwise stay light-on-light or dark-on-dark in dark mode because inline
 * styles beat class-based dark overrides. Attribute selectors with
 * !important reach into inline styles and substitute themed equivalents.
 *
 * Patterns covered (with and without the space after the colon, since the
 * codebase uses both `color:#xxx` and `color: #xxx`):
 *   - Dark slate text colors → light themed text
 *   - Light surface backgrounds → themed dark surfaces
 *   - Common border colors → themed borders
 * ──────────────────────────────────────────────────────────────────────── */

/* Dark text colors used inline → flip to light in dark mode. */
html[data-theme="dark"] [style*="color:#0f172a"],
html[data-theme="dark"] [style*="color: #0f172a"],
html[data-theme="dark"] [style*="color:#0F172A"],
html[data-theme="dark"] [style*="color: #0F172A"] { color: var(--vl-text-strong) !important; }

html[data-theme="dark"] [style*="color:#1e293b"],
html[data-theme="dark"] [style*="color: #1e293b"],
html[data-theme="dark"] [style*="color:#1E293B"],
html[data-theme="dark"] [style*="color: #1E293B"] { color: var(--vl-text-primary) !important; }

html[data-theme="dark"] [style*="color:#334155"],
html[data-theme="dark"] [style*="color: #334155"] { color: var(--vl-text-secondary) !important; }

html[data-theme="dark"] [style*="color:#475569"],
html[data-theme="dark"] [style*="color: #475569"] { color: var(--vl-text-secondary) !important; }

html[data-theme="dark"] [style*="color:#64748b"],
html[data-theme="dark"] [style*="color: #64748b"],
html[data-theme="dark"] [style*="color:#64748B"],
html[data-theme="dark"] [style*="color: #64748B"] { color: var(--vl-text-tertiary) !important; }

html[data-theme="dark"] [style*="color:#94a3b8"],
html[data-theme="dark"] [style*="color: #94a3b8"],
html[data-theme="dark"] [style*="color:#94A3B8"],
html[data-theme="dark"] [style*="color: #94A3B8"] { color: var(--vl-text-muted) !important; }

/* Brand navy text — flip to gold for visibility on dark, matching the
   .text-golfi.primary Tailwind override above. */
html[data-theme="dark"] [style*="color:#2F3A4E"],
html[data-theme="dark"] [style*="color: #2F3A4E"],
html[data-theme="dark"] [style*="color:#2f3a4e"],
html[data-theme="dark"] [style*="color: #2f3a4e"] { color: var(--vl-gold) !important; }

/* Banner blue text (#1e3a8a — "Working in" banner) — lift to a readable
   blue on dark. The banner background is also lifted via the bg rules
   below so the contrast holds. */
html[data-theme="dark"] [style*="color:#1e3a8a"],
html[data-theme="dark"] [style*="color: #1e3a8a"] { color: #93c5fd !important; }

/* Amber-on-tan warning text (#78350f) used in agent-assistant banner. */
html[data-theme="dark"] [style*="color:#78350f"],
html[data-theme="dark"] [style*="color: #78350f"] { color: var(--vl-warning-text) !important; }

/* Additional inline dark text colors (2026-06-22) used by JS modules:
 *   #8b5cf6 / #7c3aed  violet accents (AI/automation) → lifted violet
 *   #065f46            emerald-800 dark green → lifted green
 *   #92400e            amber-800 dark → lifted amber
 *   #666               mid grey → themed tertiary text */
html[data-theme="dark"] [style*="color:#8b5cf6"],
html[data-theme="dark"] [style*="color: #8b5cf6"],
html[data-theme="dark"] [style*="color:#7c3aed"],
html[data-theme="dark"] [style*="color: #7c3aed"] { color: #c4b5fd !important; }
html[data-theme="dark"] [style*="color:#065f46"],
html[data-theme="dark"] [style*="color: #065f46"] { color: #6ee7b7 !important; }
html[data-theme="dark"] [style*="color:#92400e"],
html[data-theme="dark"] [style*="color: #92400e"] { color: var(--vl-warning-text) !important; }
html[data-theme="dark"] [style*="color:#666"],
html[data-theme="dark"] [style*="color: #666"] { color: var(--vl-text-tertiary) !important; }

/* Hardcoded white/near-white text used on dark gradient banners — leave
   alone. Only flip if it appears on what was a light surface, which is
   tricky to detect via attribute selector alone, so we don't override
   white. */

/* Light surface backgrounds used inline → themed dark surfaces. */
html[data-theme="dark"] [style*="background:#ffffff"],
html[data-theme="dark"] [style*="background: #ffffff"],
html[data-theme="dark"] [style*="background:#fff"]:not([style*="background:#fffbe"]):not([style*="background:#fffae"]):not([style*="background:#fff5"]):not([style*="background:#fff0"]):not([style*="background:#fff3c7"]),
html[data-theme="dark"] [style*="background: #fff;"],
html[data-theme="dark"] [style*="background-color:#ffffff"],
html[data-theme="dark"] [style*="background-color: #ffffff"] { background-color: var(--vl-bg-card) !important; }

html[data-theme="dark"] [style*="background:#f8fafc"],
html[data-theme="dark"] [style*="background: #f8fafc"],
html[data-theme="dark"] [style*="background-color:#f8fafc"],
html[data-theme="dark"] [style*="background-color: #f8fafc"] { background-color: var(--vl-bg-secondary) !important; }

html[data-theme="dark"] [style*="background:#f1f5f9"],
html[data-theme="dark"] [style*="background: #f1f5f9"],
html[data-theme="dark"] [style*="background-color:#f1f5f9"],
html[data-theme="dark"] [style*="background-color: #f1f5f9"] { background-color: var(--vl-bg-tertiary) !important; }

/* Soft tinted surfaces set inline (2026-06-22) → low-alpha hue tints so they
 * don't glare as bright panels on the dark app background:
 *   #d1fae5 emerald-100 · #fee2e2 red-100 · #fffbeb/#fff8eb amber-50 */
html[data-theme="dark"] [style*="background:#d1fae5"],
html[data-theme="dark"] [style*="background: #d1fae5"],
html[data-theme="dark"] [style*="background-color:#d1fae5"],
html[data-theme="dark"] [style*="background-color: #d1fae5"] { background-color: rgba(16, 185, 129, 0.18) !important; }
html[data-theme="dark"] [style*="background:#fee2e2"],
html[data-theme="dark"] [style*="background: #fee2e2"],
html[data-theme="dark"] [style*="background-color:#fee2e2"],
html[data-theme="dark"] [style*="background-color: #fee2e2"] { background-color: rgba(239, 68, 68, 0.16) !important; }
html[data-theme="dark"] [style*="background:#fffbeb"],
html[data-theme="dark"] [style*="background: #fffbeb"],
html[data-theme="dark"] [style*="background:#fff8eb"],
html[data-theme="dark"] [style*="background: #fff8eb"] { background-color: rgba(245, 158, 11, 0.14) !important; }

/* "View as" amber banner — keep amber feel but darken so white text reads.
   The original used a 90deg gradient from #f59e0b to #f97316 with #111827
   text; in dark mode we use a deeper amber so the inline #111827 text
   (overridden above) remains readable. */
html[data-theme="dark"] [style*="background:linear-gradient(90deg,#f59e0b,#f97316)"] {
  background: linear-gradient(90deg, #b45309, #c2410c) !important;
  color: #fff7ed !important;
}

/* Working-in banner blue gradient — soften for dark. */
html[data-theme="dark"] [style*="background:linear-gradient(90deg,#dbeafe,#eff6ff)"] {
  background: linear-gradient(90deg, rgba(59,130,246,0.18), rgba(59,130,246,0.10)) !important;
  border-color: rgba(59,130,246,0.40) !important;
}

/* Agent-assistant warning banner — yellow soft on dark. */
html[data-theme="dark"] [style*="background:#fef3c7"],
html[data-theme="dark"] [style*="background: #fef3c7"] { background-color: rgba(245, 158, 11, 0.15) !important; }

/* Light "Cancel" button (#E3E4DF cool gray with navy text) — invert to a
   readable ghost button on dark. */
html[data-theme="dark"] [style*="background:#E3E4DF"],
html[data-theme="dark"] [style*="background: #E3E4DF"],
html[data-theme="dark"] [style*="background:#e3e4df"],
html[data-theme="dark"] [style*="background: #e3e4df"] {
  background-color: var(--vl-bg-elevated) !important;
  color: var(--vl-text-primary) !important;
  border-color: var(--vl-border-strong) !important;
}

/* Hardcoded dark slate borders (#e2e8f0 / #cbd5e1) used inline. */
html[data-theme="dark"] [style*="border-color:#e2e8f0"],
html[data-theme="dark"] [style*="border-color: #e2e8f0"],
html[data-theme="dark"] [style*="border:1px solid #e2e8f0"],
html[data-theme="dark"] [style*="border: 1px solid #e2e8f0"] { border-color: var(--vl-border) !important; }

html[data-theme="dark"] [style*="border-color:#cbd5e1"],
html[data-theme="dark"] [style*="border-color: #cbd5e1"] { border-color: var(--vl-border-strong) !important; }

/* Theme-aware scrollbars — flip with --vl-scrollbar-* variables.
 * Firefox uses `scrollbar-color`; WebKit (Chrome/Safari) uses the pseudo-els.
 * P2-21: previously dark-only, so dropdowns with scroll in light mode kept
 * a browser-default scrollbar that looked grey-on-white. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--vl-scrollbar-thumb) var(--vl-scrollbar-track);
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: var(--vl-scrollbar-thumb);
  border-radius: 5px;
}
::-webkit-scrollbar-track {
  background: var(--vl-scrollbar-track);
}

/* Prevent flashing white before app shell paints */
html[data-theme="dark"] #vl-boot-splash {
  background: var(--vl-bg-app);
}
html[data-theme="dark"] #vl-boot-splash p {
  color: var(--vl-text-tertiary) !important;
}

/* Global spinner — used inside the app shell AND on the pre-auth login page,
 * so the definition lives in the global stylesheet rather than the app-shell
 * <style> block. The app-shell block below keeps the same definition for
 * backwards-compat when this file hasn't loaded yet. */
@keyframes vl-spin { to { transform: rotate(360deg); } }
.vl-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 3px solid #e2e8f0;
  border-top-color: #C19B65;
  border-radius: 50%;
  animation: vl-spin 0.7s linear infinite;
  flex-shrink: 0;
}

/* ============================================================
   Pipeline kanban (2026-05-15 rebuild)
   Explicit styles avoid Tailwind-recompile dependency. Every
   class here is consumed by static/modules/pipeline.js.
   ============================================================ */
.vl-kanban-board {
  width: 100%;
  overflow-x: auto;
  padding-bottom: 0.75rem;
}
.vl-kanban-board-inner {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  min-width: max-content;
}
.vl-kanban-col {
  width: 288px;
  flex: 0 0 288px;
  background: var(--vl-bg-secondary);
  border: 1px solid var(--vl-border);
  border-radius: 0.5rem;
  display: flex;
  flex-direction: column;
  min-height: 320px;
}
.vl-kanban-col.is-collapsed {
  width: 44px;
  flex: 0 0 44px;
  min-height: 320px;
}
.vl-kanban-col-header {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--vl-border);
  border-top: 3px solid var(--vl-text-muted);
  border-top-left-radius: 0.5rem;
  border-top-right-radius: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.vl-kanban-col-header-btn {
  flex: 1;
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 0;
  color: inherit;
}
.vl-kanban-col-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--vl-text-strong);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.vl-kanban-col-title-tag {
  font-size: 0.625rem;
  font-weight: 400;
  color: var(--vl-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.vl-kanban-col-subtitle {
  font-size: 0.75rem;
  color: var(--vl-text-tertiary);
  margin-top: 0.125rem;
}
.vl-kanban-col-collapsed-label {
  display: block;
  transform: rotate(-90deg);
  transform-origin: left center;
  white-space: nowrap;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--vl-text-secondary);
  padding-top: 1.5rem;
  padding-left: 0.25rem;
}
.vl-kanban-col-body {
  flex: 1;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 200px;
  overflow-y: auto;
  max-height: calc(100vh - 280px);
}
.vl-kanban-col-body.is-dropzone-active {
  background: var(--vl-bg-option-hover);
  outline: 2px dashed #6366f1;
  outline-offset: -4px;
}
.vl-kanban-col-empty {
  text-align: center;
  color: var(--vl-text-muted);
  font-size: 0.75rem;
  padding: 1rem 0;
}
.vl-kanban-col-empty.is-terminal {
  font-style: italic;
}
.vl-kanban-card {
  background: var(--vl-bg-card);
  color: var(--vl-text-primary);
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  padding: 0.625rem;
  transition: box-shadow 150ms ease, transform 150ms ease;
  border-left: 3px solid #10b981;
}
.vl-kanban-card:hover {
  box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);
}
.vl-kanban-card[data-draggable="1"] { cursor: grab; }
.vl-kanban-card[data-draggable="1"]:active { cursor: grabbing; }
.vl-kanban-card[data-draggable="0"] { cursor: default; }
.vl-kanban-card.is-dragging { opacity: 0.5; }
.vl-kanban-card-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
}
.vl-kanban-card-row + .vl-kanban-card-row { margin-top: 0.375rem; }
.vl-kanban-card-primary {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vl-text-strong);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vl-kanban-card-secondary {
  font-size: 0.75rem;
  color: var(--vl-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vl-kanban-card-link {
  background: transparent;
  border: 0;
  text-align: left;
  flex: 1;
  padding: 0;
  cursor: pointer;
  color: inherit;
  min-width: 0;
}
.vl-kanban-card-pill {
  font-size: 0.625rem;
  padding: 0.125rem 0.375rem;
  border-radius: 9999px;
  font-weight: 500;
  white-space: nowrap;
}
.vl-kanban-card-pill.is-closing { background: #ffe4e6; color: #be123c; }
.vl-kanban-card-pill.is-fub     { background: #eef2ff; color: #4338ca; }

[data-theme="dark"] .vl-kanban-card-pill.is-closing { background: rgba(244, 63, 94, 0.18); color: #fca5a5; }
[data-theme="dark"] .vl-kanban-card-pill.is-fub     { background: rgba(99, 102, 241, 0.18); color: #a5b4fc; }
.vl-kanban-card-price {
  font-size: 0.75rem;
  color: var(--vl-text-tertiary);
}
.vl-kanban-card-price strong { color: var(--vl-text-primary); font-weight: 500; }
.vl-kanban-card-meta {
  font-size: 0.6875rem;
  color: var(--vl-text-tertiary);
  margin-top: 0.375rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vl-kanban-indicators {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.375rem;
}
.vl-kanban-indicator {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.375rem;
  border-radius: 9999px;
  font-size: 0.625rem;
  font-weight: 500;
  color: #fff;
}
.vl-kanban-add-col {
  width: 44px;
  flex: 0 0 44px;
  align-self: flex-start;
  height: 44px;
  border: 2px dashed var(--vl-border-strong);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--vl-text-muted);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: width 150ms ease, color 150ms ease, border-color 150ms ease;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vl-kanban-add-col:hover {
  width: 176px;
  flex: 0 0 176px;
  color: var(--vl-text-secondary);
  border-color: var(--vl-text-tertiary);
}
.vl-kanban-tabs {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.vl-kanban-tab {
  padding: 0.375rem 0.75rem;
  border-radius: 0.375rem;
  font-size: 0.875rem;
  font-weight: 500;
  border: 1px solid var(--vl-border);
  background: var(--vl-bg-card);
  color: var(--vl-text-secondary);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}
.vl-kanban-tab:hover { border-color: var(--vl-text-tertiary); }
.vl-kanban-tab.is-active {
  background: var(--vl-primary);
  border-color: var(--vl-primary);
  color: var(--vl-text-on-accent);
}
.vl-kanban-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.vl-kanban-view-toggle {
  display: inline-flex;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  overflow: hidden;
  background: var(--vl-bg-card);
}
.vl-kanban-view-toggle button {
  padding: 0.375rem 0.75rem;
  font-size: 0.875rem;
  background: transparent;
  border: 0;
  color: var(--vl-text-secondary);
  cursor: pointer;
}
.vl-kanban-view-toggle button.is-active { background: var(--vl-primary); color: var(--vl-text-on-accent); }
.vl-kanban-gear {
  padding: 0.375rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  background: var(--vl-bg-card);
  color: var(--vl-text-secondary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.vl-kanban-gear:hover { background: var(--vl-bg-hover); }
.vl-kanban-agent-select {
  font-size: 0.875rem;
  padding: 0.375rem 0.5rem;
  border-radius: 0.375rem;
  border: 1px solid var(--vl-border);
  background: var(--vl-bg-input);
  color: var(--vl-text-primary);
}
.vl-kanban-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.vl-kanban-loading {
  padding: 2rem;
  text-align: center;
  color: var(--vl-text-tertiary);
}

/* List-view filter / sort controls */
.vl-kanban-list-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  background: var(--vl-bg-card);
  border: 1px solid var(--vl-border);
  border-radius: 0.5rem;
  margin-bottom: 0.75rem;
  flex-wrap: wrap;
}
.vl-kanban-list-control {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--vl-text-primary);
}
.vl-kanban-list-control > span {
  color: var(--vl-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.6875rem;
  font-weight: 600;
}
.vl-kanban-list-control select {
  font-size: 0.875rem;
  padding: 0.375rem 0.5rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  background: var(--vl-bg-input);
  color: var(--vl-text-primary);
  min-width: 160px;
}
.vl-kanban-list-count {
  margin-left: auto;
  color: var(--vl-text-secondary);
  font-size: 0.875rem;
  font-weight: 500;
}

/* ----- Modal (popup + gear) -----
 * NOTE: these were originally hard-coded white. The earlier
 * .vl-modal / .vl-modal-backdrop block (above, around the saved-search
 * section) already uses themed CSS variables, but the kanban code paths
 * rely on the layout overrides below (inset: 0, padding, overflow). We
 * keep the layout overrides but route all colors through CSS variables
 * so dark mode works. */
.vl-modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--vl-modal-backdrop);
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 3rem 1rem 1rem 1rem;
  overflow-y: auto;
}
.vl-modal {
  background: var(--vl-bg-elevated);
  color: var(--vl-text-primary);
  border-radius: 0.75rem;
  box-shadow: var(--vl-shadow-xl);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 6rem);
  width: 100%;
}
.vl-modal-sm { max-width: 28rem; }
.vl-modal-md { max-width: 36rem; }
.vl-modal-lg { max-width: 56rem; }
.vl-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--vl-border);
}
.vl-modal-title { font-size: 1.125rem; font-weight: 600; color: var(--vl-text-strong); }
.vl-modal-subtitle { font-size: 0.875rem; color: var(--vl-text-tertiary); margin-top: 0.125rem; }
.vl-modal-close {
  background: transparent;
  border: 0;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--vl-text-tertiary);
  cursor: pointer;
  padding: 0 0.25rem;
}
.vl-modal-close:hover { color: var(--vl-text-strong); }
.vl-modal-body {
  padding: 1rem 1.25rem;
  overflow-y: auto;
  flex: 1;
  color: var(--vl-text-primary);
}
.vl-modal-footer {
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--vl-border);
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  background: var(--vl-bg-secondary);
}
/* .vl-btn-primary is already defined themed earlier in this file via
   --vl-primary; do NOT redefine it here. The previous hardcoded version
   pinned it to #0f172a which became dark-on-dark in dark mode. */
.vl-btn-ghost {
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  background: var(--vl-bg-card);
  color: var(--vl-text-secondary);
  border: 1px solid var(--vl-border);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
}
.vl-btn-ghost:hover { background: var(--vl-bg-hover); }
.vl-btn-danger-link {
  background: transparent;
  border: 0;
  color: var(--vl-danger-text);
  font-size: 0.8125rem;
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}
.vl-btn-danger-link:hover { text-decoration: underline; }

/* ----- Add-lead form (modal card) ----- */
.vl-lead-form {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}
.vl-lead-form-row {
  display: flex;
  gap: 0.75rem;
}
.vl-lead-form-row .vl-lead-form-field { flex: 1; }
.vl-lead-form-field {
  display: flex;
  flex-direction: column;
  gap: 0.3125rem;
}
.vl-lead-form-field > span {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--vl-text-secondary);
}
.vl-lead-form-field > span small {
  font-weight: 400;
  color: var(--vl-text-tertiary);
  margin-left: 0.25rem;
}
.vl-lead-form-field input {
  width: 100%;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.5rem;
  background: var(--vl-bg-card);
  color: var(--vl-text-primary);
  font-size: 0.9375rem;
}
.vl-lead-form-field input::placeholder { color: var(--vl-text-tertiary); }
.vl-lead-form-field input:focus {
  outline: none;
  border-color: var(--vl-primary);
  box-shadow: 0 0 0 3px var(--vl-primary-soft, rgba(59, 130, 246, 0.15));
}

/* ----- Deal popup ----- */
.vl-deal-popup-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.vl-deal-popup-stage {
  padding: 0.25rem 0.625rem;
  border-radius: 9999px;
  color: #ffffff;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.vl-deal-popup-meta-item {
  display: flex;
  flex-direction: column;
}
.vl-deal-popup-meta-item span {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--vl-text-tertiary);
  font-weight: 600;
}
.vl-deal-popup-meta-item strong {
  font-size: 0.875rem;
  color: var(--vl-text-strong);
  font-weight: 600;
}
.vl-deal-popup-section { margin-top: 1.25rem; }
.vl-deal-popup-section h4 {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  color: var(--vl-text-secondary);
  margin: 0 0 0.5rem 0;
}
.vl-deal-popup-dates {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.5rem 1rem;
  margin: 0;
}
.vl-deal-popup-dates div { display: flex; flex-direction: column; }
.vl-deal-popup-dates dt {
  font-size: 0.6875rem;
  color: var(--vl-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.vl-deal-popup-dates dd {
  font-size: 0.875rem;
  color: var(--vl-text-strong);
  margin: 0;
}
.vl-deal-popup-empty {
  color: var(--vl-text-tertiary);
  font-size: 0.875rem;
  padding: 0.5rem 0;
  font-style: italic;
}
.vl-deal-popup-checklist {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.vl-deal-popup-checklist li {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.375rem 0;
  font-size: 0.875rem;
}
.vl-deal-popup-checklist li.is-done span {
  text-decoration: line-through;
  color: var(--vl-text-muted);
}
.vl-deal-popup-checkbox {
  width: 20px;
  height: 20px;
  border-radius: 0.25rem;
  border: 2px solid var(--vl-border-strong);
  background: var(--vl-bg-input);
  font-size: 0.875rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  flex-shrink: 0;
}
.vl-deal-popup-checklist li.is-done .vl-deal-popup-checkbox {
  background: #10b981;
  border-color: #10b981;
}
.vl-deal-popup-checkbox:hover { border-color: var(--vl-text-tertiary); }

/* Flag list with descriptions */
.vl-deal-popup-flags {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.vl-deal-popup-flags li {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  padding: 0.5rem 0.625rem;
  background: var(--vl-bg-secondary);
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
}
.vl-deal-popup-flag-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 0.375rem;
  flex-shrink: 0;
}
.vl-deal-popup-flags li > div {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
.vl-deal-popup-flags strong {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--vl-text-strong);
}
.vl-deal-popup-flags small {
  font-size: 0.75rem;
  color: var(--vl-text-tertiary);
  line-height: 1.35;
}

/* ----- Gear panel ----- */
.vl-gear-section { margin-bottom: 1.5rem; }
.vl-gear-section:last-child { margin-bottom: 0; }
.vl-gear-section h4 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--vl-text-strong);
  margin: 0 0 0.25rem 0;
}
.vl-gear-section-help {
  color: var(--vl-text-tertiary);
  font-size: 0.8125rem;
  margin: 0 0 0.75rem 0;
}
.vl-gear-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.5rem;
}
.vl-gear-toggle {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  cursor: pointer;
  background: var(--vl-bg-card);
  color: var(--vl-text-primary);
}
.vl-gear-toggle:hover { background: var(--vl-bg-hover); }
.vl-gear-toggle input { margin-top: 0.125rem; }
.vl-gear-toggle span { display: flex; flex-direction: column; gap: 0.125rem; }
.vl-gear-toggle strong { font-size: 0.875rem; color: var(--vl-text-strong); }
.vl-gear-toggle small { font-size: 0.75rem; color: var(--vl-text-tertiary); }
.vl-gear-list {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.vl-gear-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  background: var(--vl-bg-card);
  color: var(--vl-text-primary);
  font-size: 0.875rem;
}
.vl-gear-list-actions { display: inline-flex; gap: 0.25rem; }
.vl-gear-list-actions button {
  background: transparent;
  border: 1px solid var(--vl-border);
  border-radius: 0.25rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.75rem;
  cursor: pointer;
  color: var(--vl-text-secondary);
}
.vl-gear-list-actions button:hover { background: var(--vl-bg-hover); }
.vl-gear-list-actions .vl-btn-danger-link {
  border-color: transparent;
  color: var(--vl-danger-text);
}
.vl-gear-checklist-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 1rem;
  align-items: flex-start;
}
.vl-gear-checklist-cols {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  max-height: 320px;
  overflow-y: auto;
}
.vl-gear-col-btn {
  width: 100%;
  text-align: left;
  background: var(--vl-bg-card);
  color: var(--vl-text-primary);
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  padding: 0.5rem 0.625rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
.vl-gear-col-btn:hover { background: var(--vl-bg-hover); }
.vl-gear-col-btn.is-active {
  background: var(--vl-primary);
  color: var(--vl-text-on-accent);
  border-color: var(--vl-primary);
}
.vl-gear-col-btn small {
  color: var(--vl-text-tertiary);
  font-size: 0.6875rem;
}
.vl-gear-col-btn.is-active small { color: rgba(248, 250, 252, 0.75); }
.vl-gear-checklist-editor { display: flex; flex-direction: column; gap: 0.5rem; }
.vl-gear-checklist-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--vl-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.vl-gear-textarea {
  font-family: inherit;
  font-size: 0.875rem;
  padding: 0.625rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  background: var(--vl-bg-input);
  color: var(--vl-text-primary);
  resize: vertical;
  min-height: 8rem;
}

/* Per-row checklist item editor */
.vl-gear-checklist-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.vl-gear-unsaved {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--vl-warning-text);
  background: rgba(245, 158, 11, 0.18);
  padding: 0.125rem 0.5rem;
  border-radius: 9999px;
  font-weight: 600;
}
.vl-gear-item-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.vl-gear-item-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.vl-gear-item-row input[type="text"] {
  flex: 1;
  font-family: inherit;
  font-size: 0.875rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
  background: var(--vl-bg-input);
  color: var(--vl-text-primary);
}
.vl-gear-item-row input[type="text"]:focus {
  outline: none;
  border-color: var(--vl-border-focus);
  box-shadow: 0 0 0 3px var(--vl-border-focus-ring);
}
.vl-gear-item-remove {
  width: 28px;
  height: 28px;
  border-radius: 0.375rem;
  border: 1px solid var(--vl-border);
  background: var(--vl-bg-card);
  color: var(--vl-text-tertiary);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.vl-gear-item-remove:hover {
  background: var(--vl-danger-soft-bg);
  color: var(--vl-danger-text);
  border-color: var(--vl-danger);
}
.vl-gear-empty {
  color: var(--vl-text-muted);
  font-size: 0.8125rem;
  font-style: italic;
  padding: 0.5rem 0;
}
.vl-gear-checklist-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.vl-gear-checklist-actions .vl-btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
@media (max-width: 720px) {
  .vl-gear-checklist-layout {
    grid-template-columns: 1fr;
  }
}

/* ── Leads Pipeline (2026-05-21) ─────────────────────────────────────── */
/* Reuse all vl-kanban-* layout. Only override what's lead-specific:
   card content layout, the Add lead button, popup contact panel, notes
   thread, compose box, prev/next nav, sync-status footer. */

.vl-leads-col .vl-kanban-col-body {
  padding-top: 0.25rem;
}

.vl-lead-card .vl-kanban-card-primary {
  font-weight: 600;
  color: var(--vl-text-strong);
}
.vl-lead-card .vl-kanban-card-secondary {
  color: var(--vl-text-secondary);
  font-size: 0.75rem;
  line-height: 1.35;
  margin-top: 0.125rem;
}
.vl-lead-card-source {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vl-text-muted);
  font-weight: 600;
}

.vl-kanban-add-lead-btn {
  height: 2rem;
  padding: 0 0.875rem;
  font-size: 0.8125rem;
}

.vl-lead-popup-contact {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.5rem 1rem;
  padding: 0.75rem;
  background: var(--vl-bg-secondary);
  border: 1px solid var(--vl-border);
  border-radius: 0.5rem;
  margin-bottom: 1rem;
}
.vl-lead-popup-contact > div {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  min-width: 0;
}
.vl-lead-popup-contact > div > span {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vl-text-muted);
  font-weight: 600;
}
.vl-lead-popup-contact > div > strong,
.vl-lead-popup-contact > div > a {
  color: var(--vl-text-strong);
  font-weight: 500;
  word-break: break-word;
}
.vl-lead-popup-contact > div > a {
  color: var(--vl-text-link);
  text-decoration: none;
}
.vl-lead-popup-contact > div > a:hover {
  text-decoration: underline;
}

.vl-lead-popup-actions {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--vl-border);
}

/* Each action row stacks its label/hint on the left and the control on
 * the right, with a subtle card background so the two intents read as
 * separate, deliberate actions instead of two adjacent dropdowns. */
.vl-lead-popup-action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--vl-border);
  border-radius: 0.5rem;
  background: var(--vl-bg-secondary);
}

/* Visual differentiator for the destructive-ish "convert" action so it
 * doesn't look identical to the lateral "move stage" action. */
.vl-lead-popup-action-row--promote {
  border-left: 3px solid var(--vl-primary);
  background: var(--vl-bg-card);
}

.vl-lead-popup-action-head {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}
.vl-lead-popup-action-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--vl-text-strong);
}
.vl-lead-popup-action-hint {
  font-size: 0.6875rem;
  color: var(--vl-text-muted);
}
.vl-lead-popup-action-select {
  padding: 0.375rem 0.5rem;
  border: 1px solid var(--vl-border-strong);
  border-radius: 0.375rem;
  font-size: 0.875rem;
  color: var(--vl-text-primary);
  background: var(--vl-bg-input);
  min-width: 12rem;
  flex-shrink: 0;
}

.vl-lead-popup-action-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.125rem;
}

.vl-lead-notes {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  /* Intentionally NO max-height / overflow-y here.
   *
   * Earlier we capped this list at 18rem with its own scrollbar, which
   * created a nested-scroll inside the modal body — the user would
   * scroll down, hit the inner notes list's bottom, and have to scroll
   * a second time to reach the compose box below it. The modal body
   * already owns the scroll (see .vl-modal-body { overflow-y: auto })
   * so this list just lets its content extend naturally and the single
   * outer scroll handles everything. */
}
.vl-lead-notes > li {
  padding: 0.5rem 0.75rem;
  background: var(--vl-bg-secondary);
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
}
.vl-lead-note-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.25rem;
}
.vl-lead-note-meta strong {
  font-size: 0.8125rem;
  color: var(--vl-text-strong);
}
.vl-lead-note-meta small {
  font-size: 0.6875rem;
  color: var(--vl-text-muted);
}
.vl-lead-note-body {
  font-size: 0.875rem;
  color: var(--vl-text-secondary);
  white-space: pre-wrap;
  line-height: 1.45;
}

/* Threaded replies rendered nested under their parent note. Indented
 * + smaller so they visually read as conversation under the note,
 * not as standalone notes. Read-only for now — FUB's API attributes
 * all reply POSTs to the API key owner, which we'd want to surface
 * better before letting users send replies from VL. */
.vl-lead-note-replies {
  list-style: none;
  padding: 0.5rem 0 0 1.25rem;
  margin: 0.5rem 0 0;
  border-left: 2px solid var(--vl-border);
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.vl-lead-note-replies > li {
  padding: 0.375rem 0.625rem;
  background: var(--vl-bg-app);
  border: 1px solid var(--vl-border);
  border-radius: 0.375rem;
}
.vl-lead-note-replies .vl-lead-note-meta strong { font-size: 0.75rem; }
.vl-lead-note-replies .vl-lead-note-body { font-size: 0.8125rem; }

.vl-lead-note-compose {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
  /* Now that compose lives ABOVE the notes list (not below), give it
   * breathing room before the first note so the Post button doesn't
   * crowd against the next note card. */
  margin-bottom: 1.25rem;
}
.vl-lead-note-compose textarea {
  width: 100%;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--vl-border-strong);
  border-radius: 0.375rem;
  font-size: 0.875rem;
  color: var(--vl-text-primary);
  background: var(--vl-bg-input);
  font-family: inherit;
  resize: vertical;
  min-height: 4rem;
}
.vl-lead-note-compose .vl-btn-primary {
  align-self: flex-end;
}
.vl-lead-note-compose .vl-btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.vl-lead-popup-nav {
  display: flex;
  gap: 0.375rem;
  margin-right: auto;
}
.vl-lead-popup-nav .vl-btn-ghost:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ─────────────────────────────────────────────────────────────────────────
 * Global header search bar
 * Lives on the right side of the universal header card. Renders a
 * Spotlight-style dropdown of grouped hits (intents / deals / KB).
 * Wired up by static/modules/global-search.js.
 * ─────────────────────────────────────────────────────────────────────── */
.vl-global-search-wrap {
  position: relative;
  width: 100%;
  min-width: 220px;
  max-width: 340px;
}
@media (min-width: 768px) {
  .vl-global-search-wrap { width: 280px; }
}
.vl-global-search-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--vl-text-muted, #94a3b8);
  pointer-events: none;
  display: inline-flex;
}
.vl-global-search-input {
  width: 100%;
  /* extra right padding leaves room for the clear (X) button */
  padding: 0.5rem 2rem 0.5rem 2rem;
  border: 1px solid var(--vl-border, #e2e8f0);
  border-radius: 0.5rem;
  background: var(--vl-bg-input, #ffffff);
  color: var(--vl-text-primary, #1e293b);
  font-size: 0.875rem;
  line-height: 1.25rem;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.vl-global-search-input::placeholder {
  color: var(--vl-text-muted, #94a3b8);
}
.vl-global-search-input:focus {
  border-color: var(--vl-accent, #2F3A4E);
  box-shadow: 0 0 0 3px rgba(47, 58, 78, 0.12);
}
/* Hide native search clear button — we render our own .vl-global-search-clear. */
.vl-global-search-input::-webkit-search-cancel-button { display: none; }
.vl-global-search-input::-webkit-search-decoration { display: none; }

/* Clear (X) button on the right of the search input. Shown by JS only when
   the input has text (see global-search.js _toggleClear). */
.vl-global-search-clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 9999px;
  background: transparent;
  color: var(--vl-text-muted, #94a3b8);
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.vl-global-search-clear:hover {
  color: var(--vl-text-primary, #1e293b);
  background: var(--vl-bg-hover, #f1f5f9);
}
.vl-global-search-clear:focus-visible {
  outline: 2px solid var(--vl-accent, #2F3A4E);
  outline-offset: 1px;
}

.vl-global-search-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  left: auto;
  width: min(420px, 90vw);
  max-height: 60vh;
  overflow-y: auto;
  background: var(--vl-bg-elevated, #ffffff);
  border: 1px solid var(--vl-border, #e2e8f0);
  border-radius: 0.75rem;
  box-shadow: 0 12px 32px -4px rgba(15, 23, 42, 0.18), 0 4px 8px -2px rgba(15, 23, 42, 0.08);
  z-index: 200;
  padding: 0.375rem;
}
.vl-global-search-group-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vl-text-muted, #64748b);
  padding: 0.5rem 0.625rem 0.25rem;
}
.vl-global-search-group-label:not(:first-child) {
  border-top: 1px solid var(--vl-border, #e2e8f0);
  margin-top: 0.25rem;
}
.vl-global-search-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.625rem;
  border-radius: 0.5rem;
  background: transparent;
  border: none;
  color: var(--vl-text-primary, #1e293b);
  cursor: pointer;
  text-decoration: none;
  font: inherit;
}
.vl-global-search-item:hover,
.vl-global-search-item-active {
  background: var(--vl-bg-option-hover, #eff6ff);
}
.vl-global-search-item-title {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vl-text-primary, #1e293b);
  line-height: 1.3;
}
.vl-global-search-item-subtitle {
  font-size: 0.75rem;
  color: var(--vl-text-secondary, #64748b);
  margin-top: 2px;
  line-height: 1.3;
}
.vl-global-search-mark {
  background: rgba(193, 155, 101, 0.25); /* brand gold @ 25% */
  color: inherit;
  padding: 0 1px;
  border-radius: 2px;
}
.vl-global-search-empty,
.vl-global-search-loading {
  padding: 0.875rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--vl-text-secondary, #64748b);
  text-align: center;
}

/* ──────────────────────────────────────────────────────────────────────
 * Automations builder layout
 * The app ships a pre-built tailwind.css (no runtime JIT), so the arbitrary
 * classes the builder needs (max-w-[…], lg:grid-cols-[…], lg:sticky) aren't
 * compiled and silently no-op. Define them here as real CSS instead.
 * ──────────────────────────────────────────────────────────────────── */
.vl-auto-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  align-items: start;
}
@media (min-width: 1024px) {
  .vl-auto-grid { grid-template-columns: minmax(0, 1fr) 340px; }
  .vl-auto-panel { position: sticky; top: 1rem; }
}
/* Centre each flow node in a readable column instead of stretching full width. */
.vl-auto-card {
  width: 100%;
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}

/* ──────────────────────────────────────────────────────────────────────
 * On/off switch (.vl-switch) — used for the automation enable toggle on both
 * the list rows and the flow top bar. A label wraps a visually-hidden
 * checkbox plus a track/knob, so it stays keyboard-accessible. State is
 * driven by the data-on attribute on the label (the JS owns the click; the
 * inner checkbox is decorative/aria only). Routed through CSS variables so it
 * themes in dark mode.
 * ──────────────────────────────────────────────────────────────────── */
.vl-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  user-select: none;
}
.vl-switch[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.5;
}
.vl-switch-track {
  position: relative;
  flex: 0 0 auto;
  width: 2.25rem;
  height: 1.25rem;
  border-radius: 9999px;
  background: var(--vl-border-strong);
  transition: background 0.15s ease;
}
.vl-switch-knob {
  position: absolute;
  top: 0.125rem;
  left: 0.125rem;
  width: 1rem;
  height: 1rem;
  border-radius: 9999px;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.25);
  transition: transform 0.15s ease;
}
/* Current state is carried on aria-checked (data-on is reserved for the click
 * handler's *target* state), so the visual keys off aria-checked. */
.vl-switch[aria-checked="true"] .vl-switch-track { background: var(--vl-success); }
.vl-switch[aria-checked="true"] .vl-switch-knob { transform: translateX(1rem); }
.vl-switch-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--vl-text-tertiary);
  min-width: 1.75rem;
}
.vl-switch[aria-checked="true"] .vl-switch-label { color: var(--vl-success-text); }
.vl-switch:focus-within .vl-switch-track {
  box-shadow: 0 0 0 3px var(--vl-border-focus-ring);
}

/* ───────────────────────── Phase 5 — Photos tab ─────────────────────────
 * Upload progress overlay, editable position badge, and drag-reorder
 * insertion animation. Added 2026-06-03 to give the photo workflow visible
 * feedback (the upload previously gave no indication it was working, and the
 * drag-reorder gave no preview of where a card would land). */

/* Spinner overlay shown over the dashed dropzone while a bulk upload runs.
 * The dropzone gets position:relative inline from JS before this is appended. */
.phase5-upload-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: 0.5rem;
  background: rgba(248, 250, 252, 0.88);
  backdrop-filter: blur(1px);
  z-index: 5;
}
.phase5-upload-overlay-text {
  font-size: 0.8125rem;
  font-weight: 600;
  color: #2563eb;
}
.phase5-upload-spinner {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 3px solid rgba(37, 99, 235, 0.25);
  border-top-color: #2563eb;
  animation: phase5-spin 0.7s linear infinite;
}
@keyframes phase5-spin {
  to { transform: rotate(360deg); }
}
/* Small inline spinner for a button's busy state (e.g. Confirm Selection while
 * the confirm request + refetch are in flight). Sized to sit on the text
 * baseline; currentColor so it reads on any button variant. */
.phase5-btn-spinner {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.45em;
  vertical-align: -0.1em;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: phase5-spin 0.7s linear infinite;
}

/* Editable position number on a selected photo. Styled to read like the old
 * round blue badge while being a real <input>. The spinner arrows are hidden
 * so the small badge stays legible; users type a number and press Enter. */
.phase5-pos-input {
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  background: #2563eb;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 9999px;
  -moz-appearance: textfield;
  appearance: textfield;
  cursor: text;
  z-index: 3;
}
.phase5-pos-input::-webkit-outer-spin-button,
.phase5-pos-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.phase5-pos-input:focus {
  outline: none;
  background: #1d4ed8;
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.45);
}

/* Drag-reorder: smooth slide so a card visibly shifts right to open a gap.
 * `.phase5-sp-photo` is the SharePoint-gallery card (2026-07-03) — same
 * interaction, same indicator. */
.phase5-photo,
.phase5-sp-photo {
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.phase5-photo.phase5-dragging,
.phase5-sp-photo.phase5-dragging {
  opacity: 0.4;
}
/* The card the dragged photo would land in front of slides right, and a blue
 * accent bar marks the exact insertion point on its left. */
.phase5-photo.phase5-drop-before,
.phase5-sp-photo.phase5-drop-before {
  transform: translateX(14px);
}
.phase5-photo.phase5-drop-before::after,
.phase5-sp-photo.phase5-drop-before::after {
  content: "";
  position: absolute;
  left: -10px;
  top: 8px;
  bottom: 8px;
  width: 4px;
  border-radius: 4px;
  background: #2563eb;
  z-index: 4;
}

/* ───────────────────────────────────────────────────────────────────────────
 * Lead Source Breakdown — collapsible disclosure
 * Hides the native <details> marker and rotates a custom chevron when open.
 * ─────────────────────────────────────────────────────────────────────────── */
.vl-ls-details > summary { list-style: none; }
.vl-ls-details > summary::-webkit-details-marker { display: none; }
.vl-ls-chevron { transition: transform 0.15s ease; }
.vl-ls-details[open] > summary .vl-ls-chevron { transform: rotate(90deg); }

/* ───────────────────────────────────────────────────────────────────────────
 * Compact Transaction Details (2026-06-22)
 * Scoped to .vl-deal-compact, applied only to the agent/leadership/super_admin
 * card-first detail disclosure. The admin layout never carries this class, so
 * its Transaction Details view is unchanged. Tightens labels, field boxes,
 * grid gaps and section padding so the panel fits the card-first layout.
 * Ordering matters: the bg-slate-50 section rule must follow the generic
 * .border.rounded-lg rule (equal specificity) so section padding wins.
 * ─────────────────────────────────────────────────────────────────────────── */
.vl-deal-compact .vl-label { font-size: 10px; margin-bottom: 1px; }
.vl-deal-compact .border.rounded-lg { padding: 4px 8px; font-size: 13px; }
.vl-deal-compact .grid { gap: 8px; }
.vl-deal-compact .mt-3 { margin-top: 8px; }
.vl-deal-compact .rounded-lg.bg-slate-50 { padding: 10px; margin-top: 12px; }
.vl-deal-compact .rounded-lg.bg-slate-50 > .text-xs { margin-bottom: 6px; }

/* ───────────────────────────────────────────────────────────────────────────
 * TEMPORARY: "Coming Soon" overlay for Open House / Virtual Staging.
 * Reusable wrapper that blurs + disables its content and floats a legible,
 * un-blurred "Coming Soon" badge on top. Produced by window.vlComingSoon()
 * in app.shared.js. To re-enable a service, remove the vlComingSoon() call at
 * its render site — no need to touch this block.
 * ─────────────────────────────────────────────────────────────────────────── */
.vl-coming-soon { position: relative; }
.vl-coming-soon > .vl-coming-soon-content {
  filter: blur(5px);
  opacity: 0.5;
  pointer-events: none;
  user-select: none;
}
.vl-coming-soon-badge {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  text-align: center;
  padding: 16px;
}
.vl-coming-soon-badge > span {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: rgba(15, 23, 42, 0.92);
  color: #fff;
  font-weight: 800;
  font-size: 20px;
  letter-spacing: 0.02em;
  line-height: 1.2;
  padding: 14px 28px;
  border-radius: 9999px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.35);
}
.vl-coming-soon-badge > span > small {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: normal;
  color: #cbd5e1;
}
