/* TWX CRM — dark, signal-driven dashboard theme.

   Design intent: futuristic without being fatiguing. This is a tool someone
   has open for hours, so the "AI-native" quality comes from STRUCTURE AND
   MOTION, not saturation. The accent colour appears only where something is
   actually true — the page you are on, a live status, a real alert — and
   never as decoration. A dashboard that glows everywhere signals nothing.

   Signature: a single luminous rail in the sidebar that slides to the active
   item. It is the one memorable element; everything around it stays quiet.

   THEMING FOR A CLIENT: change only the values in :root below. --accent and
   --accent-soft come from their brand; the greys stay. Nothing else in this
   file, and no markup anywhere, should need touching. */

:root {
  /* Client-brandable. These are the only values a client theme overrides. */
  --accent: #00d4ff;
  --accent-strong: #5ce1ff;
  --accent-ink: #04222c;
  --accent-glow: rgba(0, 212, 255, 0.30);
  --accent-wash: rgba(0, 212, 255, 0.10);

  /* Surfaces: cool near-black, never pure #000 — pure black under a glow
     reads as harsh and crushes the elevation steps. */
  --bg: #080b11;
  --surface: #0f151e;
  --surface-alt: #131b26;
  --surface-hover: #1a2431;
  --surface-raised: #1c2735;
  --border: #212d3d;
  --border-strong: #2c3b4e;

  --ink: #e8eef6;
  --ink-secondary: #93a3b8;
  --ink-muted: #64748b;

  --status-new: #4a9eff;
  --status-contacted: #a78bfa;
  --status-booked: #22d3ee;
  --status-completed: #34d399;
  --status-warning: #fbbf24;
  --status-danger: #f87171;
  --status-won: #34d399;
  --status-lost: #f87171;

  /* On a dark ground, elevation reads as a lifted border plus depth, not as
     a soft grey blur — a light-theme shadow is simply invisible here. */
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.02);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.03);
  /* Referenced by .login-card, .toast, and .modal but never actually
     defined anywhere — those have had no shadow at all until now. */
  --shadow-lg: 0 12px 40px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.03);

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --space-xs: 0.5rem;
  --space-sm: 0.875rem;
  --space-md: 1.25rem;
  --space-lg: 2rem;
  --space-xl: 3rem;

  /* Client-brandable: defaults to the same surface every other panel uses,
     but a client can set their own sidebar color in Settings (Allison's is
     her brand pink) independent of the accent color that drives the active
     nav rail, hover states, and buttons. */
  --sidebar-bg: var(--surface);
  /* Nav item text color, specifically for the sidebar. Defaults to the same
     muted grey used everywhere else — but when a client sets their own
     sidebar color (a colored background instead of the neutral --surface
     this was tuned against), that grey can lose most of its contrast, so
     a workspace with its own sidebar color gets its own darker override. */
  --sidebar-ink-secondary: var(--ink-secondary);

  /* Client-brandable, like --accent above — a client theme overrides only
     this, the fallback stack stays as the safety net either way. */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* Headings only. Defaults to the same Inter as body text — a client brand
     font (Settings -> Brand) overrides just this, so their identity shows up
     in page titles and section headers without a dense dashboard's actual
     working text (tables, buttons, forms) ever losing legibility to a
     display/serif face. */
  --font-heading: var(--font-sans);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.01em; font-family: var(--font-heading); }
p { margin: 0; }
button { font-family: inherit; cursor: pointer; }

/* ---------- App shell ---------- */

.app-shell {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 244px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: var(--space-md) var(--space-sm);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: visible;
}
/* One ambient bloom, top-left, behind the brand. Restraint is the point:
   a second glow anywhere else would make both meaningless. */
.sidebar::before {
  content: '';
  position: absolute;
  top: -60px; left: -70px;
  width: 240px; height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent-glow) 0%, transparent 68%);
  opacity: 0.5;
  pointer-events: none;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem 1.5rem;
  font-weight: 800;
  font-size: 1.05rem;
}
.sidebar-logo { height: 26px; width: auto; max-width: 130px; object-fit: contain; }
.sidebar-credit {
  padding: 0.65rem 0.75rem 0.2rem;
  font-size: 0.66rem;
  color: var(--ink-muted);
  opacity: 0.55;
  letter-spacing: 0.02em;
}
.sidebar-brand .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-glow);
  animation: pulse 3.2s ease-in-out infinite;
}
/* Slow, low-amplitude. It reads as "the system is running", which is true —
   this dashboard is fed by live webhooks and a background poll loop. Fast or
   bright would be decoration; this is closer to a status LED. */
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--accent-glow); }
  50%      { box-shadow: 0 0 0 7px rgba(0, 212, 255, 0.06); }
}

.nav-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; flex: 1; }

/* Section headings break a long flat list into scannable groups. */
.nav-section-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding: 1.1rem 0.75rem 0.35rem;
}
.nav-section-label:first-child { padding-top: 0.25rem; }

.nav-item a {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--sidebar-ink-secondary);
  font-weight: 600;
  font-size: 0.9rem;
  transition: background 0.15s ease, color 0.15s ease;
}
.nav-item a:hover { background: var(--surface-hover); color: var(--ink); }

/* THE SIGNATURE.
   The active item grows a luminous rail on its left edge. It scales in from
   nothing, so moving between pages reads as the light travelling rather than
   two separate highlights blinking. This is the one piece of motion that
   encodes information — where you are — which is why it earns the attention
   budget that nothing else in this file gets. */
.nav-item > a,
.nav-item > .nav-item-row > a { position: relative; }

.nav-item > a::before,
.nav-item > .nav-item-row > a::before {
  content: '';
  position: absolute;
  left: -0.5rem;
  top: 50%;
  width: 3px;
  height: 20px;
  border-radius: 3px;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent-glow), 0 0 4px var(--accent);
  transform: translateY(-50%) scaleY(0);
  transform-origin: center;
  opacity: 0;
  transition: transform 0.24s cubic-bezier(0.34, 1.4, 0.64, 1), opacity 0.18s ease;
}
.nav-item.active > a::before,
.nav-item.active > .nav-item-row > a::before {
  transform: translateY(-50%) scaleY(1);
  opacity: 1;
}

.nav-item.active > a,
.nav-item.active > .nav-item-row > a {
  background: var(--accent-wash);
  color: var(--accent-strong);
}
.nav-item .icon {
  width: 17px; height: 17px;
  flex-shrink: 0;
  opacity: 0.72;
  transition: opacity 0.15s ease;
}
.nav-item a:hover .icon { opacity: 1; }
.nav-item.active > a .icon,
.nav-item.active > .nav-item-row > a .icon { opacity: 1; }

/* A nav item that exists but isn't usable yet (e.g. Instagram automation
   before Meta's App Review completes) — visible so clients know it's coming,
   not clickable, and never confused with a normal disabled/error state. */
.nav-item.nav-locked > a {
  cursor: default;
  opacity: 0.55;
}
.nav-item.nav-locked > a:hover { background: none; color: var(--sidebar-ink-secondary); }
.nav-lock-icon { margin-left: auto; font-size: 0.75rem; opacity: 0.8; }

/* Count of things needing attention, e.g. clients behind on payment. */
.nav-badge {
  margin-left: auto;
  background: var(--status-danger);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}

.nav-item-row { display: flex; align-items: center; border-radius: var(--radius-sm); }
.nav-item-row a { flex: 1; }
.nav-caret {
  background: none;
  border: none;
  color: var(--ink-muted);
  cursor: pointer;
  padding: 0.55rem;
  font-size: 0.85rem;
  transition: transform 0.18s ease;
  border-radius: var(--radius-sm);
  /* The icon glyph itself stays small and quiet — this is the actual
     clickable/tappable area, sized well past the icon so a slightly
     off-target tap still lands on it instead of the sibling link. */
  min-width: 32px;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.nav-caret:hover { color: var(--ink); }

.nav-sublist {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 0;
  overflow: hidden;
  /* A fixed max-height animated from 0 is what made this feel laggy: the
     transition always spends its full duration crossing 0->420px even when
     the real content is 80px tall, so most of that time visually looks like
     nothing is happening yet. Shorter duration + ease-out (fast start, the
     part that actually reads as "responsive") fixes the feel without
     needing a markup change for a true auto-height animation. */
  transition: max-height 0.14s ease-out;
}

/* Three ways a group opens, in priority order:
   1. hovering the group (desktop convenience — no click needed)
   2. .is-open, set server-side when one of its own pages is active
   3. .open, toggled by the caret button (touch + keyboard) */
.nav-group:hover .nav-sublist,
.nav-group.is-open .nav-sublist,
.nav-sublist.open { max-height: 420px; }

.nav-group:hover .nav-caret,
.nav-group.is-open .nav-caret,
.nav-caret[aria-expanded="true"] { transform: rotate(90deg); }

/* Items used to fade/slide in with a staggered per-item delay (up to 130ms
   before the last one even started, on top of its own transition) — a nice
   desktop flourish that read as pure lag on a mobile tap, where the whole
   list should just be there the instant it opens. Items are visible
   immediately now; only the container's height still animates. */
.nav-sublist li { opacity: 1; }

.nav-sublist li a {
  display: block;
  padding: 0.4rem 0.75rem 0.4rem 2.4rem;
  border-radius: var(--radius-sm);
  color: var(--ink-secondary);
  font-weight: 500;
  font-size: 0.84rem;
}
.nav-sublist li a:hover { background: var(--surface-hover); color: var(--ink); }
.nav-sublist li.active a { background: var(--accent-wash); color: var(--accent-strong); font-weight: 600; }
.nav-sublist-empty { padding: 0.4rem 0.75rem 0.4rem 2.4rem; color: var(--ink-muted); font-size: 0.8rem; }

.sidebar-footer {
  border-top: 1px solid var(--border);
  padding-top: var(--space-sm);
  margin-top: var(--space-sm);
}
.sidebar-user { padding: 0.5rem 0.75rem; }
.sidebar-user .name { font-weight: 700; font-size: 0.88rem; }
.sidebar-user .email { color: var(--ink-muted); font-size: 0.78rem; }
.logout-form { margin-top: 0.5rem; }
.logout-btn {
  width: 100%; text-align: left; background: none; border: none;
  padding: 0.5rem 0.75rem; border-radius: var(--radius-sm); color: var(--ink-muted);
  font-weight: 600; font-size: 0.85rem;
}
.logout-btn:hover { background: var(--surface-hover); color: var(--status-danger); }

.main {
  flex: 1;
  min-width: 0;
  padding: var(--space-lg) var(--space-xl);
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
  flex-wrap: wrap;
}
.page-header h1 { font-size: 1.6rem; }
.page-header .subtitle { color: var(--ink-secondary); margin-top: 0.25rem; font-size: 0.92rem; }
.page-header .actions { display: flex; gap: 0.6rem; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  padding: 0.55rem 1.1rem; border-radius: var(--radius-sm); border: 1px solid transparent;
  font-weight: 600; font-size: 0.85rem; transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
}
/* .btn's own `display: inline-flex` is an author-stylesheet rule, which
   beats the browser's built-in `[hidden] { display: none }` UA rule even
   at equal selector specificity (author styles always win over UA styles)
   — so `button.hidden = true` in JS silently did nothing for any .btn.
   `.btn[hidden]` has higher specificity than `.btn` alone, so this actually
   wins. Affects every screen that toggles a .btn's hidden attribute
   (Calendars' Delete/Set Default/Save/Match, Email Automations' Clone/Delete). */
.btn[hidden] { display: none; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow-sm); }
.btn-primary:hover { box-shadow: var(--shadow-md); }
.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--border); }
.btn-secondary:hover { background: var(--surface-hover); }
.btn-danger { background: rgba(248, 113, 113, 0.14); color: var(--status-danger); }
.btn-danger:hover { background: rgba(248, 113, 113, 0.22); }
.btn-sm { padding: 0.35rem 0.75rem; font-size: 0.78rem; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.cell-actions { display: flex; gap: 0.4rem; align-items: center; }

/* ---------- Cards / grids ---------- */

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: var(--space-md); box-shadow: var(--shadow-sm);
}

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-sm); margin-bottom: var(--space-lg); }
.stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-md); box-shadow: var(--shadow-sm); }
.stat-card .label { color: var(--ink-secondary); font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.stat-card .value {
  font-size: 2rem; font-weight: 800; margin-top: 0.35rem;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.stat-card.accent {
  border-color: rgba(0, 212, 255, 0.28);
  background: linear-gradient(180deg, var(--accent-wash), var(--surface));
}
.stat-card.accent .value { color: var(--accent-strong); }

.two-col { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--space-md); }

/* ---------- Status badges ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.22rem 0.6rem; border-radius: 999px; font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-new { background: rgba(59,130,246,0.12); color: var(--status-new); }
.badge-contacted { background: rgba(139,92,246,0.12); color: var(--status-contacted); }
.badge-booked { background: rgba(0,153,204,0.12); color: var(--status-booked); }
.badge-completed, .badge-won { background: rgba(16,185,129,0.12); color: var(--status-completed); }
.badge-warning, .badge-followup { background: rgba(245,158,11,0.14); color: var(--status-warning); }
.badge-danger, .badge-lost, .badge-noshow { background: rgba(239,68,68,0.12); color: var(--status-danger); }
.badge-muted { background: var(--surface-hover); color: var(--ink-muted); }

/* ---------- Tables ---------- */

.table-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
table { width: 100%; border-collapse: collapse; min-width: 720px; }
thead th {
  text-align: left; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink-muted); font-weight: 700; padding: 0.85rem 1rem; border-bottom: 1px solid var(--border);
}
tbody td { padding: 0.85rem 1rem; border-bottom: 1px solid var(--border); font-size: 0.88rem; vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background 0.12s ease; }
tbody tr:hover { background: var(--surface-hover); cursor: pointer; }
.cell-name { font-weight: 700; }
.cell-muted { color: var(--ink-muted); font-size: 0.82rem; }

/* ---------- Filters / toolbar ---------- */

.toolbar { display: flex; align-items: center; gap: 0.6rem; margin-bottom: var(--space-md); flex-wrap: wrap; }
.input, select.input {
  padding: 0.55rem 0.8rem; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); font-size: 0.86rem; color: var(--ink); font-family: inherit;
}
.input:focus, select.input:focus, textarea.input:focus { outline: none; border-color: var(--accent-strong); box-shadow: 0 0 0 3px rgba(0,212,255,0.18); }
.search-input { min-width: 220px; }
textarea.input { width: 100%; resize: vertical; min-height: 90px; }
label.field-label { display: block; font-size: 0.78rem; font-weight: 700; color: var(--ink-secondary); margin-bottom: 0.3rem; text-transform: uppercase; letter-spacing: 0.03em; }
.field { margin-bottom: var(--space-sm); }

/* ---------- Per-day hours editor (Calendars: New/Edit Calendar modal) ---------- */

.day-hours-row { padding: 0.4rem 0; border-bottom: 1px solid var(--border); }
.day-hours-row:last-child { border-bottom: none; }
.day-hours-check {
  display: inline-flex; align-items: center; gap: 0.4rem; width: 60px; flex-shrink: 0;
  font-size: 0.82rem; font-weight: 700; color: var(--ink-secondary); cursor: pointer; user-select: none;
}
.day-hours-check input { accent-color: var(--accent-strong); }
.day-hours-check:has(input:disabled) { opacity: 0.45; cursor: not-allowed; }
.day-hours-row:has(.day-enabled:checked) .day-hours-check { color: var(--ink); }
.day-hours-row .input[type="time"] { width: auto; flex: 1; }
.day-hours-row .input[type="time"]:disabled { opacity: 0.4; background: var(--surface-hover); }
.day-hours-hint { margin: 0.25rem 0 0 76px; font-size: 0.76rem; }

/* ---------- Kanban ---------- */

.kanban { display: flex; gap: var(--space-sm); overflow-x: auto; padding-bottom: var(--space-sm); }
.kanban-column { background: var(--surface-alt); border-radius: var(--radius-lg); min-width: 260px; flex: 1 0 260px; padding: var(--space-sm); border: 1px solid var(--border); }
.kanban-column-header { display: flex; align-items: center; justify-content: space-between; padding: 0 0.35rem 0.7rem; }
.kanban-column-header h3 { font-size: 0.85rem; }
.kanban-count { background: var(--surface); border: 1px solid var(--border); border-radius: 999px; font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem; color: var(--ink-secondary); }
.kanban-cards { display: flex; flex-direction: column; gap: 0.5rem; min-height: 40px; }
.kanban-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 0.75rem 0.85rem; box-shadow: var(--shadow-sm); cursor: grab; transition: box-shadow 0.15s ease, transform 0.1s ease;
}
.kanban-card:hover { box-shadow: var(--shadow-md); }
.kanban-card.dragging { opacity: 0.5; }
.kanban-card .name { font-weight: 700; font-size: 0.88rem; }
.kanban-card .meta { color: var(--ink-muted); font-size: 0.76rem; margin-top: 0.2rem; }
.kanban-column.drop-target { outline: 2px dashed var(--accent-strong); outline-offset: -2px; }

/* ---------- Empty states ---------- */

.empty-state {
  text-align: center; padding: var(--space-xl) var(--space-md); color: var(--ink-secondary);
}
.empty-state .icon { font-size: 1.8rem; margin-bottom: 0.5rem; }
.empty-state h3 { font-size: 1rem; color: var(--ink); margin-bottom: 0.3rem; }
.empty-state p { font-size: 0.85rem; }

/* ---------- Inherit/override line (Lead detail: Calendar field) ---------- */

.inherit-line {
  display: flex; align-items: center; gap: 0.5rem; font-size: 0.84rem;
  padding: 0.55rem 0.7rem; background: var(--surface-alt); border: 1px dashed var(--border); border-radius: var(--radius-sm);
}
.inherit-line .lnk { margin-left: auto; font-size: 0.78rem; font-weight: 700; color: var(--accent-strong); flex-shrink: 0; }
.inherit-line .lnk:hover { text-decoration: underline; }

/* ---------- Lead detail / panels ---------- */

.detail-grid { display: grid; grid-template-columns: 1fr 320px; gap: var(--space-md); align-items: start; }
.timeline-item { display: flex; gap: 0.6rem; padding: 0.55rem 0; border-bottom: 1px solid var(--border); font-size: 0.84rem; }
.timeline-item:last-child { border-bottom: none; }
.timeline-item .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-strong); margin-top: 0.4rem; flex-shrink: 0; }
.note-item { padding: 0.7rem 0; border-bottom: 1px solid var(--border); }
.note-item:last-child { border-bottom: none; }
.note-item .meta { color: var(--ink-muted); font-size: 0.72rem; margin-top: 0.25rem; }

/* ---------- Toast ---------- */

.toast {
  position: fixed; bottom: 1.5rem; right: 1.5rem; background: var(--surface-raised); color: var(--ink); border: 1px solid var(--border-strong);
  padding: 0.7rem 1.1rem; border-radius: var(--radius-sm); font-size: 0.85rem; font-weight: 600;
  box-shadow: var(--shadow-lg); opacity: 0; transform: translateY(8px); transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none; z-index: 100;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast.error { background: var(--status-danger); }

/* A field the user needs to go fix, e.g. an empty Subject caught before a
   campaign send — paired with focusing the field, so the fastest-fading
   toast in the world still leaves a visible trail pointing at what to do. */
.input.field-error, textarea.field-error { border-color: var(--status-danger) !important; box-shadow: 0 0 0 2px rgba(220,38,38,0.15); }

/* ---------- Modal ---------- */

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(15,23,42,0.4); display: none;
  align-items: center; justify-content: center; z-index: 90; padding: var(--space-md);
}
.modal-backdrop.show { display: flex; }
.modal {
  background: var(--surface); border-radius: var(--radius-lg); padding: var(--space-lg);
  max-width: 480px; width: 100%; box-shadow: var(--shadow-lg);
  /* .modal-backdrop centers this with position:fixed + no scroll of its own,
     so a modal taller than the viewport (e.g. the Template form with all its
     fields) had no way to reach its own Save/Cancel row below the fold.
     Cap the modal's own height and let it scroll internally instead. */
  max-height: calc(100vh - (var(--space-md) * 2));
  overflow-y: auto;
}
.modal h3 { margin-bottom: 0.75rem; }
.modal .actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: var(--space-md); }

/* ---------- Login page ---------- */

.login-shell { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--surface-alt); padding: var(--space-md); }
.login-card { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); padding: var(--space-xl) var(--space-lg); box-shadow: var(--shadow-lg); }
.login-brand { display: flex; align-items: center; gap: 0.5rem; font-weight: 800; font-size: 1.1rem; margin-bottom: var(--space-lg); justify-content: center; }
.login-brand .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); }
.login-error { background: rgba(248, 113, 113, 0.14); color: var(--status-danger); padding: 0.6rem 0.8rem; border-radius: var(--radius-sm); font-size: 0.82rem; margin-bottom: var(--space-sm); }
.login-card .btn-primary { width: 100%; margin-top: 0.5rem; padding: 0.7rem; }

/* ---------- Responsive ---------- */

/* Desktop: the top bar and backdrop do not exist. */
.mobile-topbar, .sidebar-backdrop { display: none; }

@media (max-width: 900px) {
  .app-shell { flex-direction: column; min-width: 0; }
  html, body { overflow-x: hidden; }

  /* Fixed top bar carries the brand, the menu button, and the alert count,
     so the drawer can be fully hidden without losing the alert signal. */
  .mobile-topbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    position: sticky;
    top: 0;
    z-index: 60;
    padding: 0.7rem 0.9rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
  }
  .mobile-brand { display: flex; align-items: center; gap: 0.5rem; font-weight: 800; font-size: 0.98rem; }
  .mobile-brand .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
  .mobile-topbar .nav-badge { margin-left: auto; text-decoration: none; }

  .burger {
    background: none; border: none; padding: 0.3rem;
    display: flex; flex-direction: column; gap: 4px; cursor: pointer;
  }
  .burger span {
    display: block; width: 20px; height: 2px; border-radius: 2px;
    background: var(--ink); transition: transform 0.22s ease, opacity 0.18s ease;
  }
  .burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  .burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

  /* Off-canvas drawer. Slides rather than reflowing the page, so opening the
     menu never shifts the content underneath it. */
  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 270px;
    height: 100vh;
    z-index: 70;
    flex-direction: column;
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform 0.26s cubic-bezier(0.4, 0, 0.2, 1);
    border-right: 1px solid var(--border);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar::before { display: none; }

  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(0, 0, 0, 0.55);
    opacity: 0;
    transition: opacity 0.22s ease;
  }
  .sidebar-backdrop.show { opacity: 1; }
  .sidebar-backdrop[hidden] { display: none; }

  /* Groups stay accordions on touch: hover-to-open sticks after a tap. */
  .nav-group:hover .nav-sublist { max-height: 0; }
  .nav-group.is-open .nav-sublist, .nav-sublist.open { max-height: 420px; }
  .nav-list { flex-direction: column; }
  .nav-section-label { display: block; }
  .sidebar-footer { display: block; }

  /* Comfortable touch targets. The caret was the one thing this rule never
     covered — at its base ~28px size a thumb tap easily missed it and hit
     the sibling link instead, which is exactly why tapping it looked like
     it "did nothing": the tap was landing on the wrong element. 44px is
     Apple's own minimum recommended target size. */
  .nav-item a { padding: 0.7rem 0.75rem; }
  .nav-sublist li a { padding: 0.55rem 0.75rem 0.55rem 2.4rem; }
  .nav-caret { min-width: 44px; min-height: 44px; font-size: 1rem; }

  .main { padding: var(--space-md); min-width: 0; max-width: 100%; }
  .detail-grid { grid-template-columns: 1fr; }
  .two-col { grid-template-columns: 1fr; }

  /* Tables are the main thing that breaks on a phone. Let them scroll inside
     their own container rather than pushing the page sideways. */
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .page-header { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
  .page-header .actions { width: 100%; flex-wrap: wrap; }
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat-card { min-width: 0; }
  .stat-card .value { font-size: 1.6rem; }
  .modal { width: calc(100vw - 1.5rem); max-height: 88vh; overflow-y: auto; }
  .row-actions { text-align: left; }
}



/* Quality floor, not decoration. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
}


/* Row-level actions. Keeping them always visible rather than hover-revealed:
   a control you cannot see is a control that does not exist, which is exactly
   how the Back Office shipped the first time. */
.row-actions { white-space: nowrap; text-align: right; }
.row-actions .btn { margin-left: 0.35rem; }
.btn-sm { padding: 0.3rem 0.6rem; font-size: 0.78rem; }

/* Rows that navigate get a clearer signal than a faint background shift. */
tbody tr.client-row:hover { background: var(--surface-hover); }
tbody tr.client-row:hover .cell-name { color: var(--accent-strong); }

/* ---------- Overview insights: where leads come from ---------- */
/* Charts are plain inline SVG that read the workspace's own --accent and
   status colors, so a client's brand color re-themes them with no extra work. */

.header-tools { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; }

.range-pills {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
}
.range-pills a {
  padding: 0.38rem 0.85rem; border-radius: 999px; font-size: 0.8rem; font-weight: 600;
  color: var(--ink-secondary); text-decoration: none;
  transition: background-color 160ms ease-out, color 160ms ease-out, transform 160ms ease-out;
}
.range-pills a:active { transform: scale(0.97); }
.range-pills a.is-active { background: var(--accent-wash); color: var(--accent-strong); }
@media (hover: hover) and (pointer: fine) {
  .range-pills a:not(.is-active):hover { background: var(--surface-hover); color: var(--ink); }
}

.profile-menu { position: relative; }
.profile-menu > summary { list-style: none; }
.profile-menu > summary::-webkit-details-marker { display: none; }
.profile-trigger {
  display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  padding: 3px 8px 3px 3px; border-radius: 999px; color: var(--ink-secondary);
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color 160ms ease-out, transform 160ms ease-out;
}
.profile-trigger:active { transform: scale(0.97); }
.profile-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .profile-trigger:hover { border-color: var(--border-strong); } }
.profile-avatar {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
  background: var(--accent-wash); color: var(--accent-strong);
  border: 1px solid var(--accent-glow); font-size: 0.72rem; font-weight: 800; letter-spacing: 0.02em;
}
.profile-caret { transition: transform 160ms ease-out; }
.profile-menu[open] .profile-caret { transform: rotate(180deg); }
.profile-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; min-width: 220px;
  background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg); padding: 0.4rem; transform-origin: top right;
  animation: profile-pop 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
@keyframes profile-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }
.profile-who { padding: 0.55rem 0.7rem 0.65rem; border-bottom: 1px solid var(--border); margin-bottom: 0.3rem; }
.profile-name { font-weight: 700; font-size: 0.9rem; }
.profile-email { color: var(--ink-muted); font-size: 0.78rem; overflow-wrap: anywhere; }
.profile-link {
  display: block; width: 100%; text-align: left; padding: 0.5rem 0.7rem; border-radius: var(--radius-sm);
  color: var(--ink-secondary); font: inherit; font-size: 0.86rem; background: none; border: 0; cursor: pointer; text-decoration: none;
  transition: background-color 160ms ease-out, color 160ms ease-out;
}
@media (hover: hover) and (pointer: fine) { .profile-link:hover { background: var(--surface-hover); color: var(--ink); } }
.profile-link:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.insights { margin-bottom: var(--space-lg); }
.insights-row { display: grid; gap: var(--space-md); margin-bottom: var(--space-md); align-items: start; }
.insights-row-main { grid-template-columns: 1.7fr 1fr; align-items: stretch; }
.insights-row-main .source-card { display: flex; flex-direction: column; }
.card-foot { margin: auto 0 0; padding-top: 0.9rem; color: var(--ink-muted); font-size: 0.8rem; }
.insights-row-second { grid-template-columns: 1.7fr 1fr; }
.insights .card { min-width: 0; }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-sm); margin-bottom: 0.9rem; flex-wrap: wrap; }
.card-head h3 { font-size: 0.98rem; }
.card-note { color: var(--ink-muted); font-size: 0.78rem; }
.card-figure { display: flex; align-items: baseline; gap: 0.5rem; }
.card-figure-value { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--accent-strong); }
.card-figure-note { color: var(--ink-muted); font-size: 0.78rem; }

.area-chart { width: 100%; height: auto; display: block; overflow: visible; }
.area-chart .grid-line { stroke: var(--border); stroke-width: 1; }
.area-chart .axis-label { fill: var(--ink-muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.area-chart .area-line { fill: none; stroke: var(--accent); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 6px var(--accent-glow)); }
.area-chart .area-dot { fill: transparent; }
@media (hover: hover) and (pointer: fine) { .area-chart .area-dot:hover { fill: var(--accent); } }

.donut-wrap { display: flex; align-items: center; gap: var(--space-md); flex-wrap: wrap; }
.donut { width: 150px; height: 150px; flex: 0 0 auto; transform: rotate(0deg); }
.donut-track { fill: none; stroke: var(--surface-hover); stroke-width: 5; }
.donut-slice { fill: none; stroke-width: 5; }
.donut-total { fill: var(--ink); font-size: 7px; font-weight: 800; font-variant-numeric: tabular-nums; }
.donut-sub { fill: var(--ink-muted); font-size: 2.6px; letter-spacing: 0.04em; }
.legend { list-style: none; margin: 0; padding: 0; flex: 1 1 140px; min-width: 0; display: grid; gap: 0.5rem; }
.legend li { display: flex; align-items: center; gap: 0.5rem; font-size: 0.84rem; min-width: 0; }
.legend-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.legend-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-secondary); }
.legend-value { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.legend-pct { color: var(--ink-muted); font-weight: 500; margin-left: 0.2rem; }

.mini-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mini-table { min-width: 460px; }
.mini-table thead th { padding: 0.5rem 0.6rem; }
.mini-table tbody td { padding: 0.65rem 0.6rem; }
.mini-table tbody tr:hover { background: transparent; cursor: default; }
.mini-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.mini-table thead th.num { text-align: right; }

.bar-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.85rem; }
.bar-row { display: flex; justify-content: space-between; gap: 0.5rem; font-size: 0.86rem; margin-bottom: 0.3rem; }
.bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-sub { color: var(--ink-muted); }
.bar-value { font-weight: 700; font-variant-numeric: tabular-nums; }
.bar-track { height: 6px; border-radius: 999px; background: var(--surface-hover); overflow: hidden; }
.bar-fill { height: 100%; border-radius: 999px; background: var(--accent); transform-origin: left; animation: bar-grow 420ms cubic-bezier(0.23, 1, 0.32, 1); }
@keyframes bar-grow { from { transform: scaleX(0.1); opacity: 0.4; } to { transform: scaleX(1); opacity: 1; } }

.empty-state.compact { padding: 1.4rem 0.5rem; }
.empty-state.compact h3 { font-size: 0.95rem; }

.tag-tip { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 0.7rem 1rem; }
.tag-tip summary { cursor: pointer; color: var(--ink-secondary); font-size: 0.86rem; font-weight: 600; }
.tag-tip summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.tag-tip-note { color: var(--ink-muted); font-weight: 500; margin-left: 0.5rem; }
.tag-tip-body { margin-top: 0.75rem; color: var(--ink-secondary); font-size: 0.86rem; display: grid; gap: 0.6rem; }
.tag-tip-body p { margin: 0; }
.tag-tip-body code { display: block; overflow-x: auto; padding: 0.6rem 0.8rem; border-radius: var(--radius-sm); background: var(--surface-alt); border: 1px solid var(--border); color: var(--accent-strong); font-size: 0.8rem; }

@media (max-width: 600px) {
  /* The SVG scales down with the screen, so its text would fall under 8px.
     Larger text in chart units for the x labels, and no y labels (the card's
     headline figure and the gridlines carry the scale on a phone). */
  .area-chart .axis-x { font-size: 20px; }
  .area-chart .axis-y { display: none; }
  .donut { width: 120px; height: 120px; }
}
@media (max-width: 900px) {
  .insights-row-main, .insights-row-second { grid-template-columns: 1fr; }
  .header-tools { width: 100%; justify-content: space-between; }
}
@media (prefers-reduced-motion: reduce) {
  .bar-fill, .profile-panel { animation: none; }
  .range-pills a, .profile-trigger, .profile-caret, .profile-link { transition: none; }
}

/* ---- Overview: today tray + change badges ---- */
.today-tray { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-sm); margin-bottom: var(--space-md); }
.today-col { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 0.9rem 1rem; box-shadow: var(--shadow-sm); min-width: 0; }
.today-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.55rem; }
.today-head h3 { font-size: 0.85rem; }
.today-count { background: var(--surface-alt); border: 1px solid var(--border); border-radius: 999px; font-size: 0.75rem; font-weight: 700; padding: 0.1rem 0.55rem; color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.today-count.is-alert { background: color-mix(in srgb, var(--status-warning) 18%, transparent); border-color: var(--status-warning); color: var(--ink); }
.today-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.4rem 0; border-top: 1px solid var(--border); font-size: 0.86rem; }
.today-row:first-of-type { border-top: 0; }
.today-time { color: var(--accent-strong); font-weight: 700; font-variant-numeric: tabular-nums; min-width: 4.2rem; }
.today-meta { color: var(--ink-muted); font-size: 0.78rem; margin-left: auto; }
.today-empty { color: var(--ink-muted); font-size: 0.84rem; margin: 0; line-height: 1.5; }
.mini-action { font-size: 0.76rem; font-weight: 700; border: 1px solid var(--border-strong); border-radius: 999px; padding: 0.15rem 0.6rem; color: var(--ink); text-decoration: none; }
.kpi-note { color: var(--ink-muted); font-size: 0.8rem; margin: 0 0 0.6rem; }
.delta { display: block; font-size: 0.72rem; margin-top: 0.3rem; font-weight: 600; color: var(--ink-muted); }
.delta-up { color: var(--status-completed); }
.delta-down { color: var(--status-warning); }
.delta-flat { color: var(--ink-muted); }
@media (max-width: 900px) { .today-tray { grid-template-columns: 1fr; } }

/* ---- Board cards ---- */
.kanban-cards { max-height: calc(100vh - 13rem); overflow-y: auto; padding-right: 2px; }
.kcard-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; }
.call-pill { flex: none; font-size: 0.7rem; font-weight: 700; color: var(--accent-strong); border: 1px solid color-mix(in srgb, var(--accent-strong) 45%, transparent); border-radius: 999px; padding: 0.1rem 0.5rem; white-space: nowrap; }
.kanban-card .meta-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kcard-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.55rem; flex-wrap: wrap; }
.heat { font-size: 0.7rem; font-weight: 600; color: var(--ink-muted); }
.heat-warm { color: var(--status-warning); }
.heat-hot { color: #f87171; }
.kcard-actions { display: flex; gap: 0.35rem; margin-left: auto; }
.kcard-actions a { font-size: 0.7rem; font-weight: 700; color: var(--ink); text-decoration: none; border: 1px solid var(--border-strong); border-radius: 999px; padding: 0.1rem 0.55rem; }
.kanban-card.is-warm { border-left: 3px solid var(--status-warning); }
.kanban-card.is-hot { border-left: 3px solid #f87171; }

/* ---- Lead page: application answers ---- */
.answers { margin: 0; display: grid; gap: 0.6rem; }
.answer { padding-bottom: 0.6rem; border-bottom: 1px solid var(--border); }
.answer:last-child { border-bottom: 0; padding-bottom: 0; }
.answer dt { color: var(--ink-muted); font-size: 0.76rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.15rem; }
.answer dd { margin: 0; color: var(--ink); font-size: 0.95rem; line-height: 1.5; overflow-wrap: anywhere; }

/* ---- All Leads on phones: stacked cards instead of a clipped table ---- */
@media (max-width: 700px) {
  #leads-table, #leads-table tbody { display: block; min-width: 0; }
  #leads-table thead { display: none; }
  #leads-table tr {
    display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.75rem;
    padding: 0.85rem 1rem; border-bottom: 1px solid var(--border);
  }
  #leads-table tr:last-child { border-bottom: 0; }
  #leads-table td { display: block; padding: 0; border: 0; min-width: 0; }
  #leads-table td:nth-child(1) { grid-column: 1; font-size: 1rem; }
  #leads-table td:nth-child(4) { grid-column: 2; grid-row: 1 / span 2; align-self: start; }
  #leads-table td:nth-child(2) { grid-column: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-secondary); font-size: 0.85rem; }
  #leads-table td:nth-child(3) { grid-column: 1; color: var(--ink-muted); font-size: 0.8rem; }
  #leads-table td:nth-child(5) { grid-column: 1; font-size: 0.78rem; }
  #leads-table td:nth-child(5)::before { content: "Submitted "; }
  #leads-table td:nth-child(6), #leads-table td:nth-child(7), #leads-table td:nth-child(8) { display: none; }
}

/* ---- Offer page: Run ads panel ---- */
.ads-panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); margin-bottom: var(--space-md); box-shadow: var(--shadow-sm); }
.ads-panel > summary { cursor: pointer; padding: 0.9rem 1.1rem; display: flex; align-items: baseline; gap: 0.9rem; flex-wrap: wrap; list-style: none; }
.ads-panel > summary::-webkit-details-marker { display: none; }
.ads-panel > summary::before { content: "\25B8"; color: var(--accent-strong); }
.ads-panel[open] > summary::before { content: "\25BE"; }
.ads-title { font-weight: 700; }
.ads-sum { color: var(--ink-muted); font-size: 0.85rem; }
.ads-body { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); padding: 0 1.1rem 1.1rem; }
.ads-panel h4 { font-size: 0.9rem; margin: 0 0 0.7rem; }
.ads-sub { font-weight: 700; font-size: 0.82rem; margin: 0.8rem 0 0.3rem; color: var(--ink-secondary); }
.ads-sub:first-of-type { margin-top: 0; }
.ads-steps { margin: 0 0 0 1.1rem; padding: 0; line-height: 1.7; font-size: 0.86rem; color: var(--ink-secondary); }
.ads-link { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78rem; resize: none; }
.ads-results { border-top: 1px solid var(--border); padding: 1rem 1.1rem 1.1rem; }
@media (max-width: 800px) { .ads-body { grid-template-columns: 1fr; } }
