/* ═══════════════════════════════════════════════════════════════════════
   WGN ERP — app.css  (v3 — unified design system)
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Design Tokens ────────────────────────────────────────────────────── */
:root {
  /* ---- Palette ---- */
  --blue-50:  #eff6ff; --blue-100: #dbeafe; --blue-200: #bfdbfe;
  --blue-500: #3b82f6; --blue-600: #2563eb; --blue-700: #1d4ed8;
  --blue-800: #1e40af; --blue-900: #1e3a8a;

  --slate-50:  #f8fafc; --slate-100: #f1f5f9; --slate-200: #e2e8f0;
  --slate-300: #cbd5e1; --slate-400: #94a3b8; --slate-500: #64748b;
  --slate-600: #475569; --slate-700: #334155; --slate-800: #1e293b;
  --slate-900: #0f172a;

  --red-50:  #fef2f2; --red-100: #fee2e2; --red-200: #fecaca;
  --red-600: #dc2626; --red-700: #b91c1c; --red-800: #991b1b;

  --amber-50: #fffbeb; --amber-100: #fef3c7; --amber-200: #fde68a;
  --amber-600: #d97706; --amber-700: #b45309; --amber-800: #92400e;

  --green-50:  #f0fdf4; --green-100: #dcfce7; --green-200: #bbf7d0;
  --green-600: #16a34a; --green-700: #15803d; --green-800: #166534;

  --purple-50:  #f5f3ff; --purple-100: #ede9fe; --purple-200: #ddd6fe;
  --purple-600: #7c3aed; --purple-700: #6d28d9;

  --teal-50: #f0fdfa; --teal-100: #ccfbf1; --teal-200: #99f6e4;
  --teal-600: #0d9488; --teal-700: #0f766e;

  --sky-100: #e0f2fe; --sky-700: #0369a1;

  /* ---- Semantic ---- */
  --color-bg:              #f2f4f7;
  --color-surface:         #ffffff;
  --color-surface-raised:  #f8fafc;
  --color-border:          #e2e8f0;
  --color-border-light:    #f1f5f9;
  --color-text:            #0f172a;
  --color-text-secondary:  #475569;
  --color-text-muted:      #94a3b8;
  --color-primary:         #1d4ed8;
  --color-primary-hover:   #1e40af;
  --color-primary-active:  #1e3a8a;
  --color-danger:          #dc2626;

  /* ---- Spacing ---- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;
  --sp-4: 16px; --sp-5: 20px; --sp-6: 24px;

  /* ---- Typography ---- */
  --text-2xs: 10px; --text-xs: 11px; --text-sm: 12px;
  --text-base: 13px; --text-md: 14px; --text-lg: 16px;
  --text-xl: 18px; --text-2xl: 20px;

  /* ---- Radius ---- */
  --r-xs: 3px; --r-sm: 4px; --r-md: 6px;
  --r-lg: 8px; --r-xl: 10px; --r-2xl: 12px; --r-full: 9999px;

  /* ---- Shadows ---- */
  --shadow-xs:    0 1px 2px rgba(15,23,42,.05);
  --shadow-sm:    0 1px 4px rgba(15,23,42,.08);
  --shadow-md:    0 2px 8px rgba(15,23,42,.10);
  --shadow-lg:    0 6px 18px rgba(15,23,42,.12);
  --shadow-xl:    0 12px 32px rgba(15,23,42,.15);
  --shadow-panel: -10px 0 40px rgba(15,23,42,.14);

  /* ---- Transitions ---- */
  --t-fast: 80ms ease;
  --t-base: 150ms ease;
  --t-slow: 250ms ease;
  --refresh-fade-start: .92;

  /* ---- Chips ---- */
  --chip-lead-bg: #eef2ff; --chip-lead-border: #c7d2fe; --chip-lead-text: #1d4ed8;
  --chip-owner-bg: #ecfdf5; --chip-owner-border: #a7f3d0; --chip-owner-text: #047857;
  --chip-task-bg: #f5f3ff; --chip-task-border: #ddd6fe; --chip-task-text: #6d28d9;
  --chip-comm-bg: #fff7ed; --chip-comm-border: #fed7aa; --chip-comm-text: #b45309;
  --chip-contact-bg: #f8fafc; --chip-contact-border: #e2e8f0; --chip-contact-text: #475569;
  --chip-homelead-bg: #fdf2f8; --chip-homelead-border: #fbcfe8; --chip-homelead-text: #be185d;
}

/* ── Reset & Base ─────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--color-bg);
  font-size: 18px;
  color: var(--color-text);
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
[x-cloak] { display: none !important; }

/* ── Scrollbar ────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--slate-300); border-radius: var(--r-full); }
::-webkit-scrollbar-thumb:hover { background: var(--slate-400); }

/* ── App Header ───────────────────────────────────────────────────────── */
.app-header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 0 var(--sp-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 50px;
  position: sticky;
  top: 0;
  z-index: 200;
  box-shadow: 0 1px 0 var(--color-border), var(--shadow-xs);
  flex-shrink: 0;
}
.logo { height: 34px; object-fit: contain; cursor: pointer; }
.header-left { display: flex; align-items: center; gap: var(--sp-2); }
.header-right { display: flex; align-items: center; gap: var(--sp-2); }
.user-chip { position: relative; }
.user-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--slate-800);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--r-full);
  padding: 3px 10px 3px 4px;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.user-pill:hover { background: var(--blue-50); border-color: var(--blue-200); }
.user-pill.open {
  background: var(--blue-50);
  border-color: var(--blue-500);
  color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(59,130,246,.15);
}
.user-pill-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--blue-700), var(--blue-500));
  color: #fff;
  font-weight: 700;
  font-size: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.user-pill-caret { font-size: var(--text-2xs); opacity: .55; margin-left: 1px; }
.user-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 14px;
  box-shadow: 0 8px 24px rgba(15,23,42,.13), 0 2px 6px rgba(15,23,42,.07);
  width: 252px;
  overflow: hidden;
  z-index: 250;
  transform-origin: top right;
}
.user-menu-enter { transition: opacity 120ms ease, transform 120ms ease; }
.user-menu-enter-start { opacity: 0; transform: scale(.95) translateY(-4px); }
.user-menu-enter-end   { opacity: 1; transform: scale(1) translateY(0); }
.user-menu-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: linear-gradient(135deg, var(--blue-50) 0%, #eef2ff 100%);
  border-bottom: 1px solid var(--blue-100);
}
.user-monogram {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--blue-700), var(--blue-500));
  color: #fff;
  font-weight: 700;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(29,78,216,.30);
}
.user-menu-info { min-width: 0; }
.user-menu-name  { font-size: var(--text-md); font-weight: 700; color: var(--color-text); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-menu-email { font-size: var(--text-sm); color: var(--slate-500); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-menu-actions { padding: 8px; }
.user-menu-actions-row { display: flex; justify-content: flex-end; gap: 2px; }
.user-menu-actions-row form { margin: 0; }
.user-menu-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-danger);
  text-decoration: none;
  padding: 8px 10px;
  border-radius: var(--r-lg);
  transition: background var(--t-fast), color var(--t-fast);
  background: none;
  border: none;
  cursor: pointer;
  width: 100%;
  white-space: nowrap;
}
.user-menu-item:hover { background: var(--red-50); color: var(--red-700); }
.user-menu-item--admin { color: var(--blue-600); }
.user-menu-item--admin:hover { background: var(--blue-50); color: var(--blue-700); }
/* Subscriptions link in user menu */
.user-menu-item--subs { color: var(--slate-600); }
.user-menu-item--subs:hover { background: var(--slate-50); color: var(--slate-800); }
.user-menu-actions-col { padding: 0 8px; border-bottom: 1px solid var(--color-border); padding-bottom: 4px; margin-bottom: 4px; }

/* Header "Email" button → WGN Mail deep-link chooser (shared _email_compose_menu.html) */
.email-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(15,23,42,.13), 0 2px 6px rgba(15,23,42,.07);
  min-width: 268px;
  max-width: 340px;
  max-height: 60vh;
  overflow-y: auto;
  z-index: 250;
  padding: 6px;
}
.email-menu-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px;
  border-radius: var(--r-lg);
  text-decoration: none;
  color: var(--color-text);
  transition: background var(--t-fast);
}
.email-menu-item:hover { background: var(--blue-50); }
/* "Start a new conversation" is a single line: icon inline with the label
   (the base .email-menu-item is a column so the reply rows can stack a subtitle). */
.email-menu-item--new { flex-direction: row; align-items: center; gap: 6px; font-weight: 700; color: var(--blue-700); }
.email-menu-item-title {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.email-menu-item-sub {
  font-size: 10px; color: var(--slate-400);
  padding-left: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.email-menu-sep { height: 1px; background: var(--color-border); margin: 5px 4px; }
.email-menu-label {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--slate-400); padding: 4px 10px 2px;
}

/* Subscriptions panel */
.subs-section-title {
  font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  margin: 20px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--color-border);
}
.subs-section-title--lead { color: var(--blue-600); }
.subs-section-title--owner { color: var(--emerald-700, #047857); }
.subs-section-title--task { color: var(--amber-700, #b45309); }
.subs-table { width: 100%; border-collapse: collapse; margin-bottom: 8px; }
.subs-table td { padding: 8px 10px; border-bottom: 1px solid var(--slate-100, #f1f5f9); font-size: var(--text-md); }
.subs-row { cursor: pointer; }
.subs-row:hover { background: var(--slate-50); }
.subs-table-title { font-weight: 600; color: var(--color-text); }
.subs-table-status { width: 140px; white-space: nowrap; }
.subs-table-status .status-pill { white-space: nowrap; }
.subs-table-due { width: 100px; color: var(--slate-500); font-size: var(--text-sm); white-space: nowrap; }
.subs-table-action { width: 40px; text-align: center; }
.subs-table-lead { width: 240px; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--slate-500); font-size: var(--text-sm); }
.subs-lead-chip {
  cursor: pointer; color: var(--blue-600); font-weight: 500;
  transition: color var(--t-fast);
}
.subs-lead-chip:hover { color: var(--blue-800); text-decoration: underline; }
.subs-unsub-btn {
  background: none; border: none; cursor: pointer; color: var(--slate-400);
  padding: 4px; border-radius: var(--r-sm); display: inline-flex; align-items: center;
  transition: color var(--t-fast), background var(--t-fast);
}
.subs-unsub-btn:hover { color: var(--red-600); background: var(--red-50); }
.subs-empty { text-align: center; color: var(--slate-400); padding: 40px 16px; font-size: var(--text-md); }
.btn-settings {
  font-size: var(--text-base);
  background: var(--blue-50);
  color: var(--blue-700);
  border: 1px solid var(--blue-200);
  padding: 4px 10px;
  border-radius: var(--r-md);
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  transition: background var(--t-fast);
}
.btn-settings:hover { background: var(--blue-100); }

/* ── Header Quick-Add Buttons ──────────────────────────────────────────── */
.header-quick-add {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex-shrink: 0;
  margin: 0 var(--sp-2);
}
.btn-quick-add {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--r-full);
  border: 1px solid;
  cursor: pointer;
  font-family: inherit;
  letter-spacing: .01em;
  transition: filter var(--t-fast), transform var(--t-fast);
  white-space: nowrap;
}
.btn-quick-add:hover  { filter: brightness(0.93); }
.btn-quick-add:active { filter: brightness(0.86); transform: scale(0.96); }
.btn-quick-add-plus   { font-size: 14px; font-weight: 700; line-height: 1; margin-right: 1px; }

.btn-quick-add--lead    { background: var(--chip-lead-bg);    color: var(--chip-lead-text);    border-color: var(--chip-lead-border); }
.btn-quick-add--homelead { background: var(--chip-homelead-bg); color: var(--chip-homelead-text); border-color: var(--chip-homelead-border); }
.btn-quick-add--owner   { background: var(--chip-owner-bg);   color: var(--chip-owner-text);   border-color: var(--chip-owner-border); }
.btn-quick-add--task    { background: var(--chip-task-bg);    color: var(--chip-task-text);    border-color: var(--chip-task-border); }
.btn-quick-add--contact { background: var(--chip-contact-bg); color: var(--chip-contact-text); border-color: var(--chip-contact-border); }

@media (max-width: 768px) {
  .header-quick-add { gap: 2px; }
  .btn-quick-add    { padding: 4px 7px; }
}
@media (max-width: 540px) {
  .header-quick-add { display: none; }
}

/* ── Global Search ────────────────────────────────────────────────────── */
.header-search {
  position: relative;
  flex: 1;
  max-width: 420px;
  margin: 0 var(--sp-4);
}
.header-search-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.header-search-icon {
  position: absolute;
  left: 10px;
  color: var(--slate-400);
  pointer-events: none;
  flex-shrink: 0;
}
.header-search-input {
  width: 100%;
  height: 34px;
  padding: 0 32px 0 32px;
  border: 1px solid var(--color-border);
  border-radius: var(--r-full);
  background: var(--color-surface-raised);
  font-size: var(--text-sm);
  font-family: inherit;
  color: var(--color-text);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
  outline: none;
}
.header-search-input::placeholder { color: var(--slate-400); }
.header-search-input:focus {
  border-color: var(--blue-400);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(59,130,246,.15);
}
/* Remove native clear button */
.header-search-input::-webkit-search-cancel-button { display: none; }
.header-search-clear {
  position: absolute;
  right: 8px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--slate-400);
  font-size: 12px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: var(--r-full);
  transition: color var(--t-fast), background var(--t-fast);
}
.header-search-clear:hover { color: var(--slate-600); background: var(--slate-100); }
.global-search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-xl);
  box-shadow: 0 8px 24px rgba(15,23,42,.12), 0 2px 6px rgba(15,23,42,.06);
  overflow: hidden;
  z-index: 300;
  max-height: 420px;
  overflow-y: auto;
}
.search-group { padding: 6px 0; }
.search-group + .search-group { border-top: 1px solid var(--color-border); }
.search-group-label {
  padding: 6px 14px 4px;
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--slate-400);
}
.search-result-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 7px 14px;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-sm);
  color: var(--color-text);
  transition: background var(--t-fast);
}
.search-result-item:hover { background: var(--blue-50); }
.search-result-item:focus { background: var(--blue-50); outline: none; box-shadow: inset 0 0 0 2px var(--blue-300); }
.search-result-id {
  font-size: var(--text-xs);
  color: var(--slate-400);
  font-weight: 500;
  min-width: max-content;
}
.search-result-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.search-result-badges {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
/* "↳ <parent title>" after a sub-task's name in global search — several
   sub-tasks share generic names ("Power", "Survey"), so the parent is what
   tells them apart. */
.search-result-sub {
  font-size: var(--text-2xs);
  font-weight: 500;
  color: var(--slate-400);
  white-space: nowrap;
}

.search-result-lead-pill {
  font-size: var(--text-2xs);
  font-weight: 500;
  padding: 2px 7px;
  border-radius: var(--r-full);
  background: var(--slate-100);
  color: var(--slate-600);
  border: 1px solid var(--slate-200);
  white-space: nowrap;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.search-result-meta {
  font-size: var(--text-xs);
  color: var(--slate-500);
  white-space: nowrap;
  flex-shrink: 0;
}
.search-result-status {
  font-size: var(--text-2xs);
  font-weight: 600;
  padding: 2px 7px;
  border-radius: var(--r-full);
  white-space: nowrap;
  flex-shrink: 0;
}
.search-empty {
  padding: 20px 14px;
  text-align: center;
  color: var(--slate-400);
  font-size: var(--text-sm);
}

/* ── Tab Nav ──────────────────────────────────────────────────────────── */
.main-tabs {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 0 var(--sp-4);
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  flex-shrink: 0;
  gap: 2px;
}
.main-tabs::-webkit-scrollbar { display: none; }
.tab {
  padding: 10px 14px;
  font-size: var(--text-sm);
  cursor: pointer;
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  color: var(--slate-500);
  font-weight: 500;
  white-space: nowrap;
  font-family: inherit;
  transition: color var(--t-base), border-color var(--t-base);
  margin-bottom: -1px;
  letter-spacing: .01em;
}
.tab:hover { color: var(--color-text); }
.tab-active { color: var(--blue-700) !important; border-bottom-color: var(--blue-700) !important; font-weight: 700; }
.tab-red.tab-active { color: var(--red-600) !important; border-bottom-color: var(--red-600) !important; }

/* ── Swipe Navigation ────────────────────────────────────────────────── */
.main-content.swiping { overflow-y: hidden; }
.main-content.swiping > [data-tab] { will-change: transform; }
.main-content.swipe-animating > [data-tab] { will-change: transform; }

/* ── Pull-to-Refresh ─────────────────────────────────────────────────── */
.ptr-indicator {
  position: fixed;
  top: 0; left: 0; right: 0;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  height: 0;
  z-index: 999;
  pointer-events: none;
  opacity: 0;
  transition: opacity .2s ease;
}
.ptr-indicator.ptr-visible,
.ptr-indicator.ptr-refreshing { opacity: 1; }
.ptr-spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--slate-200, #e2e8f0);
  border-top-color: var(--blue-700, #1d4ed8);
  border-radius: 50%;
  margin-bottom: 8px;
}
.ptr-refreshing .ptr-spinner {
  animation: ptr-spin .6s linear infinite;
}
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* ── "Update available" chip ──────────────────────────────────────────────
   Bottom-left, clear of the compose drawers' minimized pill (bottom-right)
   and above the mobile tab bar's safe area. Quiet on purpose: a newer
   release is worth knowing about, not worth interrupting a message for. */
.update-chip {
  position: fixed;
  left: 14px;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  z-index: 99998;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--slate-800, #1e293b); color: #fff;
  border-radius: 20px; padding: 8px 10px 8px 14px;
  font-size: 12px; font-weight: 600; cursor: pointer;
  box-shadow: 0 6px 20px rgba(15, 23, 42, .35);
}
.update-chip:hover { background: var(--slate-900, #0f172a); }
.update-chip-x {
  background: rgba(255, 255, 255, .18); border: none; color: inherit;
  border-radius: 50%; cursor: pointer;
  width: 20px; height: 20px; line-height: 1; font-size: 14px;
  display: inline-flex; align-items: center; justify-content: center;
}
.update-chip-x:hover { background: rgba(255, 255, 255, .32); }
/* The mobile tab bar owns the bottom edge, so sit above it. */
@media (max-width: 768px) {
  .update-chip { bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}

/* ── Main Content ─────────────────────────────────────────────────────── */
.main-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sp-3) var(--sp-4);
  min-height: 0;
  overscroll-behavior-y: contain;
}
.tab-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-wrap: wrap; gap: 7px; }
.toolbar-left { display: flex; gap: 7px; align-items: center; }

/* ── Badges & Chips ───────────────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 1px 7px;
  border-radius: var(--r-full);
  font-size: var(--text-xs);
  font-weight: 700;
  margin-left: 4px;
  border: 1px solid transparent;
  background: var(--color-surface-raised);
  color: var(--slate-700);
  line-height: 1.4;
}
.badge-xs { font-size: var(--text-2xs); padding: 0 5px; }
.count-square { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 4px; border-radius: var(--r-md); font-size: var(--text-xs); font-weight: 700; border: 1px solid transparent; }
.badge-red    { background: var(--red-50);    color: var(--red-600);    border-color: var(--red-200); }
.badge-amber  { background: var(--amber-50);  color: var(--amber-700);  border-color: var(--amber-200); }
.badge-slate  { background: var(--slate-50);  color: var(--slate-600);  border-color: var(--slate-200); }
.badge-success { background: var(--green-50); color: var(--green-700);  border-color: var(--green-200); }

/* Call outcome pill — shown next to the Call channel label in the comms feed
   and the comm panel. Colour-coded so no-answer/busy/failed read at a glance. */
.call-outcome-pill { display:inline-flex; align-items:center; margin-left:6px; padding:0 6px;
  border-radius:9px; font-size:10px; font-weight:700; border:1px solid transparent; white-space:nowrap; }
.call-outcome--answered  { background: var(--green-50); color: var(--green-700);  border-color: var(--green-200); }
.call-outcome--voicemail { background: var(--amber-50); color: var(--amber-700);  border-color: var(--amber-200); }
.call-outcome--no_answer { background: var(--slate-50); color: var(--slate-600);  border-color: var(--slate-200); }
.call-outcome--busy      { background: var(--amber-50); color: var(--amber-700);  border-color: var(--amber-200); }
.call-outcome--failed    { background: var(--red-50);   color: var(--red-600);    border-color: var(--red-200); }
.call-outcome--inbound   { background: var(--blue-50);  color: var(--blue-700);   border-color: var(--blue-200); }
/* wrong_number + the legacy values consolidated into it */
.call-outcome--wrong_number, .call-outcome--not_in_service, .call-outcome--disconnected
                         { background: var(--red-50);   color: var(--red-600);    border-color: var(--red-200); }

/* Channel icon box — fixed width + centered so ☎/✉/💬 (whose glyph widths
   differ wildly, and differ again per platform emoji font) all occupy the
   same slot: the icons line up in a column and the text after them starts
   at the same x in every card/row. */
.comm-ico { display: inline-flex; align-items: center; justify-content: center;
  width: 1.4em; vertical-align: -0.15em; }

/* Comm direction mark — tiny in/out arrow badged onto the channel glyph
   (comms table + every panel's comm cards). Sized in em so it scales with
   whatever font-size the host span sets (13px rows, 20px cards). */
.comm-dir { position: relative; }
.comm-dir .comm-dir-mark {
  position: absolute; right: -0.45em; bottom: -0.15em;
  font-size: 0.62em; font-weight: 800; line-height: 1;
  padding: 0.04em 0.1em; border-radius: 50%;
  background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.08);
}
.comm-dir--out .comm-dir-mark { color: var(--blue-600); }
.comm-dir--in  .comm-dir-mark { color: var(--green-600); }

.chip-lead    { background: var(--chip-lead-bg);    border-color: var(--chip-lead-border);    color: var(--chip-lead-text); }
.chip-owner   { background: var(--chip-owner-bg);   border-color: var(--chip-owner-border);   color: var(--chip-owner-text); }
.chip-task    { background: var(--chip-task-bg);    border-color: var(--chip-task-border);    color: var(--chip-task-text); }
.chip-comm    { background: var(--chip-comm-bg);    border-color: var(--chip-comm-border);    color: var(--chip-comm-text); }
.chip-homelead { background: var(--chip-homelead-bg); border-color: var(--chip-homelead-border); color: var(--chip-homelead-text); }
.chip-contact { background: var(--chip-contact-bg); border-color: var(--chip-contact-border); color: var(--chip-contact-text); }

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn-primary {
  background: var(--color-primary);
  color: #fff;
  border: none;
  padding: 6px 13px;
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  letter-spacing: .01em;
}
.btn-primary:hover { background: var(--color-primary-hover); }

.btn-secondary {
  background: var(--color-surface);
  color: var(--slate-600);
  border: 1px solid var(--color-border);
  padding: 5px 11px;
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
}
.btn-secondary:hover { background: var(--color-surface-raised); color: var(--color-text); }

.btn-danger {
  background: var(--red-50);
  color: var(--red-600);
  border: 1px solid var(--red-200);
  padding: 4px 9px;
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}
.btn-open {
  background: var(--blue-50);
  color: var(--blue-700);
  border: none;
  padding: 4px 10px;
  border-radius: var(--r-md);
  font-size: var(--text-base);
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.btn-open .btn-open-text { display: inline; }
.btn-open .btn-open-arrow { display: none; }

/* ── User avatar circle ────────────────────────────────────────────── */
.user-avatar {
  display: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--blue-100);
  color: var(--blue-700);
  font-size: 12px;
  font-weight: 700;
  line-height: 26px;
  text-align: center;
  flex-shrink: 0;
}

/* ── Mobile sub-row (second line of info) ──────────────────────────── */
.mobile-sub { display: none; }
.msub-pills-row { display: none; }
.comms-table td { border-bottom-color: var(--color-border); }

/* Cap the comms subject at 2 visual lines on tablet/desktop so a long
   subject (or one with the "unlinked" amber badge tagging on after the
   text) can't stretch its row 3-5× taller than its neighbors — the
   runaway-tall row in the middle of an otherwise uniform scroll reads
   as a broken layout. Hover the cell for the full text via the title
   attribute. Mobile has its own single-line nowrap+ellipsis rule below
   so this clamp is intentionally scoped out of that breakpoint. */
@media (min-width: 769px) {
  .comms-table .comms-subject-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}
.mobile-sub .mobile-field-row { display: none; }
/* !important so this wins against later sibling rules that pin
   ``display`` on a base class (e.g. ``.th-search { display: block }``)
   when an element carries BOTH classes. The mobile media query
   below uses ``!important`` for the same reason — they stay in
   lockstep so the cascade flips correctly at the breakpoint. */
.mobile-only { display: none !important; }
/* Keep the cell in layout but with zero width — `display: none` here
   would leave a phantom column that table-layout: fixed still allots
   space to (Chrome behavior), pulling the header short of the right edge. */
.mobile-only-th, .mobile-only-td {
  width: 0 !important; min-width: 0 !important; max-width: 0 !important;
  padding: 0 !important; border: 0 !important; overflow: hidden !important;
}
.mobile-only-th > *, .mobile-only-td > * { display: none !important; }
/* Row "open panel" button — Tasks + Contacts rows inline-edit their
   title/name, so the first cell is wall-to-wall input with no blank spot
   left to click; this pins an explicit open affordance to the cell's
   right edge (the cell reserves right padding for it). */
.row-open-btn {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-sm); color: var(--slate-500); cursor: pointer;
}
.row-open-btn:hover { color: var(--color-primary); border-color: var(--color-primary); background: var(--blue-50); }
.tasks-table td:first-child,
.contacts-table td:first-child { position: relative; padding-right: 34px; }

.btn-icon {
  background: var(--slate-100);
  color: var(--slate-600);
  border: 1px solid var(--color-border);
  padding: 4px var(--sp-2);
  border-radius: var(--r-sm);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.btn-icon-danger {
  background: transparent;
  color: #9ca3af;
  border: none;
  cursor: pointer;
  font-family: inherit;
  border-radius: var(--r-sm);
  transition: color var(--t-fast), background var(--t-fast);
}
.btn-icon-danger:hover { color: #ef4444; background: #fef2f2; }

/* Thud click effect on all buttons */
.btn-primary, .btn-secondary, .btn-danger,
button.btn-primary, button.btn-secondary, button.btn-danger {
  transition: transform 60ms cubic-bezier(.3,0,.5,1), background var(--t-fast);
}
.btn-primary:active, button.btn-primary:active {
  transform: scale(0.94); background: var(--color-primary-active) !important;
}
.btn-secondary:active, button.btn-secondary:active {
  transform: scale(0.94); background: var(--slate-200) !important;
}
.btn-danger:active, button.btn-danger:active {
  transform: scale(0.94); background: var(--red-100) !important;
}

/* ── Tables ───────────────────────────────────────────────────────────── */
/* scrollbar-gutter reserves the vertical scrollbar's lane up front. Without
   it, Windows Firefox sizes the width:100% table BEFORE adding the (classic,
   ~17px) scrollbar and never re-shrinks it — leaving the table one
   scrollbar-width too wide and showing a spurious horizontal scrollbar. */
.tbl-wrap { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--r-lg); overflow: auto; scrollbar-gutter: stable; max-height: calc(100vh - 155px); box-shadow: var(--shadow-xs); }
table { width: 100%; border-collapse: collapse; min-width: 600px; }
thead tr { background: var(--color-surface-raised); }
th {
  padding: 8px 10px;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--slate-500);
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
  position: sticky; top: 0; z-index: 5; background: var(--color-surface-raised);
}
th:hover { background: var(--slate-100); }
/* Sort button inside th */
.sort-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .6px; color: var(--slate-500);
  display: flex; align-items: center; gap: 3px; white-space: nowrap;
}
.sort-btn:hover { color: var(--slate-700); }
.sort-icon { font-size: 9px; opacity: .55; }
td {
  padding: 8px 10px;
  font-size: var(--text-md);
  border-bottom: 1px solid var(--color-border-light);
  vertical-align: middle;
  overflow: visible;
}
tr { overflow: visible; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--slate-50); }
tr.overdue td { background: var(--red-50); }
tr.overdue:hover td { background: var(--red-100); }
tr.row-clickable { cursor: pointer; }
tr.overdue .field-select { background: #fff !important; }
table td select { height: 28px !important; overflow: hidden !important; }
.th-search {
  font-size: var(--text-sm);
  padding: 3px 6px;
  border: 1px solid var(--slate-300);
  border-radius: var(--r-sm);
  outline: none;
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-surface);
  width: 100%;
  min-width: 120px;
  margin-top: 4px;
  display: block;
  box-sizing: border-box;
  height: 26px;
  transition: border-color var(--t-base);
}
.th-search:focus { border-color: var(--color-primary); }
.th-search::placeholder { color: var(--slate-400); }
select.th-search {
  padding-right: 28px;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--slate-500) 50%),
    linear-gradient(135deg, var(--slate-500) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 8px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

table.data-table { table-layout: fixed; }
table.data-table th, table.data-table td { min-width: 120px; }
table.data-table th { cursor: default; }
table.data-table td { word-break: break-word; }

/* Manual drag-to-reorder ("Manual" sort mode). The grip lives on the left edge
   of the Title cell (no extra column, so nth-child column rules are unaffected
   and out-of-band single-row swaps stay aligned). The cell gets left padding in
   manual mode to make room; the grip is absolutely positioned in that gutter. */
table.data-table.manual-order th:first-child,
table.data-table.manual-order td:first-child { padding-left: 22px; }
table.data-table.manual-order td:first-child { position: relative; }
table.data-table.manual-order .drag-handle {
  position: absolute;
  left: 2px;
  top: 50%;
  transform: translateY(-50%);
  cursor: grab;
  color: #9ca3af;
  font-size: 15px;
  line-height: 1;
  user-select: none;
  padding: 0 2px;
  z-index: 1;
}
table.data-table.manual-order .drag-handle:hover { color: #4b5563; }
table.data-table.manual-order tr.dragging {
  opacity: 0.5;
  background: #eff6ff;
}
table.data-table.manual-order tr.drop-before td { box-shadow: inset 0 2px 0 0 #2563eb; }
table.data-table.manual-order tr.drop-after td { box-shadow: inset 0 -2px 0 0 #2563eb; }
/* Boundary between the pinned tasks and the due-date pile. */
table.data-table.manual-order tr.manual-divider { cursor: default; }
table.data-table.manual-order tr.manual-divider td {
  background: #f1f5f9;
  color: #64748b;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 5px 12px;
  text-align: center;
  border-top: 2px dashed #cbd5e1;
  border-bottom: 1px solid var(--color-border);
}

/* Inline table fields fill their cell, capped at each variant's design
   width. Fixed widths here made every input a hard floor on its column: in
   laptop-width windows the Next Step column dropped below 180px and the
   inputs poked past the table's right edge, growing a horizontal scrollbar
   on every list tab. */
.table-field {
  width: 100%;
  max-width: 140px;
  min-width: 0;
  font-size: var(--text-sm);
  border: none;
  border-bottom: 1px solid transparent;
  border-radius: 0;
  padding: 2px 0;
  font-family: inherit;
  color: var(--color-text);
  background: transparent;
  transition: border-color var(--t-base), box-shadow var(--t-base), background var(--t-base);
  min-height: 24px;
}
.table-field:focus {
  outline: none;
  border-bottom-color: var(--color-primary);
  background: #fff;
  box-shadow: inset 0 -1px 0 var(--color-primary);
}
.table-field--date { width: 100%; max-width: 140px; }
.table-field--date::-webkit-calendar-picker-indicator {
  opacity: 0; transition: opacity var(--t-base);
}
.table-field--date:focus::-webkit-calendar-picker-indicator { opacity: 1; }
.table-field--select {
  width: 100%; max-width: 150px; min-height: 26px; cursor: pointer;
  padding-right: 0; appearance: none; background-image: none;
}
.table-field--select:focus {
  padding-right: 22px;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-primary) 50%),
    linear-gradient(135deg, var(--color-primary) 50%, transparent 50%);
  background-position: calc(100% - 12px) 55%, calc(100% - 6px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.table-field--wide   { width: 100%; max-width: 180px; }
.table-field--narrow { width: 100%; max-width: 120px; }
.table-field--linker { width: 100%; min-width: 0; padding: 2px 0; font-size: var(--text-sm); border-bottom: none; }
.table-field--linker:focus { border-bottom: none; box-shadow: none; }
/* Desktop comms inline-linker: collapsed pill that widens on focus. Width per
   entity type; `.is-open` is toggled by Alpine (:class="focused?'is-open':''").
   Replaces per-row inline style/:style soup in comms_row.html. */
.comms-linker { display: inline-flex; flex-shrink: 0; }
/* Wide desktop: in the narrow linked-* cells the add-linker must yield its
   width to the chips — with a fixed-width linker the chip text collapsed to
   0 and only its round unlink button survived, which read as a mystery
   arrow badge instead of a chip. flex-shrink 999 makes the linker soak up
   the deficit (down to a small stub) before any chip text is sacrificed; a
   cell with no chips still shows the linker's full label. */
@media (min-width: 1601px) {
  .comms-table td.hide-mobile .comms-linker:not(.is-open) { flex-shrink: 999; min-width: 34px; }
  .comms-table td.hide-mobile .pill-link.pill-xs { min-width: 40px; }
  /* NO overflow:hidden on these tds — the linker's .ac-dropdown is
     absolutely positioned inside the cell and clipping the td made every
     dropdown invisible/unclickable. Chip min-widths keep overflow rare. */
  /* Cap Message's 22% share on very wide screens and pin the four linked
     columns wider so chips get readable text instead of a 6-char stub. */
  .comms-table th:nth-child(7) { width: min(22%, 340px); }
  .comms-table th:nth-child(n+8):nth-child(-n+11) { width: 170px; }
}
.comms-linker--lead  { width: 46px; }
.comms-linker--homelead { width: 88px; }
.comms-linker--owner { width: 54px; }
.comms-linker--task  { width: 44px; }
.comms-linker.is-open { width: 90px; }
.comms-linker--homelead.is-open { width: 130px; }
.comms-linker--task.is-open { width: 120px; }
.comms-linker .table-field--linker { text-align: center; color: #9ca3af; cursor: pointer; font-size: 11px; }
.comms-linker.is-open .table-field--linker { text-align: left; color: inherit; cursor: text; }
.table-field--overdue { color: var(--red-700); border-bottom-color: #f87171; background: transparent; }
select.table-field { padding: 0; }
.lead-title-wrap {
  display: inline-flex; align-items: center; gap: 6px; max-width: 220px;
}
.lead-title-text {
  font-weight: 600; font-size: var(--text-base);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.owner-link-btn {
  width: 26px; height: 26px;
  border-radius: var(--r-md);
  border: 1px solid var(--chip-owner-border);
  background: var(--chip-owner-bg);
  color: var(--chip-owner-text);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; cursor: pointer; line-height: 1; font-family: inherit;
  transition: background var(--t-base), border-color var(--t-base), transform var(--t-base);
}
.owner-link-btn svg { width: 14px; height: 14px; }
.owner-link-btn:hover { background: #d1fae5; border-color: #34d399; }
.owner-link-btn:active { transform: scale(0.9); }
.owner-link-btn:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; }
.owner-link-btn--sm { width: 22px; height: 22px; }
.col-count { font-size: var(--text-base); color: var(--slate-500); }
.td-muted  { font-size: var(--text-sm); color: var(--slate-500); }
.contacts-inline-hint { font-size: var(--text-sm); color: var(--slate-500); margin-bottom: 6px; }
.contacts-table td { font-size: var(--text-sm); color: var(--slate-800); }
.contacts-inline-input,
.contacts-inline-select,
.contacts-inline-notes {
  width: 100%; font-size: var(--text-sm); border: none;
  border-bottom: 1px solid transparent; padding: 2px 0;
  font-family: inherit; background: transparent; color: var(--color-text);
  transition: background var(--t-base), border-color var(--t-base);
}
.contacts-inline-input::placeholder, .contacts-inline-notes::placeholder { color: var(--slate-400); }
.contacts-inline-input:focus, .contacts-inline-select:focus, .contacts-inline-notes:focus {
  outline: none;
  border-bottom-color: var(--color-primary);
  background: #fff;
  box-shadow: inset 0 -1px 0 var(--color-primary);
}
.contacts-inline-select {
  min-height: 26px; padding-right: 14px; appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--slate-500) 50%),
    linear-gradient(135deg, var(--slate-500) 50%, transparent 50%);
  background-position: calc(100% - 10px) 45%, calc(100% - 6px) 45%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}
.contacts-inline-notes { min-height: 36px; resize: vertical; }
.contact-inline-row td:first-child input { font-weight: 600; }
.contact-inline-row td:nth-child(7) textarea { max-height: 80px; }
.contact-row-actions-cell { text-align: right; width: 170px; }
.contact-row-actions { display: inline-flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.btn-xs { font-size: var(--text-xs); padding: 4px var(--sp-2); line-height: 1.2; }
/* Per-table toolbar (Reset / sticky filter / Active only / + New …) — pin
   every direct button + select child to one height so the row reads as a
   single, evenly-spaced strip regardless of which button class each child
   uses (.btn-primary, .btn-xs, .btn-filter-on all have different default
   padding). */
.table-toolbar > button,
.table-toolbar > select {
  height: 28px;
  padding-top: 0;
  padding-bottom: 0;
  line-height: 26px;
  box-sizing: border-box;
  /* Never wrap a label inside the fixed-height button: on narrow phones
     flex pressure used to break multi-word labels onto a second line that
     overflowed the 28px button and poked out from under the table header
     as stray text. Labels are one word ("Reset" / "Active" / "+ New" /
     "Manual" — full wording in the hover title) so the whole toolbar
     always fits a single row. */
  white-space: nowrap;
}
.btn-spinner {
  display: inline-block; width: 10px; height: 10px;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: 50%; animation: btn-spin 0.6s linear infinite;
  vertical-align: middle;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn-filter-on {
  background: var(--blue-50, #eff6ff);
  color: var(--blue-700, #1d4ed8);
  border: 1px solid var(--blue-200, #bfdbfe);
  font-size: var(--text-xs); padding: 4px var(--sp-2); line-height: 1.2;
  border-radius: var(--radius-sm); font-weight: 500; cursor: pointer;
  font-family: inherit;
}
.btn-filter-on:hover { background: var(--blue-100, #dbeafe); }
.contact-row-indicator {
  display: none; margin-top: 6px; font-size: var(--text-xs);
  color: var(--teal-700); gap: 6px; align-items: center; justify-content: flex-end;
}
.contact-row-indicator .spinner { width: 14px; height: 14px; border-width: 2px; }
.contact-row-indicator.htmx-request { display: inline-flex; }
.contact-inline-row.htmx-request td { background: var(--blue-50) !important; }

/* ── Status Pill ──────────────────────────────────────────────────────── */
.status-pill {
  display: inline-block; padding: 2px 9px; border-radius: var(--r-full);
  font-size: var(--text-sm); font-weight: 700; white-space: nowrap; border: 1px solid;
}
.leads-table td:nth-child(2) .status-pill,
.owners-table td:nth-child(2) .status-pill,
.tasks-table td:nth-child(2) .status-pill {
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; display: inline-block; vertical-align: middle;
}
.leads-table td:first-child,
.owners-table td:first-child,
.tasks-table td:first-child { padding-right: 32px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Give title column 30% more width, funded by city (col 5) and acres (col 6) */
.leads-table th:nth-child(1), .leads-table td:nth-child(1) { width: 19.2%; }
.leads-table th:nth-child(5), .leads-table td:nth-child(5) { width: 10.5%; }
.leads-table th:nth-child(6), .leads-table td:nth-child(6) { width: 7.3%; }
.status-select-inline {
  font-size: var(--text-sm); border: none; background: transparent;
  cursor: pointer; font-weight: 700; font-family: inherit; padding: 0;
}

/* ── Panel Stack ──────────────────────────────────────────────────────── */
.panel-stack { position: fixed; inset: 0; pointer-events: none; z-index: 300; }
.panel-backdrop {
  position: absolute; inset: 0; background: rgba(15,23,42,.4);
  display: flex; justify-content: flex-end; pointer-events: all;
  backdrop-filter: blur(1px);
}
.panel-inner {
  background: var(--color-surface); height: 100vh; overflow: hidden;
  box-shadow: var(--shadow-panel); position: relative;
  display: flex; flex-direction: row; max-width: 98vw;
}
@supports (height: 100dvh) { .panel-inner { height: 100dvh; } }
/* On 13"/13.5" laptops (≤1536px): cap the panel so the form column is 20%
   narrower than its old natural width and the sidebar is 20% wider than its
   shrunk value (510px, see rule below). Leaves a comfortable gutter on the
   left for the vtab rail and the table behind.
   Formula: 510 + 0.8 * (100vw - 100 - 425) → 80vw + 90px. */
@media (max-width: 1536px) {
  .panel-inner:not(.panel-mobile) { max-width: calc(80vw + 90px); }
}
.panel-inner.panel-mobile {
  width: 100vw !important; max-width: 100vw !important;
  height: 100% !important; max-height: 100% !important;
  border-radius: 0; box-shadow: none;
}
.panel-inner.panel-mobile .panel-drag-handle { display: none !important; }
.panel-inner.panel-mobile .panel-header {
  position: sticky; top: 0;
  /* Above the map's absolute controls (Fullscreen / Google Maps, z-index:1000)
     so they tuck behind the sticky header when the map scrolls up, but below
     the fullscreen modal (z-index:9999) so that still covers the header. */
  z-index: 1100;
  padding-top: calc(10px + env(safe-area-inset-top));
  flex-wrap: wrap;
}
.panel-inner.panel-mobile .panel-header > div:first-child {
  padding-right: 40px;
}
.panel-inner.panel-mobile .panel-header-actions {
  width: 100%; margin-top: 8px;
  /* ONE row, always: labels drop to icon-only (rule below) so everything
     fits; if a panel still overflows, the row scrolls sideways rather
     than wrapping to a second line. */
  display: flex; flex-wrap: nowrap; gap: 6px; align-items: center;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.panel-inner.panel-mobile .panel-header-actions > * { margin: 0; }
/* Email / Text / Call share one Alpine component, so on the home-lead and
   task panels the three buttons live inside a single wrapper element —
   which makes them ONE flex item here, not three. As an inline-block that
   item shrank and its buttons wrapped inside it, producing the 2×2 block
   the nowrap rule above exists to prevent (mail + chat on one line, phone
   underneath). A nowrap flex row that refuses to shrink puts them back on
   the header's own line; if the row still overflows, the parent scrolls
   sideways as designed. The lead and owner panels never showed this — they
   hang x-data on the <form>, so their buttons are direct flex children. */
.panel-comm-actions {
  display: inline-flex; align-items: center; gap: 6px;
  flex: none; flex-wrap: nowrap;
}
.panel-inner.panel-mobile .panel-header-actions .btn-secondary,
.panel-inner.panel-mobile .panel-header-actions .btn-panel-delete,
.panel-inner.panel-mobile .panel-header-actions .btn-panel-save,
.panel-inner.panel-mobile .panel-header-actions > div > button {
  box-sizing: border-box;
  /* icon + label on one centered line — stops the ragged two-line wrap */
  display: inline-flex; align-items: center; justify-content: center;
  gap: 5px; min-width: 0;
  font-size: 11px !important; padding: 6px 8px !important;
  white-space: nowrap; line-height: 1.15; text-align: center;
  /* equal height for every action — Save has no icon, so without this it
     rendered a few px shorter than its icon-bearing neighbours */
  min-height: 32px;
}
/* Comm-card header on phones: From › To, the subject and the date all
   competed for one narrow flex line, so the participants collapsed to
   '"Clark ...  R...' — unreadable, which is the one thing the row exists
   to tell you. Wrap it: From › To takes a full first line, subject +
   date follow on the second. Desktop keeps the single-line layout. */
@media (max-width: 768px) {
  .comm-hdr-line { flex-wrap: wrap; row-gap: 2px; }
  .comm-hdr-line > .comm-fromto { flex: 1 1 100%; min-width: 100%; }
  /* Edit / × / ▾ held a fixed column down the right, so every line of the
     card wrapped inside what was left. Float them to a top row with the
     channel icon instead, and let the card body span the full width. */
  .comm-card-hdr { flex-wrap: wrap; gap: 6px !important; }
  .comm-card-icon { order: 1; }
  .comm-card-actions { order: 2; margin-left: auto; }
  .comm-card-main { order: 3; flex: 1 1 100% !important; }
}

/* Collapsed "Add scheduled dates" affordance in the task panel — quiet,
   link-like, so an unscheduled task shows one thin line instead of the
   full blue two-date block. */
.sched-toggle { display: inline-flex; align-items: center; gap: 5px; background: none;
  border: none; padding: 4px 2px; margin: 0; font: inherit; font-size: 11px;
  font-weight: 600; color: #0369a1; cursor: pointer; }
.sched-toggle:hover { text-decoration: underline; }

/* wgnmail:// deep links only resolve on a desktop with the WGN Mail client
   installed — on phones they dead-end, so hide every element tagged
   data-mail-deeplink (comm-card Reply/Open icons, the drawer's per-thread ↗). */
@media (max-width: 768px) {
  [data-mail-deeplink] { display: none !important; }
}
/* Icon-only on mobile (must come AFTER the shared block above so its
   font-size wins): the label is a bare text node next to the inline SVG,
   so zeroing the button's font hides it while the fixed-size icon stays
   put. Count badges keep their own inline font-size (absolute values
   don't inherit the 0). Save keeps its text — no icon, not matched. */
.panel-inner.panel-mobile .panel-header-actions .btn-secondary {
  font-size: 0 !important; gap: 0 !important;
}
/* Desktop-tool actions are dead weight on a phone: the Email menu deep-links
   the DESKTOP mail client, Text Owner drives the Click-to-Text browser
   extension, Call Owner dials through the paired Android dialer from the
   desktop. Hide all three on mobile panels. */
.panel-inner.panel-mobile .panel-header-actions .email-menu-wrap,
.panel-inner.panel-mobile .panel-header-actions [data-desktop-only] {
  display: none !important;
}
/* Delete stays SMALL on mobile and keeps its buffer from whatever follows
   (order:-1 from the base rule pins it first) — a stray thumb tap next to
   it hits dead space, not another action. */
.panel-inner.panel-mobile .panel-header-actions .btn-panel-delete {
  padding: 4px 10px !important; margin-right: 10px;
}
/* Save always hugs the RIGHT edge of its row — the auto margin absorbs
   whatever space is left whether it shares the line or wraps to its own. */
.panel-inner.panel-mobile .panel-header-actions .btn-panel-save {
  margin-left: auto; padding: 6px 16px !important;
}
.panel-inner.panel-mobile .btn-panel-close {
  position: absolute; top: calc(8px + env(safe-area-inset-top)); right: 10px;
}
/* Close is absolutely positioned on a phone, so its new sibling needs
   placing too or the two land on top of each other. */
.panel-inner.panel-mobile .btn-panel-min {
  position: absolute; top: calc(8px + env(safe-area-inset-top)); right: 52px;
}
.panel-inner.panel-mobile .panel-content {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: env(safe-area-inset-bottom, 16px);
  scroll-padding-bottom: 60px;
}
.panel-content {
  flex: 1; overflow-y: auto; display: block; min-width: 0; min-height: 0;
}
.panel-content > form {
  display: flex; flex-direction: column; min-height: 100%; height: auto; padding-bottom: 48px;
}
.panel-form { display: flex; flex-direction: column; height: 100%; }

/* ── Panel Vertical Tab Rail ──────────────────────────────────────────── */
.panel-vtab-bar {
  flex-shrink: 0; align-self: stretch;
  display: flex; flex-direction: row; gap: 5px;
  padding: 14px 5px 14px 10px; align-items: flex-start;
}
.pvtab {
  display: flex; flex-direction: column; align-items: center;
  padding: 9px 7px 13px; flex: 0 0 auto; gap: 8px;
  cursor: pointer; font-family: inherit;
  border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.09);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-radius: var(--r-xl);
  box-shadow: 0 2px 8px rgba(0,0,0,0.18), inset 0 1px 0 rgba(255,255,255,0.12);
  transition: background var(--t-base), border-color var(--t-base), box-shadow var(--t-base);
}
.pvtab:hover {
  background: rgba(255,255,255,0.16);
  border-color: rgba(255,255,255,0.26);
  box-shadow: 0 4px 16px rgba(0,0,0,0.24), inset 0 1px 0 rgba(255,255,255,0.18);
}
.pvtab.active {
  background: rgba(255,255,255,0.95);
  border-color: rgba(255,255,255,0.98);
  box-shadow: 0 4px 20px rgba(0,0,0,0.22), inset 0 1px 0 #fff;
}
.pvtab-label {
  writing-mode: vertical-lr;
  font-size: var(--text-sm); font-weight: 500;
  color: rgba(255,255,255,0.65);
  white-space: nowrap; letter-spacing: 0.01em;
  transition: color var(--t-base);
}
.pvtab:hover:not(.active) .pvtab-label { color: rgba(255,255,255,0.92); }
.pvtab.active .pvtab-label { color: var(--slate-700); font-weight: 600; }
.pvtab-close {
  font-size: 15px; line-height: 1; color: rgba(255,255,255,0.38);
  width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md); flex-shrink: 0;
  transition: background var(--t-fast), color var(--t-fast);
}
.pvtab.active .pvtab-close { color: var(--slate-400); }
.pvtab-close:hover { background: rgba(255,255,255,0.18); color: rgba(255,255,255,0.95) !important; }
.pvtab.active .pvtab-close:hover { background: var(--slate-200); color: var(--slate-700) !important; }

/* ── Panel Drag Handle ────────────────────────────────────────────────── */
.panel-drag-handle {
  position: absolute; left: 0; top: 0; bottom: 0; width: 8px;
  cursor: col-resize; z-index: 20; background: transparent;
}
.panel-drag-handle:hover { background: rgba(29,78,216,.2); }

/* ── Panel Header — Dark Navy ─────────────────────────────────────────── */
.panel-header {
  background: var(--slate-800);
  border-bottom: 1px solid var(--slate-700);
  padding: 13px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.panel-title    { font-size: var(--text-lg); font-weight: 700; color: var(--slate-50); }
.panel-subtitle { font-size: var(--text-sm); color: var(--slate-400); margin-top: 2px; }
/* "↳ Sub-task of <parent>" — amber chip in the task panel subtitle; clicking
   opens the parent panel. Pops on the dark header so the sub relationship is
   unmissable (replaced the easy-to-miss ↖ Parent header button). */
.subtask-chip { display: inline-block; background: #fef3c7; color: #92400e; border-radius: 10px;
  padding: 1px 9px; font-size: 11px; font-weight: 700; text-decoration: none; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.subtask-chip:hover { background: #fde68a; }
/* "re: <lead>" — lead-colored chip in the task panel subtitle; clicking opens
   the lead panel. Lives in the dark header so a task's lead is visible without
   scrolling to the Related Leads sidebar (which sits below the fold on
   mobile). Same shape as .subtask-chip, lead palette instead of amber. */
.lead-chip { display: inline-block; background: var(--chip-lead-bg); color: var(--chip-lead-text);
  border-radius: 10px; padding: 1px 9px; font-size: 11px; font-weight: 700; text-decoration: none;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.lead-chip:hover { background: var(--chip-lead-border); }
.panel-subtitle a.lead-chip { color: var(--chip-lead-text); }
.panel-subtitle a.lead-chip:hover { text-decoration: none; }
.panel-subtitle a { color: var(--blue-400, #60a5fa); text-decoration: none; }
.panel-subtitle a:hover { text-decoration: underline; }
/* #id chip that copies a deep link to the panel (see window.copyDeepLink) */
.panel-id-link { cursor: pointer; white-space: nowrap; }
.panel-id-link .erp-icon { width: 11px; height: 11px; vertical-align: -1px; margin-left: 3px; opacity: .65; }
.panel-id-link:hover .erp-icon { opacity: 1; }
.panel-subtitle-hint { font-size: var(--text-xs); color: #34d399; margin-top: 2px; }
.panel-entity-type { color: var(--slate-300); }
.panel-id { color: var(--slate-500); }
.panel-header-actions { display: flex; gap: 6px; align-items: center; }

.btn-panel-close {
  background: rgba(255,255,255,.1); color: var(--slate-300); border: none;
  padding: 5px 10px; border-radius: var(--r-md); cursor: pointer;
  font-family: inherit; font-size: var(--text-lg);
  transition: background var(--t-fast);
}
.btn-panel-close:hover { background: rgba(255,255,255,.18); color: var(--slate-100); }
.btn-panel-close:active { transform: scale(0.94); }

/* Minimize sits beside close and reads as the same family of window
   control — quieter than Save, which is the one thing in that corner that
   should draw the eye. */
.btn-panel-min {
  background: rgba(255,255,255,.1); color: var(--slate-300); border: none;
  padding: 5px 10px; border-radius: var(--r-md); cursor: pointer;
  font-family: inherit; font-size: var(--text-lg); line-height: 1;
  transition: background var(--t-fast);
}
.btn-panel-min:hover { background: rgba(255,255,255,.18); color: var(--slate-100); }
.btn-panel-min:active { transform: scale(0.94); }

/* ── Parked (minimized) panels ────────────────────────────────────────── */
.panel-tray {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  z-index: 99997;              /* over panels; under the drawers and modals */
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  max-width: min(92vw, 900px);
}
.panel-tray-pill {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 240px;
  background: var(--slate-800, #1e293b); color: #fff;
  border: none; border-radius: 20px; padding: 8px 8px 8px 14px;
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  box-shadow: 0 6px 20px rgba(15, 23, 42, .35);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.panel-tray-pill:hover { background: var(--slate-900, #0f172a); }
/* Reads as "comes back up" — the pill is minimize's other half. */
.panel-tray-up { opacity: .7; font-size: 14px; line-height: 1; flex: none; }
.panel-tray-x {
  background: rgba(255, 255, 255, .18); border-radius: 50%;
  width: 20px; height: 20px; line-height: 1; font-size: 14px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.panel-tray-x:hover { background: rgba(255, 255, 255, .32); }
@media (max-width: 768px) {
  /* Clear of the bottom tab bar. */
  .panel-tray { bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
  .panel-tray-pill { max-width: 60vw; }
}

.btn-panel-save {
  background: var(--blue-500); color: #fff; border: none;
  padding: 5px 15px; border-radius: var(--r-md); font-size: var(--text-sm);
  font-weight: 700; cursor: pointer; font-family: inherit;
  transition: transform 60ms cubic-bezier(.3,0,.5,1), background var(--t-fast);
}
.btn-panel-save:hover { background: var(--blue-600); }
.btn-panel-save:active { transform: scale(0.94); background: var(--blue-700) !important; }

.btn-panel-delete {
  background: rgba(220,38,38,.12); color: #fca5a5;
  border: 1px solid rgba(220,38,38,.3); padding: 4px var(--sp-2);
  border-radius: var(--r-sm); font-size: var(--text-base); font-weight: 700;
  cursor: pointer; font-family: inherit;
  transition: transform 60ms cubic-bezier(.3,0,.5,1), background var(--t-fast);
}
.btn-panel-delete:hover { background: rgba(220,38,38,.22); }
.btn-panel-delete:active { transform: scale(0.94); background: rgba(220,38,38,.35) !important; }
/* Keep Delete AWAY from Save/Close: order it to the far (left) side of the
   header action cluster with an extra separation gap, on every panel —
   an accidental click near the primary actions can't land on it. Works for
   the desktop flex row and the mobile grid alike (order applies to both). */
.panel-header-actions .btn-panel-delete { order: -1; margin-right: 12px; }

/* Secondary actions in panel header (e.g. Email link) */
.panel-header .btn-secondary {
  background: rgba(255,255,255,.1);
  color: var(--slate-300);
  border-color: rgba(255,255,255,.15);
  font-size: var(--text-xs);
}
.panel-header .btn-secondary:hover {
  background: rgba(255,255,255,.18);
  color: var(--slate-100);
}

.panel-header button:active { transform: scale(0.94); }

/* Unified action-button icons (see erp_tags.icon). Outline SVGs that
   inherit the button's text color, so they render light + consistent on
   the dark header instead of the old multicolor emoji. */
.erp-icon { display: inline-block; vertical-align: -2px; flex: none; }
/* Tabs with a leading outline icon (Map / Scheduling) — replaces the OS
   emoji so the glyphs render identically everywhere. */
.tab-iconed .erp-icon { width: 13px; height: 13px; margin-right: 2px; }
.erp-icon--spin { animation: erp-icon-spin 0.8s linear infinite; }
@keyframes erp-icon-spin { to { transform: rotate(360deg); } }

/* ── Panel Two-Col Layout ─────────────────────────────────────────────── */
.panel-two-col {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 575px;
  min-height: 100%;
  overflow: visible;
}
.panel-main {
  padding: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  overflow-y: visible;
}
.panel-sidebar {
  padding: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--color-surface-raised);
  border-left: 1px solid var(--color-border);
  overflow-y: visible;
}

@media (max-width: 820px) {
  .panel-two-col { grid-template-columns: 1fr !important; }
  .panel-sidebar {
    display: flex; flex-direction: column; width: 100%;
    border-left: none; border-top: 1px solid var(--color-border);
    margin-top: 10px; padding-top: var(--sp-3); padding-bottom: 6px;
  }
  .panel-main { padding-bottom: 0; }

  /* Lead panel on mobile: hoist the mini-map + its quick-look chips out of the
     stacked sidebar so they sit right after the Details editor instead of at
     the very bottom. display:contents flattens the two columns into a single
     flex column on .panel-two-col--lead, then `order` interleaves the sidebar
     map/chips between Details and the rest of the form. Pure CSS — the map's
     Leaflet instance never moves in the DOM, so it survives HTMX morphs and
     needs no re-init. The gutter that .panel-main/.panel-sidebar normally
     provide is moved onto the flattened container. */
  .panel-two-col.panel-two-col--lead {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    padding: var(--sp-3);
  }
  .panel-two-col--lead > .panel-main,
  .panel-two-col--lead > .panel-sidebar {
    display: contents;
  }
  .panel-two-col--lead .panel-main > *,
  .panel-two-col--lead .panel-sidebar > * { order: 3; }
  .panel-two-col--lead .panel-main > .top-bar { order: 1; }
  .panel-two-col--lead .panel-main > .lead-details-group { order: 2; }
  .panel-two-col--lead .panel-sidebar > .panel-lead-map,
  .panel-two-col--lead .panel-sidebar > .lead-map-chips { order: 2; }
}

/* Narrow laptops (821-1536px): shrink the sidebar (map/files) so the form
   column stays the wider of the two. Pairs with the .panel-inner cap above. */
@media (min-width: 821px) and (max-width: 1536px) {
  .panel-two-col { grid-template-columns: minmax(0, 1fr) 510px; }
}

/* Tablet (769-1600px): tighten wide data tables so headers and search boxes
   don't get clipped. Base th/th-search min-width of 120px times 11 comms
   columns overflows the viewport. */
@media (min-width: 769px) and (max-width: 1600px) {
  .comms-table .th-search,
  .leads-table .th-search,
  .owners-table .th-search,
  .homeleads-table .th-search,
  .tasks-table .th-search { min-width: 0; }
  .comms-table.data-table th,
  .comms-table.data-table td { min-width: 0; }
  .comms-table th { white-space: normal; }
  .comms-table .sort-btn { white-space: normal; }

  /* Show a dedicated pills row under each comm (like mobile) so linked
     pills aren't clipped by the narrow linked-* columns. */
  .comms-table .msub-pills-row { display: table-row; }
  .comms-table .msub-pills-row td {
    border: none !important;
    border-bottom: 1px solid var(--slate-300, #cbd5e1) !important;
    padding: 6px 10px 8px !important;
  }
  /* Drop the divider between the main comm row and its pills row — they
     belong to the same record. The bolder border-bottom on the pills row
     separates one comm from the next. */
  .comms-table tbody tr[id^="comm-row-"] > td { border-bottom: none !important; }
  .comms-table .msub-pills-wrap { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
  .comms-table .msub-pills-wrap .msub-pill {
    max-width: 100%; flex-shrink: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis;
    display: inline-flex; align-items: center; gap: 4px; border: none;
    padding-right: 4px;
  }
  .comms-table .msub-pills-wrap .msub-pill-x {
    flex-shrink: 0;
    font-size: 13px; line-height: 1;
    background: none; border: none; cursor: pointer;
    padding: 2px 5px; margin-left: 2px;
    border-radius: 10px;
    color: inherit; opacity: 0.45;
    min-width: 18px; min-height: 18px;
    display: inline-flex; align-items: center; justify-content: center;
    transition: opacity var(--t-fast), background var(--t-fast);
  }
  .comms-table .msub-pills-wrap .msub-pill-x:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.08);
  }
}

/* Small laptops (769-1600px): the four link columns are pure dead weight on
   the main row — their chips already render in the pills row below, and the
   +Lead/+Home L/+Owner/+Task linkers now live there too (see comms_row's
   pills-row linkers). Hide the columns entirely so Subject / From / To /
   Message get their width back, exactly one line per field. */
@media (min-width: 769px) and (max-width: 1600px) {
  /* Zero-width, NOT display:none: Firefox keeps display:none cells as
     phantom columns in table-layout:fixed and still allots them their
     share of the width — operators saw the freed space as a dead gutter
     after the last column instead of wider text columns. Same technique
     (and same reason) as .mobile-only-th above. */
  .comms-table thead th:nth-child(n+8):nth-child(-n+11),
  .comms-table tbody tr[id^="comm-row-"] > td:nth-child(n+8):nth-child(-n+11) {
    width: 0 !important; min-width: 0 !important; max-width: 0 !important;
    padding: 0 !important; border: 0 !important; overflow: hidden !important;
  }
  .comms-table thead th:nth-child(n+8):nth-child(-n+11) > *,
  .comms-table tbody tr[id^="comm-row-"] > td:nth-child(n+8):nth-child(-n+11) > * {
    display: none !important;
  }
  /* fixed table layout would otherwise shrink to the surviving columns'
     widths — force full width so the freed space flows into the text
     columns instead */
  .comms-table.data-table { width: 100%; }
  /* ...and keep the trailing button column from swallowing the slack */
  .comms-table th.open-col { width: 48px; }
}
/* All widths: the comms table always stretches to its container so the
   columns share the whole screen instead of leaving a dead right gutter. */
.comms-table.data-table { width: 100%; }
/* Column diet (tablet/desktop): Channel, Date and Match need far less than
   an equal share under table-layout: fixed — pin them small and hand the
   freed width to Message, the column operators actually read. Mobile keeps
   its own auto layout + first-column rules. */
@media (min-width: 769px) {
  .comms-table th:nth-child(1) { width: 92px; min-width: 0; }
  .comms-table th:nth-child(3) { width: 82px; min-width: 0; }
  .comms-table th:nth-child(12) { width: 84px; min-width: 0; }
  .comms-table th:nth-child(7) { width: 22%; }
  .comms-table th:nth-child(1) .th-search,
  .comms-table th:nth-child(3) .th-search { min-width: 0; width: 100%; }
}
/* re-open: the rules below this marker belonged to the same 1600px block */
@media (max-width: 1600px) {

  /* Hide inline pills in linked-* cells — pills now live in the pills row
     below. Keep the +Lead/+Owner/+Task add-linker chips (.ac-wrap) visible
     in their original column so the user can add links from the first row. */
  .comms-table td.hide-mobile .pill-link.pill-xs { display: none !important; }

  /* Tasks: 9 columns at the 120px floor plus the 180px Next Step input
     overflow a 13" viewport and force a horizontal scrollbar. Let the columns
     shrink to fit and let Next Step fill its cell (text clips instead). */
  .tasks-table.data-table { width: 100%; }
  .tasks-table.data-table th,
  .tasks-table.data-table td { min-width: 0; }
  .tasks-table .table-field--wide { width: 100%; min-width: 0; }

  /* Hand the Parent Task column's width to Next Step — Parent Task is usually
     empty ("—"), so Next Step gets the room it needs on narrow screens. */
  .tasks-table th:nth-child(6), .tasks-table td:nth-child(6) { width: 90px; }
  .tasks-table th:nth-child(9), .tasks-table td:nth-child(9) { width: 230px; }

}

/* Shorten "Linked " prefix at narrow widths so Leads/Owners/Tasks fit. */
@media (max-width: 1600px) {
  .hide-narrow { display: none; }
}


/* ── Mini Map ─────────────────────────────────────────────────────────── */
.panel-mini-map {
  isolation: isolate; position: relative; contain: layout paint;
  border: 1px solid var(--color-border); border-radius: var(--r-lg);
  overflow: hidden; height: 180px; flex-shrink: 0;
}
.panel-mini-map .leaflet-pane { z-index: 1 !important; }
.panel-mini-map .leaflet-top, .panel-mini-map .leaflet-bottom { z-index: 2 !important; }

/* ── Main map ─────────────────────────────────────────────────────────── */
#map-container { position: relative; z-index: 0; }

/* ── Custom map popup ─────────────────────────────────────────────────── */
.erp-popup .leaflet-popup-content-wrapper {
  padding: 0; border-radius: var(--r-xl); overflow: hidden;
  box-shadow: var(--shadow-xl);
}
.erp-popup .leaflet-popup-content { margin: 0; width: auto !important; }
.erp-popup .leaflet-popup-tip-container { margin-top: -1px; }

/* ── Map filters overlay ──────────────────────────────────────────────── */
.map-filter-bar {
  position: absolute; top: 10px; left: 50px; right: 10px; z-index: 800;
  display: flex; gap: 6px; align-items: center;
}
.map-filter-select {
  flex: 1; min-width: 0;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-md); padding: 5px 10px;
  font-size: var(--text-sm); font-weight: 500; color: var(--slate-800);
  box-shadow: var(--shadow-sm); cursor: pointer; outline: none;
}
.map-filter-select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(29,78,216,.12); }
.map-filter-badge {
  background: var(--color-primary); color: #fff; border-radius: var(--r-full);
  padding: 3px 10px; font-size: var(--text-xs); font-weight: 600; white-space: nowrap;
}
.map-filter-clear {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-md); padding: 5px 8px;
  font-size: var(--text-xs); color: var(--slate-500); cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.map-filter-clear:hover { background: var(--color-surface-raised); color: var(--slate-800); }
.map-filter-address { min-width: 220px; }

/* Address input lives in a relative wrapper so the autocomplete dropdown
   can position itself directly below the input without escaping the bar. */
.map-filter-address-wrap {
  position: relative;
  flex: 1 1 220px;
  min-width: 220px;
  display: flex;
}
.map-filter-address-wrap > .map-filter-address {
  flex: 1; min-width: 0; width: 100%;
}
.map-address-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-md); box-shadow: var(--shadow-md);
  max-height: 280px; overflow-y: auto; z-index: 900;
  padding: 4px;
}
.map-address-pred {
  display: block; width: 100%; text-align: left;
  background: transparent; border: none; cursor: pointer;
  padding: 7px 10px; border-radius: var(--r-sm);
  font-family: inherit; color: var(--slate-800); line-height: 1.3;
}
.map-address-pred.is-highlight,
.map-address-pred:hover { background: var(--color-surface-raised); }
.map-address-pred .pred-main {
  display: block; font-size: var(--text-sm); font-weight: 600;
}
.map-address-pred .pred-secondary {
  display: block; font-size: var(--text-xs); color: var(--slate-500); margin-top: 1px;
}

@media (max-width: 768px) {
  /* On mobile the bar would otherwise overflow off-screen — wrap into rows
     so every control stays reachable. Status/Users sit two-up; the long
     "Zoom to leads" gets its own row; address input grows with Go button
     hugging beside it; Clear stays right-aligned. */
  .map-filter-bar { flex-wrap: wrap; gap: 4px; }
  .map-filter-bar select.map-filter-select {
    flex: 1 1 calc(50% - 2px);
    min-width: 0;
    font-size: var(--text-xs);
  }
  .map-filter-zoom {
    flex: 1 1 100% !important;
    font-size: var(--text-xs);
  }
  .map-filter-address-wrap {
    flex: 1 1 0 !important;
    min-width: 0 !important;
  }
  .map-filter-address {
    font-size: var(--text-xs);
  }
  .map-filter-go {
    flex: 0 0 auto !important;
    font-size: var(--text-xs);
  }
  .map-filter-clear { flex: 0 0 auto; margin-left: auto; }
}

/* ── Scheduling calendar (FullCalendar) ───────────────────────────────── */
/* Fill the screen below the header/tabs (same offset the Map tab uses) and lay
   out as a column so the filter bar takes its natural height and the calendar
   flexes to fill the rest — the grid fits the viewport with no page scroll. */
#schedule-container { padding: 12px; height: calc(100vh - 110px); display: flex; flex-direction: column; }
/* Toolbar above the calendar — reuses .map-filter-select for the controls but,
   unlike the map's absolutely-positioned bar, sits in normal flow. */
.cal-filter-bar {
  display: flex; gap: 6px; align-items: center;
  margin-bottom: 12px; flex-wrap: wrap;
}
.cal-filter-bar > .map-filter-select { flex: 1 1 160px; }
#erp-calendar { font-size: var(--text-sm); flex: 1; min-height: 0; }
/* Two-line event chip: bold title + muted next-step, each clipped to one line
   so a long next-step can't blow out the day cell. */
.fc-ev { overflow: hidden; line-height: 1.25; }
.fc-ev-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fc-ev-next {
  font-size: var(--text-xs); opacity: .85;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fc .fc-event { cursor: pointer; }
/* FullCalendar builds its grid out of <table>/<th>/<td>, so the app's global
   table rules above (`table { min-width: 600px }`, `th`/`td { padding; sticky }`,
   `border-collapse: collapse`) leak into the calendar and collapse the day
   columns — a long event title balloons its own column and squashes the rest.
   Re-pin the calendar's grid tables to an equal-width fixed layout (!important
   because FullCalendar injects its own stylesheet after app.css) and strip the
   leaked cell styling. */
#erp-calendar .fc-scrollgrid-sync-table,
#erp-calendar .fc-col-header {
  table-layout: fixed !important; width: 100% !important; min-width: 0 !important;
  border-collapse: separate !important;
}
#erp-calendar th, #erp-calendar td { padding: 0; }
#erp-calendar th { position: static; background: none; text-transform: none; letter-spacing: normal; }
#erp-calendar .fc-daygrid-event { min-width: 0; overflow: hidden; }
/* The same global rules also strip the grid cells' bottom border, so the last
   week row loses its bottom edge (middle rows borrow the next row's top border).
   Draw the grid's bottom frame line back. */
#erp-calendar .fc-scrollgrid { border-bottom: 1px solid var(--color-border); }

@media (max-width: 768px) {
  #schedule-container { padding: 6px; }
  .cal-filter-bar > .map-filter-select { flex: 1 1 calc(50% - 3px); font-size: var(--text-xs); }
}

/* ── Field Groups ─────────────────────────────────────────────────────── */
.field-group { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--r-lg); overflow: visible; }

/* Wraps rather than overflows. A section header carries a title, sometimes
   a count, sometimes a filter, and one or two buttons; on a phone that adds
   up past 375px and the buttons — and the ▶ that says whether the section is
   even open — ran off the right edge with nothing to scroll them back. */
.collapsible-hdr {
  display: flex !important; align-items: center; justify-content: space-between;
  flex-wrap: wrap; row-gap: 6px;
  padding: 8px 14px; border-bottom: 1px solid var(--color-border);
  font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .8px;
  color: var(--slate-500); background: var(--color-surface-raised);
  cursor: pointer; user-select: none;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  transition: background var(--t-base);
}
.collapsible-hdr:hover { background: var(--slate-100); }
.collapsible-hdr.closed { border-bottom: none; border-radius: var(--r-lg); }
.collapsible-body { padding: 10px 12px; }

.field-grid   { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-2); }
.field-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.field-grid-4 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: var(--sp-2); }
.field-full   { grid-column: 1 / -1; }

/* ── Form Fields ──────────────────────────────────────────────────────── */
.field-label {
  font-size: var(--text-xs); font-weight: 700; color: var(--slate-500);
  display: flex; align-items: center; gap: 3px;
  margin-bottom: 2px; text-transform: uppercase; letter-spacing: .5px;
}
.field-label .req { color: var(--color-danger); }
.field-input {
  background: transparent; border: none; border-bottom: 1px solid var(--slate-300);
  color: var(--color-text); padding: 5px 2px; border-radius: 0;
  font-size: var(--text-md); width: 100%; outline: none; font-family: inherit;
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.field-input[type="date"],
.field-input[type="datetime-local"],
.field-input[type="time"] { width: 100%; min-width: 0; max-width: 100%; box-sizing: border-box; }
.field-input:focus { border-bottom-color: var(--color-primary); box-shadow: inset 0 -1px 0 var(--color-primary); }
.field-input:disabled { background: transparent; color: var(--slate-400); }
/* Quick-fill controls sit in a grid matching the Channel/From/To/User row
   above (same column template + gap + side padding) so they line up directly
   beneath the From/To fields they act on, with no dividing border. */
.qf-fill { display: grid; gap: var(--sp-2); padding: 0 12px 8px; }
.qf-actions { grid-column: 2 / 4; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.qf-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--slate-100); border: 1px solid var(--slate-300); color: var(--slate-600);
  border-radius: var(--r-md); padding: 3px 10px; font-size: var(--text-xs);
  font-weight: 600; cursor: pointer; line-height: 1.4;
  transition: background var(--t-base), border-color var(--t-base), color var(--t-base);
}
.qf-chip svg { width: 13px; height: 13px; }
.qf-chip:hover { background: var(--slate-200); border-color: var(--color-primary); color: var(--color-primary); }
.qf-chip--primary {
  background: var(--color-primary-soft, #eff6ff); border-color: var(--color-primary);
  color: var(--color-primary);
}
.qf-chip--primary:hover { background: var(--color-primary); color: #fff; }
.field-textarea {
  background: var(--slate-50); border: 1px solid var(--slate-200);
  color: var(--color-text); padding: 6px var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--text-base); width: 100%; outline: none; resize: vertical;
  font-family: inherit; min-height: 80px;
  transition: border-color var(--t-base);
}
.field-textarea:focus { border-color: var(--color-primary); }
.field-select {
  background: transparent; border: none; border-bottom: 1px solid var(--slate-300);
  color: var(--color-text); padding: 5px 2px; border-radius: 0;
  font-size: var(--text-md); width: 100%; outline: none; cursor: pointer;
  font-family: inherit; height: auto;
  transition: border-color var(--t-base);
}
.field-select:focus { border-bottom-color: var(--color-primary); outline: none; }
.date-input-wrap { display: flex; align-items: center; gap: 6px; width: 100%; }
.date-input-wrap .field-input { flex: 1; }
.date-clear-btn {
  background: var(--slate-100); border: 1px solid var(--slate-300); color: var(--slate-600);
  border-radius: var(--r-md); padding: 5px var(--sp-2); font-size: var(--text-base);
  font-weight: 600; cursor: pointer; flex-shrink: 0;
  transition: background var(--t-base);
}
.date-clear-btn:hover { background: var(--slate-200); }
.date-clear-btn:active { transform: scale(0.94); }
.sched-wrap { background: var(--sky-100); border: 1px solid #7dd3fc; border-radius: var(--r-md); padding: 7px var(--sp-2); }
.sched-wrap .field-label { color: var(--sky-700) !important; }

/* ── Top Bar (pinned fields) ──────────────────────────────────────────── */
.top-bar { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--r-lg); overflow: visible; }
.top-bar-row { padding: 8px 12px; display: grid; gap: var(--sp-2); align-items: end; }
.top-bar-row + .top-bar-row { border-top: 1px solid var(--color-border); }
/* The .top-bar-fields wrapper breaks the Title-row → Status-row sibling
   adjacency, so re-draw that divider on the wrapper. On desktop the wrapper
   is transparent (its two rows lay out exactly as before); mobile turns it
   into the 6-col grid (see the max-width:768px block). */
.top-bar-fields { border-top: 1px solid var(--color-border); }
.top-bar-fields > .top-bar-row:first-child { border-top: none; }

/* ── Comm Card ────────────────────────────────────────────────────────── */
.comm-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--r-lg); overflow: hidden; }
.comm-card-hdr { display: flex; align-items: center; gap: var(--sp-2); padding: 8px 12px; cursor: pointer; transition: background var(--t-base); }
.comm-card-hdr:hover { background: var(--color-surface-raised); }
/* The collapsed comm preview is a bare <div>; if an expanded email ever leaks a
   `div{text-align:center}` rule into the page it would match this div directly
   and beat inherited alignment. Pin the header's text left so the preview can't
   be centred regardless. */
.comm-card-hdr, .comm-card-hdr div { text-align: left; }
.comm-channel-icon {
  width: 26px; height: 26px; border-radius: var(--r-md);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--text-md); flex-shrink: 0;
}
.comm-card-body {
  padding: 10px 12px; border-top: 1px solid var(--color-border);
  background: var(--color-surface-raised); font-size: var(--text-md); line-height: 1.6;
}
.comm-card, .comm-card-hdr, .comm-card-body { width: 100%; max-width: 100%; }
.comm-card-hdr > * { min-width: 0; }
.comm-card-body { overflow-x: auto; }
.comm-body-html { max-width: 100%; overflow-wrap: anywhere; word-break: break-word; }
.comm-body-html img,
.comm-body-html table,
.comm-body-html iframe,
.comm-body-html pre { max-width: 100%; width: 100%; }
.comm-body-html pre { white-space: pre-wrap; }
.comm-ai { background: #fdf4ff; border: 1px solid var(--purple-200); border-radius: var(--r-md); padding: 8px 10px; margin-top: 8px; font-size: var(--text-base); }
.comm-ai-label { font-size: var(--text-sm); font-weight: 700; color: var(--purple-600); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 5px; }

/* ── File Manager ─────────────────────────────────────────────────────── */
.attachments-block {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-xl);
  padding: var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.att-block-hdr { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-3); }
.att-block-title { font-size: 15px; font-weight: 700; color: var(--slate-900); }
.att-block-subtitle { font-size: var(--text-base); color: var(--slate-500); }
.att-hdr-actions { display: flex; gap: 6px; }
.att-list { display: flex; flex-direction: column; gap: 6px; }
.att-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px 12px; border: 1px solid var(--color-border);
  border-radius: var(--r-lg); background: var(--color-surface-raised);
  transition: border-color var(--t-base);
}
.att-row:hover { border-color: var(--slate-300); }
.att-icon-chip {
  width: 36px; height: 36px; border-radius: var(--r-lg);
  background: #e0e7ff; color: #312e81;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--text-xl); flex-shrink: 0;
}
.att-info { flex: 1; min-width: 0; }
.att-name {
  font-size: 15px; font-weight: 700; color: var(--color-text);
  background: none; border: none; padding: 0; cursor: pointer;
  text-align: left; font-family: inherit; width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color var(--t-base);
}
.att-name:hover { color: var(--color-primary); }
.att-name-unavailable { opacity: .5; cursor: default; }
.att-name-unavailable:hover { color: inherit; }
.att-meta { font-size: var(--text-sm); color: var(--slate-500); margin-top: 2px; }
.att-actions { display: flex; gap: 6px; align-items: center; }
.att-btn {
  border: 1px solid var(--blue-100); background: var(--blue-50); color: var(--blue-700);
  padding: 4px 9px; border-radius: var(--r-md); font-size: var(--text-sm); font-weight: 700;
  cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; gap: 4px; text-decoration: none;
  transition: background var(--t-fast);
}
.att-btn:hover { background: #e0e7ff; }
.att-btn.ghost { background: var(--color-surface); border-color: var(--color-border); color: var(--slate-600); }
.att-btn.ghost:hover { background: var(--color-surface-raised); }
.att-btn.danger { background: var(--red-50); border-color: var(--red-200); color: var(--red-600); }
.att-btn.danger:hover { background: var(--red-100); }
.att-btn-cover-on { background: var(--amber-50); border-color: var(--amber-200); color: var(--amber-800); }
.att-btn-cover-on:hover { background: var(--amber-100); }
.att-row-cover { background: var(--amber-50); border-radius: var(--r-md); }
.att-cover-preview { margin-bottom: 8px; }
.att-empty {
  border: 1px dashed var(--slate-300); border-radius: var(--r-lg);
  padding: 16px; font-size: var(--text-md); color: var(--slate-400); text-align: center;
}
.att-drop-wrap { border: 1px dashed var(--color-border); border-radius: var(--r-xl); padding: 6px; background: var(--color-surface-raised); }
.drop-zone {
  border: 2px dashed var(--slate-300); border-radius: var(--r-lg);
  padding: 14px; text-align: center; cursor: pointer;
  transition: all var(--t-base); font-size: var(--text-md); color: var(--slate-600); background: var(--color-surface);
}
.drop-zone:hover, .drop-zone.dragover { border-color: var(--color-primary); background: var(--blue-50); color: var(--color-primary); }
/* The drop zone's <input type="file" class="hidden"> relied on a .hidden
   utility that was never defined, so a stray native "Choose File" control
   rendered inside the zone (most visibly on mobile). The zone's click
   handler opens the picker programmatically — the input itself never needs
   to be visible. */
.drop-zone input[type="file"].hidden { display: none; }
.att-uploading { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); font-weight: 600; color: var(--color-primary); }
.spinner {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--slate-300); border-top-color: var(--color-primary);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.att-table { width: 100%; border-collapse: collapse; font-size: var(--text-md); }
.att-table th { padding: 5px var(--sp-2); font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; color: var(--slate-500); background: var(--color-surface-raised); border-bottom: 1px solid var(--color-border); text-align: left; }
.att-table td { padding: 6px var(--sp-2); border-bottom: 1px solid var(--color-border-light); vertical-align: middle; }
.att-table tr:last-child td { border-bottom: none; }

/* ── File Viewer ──────────────────────────────────────────────────────── */
.file-viewer {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(15,23,42,.88);
  display: flex; align-items: center; justify-content: center; padding: 30px;
}
.file-viewer-panel {
  width: min(960px, 96vw); height: min(85vh, 900px);
  background: var(--color-surface); border-radius: var(--r-2xl);
  box-shadow: 0 28px 64px rgba(15,23,42,.45);
  display: flex; flex-direction: column; overflow: hidden;
}
.file-viewer-bar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: 12px 18px; background: var(--slate-900); color: var(--slate-100);
}
.file-viewer-title { font-size: 15px; font-weight: 700; }
.file-viewer-actions { display: flex; gap: var(--sp-2); }
.file-viewer-frame { flex: 1; border: none; background: var(--color-surface); }

/* ── Autocomplete ─────────────────────────────────────────────────────── */
.ac-wrap { position: relative; }
.ac-dropdown {
  position: absolute; top: 100%; left: 0; right: 0; min-width: 220px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg); z-index: 100;
  max-height: 300px; overflow-y: auto;
}
.ac-item { padding: 7px 10px; font-size: 15px; cursor: pointer; transition: background var(--t-fast); }
.ac-item:hover { background: var(--blue-50); }

/* pill badges inside ac-item */
.pill-lead  { background: #dbeafe; color: #1e40af; }
.pill-owner { background: #fef3c7; color: #92400e; }
.pill-task  { background: #d1fae5; color: #065f46; }

/* ── WYSIWYG ──────────────────────────────────────────────────────────── */
.wysiwyg-wrap { border: 1px solid var(--color-border); border-radius: var(--r-md); overflow: hidden; }
.wysiwyg-toolbar { display: flex; gap: 2px; padding: 4px 6px; border-bottom: 1px solid var(--color-border); background: var(--color-surface-raised); flex-wrap: wrap; }
.wysiwyg-toolbar button { background: none; border: 1px solid transparent; border-radius: var(--r-xs); padding: 2px 5px; cursor: pointer; font-size: var(--text-base); color: var(--slate-600); font-family: inherit; transition: background var(--t-fast); }
.wysiwyg-toolbar button:hover { background: var(--slate-200); border-color: var(--slate-300); }
.wysiwyg-toolbar button.active { background: var(--blue-100); color: var(--blue-700); border-color: var(--blue-200); }
.wysiwyg-editor { min-height: 100px; padding: 8px 10px; font-size: var(--text-lg); line-height: 1.6; color: var(--color-text); outline: none; overflow-y: auto; }
.wysiwyg-editor:empty::before { content: attr(data-placeholder); color: var(--slate-400); }
.wysiwyg-editor p { margin: 0 0 0.6em 0; }
.wysiwyg-editor p:last-child { margin-bottom: 0; }
.wysiwyg-editor ul, .wysiwyg-editor ol { margin: 0 0 0.6em 0; padding-left: 1.6em; }
.wysiwyg-editor ul { list-style: disc; }
.wysiwyg-editor ol { list-style: decimal; }

/* ── Trix editor (lead/owner/task notes) ──────────────────────────────────
   Real editor that owns its own hidden <input>; replaces the hand-rolled
   contenteditable above for these three fields (comm still uses .wysiwyg-*). */
/* 🎤 dictate — injected by attachFieldDictation into every rich-text
   editor. In Trix it becomes a real toolbar button group appended after
   undo/redo (floating it over the corner covered those buttons); in the
   custom wysiwyg it's just another toolbar button, pushed to the right. */
.wysiwyg-toolbar > .field-mic { margin-left: auto; }
/* Live dictation preview. Floats over the bottom of the editor instead of
   being typed into it — the cleanup pass rewrites the whole utterance, so
   text in the field would only have to be taken back. Pointer-events off
   so it never blocks a click on the text underneath. */
.trix-wrap, .wysiwyg-wrap { position: relative; }
.dictate-live {
  position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 3;
  pointer-events: none; padding: 6px 10px; border-radius: var(--r-sm, 6px);
  background: rgba(15, 23, 42, .92); color: #fff;
  font-size: var(--text-sm); line-height: 1.4;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
  /* A long dictation must not be truncated mid-sentence. The chip grows to
     a few lines, then scrolls itself so the words just spoken stay visible
     — the JS pins it to the bottom on every update. Pointer-events are off,
     so this is the only way it can scroll. */
  max-height: 7.6em; overflow-y: auto; scrollbar-width: none;
}
.dictate-live::-webkit-scrollbar { display: none; }
.dictate-live[hidden] { display: none; }
/* Plain textareas / the Next step line have no toolbar to hang the mic on,
   so it floats in the top-right corner and the field reserves room for it —
   overlaying text was the mistake made with the Trix button. */
.dictate-wrap { position: relative; display: block; }
.dictate-wrap > .field-mic {
  position: absolute; top: 4px; right: 4px; z-index: 2;
  padding: 1px 6px; font-size: var(--text-sm); line-height: 1.3;
}
.dictate-wrap > textarea, .dictate-wrap > input { padding-right: 36px; }
.dictate-live--busy { font-style: italic; opacity: .85; }
.field-mic {
  background: none; border: 1px solid var(--slate-300); border-radius: var(--r-xs);
  padding: 2px 7px; font-size: var(--text-base); line-height: 1.4; cursor: pointer;
  font-family: inherit; color: var(--slate-600);
}
.field-mic:hover { background: var(--blue-50, #eff6ff); border-color: var(--blue-300, #93c5fd); }
.field-mic--on { background: #dc2626; border-color: #dc2626; color: #fff; font-weight: 700;
  box-shadow: 0 0 0 3px rgba(239, 68, 68, .3); }
.field-mic--busy { opacity: .7; }

.trix-wrap trix-toolbar { margin-bottom: 4px; }
/* Single-row toolbar; comfortable on desktop, compact on mobile (below). */
.trix-wrap trix-toolbar .trix-button-row { flex-wrap: nowrap; overflow-x: auto; }
.trix-wrap trix-toolbar .trix-button-group { margin: 0 6px 0 0; }
.trix-wrap trix-toolbar .trix-button { height: 1.8rem; padding: 0 0.5em; font-size: 0.8em; }
.trix-wrap trix-toolbar .trix-button--icon { width: 2.3em; }
/* The injected mic rides in its own group at the end of the row, so it
   never sits on top of undo/redo; height/font come from .trix-button.
   Pinned to the right edge and sticky: the row is nowrap + overflow-x
   auto, so in a narrow panel the last group scrolls out of sight and the
   mic looks absent — the one control here nothing else replaces. */
.trix-wrap trix-toolbar .trix-button-group--dictate {
  margin-right: 0;
  margin-left: auto;
  position: sticky;
  right: 0;
  background: inherit;
}
.trix-wrap trix-toolbar .field-mic { border: 0; border-radius: 0; padding: 0 0.5em; }
/* No upload handler is wired — hide attach/file tools so users can't insert
   un-uploadable attachments. */
.trix-wrap trix-toolbar .trix-button-group--file-tools { display: none; }
/* Drop the nesting (decrease/increase level) buttons — not needed for notes. */
.trix-wrap trix-toolbar [data-trix-action="decreaseNestingLevel"],
.trix-wrap trix-toolbar [data-trix-action="increaseNestingLevel"] { display: none; }
/* Mobile: shrink the toolbar so all buttons still fit on one row. */
@media (max-width: 768px) {
  .trix-wrap trix-toolbar .trix-button { height: 1.4rem; padding: 0 0.3em; font-size: 0.65em; }
  .trix-wrap trix-toolbar .trix-button--icon { width: 1.8em; }
}
.trix-wrap trix-editor {
  min-height: 200px; padding: 8px 10px; background: #fff;
  border: 1px solid var(--color-border); border-radius: var(--r-md);
  font-size: var(--text-lg); line-height: 1.6; color: var(--color-text);
  overflow-y: auto;
}

/* ── Related Items ────────────────────────────────────────────────────── */
/* table-layout: fixed — the declared column widths win and cell content
   truncates (the tds already ellipsize) instead of widening the table. With
   auto layout, nowrap content (status pills, user names) set a minimum table
   width that overflowed the panel sidebar's fixed-width card on smaller
   screens, pushing the × unlink column past the panel edge and giving the
   whole panel a horizontal scrollbar. */
.related-table { width: 100%; border-collapse: collapse; font-size: var(--text-md); margin-top: 6px; min-width: auto; table-layout: fixed; }
.related-table .status-pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; box-sizing: border-box; }
.related-table th { padding: 4px 6px; font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; color: var(--slate-500); background: var(--color-bg); border-bottom: 1px solid var(--color-border); text-align: left; overflow: hidden; text-overflow: ellipsis; }
.related-table td { padding: 5px 6px; border-bottom: 1px solid var(--color-border-light); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.related-table th:last-child, .related-table td:last-child { width: 50px; min-width: 50px; max-width: 50px; overflow: visible; white-space: normal; text-align: center; padding: 5px 2px; }
.related-table tr:last-child td { border-bottom: none; }
.related-table tr:hover td { background: var(--color-surface-raised); }

/* × button in related tables */
.related-table td:last-child button, .btn-unlink {
  background: none; border: none; color: var(--slate-400);
  cursor: pointer; font-size: 20px; font-weight: 700;
  line-height: 1; padding: 4px 6px; transition: color var(--t-base);
  display: inline-block !important; min-width: 24px; text-align: center;
}
.related-table td:last-child button:hover, .related-table tr:hover td:last-child button,
.btn-unlink:hover, .related-table tr:hover .btn-unlink { color: #ef4444; }
.related-link { color: var(--color-primary); font-weight: 600; cursor: pointer; text-decoration: none; }
.related-link:hover { text-decoration: underline; }

/* ── Toast ────────────────────────────────────────────────────────────── */
.toast { position: fixed; bottom: 24px; right: 24px; background: var(--slate-900); color: var(--slate-100); padding: 10px 18px; border-radius: var(--r-lg); font-size: 15px; font-weight: 600; z-index: 9999; box-shadow: var(--shadow-xl); }
.save-toast { background: var(--green-50); color: var(--green-700); border: 1px solid var(--green-200); border-radius: var(--r-sm); padding: 5px 10px; font-size: var(--text-base); font-weight: 600; display: inline-block; }
.error-msg { color: var(--color-danger); font-size: var(--text-base); font-weight: 600; margin-top: 4px; }
/* Phones: center the toast. With only `right:24px`, a long message (e.g. the
   contact-gate warning) stretches from the right edge and sits off-center on
   narrow screens like 375px. Symmetric left/right + centered text fills the
   width with equal margins (no transform, so Alpine's x-transition is safe). */
@media (max-width: 768px) {
  .toast { left: 12px; right: 12px; bottom: 16px; text-align: center; }
}

/* ── Type Badges ──────────────────────────────────────────────────────── */
.type-badge { display: inline-block; padding: 2px 7px; border-radius: var(--r-full); font-size: var(--text-xs); font-weight: 700; border: 1px solid; }
.type-task  { background: var(--purple-50);  color: var(--purple-700); border-color: var(--purple-200); }
.type-lead  { background: var(--green-50);   color: var(--green-700);  border-color: var(--green-200); }
.type-owner { background: var(--teal-50);    color: var(--teal-700);   border-color: var(--teal-200); }
.type-homelead { background: var(--chip-homelead-bg); color: var(--chip-homelead-text); border-color: var(--chip-homelead-border); }

/* ── Settings Panel ───────────────────────────────────────────────────── */
.settings-panel { width: min(900px, calc(100vw - 10px)); overflow-y: auto; }
.settings-section { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--r-lg); margin-bottom: var(--sp-3); overflow: hidden; }
.settings-hdr { padding: 10px 14px; border-bottom: 1px solid var(--color-border); font-size: var(--text-base); font-weight: 700; color: var(--color-text); background: var(--color-surface-raised); }
.settings-body { padding: 14px; }

/* ── Overdue Dashboard ────────────────────────────────────────────────── */
.od-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: var(--sp-3); }
/* Desktop: the summary cards + filters stack above the table pushed the tab
   past the viewport, so the page scrollbar appeared NEXT TO the table box's
   own — two vertical scrollbars side by side. Flex the tab to the viewport
   instead: cards and filters keep their natural height, the table box takes
   exactly what remains, and its scrollbar is the only one. Phones keep their
   own one-scroller rules (the max-width:768px block below). */
@media (min-width: 769px) {
  .main-content > [data-tab="overdue"] { height: 100%; }
  #overdue-content { display: flex; flex-direction: column; height: 100%; min-height: 0; }
  #overdue-content > .od-cards, #overdue-content > .od-filters { flex: none; }
  #overdue-content > .tbl-wrap { flex: 1 1 auto; min-height: 0; max-height: none; }
}
.od-card {
  background: var(--color-surface); border-radius: var(--r-lg); padding: 12px 14px;
  cursor: pointer; border: 2px solid; transition: border-color var(--t-base), box-shadow var(--t-base);
  box-shadow: var(--shadow-xs);
}
.od-card:hover { box-shadow: var(--shadow-md); }
/* Selected state when a card is acting as the active type filter. */
.od-card--active { background: var(--blue-50); box-shadow: 0 0 0 2px var(--blue-500), var(--shadow-md); }
.od-card-num { font-size: 28px; font-weight: 900; line-height: 1; }
.od-card-label { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .5px; margin-top: 3px; }
.od-card-clear { font-size: var(--text-2xs); color: var(--green-700); margin-top: 2px; }
.od-card--task  .od-card-num, .od-card--task  .od-card-label { color: var(--red-600); }
.od-card--lead  .od-card-num, .od-card--lead  .od-card-label { color: #c2410c; }
.od-card--owner .od-card-num, .od-card--owner .od-card-label { color: var(--amber-700); }
.od-card--homelead .od-card-num, .od-card--homelead .od-card-label { color: #be185d; }
.od-load-more td { padding: var(--sp-2); text-align: center; color: var(--slate-400); font-size: var(--text-xs); }
.od-empty-state {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-lg); padding: 40px; text-align: center;
}
.od-empty-state-icon { font-size: 32px; margin-bottom: 8px; }
.od-empty-state-text { font-size: var(--text-lg); font-weight: 700; color: var(--color-text); }
.od-filters { display: flex; gap: 7px; margin-bottom: 10px; flex-wrap: wrap; }
.od-search { width: 200px; }
.od-subject  { font-weight: 600; font-size: var(--text-sm); }
.od-due-date { color: var(--red-600); font-weight: 700; font-size: var(--text-xs); }
.od-status-item {
  padding: 7px 14px; cursor: pointer; font-size: var(--text-sm); color: var(--slate-700);
  transition: background var(--t-fast);
}
.od-status-item:hover { background: var(--slate-100); }

/* ── Login ────────────────────────────────────────────────────────────── */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--slate-100) 0%, #eef2ff 100%);
}
.login-box {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--r-2xl); padding: 36px 32px;
  width: 380px; box-shadow: var(--shadow-xl);
}
.login-logo { text-align: center; margin-bottom: 22px; }
.login-logo img { height: 48px; }
.login-title { font-size: var(--text-2xl); font-weight: 700; color: var(--color-text); text-align: center; margin-bottom: 22px; }
.login-error {
  background: var(--red-50); border: 1px solid var(--red-200);
  border-radius: var(--r-md); padding: 10px 12px; margin-bottom: 14px;
  color: var(--red-600); font-size: var(--text-sm); font-weight: 600;
}
.login-form-field { margin-bottom: 14px; }
.login-form-field-last { margin-bottom: 22px; }
.login-submit { width: 100%; padding: 11px; font-size: var(--text-md); }

/* ── Leaflet Overrides ────────────────────────────────────────────────── */
.leaflet-container { border-radius: 0 !important; }
.leaflet-popup-content-wrapper { border-radius: var(--r-xl) !important; padding: 0 !important; overflow: hidden; box-shadow: 0 8px 30px rgba(0,0,0,.18) !important; }
.leaflet-popup-content { margin: 0 !important; min-width: 200px; }
.leaflet-popup-tip { display: none; }
/* Outlook-generated email bodies ship a <style>a:link{color:blue;
   text-decoration:underline}</style> that leaks to the whole page
   (rendered inline without shadow/iframe isolation). Leaflet's zoom
   +/- are <a> tags, so they get browser-blue + underlined unless we
   force them back to Leaflet's default look. Scoped to .leaflet-bar
   descendants so it only touches map chrome, not app links. */
.leaflet-bar a, .leaflet-bar a:link, .leaflet-bar a:visited,
.leaflet-bar a:hover, .leaflet-bar a:active {
  color: #333 !important;
  text-decoration: none !important;
}

/* ── Inline field row grids (used inside panels) ─────────────────────── */
.field-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.field-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.field-row-4 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 8px; }
.field-row-1-1-2 { display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 8px; }

/* ── Mobile ───────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* Chrome's table-layout: fixed algorithm still factors in inline `width`
     hints on display:none cells (legacy quirk), so we explicitly zero them
     to keep fixed-width layouts from stealing space from the title column. */
  .hide-mobile { display: none !important; width: 0 !important; min-width: 0 !important; max-width: 0 !important; }
  .app-header { height: 44px; padding: 0 10px; }
  .logo { height: 28px; }
  .header-right { gap: 5px; }
  .header-search { max-width: 160px; margin: 0 var(--sp-2); }
  .header-search-input { font-size: var(--text-xs); }
  .global-search-results {
    position: fixed;
    top: 44px;
    left: 8px;
    right: 8px;
    max-height: 60vh;
    border-radius: var(--r-lg);
  }
  .search-result-item {
    min-height: 44px;
    padding: 10px 14px;
    flex-wrap: wrap;
    gap: 4px;
  }
  .search-result-badges { flex-wrap: wrap; }
  .search-result-name { min-width: 0; }
  .search-result-lead-pill { max-width: 100px; }
  .main-tabs { padding: 0 var(--sp-2); }
  .tab { padding: 8px 9px; font-size: var(--text-base); }
  .main-content { padding: var(--sp-2); max-width: 100vw; }
  .tab-toolbar { margin-bottom: 6px; }
  .btn-primary, .btn-secondary { font-size: var(--text-base); padding: 4px var(--sp-2); }
  .btn-open { background: none; color: var(--blue-700); padding: 4px 6px; font-size: 18px; line-height: 1; }
  .btn-open .btn-open-text { display: none; }
  .btn-open .btn-open-arrow { display: inline; }
  .mobile-sub { display: flex; gap: 4px; align-items: center; margin-top: 1px; padding-bottom: 0; flex-wrap: wrap; font-size: 11px; color: #6b7280; }
  .mobile-sub .msub-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; }
  .mobile-sub .msub-item--overdue { color: #dc2626; font-weight: 700; }
  .mobile-sub .msub-pill { font-size: 10px; padding: 1px 5px; max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.3; }
  .comms-subject-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; max-width: 60vw; }
  .comms-subject-cell { max-width: none !important; position: relative; }
  .comms-table { border-collapse: separate; border-spacing: 0; }
  .comms-table td { border: none; }
  /* One thin divider between comm rows (on the pills-row's bottom) — the
     main row keeps 4px of breathing room above its content. The previous
     2px top + 1px bottom stack added ~13px between rows on mobile. */
  .comms-table .row-clickable td { padding-top: 4px; padding-bottom: 0; }
  .comms-table tbody tr:first-child td { border-top: none; }
  .comms-table .msub-pills-row { display: table-row; }
  .comms-table .msub-pills-row td {
    border: none !important;
    border-bottom: 1px solid var(--color-border) !important;
    /* Match the 10px left padding of the base td rule so chips align
       under the subject text instead of running flush to the cell edge.
       Some rows otherwise render the pills row visibly indented further
       left than the row above, reading as a broken layout. */
    padding: 0 10px 4px 10px !important;
    box-sizing: border-box;
  }
  .msub-pills-wrap { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin: 0; padding: 0; min-width: 0; max-width: 100%; }
  .msub-pills-wrap .msub-pill { max-width: 100%; flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; display: inline-flex; align-items: center; gap: 2px; border: none; }
  .msub-pill-x { flex-shrink: 0; font-size: 14px; line-height: 1; opacity: 0.5; background: none; border: none; padding: 2px 4px; cursor: pointer; min-width: 24px; min-height: 24px; display: inline-flex; align-items: center; justify-content: center; }
  /* On mobile the add-linker chips live inside .mobile-sub (subject cell).
     Hide the new pills-row linkers so they don't duplicate. */
  .comms-table .msub-pills-row .msub-linker-wrap { display: none; }
  .msub-pill-x:hover { opacity: 1; }
  .msub-linker-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
  .msub-linker-wrap--open { flex-grow: 1; min-width: 100px; }
  .msub-linker-input {
    font-size: 10px; padding: 4px 8px; border-radius: 10px;
    border: none;
    background: transparent; cursor: pointer; width: 52px; text-align: center;
    line-height: 1.3; font-weight: 500; outline: none;
    -webkit-appearance: none; appearance: none;
    min-height: 24px;
  }
  .msub-linker-wrap--open .msub-linker-input { width: 100%; text-align: left; border: 1px solid; border-bottom: none; }
  .msub-linker-input.chip-lead { border-color: var(--chip-lead-border); color: var(--chip-lead-text); }
  .msub-linker-input.chip-lead:focus { background: var(--chip-lead-bg); }
  .msub-linker-input.chip-owner { border-color: var(--chip-owner-border); color: var(--chip-owner-text); }
  .msub-linker-input.chip-owner:focus { background: var(--chip-owner-bg); }
  .msub-linker-input.chip-task { border-color: var(--chip-task-border); color: var(--chip-task-text); }
  .msub-linker-input.chip-task:focus { background: var(--chip-task-bg); }
  /* "+Home Lead" is the longest collapsed label — the shared 52px input
     width clips it, so give this one chip room to show the full label. */
  .msub-linker-input.chip-homelead { border-color: var(--chip-homelead-border); color: var(--chip-homelead-text); width: 84px; }
  .msub-linker-input.chip-homelead:focus { background: var(--chip-homelead-bg); }
  /* max-height: none — on mobile the wrapper is overflow:visible and the whole
     page scrolls, so the desktop `max-height: calc(100vh - 155px)` (line ~715)
     would cap the bordered frame mid-list while rows spill out below it. Same
     fix the overdue tab already carries (#overdue-content .tbl-wrap). */
  .tbl-wrap--comms { overflow: visible; max-height: none; }
  .comms-subject-cell { overflow: visible !important; }
  .comms-subject-cell .msub-linker-wrap { display: inline-flex !important; }
  .comms-table { overflow: visible; table-layout: auto !important; width: 100% !important; }
  .msub-linker-wrap .ac-dropdown { z-index: 200; }
  .mobile-sub .mobile-field-row { display: flex; gap: 4px; width: 100%; margin-top: 4px; flex-wrap: wrap; }
  .mobile-field { font-size: 11px; padding: 3px 5px; border: 1px solid #d1d5db; border-radius: 4px; background: #fff; color: #111827; }
  .mobile-field:focus { border-color: #93c5fd; outline: none; }
  .mobile-field--date { width: 110px; }
  .mobile-field--select { max-width: 100px; }
  .mobile-field--text { flex: 1; min-width: 80px; }
  .mobile-only { display: inline-flex !important; }
  .mobile-only-th { display: table-cell !important; }
  .mobile-only-td { display: table-cell !important; }
  .mobile-only-th > *, .mobile-only-td > * { display: inline-block !important; }
  .user-avatar { display: inline-flex; align-items: center; justify-content: center; }
  table.data-table th:first-child, table.data-table td:first-child { width: auto; }
  th { padding: 6px; font-size: var(--text-xs); }
  td { padding: 6px; font-size: var(--text-base); }
  .th-search { width: 64px; min-width: 0; font-size: var(--text-xs); padding: 2px 4px; }
  /* Primary column (title/name/subject) gets a wider search box — twice the
     default. Long-tail tables (Leads/Owners/Tasks/Contacts have it in col 1;
     Comms has subject in col 2). */
  .leads-table th:first-child .th-search,
  .owners-table th:first-child .th-search,
  .tasks-table th:first-child .th-search,
  .homeleads-table th:first-child .th-search,
  .contacts-table th:first-child .th-search,
  .comms-table th:nth-child(2) .th-search { width: 128px !important; }
  /* Secondary filter (status/user/company on the right) — right-aligned within
     its cell so the field hugs the column edge, plus `direction: rtl` so the
     native <select>'s options popup opens leftward (away from the viewport
     edge) instead of getting clipped on the right. We restore LTR on the
     option text so labels still read normally. */
  .leads-table th:nth-child(2) .th-search,
  .owners-table th:nth-child(2) .th-search,
  .tasks-table th:nth-child(2) .th-search,
  .homeleads-table th:nth-child(3) .th-search,
  .comms-table .mobile-only-th .th-search,
  .contacts-table th:nth-child(2) .th-search {
    margin-left: auto !important; display: block !important;
    text-align: right;
  }
  /* Right-aligned select. `direction: rtl` flips the writing mode so the
     native dropdown options popup opens leftward (away from the viewport
     edge) instead of right (which clips on a 375px screen). To keep the
     chevron visually on the right, we use the `right 8px center` keyword
     form for `background-position` — that's anchored to the physical right
     edge regardless of `direction`. (`calc(100% - X)` would flip with rtl
     and put the chevron on the visual left, which is what we don't want.) */
  .leads-table th:nth-child(2) select.th-search,
  .owners-table th:nth-child(2) select.th-search,
  .tasks-table th:nth-child(2) select.th-search,
  .homeleads-table th:nth-child(3) select.th-search,
  .comms-table .mobile-only-th select.th-search {
    direction: rtl; text-align-last: right;
    padding-right: 18px !important; padding-left: 4px !important;
    background-position: right 14px center, right 8px center !important;
  }
  /* Restore LTR for option labels so they read normally in the popup. */
  .leads-table th:nth-child(2) select.th-search option,
  .owners-table th:nth-child(2) select.th-search option,
  .tasks-table th:nth-child(2) select.th-search option,
  .homeleads-table th:nth-child(3) select.th-search option,
  .comms-table .mobile-only-th select.th-search option { direction: ltr; text-align: left; }
  .col-count { font-size: var(--text-sm); }

  /* ── Prevent all tables from causing horizontal scroll ── */
  .main-content { padding-left: var(--sp-2); padding-right: var(--sp-2); overflow-x: hidden; }
  .tbl-wrap { overflow-x: hidden; -webkit-overflow-scrolling: touch; max-width: 100%; box-sizing: border-box; }
  .tbl-wrap--comms { overflow-x: visible !important; }
  /* ONE scroller on a phone. The base rule boxes every table in its own
     `max-height: calc(100vh - 155px)` + `overflow: auto`, which on a phone
     means the rows scroll INSIDE the box and .main-content never overflows
     at all — its scrollTop is pinned at 0 forever.
     Two things break as a result. Reaching the top of the inner box, the
     drag chains outward with nothing left to scroll. And pull-to-refresh
     guards itself with `mainContent.scrollTop <= 0`, which is now always
     true, so it arms on every touch anywhere on the page: dragging DOWN to
     scroll back up became a pull, and past its threshold it refreshed the
     tab and threw the operator back to the top. Reported as "I scroll down
     all the way and I can't scroll back up — it thinks I'm refreshing."
     The overdue tab was already exempted for a layout reason (rule further
     down, unchanged); every table needs it, for this one. */
  .tbl-wrap { max-height: none; overflow-y: visible; }
  table { min-width: 0 !important; width: 100% !important; max-width: 100% !important; table-layout: auto !important; box-sizing: border-box; }
  table.data-table { table-layout: auto !important; width: 100% !important; max-width: 100% !important; }
  table.data-table th, table.data-table td { min-width: 0; overflow: hidden; text-overflow: ellipsis; word-break: break-word; box-sizing: border-box; }

  /* ── Status column across all tables — keep visible on mobile ──
     Force table-layout: fixed (outranks the `table.data-table { table-layout:
     auto !important }` mobile rule by adding a second class to the selector).
     With fixed layout: col1 (title) takes remaining space automatically, col2
     (status) is pinned to 96px, and `overflow:hidden`/`text-overflow:ellipsis`
     work on cells. The first-child rule below intentionally sets NO width so
     the browser distributes remaining space to it. */
  table.leads-table.data-table,
  table.owners-table.data-table,
  table.tasks-table.data-table { table-layout: fixed !important; }
  .leads-table td:nth-child(2),
  .owners-table td:nth-child(2),
  .tasks-table td:nth-child(2) {
    width: 96px !important; text-align: right; white-space: nowrap; vertical-align: middle; padding: 4px !important; box-sizing: border-box; overflow: hidden !important;
  }
  .leads-table th:nth-child(2),
  .owners-table th:nth-child(2),
  .tasks-table th:nth-child(2) { width: 96px !important; text-align: right; padding: 4px !important; box-sizing: border-box; overflow: hidden !important; }
  .leads-table td:nth-child(2) .status-pill,
  .owners-table td:nth-child(2) .status-pill,
  .tasks-table td:nth-child(2) .status-pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; display: inline-block; vertical-align: middle; font-size: 10px; }
  .leads-table td:nth-child(2) .field-select,
  .owners-table td:nth-child(2) .field-select,
  .tasks-table td:nth-child(2) .field-select { font-size: 10px; padding: 2px 4px; max-width: 100%; }

  /* ── Comms table mobile columns ── */
  .comms-table th:first-child,
  .comms-table td:first-child { width: 32px !important; padding: 2px 4px !important; max-width: 48px !important; }
  .comms-table th:first-child .sort-btn { display: none; }
  .comms-table th:first-child { vertical-align: bottom !important; }
  .comms-table th:first-child .th-search { width: 40px !important; min-width: 0 !important; font-size: 9px; padding: 2px; }
  /* Mobile first column = channel icon only. Hide every span after the icon
     (the channel word, and the call-outcome pill) — keyed off :not(:first-child)
     rather than :last-child so a trailing call-outcome pill can't make the word
     leak through on call rows. */
  .comms-table td:first-child > span:not(:first-child) { display: none; }
  /* Open-col (delete X) is moved INTO the mobile-sub flex line on small screens so
     the X sits next to the linker chips instead of leaving an empty right-edge
     column. Hide the original cell entirely so the table doesn't reserve space. */
  .comms-table .open-col,
  .comms-table th.open-col { display: none !important; }
  .comms-table .btn-danger { font-size: 14px; padding: 2px 5px; min-width: 0; }
  .comms-table .msub-delete-btn { font-size: 13px; padding: 1px 6px; line-height: 1; }

  /* ── Overdue table — keep Status column visible ── */
  #overdue-content table { table-layout: fixed !important; }
  /* The overdue tab has stat cards + a search row above the table, so the
     table's own `max-height: calc(100vh - 155px)` (tuned for the card-less
     leads/owners/tasks tabs) overflows .main-content and produces a second
     scrollbar. Scope-fix: let the overdue table flow inside the single
     .main-content scroller. Other tabs keep their own table scroll. */
  #overdue-content .tbl-wrap { max-height: none; overflow-y: visible; }

  /* ── Leads / Owners / Tasks — title cell takes remaining space ──
     With table-layout: fixed, Chrome won't distribute remaining width to
     "auto" cells when other cells have explicit pixel widths — col1 collapses
     to min-content (~32px). And `calc(100% - X)` doesn't resolve correctly
     for table cell widths in fixed layout (parent reference is fuzzy), but
     `calc(100vw - X)` does. We size col1 against viewport minus:
       16px (main padding) + 96px (status col) + 8px (table border + safety). */
  .leads-table th:first-child,
  .owners-table th:first-child,
  .tasks-table th:first-child { width: calc(100vw - 120px) !important; overflow: hidden; text-overflow: ellipsis; word-break: break-word; }
  .leads-table td:first-child,
  .owners-table td:first-child,
  .tasks-table td:first-child { overflow: hidden; text-overflow: ellipsis; word-break: break-word; }
  .tasks-table th:nth-child(2) { text-align: right; }
  .tasks-table th:nth-child(2) .sort-btn { justify-content: flex-end; }
  .tasks-table th:nth-child(2) .th-search { width: 100%; max-width: 100%; float: right; overflow: hidden; text-overflow: ellipsis; }
  .tasks-table td:first-child .table-field { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* ── Contacts table mobile columns ──
     At 375px there is no room for 3 inline-edit inputs side by side without
     squeezing each to ~10 chars. Hide Trade on mobile (still in mobile-sub of
     the Name cell) so Name and Company get usable widths. */
  .contacts-table th:nth-child(3),
  .contacts-table td:nth-child(3) { display: none !important; }
  .contacts-table th:first-child,
  .contacts-table td:first-child { width: 58%; }
  .contacts-table th:nth-child(2),
  .contacts-table td:nth-child(2) { width: 42%; }
  .contacts-table th, .contacts-table td { overflow: hidden; text-overflow: ellipsis; }
  .contacts-table .contacts-inline-input { font-size: 12px; padding: 4px 6px; width: 100%; min-width: 0; }
  .contacts-table .contact-row-actions .btn-secondary { padding: 3px 6px; font-size: 10px; }

  /* ── Overdue table mobile columns ── */
  /* Wide enough for the two-word "Home Lead" badge: at 52px it overflowed the
     fixed-layout cell (nowrap) and overlapped the Subject column. */
  #overdue-content table th:first-child,
  #overdue-content table td:first-child { width: 68px; min-width: 68px; padding-right: 6px !important; }
  /* Belt-and-suspenders: keep the badge inside its cell whatever the label. */
  #overdue-content .type-badge { font-size: 9px; padding: 1px 6px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  #overdue-content table th:nth-child(2),
  #overdue-content table td:nth-child(2) { overflow: hidden; text-overflow: ellipsis; word-break: break-word; padding-left: 4px !important; }
  #overdue-content table th:last-child,
  #overdue-content table td:last-child { width: 110px; text-align: right; white-space: nowrap; overflow: hidden !important; }
  #overdue-content table td:last-child .status-pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; display: inline-block; }
  /* SUBJECT (col 2) absorbs the leftover width so table-layout:fixed doesn't
     leave an empty strip on the right — Chrome won't auto-distribute it to two
     "auto" columns. NEXT STEP gets a fixed width so SUBJECT is the only
     flexible one. Mirrors the leads/owners/tasks calc(100vw - …) fix above.
     286px = 68 (type) + 84 (next step) + 110 (status) + ~24 (padding/border). */
  #overdue-content table th:nth-child(2),
  #overdue-content table td:nth-child(2) { width: calc(100vw - 286px) !important; }
  #overdue-content table th:nth-child(4),
  #overdue-content table td:nth-child(4) { width: 84px; overflow: hidden; text-overflow: ellipsis; }

  .table-field { width: 100%; }
  .table-field--date { width: 110px; }
  .table-field--select { width: 100%; }
  .table-field--wide { width: 100%; }
  .th-search { min-width: 0; }
  .lead-title-wrap { max-width: 100%; min-width: 0; display: flex; align-items: center; gap: 6px; }
  .lead-title-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; min-width: 0; flex: 1; }
  /* Status pill must respect its column width on mobile so long statuses
     ellipsize cleanly instead of being hard-clipped by the cell. */
  .status-pill { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; font-size: 10px; padding: 2px 5px; }
  #overdue-content .status-pill { max-width: 100%; font-size: 10px; padding: 2px 5px; }
  td.open-col, th.open-col { width: 28px !important; min-width: 28px !important; white-space: nowrap; padding: 2px 4px !important; }

  .panel-backdrop { justify-content: stretch; align-items: stretch; padding: 0; }
  .panel-inner { width: 100vw !important; max-width: 100vw !important; height: 100% !important; border-radius: 0; }
  .panel-vtab-bar { display: none !important; }
  .panel-header { padding: 8px 10px; flex-wrap: wrap; gap: 6px; }
  .panel-title { font-size: 15px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .panel-subtitle { font-size: var(--text-xs); }
  .panel-header-actions { gap: 4px; flex-shrink: 0; }
  .btn-panel-save { padding: 4px 9px; font-size: var(--text-base); }
  .btn-panel-close { padding: 3px 7px; font-size: var(--text-md); }
  .btn-panel-delete { padding: 3px 6px; font-size: var(--text-sm); }
  .panel-main { padding: var(--sp-2); gap: var(--sp-2); }
  .panel-sidebar { padding: var(--sp-2); gap: var(--sp-2); }
  .panel-content > form { min-width: 0; overflow-x: clip; }
  .panel-two-col { min-width: 0; overflow-x: clip; }
  .panel-main { min-width: 0; overflow-x: clip; }
  .panel-sidebar { min-width: 0; overflow-x: clip; }
  .related-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -2px; padding: 0 2px; }
  .related-table { min-width: 420px; }
  .od-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
  .od-card { padding: 5px 6px; min-height: 56px; }
  .od-card-num { font-size: 18px; }
  .od-card-label { font-size: 9px; margin-top: 1px; letter-spacing: 0; }
  .od-card-clear { display: none; }
  .od-filters { gap: 6px; flex-wrap: wrap !important; }
  .od-search { width: 145px !important; min-width: 145px; }
  .od-filters .btn-secondary { padding: 4px var(--sp-2); font-size: var(--text-base); white-space: nowrap; }

  .top-bar-row { padding: 6px var(--sp-2); gap: 6px; }
  .collapsible-hdr { padding: 6px var(--sp-2); font-size: var(--text-xs); }
  .collapsible-body { padding: var(--sp-2); }
  .field-grid { grid-template-columns: repeat(3, 1fr) !important; }
  .field-grid-2, .field-grid-4 { grid-template-columns: 1fr 1fr !important; }
  .field-row-2 { grid-template-columns: 1fr 1fr !important; }
  .field-row-3 { grid-template-columns: 1fr 1fr 1fr !important; }
  .field-row-4 { grid-template-columns: 1fr 1fr !important; }
  .field-row-1-1-2 { grid-template-columns: 1fr 1fr 1fr !important; }
  .field-label { font-size: var(--text-sm); margin-bottom: 3px; }
  .field-input, .field-select, .field-textarea { font-size: var(--text-md); padding: 6px var(--sp-2); }
  .field-select { height: 30px; }
  .comm-card-hdr { padding: 6px var(--sp-2); gap: 6px; }
  .comm-card-body { padding: var(--sp-2); font-size: var(--text-base); }
  .top-bar-row { grid-template-columns: 1fr !important; }
  /* Fields stack to one column on mobile — collapse the quick-fill grid too so
     the buttons sit full-width under the From/To fields instead of in a stray
     middle column. */
  .qf-fill { grid-template-columns: 1fr !important; }
  .qf-actions { grid-column: 1 !important; }
  /* Owner / Task panels: keep Status and User side-by-side on mobile, with the
     Due Date field dropping to its own full-width row below (so the date +
     inline Clear button have room, same as the lead panel). */
  .top-bar-row.top-bar-row--meta-sud { grid-template-columns: 1fr 1fr !important; }
  .top-bar-row--meta-sud > .meta-due-cell { grid-column: 1 / 3; }
  /* Task panel: keep Scheduled and Scheduled End side-by-side on mobile. The
     cells are half-width, where a native date input won't shrink enough for an
     inline Clear button, so let each wrap drop its Clear button to a line below
     the field (right-aligned) where it stays visible. */
  .top-bar-row.top-bar-row--sched { grid-template-columns: 1fr 1fr !important; }
  .top-bar-row--sched .date-input-wrap { flex-wrap: wrap; }
  .top-bar-row--sched .date-input-wrap .field-input { flex-basis: 100%; }
  .top-bar-row--sched .date-input-wrap .date-clear-btn { margin-left: auto; }
  /* Mobile re-layout of the 8 price/meta fields into 3 even rows:
       Status | User
       Asking | Offered | Due Date
       Acres  | MH Zoning | Listed
     The two source rows go display:contents so their children become items
     of the .top-bar-fields grid; explicit row/column keeps it deterministic.
     (The grid-template-columns rules below are the no-display:contents
     fallback for the two rows and are otherwise inert here.) */
  .top-bar-row.top-bar-row--status { grid-template-columns: 1fr 1fr 1fr !important; }
  .top-bar-row.top-bar-row--prices { grid-template-columns: 1fr 1fr !important; }
  .top-bar-fields {
    display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 6px; padding: 6px var(--sp-2); align-items: end;
  }
  .top-bar-fields .top-bar-row--status,
  .top-bar-fields .top-bar-row--prices { display: contents; }
  .top-bar-fields .tbf { min-width: 0; }
  .tbf-status  { grid-row: 1; grid-column: 1 / 7; }
  .tbf-user    { grid-row: 1; grid-column: 7 / 13; }
  /* Asking/Offered split a row; Due Date gets its OWN full-width row below.
     A native date input refuses to shrink below its intrinsic width on
     mobile, so in a half-width cell the inline Clear button overflowed and
     was clipped by the panel's overflow-x: clip — invisible. A full-width
     row leaves room for the date AND the Clear button on one line. */
  .tbf-asking  { grid-row: 2; grid-column: 1 / 7; }
  .tbf-offered { grid-row: 2; grid-column: 7 / 13; }
  .tbf-due     { grid-row: 3; grid-column: 1 / 13; }
  /* MH Zoning takes the wide middle; Listed (a checkbox) needs little, Acres unchanged. */
  .tbf-acres   { grid-row: 4; grid-column: 1 / 5; }
  .tbf-mhz     { grid-row: 4; grid-column: 5 / 11; }
  .tbf-listed  { grid-row: 4; grid-column: 11 / 13; }
  .date-clear-btn { padding: 4px 6px; font-size: var(--text-sm); }
  .panel-content > form { padding-bottom: calc(80px + env(safe-area-inset-bottom, 16px)); }

  .login-box { width: calc(100vw - 32px); padding: 28px 20px; }
}

/* ── Silent HTMX refresh transitions (avoid white flash while swapping) ─── */
.htmx-added {
  animation: htmxFadeIn 120ms ease-in;
}
@keyframes htmxFadeIn {
  from { opacity: var(--refresh-fade-start); }
  to   { opacity: 1; }
}

/* ── Pill-link styles for comm panel related items ────────────────────── */
.pill-link {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--color-surface-raised); color: var(--slate-800);
  border: 1px solid transparent; padding: 3px var(--sp-2);
  border-radius: var(--r-full); font-size: var(--text-base); font-weight: 600;
}
.pill-link button, button.pill-link { cursor: pointer; }
.pill-link.pill-xs { font-size: var(--text-xs); padding: 2px 6px; }
.pill-link .related-link { cursor: pointer; }
.pill-link .related-link:hover { text-decoration: underline; }
.btn-unlink-pill {
  background: none; border: none; color: var(--slate-400);
  cursor: pointer; font-weight: 800; font-size: 15px;
  line-height: 1; padding: 0 2px; transition: color var(--t-base);
}
.btn-unlink-pill:hover { color: #ef4444; }

/* ── Touch-tap tooltip (first-tap-shows-title pattern on touch) ────────── */
.touch-tooltip {
  position: fixed;
  background: rgba(17, 24, 39, 0.95);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  padding: 6px 10px;
  border-radius: 6px;
  max-width: 260px;
  word-wrap: break-word;
  white-space: normal;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  pointer-events: none;
  z-index: 99999;
  animation: touchTipFadeIn 120ms ease-out;
}
.related-link[data-tip-primed] {
  outline: 2px solid var(--blue-500, #3b82f6);
  outline-offset: 1px;
  border-radius: 3px;
}
@keyframes touchTipFadeIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Skeleton Loading ────────────────────────────────────────────────── */
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.skeleton-loader { padding: 16px; }
.skeleton-bar {
  height: 12px; border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--slate-100) 25%, var(--slate-200) 50%, var(--slate-100) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.6s ease-in-out infinite;
}
.skeleton-bar-lg  { height: 18px; }
.skeleton-bar-sm  { height: 10px; }
.skeleton-circle {
  width: 32px; height: 32px; border-radius: 50%;
  background: linear-gradient(90deg, var(--slate-100) 25%, var(--slate-200) 50%, var(--slate-100) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.6s ease-in-out infinite;
  flex-shrink: 0;
}

/* Table skeleton */
.skeleton-table { width: 100%; border-collapse: collapse; }
.skeleton-table th {
  padding: 10px 12px; background: var(--color-surface-raised);
  border-bottom: 1px solid var(--color-border);
}
.skeleton-table td { padding: 12px; border-bottom: 1px solid var(--color-border-light); }
.skeleton-table tr:last-child td { border-bottom: none; }

/* Panel skeleton */
.skeleton-panel { padding: 20px; }
.skeleton-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 18px; border-bottom: 1px solid var(--slate-700);
  background: var(--slate-800);
}
.skeleton-panel-header .skeleton-bar {
  background: linear-gradient(90deg, rgba(255,255,255,.08) 25%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.08) 75%);
  background-size: 800px 100%;
}
.skeleton-panel-body {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: 20px;
}
.skeleton-field { display: flex; flex-direction: column; gap: 6px; }
@media (max-width: 768px) {
  .skeleton-panel-body { grid-template-columns: 1fr; }
}

/* ── Delete-confirm modal (relink-before-delete) ─────────────────────────── */
.delete-modal-backdrop {
  position: fixed; inset: 0; z-index: 1300;
  background: rgba(15,23,42,.55);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.delete-modal-panel {
  width: min(520px, 96vw); max-height: min(85vh, 720px);
  background: var(--color-surface); border-radius: var(--r-2xl);
  box-shadow: 0 28px 64px rgba(15,23,42,.45);
  display: flex; flex-direction: column; overflow: hidden;
}
.delete-modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: 14px 18px; background: #fef2f2; border-bottom: 1px solid #fecaca;
}
.delete-modal-title { font-size: 15px; font-weight: 700; color: #991b1b; line-height: 1.3; }
.delete-modal-close {
  background: transparent; border: 0; font-size: 22px; line-height: 1;
  color: #991b1b; cursor: pointer; padding: 2px 6px; border-radius: 4px;
}
.delete-modal-close:hover { background: rgba(220,38,38,.12); }
.delete-modal-body { padding: 16px 18px; overflow-y: auto; }
.delete-modal-summary { font-size: 13px; color: var(--slate-700); line-height: 1.5; }
.delete-modal-summary-plain { padding: 4px 0; }
.delete-modal-summary-label { font-weight: 600; margin-bottom: 6px; color: var(--slate-800); }
.delete-modal-counts { margin: 0 0 10px 18px; padding: 0; }
.delete-modal-counts li { margin: 2px 0; }
.delete-modal-summary-hint { font-size: 12px; color: var(--slate-600); margin-top: 8px; }

.delete-modal-picker { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--slate-200); }
.delete-modal-picker-label {
  display: block; font-size: 12px; font-weight: 600; color: var(--slate-700);
  margin-bottom: 6px; text-transform: uppercase; letter-spacing: .03em;
}
.delete-modal-search {
  width: 100%; box-sizing: border-box; padding: 8px 10px;
  border: 1px solid var(--slate-300); border-radius: 6px; font-size: 13px;
  background: var(--color-surface);
}
.delete-modal-search:focus { outline: 2px solid var(--slate-400); outline-offset: 1px; }
.delete-modal-results {
  margin-top: 6px; max-height: 200px; overflow-y: auto;
  border: 1px solid var(--slate-200); border-radius: 6px; background: var(--slate-50);
}
.delete-modal-results:empty { display: none; }
.delete-modal-result {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 6px 10px; background: transparent; border: 0;
  border-bottom: 1px solid var(--slate-200); cursor: pointer; text-align: left;
  font-size: 13px; color: var(--slate-800);
}
.delete-modal-result:last-child { border-bottom: 0; }
.delete-modal-result:hover { background: var(--slate-100); }
.delete-modal-result-id { font-size: 11px; color: var(--slate-500); font-family: ui-monospace,Menlo,Consolas,monospace; }
.delete-modal-result-empty { padding: 8px 10px; font-size: 12px; color: var(--slate-500); font-style: italic; }
.delete-modal-section + .delete-modal-section { border-top: 1px solid var(--slate-200); }
.delete-modal-section-label {
  padding: 4px 10px; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--slate-500); background: var(--slate-100);
}

.delete-modal-selected { margin-bottom: 6px; }
.delete-modal-selected-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 4px; background: #dcfce7; color: #14532d;
  border: 1px solid #86efac; border-radius: 999px; font-size: 12px; font-weight: 600;
}
.delete-modal-selected-type {
  text-transform: uppercase; font-size: 10px; letter-spacing: .04em;
  background: #14532d; color: #dcfce7; padding: 2px 6px; border-radius: 999px;
}
.delete-modal-selected-pill button {
  background: transparent; border: 0; color: #14532d; cursor: pointer;
  font-size: 16px; line-height: 1; padding: 0 2px;
}
.delete-modal-selected-pill button:hover { color: #991b1b; }

.delete-modal-footer {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 12px 18px; border-top: 1px solid var(--slate-200); background: var(--slate-50);
}
.delete-modal-btn-cancel {
  padding: 7px 14px; background: #fff; border: 1px solid var(--slate-300); border-radius: 6px;
  font-size: 13px; font-weight: 600; color: var(--slate-700); cursor: pointer;
}
.delete-modal-btn-cancel:hover { background: var(--slate-100); }
.delete-modal-btn-delete {
  padding: 7px 14px; background: #dc2626; border: 1px solid #b91c1c; border-radius: 6px;
  font-size: 13px; font-weight: 600; color: #fff; cursor: pointer;
}
.delete-modal-btn-delete:hover { background: #b91c1c; }
.delete-modal-btn-delete.is-armed {
  background: #991b1b; border-color: #7f1d1d;
  animation: delete-armed-pulse 1.1s ease-in-out infinite;
}
@keyframes delete-armed-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(220,38,38,.5); }
  50%     { box-shadow: 0 0 0 6px rgba(220,38,38,0); }
}
/* Non-destructive confirm (move comms) — green, not the delete red. */
.delete-modal-btn-move {
  padding: 7px 14px; background: #16a34a; border: 1px solid #15803d; border-radius: 6px;
  font-size: 13px; font-weight: 600; color: #fff; cursor: pointer;
}
.delete-modal-btn-move:hover { background: #15803d; }
.delete-modal-btn-move:disabled { opacity: .5; cursor: not-allowed; }
/* Move-comms modal reuses the delete shell but isn't destructive — swap the
   red header for a neutral green that matches the confirm button. */
.move-modal .delete-modal-header { background: #f0fdf4; border-bottom-color: #bbf7d0; }
.move-modal .delete-modal-title,
.move-modal .delete-modal-close { color: #166534; }

/* ── "Only with them" comms filter ────────────────────────────────────────
   A record collects conversations it is only the SUBJECT of — the surveyor,
   the title company, a colleague thread — and they bury the handful
   actually with the owner or buyer. The switch hides the rest; which comms
   count is decided server-side (helpers.counterparty_comm_ids). */
.comms-only-them .comm-card--other { display: none; }
.comms-only-them-toggle {
  display: inline-flex; align-items: center; gap: 5px; margin-left: 8px;
  font-size: 10px; font-weight: 600; color: var(--slate-600, #475569);
  cursor: pointer; user-select: none; white-space: nowrap;
  /* The header sets uppercase + letter-spacing for its title. Inheriting
     both turned this into a shouty "O N L Y  W I T H  T H E M" that read as
     a second heading and was half again as wide as the sentence it is. */
  text-transform: none; letter-spacing: normal;
}
.comms-only-them-toggle input { margin: 0; cursor: pointer; }
.comms-only-them-count {
  background: var(--chip-comm-bg, #fff7ed); color: var(--chip-comm-text, #b45309);
  border-radius: 8px; padding: 0 5px; font-size: 9px; font-weight: 700;
}
