:root {
  --blue: #1a5cb8;
  --blue-dark: #123f80;
  --bg: #f4f6f9;
  --card: #ffffff;
  --border: #e2e6ec;
  --text: #1f2937;
  --muted: #6b7280;
  --green: #1e8e5a;
  --red: #c0392b;
  --a-plus: #123f80;
  --a: #1a5cb8;
  --b: #2f9e6b;
  --c: #e0a11e;
  --d: #b4b8bf;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}

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

.topbar {
  background: var(--blue);
  color: #fff;
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.topbar .brand { font-weight: 700; font-size: 18px; display: flex; align-items: center; }
/* 2026-07-20: topbar logo, next to the "Inside Referral CRM" brand text -
   sized to sit comfortably in the topbar's own 14px vertical padding
   without inflating its height. */
.topbar .brand-logo { height: 32px; width: 32px; border-radius: 50%; margin-right: 10px; }
.topbar .brand span { opacity: .8; font-weight: 400; font-size: 13px; margin-left: 8px; }
.topbar .user { font-size: 14px; }
.topbar .user a { color: #dce8ff; margin-left: 14px; }

.layout { display: flex; min-height: calc(100vh - 54px); }

/* Sidebar lives on the left (moved back 2026-07-13, per Saleem's request -
   briefly tried on the right, moved back) - swapped via flex `order` rather
   than reordering the markup itself, so nothing else about the layout has
   to change if it ever moves again. */
.content { flex: 1; padding: 28px; order: 2; }

.sidebar {
  width: 220px;
  background: #fff;
  border-right: 1px solid var(--border);
  padding: 16px 10px;
  order: 1;
}
/* 2026-07-19: desktop sidebar beautify pass. Previously every link - the
   top-level "Dashboard" link AND every link nested inside a collapsible
   nav-group (Manage Relationships, Send Email, etc.) - shared the exact
   same flat `padding: 10px 20px` rule, so a sub-menu item lined up flush
   with its own section header instead of reading as nested under it.
   Top-level items and the nav-group summaries now share one indent level
   (10px link padding + the sidebar's own 10px inset = 20px from the edge,
   matching the original look), while links living *inside* a nav-group get
   a distinctly deeper `.nav-group a` indent below - see that rule - so the
   hierarchy is visible at a glance instead of every row looking equally
   important. Rounded hover/active "chip" styling (border-radius + a bit of
   margin) replaces the old edge-to-edge highlight bar for a cleaner look. */
.sidebar a {
  display: block;
  padding: 9px 10px;
  margin: 1px 0;
  border-radius: 6px;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}
.sidebar a:hover { background: #f0f4fa; text-decoration: none; }
.sidebar a.active { background: #eaf1fc; color: var(--blue); }
.sidebar .section-label {
  padding: 14px 10px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
}

/* Collapsible nav groups (2026-07-13): plain <details>/<summary> so each
   section (Relationships/Marketing/Account) expands/collapses with zero JS -
   same disclosure pattern already used for the Groups column on Manage
   Relationships. Whichever section contains the current page starts open
   (set server-side via the `open` attribute in base.html); the rest start
   collapsed. State is not remembered across page loads by design - it
   always resets to "current section open, everything else closed". All
   three <details> share `name="nav_accordion"` (base.html) so opening one
   automatically closes whichever other one was open - native browser
   exclusive-accordion behavior, no JS needed for that either. */
.sidebar .nav-group {
  border-top: 1px solid var(--border);
  margin-top: 4px;
  padding-top: 2px;
}
.sidebar .nav-group:first-of-type { border-top: none; margin-top: 0; }
.sidebar .nav-group summary {
  padding: 10px 10px;
  margin: 1px 0;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
.sidebar .nav-group summary::-webkit-details-marker { display: none; }
.sidebar .nav-group summary::before {
  content: "▸";
  display: inline-block;
  width: 14px;
  font-size: 10px;
  transition: transform .1s ease;
}
.sidebar .nav-group[open] summary::before { transform: rotate(90deg); }
.sidebar .nav-group summary:hover { background: #f0f4fa; color: var(--text); }

/* The actual sub-menu links inside an open group - deliberately indented
   well past the "▸" toggle glyph above them (28px vs. the 10px every
   top-level link/summary uses), in a lighter weight/slightly smaller size,
   with a faint vertical guide line down the indent gutter so a long open
   section (e.g. Marketing's 8 links) still visually reads as one nested
   block rather than a wall of equal-looking rows. */
.sidebar .nav-group a {
  padding: 7px 10px 7px 28px;
  margin: 0 0 0 8px;
  font-size: 13px;
  font-weight: 400;
  color: #444;
  border-left: 2px solid var(--border);
  border-radius: 0 6px 6px 0;
}
.sidebar .nav-group a:hover { border-left-color: var(--blue); }
.sidebar .nav-group a.active {
  border-left-color: var(--blue);
  color: var(--blue);
  font-weight: 600;
}

h1 { font-size: 22px; margin: 0 0 18px; }
h2 { font-size: 17px; margin: 0 0 12px; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
}

/* FAQ (Help Menu, 2026-07-13) - a plain <details> per question, styled
   lighter than the sidebar's .nav-group accordion since this is page
   content, not navigation. */
.faq-item { border-bottom: 1px solid var(--border); padding: 12px 0; }
.faq-item:last-child { border-bottom: none; }
.faq-item summary { cursor: pointer; font-weight: 600; list-style: none; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before { content: "+ "; color: var(--blue); }
.faq-item[open] summary::before { content: "\2212 "; }
.faq-item p, .faq-item ol, .faq-item ul { margin: 8px 0 0; color: var(--text-muted, #555); }
.faq-item ol, .faq-item ul { padding-left: 20px; }

.badge.overdue { background: #fdecea; color: var(--red); }

/* Report a Problem conversation thread (2026-07-13 follow-up) - a plain
   back-and-forth log rendered as "username: ..." / "Admin: ..." lines, used
   on both the tenant's own report list (report_problem.html, inside a
   .faq-item <details> per report - hence .report-thread summary needing
   room for the status badges alongside the subject) and the admin review
   screen (admin_problem_reports.html). */
.report-thread summary { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.conversation { background: var(--bg); border-radius: 8px; padding: 10px 14px; margin-top: 10px; }
.conversation p { margin: 6px 0; }
.conversation p strong { color: var(--blue-dark); }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.stat { text-align: center; }
.stat .num { font-size: 28px; font-weight: 700; color: var(--blue); }
.stat .label { color: var(--muted); font-size: 13px; }

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--border); font-size: 14px; }
th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; }
tr:hover td { background: #fafbfd; }

.btn {
  display: inline-block;
  padding: 8px 16px;
  border-radius: 6px;
  border: 1px solid var(--blue);
  background: var(--blue);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
}
.btn:hover { background: var(--blue-dark); text-decoration: none; }
.btn.secondary { background: #fff; color: var(--blue); }
.btn.secondary:hover { background: #eaf1fc; }
.btn.danger { background: #fff; color: var(--red); border-color: var(--red); }
.btn.danger:hover { background: #fdecea; }
.btn.small { padding: 5px 10px; font-size: 12px; }
.btn.success { background: var(--green); border-color: var(--green); }
/* 2026-07-20: engaged state for the Manage Relationships "Show only:"
   quick-filter toggle buttons (Missing Phone/Email/Address) - same filled
   treatment as .rank-buttons a.active, so an engaged filter is visually
   obvious rather than looking identical to the other two. */
.btn.secondary.active { background: var(--blue); color: #fff; border-color: var(--blue); }

.rank-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.rank-A\+ { background: var(--a-plus); }
.rank-A { background: var(--a); }
.rank-B { background: var(--b); }
.rank-C { background: var(--c); }
.rank-D { background: var(--d); color: #333; }

/* 2026-07-15 (batch #13): on mobile the rank-quick-select buttons on Manage
   Relationships used to wrap onto 2-3 lines per row, which looked messy and
   made the row height inconsistent. white-space:nowrap keeps them on one
   line; the table's containing .card already scrolls horizontally on narrow
   screens (see the @media (max-width: 900px) block below), so nothing is
   ever cut off - the user just swipes sideways if needed. */
.rank-buttons { display: inline-block; white-space: nowrap; }
.rank-buttons a {
  display: inline-block;
  width: 30px; height: 26px; line-height: 26px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 4px;
  margin-right: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
}
.rank-buttons a.active { background: var(--blue); color: #fff; border-color: var(--blue); }

form.inline { display: inline; }

label { display: block; font-size: 13px; font-weight: 600; margin: 12px 0 4px; }
input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=number], input[type=datetime-local], select, textarea {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  font-family: inherit;
}
textarea { min-height: 160px; }
.checkbox-row { display: flex; align-items: center; gap: 8px; margin: 12px 0; }
.checkbox-row input { width: auto; }

/* Image library "Insert Image" picker (2026-07-13) - a small popover of
   thumbnails anchored under its trigger button, reused on Send Email, Print
   Letters, and the Signature editors in Settings. */
.image-picker { position: relative; display: inline-block; margin: 6px 0; }
.image-picker-panel {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  margin-top: 4px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  padding: 8px;
  display: none;
  max-height: 260px;
  overflow-y: auto;
  width: 260px;
}
.image-picker-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.image-picker-item {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 6px;
  padding: 4px;
  cursor: pointer;
  text-align: center;
  font-size: 11px;
  color: var(--text);
}
.image-picker-item:hover { border-color: var(--blue); }
.image-picker-item img { width: 100%; height: 48px; object-fit: cover; border-radius: 4px; display: block; margin-bottom: 3px; }
.image-picker-item span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.image-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 12px; margin: 12px 0; }
.image-library-item { text-align: center; font-size: 12px; }
.image-library-item img { width: 100%; height: 80px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); display: block; margin-bottom: 6px; }
.image-library-item span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 4px; }

.filters { display: flex; gap: 12px; align-items: end; margin-bottom: 16px; flex-wrap: wrap; }
.filters > div { min-width: 160px; }

/* 2026-07-29: the "Add to Group" bulk-action select (contacts_list.html's
   #bulk-groups-form) sits bare inside an .actions-row flex container with no
   wrapping div, unlike the Group filter select above which is constrained by
   .filters > div's min-width. Without this override the global
   `select { width: 100% }` rule (below) stretches it to fill the flex row
   instead of sizing to its content, making it look oversized next to the
   other Group dropdown. width:auto + a matching min-width brings it back in
   line with that dropdown's size. */
.bulk-group-select { width: auto; min-width: 160px; }

.alert { padding: 10px 14px; border-radius: 6px; margin-bottom: 16px; font-size: 14px; }
.alert.error { background: #fdecea; color: var(--red); border: 1px solid #f5c6c0; }
.alert.success { background: #e8f6ee; color: var(--green); border: 1px solid #bfe6cf; }
.alert.info { background: #eaf1fc; color: var(--blue-dark); border: 1px solid #c6d9f5; }

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

/* 2026-07-23: honeypot field for public, no-login forms (signup, Contact
   Us, the lead capture funnel, meeting booking) - see app/antibot.py and
   templates/_honeypot_field.html. Keeps the field technically present and
   fillable in the DOM (so a naive scraping bot that blindly fills every
   input still fills it in) while staying invisible and unreachable to a
   real visitor or a screen reader. */
.hp-field { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; overflow: hidden; }

.actions-row { display: flex; gap: 8px; margin-bottom: 16px; }

.pager { display: flex; align-items: center; gap: 10px; }

.badge { display:inline-block; padding:2px 8px; border-radius:4px; font-size:11px; font-weight:600; }
.badge.type-call { background:#eaf1fc; color:var(--blue-dark); }
.badge.type-whatsapp { background:#e6f7ec; color:var(--green); }
.badge.type-email { background:#fff4e0; color:#8a5a00; }
.badge.type-note { background:#f1f1f4; color:#444; }
.badge.type-system { background:#f1f1f4; color:#888; }

.qualified-pill {
  display: inline-block;
  padding: 3px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}
.qualified-pill.yes { background: var(--green); }
.qualified-pill.no { background: var(--muted); }

.group-dropdown { position: relative; }
.group-dropdown summary {
  cursor: pointer;
  list-style: none;
  font-size: 13px;
  color: var(--blue);
}
.group-dropdown summary::-webkit-details-marker { display: none; }
.group-dropdown[open] summary { color: var(--blue-dark); }
.group-dropdown form {
  position: absolute;
  z-index: 20;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px;
  min-width: 180px;
  box-shadow: 0 4px 14px rgba(0,0,0,.12);
  margin-top: 4px;
}
.group-dropdown .checkbox-row { margin: 6px 0; }

.mapping-table select { min-width: 180px; }

.auth-wrap {
  max-width: 400px;
  margin: 60px auto;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 32px;
}
.auth-wrap h1 { text-align: center; }

/* 2026-07-14 (batch #8): dashboard quick-link row - small icon links using
   plain Unicode glyphs (no icon library/CDN dependency). */
.quick-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 14px 16px;
}
.quick-link {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.quick-link:hover {
  background: #eaf0fb;
  border-color: var(--blue);
  text-decoration: none;
}
.quick-link-icon {
  font-size: 16px;
  line-height: 1;
}
@media (max-width: 640px) {
  .quick-link { flex: 1 1 calc(50% - 10px); justify-content: center; }
}

/* 2026-07-14 (batch #10): "make these links colorful" - each quick link gets
   its own tinted background/border/text color instead of the flat gray chip
   above, on both the Dashboard's own row and the mobile nav bar (same markup,
   see _quick_links.html). Border-left kept a little heavier than the rest of
   the border so the color reads clearly even at a glance. */
.quick-link.qc-add { background: #e6f7ec; border-color: #34a853; color: #1e7e37; border-left-width: 3px; }
.quick-link.qc-add:hover { background: #d7f3e0; border-color: #2b8a45; }
.quick-link.qc-manage { background: #eaf1fd; border-color: #2f6fed; color: #1a4fc4; border-left-width: 3px; }
.quick-link.qc-manage:hover { background: #dbe8fc; border-color: #1a4fc4; }
.quick-link.qc-activity { background: #f2eafd; border-color: #8e44ec; color: #6b21c9; border-left-width: 3px; }
.quick-link.qc-activity:hover { background: #e7d9fb; border-color: #6b21c9; }
.quick-link.qc-email { background: #fdf1e3; border-color: #f4941e; color: #b8620a; border-left-width: 3px; }
.quick-link.qc-email:hover { background: #fbe6c8; border-color: #b8620a; }
.quick-link.qc-whatsapp { background: #e4f8f0; border-color: #1fb975; color: #0d8a54; border-left-width: 3px; }
.quick-link.qc-whatsapp:hover { background: #d1f2e3; border-color: #0d8a54; }
.quick-link.qc-report { background: #fdeaea; border-color: #e5484d; color: #c0272b; border-left-width: 3px; }
.quick-link.qc-report:hover { background: #fad6d7; border-color: #c0272b; }
.quick-link.qc-calllist { background: #fff6df; border-color: #d69e2e; color: #92600a; border-left-width: 3px; }
.quick-link.qc-calllist:hover { background: #fcecc0; border-color: #92600a; }
.quick-link.qc-meetings { background: #e8f0fe; border-color: #3f6fd6; color: #1f3f8f; border-left-width: 3px; }
.quick-link.qc-meetings:hover { background: #d5e3fc; border-color: #1f3f8f; }
/* 2026-07-22: Manage Teams quick link - Saleem asked for a Dashboard
   link/button to the new Manage Teams feature, same colorful quick-link
   treatment as every other one here. A rose/pink tone, distinct from every
   other qc-* color already in use. */
.quick-link.qc-teams { background: #fce7f3; border-color: #db2777; color: #9d174d; border-left-width: 3px; }
.quick-link.qc-teams:hover { background: #fbcfe8; border-color: #9d174d; }

/* 2026-07-15 (batch #13): shared confirm modal, replacing native confirm()
   dialogs sitewide (see the markup in base.html and showConfirmModal() in
   app.js). Simple centered overlay - no animation library, consistent with
   the rest of this app's minimal-dependency approach. */
.modal-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal-box {
  background: #fff;
  border-radius: 10px;
  padding: 24px;
  max-width: 420px;
  width: calc(100% - 32px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
}
.modal-box p { margin: 0 0 20px; font-size: 14px; line-height: 1.5; }
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 2026-07-14 (batch #8): sitewide footer (Terms/Privacy links). */
.site-footer {
  text-align: center;
  padding: 18px 12px;
  font-size: 12px;
  color: var(--muted);
}
.site-footer a { color: var(--muted); text-decoration: underline; }
.site-footer span { margin: 0 8px; }

/* Hidden by default (desktop still has the full sidebar) - only shown via
   the @media rule below. Reuses the same .quick-link/.quick-link-icon
   styling as the Dashboard's own row.
   2026-07-14 (batch #11): this rule USED TO sit after the @media block below
   instead of before it - since both this rule and the media query's
   ".mobile-quick-links { display: flex; }" target the exact same selector
   with identical specificity, CSS resolves the tie by source order, and
   whichever one is declared LAST in the file wins regardless of viewport
   width. With this rule declared after the media query, "display: none"
   always won - so the mobile quick-links bar has never actually been visible
   on any screen size since it was first added, including on real phones,
   even though the media query itself was completely correct. Moving this
   block above the @media rule (so the media query's override comes last)
   fixes it without changing either rule's actual content. */
.mobile-quick-links {
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 16px;
  background: #fff;
  border-bottom: 1px solid var(--border);
}

/* 2026-07-14 (batch #8): incremental mobile-responsive pass (see backlog for
   why incremental rather than a full Bootstrap rewrite of every template -
   this app has a lot of shipped functionality tied to specific existing
   markup/classes, and a big-bang rewrite is real regression risk). These
   rules are additive CSS only - no template markup had to change for this
   part, which is exactly why this was the first thing done here. */
@media (max-width: 900px) {
  .layout { flex-direction: column; }
  /* 2026-07-14 (batch #8 follow-up): Saleem asked for the full sidebar menu
     to be hidden on mobile entirely (not just stacked below the content),
     keeping only the same quick-links row the Dashboard already has for
     navigation - see .mobile-quick-links below and the macro in
     _quick_links.html. Previously this just stacked the sidebar under the
     content, which was still a lot of nav to scroll past on a phone. */
  .sidebar { display: none; }
  .content { padding: 16px; }
  .grid-3 { grid-template-columns: 1fr; }
  .topbar { flex-direction: column; align-items: flex-start; gap: 8px; }
  .topbar .user a { margin-left: 0; margin-right: 14px; }
  /* 2026-07-14 (batch #10): Saleem asked to remove Settings/Billing/Log out
     from the mobile topbar entirely, in favor of the mobile-quick-links bar
     below (which already covers day-to-day navigation) - the user's name
     next to these links stays visible, only the three links themselves hide. */
  .topbar .user a.topbar-menu-link { display: none; }
  /* Lets any wide table (Manage Relationships, Recent Activity, etc.) scroll
     horizontally within its own card instead of squeezing/breaking the page
     layout - works for every existing table without touching any of the 34
     templates individually. */
  .card { overflow-x: auto; }

  .mobile-quick-links { display: flex; }
  /* Dashboard's own copy of this same row would otherwise show twice on a
     narrow screen, right below the always-visible one in the topbar. */
  .quick-links-desktop-only { display: none; }
}

/* 2026-07-14 (batch #8 follow-up): "Single Relationship" combobox (Send
   Email, Print Letters) - see initContactCombobox() in app.js. */
.combobox { position: relative; }
.combobox-suggestions {
  display: none;
  position: absolute;
  z-index: 30;
  top: 100%;
  left: 0;
  right: 0;
  max-height: 220px;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0,0,0,.12);
  margin-top: 2px;
}
.combobox-item {
  padding: 8px 12px;
  font-size: 14px;
  cursor: pointer;
}
.combobox-item:hover { background: #eaf1fc; }

/* 2026-07-22 (Manage Teams): "pending member" chips shown while building up
   a team's member list (either at creation time, or a small standalone
   badge list of current members on the team detail page). */
.pending-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #eaf1fc;
  color: var(--blue-dark, #1a5cb8);
  border-radius: 14px;
  padding: 4px 6px 4px 12px;
  font-size: 13px;
  margin: 3px 4px 3px 0;
}
.pending-chip button {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0 4px;
}

/* 2026-07-15 (batch #16): generic sortable-table headers - see
   initSortableTables() in app.js. Works on any table[data-sortable]. */
th.sortable-col {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
th.sortable-col:hover { background: #eef2f7; }
th.sortable-col::after { content: "\2195"; opacity: .35; margin-left: 4px; font-size: 11px; }
th.sortable-col.sorted-asc::after { content: "\2191"; opacity: 1; }
th.sortable-col.sorted-desc::after { content: "\2193"; opacity: 1; }

/* 2026-07-15 (batch #17): progress bar for bulk email sends / letter
   generation - see bulk_job_progress.html. Plain CSS, no library. */
.progress-bar-track {
  width: 100%;
  height: 18px;
  background: #e6e9ee;
  border-radius: 9px;
  overflow: hidden;
}
.progress-bar-fill {
  height: 100%;
  background: var(--blue, #2f6fed);
  transition: width .3s ease;
}

/* 2026-07-20: public marketing site (landing/about/contact) - deliberately
   a distinct navy/gold palette matching the actual logo, rather than
   reusing the app's own --blue theme. This only ever renders for a
   logged-out visitor (see base.html's {% if user %} gate, which hides the
   app's sidebar/topbar entirely in that case), so there's no clash between
   this palette and the logged-in app UI on the same page. */
.marketing { --mk-navy: #0b2d5c; --mk-navy-dark: #081f42; --mk-gold: #f2c200; }

.marketing-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 32px;
  background: var(--mk-navy);
}
.marketing-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #fff;
  font-weight: 700;
  font-size: 18px;
}
.marketing-brand img { height: 40px; width: 40px; }
.marketing-nav-links { display: flex; align-items: center; gap: 22px; }
.marketing-nav-links a { color: #dce8ff; font-weight: 500; }
.marketing-nav-links a:hover { color: #fff; }
.marketing-nav-links a.active { color: var(--mk-gold); }
.marketing-nav-links a.btn {
  color: var(--mk-navy-dark);
  background: var(--mk-gold);
  border-color: var(--mk-gold);
  font-weight: 700;
  padding: 8px 18px;
}
.marketing-nav-links a.btn:hover { background: #ffd633; border-color: #ffd633; }

.marketing-hero {
  background: linear-gradient(180deg, var(--mk-navy) 0%, var(--mk-navy-dark) 100%);
  color: #fff;
  text-align: center;
  padding: 70px 24px 60px;
}
.marketing-hero h1 { font-size: 34px; max-width: 780px; margin: 0 auto 18px; line-height: 1.25; }
.marketing-hero p { max-width: 640px; margin: 0 auto; color: #cfdcf2; font-size: 16px; line-height: 1.6; }
.marketing-hero-actions { margin-top: 28px; display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }
.marketing-hero-actions .btn { background: var(--mk-gold); color: var(--mk-navy-dark); border-color: var(--mk-gold); font-weight: 700; }
.marketing-hero-actions .btn:hover { background: #ffd633; border-color: #ffd633; }
.marketing-hero-actions .btn.secondary { background: transparent; color: #fff; border-color: rgba(255,255,255,.6); }
.marketing-hero-actions .btn.secondary:hover { background: rgba(255,255,255,.1); }

/* 2026-07-23 follow-up: switched from a CSS grid to a centered flexbox
   layout per Saleem's request ("Center tiles on screen... if in one row two
   [rows of] 4 tiles and second 2 tiles, second row should be centered").
   A CSS grid's auto-fit columns always left-align a short last row; a
   flex-wrap row with justify-content:center naturally centers whatever's
   left on that final row instead - exactly what was asked for. Mobile (one
   card per row) is unaffected: flex-grow still fills the full row width
   there, same as the grid's 1fr columns did before. */
.marketing-features {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  padding: 50px 32px;
  max-width: 1100px;
  margin: 0 auto;
}
.marketing-feature-card {
  flex: 1 1 230px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px 20px;
  text-align: center;
}
/* Above the mobile breakpoint, cap each card's width instead of letting it
   stretch to fill leftover row space - a short last row (e.g. 2 cards) then
   sits centered at its natural size rather than growing to fill the row. */
@media (min-width: 701px) {
  .marketing-feature-card { flex-grow: 0; max-width: 260px; }
}
.marketing-feature-icon { font-size: 30px; margin-bottom: 10px; }
.marketing-feature-card h3 { margin: 0 0 8px; font-size: 16px; color: var(--mk-navy); }
.marketing-feature-card p { margin: 0; font-size: 14px; color: var(--muted); line-height: 1.55; }

/* 2026-07-22: "see it in action" screenshot gallery, per Saleem's request
   ("Can Claude add several screen shots in zoom in fashion when someone
   clicks on a screen shots like www.aioapp.com as an example"). Plain CSS
   grid of thumbnails + a vanilla-JS lightbox modal below - no new library,
   same pattern this project already uses for every other interactive bit
   (comboboxes, toggles, etc.). */
.marketing-gallery { padding: 10px 32px 60px; max-width: 1100px; margin: 0 auto; text-align: center; }
.marketing-gallery h2 { color: var(--mk-navy); margin-bottom: 8px; }
.marketing-gallery > p { color: var(--muted); max-width: 640px; margin: 0 auto 30px; }
.marketing-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}
.marketing-gallery-item {
  display: block;
  width: 100%;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  text-align: left;
  cursor: zoom-in;
  padding: 0;
  font: inherit;
  color: inherit;
  transition: box-shadow .15s ease, transform .15s ease;
}
.marketing-gallery-item:hover { box-shadow: 0 8px 22px rgba(11,45,92,0.18); transform: translateY(-2px); }
.marketing-gallery-thumb {
  display: block;
  width: 100%;
  height: 160px;
  object-fit: cover;
  object-position: top;
  background: #f1f4f9;
  border-bottom: 1px solid var(--border);
}
/* The two sidebar-menu screenshots are tall/narrow instead of wide
   screenshots, so they get "contain" framing (letterboxed on a white
   background) instead of being cropped like the full-page shots above. */
.marketing-gallery-item.is-menu .marketing-gallery-thumb { object-fit: contain; background: #fff; padding: 10px; }
.marketing-gallery-caption { padding: 12px 14px; font-size: 14px; font-weight: 600; color: var(--mk-navy); }

/* Lightbox / zoom overlay - opened via openGalleryLightbox() in landing.html. */
.marketing-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(8,31,66,0.9);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 70px 20px 30px;
}
.marketing-lightbox.is-open { display: flex; }
.marketing-lightbox-inner { position: relative; max-width: 1100px; width: 100%; text-align: center; }
.marketing-lightbox-inner img {
  max-width: 100%;
  max-height: 74vh;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
.marketing-lightbox-caption { color: #fff; margin-top: 16px; font-size: 15px; }
.marketing-lightbox-close {
  position: fixed;
  top: 18px;
  right: 24px;
  background: none;
  border: none;
  color: #fff;
  font-size: 34px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 10px;
}
.marketing-lightbox-close:hover { color: var(--mk-gold); }

.marketing-pricing { padding: 20px 32px 60px; max-width: 1000px; margin: 0 auto; text-align: center; }
.marketing-pricing h2 { color: var(--mk-navy); margin-bottom: 30px; }
.marketing-pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}
.marketing-pricing-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 26px 20px;
}
.marketing-pricing-card h3 { margin: 0 0 6px; color: var(--mk-navy); }
.marketing-price { font-size: 30px; font-weight: 700; color: var(--mk-navy); margin-bottom: 14px; }
.marketing-price span { font-size: 14px; font-weight: 400; color: var(--muted); }
.marketing-pricing-card ul { list-style: none; padding: 0; margin: 0 0 18px; text-align: left; }
.marketing-pricing-card li { padding: 5px 0; font-size: 14px; color: var(--text); }
.marketing-pricing-card li::before { content: "\2713 "; color: var(--green); font-weight: 700; }

.marketing-cta-banner {
  background: var(--mk-navy-dark);
  color: #fff;
  text-align: center;
  padding: 50px 24px;
}
.marketing-cta-banner h2 { margin: 0 0 8px; }
.marketing-cta-banner p { margin: 0 0 20px; color: #cfdcf2; }
.marketing-cta-banner .btn { background: var(--mk-gold); color: var(--mk-navy-dark); border-color: var(--mk-gold); font-weight: 700; }
.marketing-cta-banner .btn:hover { background: #ffd633; border-color: #ffd633; }

.marketing-page { max-width: 720px; margin: 50px auto; padding: 0 24px 60px; }
.marketing-page h1 { color: var(--mk-navy); }
.marketing-page p { line-height: 1.7; color: var(--text); }
/* Contact form's submit button - the marketing site's own gold/navy accent
   rather than the app's default --blue, so it matches the rest of this page
   instead of looking like a stray app-internal button. */
.marketing-page .marketing-submit { background: var(--mk-navy); border-color: var(--mk-navy); }
.marketing-page .marketing-submit:hover { background: var(--mk-navy-dark); border-color: var(--mk-navy-dark); }

@media (max-width: 700px) {
  .marketing-nav { flex-direction: column; gap: 14px; align-items: flex-start; }
  .marketing-nav-links { flex-wrap: wrap; gap: 14px; }
  .marketing-hero h1 { font-size: 26px; }
  .marketing-gallery-thumb { height: 130px; }
  .marketing-lightbox-close { top: 8px; right: 10px; font-size: 30px; }
}

/* Meeting Scheduler (2026-07-20) - the public /book/<token> slot-picker and
   the agent-facing /scheduler management page share these classes. */
.slot-day { margin-bottom: 18px; }
.slot-day-label { font-weight: 600; margin-bottom: 8px; }
.slot-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.slot-btn {
  padding: 8px 14px; border: 1px solid var(--border); border-radius: 6px; background: #fff;
  cursor: pointer; font-size: 14px; color: var(--text);
}
.slot-btn:hover { border-color: var(--blue); color: var(--blue); }
.slot-btn.selected { background: var(--blue); border-color: var(--blue); color: #fff; }
.booking-details { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border); display: none; }
.booking-details.visible { display: block; }
.no-slots-message { color: var(--muted); padding: 20px 0; }

.avail-rule-row, .avail-slot-row, .avail-block-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.avail-rule-row:last-child, .avail-slot-row:last-child, .avail-block-row:last-child { border-bottom: none; }
.avail-inline-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0; }
.avail-inline-form input, .avail-inline-form select { width: auto; }
.booking-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.booking-row:last-child { border-bottom: none; }
.booking-status-badge { padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; }
.booking-status-badge.upcoming { background: #e6f7ec; color: #1e7e37; }
.booking-status-badge.past { background: #f0f0f0; color: #666; }
.booking-status-badge.canceled { background: #fdeaea; color: #c0272b; }
