/* ========================================================
   DARK THEME (default)
   ======================================================== */
:root,
:root[data-theme="dark"] {
  --bg-0: #0a0b0f;
  --bg-1: #12141a;
  --bg-2: #1a1d26;
  --bg-3: #1e2230;
  --bg-hover: #232736;
  --border: #262a36;
  --border-strong: #323749;
  --text-primary: #e8eaed;
  --text-secondary: #9aa0ac;
  --text-muted: #5a6170;
  --accent: #b22222;
  --accent-hover: #c62929;
  --accent-soft: rgba(178, 34, 34, 0.16);
  --accent-strong: rgba(178, 34, 34, 0.32);
  --danger: #ef4444;
  --danger-soft: rgba(239, 68, 68, 0.12);
  --success: #10b981;
  --shadow-lg: 0 20px 60px -20px rgba(0, 0, 0, 0.6);
  --shadow-md: 0 8px 20px -8px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 2px 8px -2px rgba(0, 0, 0, 0.4);
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  /* Contextual tokens that need to flip per theme */
  --nav-bg: rgba(18, 20, 26, 0.85);
  --avatar-text: #fca5a5;
  --brand-gradient: linear-gradient(135deg, #b22222 0%, #7f1d1d 100%);
  --page-gradient-1: rgba(178, 34, 34, 0.09);
  --page-gradient-2: rgba(178, 34, 34, 0.05);

  /* Lead status palette — color per SPEC §3 (stable across themes) */
  --st-coral:   #f87171;
  --st-coral2:  #fb923c;  /* J.2.7.6 intro_sent — coral→amber gradient bridge */
  --st-amber:   #f59e0b;
  --st-amber2:  #fbbf24;
  --st-blue:    #3b82f6;
  --st-indigo:  #6366f1;
  --st-teal:    #14b8a6;
  --st-green:   #34d399;
  --st-green2:  #10b981;
  --st-green3:  #059669;
  --st-gray:    #6b7280;
  --st-purple:  #a855f7;

  /* K.E.1.1 — iMessage blue. Used by any send-via-iMessage CTA so
     the visual signal matches Apple's bubble color rather than the
     red brand accent (which reads as primary action / destructive). */
  --color-imessage: #007AFF;
  --color-imessage-hover: #0071eb;
}

/* ========================================================
   LIGHT THEME
   ======================================================== */
:root[data-theme="light"] {
  --bg-0: #f6f7f9;
  --bg-1: #ffffff;
  --bg-2: #f3f4f6;
  --bg-3: #e9ecef;
  --bg-hover: #eef0f4;
  --border: #e5e7eb;
  --border-strong: #cbd5e1;
  --text-primary: #111827;
  --text-secondary: #374151;
  --text-muted: #6b7280;
  --accent: #b22222;
  --accent-hover: #991b1b;
  --accent-soft: rgba(178, 34, 34, 0.08);
  --accent-strong: rgba(178, 34, 34, 0.22);
  --danger: #dc2626;
  --danger-soft: rgba(220, 38, 38, 0.08);
  --success: #047857;
  --shadow-lg: 0 18px 50px -24px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 8px 20px -10px rgba(0, 0, 0, 0.1);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);

  --nav-bg: rgba(255, 255, 255, 0.88);
  --avatar-text: #991b1b;
  --page-gradient-1: rgba(178, 34, 34, 0.04);
  --page-gradient-2: rgba(178, 34, 34, 0.02);

  --color-imessage: #007AFF;
  --color-imessage-hover: #006fe6;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg-0);
  color: var(--text-primary);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

#app { min-height: 100%; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

::selection { background: var(--accent-soft); color: var(--text-primary); }

/* =====================================================
   LOGIN SCREEN
   ===================================================== */

.login-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
  background:
    radial-gradient(ellipse 900px 600px at 50% -10%, var(--page-gradient-1), transparent 70%),
    radial-gradient(ellipse 600px 400px at 85% 110%, var(--page-gradient-2), transparent 70%),
    var(--bg-0);
}
.login-card {
  width: 100%; max-width: 420px;
  background: var(--bg-1); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 2.5rem 2rem;
  box-shadow: var(--shadow-lg);
}
.brand { text-align: center; margin-bottom: 1.75rem; }
.brand-logo {
  display: flex;
  justify-content: center;
  margin-bottom: 0.25rem;
}
.brand-subtitle {
  font-size: 0.875rem;
  color: var(--text-muted);
  letter-spacing: 0.01em;
}

/* Logo image (shared across login / client / nav). The PNG has a
   transparent background, but its black elements (R's, roofline,
   wordmark) vanish on dark surfaces. Dark mode inverts luminance via
   invert(1) and rotates hue 180° so the red door stays red —
   net effect: black → white, white → black, red ≈ red. */
.rr-logo {
  display: block;
  max-width: 100%;
  height: auto;
}
.rr-logo-full {
  width: 100%;
  max-width: 280px;
}
.rr-logo-nav {
  height: 42px;
  width: 96px;
  object-fit: cover;
  object-position: center 38%;
}

[data-theme="dark"] .rr-logo,
:root:not([data-theme]) .rr-logo {
  filter: invert(1) hue-rotate(180deg);
}
form.stack > * + * { margin-top: 1.125rem; }
.footnote {
  margin-top: 1.5rem; text-align: center;
  font-size: 0.8125rem; color: var(--text-muted);
}

/* =====================================================
   FIELDS (shared between login + forms)
   ===================================================== */

.field { display: block; }
.field label {
  display: block;
  font-size: 0.8125rem; font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 0.5rem; letter-spacing: 0.01em;
}
.field .req { color: var(--danger); }
/* K.G.6.E — inline per-field validation error (e.g. phone must be
   10 digits). Sits directly below the input. Hidden until validation
   on blur or submit flags an issue. */
.field-error {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.75rem;
  color: var(--danger, #ef4444);
}
.field-error[hidden] { display: none; }
.field input,
.field select,
.field textarea {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.65rem 0.8125rem;
  color: var(--text-primary);
  font-size: 0.9375rem; font-family: inherit;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.field textarea { resize: vertical; min-height: 80px; }
.field input:hover:not(:focus),
.field select:hover:not(:focus),
.field textarea:hover:not(:focus) {
  border-color: var(--border-strong);
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-3);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--text-muted); }

.field select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%239aa0ac' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  padding-right: 2rem;
}

/* --------- Password input with eye toggle --------- */

.password-input-wrap {
  position: relative;
}
.password-input-wrap input {
  /* leave room on the right for the toggle button */
  padding-right: 2.5rem !important;
}
.password-toggle {
  position: absolute;
  right: 6px; top: 50%;
  transform: translateY(-50%);
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .12s ease, background .12s ease;
  padding: 0;
  font-family: inherit;
}
.password-toggle:hover {
  color: var(--text-primary);
  background: var(--bg-3);
}
.password-toggle:focus-visible {
  outline: none;
  color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.eye-icon { width: 18px; height: 18px; display: block; }
.password-toggle[aria-pressed="true"]  .eye-show { display: none; }
.password-toggle[aria-pressed="false"] .eye-hide { display: none; }

.password-mismatch {
  margin-top: -0.25rem;
  font-size: 0.8125rem;
  color: #fca5a5;
  padding: 0.125rem 0;
}
[data-theme="light"] .password-mismatch { color: #b91c1c; }

.field.inline {
  display: flex; flex-direction: column; gap: 0.375rem;
}
.field.inline label { margin-bottom: 0; }
.inline-label {
  display: block;
  font-size: 0.8125rem; font-weight: 500;
  color: var(--text-secondary); margin-bottom: 0.375rem;
}

/* =====================================================
   BUTTONS
   ===================================================== */

button, .primary, .ghost {
  font-family: inherit;
}

.primary {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: white;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: 0.65rem 1rem;
  font-size: 0.9375rem; font-weight: 500;
  cursor: pointer;
  transition: background .15s ease, transform .05s ease, box-shadow .15s ease;
  box-shadow: var(--shadow-sm);
  text-decoration: none;
}
button.primary { width: 100%; padding: 0.8125rem; }
form .primary { width: 100%; padding: 0.8125rem; }
.primary:hover:not(:disabled) { background: var(--accent-hover); color: white; }
.primary:active:not(:disabled) { transform: translateY(1px); }
.primary:disabled { opacity: 0.55; cursor: not-allowed; }
a.primary { width: auto; }

.ghost {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.55rem 0.9rem;
  font-size: 0.875rem; font-weight: 500;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
  text-decoration: none;
}
.ghost:hover:not(:disabled) {
  background: var(--bg-2); color: var(--text-primary);
  border-color: var(--border-strong);
}
.ghost:disabled { opacity: .5; cursor: not-allowed; }

.ghost.small, .primary.small {
  padding: 0.375rem 0.75rem;
  font-size: 0.8125rem;
  border-radius: var(--radius-sm);
}

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: transparent; color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 1.125rem; line-height: 1;
  cursor: pointer;
}
.icon-btn:hover { background: var(--bg-2); color: var(--text-primary); }

/* =====================================================
   ALERTS
   ===================================================== */

.alert {
  padding: 0.75rem 0.875rem;
  border-radius: var(--radius-md);
  font-size: 0.875rem;
  border: 1px solid transparent;
}
.alert.error {
  background: var(--danger-soft);
  border-color: rgba(239,68,68,.25);
  color: #fca5a5;
}
.alert.success {
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.3);
  color: #6ee7b7;
}
[data-theme="light"] .alert.success { color: #047857; }
.alert.info {
  background: var(--accent-soft);
  border-color: var(--accent-strong);
  color: var(--text-primary);
}
/* RAP-43 — low-inventory advisory (success-with-warning, amber): distinct
   from .error (failure red) and .info (accent). */
.alert.warning {
  background: rgba(232, 161, 60, 0.12);
  border-color: rgba(232, 161, 60, 0.35);
  color: #fcd34d;
}
[data-theme="light"] .alert.warning { color: #92400e; }

/* =====================================================
   APP SHELL (nav + main)
   ===================================================== */

.nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--nav-bg);
  backdrop-filter: saturate(140%) blur(8px);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  max-width: 1280px; margin: 0 auto;
  display: flex; align-items: center; gap: 1.5rem;
  padding: 0.625rem 1.5rem;
}
.nav-brand {
  display: inline-flex; align-items: center;
  color: var(--text-primary);
  text-decoration: none;
  padding: 4px;
  border-radius: var(--radius-sm);
}
.nav-brand:hover { color: var(--text-primary); }
.nav-brand:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.nav-links {
  display: flex; align-items: center; gap: 0.125rem;
  flex: 1;
}
.nav-link {
  padding: 0.5rem 0.875rem;
  font-size: 0.875rem; font-weight: 500;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background .15s ease, color .15s ease;
}
.nav-link:hover {
  color: var(--text-primary);
  background: var(--bg-2);
}
.nav-link.is-active {
  color: var(--text-primary);
  background: var(--bg-2);
}

/* J.2.2.4 — aggregate-unread badge on the Messages tab. Inline-block
   to flow next to the label, accent background. K.N C — counts are
   exact (no '10+' cap); the pill widens with the number, whitespace
   nowrap so a 3-digit count never wraps or clips at phone width.
   Hidden via [hidden] when zero. */
.nav-link-badge {
  white-space: nowrap;
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.4;
  color: #fff;
  background: var(--accent);
  border-radius: 999px;
  vertical-align: 1px;
  min-width: 1.2rem;
  text-align: center;
}
.nav-link-badge[hidden] { display: none; }

.nav-user {
  display: flex; align-items: center; gap: 0.5rem;
}
.nav-avatar {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--avatar-text);
  font-size: 0.8125rem; font-weight: 600;
  letter-spacing: 0.02em;
}

.nav-theme-toggle {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
  padding: 0;
}
.nav-theme-toggle:hover {
  background: var(--bg-2);
  color: var(--text-primary);
  border-color: var(--border);
}
.nav-theme-toggle:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.theme-icon { width: 16px; height: 16px; }
/* Dark mode shows the sun (tap → light). Light mode shows the moon. */
[data-theme="dark"]  .theme-icon-moon { display: none; }
[data-theme="light"] .theme-icon-sun  { display: none; }
/* Fallback when no theme attr is set — treat as dark. */
:root:not([data-theme]) .theme-icon-moon { display: none; }
.nav-signout {
  background: transparent; color: var(--text-muted);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0.375rem 0.625rem;
  font-size: 0.8125rem; font-family: inherit;
  cursor: pointer;
}
.nav-signout:hover {
  color: var(--text-primary);
  background: var(--bg-2);
  border-color: var(--border);
}

.app-main {
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.75rem 1.5rem 3rem;
}
.app-main.narrow { max-width: 780px; }

/* =====================================================
   PAGE HEADER + LAYOUT BLOCKS
   ===================================================== */

.page-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.5rem;
  flex-wrap: wrap;
}
.page-title {
  font-size: 1.5rem; font-weight: 600;
  letter-spacing: -0.02em;
}
.page-subtitle {
  color: var(--text-secondary);
  font-size: 0.9375rem;
  margin-top: 0.25rem;
}
.page-actions {
  display: flex; align-items: center; gap: 0.625rem;
}

.breadcrumbs {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.8125rem; color: var(--text-muted);
  margin-bottom: 0.875rem;
}
.breadcrumbs a { color: var(--text-secondary); }
.breadcrumbs a:hover { color: var(--text-primary); }
.breadcrumbs span { color: var(--text-muted); }

/* Phase J: lead-detail nav row — "← Back to leads · Prev | Next" */
.lead-detail-nav { gap: 0.625rem; }
.lead-detail-nav .nav-back { font-weight: 500; }
.lead-detail-nav .nav-pn { color: var(--text-secondary); }
.lead-detail-nav .nav-pn:hover { color: var(--text-primary); }
.lead-detail-nav .nav-sep { color: var(--text-muted); user-select: none; }

/* K.K.1.B — "Return to creating new lead" breadcrumb that appears on
   the lead detail page when the user clicked "View existing lead" from
   the new-lead collision panel. */
.pending-lead-banner {
  display: inline-flex;
  align-items: center;
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.875rem;
  background: rgba(59, 130, 246, 0.1);
  border: 1px solid rgba(59, 130, 246, 0.3);
  color: var(--text-primary);
  border-radius: var(--radius-md);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.pending-lead-banner:hover {
  background: rgba(59, 130, 246, 0.16);
  border-color: rgba(59, 130, 246, 0.5);
}
[data-theme="light"] .pending-lead-banner {
  background: rgba(59, 130, 246, 0.08);
  border-color: rgba(59, 130, 246, 0.3);
  color: #1d4ed8;
}
[data-theme="light"] .pending-lead-banner:hover {
  background: rgba(59, 130, 246, 0.14);
}

.card {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: 1.25rem;
  overflow: hidden;
}
.card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.card-header h2, .card-header h3 {
  font-size: 1rem; font-weight: 600; letter-spacing: -0.01em;
}
.placeholder-card-inline {
  padding: 1.25rem;
  text-align: center;
  background: transparent;
  border: 1px dashed var(--border);
  box-shadow: none;
}

/* =====================================================
   EMPTY / LOADING
   ===================================================== */

.empty-state {
  padding: 3rem 1.5rem; text-align: center;
  color: var(--text-secondary);
}
.empty-state h2 {
  font-size: 1.125rem; font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
}
.empty-state p { margin-bottom: 0.5rem; }
.empty-state.small { padding: 1.5rem; }

.loading {
  padding: 2rem; text-align: center;
  color: var(--text-muted); font-size: 0.875rem;
}

/* =====================================================
   SEGMENTED CONTROL (Calendar / List toggle)
   ===================================================== */

.segmented {
  display: inline-flex;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 3px;
}
.segmented-btn {
  background: transparent;
  border: none;
  padding: 0.4rem 0.875rem;
  font-size: 0.8125rem; font-weight: 500;
  color: var(--text-secondary);
  border-radius: calc(var(--radius-md) - 3px);
  cursor: pointer; font-family: inherit;
  transition: color .15s ease, background .15s ease;
}
.segmented-btn.is-active {
  background: var(--bg-1);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}

/* =====================================================
   CALENDAR
   ===================================================== */

.calendar-card { padding-bottom: 0.5rem; }
.calendar-header {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.calendar-title {
  font-size: 1.0625rem; font-weight: 600;
  letter-spacing: -0.01em;
  flex: 1; text-align: center;
}
.calendar-header .icon-btn { flex-shrink: 0; }
.calendar-header .small { margin-left: 0.5rem; }

.calendar-legend {
  display: flex; flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  padding: 0.625rem 1.25rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.8125rem;
  color: var(--text-secondary);
}
.legend-item {
  display: inline-flex; align-items: center;
  gap: 0.5rem;
}

.calendar-grid { padding: 0.75rem 0.75rem 1rem; }
.cal-weekdays, .cal-days {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.cal-weekdays {
  padding-bottom: 0.5rem;
}
.cal-weekday {
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted);
  text-align: center; padding: 0.375rem 0;
}
.cal-day {
  aspect-ratio: 1 / 0.95;
  min-height: 76px;
  padding: 0.4rem 0.5rem 0.3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  display: flex; flex-direction: column;
  background: var(--bg-1);
}
.cal-day.is-empty {
  background: transparent;
  border-color: transparent;
}
.cal-day.is-filled {
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.cal-day.is-filled:hover { border-color: var(--border-strong); background: var(--bg-2); }
.cal-day.is-today { border-color: var(--accent); }
.cal-day.is-today .cal-date { color: var(--accent); font-weight: 600; }
.cal-day.is-selected {
  background: var(--bg-3);
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft) inset;
}
.cal-date {
  font-size: 0.8125rem; font-weight: 500;
  color: var(--text-secondary);
}
.cal-dots {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: auto; padding-top: 0.5rem;
  align-items: center;
}
.dot-more {
  font-size: 0.6875rem; color: var(--text-muted); margin-left: 0.125rem;
}

/* =====================================================
   STATUS DOTS & BADGES
   ===================================================== */

.status-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 999px;
  box-shadow: 0 0 0 2px rgba(0,0,0,0.3);
}
.dot-coral   { background: var(--st-coral); }
.dot-coral2  { background: var(--st-coral2); }
.dot-amber   { background: var(--st-amber); }
.dot-amber2  { background: var(--st-amber2); }
.dot-blue    { background: var(--st-blue); }
.dot-indigo  { background: var(--st-indigo); }
.dot-teal    { background: var(--st-teal); }
.dot-green   { background: var(--st-green); }
.dot-green2  { background: var(--st-green2); }
.dot-green3  { background: var(--st-green3); }
.dot-gray    { background: var(--st-gray); }
.dot-purple  { background: var(--st-purple); }

.badge {
  display: inline-flex; align-items: center;
  padding: 0.2rem 0.55rem;
  font-size: 0.75rem; font-weight: 500;
  letter-spacing: 0.01em;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  color: var(--text-secondary);
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge-coral   { background: rgba(248,113,113,.12); color: #fca5a5; border-color: rgba(248,113,113,.25); }
.badge-coral2  { background: rgba(251,146,60,.12); color: #fdba74; border-color: rgba(251,146,60,.25); }
.badge-amber   { background: rgba(245,158,11,.12); color: #fcd34d; border-color: rgba(245,158,11,.25); }
.badge-amber2  { background: rgba(251,191,36,.12); color: #fde68a; border-color: rgba(251,191,36,.25); }
.badge-blue    { background: rgba(59,130,246,.14); color: #93c5fd; border-color: rgba(59,130,246,.28); }
.badge-indigo  { background: rgba(99,102,241,.14); color: #a5b4fc; border-color: rgba(99,102,241,.28); }
.badge-teal    { background: rgba(20,184,166,.14); color: #5eead4; border-color: rgba(20,184,166,.28); }
.badge-green   { background: rgba(52,211,153,.14); color: #6ee7b7; border-color: rgba(52,211,153,.28); }
.badge-green2  { background: rgba(16,185,129,.14); color: #6ee7b7; border-color: rgba(16,185,129,.28); }
.badge-green3  { background: rgba(5,150,105,.18); color: #a7f3d0; border-color: rgba(5,150,105,.28); }
.badge-gray    { background: rgba(107,114,128,.14); color: #d1d5db; border-color: rgba(107,114,128,.3); }
.badge-purple  { background: rgba(168,85,247,.14); color: #d8b4fe; border-color: rgba(168,85,247,.28); }

.chip {
  display: inline-flex; align-items: center;
  padding: 0.15rem 0.55rem;
  font-size: 0.75rem; font-weight: 500;
  border-radius: var(--radius-sm);
  background: var(--bg-2);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}

/* =====================================================
   LEAD ROW / DAY PANEL
   ===================================================== */

.lead-list {
  list-style: none;
  padding: 0.25rem;
}
.lead-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background .12s ease;
}
.lead-row:hover { background: var(--bg-2); }
.lead-row + .lead-row { border-top: 1px solid var(--border); }
.lead-name { font-weight: 500; }

.match-context {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--text-muted);
  margin-top: 2px;
}

/* =====================================================
   DATA TABLE
   ===================================================== */

.table-wrap {
  overflow-x: auto;
}
.data-table {
  width: 100%; border-collapse: collapse;
  font-size: 0.875rem;
}
.data-table thead th {
  text-align: left;
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted);
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
}
.data-table tbody td {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  color: var(--text-primary);
  vertical-align: middle;
}
.data-table tbody tr {
  cursor: pointer;
  transition: background .12s ease;
}
.data-table tbody tr:hover { background: var(--bg-2); }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table .nowrap { white-space: nowrap; }

.pagination {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.875rem 1.25rem;
  border-top: 1px solid var(--border);
  font-size: 0.8125rem;
  gap: 0.75rem;
}
.pagination-controls {
  display: flex; align-items: center; gap: 0.5rem;
}
.page-indicator {
  color: var(--text-secondary);
  font-weight: 500;
  padding: 0 0.375rem;
}

/* =====================================================
   FILTER BAR
   ===================================================== */

/* Phase J: lifted into the page header so it sits above the Calendar/List
   toggle and is visible in both views. Flex-wrap so it accommodates the
   variable filter set (search + status + source + assigned [admin+] +
   date_from + date_to + page-size [list-only]) on any viewport. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  padding: 1rem 1.25rem;
  align-items: end;
}
.filter-bar .field.inline { flex: 0 0 auto; }
.filter-bar .filter-search { flex: 1 1 220px; min-width: 180px; }
.filter-bar input[type="date"],
.filter-bar select { min-width: 9rem; }

/* K.O follow-up — ONE row at desktop in BOTH views. List view's extra
   controls (Date from/to, Rows) used to wrap the bar to a second row,
   so the layout visibly jumped when switching Calendar ↔ List. Above
   the K.N mobile-collapse breakpoint the bar no longer wraps: the date
   inputs and the Rows select are compacted to fixed widths and the
   wide selects shrink instead of forcing a wrap. Mobile (≤820px)
   keeps the collapsed-filters behavior untouched. */
@media (min-width: 821px) {
  .filter-bar { flex-wrap: nowrap; gap: 0.625rem; }
  /* shrinkable, but never below the control's own min-width (the
     automatic flex minimum) — a wrapper squeezed below its control
     would let the control protrude and overflow the bar */
  .filter-bar .field.inline { flex: 0 1 auto; }
  .filter-bar .field.inline select {
    width: 100%;
    min-width: 5.5rem;
  }
  /* Date inputs render ~2px taller than selects; pin every control to
     one height so the bar is pixel-identical in both views. */
  .filter-bar .field.inline select,
  .filter-bar input[type="date"] {
    height: 42px;
  }
  .filter-bar input[type="date"] {
    width: 100%;
    min-width: 6.75rem;
    max-width: 8.5rem;
  }
  .filter-bar #flt-page-size {
    width: 4.75rem;
    min-width: 4.75rem;
  }
  .filter-bar .filter-search { flex: 1 1 200px; min-width: 118px; }
}

/* =====================================================
   LEAD DETAIL
   ===================================================== */

.lead-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; margin-bottom: 1.5rem;
  flex-wrap: wrap;
}
.lead-header-main { flex: 1; min-width: 240px; }
.lead-header-actions {
  min-width: 240px;
  display: flex; flex-direction: column; gap: 0.375rem;
}
/* RAP-43 (prod Bug 2): the status line under the CRMLS auto-email button
   must never inflate the actions column. A long message gave the column a
   page-wide intrinsic (max-content) width; .lead-header wraps, so the
   column landed on its own full-width row and align-items:stretch turned
   every action button into a page-wide bar. width:0 removes the text from
   the intrinsic-width calculation; min-width:100% re-stretches the line to
   the column's resolved width at layout time so the text wraps inside it. */
#crmls-auto-email-msg { width: 0; min-width: 100%; }
/* RAP-73 — skipped-city callout on the CRMLS auto-email summary line. */
.crmls-skipped-cities { color: var(--warning, #e0a93e); }
/* RAP-87 — location-retry note on the same line. Deliberately NOT warning
   coloured: the search that got set up is correct, this only explains why
   the Matrix search reads differently from the lead's city list. */
.crmls-geocode-retry { color: var(--text-muted, #6b7280); }
.lead-meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.625rem;
  margin-top: 0.625rem;
  color: var(--text-secondary);
  font-size: 0.9375rem;
}
.lead-meta.small { font-size: 0.8125rem; }
.lead-meta strong { color: var(--text-primary); font-weight: 500; }

.status-msg { font-size: 0.8125rem; color: var(--text-muted); min-height: 1rem; }
.status-msg.ok { color: var(--success); }
.status-msg.error { color: #fca5a5; }

.kv-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.25rem 1.5rem;
  padding: 1rem 1.25rem;
}
.kv {
  display: flex; flex-direction: column;
  gap: 0.25rem;
  padding: 0.625rem 0;
  border-bottom: 1px solid var(--border);
}
.kv:last-child, .kv:nth-last-child(2):not(:nth-child(odd)) { border-bottom: none; }
.kv-wide { grid-column: 1 / -1; }
.kv dt {
  font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); font-weight: 500;
}
.kv dd {
  font-size: 0.9375rem;
  color: var(--text-primary);
  word-break: break-word;
}

.checklist {
  padding: 0.5rem 0;
}
.checklist-item {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.625rem 1.25rem;
  color: var(--text-secondary);
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.checklist-item:hover:not(:disabled) {
  background: var(--bg-2);
  color: var(--text-primary);
}
.checklist-item:hover:not(:disabled):not(.is-done) .checklist-check {
  border-color: var(--accent);
}
.checklist-item:focus-visible {
  outline: none;
  background: var(--bg-2);
  box-shadow: inset 2px 0 0 var(--accent);
}
.checklist-item:disabled { cursor: wait; opacity: 0.65; }
.checklist-item.is-done { color: var(--text-primary); }
.checklist-check {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: 6px;
  font-size: 0.75rem; font-weight: 700;
  color: transparent;
  transition: background .15s ease, border-color .15s ease;
}
.checklist-item.is-done .checklist-check {
  background: var(--success);
  border-color: var(--success);
  color: white;
}
.checklist-label { flex: 1; }

/* =====================================================
   FORM GRID (Add Lead)
   ===================================================== */

.form-grid {
  padding: 1.25rem;
  display: flex; flex-direction: column; gap: 1.25rem;
}
.form-grid .fs {
  border: none;
  display: flex; flex-direction: column; gap: 0.875rem;
}
.form-grid legend {
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}
.grid-2 {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0.875rem;
}
.grid-3 {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0.875rem;
}
.form-actions {
  display: flex; justify-content: flex-end;
  gap: 0.625rem;
}
.form-actions .primary { width: auto; padding: 0.65rem 1.25rem; }

/* =====================================================
   INLINE FORMS (Add Note / Add Task / Add Appointment)
   ===================================================== */

.inline-form {
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 0.75rem;
}
.inline-form textarea,
.inline-form input,
.inline-form select {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.55rem 0.8125rem;
  color: var(--text-primary);
  font-size: 0.9375rem; font-family: inherit;
}
.inline-form textarea {
  resize: vertical;
  min-height: 72px;
}
.inline-form textarea:focus,
.inline-form input:focus,
.inline-form select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-3);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.inline-form-actions {
  display: flex; justify-content: flex-end;
  gap: 0.5rem;
}
.inline-form .primary,
.inline-form-actions .primary {
  width: auto;
}

/* Subhead separator (e.g. Upcoming / Past, Leads / Appointments) */
.subhead {
  padding: 0.875rem 1.25rem 0.375rem;
  font-size: 0.6875rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted);
}
.subhead-muted { opacity: 0.75; }

/* =====================================================
   NOTES
   ===================================================== */

.notes-list {
  list-style: none;
  padding: 0.25rem 0;
}
.note {
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.note:last-child { border-bottom: none; }
.note-meta {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 0.375rem;
}
.note-author {
  font-weight: 500;
  font-size: 0.875rem;
  color: var(--text-primary);
}
.note-meta .icon-btn.note-delete {
  margin-left: auto;
  opacity: 0;
  transition: opacity .15s ease;
}
.note:hover .note-meta .icon-btn.note-delete { opacity: 1; }
.note-content {
  color: var(--text-secondary);
  font-size: 0.9375rem;
  line-height: 1.55;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* K.H.A.3 — System-authored notes (notes.source IS NOT NULL). Muted background
   stripe + italic author so the eye can pick them out from manual notes. */
.note.note-system {
  background: rgba(255, 255, 255, 0.025);
  border-left: 3px solid var(--accent, #6b8eff);
  padding-left: calc(1.25rem - 3px);
}
.note.note-system .note-author {
  font-style: italic;
  color: var(--text-secondary);
  font-weight: 600;
}

/* =====================================================
   TASKS
   ===================================================== */

.task-list {
  list-style: none;
  padding: 0.25rem 0;
}
.task {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--border);
  transition: background .12s ease;
}
.task:last-child { border-bottom: none; }
.task-toggle {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: 6px;
  background: transparent;
  color: transparent;
  font-size: 0.8125rem; font-weight: 700;
  cursor: pointer; font-family: inherit;
  transition: background .15s ease, border-color .15s ease;
  margin-top: 2px;
}
.task-toggle:hover { border-color: var(--accent); }
.task.is-done .task-toggle {
  background: var(--success);
  border-color: var(--success);
  color: white;
}
.task-main { flex: 1; min-width: 0; }
.task-title {
  font-size: 0.9375rem;
  color: var(--text-primary);
  font-weight: 500;
  word-wrap: break-word;
}
.task.is-done .task-title {
  text-decoration: line-through;
  color: var(--text-muted);
}
.task-desc {
  margin-top: 0.2rem;
  word-wrap: break-word;
}
.task-meta {
  margin-top: 0.3rem;
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  align-items: center;
}
.overdue-badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  font-size: 0.6875rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  border-radius: 999px;
  background: var(--danger-soft);
  color: #fca5a5;
  border: 1px solid rgba(239,68,68,.28);
}
.task.is-overdue {
  background: rgba(239,68,68,.04);
}
/* RAP-94 — Reschedule + delete now share a right-hand action group, so the
   `margin-left:auto` that used to push the lone delete button right lives on
   the container. The delete button keeps its reveal-on-hover behavior
   (unchanged); Reschedule is always visible, because it is a primary action
   on a phone, where :hover never fires. */
.task-actions {
  display: flex; align-items: center; gap: 0.25rem;
  margin-left: auto;
  flex-shrink: 0;
  margin-top: 2px;
}
.task .task-delete {
  opacity: 0;
  transition: opacity .15s ease;
  flex-shrink: 0;
}
.task:hover .task-delete { opacity: 1; }
.task-edit { margin-top: 0.6rem; }

/* RAP-94 — reminder settings card checkbox. The existing .checkbox-inline and
   .checkbox-row rules are both scoped to other components, so this is a local
   rule rather than a change to theirs. */
label.reminders-check {
  display: inline-flex; align-items: center; gap: 0.5rem;
  cursor: pointer;
  color: var(--text-primary);
}
label.reminders-check input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--accent, #6366f1);
  cursor: pointer;
}

/* =====================================================
   APPOINTMENTS
   ===================================================== */

.appt-list {
  list-style: none;
  padding: 0.25rem 0;
}
.appt-list.is-past { opacity: 0.65; }
.appt {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.appt:last-child { border-bottom: none; }
.appt-date {
  width: 52px; flex-shrink: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 0.35rem 0;
  border-radius: var(--radius-md);
  background: var(--bg-2);
  border: 1px solid var(--border);
  line-height: 1;
}
.appt-date.type-teal   { border-color: rgba(20,184,166,.35);  background: rgba(20,184,166,.08); }
.appt-date.type-indigo { border-color: rgba(99,102,241,.35);  background: rgba(99,102,241,.08); }
.appt-date.type-gray   { border-color: rgba(107,114,128,.35); background: rgba(107,114,128,.08); }
.appt-month {
  font-size: 0.6875rem; font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.appt-day {
  font-size: 1.125rem; font-weight: 600;
  color: var(--text-primary);
}
.appt-main { flex: 1; min-width: 0; }
.appt-title {
  display: flex; align-items: center; gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.9375rem;
  color: var(--text-primary);
  font-weight: 500;
}
.appt-meta { margin-top: 0.25rem; }
.appt-desc {
  margin-top: 0.3rem;
  color: var(--text-secondary);
  word-wrap: break-word;
}

/* RAP-94 — Reschedule / delete controls on an appointment row. The row is
   align-items:center, which reads fine for a one-line row but pins the
   buttons to the vertical middle of an expanded reschedule form; align them
   to the top so they stay next to the title they belong to. */
.appt { align-items: flex-start; }
.appt-actions {
  display: flex; align-items: center; gap: 0.25rem;
  flex-shrink: 0;
}
.appt-edit { margin-top: 0.6rem; }

/* Compact variant used inside the day-panel on the calendar view. */
.appt-list-compact .lead-row {
  padding: 0.6rem 1rem;
}

/* =====================================================
   APPOINTMENT MARKERS (calendar day cells)
   ===================================================== */

.cal-appts {
  display: flex; flex-wrap: wrap; gap: 3px;
  padding-top: 3px;
  align-items: center;
}
.appt-marker {
  display: inline-block;
  width: 10px; height: 5px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
}
.mk-teal   { background: var(--st-teal); }
.mk-indigo { background: var(--st-indigo); }
.mk-gray   { background: var(--st-gray); }

/* =====================================================
   DASHBOARD
   ===================================================== */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.875rem;
  margin-bottom: 1.25rem;
}
.stat-card {
  display: block;
  padding: 1.125rem 1.25rem;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s ease, transform .05s ease, background .15s ease;
}
.stat-card:hover {
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.stat-card:active { transform: translateY(1px); }
.stat-card.is-accent { border-color: var(--accent-strong); background: var(--accent-soft); }
.stat-card.is-alert  { border-color: rgba(239,68,68,.3);   background: rgba(239,68,68,.05); }
.stat-label {
  font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}
.stat-value {
  font-size: 1.875rem; font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text-primary);
}
.stat-card.is-alert .stat-value { color: #fca5a5; }
.stat-hint {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.pipeline-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1px;
  background: var(--border);
}
.pipeline-cell {
  display: flex; align-items: center; gap: 0.625rem;
  padding: 0.9rem 1.25rem;
  background: var(--bg-1);
  text-decoration: none;
  color: var(--text-primary);
  font-size: 0.9375rem;
  transition: background .15s ease;
}
.pipeline-cell:hover {
  background: var(--bg-2);
  color: var(--text-primary);
}
.pipeline-cell.is-empty { color: var(--text-muted); }
.pipeline-dot { flex-shrink: 0; }
.pipeline-label { flex: 1; }
.pipeline-count {
  font-weight: 600;
  color: var(--text-secondary);
  min-width: 1.5rem;
  text-align: right;
}
.pipeline-cell:hover .pipeline-count { color: var(--text-primary); }

/* =====================================================
   MODAL
   ===================================================== */

.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
  animation: modalFade 0.15s ease;
}
@keyframes modalFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal {
  width: 100%; max-width: 480px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 1.5rem;
  animation: modalIn 0.18s cubic-bezier(0.2, 0.8, 0.3, 1);
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.modal-title {
  font-size: 1.125rem; font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.75rem;
}
.modal-body {
  color: var(--text-secondary);
  margin-bottom: 1rem;
  font-size: 0.9375rem;
  line-height: 1.55;
}
.modal-body p + p { margin-top: 0.625rem; }
.modal-body p strong { color: var(--text-primary); font-weight: 500; }
.modal-body .field { margin-bottom: 0; }
.modal-body form.stack > * + * { margin-top: 0.875rem; }
.modal-error { margin-bottom: 0.75rem; }
.modal-actions {
  display: flex; justify-content: flex-end;
  gap: 0.5rem;
}
.modal-actions .primary,
.modal-actions .ghost { width: auto; padding: 0.55rem 1rem; }

/* =====================================================
   DANGER BUTTON VARIANTS
   ===================================================== */

.primary.is-danger {
  background: var(--danger);
}
.primary.is-danger:hover:not(:disabled) {
  background: #dc2626;
}

.ghost.is-danger {
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.35);
}
.ghost.is-danger:hover:not(:disabled) {
  background: var(--danger-soft);
  color: #fecaca;
  border-color: rgba(239, 68, 68, 0.55);
}

/* =====================================================
   INLINE EDIT SLOTS
   ===================================================== */

.inline-edit-slot {
  display: inline-block;
  width: 100%;
  min-width: 0;
}
.inline-edit-slot.is-editing {
  display: block;
}

.inline-edit {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.25rem 0.5rem;
  margin: -0.25rem -0.5rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  max-width: 100%;
  transition: background .12s ease, border-color .12s ease;
}
.inline-edit:hover {
  background: var(--bg-2);
  border-color: var(--border);
}
.inline-edit:focus-visible {
  outline: none;
  background: var(--bg-2);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.inline-edit-value {
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.inline-edit-value a { color: inherit; }
.inline-edit-placeholder {
  color: var(--text-muted);
  font-style: italic;
  /* Italic glyphs slant past their character box; the parent's
     overflow:hidden (for ellipsis truncation) clips the trailing char
     without this breathing room. */
  padding-inline-end: 0.15rem;
}
.inline-edit-pencil {
  font-size: 0.75rem;
  color: var(--text-muted);
  opacity: 0;
  transition: opacity .12s ease;
  flex-shrink: 0;
}
.inline-edit:hover .inline-edit-pencil,
.inline-edit:focus-visible .inline-edit-pencil { opacity: 1; }

.inline-edit-form {
  display: flex; flex-direction: column;
  gap: 0.5rem;
  padding: 0.25rem 0;
}
.inline-edit-control {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.625rem;
  color: var(--text-primary);
  font: inherit;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.inline-edit-control:focus { outline: none; }
textarea.inline-edit-control { resize: vertical; min-height: 72px; }
select.inline-edit-control {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%239aa0ac' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.625rem center;
  padding-right: 1.75rem;
}
.inline-edit-error { margin: 0; }
.inline-edit-actions {
  display: flex;
  gap: 0.375rem;
}
/* Override the form-wide "button.primary fills the row" rule set by the
   login form — inline edits need Save + Cancel side-by-side. Save takes
   the remaining space; Cancel sizes to its text so "Cancel" never wraps. */
.inline-edit-actions .primary {
  width: auto;
  flex: 1;
}
.inline-edit-actions .ghost {
  flex-shrink: 0;
  white-space: nowrap;
}

/* =====================================================
   DANGER ZONE (lead detail)
   ===================================================== */

.danger-zone {
  border-color: rgba(239, 68, 68, 0.25);
  background: rgba(239, 68, 68, 0.03);
}
.danger-zone .card-header {
  border-bottom-color: rgba(239, 68, 68, 0.2);
}
.danger-zone-body {
  padding: 1rem 1.25rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.danger-zone-copy { flex: 1; min-width: 220px; }
.danger-zone-title {
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 0.25rem;
}
/* K.L — second row in the danger zone gets a top divider */
.danger-zone .danger-zone-body + .danger-zone-body {
  border-top: 1px solid rgba(239, 68, 68, 0.15);
}

/* =====================================================
   ABSORBED-LEAD BANNER (Phase K.L.D.2)
   ===================================================== */
.absorbed-lead-banner {
  margin: 0.75rem 0;
  padding: 0.875rem 1rem;
}
.absorbed-lead-banner-body {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.absorbed-lead-banner-body strong { color: var(--text-primary); }
.absorbed-lead-banner-body .button {
  flex-shrink: 0;
  text-decoration: none;
  padding: 0.5rem 0.875rem;
  border-radius: var(--radius-sm);
}

/* =====================================================
   MERGE LEAD MODAL (Phase K.L)
   ===================================================== */

.modal.modal-wide {
  max-width: 640px;
  width: 100%;
}

.merge-search-input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 0.9375rem;
  font-family: inherit;
  margin: 0.5rem 0 0.75rem;
}
.merge-search-input:focus {
  outline: none;
  border-color: var(--accent, #6366f1);
}
.merge-results {
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-2);
}
.merge-results .muted { padding: 0.75rem; }
.merge-results .alert.error { margin: 0.5rem; }
.merge-candidate-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--border);
}
.merge-candidate-row:last-child { border-bottom: none; }
.merge-candidate-main { flex: 1; min-width: 0; }
.merge-candidate-name {
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 0.125rem;
}
.merge-candidate-meta {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  font-size: 0.75rem;
}

.merge-preview-pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.merge-preview-side {
  padding: 0.75rem;
  background: var(--bg-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.merge-preview-absorbed {
  border-color: rgba(239, 68, 68, 0.25);
  background: rgba(239, 68, 68, 0.04);
}
.merge-side-name {
  font-weight: 500;
  margin: 0.25rem 0;
  color: var(--text-primary);
}
.merge-preview-arrow {
  font-size: 1.25rem;
  color: var(--text-secondary);
}
.merge-section-h {
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin: 1rem 0 0.5rem;
}
.merge-counts {
  list-style: none;
  padding: 0;
  margin: 0 0 0.5rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.25rem 1rem;
}
.merge-counts li { font-size: 0.875rem; }
.merge-conflicts {
  margin: 0.5rem 0;
  padding-left: 1.25rem;
  font-size: 0.875rem;
}
.merge-conflicts code {
  font-family: ui-monospace, Menlo, Monaco, monospace;
  font-size: 0.8125rem;
  background: var(--bg-2);
  padding: 0.0625rem 0.25rem;
  border-radius: 3px;
}
.merge-inheritances { margin-top: 0.5rem; }
.merge-undo-note {
  margin-top: 1rem;
  padding: 0.625rem 0.75rem;
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.25);
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
}

/* =====================================================
   MERGE UNDO TOAST (Phase K.L.C.6)
   ===================================================== */
.merge-undo-toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.625rem 1rem;
  display: flex; align-items: center; gap: 0.75rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  z-index: 10000;
  max-width: 90vw;
  font-size: 0.875rem;
}
.merge-undo-counter {
  background: var(--bg-2);
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  color: var(--text-secondary);
}
.merge-undo-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-primary);
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  cursor: pointer;
  font: inherit;
}
.merge-undo-btn:hover { background: var(--bg-2); }
.merge-undo-close {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 1.125rem;
  line-height: 1;
  padding: 0 0.25rem;
}
.merge-undo-err {
  color: var(--danger, #ef4444);
  font-size: 0.75rem;
  margin-left: 0.5rem;
}

/* =====================================================
   TEAM PAGE
   ===================================================== */

.team-name {
  display: flex; align-items: center; gap: 0.75rem;
}
.team-actions {
  display: flex; align-items: center; gap: 0.375rem;
  justify-content: flex-end;
}
.role-select {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.35rem 1.75rem 0.35rem 0.625rem;
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%239aa0ac' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
  transition: border-color .15s ease;
}
.role-select:hover:not(:disabled) { border-color: var(--border-strong); }
.role-select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.role-select:disabled { opacity: 0.6; cursor: wait; }

/* K.F.7.C.4 — permission toggle (checkbox styled as switch) */
.perm-toggle {
  display: inline-flex; align-items: center;
  cursor: pointer;
}
/* RBAC (2026-07) — per-admin team-member picker (Team detail drawer). */
.team-member-list { display: flex; flex-direction: column; gap: 0.25rem; }
.team-member-option {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.35rem 0.5rem; border-radius: 8px; cursor: pointer;
}
.team-member-option:hover { background: var(--bg-2); }
.team-member-option input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }
.perm-toggle input[type="checkbox"] {
  appearance: none;
  width: 36px; height: 20px;
  background: var(--bg-3, var(--bg-2));
  border: 1px solid var(--border);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
  margin: 0;
}
.perm-toggle input[type="checkbox"]::after {
  content: '';
  position: absolute;
  top: 1px; left: 1px;
  width: 16px; height: 16px;
  background: var(--text-secondary, #9aa0ac);
  border-radius: 50%;
  transition: transform .15s ease, background-color .15s ease;
}
.perm-toggle input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.perm-toggle input[type="checkbox"]:checked::after {
  transform: translateX(16px);
  background: #fff;
}
.perm-toggle input[type="checkbox"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.perm-toggle input[type="checkbox"]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* =====================================================
   TEAM — slim table rows + detail drawer (2026-07)
   ===================================================== */

/* The base .data-table is width:100%, which stretched these four short
   columns across the whole card and inflated the inter-column gaps. Size the
   team table to its content and left-align it, so leftover width collects on
   the right instead of being distributed between columns. .table-wrap keeps
   overflow-x:auto, so narrow viewports still scroll. */
.data-table.team-table { width: auto; }
/* ...but the table lives in a block .card + .table-wrap, both of which still
   filled the container — leaving a half-empty box with a hard right edge and a
   stranded header underline. Make the team card (and its wrap) hug the table:
   fit-content shrinks the box to the table's width; max-width keeps it from
   sprawling on very long names and clamps to 100% so narrow viewports still
   scroll the table inside the wrap. Scoped to #team-body so the shared .card
   component is untouched elsewhere. */
#team-body > .card { width: fit-content; max-width: min(100%, 60rem); }
#team-body > .card > .table-wrap { width: fit-content; max-width: 100%; }
/* Tighten the column gaps (gap = right-padding of a cell + left-padding of the
   next). 0.75rem each ≈ 24px between columns — cohesive but not cramped. */
.data-table.team-table thead th,
.data-table.team-table tbody td {
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}
/* Keep the first column breathing against the card edge, and let the trailing
   chevron hug Last login rather than floating far right. */
.data-table.team-table thead th:first-child,
.data-table.team-table tbody td:first-child { padding-left: 1rem; }
.data-table.team-table thead th:last-child,
.data-table.team-table tbody td:last-child { padding-left: 0.4rem; }

/* Clickable rows: hover highlight already comes from .data-table tbody tr:hover.
   Add the pointer + a visible chevron + keyboard focus ring. */
.data-table.team-table tbody tr.is-clickable { cursor: pointer; }
.data-table.team-table tbody tr.is-clickable:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--accent-soft);
}
.team-row-chevron {
  color: var(--text-muted);
  font-size: 1.25rem;
  text-align: right;
  width: 1.5rem;
  transition: color .15s ease, transform .15s ease;
}
.data-table.team-table tbody tr:hover .team-row-chevron {
  color: var(--text-secondary);
  transform: translateX(2px);
}

.drawer-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex; justify-content: flex-end;
  animation: modalFade 0.15s ease;
}
.drawer {
  width: 100%; max-width: 420px; height: 100%;
  background: var(--bg-1);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column;
  animation: drawerIn 0.2s cubic-bezier(0.2, 0.8, 0.3, 1);
}
@keyframes drawerIn {
  from { transform: translateX(28px); opacity: 0.5; }
  to   { transform: none; opacity: 1; }
}
.drawer-header {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 1.25rem 1.25rem 1rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.drawer-avatar { width: 40px; height: 40px; font-size: 0.9375rem; flex-shrink: 0; }
.drawer-head-text { flex: 1; min-width: 0; }
.drawer-name { font-size: 1.0625rem; font-weight: 500; margin: 0; color: var(--text-primary); }
.drawer-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-close {
  background: none; border: none; cursor: pointer;
  color: var(--text-secondary); font-size: 1.5rem; line-height: 1;
  width: 32px; height: 32px; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  transition: background-color .15s ease, color .15s ease;
  flex-shrink: 0;
}
.drawer-close:hover { background: var(--bg-hover); color: var(--text-primary); }
.drawer-close:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

.drawer-content {
  flex: 1; overflow-y: auto;
  padding: 1.25rem;
  display: flex; flex-direction: column; gap: 1.5rem;
}
.drawer-section h3 {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); margin: 0 0 0.75rem; font-weight: 600;
}
.drawer-perm-list { display: flex; flex-direction: column; }
.drawer-perm-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.625rem 0;
}
.drawer-perm-row + .drawer-perm-row { border-top: 1px solid var(--border); }
.drawer-perm-label { font-size: 0.875rem; color: var(--text-primary); }
.drawer-meta {
  display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 1rem;
  font-size: 0.8125rem; margin: 0;
}
.drawer-meta dt { color: var(--text-muted); }
.drawer-meta dd { margin: 0; color: var(--text-secondary); text-align: right; }
.drawer-actions {
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--border);
  display: flex; gap: 0.5rem; flex-shrink: 0;
}
.drawer-actions button { flex: 1; }
.team-save-status { margin-top: 0.5rem; min-height: 1rem; }

@media (max-width: 480px) {
  .drawer { max-width: 100%; }
}

/* =====================================================
   PROPERTIES (lead detail)
   ===================================================== */

.property-list {
  padding: 0.75rem;
  display: flex; flex-direction: column;
  gap: 0.75rem;
}
.property-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-2);
  padding: 1rem 1.125rem;
}
.property-card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 0.5rem;
}
.property-address { flex: 1; min-width: 0; }
.property-title {
  font-size: 0.9375rem; font-weight: 500;
  color: var(--text-primary);
  word-wrap: break-word;
}
.property-card-actions {
  display: flex; align-items: center; gap: 0.5rem;
  flex-shrink: 0;
}

.property-status-wrap {
  display: inline-flex;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: background .12s ease;
}
.property-status-select {
  background: transparent;
  border: none;
  font: inherit;
  font-size: 0.75rem; font-weight: 500;
  padding: 0.2rem 1.75rem 0.2rem 0.625rem;
  border-radius: 999px;
  color: inherit;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' opacity='0.6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
}
.property-status-select:focus { outline: none; }
.property-status-select:focus-visible { box-shadow: 0 0 0 3px var(--accent-soft); }

.property-status-gray  { background: rgba(107,114,128,.14); color: #d1d5db; border-color: rgba(107,114,128,.3); }
.property-status-amber { background: rgba(245,158,11,.12); color: #fcd34d; border-color: rgba(245,158,11,.25); }
.property-status-blue  { background: rgba(59,130,246,.14); color: #93c5fd; border-color: rgba(59,130,246,.28); }
.property-status-green { background: rgba(52,211,153,.14); color: #6ee7b7; border-color: rgba(52,211,153,.28); }
.property-status-coral { background: rgba(248,113,113,.14); color: #fca5a5; border-color: rgba(248,113,113,.28); }

.property-card-body {
  display: flex; flex-direction: column; gap: 0.375rem;
}
.property-link a { font-size: 0.875rem; }
.property-notes {
  margin-top: 0.25rem;
  color: var(--text-secondary);
  font-size: 0.875rem;
  white-space: pre-wrap;
}

/* =====================================================
   DOCUMENTS (lead detail)
   ===================================================== */

.documents-contact-block {
  border-top: 1px solid var(--border);
}
.documents-contact-block:first-child {
  border-top: none;
}
.documents-contact-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1.25rem 0;
  flex-wrap: wrap;
}
.documents-contact-title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
}

.documents-toolbar {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.5rem 1.25rem 0.75rem;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.documents-contact-block:last-child .documents-toolbar + .documents-grid {
  border-bottom: none;
}
.documents-grid {
  padding: 0.75rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0.5rem;
}
.doc-slot {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-2);
  color: var(--text-primary);
  transition: border-color .12s ease, background .12s ease;
  min-width: 0;
  overflow: hidden;
}
.doc-slot.is-empty { opacity: 0.75; }
.doc-slot.is-uploaded:hover { border-color: var(--accent); }

/* Main click target — view the document inline. On empty slots this
   element is a non-interactive <div> with the same layout. */
.doc-slot-view {
  flex: 1;
  min-width: 0;
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.75rem 0.875rem;
  background: transparent;
  border: none;
  color: inherit;
  font: inherit;
  text-align: left;
}
.doc-slot.is-uploaded .doc-slot-view {
  cursor: pointer;
  transition: background .12s ease;
}
.doc-slot.is-uploaded .doc-slot-view:hover { background: var(--bg-3); }
.doc-slot.is-uploaded .doc-slot-view:focus-visible {
  outline: none;
  background: var(--bg-3);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* Download icon button on the right side of uploaded slots. */
.doc-slot-download {
  flex-shrink: 0;
  width: 44px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  transition: color .12s ease, background .12s ease;
}
.doc-slot-download:hover {
  color: var(--text-primary);
  background: var(--bg-3);
}
.doc-slot-download:focus-visible {
  outline: none;
  color: var(--accent);
  background: var(--bg-3);
  box-shadow: inset 2px 0 0 var(--accent);
}
.doc-slot-download svg { width: 18px; height: 18px; }

/* bugfix-doc-delete-capability — trash button, same shell as download
   button but with a destructive (red) hover state to signal the action. */
.doc-slot-delete {
  flex-shrink: 0;
  width: 44px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  transition: color .12s ease, background .12s ease;
}
.doc-slot-delete:hover {
  color: var(--danger, #ef4444);
  background: var(--bg-3);
}
.doc-slot-delete:focus-visible {
  outline: none;
  color: var(--danger, #ef4444);
  background: var(--bg-3);
  box-shadow: inset 2px 0 0 var(--danger, #ef4444);
}
.doc-slot-delete svg { width: 18px; height: 18px; }

/* Phase Employment-Types.3 — custom-slot controls. */
/* "Custom" chip next to a custom slot's label. */
.doc-slot-chip {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  vertical-align: middle;
}
/* Remove (×) button on custom slot tiles — removes the slot definition
   (gated server-side when a doc is uploaded). Same right-rail shell as the
   download/delete buttons, narrower. */
.doc-slot-remove {
  flex-shrink: 0;
  width: 34px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: color .12s ease, background .12s ease;
}
.doc-slot-remove:hover {
  color: var(--danger, #ef4444);
  background: var(--bg-3);
}
.doc-slot-remove:focus-visible {
  outline: none;
  color: var(--danger, #ef4444);
  background: var(--bg-3);
  box-shadow: inset 2px 0 0 var(--danger, #ef4444);
}
/* "+ Add custom slot" tile — a dashed, muted variant of .doc-slot that
   reads as an action rather than a document. */
.doc-slot.doc-slot-add {
  cursor: pointer;
  border-style: dashed;
  background: transparent;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0.875rem;
  color: var(--text-muted);
  text-align: left;
  font: inherit;
  opacity: 1;
}
.doc-slot.doc-slot-add:hover {
  border-color: var(--accent);
  color: var(--text-primary);
  background: var(--bg-2);
}
.doc-slot.doc-slot-add:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.doc-slot-add-plus {
  width: 28px; height: 28px;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px dashed var(--border-strong, var(--border));
  border-radius: 999px;
  font-size: 1.1rem;
  line-height: 1;
}

.doc-slot-check {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--success);
  color: white;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.9375rem;
  flex-shrink: 0;
}
.doc-slot-check-empty {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1.5px dashed var(--border-strong);
  color: var(--text-muted);
  border-radius: 999px;
  flex-shrink: 0;
}
.doc-slot-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.doc-slot-label {
  font-size: 0.9375rem;
  font-weight: 500;
}
.doc-slot-meta {
  margin-top: 0.15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* =====================================================
   PUBLIC CLIENT UPLOAD PAGE
   ===================================================== */

.client-wrap {
  min-height: 100vh;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 2.5rem 1.25rem;
  background:
    radial-gradient(ellipse 900px 600px at 50% -10%, var(--page-gradient-1), transparent 70%),
    radial-gradient(ellipse 600px 400px at 85% 110%, var(--page-gradient-2), transparent 70%),
    var(--bg-0);
}
.client-card {
  width: 100%; max-width: 560px;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 2rem;
  box-shadow: var(--shadow-lg);
}
.client-brand {
  display: flex; justify-content: center;
  margin-bottom: 1.75rem;
  color: var(--text-primary);
}
.client-brand .rr-logo {
  width: 100%;
  max-width: 280px;
  height: auto;
}
.client-greeting {
  font-size: 1.375rem; font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
}
.client-intro p { color: var(--text-secondary); }
.client-intro { margin-bottom: 1.5rem; }

.client-progress {
  margin-top: 1rem;
  display: flex; align-items: center; gap: 0.75rem;
}
.client-progress-bar {
  flex: 1;
  height: 6px;
  background: var(--bg-2);
  border-radius: 999px;
  overflow: hidden;
}
.client-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-hover) 100%);
  transition: width .3s ease;
}

.client-success {
  display: flex; align-items: center; gap: 0.875rem;
  padding: 1rem 1.25rem; margin-bottom: 1.25rem;
  background: rgba(16, 185, 129, 0.08);
  border: 1px solid rgba(16, 185, 129, 0.3);
  border-radius: var(--radius-md);
}
.client-success-mark {
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--success); color: white;
  border-radius: 999px; font-weight: 700;
  flex-shrink: 0;
}
.client-success h3 { font-size: 1rem; font-weight: 600; margin-bottom: 0.125rem; }
.client-success p { font-size: 0.875rem; margin: 0; }

.client-list {
  list-style: none; padding: 0;
  display: flex; flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}
.client-item {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-2);
  transition: border-color .12s ease, background .12s ease;
}
.client-item:hover:not(.is-busy) { border-color: var(--border-strong); }
.client-item.is-done { border-color: rgba(16, 185, 129, 0.35); background: rgba(16, 185, 129, 0.04); }
.client-item.is-busy { opacity: 0.75; }

.client-item-label {
  display: flex; align-items: center; gap: 0.875rem;
  padding: 0.875rem 1rem;
  cursor: pointer;
}
.client-item.is-busy .client-item-label { cursor: wait; }
.client-item-label input[type="file"] {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}
.client-item-check {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--border-strong);
  border-radius: 999px;
  color: white; font-weight: 700; font-size: 0.9375rem;
  flex-shrink: 0;
  transition: background .15s ease, border-color .15s ease;
}
.client-item.is-done .client-item-check {
  background: var(--success);
  border-color: var(--success);
}
.client-item-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.client-item-title { font-weight: 500; color: var(--text-primary); }
.client-item-meta { font-size: 0.8125rem; color: var(--text-secondary); margin-top: 0.125rem; }
.client-item-action { flex-shrink: 0; }
.client-item-upload, .client-item-replace {
  display: inline-flex; align-items: center;
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.8125rem; font-weight: 500;
  background: var(--accent-soft);
  color: var(--avatar-text);
  border: 1px solid var(--accent-strong);
}
.client-item.is-done .client-item-replace {
  background: transparent;
  color: var(--text-secondary);
  border-color: var(--border);
}
/* 2026-07 lock-on-upload — slot past its 45s replace window. */
.client-item.is-locked .client-item-label { cursor: default; }
.client-item-locked { font-size: 1rem; opacity: 0.7; }
.client-replace-countdown { font-variant-numeric: tabular-nums; }

.client-spinner {
  display: inline-block;
  width: 16px; height: 16px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 999px;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.client-footnote { margin-top: 0.5rem; text-align: center; }

.client-error {
  text-align: center;
  padding: 1.5rem 0;
}
.client-error h2 { font-size: 1.125rem; margin-bottom: 0.5rem; }
.client-error p { color: var(--text-secondary); margin-bottom: 0.5rem; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* =====================================================
   LEAD DETAIL TABS
   ===================================================== */

#lead-header-area { margin-bottom: 1.25rem; }

.tab-bar {
  display: flex;
  gap: 0.25rem;
  padding: 0.375rem;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 1.25rem;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.tab-bar::-webkit-scrollbar { height: 6px; }
.tab-bar::-webkit-scrollbar-track { background: transparent; }
.tab-bar::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
}

.tab-btn {
  flex-shrink: 0;
  padding: 0.5rem 0.9rem;
  background: transparent;
  border: none;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: background .15s ease, color .15s ease;
}
.tab-btn:hover {
  color: var(--text-primary);
  background: var(--bg-2);
}
.tab-btn.is-active {
  color: var(--text-primary);
  background: var(--bg-3);
  box-shadow: var(--shadow-sm);
}
.tab-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.tab-panel {
  /* Hidden panels still occupy no space since we use the [hidden] attr. */
}

/* =====================================================
   ATTACHMENTS (lead detail)
   ===================================================== */

.att-dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.375rem;
  margin: 0.75rem 1.25rem 1rem;
  padding: 1.25rem 1rem;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-2);
  color: var(--text-secondary);
  text-align: center;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.att-dropzone:hover:not(.is-busy),
.att-dropzone:focus-visible {
  border-color: var(--accent);
  background: var(--bg-3);
  color: var(--text-primary);
  outline: none;
}
.att-dropzone.is-dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text-primary);
}
.att-dropzone.is-busy {
  cursor: wait;
  color: var(--text-primary);
}
.att-dropzone u { text-decoration: underline; color: var(--text-primary); }
.att-dropzone-icon {
  font-size: 1.375rem;
  color: var(--accent);
  line-height: 1;
  margin-bottom: 0.125rem;
}
.att-error { margin: 0 1.25rem 1rem; }

.att-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.75rem;
  padding: 0.75rem 1.25rem 1.25rem;
}
.att-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  cursor: pointer;
  transition: border-color .12s ease, transform .05s ease;
}
.att-card:hover { border-color: var(--border-strong); }
.att-card:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.att-card:active { transform: translateY(1px); }

.att-thumb {
  width: 100%;
  height: 150px;
  background: var(--bg-3);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  color: var(--text-muted);
}
.att-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.att-thumb-pdf {
  background: linear-gradient(135deg, #1a1d26 0%, #232736 100%);
  color: var(--accent);
}
.att-thumb-loading { font-size: 1.125rem; opacity: 0.6; }

.att-card-body {
  padding: 0.625rem 0.75rem 0.75rem;
  display: flex; flex-direction: column; gap: 0.25rem;
  flex: 1;
}
.att-card-filename {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.att-card-meta {
  display: flex; align-items: center; gap: 0.5rem;
  flex-wrap: wrap;
}
.att-card-caption {
  margin-top: 0.125rem;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
}
.att-card-footer { margin-top: auto; padding-top: 0.25rem; }

/* ── Kebab menu ──────────────────────────────────────────────── */
.att-kebab-wrap {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 10;
}

.att-kebab {
  opacity: 0;
  font-size: 1.1rem;
  line-height: 1;
  padding: 2px 7px;
  background: var(--bg-3) !important;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  transition: opacity .12s ease;
}

.att-card:hover .att-kebab,
.att-card:focus-within .att-kebab { opacity: 1; }

.att-dropdown {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  background: var(--bg-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  min-width: 150px;
  z-index: 50;
  padding: 0.25rem 0;
}

.att-dropdown-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.875rem;
  font-size: 0.875rem;
  background: none;
  border: none;
  color: var(--text-primary);
  cursor: pointer;
  transition: background .1s;
}
.att-dropdown-item:hover { background: var(--bg-2); }
.att-dropdown-danger     { color: var(--danger); }

/* =====================================================
   ADD LEAD: SCREENSHOT UPLOAD
   ===================================================== */

.new-lead-tabs {
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.screenshot-panel {
  padding: 1.25rem;
}

.screenshot-dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.5rem;
  min-height: 220px;
  padding: 2rem 1.5rem;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  color: var(--text-secondary);
  text-align: center;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.screenshot-dropzone:hover,
.screenshot-dropzone:focus-visible {
  border-color: var(--accent);
  background: var(--bg-3);
  color: var(--text-primary);
  outline: none;
}
.screenshot-dropzone.is-dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text-primary);
}
.screenshot-icon {
  color: var(--accent);
  margin-bottom: 0.25rem;
}
.screenshot-dropzone-title {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-primary);
}

.screenshot-processing {
  display: flex; align-items: center; gap: 0.875rem;
  min-height: 220px;
  padding: 2rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  justify-content: center;
}
.screenshot-processing .client-spinner {
  width: 24px; height: 24px;
  border-width: 3px;
  flex-shrink: 0;
}
.screenshot-processing-title {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-primary);
}

.prefill-banner {
  display: flex; align-items: flex-start; gap: 0.75rem;
  margin: 1rem 1.25rem 0;
  padding: 0.75rem 1rem;
  background: var(--accent-soft);
  border: 1px solid var(--accent-strong);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: 0.875rem;
  line-height: 1.5;
}
.prefill-banner-icon {
  font-size: 1.125rem;
  line-height: 1;
  flex-shrink: 0;
}
.prefill-banner-body strong { color: var(--text-primary); font-weight: 500; }

/* =====================================================
   K.K.D — Related leads card on lead detail
   ===================================================== */

.relationships-list {
  display: flex; flex-direction: column; gap: 0.5rem;
}
.relationship-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem;
  padding: 0.625rem 0.75rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-radius: var(--radius-sm);
}
.relationship-row-main {
  display: flex; flex-direction: column; gap: 0.125rem;
  flex: 1 1 auto; min-width: 0;
}
.relationship-row-head {
  display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
}
.relationship-row-head strong { color: var(--text-primary); font-weight: 500; }
.relationship-row-actions {
  display: flex; gap: 0.25rem; flex-shrink: 0;
}

[data-theme="light"] .relationship-row {
  background: rgba(0, 0, 0, 0.015);
  border-color: rgba(0, 0, 0, 0.08);
}

.linkage-badge {
  display: inline-flex; align-items: center; gap: 0.2rem;
  font-size: 0.75rem;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: rgba(99, 102, 241, 0.12);
  color: var(--text-primary);
  border: 1px solid rgba(99, 102, 241, 0.32);
  margin-left: 0.35rem;
}
[data-theme="light"] .linkage-badge {
  color: #4338ca;
  background: rgba(99, 102, 241, 0.08);
}

.add-rel-modal { display: flex; flex-direction: column; gap: 0.75rem; }
.add-rel-results {
  display: flex; flex-direction: column; gap: 0.35rem;
  max-height: 240px; overflow-y: auto;
}
.add-rel-result {
  display: flex; flex-direction: column; gap: 0.1rem;
  text-align: left;
  padding: 0.5rem 0.7rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-primary);
}
.add-rel-result:hover { background: rgba(255, 255, 255, 0.06); }
.add-rel-picked {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0.7rem;
  background: rgba(99, 102, 241, 0.08);
  border: 1px solid rgba(99, 102, 241, 0.32);
  border-radius: var(--radius-sm);
}
.add-rel-picked-row {
  display: flex; flex-direction: column; gap: 0.1rem;
}

[data-theme="light"] .add-rel-result {
  background: rgba(0, 0, 0, 0.02);
  border-color: rgba(0, 0, 0, 0.08);
}
[data-theme="light"] .add-rel-result:hover { background: rgba(0, 0, 0, 0.05); }
[data-theme="light"] .add-rel-picked {
  background: rgba(99, 102, 241, 0.06);
}

/* =====================================================
   K.K.C — collision warning panel on lead creation form
   ===================================================== */

.collision-panel {
  margin: 1rem 0 0;
  padding: 0.875rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: 0.875rem;
  line-height: 1.45;
  display: flex; flex-direction: column; gap: 0.625rem;
}
.collision-panel-loading {
  background: rgba(107, 114, 128, 0.08);
  border-color: rgba(107, 114, 128, 0.28);
  color: var(--text-muted);
  font-style: italic;
}
.collision-panel-exact {
  background: rgba(245, 158, 11, 0.08);
  border-color: rgba(245, 158, 11, 0.32);
  color: var(--text-primary);
}
.collision-panel-fuzzy {
  background: rgba(245, 158, 11, 0.08);
  border-color: rgba(245, 158, 11, 0.32);
  color: var(--text-primary);
}
/* K.K.2.C — intra-agent hard-block. Saturated red (stronger than the
   K.K.1 amber used for cross-agent) so the visual weight matches the
   actual "you cannot create this" semantic. */
.collision-panel-intra {
  background: rgba(220, 38, 38, 0.12);
  border-color: rgba(220, 38, 38, 0.55);
  color: var(--text-primary);
}
.collision-panel-header {
  font-weight: 600;
  color: var(--text-primary);
  display: flex; align-items: center; gap: 0.5rem;
}
.collision-panel-header-fuzzy { color: var(--text-primary); }
.collision-panel-header-intra {
  color: rgb(239, 68, 68);
}
.collision-panel-icon { font-size: 1rem; line-height: 1; }

.collision-rows {
  display: flex; flex-direction: column; gap: 0.625rem;
}
.collision-row {
  padding-top: 0.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.collision-row:first-of-type {
  border-top: 0;
  padding-top: 0;
}
.collision-row-head {
  display: flex; flex-direction: column; gap: 0.2rem;
}
.collision-row-name strong { color: var(--text-primary); font-weight: 600; }
.collision-row-name .muted { font-weight: 400; }
.collision-row-meta { line-height: 1.4; }

.collision-actions {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 0.25rem;
}
.collision-actions .ghost.small,
.collision-picker-actions .ghost.small,
.collision-picker-actions .primary.small {
  font-size: 0.8125rem;
  padding: 0.35rem 0.7rem;
}

.collision-picker {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 0.6rem 0.75rem;
  background: rgba(255, 255, 255, 0.03);
  border-radius: var(--radius-sm);
}
.collision-picker select {
  width: 100%;
  padding: 0.4rem 0.6rem;
  background: var(--input-bg, rgba(255, 255, 255, 0.04));
  color: var(--text-primary);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.12));
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
}
.collision-picker-actions {
  display: flex; gap: 0.5rem; justify-content: flex-end;
}

[data-theme="light"] .collision-panel-exact {
  background: rgba(245, 158, 11, 0.07);
  border-color: rgba(245, 158, 11, 0.32);
}
[data-theme="light"] .collision-panel-fuzzy {
  background: rgba(245, 158, 11, 0.07);
  border-color: rgba(245, 158, 11, 0.32);
}
[data-theme="light"] .collision-panel-intra {
  background: rgba(220, 38, 38, 0.08);
  border-color: rgba(220, 38, 38, 0.55);
}
[data-theme="light"] .collision-panel-header-intra {
  color: rgb(185, 28, 28);
}
[data-theme="light"] .collision-row {
  border-top-color: rgba(0, 0, 0, 0.06);
}
[data-theme="light"] .collision-picker {
  background: rgba(0, 0, 0, 0.03);
}

/* =====================================================
   LIGHT-THEME CONTRAST OVERRIDES
   Pastel text colours (e.g. #fca5a5, #6ee7b7) work on the dark
   tinted backgrounds but wash out against a white card. Swap in
   the corresponding 700-range shades when the light theme is on.
   ===================================================== */

[data-theme="light"] .badge-coral   { color: #b91c1c; background: rgba(220, 38, 38, 0.08);  border-color: rgba(220, 38, 38, 0.28); }
[data-theme="light"] .badge-amber   { color: #b45309; background: rgba(245, 158, 11, 0.1);  border-color: rgba(245, 158, 11, 0.3); }
[data-theme="light"] .badge-amber2  { color: #b45309; background: rgba(251, 191, 36, 0.12); border-color: rgba(251, 191, 36, 0.3); }
[data-theme="light"] .badge-blue    { color: #1d4ed8; background: rgba(59, 130, 246, 0.1);  border-color: rgba(59, 130, 246, 0.3); }
[data-theme="light"] .badge-indigo  { color: #4338ca; background: rgba(99, 102, 241, 0.1);  border-color: rgba(99, 102, 241, 0.3); }
[data-theme="light"] .badge-teal    { color: #0f766e; background: rgba(20, 184, 166, 0.1);  border-color: rgba(20, 184, 166, 0.3); }
[data-theme="light"] .badge-green   { color: #047857; background: rgba(16, 185, 129, 0.1);  border-color: rgba(16, 185, 129, 0.3); }
[data-theme="light"] .badge-green2  { color: #047857; background: rgba(16, 185, 129, 0.1);  border-color: rgba(16, 185, 129, 0.3); }
[data-theme="light"] .badge-green3  { color: #065f46; background: rgba(5, 150, 105, 0.12);  border-color: rgba(5, 150, 105, 0.32); }
[data-theme="light"] .badge-gray    { color: #374151; background: rgba(107, 114, 128, 0.1); border-color: rgba(107, 114, 128, 0.3); }
[data-theme="light"] .badge-purple  { color: #7e22ce; background: rgba(168, 85, 247, 0.1);  border-color: rgba(168, 85, 247, 0.3); }

[data-theme="light"] .alert.error         { color: #b91c1c; border-color: rgba(220, 38, 38, 0.28); }
[data-theme="light"] .overdue-badge       { color: #b91c1c; border-color: rgba(220, 38, 38, 0.28); }
[data-theme="light"] .status-msg.error    { color: #b91c1c; }
/* Theme fix (2026-07-04): two pale-danger literals that never got the
   light override the rest of this family has. */
[data-theme="light"] .ghost.is-danger     { color: #b91c1c; }
[data-theme="light"] .ghost.is-danger:hover:not(:disabled) { color: #991b1b; }
[data-theme="light"] .stat-card.is-alert .stat-value { color: #b91c1c; }

/* Appointment date-block tints use the same hues as the type colours —
   soften them a touch for white surfaces. */
[data-theme="light"] .appt-date.type-teal   { background: rgba(20, 184, 166, 0.08);  border-color: rgba(20, 184, 166, 0.35); }
[data-theme="light"] .appt-date.type-indigo { background: rgba(99, 102, 241, 0.08);  border-color: rgba(99, 102, 241, 0.35); }
[data-theme="light"] .appt-date.type-gray   { background: rgba(107, 114, 128, 0.08); border-color: rgba(107, 114, 128, 0.35); }

[data-theme="light"] .client-success {
  background: rgba(16, 185, 129, 0.08);
  border-color: rgba(5, 150, 105, 0.3);
}
[data-theme="light"] .client-success h3 { color: #065f46; }

[data-theme="light"] .task.is-overdue   { background: rgba(220, 38, 38, 0.03); }
[data-theme="light"] .danger-zone       { background: rgba(220, 38, 38, 0.02); }

/* Calendar status dots have a faint dark ring in dark mode that vanishes on
   light backgrounds — give them a subtle light-mode ring instead. */
[data-theme="light"] .status-dot { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12); }

/* =====================================================
   UTILITIES
   ===================================================== */

.muted { color: var(--text-muted); }
.small { font-size: 0.8125rem; }

/* =====================================================
   RESPONSIVE
   ===================================================== */

@media (max-width: 820px) {
  .nav-inner { gap: 0.75rem; padding: 0.75rem 1rem; }
  .nav-brand-text { display: none; }
  .nav-link { padding: 0.4rem 0.625rem; font-size: 0.8125rem; }
  .app-main { padding: 1.25rem 1rem 2.5rem; }
  .page-header { align-items: flex-start; }
  .filter-bar { flex-direction: column; align-items: stretch; }
  .filter-bar .field.inline,
  .filter-bar .filter-search { flex: 1 1 auto; min-width: 0; }
  .kv-grid { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .lead-header-actions { min-width: 0; width: 100%; }
  .property-card-head { flex-direction: column; align-items: stretch; gap: 0.5rem; }
  .property-card-actions { align-self: flex-end; }
}

@media (max-width: 560px) {
  .grid-3 { grid-template-columns: 1fr; }
  .cal-day { min-height: 62px; padding: 0.3rem; }
  .cal-date { font-size: 0.75rem; }
  .status-dot { width: 7px; height: 7px; }
  .cal-dots { gap: 3px; padding-top: 0.3rem; }
  .cal-appts { gap: 2px; padding-top: 2px; }
  /* K.N A visual-pass catch — scope to the header (as the 820px rule
     already is): unscoped, this also hid the DRAWER's Sign out button
     at ≤560px, leaving the drawer footer with no visible Sign out. */
  .nav .nav-signout { display: none; }
  .page-title { font-size: 1.25rem; }
  .appt { gap: 0.75rem; }
  .appt-date { width: 44px; }
}

@media (max-width: 480px) {
  .login-card { padding: 2rem 1.5rem; }
  .brand h1 { font-size: 1.25rem; }
}

/* =====================================================
   MODAL — WIDE VARIANT (Send Intro Text, future larger modals)
   ===================================================== */

.modal.modal-wide { max-width: 640px; }

/* =====================================================
   RAP-104 — "Remind me" custom lead time (hours + minutes)
   ===================================================== */

.reminder-custom {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
}

.reminder-custom[hidden] { display: none; }

.reminder-custom-inputs {
  display: flex;
  gap: 8px;
}

/* Each unit is [number input][unit label] side by side, so "2 hours
   15 minutes" reads left-to-right the way it's spoken. flex:1 keeps the two
   boxes equal at any width instead of letting the hours box dominate. */
.reminder-custom-unit {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 0;
  min-width: 0;
}

.reminder-custom-unit input {
  /* min-width:0 so flex can actually shrink these on a 375px screen —
     number inputs carry an intrinsic width that otherwise overflows the row. */
  min-width: 0;
  width: 100%;
  /* 16px prevents iOS Safari from zooming the page on focus, which on a phone
     reads as the layout jumping when you tap the field. */
  font-size: 16px;
}

.reminder-custom-unit span { white-space: nowrap; }

.reminder-custom .help.is-error { color: var(--danger, #f87171); }

/* =====================================================
   TOAST (inline helper; shared .toast base lives in call-recorder.css)
   ===================================================== */

.toast.toast-success {
  border-color: rgba(16, 185, 129, 0.4);
  color: #6ee7b7;
}
[data-theme="light"] .toast.toast-success { color: #047857; }

/* RAP-104 — "your early reminder was skipped" is not a success and not an
   error: the save worked, one of the two reminders just couldn't be armed.
   Amber so it reads as something to notice rather than something that broke. */
.toast.toast-warning {
  border-color: rgba(245, 158, 11, 0.45);
  color: #fcd34d;
}
[data-theme="light"] .toast.toast-warning { color: #b45309; }

/* =====================================================
   SETTINGS — MISSION CONTROL CARD (SPEC §6.1)
   ===================================================== */

.mc-banner {
  background: var(--accent-soft);
  border-color: var(--accent-strong);
  color: var(--text-primary);
  margin-bottom: 1rem;
  font-size: 0.9rem;
}
.mc-banner strong { font-weight: 600; }

/* Phase E — duplicate-phone banner reuses .mc-banner colors but adds
   a row layout so the Dismiss button sits to the right of the text. */
.duplicate-banner {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.duplicate-banner-text { flex: 1 1 320px; }

/* K.H — Intake-overwrite banner (expandable details) */
.intake-overwrite-banner .intake-overwrite-text {
  flex: 1 1 100%;
  min-width: 0;
}
.intake-overwrite-header {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
}
.intake-overwrite-header > span { flex: 1 1 280px; }
.intake-overwrite-details {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.intake-overwrite-details[hidden] { display: none; }
.intake-overwrite-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 0.5rem;
}
.intake-overwrite-table th,
.intake-overwrite-table td {
  padding: 0.375rem 0.5rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
  vertical-align: top;
}
.intake-overwrite-table th {
  font-weight: 600;
  color: var(--text-secondary);
  background: rgba(255, 255, 255, 0.02);
}
.intake-overwrite-table tr.phone-ignored-row td {
  font-style: italic;
}
.intake-overwrite-footer { margin: 0.5rem 0 0; }

.mc-secret-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}
.mc-secret-input { flex: 1 1 220px; min-width: 0; }

.mc-template-hint code {
  background: var(--bg-3);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.8em;
}

.mc-actions { justify-content: flex-end; gap: 0.625rem; }

.mc-test-line { margin-top: 0.25rem; }
.mc-test-ok { color: #6ee7b7; }
[data-theme="light"] .mc-test-ok { color: #047857; }
.mc-test-failed { color: #fca5a5; }
[data-theme="light"] .mc-test-failed { color: #b91c1c; }

/* =====================================================
   SEND INTRO TEXT MODAL (SPEC §6.3)
   ===================================================== */

.sit-modal .modal-body { color: var(--text-primary); }

.sit-header {
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
.sit-header .modal-title { margin-bottom: 0; }

.sit-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 1.5rem;
  line-height: 1;
  width: 2rem; height: 2rem;
  padding: 0;
  cursor: pointer;
  border-radius: var(--radius-sm, 6px);
}
.sit-close:hover { color: var(--text-primary); background: var(--bg-3); }

.sit-loading {
  display: flex; flex-direction: column; align-items: center;
  gap: 0.75rem;
  padding: 2rem 1rem;
}

.sit-to {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-2);
  border-radius: var(--radius-md);
  margin-bottom: 0.875rem;
  font-size: 0.9rem;
}
.sit-to strong { font-weight: 600; }

.sit-field { margin-bottom: 0.875rem; display: block; }
.sit-label {
  display: block;
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 0.375rem;
}

.sit-textarea {
  width: 100%;
  min-height: 120px;
  padding: 0.6rem 0.75rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font: inherit;
  line-height: 1.5;
  resize: vertical;
}
.sit-textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-3);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.sit-attachment {
  display: flex; flex-direction: column; gap: 0.5rem;
}
.sit-thumb {
  width: 180px;
  max-width: 100%;
  min-height: 120px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.sit-thumb img {
  display: block;
  max-width: 100%;
  max-height: 240px;
  object-fit: contain;
}

.sit-filename {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  word-break: break-all;
}

.sit-attachment-meta {
  display: flex; flex-direction: column; gap: 0.25rem;
}

.sit-download-link {
  color: var(--accent);
  text-decoration: none;
}
.sit-download-link:hover { text-decoration: underline; }

.sit-copy-hint {
  margin-top: 0.25rem;
  font-style: italic;
}

.mc-openclaw-hint {
  margin-top: -0.25rem;
  font-style: italic;
}

.sit-error { margin-bottom: 0.75rem; }

/* =====================================================
   MESSAGES — two-pane shell (Phase J.2.1, refined J.2.2.1)
   Layout strategy (J.2.2.1): when the messages view is on
   screen we promote body + #app to flex columns via :has(),
   and the shell takes flex:1 of the remaining space. This
   replaces the old `height: calc(100vh - 9rem)` calc that
   was off by ~50px and pushed the composer past the
   viewport on shorter desktop windows. Side-effect-free for
   other views — :has() only fires when .messages-shell is
   actually mounted.
   ===================================================== */

body:has(.messages-shell) {
  /* Lock scrolling to inside the panes. Without this, page can
     scroll vertically AND each pane can scroll, fighting each other. */
  overflow: hidden;
}

body:has(.messages-shell),
body:has(.messages-shell) #app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

body:has(.messages-shell) #app {
  flex: 1 1 auto;
  min-height: 0;
}

/* J.2.2.3 — when the messages view is mounted, drop the nav's
   1280px max-width so the avatar + signout button sit at the same
   right edge as the messages shell. Without this, the nav-inner
   stays centered at 1280px on wide screens while the shell extends
   to viewport edge — visually the avatar floats in a column the
   panes can't enter.

   J.2.2.4 — scoped to viewports >820px (matches the existing
   desktop/mobile breakpoint elsewhere in this file). On mobile,
   the nav uses its standard layout — without the cap, narrow
   screens didn't have enough horizontal room for all tabs +
   avatar without the avatar bleeding past the right edge or the
   leftmost tab clipping past the left edge. */
@media (min-width: 821px) {
  body:has(.messages-shell) .nav-inner {
    max-width: none;
  }
}

.app-main.messages-app-main {
  /* Inbox uses the full viewport width — overrides the default
     1280px max-width + 0-auto margins on .app-main. The margin
     reset is critical: max-width:none removes the cap but
     margin: 0 auto can STILL center in a flex container's
     remaining space, which is what was visually narrowing the
     shell on wide desktops. Belt + suspenders width:100% guards
     the case where some browser quirk de-prioritises stretch. */
  max-width: none;
  margin: 0;
  width: 100%;
  padding: 1rem 1.25rem 1rem;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.messages-shell {
  display: grid;
  /* CSS variable is set inline by messagesInbox.js, restored from
     localStorage on each mount. The 4px middle column is the resize
     handle. */
  grid-template-columns: var(--inbox-width, 320px) 4px 1fr;
  gap: 0;
  flex: 1 1 auto;
  min-height: 0;
}

.messages-pane {
  display: flex;
  flex-direction: column;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  min-height: 0;
  min-width: 0;
}

.messages-pane-list {
  /* No left-rounded corner needed when the resize handle butts up
     against the right edge — keeps both panes visually anchored. */
  border-radius: 12px 0 0 12px;
}

.messages-pane-detail {
  border-radius: 0 12px 12px 0;
  border-left: 0;
}

.messages-pane-header {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 48px;
}

.messages-list-header {
  justify-content: space-between;
}

.messages-pane-header .page-title {
  margin: 0;
  font-size: 1.15rem;
}

.messages-pane-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1rem 1.25rem;
  min-height: 0;
}

.messages-pane-footer {
  border-top: 1px solid var(--border);
  padding: 0.75rem 1rem;
  background: var(--bg-2);
}

.messages-pane-footer:empty {
  display: none;
}

.messages-placeholder,
.messages-empty-state {
  color: var(--text-muted, #9aa0aa);
}

.messages-empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: 2rem;
  font-size: 0.95rem;
}

/* ── Phase J.2.2.1 — resize handle, collapse, back arrow ───────── */

.messages-resize-handle {
  position: relative;
  cursor: col-resize;
  background: transparent;
  user-select: none;
  touch-action: none;
}

.messages-resize-handle::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 1px; right: 1px;
  background: var(--border);
  transition: background 0.15s;
}

.messages-resize-handle:hover::before,
.messages-resize-handle.is-dragging::before {
  background: var(--accent);
}

.messages-collapse-btn,
.messages-back-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--text-muted, #9aa0aa);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}

.messages-collapse-btn:hover,
.messages-back-arrow:hover {
  background: var(--bg-hover);
  color: inherit;
}

.messages-back-arrow {
  /* Hidden on desktop; CSS-only show via media query when on mobile
     AND a conversation is selected. */
  display: none;
}

.messages-detail-header-slot {
  flex: 1 1 auto;
  min-width: 0;
}

/* Detail-pane header on desktop: until J.2.3 fills the slot, the
   back arrow is hidden and the slot is empty. Collapse the header
   to zero height so the right pane's empty state isn't sitting
   below an empty 48px strip. On mobile, the back arrow shows
   inside this header (via .has-active rule below) and collapses
   that selector by re-asserting min-height.
   J.2.3 — when thread.js fills the slot with
   .messages-thread-header-content, restore the normal header
   styling so the lead/agent name + subtitle have room. The :has()
   selector wins on specificity AND only matches when content
   exists, so the empty-state right pane stays uncluttered. */
@media (min-width: 821px) {
  .messages-pane-detail > .messages-detail-header {
    min-height: 0;
    padding: 0;
    border-bottom: 0;
  }
  .messages-pane-detail > .messages-detail-header:has(.messages-thread-header-content) {
    min-height: 48px;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border);
  }
}

/* Collapsed left pane: shrink to a sliver, hide all body content,
   only the toggle button remains visible (now serving as expand). */
.messages-shell.is-collapsed-left {
  grid-template-columns: 56px 4px 1fr;
}

.messages-shell.is-collapsed-left .messages-pane-list .messages-pane-body,
.messages-shell.is-collapsed-left .messages-list-header .page-title {
  display: none;
}

.messages-shell.is-collapsed-left .messages-list-header {
  justify-content: center;
}

.messages-shell.is-collapsed-left .messages-resize-handle {
  pointer-events: none;
}

/* ── Mobile (≤820px) — single pane stack, back arrow on detail ── */

@media (max-width: 820px) {
  body:has(.messages-shell) {
    /* Keep page lockscroll behaviour on mobile too. */
    overflow: hidden;
  }
  .app-main.messages-app-main {
    padding: 0.5rem 0.5rem 0.5rem;
  }
  .messages-shell {
    /* Single column; one pane visible at a time. */
    grid-template-columns: 1fr;
  }
  .messages-resize-handle,
  .messages-collapse-btn {
    display: none;
  }
  .messages-shell.has-active .messages-pane-list { display: none; }
  .messages-shell.no-active  .messages-pane-detail { display: none; }
  .messages-shell.has-active .messages-back-arrow { display: inline-flex; }
  .messages-pane-list,
  .messages-pane-detail {
    border-radius: 12px;
  }
}

/* =====================================================
   MESSAGES — inbox conversation list (Phase J.2.2)
   ===================================================== */

.messages-inbox {
  display: flex;
  flex-direction: column;
  height: 100%;
  margin: -1rem -1.25rem; /* break out of .messages-pane-body padding */
}

.messages-inbox-toolbar {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-1);
  position: sticky;
  top: 0;
  z-index: 1;
}

.messages-search-wrap {
  position: relative;
  margin-bottom: 0.5rem;
}

.messages-search-input {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 2rem 0.5rem 0.75rem; /* right padding for clear button */
  font: inherit;
  color: inherit;
}

.messages-search-input:focus {
  outline: none;
  border-color: var(--accent);
}

/* Hide the native browser X on type=search so our custom one is the
   only clear control. Webkit + Edge. */
.messages-search-input::-webkit-search-cancel-button,
.messages-search-input::-webkit-search-decoration { -webkit-appearance: none; }

.messages-search-clear {
  position: absolute;
  top: 50%;
  right: 0.4rem;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: var(--text-muted, #9aa0aa);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.messages-search-clear:hover {
  background: var(--bg-hover);
  color: inherit;
}

.messages-search-clear[hidden] {
  display: none;
}

.messages-result-count {
  margin-top: 0.5rem;
  font-size: 0.75rem;
}

.messages-result-count:empty {
  display: none;
}

.messages-filter-chips {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.filter-chip {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted, #9aa0aa);
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.filter-chip:hover {
  background: var(--bg-hover);
  color: inherit;
}

.filter-chip.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}

.messages-conv-list {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}

.messages-conv-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* RAP-100 — paging footer under the conversation rows: infinite-scroll
   sentinel, load-more button, in-flight text and retry, all in one slot.
   The generous vertical padding is deliberate on touch: it puts the
   button in a comfortable thumb target and gives the scroll handler room
   to fire before the user hits a hard stop. */
.messages-conv-more {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 6px;
  padding: 14px 12px 20px;
  text-align: center;
}

.messages-conv-more p {
  margin: 0;
}

.messages-conv-more button {
  width: 100%;
  max-width: 260px;
  min-height: 40px;
}

/* J.2.2.4 — iMessage-style three-column row:
       [● dot] [name         ] [time]
               [preview......]
   Dot is a fixed-width left-side indicator (visible only when
   unread > 0); main is name+preview stacked; time is the only
   meta. Eliminates the J.2.2.3 height mismatch where the meta
   column (time + counter badge) had a different stacked height
   than the main column (name + preview), which broke center
   alignment with mixed font-sizes. Aggregate unread count now
   lives on the nav tab. */
.messages-conv-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
}

.messages-conv-row:hover {
  background: var(--bg-hover);
}

/* J.2.3.1 — active row uses a subtle background highlight (Apple
   Messages convention) rather than the previous accent left-bar +
   accent-soft tint. The unread dot indicator stays accent-colored —
   it signals unread, not selection. */
.messages-conv-row.is-active {
  background: var(--bg-3);
}

.conv-row-unread-dot {
  flex: 0 0 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  /* Hidden when row not unread — keeps the indent consistent so
     unread rows don't visually shift left/right when count drops
     to 0. Hidden via visibility instead of display so the layout
     reserves the slot. */
  visibility: hidden;
}

.messages-conv-row.has-unread .conv-row-unread-dot {
  visibility: visible;
}

.conv-row-main {
  flex: 1 1 auto;
  min-width: 0; /* allows children to shrink below intrinsic width → ellipsis */
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.conv-row-name {
  font-weight: 500;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.messages-conv-row.has-unread .conv-row-name {
  font-weight: 700;
}

.conv-row-time {
  flex: 0 0 auto;
  font-size: 0.78rem;
  white-space: nowrap;
  align-self: center;
}

.conv-row-preview {
  font-size: 0.85rem;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-muted, #9aa0aa);
}

.messages-conv-row.has-unread .conv-row-preview {
  color: inherit;
}

/* =====================================================
   MESSAGES — thread (Phase J.2.3 right-pane)
   Bubble layout, day dividers, attribution, reactions.
   ===================================================== */

.messages-thread {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
  padding: 1rem 1.25rem;
  /* J.2.5 — dropped the negative-margin "break out of pane padding"
     trick. It worked in the /messages right pane but bled past the
     host edges when the same module was embedded in the per-lead
     Messages tab (where the host has no surrounding padding). The
     small extra inset in the inbox is the cosmetic trade-off. */
}

.messages-thread-content {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  /* Push content to the bottom of the scroller when the thread
     doesn't fill the viewport — feels natural for short threads. */
  margin-top: auto;
}

.messages-day-group {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.messages-day-divider {
  position: relative;
  text-align: center;
  margin: 0.75rem 0 0.25rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted, #9aa0aa);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.messages-day-divider::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0; right: 0;
  height: 1px;
  background: var(--border);
}
.messages-day-divider span {
  position: relative;
  background: var(--bg-1);
  padding: 0 0.6rem;
}

/* Bubble wrapper: caps width and side-aligns. */
.message-bubble-wrap {
  display: flex;
  flex-direction: column;
  max-width: 70%;
  margin-bottom: 0.1rem;
  position: relative;
}

/* J.2.7.5 Bug J — owner-only delete affordance. Hidden by default,
 * fades in on hover. Positioned outside the bubble so it doesn't
 * eclipse content. From-me bubbles show it on the LEFT side of the
 * bubble; from-them bubbles show it on the RIGHT. */
.message-delete-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: var(--bg-3);
  color: var(--text-secondary);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  z-index: 1;
}
.message-bubble-wrap:hover .message-delete-btn { opacity: 0.85; }
.message-delete-btn:hover { background: #c0392b; color: #fff; opacity: 1; }
.message-delete-btn:disabled { opacity: 0.4; cursor: wait; }
.message-bubble-wrap.is-from-me .message-delete-btn  { left:  -28px; }
.message-bubble-wrap.is-from-them .message-delete-btn { right: -28px; }
.message-bubble-wrap.is-from-me {
  align-self: flex-end;
  align-items: flex-end;
}
.message-bubble-wrap.is-from-them {
  align-self: flex-start;
  align-items: flex-start;
}

/* Stacked-bubble: same-author runs hide their own attribution + tighten. */
.message-bubble-wrap + .message-bubble-wrap {
  margin-top: -0.05rem;
}

.message-bubble {
  padding: 0.5rem 0.8rem;
  border-radius: 16px;
  word-wrap: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
  font-size: 0.95rem;
}

/* J.2.3.1 — bubble colors per Apple Messages convention.
   Outbound iMessage: blue.   Outbound SMS: green.   Inbound (any): gray.
   The .is-from-them rule comes after, so inbound styling wins
   regardless of the service class on the wrapper.
   J.2.7.1 — .is-image-only wrappers don't get a bubble (Apple
   Messages convention: standalone photos float without a colored
   pill). When body OR non-image attachments exist alongside images,
   the bubble still renders for the text/non-image part. */
.message-bubble-wrap.is-from-me.is-imessage .message-bubble {
  background: #0b93f6;
  color: #fff;
  border-bottom-right-radius: 5px;
}
.message-bubble-wrap.is-from-me.is-sms .message-bubble {
  background: #34c759;
  color: #fff;
  border-bottom-right-radius: 5px;
}
.message-bubble-wrap.is-from-them .message-bubble {
  background: var(--bg-2);
  color: var(--text-primary);
  border-bottom-left-radius: 5px;
}

/* J.2.7.1 — multi-image stack (vertical, tight gap), and the
   image-only modifier that suppresses the bubble entirely. */
.message-images-stack {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.message-bubble-wrap.is-image-only .message-bubble { display: none; }
.message-bubble a {
  color: inherit;
  text-decoration: underline;
}

.message-attribution {
  font-size: 0.7rem;
  color: var(--text-muted, #9aa0aa);
  margin-top: 0.18rem;
  padding: 0 0.4rem;
}

/* Attachments — J.2.3 pill UI for non-images / images without
   thumbnails. J.2.7 inline <img> for images that have one.
   J.2.7.1 — pills are now <a> elements linking to /full; remove
   the default <a> underline + force inherit color so they keep
   reading as pills. */
.message-attachment-pill {
  margin-top: 0.3rem;
  padding: 0.35rem 0.6rem;
  background: rgba(0,0,0,0.06);
  border-radius: 8px;
  font-size: 0.85rem;
  color: inherit;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}
.message-attachment-pill:hover {
  background: rgba(0, 0, 0, 0.1);
}
.message-bubble-wrap.is-from-me .message-attachment-pill {
  background: rgba(255,255,255,0.18);
  color: #fff;
}
.message-bubble-wrap.is-from-me .message-attachment-pill:hover {
  background: rgba(255, 255, 255, 0.28);
}
[data-theme="light"] .message-bubble-wrap.is-from-them .message-attachment-pill {
  background: var(--bg-3);
}
[data-theme="light"] .message-bubble-wrap.is-from-them .message-attachment-pill:hover {
  background: var(--bg-hover);
}

/* J.2.7 — inline image attachment + onerror→pill fallback container.
   The pill is in the DOM at all times but hidden by default;
   .img-failed (set by the <img onerror>) hides the link and reveals
   the pill. */
.message-attachment-image-container {
  margin-top: 0.3rem;
}
.message-attachment-image-container .message-attachment-pill-fallback {
  display: none;
}
.message-attachment-image-container.img-failed > .message-attachment-image-link {
  display: none;
}
.message-attachment-image-container.img-failed .message-attachment-pill-fallback {
  display: inline-block;
}
.message-attachment-image-link {
  display: inline-block;
  line-height: 0; /* kill the inline-img descender gap */
}
.message-attachment-image {
  display: block;
  max-width: 280px;
  max-height: 360px;
  width: auto;
  height: auto;
  object-fit: cover;
  border-radius: 12px;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.04); /* soft placeholder while loading */
}
@media (max-width: 820px) {
  .message-attachment-image {
    max-width: 220px;
    max-height: 280px;
  }
}

/* Reactions row sits just below the bubble. Slight overlap is the
   iMessage convention but we keep it separate for simplicity. */
.message-reactions {
  display: flex;
  gap: 0.2rem;
  margin-top: 0.2rem;
  padding: 0 0.4rem;
}
.message-reaction {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.4rem;
  font-size: 0.78rem;
  line-height: 1.2;
}

/* RAP-41 — tapback affordance. Rendered only on the newest inbound
   message (the only one Apple's mechanism can react to). The add-chip
   sits in the reactions row so it needs no hover to discover (phone
   friendly); the picker pops above it. */
/* No position:relative here — the picker anchors to the nearest
   positioned ancestor, .message-bubble-wrap, so it pops above the
   whole message instead of covering the bubble text. */
.message-tapback-area {
  display: inline-flex;
  align-items: center;
}
.message-tapback-add {
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.45rem;
  font-size: 0.78rem;
  line-height: 1.2;
  color: var(--text-secondary);
  cursor: pointer;
  opacity: 0.65;
  transition: opacity 0.15s ease, border-color 0.15s ease;
}
.message-tapback-add:hover {
  opacity: 1;
  border-color: var(--accent);
}
.message-tapback-plus {
  font-size: 0.65rem;
  vertical-align: super;
}
.message-tapback-picker {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  display: flex;
  gap: 0.15rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.25rem 0.4rem;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  z-index: 5;
  white-space: nowrap;
}
.message-tapback-picker[hidden] { display: none; }
.message-tapback-option {
  background: transparent;
  border: none;
  border-radius: 50%;
  font-size: 1.05rem;
  line-height: 1;
  padding: 0.3rem;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.15s ease;
}
.message-tapback-option:hover:not(:disabled) {
  transform: scale(1.25);
  background: var(--bg-1);
}
.message-tapback-option:disabled {
  opacity: 0.35;
  cursor: default;
}

/* Reply quote line above its bubble. Truncated to one line. */
.message-reply-quote {
  border-left: 3px solid var(--accent);
  padding: 0.1rem 0.5rem;
  margin-bottom: 0.2rem;
  font-size: 0.78rem;
  color: var(--text-muted, #9aa0aa);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--bg-1);
  border-radius: 4px;
}

.thread-load-top {
  text-align: center;
  padding: 0.5rem 0;
}

/* Thread header content (rendered into messages-detail-header-slot) */
.messages-thread-header-content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  /* RAP-57 — was 0.05rem, which put the phone subtitle <1px under the
     name so it visually crowded the top of its line. */
  gap: 0.25rem;
}
.messages-thread-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
a.messages-thread-title:hover {
  color: var(--accent);
}
.messages-thread-subtitle {
  font-size: 0.72rem;
}

/* RAP-54 — owner-only thread archive controls */
.messages-thread-header-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1 1 auto;
  min-width: 0;
  /* RAP-57 — on narrow screens the action group (archived badge +
     Restore + Delete permanently) is wider than the space next to the
     title; without wrap it crushed the title column into mid-word
     button wraps. Let it drop to its own right-aligned line instead. */
  flex-wrap: wrap;
  row-gap: 0.35rem;
}
/* RAP-57 — when the header carries capture actions (Create lead /
   Link to lead), the right-side action group used to float mid-height,
   ~15px above the capture buttons' baseline. Bottom-align the row so
   both button groups sit on one clean baseline. Headers without
   capture actions (lead threads, archived threads) keep the centered
   layout, which is already correct for a title+subtitle stack. */
.messages-thread-header-row:has(.messages-thread-link-actions) {
  align-items: flex-end;
}
.messages-thread-header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  flex: 0 0 auto;
  /* RAP-57 — badge + Restore + Delete permanently can exceed a phone
     viewport; wrap right-aligned instead of clipping off-screen. */
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 0.35rem;
  min-width: 0;
  max-width: 100%;
}
.messages-archived-badge {
  font-size: 0.72rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--danger-soft);
  color: var(--danger);
  border: 1px solid var(--danger);
  white-space: nowrap;
}
.messages-conv-row .conv-row-restore {
  flex: 0 0 auto;
  align-self: center;
}
.messages-conv-row.is-archived .conv-row-archived-meta {
  color: var(--danger);
  opacity: 0.85;
}

/* RAP-56 — delete-permanently-now controls */
.messages-conv-row .conv-row-purge {
  flex: 0 0 auto;
  align-self: center;
}
.purge-confirm-input {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.65rem 0.8125rem;
  color: var(--text-primary);
  font-size: 0.9375rem;
  font-family: inherit;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.purge-confirm-input:focus {
  outline: none;
  border-color: var(--danger);
  background: var(--bg-3);
  box-shadow: 0 0 0 3px var(--danger-soft);
}
.purge-confirm-input::placeholder { color: var(--text-muted); }

/* =====================================================
   MESSAGES — composer (Phase J.2.4)
   Right-pane footer: textarea + send button + meta line.
   ===================================================== */

.messages-composer {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.messages-composer-meta {
  font-size: 0.72rem;
  padding: 0 0.25rem;
}

.messages-composer-input-row {
  display: flex;
  gap: 0.5rem;
  align-items: flex-end;
}

.messages-composer-input {
  flex: 1 1 auto;
  min-height: 36px;
  max-height: 200px;
  padding: 0.55rem 0.85rem;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 18px;
  font: inherit;
  color: inherit;
  resize: none;
  overflow-y: auto;
  line-height: 1.35;
}

.messages-composer-input:focus {
  outline: none;
  border-color: #0b93f6;
  box-shadow: 0 0 0 2px rgba(11, 147, 246, 0.15);
}

.messages-composer-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Send button styled to match the iMessage-blue outbound bubble — the
   button literally produces those bubbles. Disabled state desaturates. */
.messages-composer-send {
  flex: 0 0 auto;
  background: #0b93f6;
  color: #fff;
  border: 0;
  padding: 0.55rem 1.1rem;
  border-radius: 18px;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  transition: background 0.12s, opacity 0.12s;
}

.messages-composer-send:hover:not(:disabled) {
  background: #0a7fd4;
}

.messages-composer-send:disabled {
  background: var(--bg-3);
  color: var(--text-muted, #9aa0aa);
  cursor: not-allowed;
}

.messages-composer-error {
  margin-top: 0.25rem;
  font-size: 0.85rem;
}

/* =====================================================
   PER-LEAD MESSAGES SECTION (Phase J.2.5)
   Embeds the same thread + composer modules from the
   top-level /messages view inside a card on the lead
   detail page's Messages tab.
   ===================================================== */

.lead-messages-section .lead-messages-tabs {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 0.5rem 0.75rem 0.6rem;
  border-bottom: 1px solid var(--border);
}

.lead-messages-tab {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted, #9aa0aa);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.lead-messages-tab:hover {
  background: var(--bg-hover);
  color: inherit;
}

.lead-messages-tab.is-active {
  background: var(--bg-3);
  color: var(--text-primary);
  border-color: var(--border-strong, var(--border));
}

/* K.G.C — per-tab unread badge for multi-contact threads */
.lead-messages-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.2em;
  margin-left: 0.4em;
  padding: 0 0.35em;
  border-radius: 999px;
  background: var(--accent, #5a8fff);
  color: #fff;
  font-size: 0.65rem;
  font-weight: 600;
  line-height: 1.4;
}

.lead-messages-hidden-note {
  margin-left: auto;
  font-size: 0.72rem;
}

/* The pane gives the embedded thread + composer a constrained
   container with explicit height — the thread.js module needs a
   sized parent for its internal flex / scroll layout to work
   (height: 100% on .messages-thread). 70vh feels right for desktop;
   capped so very tall windows don't make a single section dominate. */
.lead-messages-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 70vh;
  max-height: 720px;
  border-top: 0; /* tabs above already have border-bottom */
}

.lead-messages-thread-host {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.lead-messages-composer-host {
  flex: 0 0 auto;
  border-top: 1px solid var(--border);
  padding: 0.75rem 1rem;
  background: var(--bg-2);
}

/* Smaller mobile: shrink the pane to the available viewport so it
   doesn't push the lead-detail action footer off screen. */
@media (max-width: 820px) {
  .lead-messages-pane {
    height: 60vh;
    max-height: 560px;
  }
}

/* K.G.6.C — empty-tab state inside the thread host. Shown when the
   user selects a tab for a contact who has no conversation yet. */
.lead-messages-thread-host .lead-messages-empty-state {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
  text-align: center;
}

/* =====================================================
   COMPOSER — attachment picker (Phase J.2.7.1)
   Paperclip button, file input, drag/drop visual state,
   row of preview thumbnails above the input.
   ===================================================== */

.messages-composer.is-drop-target {
  outline: 2px dashed #0b93f6;
  outline-offset: -4px;
  border-radius: 12px;
}

.messages-composer-attach {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text-muted, #9aa0aa);
  cursor: pointer;
  padding: 0;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.messages-composer-attach:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.messages-composer-attach:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* RAP-8 — snippet picker + unresolved-variable warning */
.messages-composer-snippets-menu {
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-elevated, var(--bg-card, #1c1e24));
  padding: 0.35rem;
  margin: 0 0.25rem 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.messages-composer-snippet-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.45rem 0.55rem;
  cursor: pointer;
  color: var(--text-primary);
}
.messages-composer-snippet-item:hover {
  background: var(--bg-hover);
}
.messages-composer-snippet-name {
  font-weight: 600;
  font-size: 0.9rem;
}
.messages-composer-snippet-warn {
  font-size: 0.75rem;
  color: var(--warning, #e8a13c);
}
.messages-composer-snippet-preview {
  font-size: 0.78rem;
  color: var(--text-muted, #9aa0aa);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.messages-composer-unresolved {
  margin: 0 0.25rem 0.4rem;
}
.messages-composer-unresolved code {
  background: rgba(232, 76, 76, 0.15);
  border-radius: 4px;
  padding: 0 0.3em;
}

.messages-composer-attachments {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  padding: 0 0.25rem;
}

.messages-composer-attachment-preview {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-3);
  border: 1px solid var(--border);
}
.messages-composer-attachment-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.messages-composer-attachment-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 0.85rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.messages-composer-attachment-remove:hover {
  background: rgba(0, 0, 0, 0.85);
}

/* ── J.2.7.6 Bug M — Intro Templates Settings section ─────────────── */
.intro-template-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
/* Theme fix (2026-07-04): this section referenced token names that were
   never defined (--bg-secondary/--bg-tertiary/--border-secondary), so
   the hardcoded dark fallbacks always won and light mode rendered
   dark-on-dark. Real tokens only — no literal fallbacks. */
.intro-template-row {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  background: var(--bg-2);
}
.intro-template-row-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}
.intro-template-body {
  margin: 0.25rem 0 0.6rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-3);
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.9rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.intro-template-row-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.intro-template-row-actions button {
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
}
.intro-template-editor {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1rem;
  background: var(--bg-2);
  border: 1px solid var(--accent);
  border-radius: 8px;
  margin-bottom: 1rem;
}
.intro-template-editor label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
}
.intro-template-editor label.checkbox-row {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}
.intro-template-editor input[type="text"],
.intro-template-editor input[type="email"],
.intro-template-editor input[type="password"],
.intro-template-editor textarea {
  width: 100%;
  font-family: inherit;
  font-size: 0.95rem;
  /* Theme fix (2026-07-04): these were UA-default (white even in dark
     mode) — token them like the app's standard .field controls. */
  background: var(--bg-1);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.65rem;
}
/* J.2.7.7 Bug R — keep the checkbox at native size; the width:100%
 * rule above was making it stretch to fill the row, pushing it far
 * left of its label text. */
.intro-template-editor label.checkbox-row input[type="checkbox"] {
  width: auto;
  margin: 0;
  flex: 0 0 auto;
}
.intro-template-editor textarea {
  min-height: 8rem;
  resize: vertical;
}

/* ── J.2.7.6 — Send Intro Text modal: template picker dropdown ────── */
.sit-select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  font-family: inherit;
  font-size: 0.95rem;
  /* Theme fix (2026-07-04): dead token names → always-dark fallbacks;
     match the app's standard form controls (.field select). */
  background: var(--bg-2);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 6px;
}

/* ── J.2.10 — Call Recorder modal + floating pill ───────────────────────── */

.cr-modal {
  max-width: 460px;
}
.cr-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}
.cr-header-btns {
  display: flex;
  gap: 0.25rem;
}
.cr-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  padding: 0.5rem 0.25rem;
  text-align: center;
}
.cr-icon {
  font-size: 2rem;
  line-height: 1;
}
.cr-icon-warn {
  filter: hue-rotate(-15deg);
}
.cr-hint {
  color: var(--text-secondary);
  font-size: 0.95rem;
  margin: 0;
}
.cr-rec-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.cr-rec-label {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.cr-timer {
  font-variant-numeric: tabular-nums;
  font-size: 2.25rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}
.cr-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.cr-stages {
  list-style: none;
  padding: 0;
  margin: 0;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 100%;
}
.cr-stage {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.95rem;
  color: var(--text-muted);
}
.cr-stage.cr-active { color: var(--text-secondary); }
.cr-stage.cr-done   { color: var(--text-primary); }
.cr-error-msg {
  color: var(--danger);
  font-weight: 500;
  margin: 0;
}

/* Recording dot — pulsing red, or static gray when paused. */
.cr-dot {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--danger);
  flex-shrink: 0;
}
.cr-dot.is-pulsing {
  animation: crPulse 1.2s ease-in-out infinite;
}
.cr-dot.is-static {
  background: var(--text-muted);
}
@keyframes crPulse {
  0%   { box-shadow: 0 0 0 0 var(--danger); opacity: 1; }
  60%  { box-shadow: 0 0 0 7px transparent; opacity: 0.55; }
  100% { box-shadow: 0 0 0 0 transparent;  opacity: 1; }
}

/* ── Floating pill (minimized state) ─────────────────────────────────────
 * The host is a pointer-events:none full-screen wrapper so the
 * underlying page receives clicks/scroll. The pill itself opts back
 * in to pointer-events. z-index 1000 sits above sticky bars and
 * dropdowns; the modal-backdrop is 100, but the two views are never
 * concurrent (minimized vs expanded). */
.cr-pill-host {
  position: fixed;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
}
.cr-pill {
  position: absolute;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.95rem;
  min-height: 30px;
  background: var(--bg-2);
  border: 2px solid var(--border);
  border-radius: 999px;
  box-shadow: var(--shadow-lg, 0 12px 34px rgba(0, 0, 0, 0.5));
  user-select: none;
  cursor: grab;
  font-size: 1rem;
  color: var(--text-primary);
  /* RAP-69 Phase 2: free-drag + resize use Pointer Events; disable native
     touch gestures on the pill so a drag/resize doesn't scroll the page. */
  touch-action: none;
}
/* RAP-69 Phase 2: corner grip to resize the pill (JS scales via transform,
   origin top-left, and persists the size). */
.cr-pill-resize {
  position: absolute;
  right: 3px;
  bottom: 3px;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  opacity: 0.5;
  touch-action: none;
  background:
    linear-gradient(135deg,
      transparent 0 42%, var(--text-secondary) 42% 52%,
      transparent 52% 66%, var(--text-secondary) 66% 76%,
      transparent 76%);
}
.cr-pill-resize:hover { opacity: 0.95; }
.cr-pill.is-resizing { cursor: nwse-resize; }
/* FIX 4: bigger, always-visible status dot + label inside the pill. */
.cr-pill .cr-dot { width: 14px; height: 14px; }
.cr-pill-label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.72rem;
  color: var(--danger);
}
/* (RAP-69 Phase 2 removed the FIX 4 corner-dock classes — the pill free-drags
   with a clamped on-screen position set inline by applyPillTransform().) */
.cr-pill.is-dragging {
  cursor: grabbing;
  opacity: 0.92;
}
/* Subtle red glow during active recording to keep the user aware. */
.cr-pill.is-recording {
  border-color: var(--danger);
  box-shadow: 0 0 0 2px var(--danger-soft, rgba(239, 68, 68, 0.18)),
              0 10px 28px rgba(0, 0, 0, 0.45);
}
.cr-pill-timer {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-size: 1.05rem;
}
.cr-pill-uploading {
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-style: italic;
}
.cr-pill-btn {
  font-size: 0.8rem;
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-3);
  color: var(--text-primary);
  cursor: pointer;
  white-space: nowrap;
}
.cr-pill-btn:hover { background: var(--bg-hover); }
.cr-pill-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.cr-pill-stop {
  background: var(--danger-soft, rgba(239, 68, 68, 0.12));
  border-color: var(--danger);
  color: var(--danger);
}
.cr-pill-stop:hover {
  background: var(--danger);
  color: #fff;
}
.cr-pill-expand {
  border-radius: 50%;
  width: 28px;
  height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* =====================================================
   K.E.1 — Lead detail Properties tab
   ===================================================== */

.portal-link-card {
  background: var(--bg-2);
  border: 1px solid var(--border);
}
.portal-link-card .portal-link-url {
  margin: 0.5rem 0 0.75rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: monospace;
  font-size: 0.875rem;
  word-break: break-all;
}
.portal-link-card .portal-link-url a { color: var(--accent); }
.portal-link-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.portal-link-status { margin: 0; }

.lead-properties-table .data-table-actions {
  text-align: right;
  white-space: nowrap;
}
.lead-properties-table .data-table-actions button + button {
  margin-left: 0.25rem;
}
.lead-properties-row-address { cursor: pointer; }
.lead-properties-row-address strong { display: block; }


/* =====================================================
   K.E.1.1 — Lead profile polish + bug-fix increment
   ===================================================== */

/* The portal URL is informational, not action — drop the accent
   (red) color and use the muted/secondary token so it reads as
   plain text. The Copy / Send buttons retain their colors. */
.portal-link-card .portal-link-url a {
  color: var(--text-secondary);
  text-decoration: none;
}
.portal-link-card .portal-link-url a:hover {
  color: var(--text-primary);
  text-decoration: underline;
}

/* Inline-sized portal action buttons. Default `button.primary` /
   `button.ghost` are width:100%; we override here so the buttons
   sit naturally next to each other inside .portal-link-actions. */
.portal-link-card .portal-link-actions button.primary,
.portal-link-card .portal-link-actions button.ghost {
  width: auto;
  padding: 0.4rem 0.85rem;
}

/* Send via iMessage button — iMessage blue, applied to portal card
   and any future send-via-iMessage CTA. */
.portal-link-card button[data-portal-send-imessage] {
  background: var(--color-imessage);
  color: #ffffff;
  border-color: var(--color-imessage);
}
.portal-link-card button[data-portal-send-imessage]:hover:not(:disabled) {
  background: var(--color-imessage-hover);
  border-color: var(--color-imessage-hover);
  color: #ffffff;
}

/* Inline-sized + Add Property by MLS# in the section header. */
.lead-properties-list .card-header button.primary[data-add-mls] {
  width: auto;
  padding: 0.4rem 0.85rem;
}

/* Wide modal variant — used by composeOutreachModal +
   propertyDetailModal to give the embedded thread / property detail
   room to breathe. Generic .modal caps at 480px; .modal-wide bumps
   to a more comfortable working width and pins the modal to a
   flexible height that still scrolls when content overflows. */
.modal-wide {
  max-width: 720px;
  width: 100%;
  max-height: calc(100vh - 3rem);
  display: flex;
  flex-direction: column;
}

.modal-wide .compose-outreach-modal-header,
.modal-wide .property-detail-modal-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.75rem;
  margin-bottom: 0.75rem;
}
.modal-wide .compose-outreach-modal-header .modal-title,
.modal-wide .property-detail-modal-header .modal-title {
  flex: 1 1 auto;
  margin-bottom: 0;
}
.modal-wide .compose-outreach-modal-close,
.modal-wide .property-detail-modal-close {
  flex-shrink: 0;
}

.compose-outreach-modal-body,
.property-detail-modal-body {
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

/* K.E.2.1 — Picker shown when a property has 2+ interests. Sits
   above the thread/composer; lets the user pick which client to
   compose on behalf of. Matches dark-theme inputs elsewhere. */
.compose-picker {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-2);
  font-size: 0.9rem;
}
.compose-picker label {
  color: var(--muted);
  white-space: nowrap;
}
.compose-picker select {
  padding: 0.25rem 0.5rem;
  background: var(--bg-1);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

/* The compose-outreach modal embeds thread.js + composer.js. Keep
   the thread bounded so the composer stays in view; matches the
   /agents/:id page rhythm but inside the modal frame. */
.compose-outreach-thread {
  min-height: 200px;
  max-height: 50vh;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 0.75rem;
  background: var(--bg-2);
}
.compose-outreach-composer {
  /* composer.js owns its own internal padding; just give it room. */
  min-height: 0;
}

.property-detail-modal-fullpage {
  text-decoration: none;
  white-space: nowrap;
}
.property-detail-modal-fullpage:hover {
  color: var(--text-primary);
  text-decoration: underline;
}

/* When propertyDetail.js's paint() runs inside the modal, the
   inline /properties breadcrumb at the top of its output is
   redundant (the modal title already shows the address). Hide it
   inside the modal body but keep it on the standalone page. */
.property-detail-modal-body > .breadcrumbs:not(.property-back-to-lead) {
  display: none;
}
/* The Back-to-lead breadcrumb is not relevant inside the modal —
   the user is already on the lead profile. */
.property-detail-modal-body > .property-back-to-lead {
  display: none;
}

/* Back-to-lead breadcrumb on the full /properties/:id page. */
.property-back-to-lead {
  margin-bottom: 0.5rem;
}
.property-back-to-lead a {
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: 500;
}
.property-back-to-lead a:hover {
  color: var(--text-primary);
  text-decoration: underline;
}


/* =====================================================
   K.E.1.2 — Card padding fix
   The base .card has zero body padding (only .card-header
   is padded). Children directly inside the card therefore
   sit flush against the rounded corners — visible as text
   clipping on the lead Properties tab and the property
   detail modal. Add explicit horizontal+bottom padding to
   the body content of the affected cards. We avoid a global
   `.card > :not(.card-header)` rule because some cards
   (e.g. .property-interests with its data table, the
   leadProperties.js properties table) want their child
   elements to span edge-to-edge.
   ===================================================== */

/* Client portal card body content (lead Properties tab) */
.portal-link-card > :not(.card-header) {
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.portal-link-card > :last-child {
  padding-bottom: 1rem;
}

/* Properties section empty state on the lead Properties tab.
   The data-table case keeps no padding so rows span edge-to-edge. */
.lead-properties-list .empty-state {
  padding: 1rem 1.25rem 1.25rem;
}

/* Property detail cards (full /properties/:id page AND the modal).
   Each card body needs horizontal padding so dl/dt/dd, paragraphs,
   and edit affordances clear the rounded corners. .property-interests
   is excluded — its <table> spans edge-to-edge by design. */
.property-header > :not(.card-header),
.property-listing-agent > :not(.card-header),
.property-details > :not(.card-header),
.property-notes > :not(.card-header) {
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.property-header > :last-child,
.property-listing-agent > :last-child,
.property-details > :last-child,
.property-notes > :last-child {
  padding-bottom: 1.25rem;
}

/* The interests card's "+ Link to a client" picker and empty state
   need padding too — but the table inside data-interests-body should
   stay edge-to-edge, so target the empty-state and link-picker only. */
.property-interests .empty-state,
.property-interests .property-link-picker {
  padding: 0.5rem 1.25rem 1rem;
}


/* =====================================================
   K.E.1.3 — Agent detail card padding
   Extends the K.E.1.2 pattern to the agent detail page's
   cards. Same root cause: .card has zero body padding so
   the phone/email/license dl on .agent-header, the
   properties-listed paragraph on .agent-properties, and
   the iMessage thread embed on .agent-thread-card all sit
   flush against the rounded corners.
   ===================================================== */
.agent-header > :not(.card-header),
.agent-properties > :not(.card-header),
.agent-thread-card > :not(.card-header) {
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.agent-header > :last-child,
.agent-properties > :last-child,
.agent-thread-card > :last-child {
  padding-bottom: 1.25rem;
}

/* =====================================================
   K.E.2 — Multi-agent list on property detail
   The Agents card may render N entries instead of one
   fixed listing-agent block. Each entry is separated by
   a hairline divider, and the per-entry name + role
   label sit on one row.
   ===================================================== */
.property-agents-list {
  display: flex;
  flex-direction: column;
}
.property-agent-entry {
  padding: 1rem 0;
  border-bottom: 1px solid var(--border);
}
.property-agent-entry:first-child {
  padding-top: 0;
}
.property-agent-entry:last-child {
  padding-bottom: 0;
  border-bottom: none;
}
.property-agent-entry-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.property-agent-entry-name {
  text-decoration: none;
  color: var(--text);
}
.property-agent-entry-name:hover strong {
  text-decoration: underline;
}
.property-agent-role-badge {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--surface-2, rgba(255, 255, 255, 0.06));
  color: var(--muted);
  white-space: nowrap;
}
.property-agent-role-listing_agent {
  background: rgba(59, 130, 246, 0.15);
  color: var(--blue, #60a5fa);
}
.property-agent-role-co_listing_agent {
  background: rgba(168, 162, 158, 0.18);
  color: var(--muted);
}
.property-agent-entry .property-agent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

/* Add-agent modal — narrower than the compose-outreach modal. */
.add-agent-modal {
  width: min(420px, calc(100vw - 2rem));
}
.add-agent-modal .modal-body {
  padding: 0 1.25rem 1.25rem;
}
.add-agent-modal .field {
  margin-bottom: 0.75rem;
}
.add-agent-modal .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* ─────────────────────────────────────────────────────────────────
   K.F.3.C.2 — Admin decision-state pill (5 states, locked colors)
   Same visual language as the property header "Available" badge:
   background at ~14% alpha, border at full alpha, text at full alpha.
   ───────────────────────────────────────────────────────────────── */

.decision-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.625rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
  line-height: 1.4;
}
.decision-pill-gray {
  background: rgba(148, 163, 184, 0.14);
  border-color: rgba(148, 163, 184, 0.55);
  color: rgb(148, 163, 184);
}
.decision-pill-yellow {
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.65);
  color: rgb(245, 158, 11);
}
.decision-pill-green {
  background: rgba(16, 185, 129, 0.14);
  border-color: rgba(16, 185, 129, 0.65);
  color: rgb(16, 185, 129);
}
.decision-pill-red {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.65);
  color: rgb(239, 68, 68);
}
.decision-pill-leased {
  background: rgba(71, 85, 105, 0.20);
  border-color: rgba(71, 85, 105, 0.85);
  color: rgb(148, 163, 184);
}
/* K.O B.1 — .decision-pill-off-market is GONE: the class override that
   routed Off market to a gray pill was removed from decisionStatePill.js;
   off_market + not_pursuing now inherit red from the canonical map. */

/* K.O B.1 — light-mode legibility. The slate text that reads as "gray"
   on the dark theme is near-invisible on white (the July 4 gray-on-gray
   screenshot). Darken text in light mode; tint stays subtle. */
:root[data-theme="light"] .decision-pill-gray {
  background: rgba(100, 116, 139, 0.10);
  border-color: rgba(71, 85, 105, 0.45);
  color: rgb(71, 85, 105);
}
:root[data-theme="light"] .decision-pill-leased {
  background: rgba(71, 85, 105, 0.12);
  border-color: rgba(51, 65, 85, 0.65);
  color: rgb(51, 65, 85);
}

/* Property Workflow Hygiene polish C — Notes card layout. Two
   sections (Admin / Client) need explicit vertical rhythm and a
   visual divider so the user immediately sees the boundary between
   internal and portal-visible notes. */
.property-notes-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.property-notes-section {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
/* Subtle horizontal divider between admin and client sections. Uses
   the same --border token as card edges so it disappears into the
   theme — present but not loud. */
.property-notes-section-client {
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.property-notes-label {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  margin-bottom: 0;
}
.property-notes-label-title {
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--text-primary);
  letter-spacing: 0;
}
.property-notes-label-sub {
  font-weight: 400;
  margin-left: 0;
}
.property-notes-footer {
  padding-top: 0.25rem;
}

/* Polish phase E — count badge in the lead-detail Properties section
   header. Subtle pill matching existing .badge defaults; spaced and
   vertically centered against the h2 text. */
.lead-properties-heading {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.lead-properties-count {
  font-size: 0.75rem;
  font-weight: 600;
}
/* Portal property detail — "Notes from your agent" block preserves
   newlines from the textarea. */
.portal-detail-client-notes-body {
  white-space: pre-line;
}

/* /properties aggregate-state badges — compact + clickable look. */
.properties-aggregate-badges {
  display: inline-flex; flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.25rem;
}
.properties-aggregate-badge {
  display: inline-flex; align-items: center;
  gap: 0.25rem;
  padding: 0.125rem 0.4375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid transparent;
}
.properties-aggregate-badge .properties-aggregate-count {
  font-weight: 700;
}

/* Phase D.2 — outreach indicator badge in the lead Properties tab.
   Reuses the decision-pill-green visual; only adds the inline spacing
   so it sits cleanly below the city/state/zip line in the address
   cell. Hover tooltip carries the exact ISO timestamp. */
.outreach-badge-row {
  margin-top: 0.25rem;
}
.outreach-badge {
  cursor: help;
}

/* K.F.3.C.1 — Client-note preview row.
   Sits beneath the property row in the lead detail table OR inline
   in the property-detail interests table's NOTES cell. */
.client-note-preview {
  display: inline-flex; align-items: center;
  gap: 0.375rem;
  max-width: 100%;
  cursor: pointer;
  background: none;
  border: 1px dashed rgba(148, 163, 184, 0.35);
  border-radius: var(--radius-sm);
  padding: 0.125rem 0.4375rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  text-align: left;
}
.client-note-preview:hover {
  border-color: rgba(148, 163, 184, 0.7);
  color: var(--text-primary);
}
.client-note-preview-icon { font-size: 0.875rem; opacity: 0.7; }
.client-note-preview-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 22ch;
}
.client-note-preview-count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.client-notes-popover {
  margin-top: 0.375rem;
  padding: 0.625rem 0.75rem;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 0.8125rem;
  max-height: 220px;
  overflow-y: auto;
}
.client-notes-popover ul { list-style: none; padding: 0; margin: 0; }
.client-notes-popover li {
  display: flex; flex-direction: column; gap: 0.125rem;
  padding: 0.4375rem 0;
  border-bottom: 1px solid rgba(148, 163, 184, 0.18);
}
.client-notes-popover li:last-child { border-bottom: none; }
.client-notes-popover .author-tag {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}
.client-notes-popover .author-tag.client { color: rgb(16, 185, 129); }
.client-notes-popover .author-tag.admin,
.client-notes-popover .author-tag.owner { color: rgb(99, 102, 241); }

/* K.F.3.C.3 — Status advance buttons in the lead-detail row. */
.lead-properties-status-cell {
  display: flex; flex-direction: column;
  gap: 0.25rem;
  align-items: flex-start;
}
/* UI/UX overhaul follow-up (Increment D) — bird's-eye access-type line
   under each per-lead row, mirroring the client portal mapping. */
.lead-properties-access-hint {
  line-height: 1.3;
  max-width: 22rem;
}
/* K.O Phase C — the Increment E toolbar select + header click-cycle
   are gone. One mechanism: a multi-select filter menu anchored in the
   Status column header, plus an explicit Date added sort toggle. */
.lead-properties-status-th {
  position: relative;
  white-space: nowrap;
}
.status-filter-toggle,
.date-sort-toggle {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-weight: inherit;
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.status-filter-toggle:hover,
.date-sort-toggle:hover { color: var(--accent); }
.lead-properties-status-th.is-filtered .status-filter-toggle { color: var(--accent); }
.status-filter-menu {
  /* position: fixed — absolute positioning got clipped by the .card
     overflow:hidden + .table-wrap overflow-x:auto ancestors (K.O
     review finding). Fixed elements ignore ancestor overflow; the JS
     anchors top/left to the toggle on open and closes on scroll. */
  position: fixed;
  z-index: 60;
  min-width: 13rem;
  max-height: min(20rem, 70vh);
  overflow-y: auto;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  text-align: left;
}
.status-filter-menu[hidden] { display: none; }
.status-filter-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.375rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--text-primary);
  white-space: nowrap;
}
.status-filter-option:hover { background: var(--bg-3); }
.status-filter-all {
  align-self: flex-start;
  padding: 0.2rem 0.375rem;
}
.lead-properties-no-match { text-align: center; padding: 1rem; }
.lead-properties-status-actions {
  display: flex; flex-wrap: wrap;
  gap: 0.25rem;
  align-items: center;
}
.lead-properties-status-actions button {
  font-size: 0.6875rem;
  padding: 0.125rem 0.4375rem;
}
/* K.F.4.A.4 — "+ Schedule tour" / "Reschedule tour" sits on yellow
   rows. Renders as an inline text link, not a button-pill. */
.lead-properties-status-actions .link-button {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
  font-size: 0.75rem;
}
.lead-properties-status-actions .link-button:hover { color: var(--accent-strong, var(--accent)); }

/* ─────────────────────────────────────────────────────────────────
   K.F.3.B.5 — Failed uploads (admin retry surface)
   ───────────────────────────────────────────────────────────────── */

.lead-failed-uploads {
  margin-top: 1rem;
}
.failed-uploads-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.failed-upload-row {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-3);
}
.failed-upload-thumb {
  width: 96px;
  aspect-ratio: 16 / 9;
  flex-shrink: 0;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: 0; margin: 0;
  cursor: zoom-in;
}
.failed-upload-thumb:hover { border-color: var(--border-strong); }
.failed-upload-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
.failed-upload-thumb-placeholder {
  font-size: 1.5rem;
  opacity: 0.5;
  user-select: none;
}
/* ── In-page attachment viewer (RAP-69, promoted by RAP-79) ──────────────
 * The standard viewer for every attachment/document/file open in the CRM
 * (RAP-79) — files never front a new tab by default, which also keeps the
 * RAP-69 invariant: the recording tab never goes hidden (visibilitychange
 * would salvage the recording). z-index 900 sits above page chrome but
 * BELOW the recorder pill (.cr-pill-host, 1000) so Stop/Pause stay
 * reachable. */
.att-viewer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 900;
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  animation: modalFade 0.15s ease;
}
.att-viewer {
  display: flex;
  flex-direction: column;
  max-width: min(1100px, 96vw);
  max-height: 94vh;
  min-width: min(340px, 92vw);
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: modalIn 0.18s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.att-viewer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--border);
  flex: none;
}
.att-viewer-name {
  font-size: 0.9rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.att-viewer-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
}
.att-viewer-body audio {
  width: min(420px, 86vw);
  margin: 2rem 1.25rem;
}
.att-viewer-body {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
  min-height: 120px;
}
.att-viewer-body img {
  max-width: 100%;
  max-height: calc(94vh - 56px);
  display: block;
  object-fit: contain;
}
.att-viewer-body iframe {
  width: min(1000px, 94vw);
  height: calc(94vh - 56px);
  border: 0;
}
.att-viewer-nopreview {
  padding: 2rem 1.5rem;
  max-width: 420px;
  text-align: center;
}
.failed-upload-body {
  flex: 1;
  min-width: 0;
  display: flex; flex-direction: column; gap: 0.125rem;
}
.failed-upload-actions {
  display: flex; flex-direction: column; gap: 0.375rem;
  flex-shrink: 0;
}
.failed-upload-row.is-processing { opacity: 0.72; }
.failed-upload-processing {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.375rem 0.625rem;
  border: 1px dashed var(--border-color, #444);
  border-radius: 6px;
  white-space: nowrap;
}
@media (max-width: 560px) {
  .failed-upload-row { flex-wrap: wrap; }
  .failed-upload-thumb { width: 80px; }
  .failed-upload-actions { flex-direction: row; width: 100%; }
  .failed-upload-actions button { flex: 1; }
}

/* =====================================================
   PHASE K.F.5.B — PER-INTEREST SHARE ACCESS
   ===================================================== */

/* Property details card header gets two right-side slots: the share-
   access button (admin opt-in) and the auto-save status flash. */
.property-details-header-right {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
}

.property-share-access-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius-md);
  background: var(--bg-3);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.property-share-access-btn:hover:not(:disabled) {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.property-share-access-btn.is-sharing {
  background: rgba(16, 185, 129, 0.18);
  border-color: rgba(16, 185, 129, 0.55);
  color: rgb(16, 185, 129);
}
.property-share-access-btn.is-sharing:hover:not(:disabled) {
  background: rgba(16, 185, 129, 0.28);
  border-color: rgba(16, 185, 129, 0.75);
  color: rgb(16, 185, 129);
}
.property-share-access-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* =====================================================
   K.G.B — Lead detail Contacts section
   (K.O Phase D: embedded inside the Household card, which owns the
   outer margin — the embedded div keeps only the list rhythm.)
   ===================================================== */
section#lead-contacts-section {
  margin-bottom: 1rem;
}
#lead-contacts-section .contacts-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* K.O Phase D — Household section: one card for contacts + linked
   leads, with the "+ Add person" chooser menu. */
#lead-household-section {
  margin-bottom: 1rem;
}
#lead-household-section .relationships-list {
  margin-top: 0.625rem;
}
.household-add-wrap {
  position: relative;
}
.household-add-menu {
  /* position: fixed for the same overflow-clipping reason as
     .status-filter-menu — the Household .card has overflow:hidden. */
  position: fixed;
  z-index: 60;
  min-width: 17rem;
  max-width: min(22rem, calc(100vw - 1rem));
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 0.375rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.household-add-menu[hidden] { display: none; }
.household-add-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
  text-align: left;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.625rem;
  color: var(--text-primary);
  cursor: pointer;
  font: inherit;
}
.household-add-option:hover { background: var(--bg-3); }
.household-add-option .muted { white-space: normal; }
.chip-link {
  cursor: pointer;
  border: 1px solid var(--border);
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.6875rem;
}
.chip-link:hover { border-color: var(--accent); }
.contact-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--bg-2);
  border: 1px solid var(--border);
}
.contact-row-primary {
  border-color: var(--accent, #5a8fff);
  background: rgba(90, 143, 255, 0.06);
}
.contact-row-main {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1;
}
.contact-name {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.chip-primary {
  background: rgba(90, 143, 255, 0.18);
  color: rgb(140, 175, 255);
  border-color: rgba(90, 143, 255, 0.45);
}
.contact-fields {
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
}
.contact-doc-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 0.25rem;
  cursor: pointer;
  user-select: none;
}
.contact-doc-toggle input {
  margin: 0;
  cursor: pointer;
}
/* Phase Employment-Types.2 — per-contact employment type select. Compact
   inline control matching the muted-label aesthetic of .contact-doc-toggle. */
.contact-employment-type {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 0.25rem;
  flex-wrap: wrap;
}
.contact-employment-type select,
.documents-employment-type select {
  appearance: none;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.8rem;
  padding: 0.3rem 1.7rem 0.3rem 0.6rem;
  cursor: pointer;
  max-width: 100%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1L5 5L9 1' stroke='%239aa0ac' stroke-width='1.5' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.contact-employment-type select:hover:not(:focus),
.documents-employment-type select:hover:not(:focus) {
  border-color: var(--border-strong);
}
.contact-employment-type select:focus,
.documents-employment-type select:focus {
  outline: none;
  border-color: var(--accent);
  background-color: var(--bg-3);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Phase Employment-Types.2.1 — employment-type control relocated into each
   contact's Documents card, above the upload-link toolbar. Aligns to the
   card's horizontal padding; reuses the select styling above. */
.documents-employment-type {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 0.5rem 1.25rem 0;
  flex-wrap: wrap;
}
.contact-row-actions {
  display: flex;
  gap: 0.15rem;
  flex-shrink: 0;
}
.contact-form .form-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}
@media (max-width: 640px) {
  .contact-form .form-grid {
    grid-template-columns: 1fr;
  }
  .contact-row {
    flex-direction: column;
    align-items: flex-start;
  }
  .contact-row-actions {
    align-self: flex-end;
  }
}

/* ── Phase K.G.4 — Notifications banner ───────────────────────────── */

#notifications-banner-root {
  position: sticky;
  top: 0;
  z-index: 1000;
}

.notif-banner {
  background: #d97706;
  color: #fff;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  font-size: 0.92rem;
  line-height: 1.3;
}

[data-theme="light"] .notif-banner {
  background: #f59e0b;
  color: #1f2937;
}

.notif-banner-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0.55rem 1rem;
  width: 100%;
}

.notif-banner-collapsed .notif-banner-inner {
  background: transparent;
  border: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
  width: 100%;
  text-align: left;
}

.notif-icon {
  font-size: 1.05rem;
  flex-shrink: 0;
}

.notif-message {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.notif-actions {
  display: flex;
  gap: 0.35rem;
  flex-shrink: 0;
}

.notif-view,
.notif-dismiss,
.notif-dismiss-all,
.notif-expand,
.notif-collapse {
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: inherit;
  padding: 0.2rem 0.55rem;
  border-radius: 4px;
  font-size: 0.85rem;
  cursor: pointer;
  font-weight: 500;
}

[data-theme="light"] .notif-view,
[data-theme="light"] .notif-dismiss,
[data-theme="light"] .notif-dismiss-all {
  background: rgba(0, 0, 0, 0.08);
  border-color: rgba(0, 0, 0, 0.15);
}

.notif-view:hover,
.notif-dismiss:hover,
.notif-dismiss-all:hover {
  background: rgba(255, 255, 255, 0.32);
}

.notif-dismiss {
  padding: 0.2rem 0.45rem;
  font-size: 0.95rem;
  line-height: 1;
}

.notif-banner-collapsed {
  display: flex;
  align-items: center;
}

.notif-banner-collapsed .notif-dismiss-all {
  margin-right: 1rem;
  flex-shrink: 0;
}

.notif-chevron {
  margin-left: auto;
  font-size: 0.8rem;
}

.notif-banner-expanded .notif-banner-inner {
  align-items: center;
}

/* 2026-07-04 — the title strip is no longer the collapse control (its
   only visible cue was a tiny ▴ flush against Clear all → accidental
   Clear all on mobile). Collapse is an explicit labeled button with a
   44px tap target, pushed right but separated from Clear all by a
   deliberate gap; Clear all gets an armed confirm state. */
.notif-expanded-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}
.notif-banner-expanded .notif-banner-inner { flex-wrap: wrap; }
.notif-banner-expanded .notif-collapse {
  min-height: 44px;
  padding: 0.45rem 0.9rem;
  margin-right: 1.25rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
}
.notif-banner-expanded .notif-collapse .notif-chevron {
  margin-left: 0;
  font-size: 0.7rem;
}
.notif-banner-expanded .notif-dismiss-all {
  min-height: 44px;
  padding: 0.45rem 0.9rem;
}
.notif-dismiss-all.is-armed {
  background: #b91c1c;
  border-color: #7f1d1d;
  color: #fff;
  font-weight: 700;
}
.notif-dismiss-all.is-armed:hover { background: #991b1b; }

.notif-list {
  list-style: none;
  margin: 0;
  padding: 0 1rem 0.4rem;
  max-width: 1280px;
  margin: 0 auto;
}

.notif-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

[data-theme="light"] .notif-item {
  border-top-color: rgba(0, 0, 0, 0.1);
}

@media (max-width: 640px) {
  .notif-banner-inner {
    padding: 0.45rem 0.65rem;
    gap: 0.45rem;
    font-size: 0.85rem;
  }
  .notif-list {
    padding: 0 0.65rem 0.35rem;
  }
  .notif-item .notif-message {
    font-size: 0.85rem;
  }
}

/* ── Phase K.G.5 — Tasks view + filters ───────────────────────────── */

.tasks-section .card-header {
  margin-bottom: 0.5rem;
}

.tasks-filters {
  display: flex;
  gap: 0.35rem;
  margin: 0.25rem 0 1rem;
  flex-wrap: wrap;
}

.tasks-filters-inline {
  margin: 0 0 0.75rem;
}

.tasks-filter {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-size: 0.85rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.tasks-filter:hover {
  background: var(--bg-2);
  color: var(--text-primary);
}

.tasks-filter.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--text-primary);
}

.tasks-filter-count {
  background: var(--bg-3);
  color: var(--text-secondary);
  border-radius: 999px;
  padding: 0.05rem 0.4rem;
  font-size: 0.75rem;
  min-width: 1.2rem;
  text-align: center;
}

.tasks-filter-count.is-overdue {
  background: var(--danger-soft);
  color: #fff;
}

.task-person {
  margin-top: 0.15rem;
}

.task-toggle.is-readonly {
  cursor: default;
  opacity: 0.7;
}

/* ──────────────────────────────────────────────────────────────
 * Phase K.I.C/D — Activity feed (global view + per-lead tab).
 * ────────────────────────────────────────────────────────────── */
.activity-filters .card-body { padding: 1rem; }
.activity-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: end;
}
.activity-filter-row label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.activity-filter-row label.checkbox-inline {
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  padding-bottom: 0.5rem;
}
.activity-filter-row input[type="date"],
.activity-filter-row select {
  background: var(--bg-2);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.4rem 0.6rem;
  min-width: 12ch;
}
.activity-attention { border-left: 3px solid #d99a2b; }
.activity-feed {
  list-style: none;
  margin: 0;
  padding: 0;
}
.activity-feed-attention { border-left: none; }
.activity-row {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 0.75rem;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--border-subtle, var(--border));
  line-height: 1.4;
  font-size: 0.95rem;
}
.activity-row:last-child { border-bottom: none; }
.activity-row-attention {
  background: rgba(217, 154, 43, 0.07);
}
.activity-row-time { white-space: nowrap; }
.activity-row-desc code {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 0.85em;
  padding: 0.05rem 0.3rem;
  background: var(--bg-3);
  border-radius: 3px;
}
.activity-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--border-subtle, var(--border));
}
@media (max-width: 720px) {
  .activity-row { grid-template-columns: 1fr; }
  .activity-row-time { order: 2; }
}

/* ──────────────────────────────────────────────────────────────
 * Phase K.I.E.3 — MTD widget (dashboard).
 * ────────────────────────────────────────────────────────────── */
.mtd-card { margin-top: 1rem; }
.mtd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.mtd-table th, .mtd-table td {
  padding: 0.55rem 1rem;
  text-align: left;
  border-bottom: 1px solid var(--border-subtle, var(--border));
}
.mtd-table th {
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 0.85rem;
}
.mtd-table th.num, .mtd-table td.num { text-align: right; }
.mtd-table tbody tr:last-child td { border-bottom: none; }

/* Clickable count cells — Dashboard MTD drill-through. The number sits
 * inside an inline anchor so the underlying SPA router intercepts it.
 * Underline + accent on hover signals "this is interactive" without
 * adding a heavy button chrome that would jar against the table density. */
.mtd-table .mtd-drill {
  color: var(--text-primary);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  transition: background 0.12s ease, color 0.12s ease;
}
.mtd-table .mtd-drill:hover {
  color: var(--accent);
  background: var(--accent-soft);
  text-decoration: none;
}
.mtd-table .mtd-drill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Drill-through banner on /leads. Rendered above the filter bar when
 * created_in or closed_in is in the URL — distinct from the in-page
 * filter dropdowns to communicate "you arrived here via a link". */
.drill-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  margin-top: 1rem;
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
}
.drill-banner-body {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.drill-banner-icon {
  color: var(--accent);
  font-size: 1.05rem;
  line-height: 1;
}
.drill-banner-text {
  color: var(--text-primary);
  font-size: 0.95rem;
  line-height: 1.35;
}
.drill-banner-text strong { font-weight: 600; }
.drill-banner-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.drill-banner-back,
.drill-banner-clear {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  line-height: 1.2;
  transition: background 0.12s ease, color 0.12s ease;
}
.drill-banner-back:hover,
.drill-banner-clear:hover {
  background: var(--accent);
  color: #fff;
  text-decoration: none;
}
@media (max-width: 600px) {
  .drill-banner {
    flex-direction: column;
    align-items: flex-start;
  }
  .drill-banner-actions { align-self: flex-end; }
}

/* ──────────────────────────────────────────────────────────────
 * Phase K.I.F.2 — Settings → Users login summary emphasis.
 * Amber for > 3 failed attempts in 30d; red for > 10.
 * ────────────────────────────────────────────────────────────── */
.failed-logins-amber {
  color: #d99a2b;
  font-weight: 600;
}
.failed-logins-red {
  color: #d94d4d;
  font-weight: 700;
  background: rgba(217, 77, 77, 0.12);
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
}

/* ──────────────────────────────────────────────────────────────
 * Phase K.J.C — /onehome Pending Outreach queue.
 * Card-per-row layout, action footer on the right, optimistic
 * fade on mark-sent. The toast pins to the bottom-right and
 * coexists with the global notifications banner.
 * ────────────────────────────────────────────────────────────── */
.onehome-page { max-width: 920px; }

.onehome-list {
  display: flex; flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.onehome-row {
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  transition: opacity .2s ease, transform .2s ease;
}
.onehome-row-fading {
  opacity: 0;
  transform: translateY(-2px);
  pointer-events: none;
}

.onehome-row-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; margin-bottom: 0.5rem;
}
.onehome-row-title {
  font-weight: 600; font-size: 0.95rem;
  display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: baseline;
}
.onehome-lead-link {
  color: var(--text-primary);
  text-decoration: none;
}
.onehome-lead-link:hover { text-decoration: underline; }
.onehome-row-time { font-size: 0.8rem; white-space: nowrap; }

.onehome-row-body {
  display: flex; flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-top: 1px dashed var(--border);
}

.onehome-property-address { font-weight: 500; }
.onehome-property-mls { font-size: 0.8rem; }

.onehome-agent { font-size: 0.9rem; }
.onehome-agent-contact {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  margin-top: 0.25rem;
}
.onehome-agent-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  font-size: 0.8rem;
  color: var(--text-secondary);
  background: var(--bg-2);
  border-radius: 999px;
}
.onehome-agent-pending {
  font-size: 0.85rem;
  font-style: italic;
}

.onehome-row-actions {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 0.5rem;
  justify-content: flex-end;
}

.onehome-load-more { display: flex; justify-content: center; margin: 1rem 0 2rem; }

.onehome-empty {
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 2.5rem 1rem;
  text-align: center;
  margin-top: 1rem;
}
.onehome-empty-icon { font-size: 2rem; margin-bottom: 0.5rem; }
.onehome-empty-text { font-weight: 600; }
.onehome-empty-sub { font-size: 0.875rem; margin-top: 0.25rem; }

.onehome-toast {
  position: fixed;
  right: 1rem; bottom: 1rem;
  z-index: 50;
  display: inline-flex; align-items: center; gap: 0.75rem;
  padding: 0.6rem 0.9rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  font-size: 0.875rem;
}
.onehome-toast[hidden] { display: none; }
.onehome-toast .error { color: #d94d4d; }

/* K.J.C — nav overflow polish. With 8+ items the bar can get crowded
   on tablet/mobile. Allow horizontal scroll without wrapping; the
   brand + user controls stay fixed at the edges. */
@media (max-width: 820px) {
  .nav-links {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-link { flex-shrink: 0; }
}


/* =====================================================
   K.M A.1 — MOBILE NAV DRAWER (<=820px; desktop unchanged)
   ===================================================== */

.nav-hamburger {
  display: none;
  position: relative;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 1.05rem;
  line-height: 1;
  padding: 0.45rem 0.6rem;
  cursor: pointer;
}
.nav-hamburger-badge {
  position: absolute;
  top: -6px;
  right: -6px;
}

.nav-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 55;
}
.nav-drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(78vw, 300px);
  background: var(--bg-1);
  border-right: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  z-index: 60;
  display: flex;
  flex-direction: column;
  padding: 1rem 0.75rem;
  transform: translateX(-105%);
  transition: transform 0.18s ease;
  overflow-y: auto;
}
.nav-drawer.is-open { transform: translateX(0); }
.nav-drawer-links {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
.nav-drawer-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.875rem;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.nav-drawer-link:hover { color: var(--text-primary); background: var(--bg-2); }
.nav-drawer-link.is-active {
  color: var(--text-primary);
  background: var(--bg-2);
}
.nav-drawer-footer {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  /* K.N A — Sign out left, avatar + account name right. */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.nav-drawer-signout { text-align: left; padding: 0.7rem 0.875rem; flex: 0 0 auto; }
.nav-drawer-account {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 0.85rem;
}
.nav-drawer-account:hover { background: var(--bg-2); color: var(--text-primary); }
.nav-drawer-avatar { width: 28px; height: 28px; font-size: 0.75rem; flex: 0 0 auto; }
.nav-drawer-account-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 820px) {
  .nav-hamburger { display: inline-flex; align-items: center; }
  .nav .nav-links { display: none; }
  .nav .nav-signout { display: none; }
  .nav-inner { gap: 0.75rem; padding: 0.5rem 0.875rem; }
}
@media (min-width: 821px) {
  .nav-drawer, .nav-drawer-backdrop { display: none !important; }
}

/* =====================================================
   K.M A.2 — LEADS CALENDAR FITS PHONE WIDTH
   (aspect-ratio + min-height forced ~80px/cell = 584px min row;
    at small widths relax both so 7 columns fit in 390px)
   ===================================================== */

.cal-weekday-short { display: none; }

@media (max-width: 560px) {
  .cal-weekday-full { display: none; }
  .cal-weekday-short { display: inline; }
  .cal-weekdays, .cal-days { gap: 2px; }
  .calendar-grid { padding: 0.5rem 0.375rem 0.75rem; }
  .cal-day {
    aspect-ratio: auto;
    min-height: 46px;
    min-width: 0;
    padding: 0.2rem 0.25rem 0.2rem;
    border-radius: 4px;
  }
  .cal-date { font-size: 0.7rem; }
}

/* K.M C.8 — permission descriptions in the team drawer */
.drawer-perm-desc { display: block; font-weight: 400; margin-top: 2px; max-width: 260px; }

/* K.M C.1 — leads-calendar status legend + larger dots */
.cal-status-legend {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem;
  padding: 0.6rem 0.75rem 0.9rem;
  border-top: 1px solid var(--border);
  margin-top: 0.5rem;
}
.cal-status-legend .legend-item {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.75rem; color: var(--text-secondary);
}
.cal-dots .status-dot { width: 11px; height: 11px; }
@media (max-width: 560px) {
  .cal-dots .status-dot { width: 8px; height: 8px; }
}

/* K.M C.6 — agent page property list */
.agent-property-list { list-style: none; margin: 0; padding: 0 0 0.25rem; display: flex; flex-direction: column; gap: 0.45rem; }
.agent-property-list li { display: flex; align-items: baseline; gap: 0.6rem; }

/* K.M C.7 — unknown-texter capture actions + lead picker */
.messages-thread-link-actions { display: flex; gap: 0.4rem; margin-top: 0.35rem; position: relative; flex-wrap: wrap; }
.thread-link-picker {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  width: min(320px, 90vw);
  background: var(--bg-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  padding: 0.6rem;
}
.thread-link-picker-input { width: 100%; margin-bottom: 0.5rem; }
.thread-link-picker-results { display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow-y: auto; }
.thread-link-picker-row {
  display: flex; justify-content: space-between; gap: 0.75rem; align-items: baseline;
  background: none; border: none; color: var(--text-primary);
  padding: 0.45rem 0.5rem; border-radius: var(--radius-sm); cursor: pointer; text-align: left;
}
.thread-link-picker-row:hover { background: var(--bg-2); }

/* K.M D.1 — lead header ⋯ More menu */
.lead-more-wrap { position: relative; display: inline-block; }
.lead-more-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 45;
  min-width: 200px;
  background: var(--bg-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  padding: 0.35rem; display: flex; flex-direction: column; gap: 2px;
}
.lead-more-item {
  background: none; border: none; text-align: left; cursor: pointer;
  color: var(--text-primary); padding: 0.55rem 0.7rem; border-radius: var(--radius-sm);
  font-size: 0.875rem;
}
.lead-more-item:hover { background: var(--bg-2); }
.lead-more-item.is-danger { color: var(--danger, #f87171); }

/* K.M D.2 — collapsed notifications: compact pill, not a full-width bar */
.notif-banner-pill {
  width: auto !important;
  display: inline-flex;
  border-radius: 999px;
  margin: 0.35rem 0 0.35rem 0.75rem;
  padding: 0 !important;
}
.notif-banner-pill .notif-banner-inner {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}

/* K.M D.5 — portal "No longer interested" (low-key by design) */
.portal-not-interested { margin: 1.2rem 0 0; text-align: center; }
.portal-not-interested-link {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); text-decoration: underline;
  font-size: 0.85rem; padding: 0.5rem 0.75rem;
}
.portal-not-interested-link:hover { color: var(--text-secondary); }
.portal-not-interested-done { margin: 1.2rem 0 0; text-align: center; }
.lead-more-menu[hidden] { display: none; }

/* K.M fixup — notifications pill inside the open drawer.
   The banner root is sticky z-1000 at page top; while the drawer is
   open it relocates into this header row (nav.js setDrawerOpen) so it
   can't overlap the Dashboard item at any badge width. */
.nav-drawer-header { display: flex; justify-content: flex-end; }
.nav-drawer-header:has(#notifications-banner-root:not(:empty)) {
  padding-bottom: 0.6rem;
  margin-bottom: 0.6rem;
  border-bottom: 1px solid var(--border);
}
.nav-drawer-header #notifications-banner-root {
  position: static;
  z-index: auto;
  width: 100%;
  display: flex;
  justify-content: flex-end;
}
.nav-drawer-header .notif-banner-pill { margin: 0; }

/* =====================================================
   K.N A — MOBILE HEADER CONSOLIDATION (≤820px)
   One header row: ☰ + logo left; notifications pill + theme
   toggle right (toggle at the far end). The pill root's THIRD
   home is #nav-notif-slot (drawer-closed, phone width) — see
   placeNotifRoot() in notificationsBanner.js for the decision.
   Desktop (≥821px) keeps the banner above the nav; the slot is
   display:none so the .nav-user flex gap doesn't shift.
   ===================================================== */

.nav-notif-slot { display: none; }

@media (max-width: 820px) {
  /* .nav-links is display:none here, so its flex:1 no longer pushes
     .nav-user to the right edge — do it explicitly. */
  .nav .nav-user { margin-left: auto; }
  /* Avatar leaves the header at phone width (it had no function);
     it lives in the drawer footer now. Scoped to .nav so the drawer
     footer's avatar (same base class) is untouched. */
  .nav .nav-avatar { display: none; }

  .nav-notif-slot {
    display: flex;
    align-items: center;
    min-width: 0;
  }
  .nav-notif-slot #notifications-banner-root {
    position: static;
    z-index: auto;
  }
  .nav-notif-slot .notif-banner-pill { margin: 0; }
  /* Single-notification banner and the expanded list would explode the
     header row — render them as a full-width sheet anchored under the
     sticky .nav instead (the nav is the containing block). Below the
     drawer/backdrop (z 55/60), above page content. */
  .nav-notif-slot .notif-banner-single,
  .nav-notif-slot .notif-banner-expanded {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    box-shadow: var(--shadow-md);
  }
}

/* =====================================================
   K.N B — SHARED UNDO TOAST (components/toast.js)
   The .toast base (call-recorder.css) is pointer-events:none;
   the component opts back in inline. Undo is a padded,
   thumb-sized target per the K.L lesson — not a text link.
   ===================================================== */

.toast-undo {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  /* K.N visual-pass catch — the .toast base is fixed at left:50%, so
     shrink-to-fit width caps at HALF the viewport (195px at 390px) and
     the message wrapped into a tall ribbon. max-content restores the
     natural one-line width; the cap keeps it inside the phone screen. */
  width: max-content;
  max-width: calc(100vw - 2rem);
}
.toast-undo-btn {
  margin-left: 0.35rem;
  padding: 0.55rem 1.1rem;
  min-height: 40px;
  font-weight: 600;
  flex: 0 0 auto;
}

/* =====================================================
   K.N D — COLLAPSIBLE LEAD FILTERS (≤820px only)
   Search stays visible; the rest of the controls live in
   .filter-collapsible behind the "Filters (N)" button. On
   desktop the wrapper is display:contents — its children
   participate in .filter-bar's flex exactly as before, and
   the toggle button doesn't exist visually.
   ===================================================== */

.filter-toggle { display: none; }
.filter-collapsible { display: contents; }

@media (max-width: 820px) {
  .filter-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.55rem 0.75rem;
  }
  .filter-collapsible { display: none; }
  .filter-bar.filters-open .filter-collapsible {
    display: flex;
    flex-direction: column;
    /* match .filter-bar's own stacked rhythm */
    gap: 0.75rem;
  }
}

/* ── K.P — /sweeps (CRMLS sweep reports) ─────────────────────────── */
.sweeps-list { list-style: none; margin: 0; padding: 0; }
.sweeps-row + .sweeps-row { border-top: 1px solid var(--border, rgba(255,255,255,0.08)); }
.sweeps-row-link {
  display: block; padding: 0.85rem 0.5rem;
  color: inherit; text-decoration: none; border-radius: 8px;
}
.sweeps-row-link:hover { background: rgba(255,255,255,0.04); }
.sweeps-row-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.2rem; }
.sweep-items { list-style: none; margin: 0; padding: 0; }
.sweep-item { padding: 0.7rem 0.35rem; }
.sweep-item + .sweep-item { border-top: 1px solid var(--border, rgba(255,255,255,0.08)); }
.sweep-item-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.sweep-item-error { border-left: 3px solid var(--danger); padding-left: 0.6rem; }
.sweep-item-skipped_abort { opacity: 0.75; }

/* ── RAP-13 — /read-sync (iMessage read-sync health) ─────────────── */
/* Smaller stat-value variant for text values ("3 hours ago"). */
.stat-value-sm { font-size: 1.1rem; line-height: 1.5; }
.property-crmls-freshness { white-space: nowrap; }

/* ── RAP-97 — "Refresh to update" prompt ──────────────────────────── */
/* Shown when the server is running a newer build than this tab. Fixed
   bottom pill so it never reflows the page or covers the composer's
   send button. z-index 880 keeps it BELOW the recording-salvage banner
   (900) — an unsaved recording is always the more urgent message. */
.update-prompt {
  position: fixed;
  right: 1rem;
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  z-index: 880;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: min(28rem, calc(100vw - 2rem));
  padding: 0.6rem 0.75rem;
  border-radius: 10px;
  background: var(--surface-2, #1b1e27);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.14));
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  font-size: 0.9rem;
  color: var(--text, #e8eaf0);
}

[data-theme="light"] .update-prompt {
  background: #fff;
  color: #1f2937;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.update-prompt-icon { flex-shrink: 0; opacity: 0.8; }

.update-prompt-text {
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.update-prompt-refresh {
  flex-shrink: 0;
  padding: 0.35rem 0.7rem;
  border-radius: 7px;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  background: var(--accent, #4f7cff);
  color: #fff;
}

.update-prompt-refresh:hover { filter: brightness(1.08); }

.update-prompt-dismiss {
  flex-shrink: 0;
  padding: 0 0.3rem;
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
}

.update-prompt-dismiss:hover { opacity: 1; }

@media (max-width: 520px) {
  .update-prompt {
    left: 1rem;
    right: 1rem;
    max-width: none;
  }
}
