/* ---------- Design tokens ---------- */
:root {
  --bg: #eef1f6;
  --surface: #ffffff;
  --surface-2: #f3f6fa;
  --border: #dbe2ea;
  --ink: #1a2433;
  --ink-soft: #57667a;
  --ink-faint: #8a97a8;
  --accent: #2b5b8c;
  --accent-ink: #ffffff;
  --accent-soft: #e6eef7;
  --accent-strong: #1c3e60;
  --amber: #b6790a;
  --amber-soft: #fbf0dc;
  --red: #b5432f;
  --red-soft: #fbe7e2;
  --blue: #2b5b8c;
  --blue-soft: #e6eef7;
  --slate: #5b7a99;
  --slate-soft: #e9eef4;
  --green: #1f8a4c;
  --green-soft: #dcefe3;
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;
  --shadow-sm: 0 1px 2px rgba(26, 36, 51, 0.07), 0 1px 1px rgba(26,36,51,0.05);
  --shadow: 0 8px 24px rgba(26, 36, 51, 0.09), 0 2px 6px rgba(26,36,51,0.05);
  --shadow-lg: 0 16px 40px rgba(26, 36, 51, 0.16);
  --nav-h: 64px;
  --topbar-h: 60px;
  --sidebar-w: 240px;
  font-size: 16px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.01em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; display: block; }

/* Baseline icon size — every inline <svg> gets a sane default unless a more
   specific rule below overrides it. Without this, an unsized SVG falls back
   to the browser's default replaced-element size, which renders enormous. */
svg { width: 16px; height: 16px; flex-shrink: 0; vertical-align: -3px; }

/* The browser's own [hidden] rule loses to any author rule that sets display —
   .btn, .nav-subsub and friends all do, so setting el.hidden silently did
   nothing. This has caused the same bug four separate times; making it global
   means `hidden` always means hidden. */
[hidden] { display: none !important; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: #c6d0dc; border-radius: 8px; }

/* ---------- Layout shells ---------- */
#app { min-height: 100%; }

.shell-cleaner {
  max-width: 560px;
  margin: 0 auto;
  min-height: 100vh;
  background: var(--bg);
  padding-bottom: calc(var(--nav-h) + 18px);
}

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

/* ---------- Auth pages (login / signup / cleaner login / set password) ---------- */
.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 32px 28px;
}

/* ---------- Public booking page (#/book/:slug — publicBooking.js) ---------- */
.public-book-shell { min-height: 100vh; background: var(--bg); padding: 40px 16px 60px; }
.public-book-wrap { max-width: 620px; margin: 0 auto; }
.public-book-header { text-align: center; margin-bottom: 28px; }
.public-book-header .brand-mark { margin: 0 auto 14px; width: 44px; height: 44px; font-size: 20px; }
.public-book-header h1 { font-size: 22px; margin-bottom: 4px; }
.service-pick-card { cursor: pointer; border: 1px solid var(--border); transition: border-color 0.15s, box-shadow 0.15s; }
.service-pick-card:hover { border-color: var(--accent); }
.service-pick-card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.public-book-back { font-size: 13px; font-weight: 600; color: var(--accent); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; margin-bottom: 14px; }
.auth-title { font-size: 19px; font-weight: 800; margin-bottom: 18px; }
.auth-error {
  background: var(--red-soft); color: var(--red); font-size: 13px; font-weight: 600;
  border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 16px;
}
.auth-links { margin-top: 18px; display: flex; flex-direction: column; gap: 10px; text-align: center; }
.auth-links a { font-size: 13px; color: var(--accent); font-weight: 600; text-decoration: none; }
.auth-links a:hover { text-decoration: underline; }

/* Full-screen branded moment shown right after a successful login/signup, in
   place of the form, before landing on the dashboard — see auth.js
   renderAuthTransition(). */
@keyframes brandPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }
.auth-transition {
  min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; background: var(--bg); animation: contentFadeIn 0.25s ease-out;
}
.auth-transition .brand-mark { width: 48px; height: 48px; border-radius: 14px; font-size: 20px; animation: brandPulse 1.1s ease-in-out infinite; }
.auth-transition-label { font-size: 13px; font-weight: 600; color: var(--ink-faint); }

.owner-sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: #262b33;
  border-right: 1px solid #313742;
  padding: 22px 14px;
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Dark sidebar means every text/hover/active color inherited from the light-theme
   defaults needs its own scoped override here — otherwise nav labels, dividers, and
   section headers (all tuned for a white background) go near-invisible. */
.owner-sidebar .brand-name { color: #f2f3f5; }
.owner-sidebar .brand-sub { color: #8b93a1; }
.owner-sidebar .side-nav a { color: #aab0bb; }
.owner-sidebar .side-nav a:hover { background: rgba(255,255,255,0.07); color: #f2f3f5; }
.owner-sidebar .side-nav a.active { background: var(--accent); color: #fff; }
.owner-sidebar .side-nav .divider { background: #3a4049; }
.owner-sidebar .side-nav .section-label { color: #767d8a; }
.owner-sidebar .side-nav .sub-nav { border-left-color: #3a4049; }
.owner-sidebar .side-nav .sub-nav a.sub-nav-pressing { background: rgba(255,255,255,0.07); }
.owner-sidebar .side-nav .sub-nav a.sub-nav-dragging { background: #2f353e; box-shadow: 0 6px 16px rgba(0,0,0,0.35); }
.owner-sidebar .sidebar-footer { border-top-color: #3a4049; }
.owner-sidebar .settings-link { color: #aab0bb; }
.owner-sidebar .settings-link:hover { background: rgba(255,255,255,0.07); color: #f2f3f5; }
.owner-sidebar .settings-link.active { background: var(--accent); color: #fff; }

.owner-main {
  flex: 1;
  min-width: 0;
  padding: 28px 32px 80px;
}

/* Pushes the whole page down by the fixed update-banner's height instead of letting
   it overlap the sticky sidebar/topbar — set on <body> and read by app.js once the
   banner's real rendered height is known. */
body.has-update-banner { padding-top: var(--update-banner-h, 0px); }
body.has-update-banner .owner-sidebar { top: var(--update-banner-h, 0px); height: calc(100vh - var(--update-banner-h, 0px)); }
body.has-update-banner .topbar { top: var(--update-banner-h, 0px); }

@media (max-width: 860px) {
  .owner-sidebar { display: none; }
  .owner-main { padding: 18px 16px 90px; }
}

/* ---------- Brand ---------- */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px 22px;
}
.brand-mark {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 16px;
  flex-shrink: 0;
}
.brand-name { font-size: 15px; font-weight: 800; color: var(--ink); line-height: 1.2; }
.brand-sub { font-size: 10.5px; font-weight: 700; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-top: 1px; }

/* ---------- Top bar (cleaner) ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(238,241,246,0.9);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  padding: 14px 18px;
  display: flex; align-items: center; justify-content: space-between;
}
.topbar-title { font-size: 20px; font-weight: 800; }
.topbar-sub { font-size: 13px; color: var(--ink-soft); }

/* ---------- Bottom nav (mobile / cleaner) ---------- */
.bottom-nav {
  position: fixed; bottom: 0; left: 0; right: 0;
  max-width: 560px; margin: 0 auto;
  height: var(--nav-h);
  background: var(--surface);
  border-top: 1px solid var(--border);
  display: flex;
  z-index: 30;
  box-shadow: 0 -6px 20px rgba(33,31,28,0.06);
}
.bottom-nav a {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; font-size: 11px; color: var(--ink-faint); font-weight: 600;
}
.bottom-nav a.active { color: var(--accent); }
.bottom-nav svg { width: 22px; height: 22px; }

/* ---------- Owner sidebar nav ---------- */
.side-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 600; color: var(--ink-soft);
  margin-bottom: 2px;
}
.side-nav a svg { width: 18px; height: 18px; flex-shrink: 0; }
.side-nav a:hover { background: var(--surface-2); color: var(--ink); }
.side-nav a.active { background: var(--accent-soft); color: var(--accent-strong); }
.side-nav .divider { height: 1px; background: var(--border); margin: 12px 4px; }
.side-nav .section-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-faint); padding: 14px 12px 6px; font-weight: 700; }
@keyframes subNavDropdown {
  from { opacity: 0; max-height: 0; transform: translateY(-6px); }
  to { opacity: 1; max-height: 240px; transform: translateY(0); }
}
.side-nav .sub-nav {
  margin-top: 2px; padding-left: 10px; border-left: 1.5px solid var(--border); margin-left: 22px;
  display: flex; flex-direction: column; gap: 2px;
  overflow: hidden;
  animation: subNavDropdown 0.22s ease-out;
  transform-origin: top;
}
.side-nav .sub-nav a {
  font-size: 13px; padding: 8px 10px; user-select: none;
  -webkit-user-drag: none; user-drag: none;
}
.side-nav .sub-nav a svg { width: 16px; height: 16px; }
/* These land on the row, which is an <a> for a plain item and a wrapper div for
   one that has its own drawer. */
.side-nav .sub-nav .sub-nav-pressing { background: var(--surface-2); border-radius: var(--radius-sm); }
.side-nav .sub-nav .sub-nav-dragging {
  cursor: grabbing;
  box-shadow: 0 6px 16px rgba(0,0,0,0.18);
  background: var(--surface);
  border-radius: var(--radius-sm);
  opacity: 0.96;
  scale: 1.02;
}

/* ---------- Collapsible nav drawer (Bookkeeping under Payments) ---------- */
.nav-caret {
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin-left: 4px; flex-shrink: 0;
  border-radius: 4px; color: var(--ink-faint);
  transition: transform 0.18s ease, background 0.15s ease, color 0.15s ease;
}
.nav-caret:hover { background: var(--surface-2); color: var(--ink); }
.nav-caret svg { width: 14px !important; height: 14px !important; }
.nav-disclosure.open > a > .nav-caret { transform: rotate(90deg); }
/* No badge on these rows, so nothing pushes the caret right on its own. */
.nav-disclosure > a > .nav-badge-slot { margin-left: auto; }
.nav-subsub {
  margin: 2px 0 2px 22px; padding-left: 10px;
  border-left: 1.5px solid var(--border);
  display: flex; flex-direction: column; gap: 2px;
  overflow: hidden;
  animation: subNavDropdown 0.2s ease-out;
}
.side-nav .nav-subsub a { font-size: 13px; padding: 7px 10px; }
.side-nav .nav-subsub a svg { width: 15px; height: 15px; }

.sidebar-footer { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 10px; }
.settings-link { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 14px; font-weight: 600; color: var(--ink-soft); }
.settings-link svg { width: 18px; height: 18px; flex-shrink: 0; }
.settings-link:hover { background: var(--surface-2); color: var(--ink); }
.settings-link.active { background: var(--accent-soft); color: var(--accent-strong); }
.role-switch { display: flex; justify-content: center; }
.role-switch button { width: auto; }
.nav-badge-slot { margin-left: auto; display: flex; align-items: center; }
.nav-badge { background: var(--accent); color: #fff; font-size: 10.5px; font-weight: 800; padding: 1px 7px; border-radius: 999px; line-height: 1.6; }
.side-nav a.active .nav-badge { background: var(--accent-strong); }

/* ---------- Page header ---------- */
.page-header {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 14px;
  margin-bottom: 22px; flex-wrap: wrap;
}
.page-header h1 { font-size: 26px; }
.page-header .desc { color: var(--ink-soft); font-size: 14px; margin-top: 4px; }

/* ---------- Cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 12px; }
/* ...except inside a grid, where cards sit side-by-side, not stacked — the grid's own
   `gap` already handles spacing there. Without this override, .card + .card's margin
   still fires on grid siblings and pushes every card after the first down within its
   row, throwing rows out of alignment ("jumping" cards). */
.grid > .card, .bottom-trio > .card, .dash-2col > .card, .cc-chart-row > .card { margin-top: 0; }
.card-title { font-size: 15px; font-weight: 700; margin-bottom: 2px; display: flex; align-items: center; gap: 8px; }
.card-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

/* Uniform sizing for grid cards (Operations, Settings, Properties) so blocks
   don't grow/shrink with description length or content amount — fixed height,
   not just a floor, so every card matches exactly regardless of page. */
.card-tile { display: flex; flex-direction: column; height: 128px; box-sizing: border-box; overflow: hidden; }
.card-tile .faint.small { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- Row lists (Services list, section menus) — clean bordered rows
   inside one card, no per-row shadow, matching a "settings menu" layout. ---------- */
.row-list { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.row-list-item {
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.12s ease;
}
.row-list-item:last-child { border-bottom: none; }
.row-list-item:hover { background: var(--surface-2); }
.row-list-icon {
  width: 38px; height: 38px; border-radius: 10px; background: var(--surface-2);
  color: var(--ink-soft); display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.row-list-icon svg { width: 18px; height: 18px; }
.row-list-body { flex: 1; min-width: 0; }
.row-list-title { font-size: 14.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.row-list-count { font-size: 11px; font-weight: 700; color: var(--ink-soft); background: var(--surface-2); padding: 2px 8px; border-radius: 999px; }
.row-list-desc { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.row-list-meta { font-size: 13px; color: var(--ink-soft); margin-top: 2px; }
.row-list-side { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.row-list-chevron { color: var(--ink-soft); flex-shrink: 0; }
.row-list-chevron svg { width: 16px; height: 16px; }
.status-dot-label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.status-dot-label svg { width: 9px; height: 9px; }
.status-dot-label.on svg { color: #2f9e5e; }
.status-dot-label.off svg { color: var(--ink-soft); }
.drag-handle { color: var(--ink-soft); cursor: grab; flex-shrink: 0; }
.drag-handle svg { width: 14px; height: 14px; }

/* ---------- Modifier group cards (Pricing Modifiers section) — each tier
   shown as a small pill/chip rather than buried in an edit form, so the
   owner can see the whole price ladder for a group at a glance. ---------- */
.modgroup-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; margin-bottom: 12px; }
.modgroup-card-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.modgroup-card-title { font-size: 15px; font-weight: 700; }
.modgroup-card-actions { display: flex; gap: 8px; flex-shrink: 0; }
.chip-wrap { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: baseline; gap: 6px; background: var(--surface-2);
  border-radius: 8px; padding: 7px 12px; font-size: 12.5px; white-space: nowrap;
}
.chip .chip-label { font-weight: 700; color: var(--ink); }
.chip .chip-meta { color: var(--ink-soft); font-weight: 600; }
.dashed-add-btn {
  width: 100%; border: 1.5px dashed var(--border); border-radius: var(--radius);
  background: transparent; padding: 16px; font-size: 14px; font-weight: 700;
  color: var(--ink-soft); cursor: pointer; transition: border-color 0.12s ease, color 0.12s ease;
}
.dashed-add-btn:hover { border-color: var(--accent); color: var(--accent); }

/* ---------- Entity cards (Add-ons / Intake Questions rows) — a single-row
   summary card: drag handle, icon, title + meta line, Edit/trash actions.
   Same visual language as modgroup-card but flat (no nested chip list),
   matching Zenbooker's intake-question row layout. ---------- */
.entity-card {
  display: flex; align-items: center; gap: 12px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 8px;
}
.entity-card-actions { display: flex; gap: 8px; flex-shrink: 0; margin-left: auto; }

/* Zenbooker's service-detail rows use bare, bold, dark icons — no rounded
   background box — unlike the boxed icons on the flat Services list page.
   Scoped to the hub's own section headers + row cards so the top-level
   Services/Online Booking list icons (which DO use the boxed style,
   matching Zenbooker's list view) are left untouched. */
.hub-section-head .row-list-icon,
.entity-card .row-list-icon {
  width: auto; height: auto; background: transparent; color: var(--ink); flex-shrink: 0;
}
.hub-section-head .row-list-icon svg,
.entity-card .row-list-icon svg { width: 22px; height: 22px; stroke-width: 2; }

/* ---------- Hub accordion sections (Service Details / Pricing Modifiers /
   Add-ons / Intake Questions) — each is its own bordered card; clicking the
   header expands its body in place, with an accent border+glow on whichever
   one is open, matching Zenbooker's own expand-in-place service page.
   The body's content is always rendered (see ownerServices.js) — only its
   max-height animates open/closed, so there's no flash/rebuild on toggle. ---------- */
.hub-section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 12px; overflow: hidden; transition: border-color 0.15s ease, box-shadow 0.15s ease; }
.hub-section.expanded { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.hub-section-head { display: flex; align-items: center; gap: 14px; padding: 16px 18px; cursor: pointer; }
.hub-section-head:hover { background: var(--surface-2); }
.hub-section.expanded .hub-section-head:hover { background: transparent; }
.hub-section.expanded .row-list-desc { display: none; }
.hub-chevron svg { transition: transform 0.2s ease; }
.hub-section.expanded .hub-chevron svg { transform: rotate(90deg); }
.hub-section-body { max-height: 0; overflow: hidden; transition: max-height 0.28s cubic-bezier(0.4, 0, 0.2, 1); }
.hub-section-inner { padding: 16px 18px 18px; border-top: 1px solid var(--border); margin: 0 18px; }

/* ---------- Zenbooker-parity CRM pages (Customers / Estimates / Payments /
   Coupons / Territories / Recurring) ---------- */
.cust-avatar {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  border-radius: 50%; color: #fff; font-weight: 700; letter-spacing: 0.02em;
}
.cust-detail-grid { display: grid; grid-template-columns: 280px 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .cust-detail-grid { grid-template-columns: 1fr; } }
.cust-detail-grid .row-list-item:last-child { border-bottom: none !important; }

.est-metric-row { display: flex; align-items: center; gap: 10px; }
.est-metric-card { flex: 1; }
.est-metric-arrow { color: var(--ink-soft); flex-shrink: 0; }
.est-metric-arrow svg { width: 18px; height: 18px; }
.est-table-head, .est-table-row {
  display: grid; grid-template-columns: 1.4fr 2fr 1fr 1fr 0.9fr 1.4fr;
  gap: 10px; align-items: center; padding: 12px 18px; font-size: 13px;
}
.est-table-head {
  border-bottom: 1px solid var(--border); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft);
}
.est-table-row { border-bottom: 1px solid var(--border); }
.est-table-row:last-child { border-bottom: none; }
.est-expired { color: var(--red); font-weight: 600; }
.est-row-actions { display: flex; gap: 6px; justify-content: flex-end; }

.pay-stats-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.pay-stats { display: flex; gap: 28px; text-align: right; }

.terr-layout { display: grid; grid-template-columns: 320px 1fr; gap: 26px; align-items: start; }
@media (max-width: 1000px) { .terr-layout { grid-template-columns: 1fr; } }
.terr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 16px; }
.terr-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; cursor: pointer; transition: box-shadow 0.12s ease, border-color 0.12s ease;
}
.terr-card:hover { border-color: var(--accent); box-shadow: var(--shadow); }
.terr-map { height: 150px; background: var(--surface-2); position: relative; }
.terr-map-empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; text-align: center; padding: 14px; }
.terr-card-body { padding: 14px 16px 16px; }
.terr-facts { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; }
.terr-facts > div { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.terr-fact-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft); }

/* ---------- Dashboard "Today" card (cleaning_co) — Zenbooker-parity: header
   with territory filter + schedule stats, then job list beside a live map. ---------- */
.cc-today-card { padding: 0 !important; overflow: hidden; }
.cc-today-head {
  display: flex; align-items: center; gap: 18px; padding: 18px 22px;
  border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.cc-today-title { font-size: 20px; font-weight: 800; }
.cc-today-stats { display: flex; gap: 30px; margin-left: auto; text-align: left; }
.cc-stat-value { font-size: 19px; font-weight: 800; }
.cc-today-split { display: grid; grid-template-columns: 1fr 44%; min-height: 380px; }
@media (max-width: 1000px) { .cc-today-split { grid-template-columns: 1fr; } }
.cc-today-list { padding: 6px 22px 14px; min-width: 0; }
.cc-today-map { position: relative; background: var(--surface-2); border-left: 1px solid var(--border); min-height: 380px; }
@media (max-width: 1000px) { .cc-today-map { border-left: none; border-top: 1px solid var(--border); min-height: 260px; } }

/* ---------- Quick Tools dropdown (ScheduleDrop-style header menu) ---------- */
.quick-tools { position: relative; display: inline-block; }
.quick-tools-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 50; min-width: 210px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.14); padding: 6px; display: flex; flex-direction: column;
}
.quick-tools-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: transparent; border: none; padding: 9px 10px; border-radius: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.quick-tools-menu button:hover { background: var(--surface-2); color: var(--accent); }
.quick-tools-menu button svg { width: 17px; height: 17px; color: var(--ink-soft); }
.quick-tools-menu button:hover svg { color: var(--accent); }

/* ---------- Dashboard booking-status metrics (ScheduleDrop "Bookings" cards) ---------- */
.cc-bookings-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.cc-bookings-title { font-size: 17px; font-weight: 800; }
.cc-bookings-pills { display: inline-flex; gap: 6px; }
.cc-bk-pill {
  font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--ink-soft); border: 1px solid var(--border);
}
.cc-bk-pill b { color: var(--ink); margin-left: 4px; }
.cc-bk-pill.warn { background: #fff4e5; border-color: #f5c98a; color: #b26a00; }
.cc-bk-pill.warn b { color: #b26a00; }
.cc-bk-range { margin-left: auto; }
.cc-bk-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 900px) { .cc-bk-grid { grid-template-columns: repeat(2, 1fr); } }
.cc-bk-card {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.cc-bk-card .cc-bk-num { font-size: 30px; font-weight: 800; line-height: 1; }
.cc-bk-card .cc-bk-label { font-size: 12.5px; font-weight: 700; margin-top: 6px; color: var(--ink-soft); }
.cc-bk-card .cc-bk-ico { width: 30px; height: 30px; opacity: 0.85; }
.cc-bk-card .cc-bk-ico svg { width: 30px; height: 30px; }
.cc-bk-green { background: #e9f8ef; border-color: #bfe6cd; } .cc-bk-green .cc-bk-num, .cc-bk-green .cc-bk-ico { color: #1f9d55; }
.cc-bk-blue { background: #e8f1fb; border-color: #c2dbf3; } .cc-bk-blue .cc-bk-num, .cc-bk-blue .cc-bk-ico { color: #2b6cb0; }
.cc-bk-amber { background: #fdf4e3; border-color: #f2d9a8; } .cc-bk-amber .cc-bk-num, .cc-bk-amber .cc-bk-ico { color: #b7791f; }
.cc-bk-red { background: #fdecec; border-color: #f4c4c4; } .cc-bk-red .cc-bk-num, .cc-bk-red .cc-bk-ico { color: #c53030; }

/* Assigned / unassigned pill on a today's-booking row */
.assign-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; }
.assign-pill.assigned { background: #e9f8ef; color: #1f7a44; }
.assign-pill.unassigned { background: #fdf4e3; color: #b7791f; }
.assign-pill svg { width: 12px; height: 12px; }

.hub-header { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 18px; flex-wrap: wrap; }
.hub-back { font-size: 13px; font-weight: 600; color: var(--accent); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; margin-bottom: 8px; }
.hub-title { font-size: 24px; font-weight: 800; }

/* ---------- Settings hub (Zenbooker-parity replica) — top user/billing row,
   then grouped sections (Business / Scheduling & Booking / Communications /
   Invoicing & Payments / Integrations & Advanced), each a 2-col grid of
   compact clickable cards with a colored icon tile, title, and description.
   Zenbooker caps the whole hub to a fairly narrow column rather than
   stretching cards across the full page — capped here too so cards stay
   compact, roughly-square blocks instead of long full-width bars. ---------- */
.settings-hub-wrap { max-width: 800px; margin: 0 auto; }
.settings-hub-wrap + .settings-hub-wrap,
.settings-hub-header { max-width: 800px; margin: 0 auto; }
.settings-top-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 24px; }
@media (max-width: 700px) { .settings-top-row { grid-template-columns: 1fr; } }
.settings-top-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; cursor: pointer; transition: background 0.12s ease;
}
.settings-top-card:hover { background: var(--border); }
.settings-top-card-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.settings-top-card .avatar { width: 36px; height: 36px; border-radius: 8px; flex-shrink: 0; font-size: 13px; }
.settings-top-title { font-weight: 700; font-size: 14.5px; }
.settings-top-desc { font-size: 12.5px; color: var(--ink-soft); margin-top: 1px; }
.settings-top-card .row-list-chevron svg { width: 16px; height: 16px; }

.settings-section-label { font-size: 15px; font-weight: 800; color: var(--ink); margin: 24px 0 12px; }
.settings-section-label:first-of-type { margin-top: 0; }

.settings-card-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (max-width: 700px) { .settings-card-grid { grid-template-columns: 1fr; } }

.settings-card {
  display: flex; align-items: center; gap: 14px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px;
  cursor: pointer; transition: box-shadow 0.12s ease, border-color 0.12s ease;
}
.settings-card:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.settings-card-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.settings-card-icon svg { width: 20px; height: 20px; }
.settings-card-title { font-size: 14.5px; font-weight: 700; line-height: 1.25; }
.settings-card-desc { font-size: 12.5px; color: var(--ink-soft); margin-top: 3px; line-height: 1.4; }

.settings-icon-blue { background: #dbeafe; color: #2563eb; }
.settings-icon-purple { background: #ede9fe; color: #7c3aed; }
.settings-icon-green { background: #dcfce7; color: #16a34a; }
.settings-icon-yellow { background: #fef3c7; color: #d97706; }
.settings-icon-pink { background: #fce7f3; color: #db2777; }

/* ---------- Simple settings sub-pages (Branding, Scheduling Policies, etc.) ---------- */
.branding-logo-drop {
  width: 180px; height: 120px; border: 1.5px dashed var(--border); border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  overflow: hidden; background: var(--surface-2); flex-shrink: 0; position: relative;
}
.branding-logo-drop img { max-width: 100%; max-height: 100%; object-fit: contain; }
.color-swatch-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.color-swatch { width: 28px; height: 28px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; flex-shrink: 0; }
.color-swatch.selected { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); }
.settings-subpage-intro { color: var(--ink-soft); font-size: 13.5px; margin-bottom: 18px; max-width: 640px; line-height: 1.5; }

/* ---------- Toggle switch ---------- */
.switch { position: relative; display: inline-block; width: 38px; height: 22px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-track { position: absolute; inset: 0; background: var(--border); border-radius: 999px; cursor: pointer; transition: background 0.15s ease; }
.switch-track::before { content: ""; position: absolute; width: 16px; height: 16px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: transform 0.15s ease; box-shadow: 0 1px 2px rgba(0,0,0,0.2); }
.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track::before { transform: translateX(16px); }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* ---------- Stat tiles ---------- */
.stat-tile { padding: 18px; }
.stat-tile .stat-num { font-size: 28px; font-weight: 800; margin-top: 6px; }
.stat-tile .stat-label { font-size: 12.5px; color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.stat-tile .stat-foot { font-size: 12.5px; color: var(--ink-faint); margin-top: 6px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: none; border-radius: 12px; padding: 11px 18px;
  font-size: 14px; font-weight: 700; cursor: pointer;
  transition: transform 0.08s ease, opacity 0.15s ease, background 0.15s ease;
}
.btn:active { transform: scale(0.97); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-strong); }
.btn-secondary { background: var(--surface-2); color: var(--ink); border: 1px solid var(--border); }
.btn-secondary:hover { background: #e9edf3; }
.btn-ghost { background: transparent; color: var(--accent); padding: 8px 10px; }
.btn-danger { background: var(--red-soft); color: var(--red); }
.btn-block { width: 100%; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; border-radius: 9px; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.icon-btn { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn-danger { background: var(--red-soft); border-color: var(--red-soft); color: var(--red); }

/* ---------- Badges ---------- */
.badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.02em; }
.badge svg { width: 11px; height: 11px; }
.badge-pending { background: var(--blue-soft); color: var(--blue); }
.badge-in_progress { background: var(--amber-soft); color: var(--amber); }
.badge-submitted { background: var(--amber-soft); color: var(--amber); }
.badge-reviewed { background: var(--accent-soft); color: var(--accent-strong); }
.badge-flagged { background: var(--red-soft); color: var(--red); }
.badge-paid { background: var(--accent-soft); color: var(--accent-strong); }
.badge-unpaid { background: var(--red-soft); color: var(--red); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* ---------- Job list card ---------- */
.job-card { display: flex; flex-direction: column; gap: 10px; cursor: pointer; }
.job-card:hover { border-color: #d8d2c4; }
.job-card-top { display: flex; align-items: center; justify-content: space-between; }
.job-unit { font-size: 16px; font-weight: 800; }
.job-meta { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.progress-track { height: 7px; background: var(--surface-2); border-radius: 6px; overflow: hidden; border: 1px solid var(--border); }
.progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent), #5a90c4); border-radius: 6px; transition: width 0.3s ease; }
.progress-label { font-size: 11.5px; color: var(--ink-faint); font-weight: 600; }

/* ---------- Empty state ---------- */
.empty-state { text-align: center; padding: 50px 20px; color: var(--ink-faint); }
.empty-state svg { width: 46px; height: 46px; margin: 0 auto 12px; opacity: 0.5; }
.empty-state .empty-title { font-weight: 700; color: var(--ink-soft); margin-bottom: 4px; }
/* When an empty-state is the only thing rendered into a grid container (e.g. "No
   damage reports" swapped in for the card list), it still becomes a single grid item
   and only occupies the first column/track — leaving it centered within a fraction
   of the row instead of the page, which reads as off-center. Span the full row. */
.grid > .empty-state { grid-column: 1 / -1; }

/* First-paint placeholder while a view's data is being fetched — a real spinner
   rather than bare text, so a slow fetch reads as "loading" instead of "blank
   white page for a second or two". Fades in on its own short delay so a fetch
   that resolves almost instantly never even shows it (avoids a flash-of-spinner
   on fast loads, which would be its own kind of jank). */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes loadingStateIn { from { opacity: 0; } to { opacity: 1; } }
.loading-state {
  text-align: center; padding: 60px 20px; color: var(--ink-faint); font-size: 13px; font-weight: 600;
  animation: loadingStateIn 0.4s ease-out 0.12s both;
}
.loading-state::before {
  content: ''; display: block; width: 26px; height: 26px; margin: 0 auto 14px;
  border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
.grid > .loading-state { grid-column: 1 / -1; }

/* ---------- Page/content transitions ---------- */
/* Applied to the shell's content area (and, at login, the whole app root) each
   time it's rebuilt, so navigating never reads as an abrupt cut — the new
   content eases in instead of just appearing. Deliberately short (an
   animation, not a delay) so it never feels sluggish. */
@keyframes contentFadeIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.content-fade-in { animation: contentFadeIn 0.2s ease-out; }

/* ---------- Checklist ---------- */
.section-block { margin-bottom: 22px; }
.section-title { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); margin-bottom: 10px; }
.section-count { background: var(--surface-2); border: 1px solid var(--border); font-size: 11px; padding: 1px 8px; border-radius: 999px; font-weight: 700; }

.check-item { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; margin-bottom: 10px; }
.check-item.done { border-color: #bcd3ea; background: var(--accent-soft); }
.check-item-top { display: flex; align-items: flex-start; gap: 12px; }
.check-box { width: 24px; height: 24px; border-radius: 8px; border: 2px solid var(--border); flex-shrink: 0; display: flex; align-items: center; justify-content: center; cursor: pointer; background: #fff; margin-top: 1px; }
.check-box.checked { background: var(--accent); border-color: var(--accent); }
.check-box.checked svg { width: 14px; height: 14px; stroke: #fff; }
.check-label { font-size: 14.5px; font-weight: 600; line-height: 1.4; }
.check-hint { font-size: 12.5px; color: var(--ink-faint); margin-top: 2px; }
.check-photo-flag { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--amber); font-weight: 700; margin-top: 6px; }
.check-photo-flag svg { width: 13px; height: 13px; }

.photo-well { margin-top: 12px; margin-left: 36px; }
.photo-tile {
  width: 100%; max-width: 220px; height: 130px; border-radius: 12px;
  border: 1.5px dashed #c3ccd8; background: var(--surface-2);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; color: var(--ink-faint); cursor: pointer; overflow: hidden; position: relative;
}
.photo-tile img { width: 100%; height: 100%; object-fit: cover; }
.photo-tile svg { width: 22px; height: 22px; }
.photo-tile .photo-tile-label { font-size: 11.5px; font-weight: 700; }
.photo-tile.has-photo { border-style: solid; border-color: var(--accent); }
.photo-retake { position: absolute; bottom: 6px; right: 6px; background: rgba(0,0,0,0.55); color: #fff; font-size: 10.5px; padding: 3px 8px; border-radius: 999px; font-weight: 700; }

/* ---------- Par check ---------- */
.par-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.par-row:last-child { border-bottom: none; }
.par-name { font-size: 14px; font-weight: 700; }
.par-trigger { font-size: 12px; color: var(--ink-faint); }
.stepper { display: flex; align-items: center; gap: 10px; }
.stepper button { width: 32px; height: 32px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface-2); font-size: 16px; font-weight: 800; cursor: pointer; }
.stepper input { width: 46px; text-align: center; border: 1px solid var(--border); border-radius: 8px; padding: 6px 4px; font-size: 14px; font-weight: 700; }
.par-low { color: var(--red); font-weight: 800; }

/* ---------- Forms ---------- */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink-soft); margin-bottom: 6px; }
/* App input styling is scoped to .field, so any control outside one falls back to
   browser defaults and looks like a different application. .sd-input opts the
   schedule panel's inline controls into the same look. */
.field input, .field select, .field textarea, .tm-name-input, .sd-input {
  width: 100%; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border);
  font-size: 14px; font-family: inherit; background: #fff; color: var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus, .sd-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
/* The panel rows are label-left / control-right, so the control shouldn't stretch. */
.sched-detail-row .sd-input { width: auto; max-width: 60%; padding: 7px 10px; font-size: 13.5px; }
.sched-detail-header .icon-btn { color: var(--ink-soft); }
.sched-detail-header .icon-btn:hover { color: var(--ink); background: var(--surface-2); }
.field-row { display: flex; gap: 10px; }
.field-row .field { flex: 1; }
.field-hint { font-size: 11.5px; color: var(--ink-faint); margin-top: 4px; }
/* Read-only stand-in for .field input/select — same box, not editable. Used for
   values that are fixed after account creation (e.g. business type). */
.field-static { width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border); font-size: 14px; background: var(--bg); color: var(--ink-soft); }

/* ---------- Table ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th { text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink-faint); font-weight: 700; padding: 8px 12px; border-bottom: 1px solid var(--border); white-space: nowrap; }
td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--surface-2); }

/* ---------- Alerts ---------- */
.alert { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: 12px; font-size: 13px; font-weight: 600; }
.alert-amber { background: var(--amber-soft); color: #8a5c07; }
.alert-red { background: var(--red-soft); color: #8a3323; }
.alert svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }

/* ---------- Modal / sheet ---------- */
@keyframes overlayFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes overlayFadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes sheetFadeIn {
  from { opacity: 0; transform: translateY(16px) scale(0.96); filter: blur(4px); }
  to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
@keyframes sheetFadeOut {
  from { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
  to { opacity: 0; transform: translateY(16px) scale(0.96); filter: blur(4px); }
}
.overlay { position: fixed; inset: 0; background: rgba(20,18,15,0.45); z-index: 100; display: flex; align-items: flex-end; justify-content: center; animation: overlayFadeIn 0.15s ease-out; }
@media (min-width: 640px) { .overlay { align-items: center; } }
.sheet { background: var(--surface); border-radius: 20px 20px 0 0; width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto; padding: 22px; box-shadow: var(--shadow-lg); animation: sheetFadeIn 0.22s cubic-bezier(0.16, 1, 0.3, 1); transform-origin: center; }
.overlay.closing { animation: overlayFadeOut 0.21s ease-in forwards; pointer-events: none; }
.overlay.closing .sheet { animation: sheetFadeOut 0.21s cubic-bezier(0.4, 0, 1, 1) forwards; }
@media (min-width: 640px) { .sheet { border-radius: 20px; } }
/* Zenbooker's own service-detail page runs ~780px wide before it hits its
   sidebar+content max-width — the service hub matches that exactly so a
   section (e.g. Intake Questions) has the same breathing room/line lengths. */
.sheet-wide { max-width: 780px; }
.sheet-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.sheet-header h3 { font-size: 18px; }

/* ---------- Template builder ---------- */
.tmpl-section { border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; margin-bottom: 12px; background: var(--surface-2); }
.tmpl-section-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.tmpl-section-head input { flex: 1; font-weight: 800; font-size: 14.5px; border: none; background: transparent; padding: 4px 2px; }
.tmpl-section-head input:focus { outline: none; background: #fff; border-radius: 6px; }
.tmpl-item-row { display: flex; align-items: center; gap: 8px; background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; margin-bottom: 6px; }
.tmpl-item-row input[type=text] { flex: 1; border: none; font-size: 13.5px; }
.tmpl-item-row input[type=text]:focus { outline: none; }
.photo-toggle { display: flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700; color: var(--ink-faint); cursor: pointer; white-space: nowrap; padding: 4px 8px; border-radius: 8px; }
.photo-toggle svg { width: 12px; height: 12px; }
.photo-toggle.on { color: var(--accent-strong); background: var(--accent-soft); }

/* ---------- Toast ---------- */
.toast { position: fixed; bottom: 90px; left: 50%; transform: translateX(-50%); background: #201e1a; color: #fff; padding: 10px 18px; border-radius: 999px; font-size: 13px; font-weight: 600; z-index: 200; box-shadow: var(--shadow-lg); opacity: 0; transition: opacity 0.25s ease, transform 0.25s ease; pointer-events: none; }
.toast.show { opacity: 1; }
@media (min-width: 861px) { .toast { bottom: 24px; } }

/* ---------- Misc ---------- */
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mb-8 { margin-bottom: 8px; }
.mb-16 { margin-bottom: 16px; }
.mb-24 { margin-bottom: 24px; }
.mt-24 { margin-top: 24px; }
.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.small { font-size: 12.5px; }
.bold { font-weight: 700; }
.center { text-align: center; }
.ta-center { text-align: center; }
.ta-right { text-align: right; }
.min-w-0 { min-width: 0; }
.mono { font-family: 'SFMono-Regular', Menlo, Consolas, monospace; }
.avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--accent-soft); color: var(--accent-strong); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; flex-shrink: 0; }
.avatar svg { width: 55%; height: 55%; }
.link-row { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--border); cursor: pointer; }
.link-row:last-child { border-bottom: none; }
.spacer { flex: 1; }

/* ---------- Dashboard toolbar ---------- */
.dash-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; }
.filter-select { padding: 9px 30px 9px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); font-size: 13.5px; font-weight: 700; color: var(--ink); }
.date-nav { display: flex; align-items: center; gap: 10px; }
.date-label { font-size: 14px; font-weight: 700; min-width: 130px; text-align: center; }

/* ---------- Dashboard "+ New" dropdown ---------- */
.new-menu-wrap { position: relative; }
.new-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60; min-width: 208px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 32px -10px rgba(19, 35, 64, 0.28); padding: 6px; display: flex; flex-direction: column;
}
.new-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: transparent; border: none; border-radius: 8px; padding: 9px 10px;
  font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--text); cursor: pointer;
}
.new-menu button:hover { background: var(--surface-2, #f4f7fb); }
.new-menu button svg { width: 15px; height: 15px; flex: none; opacity: 0.75; }

/* ---------- Dashboard stat cards (ring + legend, horizontal) ---------- */
/* auto-fit so the row always fills evenly whatever the card count is — it was
   pinned at 4 columns, which left a dead slot once Inspection was removed. */
.ring-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
@media (max-width: 900px) { .ring-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .ring-row { grid-template-columns: 1fr; } }
.stat-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 18px;
  padding: 22px 20px; display: flex; align-items: center; gap: 18px; box-shadow: var(--shadow-sm);
  cursor: pointer; position: relative; transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.stat-card:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
/* Matches Lovable's <div className="relative h-28 w-28"> — the WRAPPER carries
   the fixed 112px size (not the svg), so sizing can never depend on the svg's
   own attributes losing a specificity fight with the global icon-reset rule. */
.stat-ring-wrap { position: relative; width: 112px; height: 112px; flex-shrink: 0; }
.stat-ring-wrap svg { display: block; width: 100% !important; height: 100% !important; }
.stat-ring-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.stat-ring-num { font-family: Georgia, 'Times New Roman', serif; font-size: 30px; font-weight: 400; color: var(--ink); line-height: 1; }
.stat-ring-of { font-size: 9.5px; font-weight: 700; color: var(--ink-faint); letter-spacing: 0.08em; margin-top: 4px; }
.stat-info { min-width: 0; flex: 1; }
.stat-title-row { display: flex; align-items: center; gap: 6px; font-family: Georgia, 'Times New Roman', serif; font-size: 17px; font-weight: 700; color: var(--ink); margin-bottom: 12px; }
.stat-title-row svg { width: 13px; height: 13px; color: var(--ink-faint); }
.stat-legend { display: flex; flex-direction: column; gap: 7px; }
.stat-legend-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-soft); font-weight: 500; }
.stat-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.stat-val { margin-left: auto; color: var(--ink); font-weight: 700; }
.stat-card-add { position: absolute; top: 12px; right: 12px; width: 26px; height: 26px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--ink-soft); transition: background 0.12s ease, color 0.12s ease, transform 0.12s ease; z-index: 1; }
.stat-card-add svg { width: 14px; height: 14px; }
.stat-card-add:hover { background: var(--accent); color: #fff; transform: scale(1.06); }

/* ---------- Ready progress dots (table) ---------- */
.ready-dots { display: flex; gap: 4px; }
.ready-dot { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ready-dot svg { width: 10px; height: 10px; stroke: #fff; }
.ready-dot.filled { background: var(--accent); border-color: var(--accent); }

.clickable-row { cursor: pointer; }

/* ---------- Calendar ---------- */
.cal-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.cal-dow { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); text-align: center; padding-bottom: 4px; }
.cal-cell { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; min-height: 108px; padding: 8px; display: flex; flex-direction: column; gap: 4px; }
.cal-cell.outside { background: var(--surface-2); opacity: 0.55; }
.cal-cell.today { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.cal-daynum { font-size: 12px; font-weight: 800; color: var(--ink-soft); margin-bottom: 2px; }
.cal-chip { font-size: 10.5px; font-weight: 700; padding: 3px 7px; border-radius: 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.cal-chip-cleaning { background: var(--accent-soft); color: var(--accent-strong); }
.cal-chip-maintenance { background: var(--slate-soft); color: var(--slate); }
.cal-chip-more { font-size: 10.5px; color: var(--ink-faint); font-weight: 700; padding: 2px 4px; }
@media (max-width: 860px) {
  .cal-grid { grid-template-columns: repeat(7, minmax(80px, 1fr)); overflow-x: auto; }
}

/* ---------- Weekly property schedule (Schedule page) ---------- */
.sched-grid { display: grid; grid-template-columns: 200px repeat(7, minmax(200px, 1fr)); gap: 0; min-width: 940px; }
.sched-corner { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); padding: 8px 10px 10px; }
.sched-day-head { font-size: 12.5px; font-weight: 800; color: var(--ink-soft); text-align: center; padding: 10px 6px 12px; border-bottom: 2px solid var(--border); }
.sched-day-head.today { color: var(--accent); border-bottom-color: var(--accent); }
.sched-prop-cell { padding: 14px 12px; border-top: 1px solid var(--border); }
.sched-day-cell { padding: 10px 8px; border-top: 1px solid var(--border); border-left: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; min-height: 84px; }
.sched-day-cell.today { background: var(--accent-soft); }
.sched-block { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 30px 26px 12px; cursor: pointer; font-size: 12.5px; }
.sched-block:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.sched-block-cleaning { border-left: 3px solid var(--accent); }
.sched-block-maintenance { border-left: 3px solid var(--slate); }
.sched-block-top { display: flex; align-items: center; gap: 6px; font-weight: 700; margin-bottom: 5px; }
.sched-block-top svg { width: 14px; height: 14px; flex-shrink: 0; }
.sched-block-template { color: var(--ink-soft); font-size: 11.5px; margin-bottom: 7px; }
.sched-block-cleaner { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-soft); }
.sched-block .badge { font-size: 10.5px; padding: 2px 8px; }
.sched-block.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.sched-block.dragging { opacity: 0.4; }
.sched-day-cell.drag-over { background: var(--accent-soft); outline: 2px dashed var(--accent); outline-offset: -2px; }

/* ---------- Schedule toolbar: week/month/year selector ---------- */
.sched-view-select { padding: 8px 28px 8px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); font-size: 13px; font-weight: 700; color: var(--ink); cursor: pointer; }

/* ---------- "Next: …" row under a property name ---------- */
.sched-next-row { display: flex; align-items: flex-start; gap: 6px; font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; cursor: pointer; border-radius: 6px; padding: 3px 4px; margin-left: -4px; }
.sched-next-row:hover { background: var(--surface-2); color: var(--ink); }
.sched-next-row svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--ink-faint); margin-top: 2px; }
/* clean type and date stack rather than wrapping mid-phrase */
.sched-next-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sched-next-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sched-next-date { font-weight: 600; color: var(--ink); white-space: nowrap; }

/* ---------- Year view: 12-month aggregate grid ---------- */
.sched-year-cell { align-items: center; justify-content: center; min-height: 84px; }
.sched-year-cell:hover { background: var(--surface-2); cursor: pointer; }
.sched-year-count { width: 34px; height: 34px; border-radius: 10px; background: var(--accent-soft); color: var(--accent-strong); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; }

/* ---------- Schedule block status indicator (top-right corner) ----------
   An icon badge (rounded square, hourglass glyph), not a bare dot — matches
   the Breezeway reference's exact treatment. Dark green = cleaned/finished,
   light green = ongoing, yellow = paused, red = not started. */
.sched-block-status { position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; border-radius: 6px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sched-block-status svg { width: 12px; height: 12px; color: #fff; }
.sched-block-status-done { background: #1a6b3c; }
.sched-block-status-ongoing { background: #4ade80; }
.sched-block-status-paused { background: #eab308; }
.sched-block-status-notstarted { background: var(--red); }

/* Bottom-right elapsed-time pill — colored to match the status tier it belongs to. */
.sched-block-timer {
  position: absolute; bottom: 6px; right: 6px;
  display: flex; align-items: center; gap: 3px;
  padding: 2px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums;
}
.sched-block-timer svg { width: 9px; height: 9px; color: #fff; }
.sched-block-timer-done { background: #1a6b3c; }
.sched-block-timer-ongoing { background: #4ade80; }
.sched-block-timer-paused { background: #eab308; }

.sched-layout { display: block; }
.sched-main { min-width: 0; }

/* ---------- cleaning_co Schedule (Zenbooker-parity: sidebar + calendar) ---------- */
.cc-sched-layout { display: grid; grid-template-columns: 210px 1fr; gap: 18px; align-items: start; }
@media (max-width: 820px) { .cc-sched-layout { grid-template-columns: 1fr; } }
.cc-sched-side { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; }
.cc-sched-tabs { display: flex; background: var(--surface-2); border-radius: 999px; padding: 3px; margin-bottom: 12px; }
.cc-sched-tab { flex: 1; border: none; background: transparent; padding: 7px 10px; border-radius: 999px; font-size: 13px; font-weight: 700; color: var(--ink-soft); cursor: pointer; }
.cc-sched-tab.active { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.cc-sched-side-label { font-size: 10.5px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); padding: 6px 8px; }
.cc-sched-list { display: flex; flex-direction: column; gap: 2px; }
.cc-sched-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  background: transparent; border: none; padding: 8px 10px; border-radius: 8px; font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.cc-sched-item:hover { background: var(--surface-2); }
.cc-sched-item.active { background: var(--accent-soft); color: var(--accent-strong); }
.cc-sched-item svg { width: 17px; height: 17px; color: var(--ink-soft); flex-shrink: 0; }
.cc-sched-avatar { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; color: #fff; font-size: 9px; font-weight: 800; flex-shrink: 0; }
.cc-sched-main { min-width: 0; }
.cc-view-seg { display: inline-flex; background: var(--surface-2); border-radius: 999px; padding: 3px; }
.cc-view-btn { border: none; background: transparent; padding: 6px 14px; border-radius: 999px; font-size: 13px; font-weight: 700; color: var(--ink-soft); cursor: pointer; }
.cc-view-btn.active { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.cc-sched-cal { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; margin-top: 12px; }

/* Month grid */
.cc-cal-dow { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--border); }
.cc-cal-dow > div { padding: 10px 8px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft); text-align: left; }
.cc-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.cc-cal-cell { min-height: 116px; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 6px 8px; }
.cc-cal-cell:nth-child(7n) { border-right: none; }
.cc-cal-cell-blank { background: var(--surface-2); }
.cc-cal-cell.today { background: var(--accent-soft); }
.cc-cal-cell-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.cc-cal-dots { display: inline-flex; gap: 3px; }
.cc-cal-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }
.cc-cal-date { font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.cc-cal-date.today { color: var(--accent); }
.cc-cal-jobs { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.cc-cal-chip { display: flex; flex-direction: column; gap: 1px; background: var(--surface-2); border-radius: 6px; padding: 4px 7px; cursor: pointer; }
.cc-cal-chip:hover { background: var(--border); }
.cc-cal-chip-status { font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; }
.cc-cal-chip-main { font-size: 11.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cc-cal-chip-time { color: var(--ink-soft); font-weight: 700; }
.cc-cal-more { font-size: 11px; font-weight: 700; color: var(--ink-soft); padding-left: 2px; }
.cc-status-pending { color: #b7791f; }
.cc-status-in_progress { color: #2b6cb0; }
.cc-status-submitted { color: #7c3aed; }
.cc-status-reviewed { color: #1f9d55; }

/* Week grid */
.cc-cal-week { display: grid; grid-template-columns: repeat(7, 1fr); }
.cc-cal-col { border-right: 1px solid var(--border); min-height: 320px; }
.cc-cal-col:last-child { border-right: none; }
.cc-cal-col.today { background: var(--accent-soft); }
.cc-cal-col-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.cc-cal-col-dow { font-size: 11px; font-weight: 800; text-transform: uppercase; color: var(--ink-soft); }
.cc-cal-col-jobs { display: flex; flex-direction: column; gap: 5px; padding: 8px; }

/* Day view */
.cc-cal-day-jobs { display: flex; flex-direction: column; gap: 6px; padding: 12px; }
.cc-cal-day .cc-cal-chip { padding: 8px 12px; }
.cc-cal-day .cc-cal-chip-main { font-size: 13.5px; }
/* A fixed, always-fully-visible drawer instead of a flex sibling that could get
   squeezed (or clipped) off the right edge of the viewport by a wide grid. */
.sched-detail-panel {
  position: fixed; top: 0; right: 0; height: 100vh; width: 340px; max-width: 92vw;
  background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--shadow-lg);
  overflow-y: auto; padding: 24px; z-index: 60;
  transform: translateX(100%);
  transition: transform 0.24s ease;
}
.sched-detail-panel.open { transform: translateX(0); }
.sched-detail-backdrop {
  position: fixed; inset: 0; background: rgba(20,18,15,0.25); z-index: 55;
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
.sched-detail-backdrop.open { opacity: 1; pointer-events: auto; }
.sched-detail-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 48px 16px; color: var(--ink-faint);
}
.sched-detail-empty svg { width: 28px; height: 28px; opacity: 0.5; margin-bottom: 4px; }
.sched-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--border);
}
.sched-detail-header h3 { font-size: 15px; margin: 0; }
.sched-detail-row { display: flex; align-items: center; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid var(--border); gap: 12px; }
.sched-detail-row:last-of-type { border-bottom: none; }
.sched-detail-row select, .sched-detail-row input { max-width: 170px; }

.link-row.unread-msg { background: var(--surface-2); border-radius: 12px; padding: 12px; border-bottom: none; margin-bottom: 4px; }

/* ---------- Tab bar (Team hub: Roster / Messages / Payments; CRM pages) ---------- */
.tab-bar, .tab-row { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.tab-row { margin-bottom: 16px; }
.tab-row .row-list-count { margin-left: 6px; }
.tab-btn { background: transparent; border: none; padding: 10px 16px; font-size: 13.5px; font-weight: 700; color: var(--ink-soft); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; display: flex; align-items: center; }
.tab-btn:hover { color: var(--ink); }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- Create Job wizard (#/owner/create-job) ---------- */
.cjob-header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-bottom: 16px; border-bottom: 1px solid var(--border); margin-bottom: 22px;
}
.cjob-header-title { font-size: 19px; font-weight: 800; }
.cjob-center { max-width: 640px; margin: 0 auto; display: flex; flex-direction: column; gap: 14px; }
.cjob-layout { display: grid; grid-template-columns: 1fr 340px; gap: 22px; align-items: start; }
@media (max-width: 1000px) { .cjob-layout { grid-template-columns: 1fr; } }
.cjob-main { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.cjob-main > .card, .cjob-side > .card { margin-top: 0; }
.cjob-side { display: flex; flex-direction: column; gap: 14px; }
.cjob-side-sec { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.cjob-locked {
  background: var(--surface-2); border-radius: var(--radius); padding: 20px 18px;
  font-size: 17px; font-weight: 800; color: var(--ink-faint);
}
.cjob-cust-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 40;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12); overflow: hidden;
}
.cjob-cust-hit { padding: 10px 14px; cursor: pointer; font-size: 13.5px; }
.cjob-cust-hit:hover { background: var(--surface-2); }

.cjob-svc-table { margin-top: 14px; border-top: 1px solid var(--border); }
.cjob-svc-head {
  display: flex; justify-content: space-between; padding: 10px 0 6px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft);
  border-bottom: 1px solid var(--border);
}
.cjob-svc-row { display: flex; justify-content: space-between; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--border); align-items: center; }
.cjob-svc-name { color: var(--accent); font-weight: 700; font-size: 14px; }
.cjob-total-row { display: flex; justify-content: space-between; padding: 8px 0; font-size: 13.5px; }
.cjob-total-row.bold { font-weight: 800; font-size: 14.5px; }

.cjob-seg { display: flex; background: var(--surface-2); border-radius: 999px; padding: 3px; }
.cjob-seg-btn {
  flex: 1; border: none; background: transparent; padding: 8px 12px; border-radius: 999px;
  font-size: 13px; font-weight: 700; color: var(--ink-soft); cursor: pointer;
}
.cjob-seg-btn.active { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.cjob-radio-row { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.cjob-date-card {
  display: flex; align-items: center; gap: 12px; border: 1px solid var(--border); border-radius: 10px;
  padding: 14px 16px; margin: 12px 0 0 26px;
}
.cjob-date-card svg { width: 22px; height: 22px; color: var(--ink-soft); flex-shrink: 0; }
.cjob-repeats-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 16px; margin: 8px 0 0 26px; border: 1px solid var(--border); border-radius: 10px; cursor: pointer;
}
.cjob-quick-assign {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  background: var(--surface-2); border-radius: var(--radius); padding: 12px 18px;
}
.cjob-qa-chip {
  display: inline-flex; align-items: center; gap: 6px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px;
  font-size: 12.5px; font-weight: 700; cursor: pointer;
}
.cjob-qa-chip:hover { border-color: var(--accent); color: var(--accent); }
.cjob-qa-chip svg { width: 13px; height: 13px; }
.cjob-mini-avatar {
  display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: 50%; background: var(--accent-soft); color: var(--accent-strong);
  font-size: 9px; font-weight: 800;
}

.cjob-cfg-group { margin-bottom: 16px; }
.cjob-cfg-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 6px;
  cursor: pointer; font-size: 13.5px;
}
.cjob-cfg-row:hover { border-color: var(--accent); }

.cjob-time-tabs {
  position: relative; display: flex; justify-content: center; gap: 4px; padding: 4px;
  background: var(--surface-2); border-radius: 999px; margin-bottom: 16px; width: fit-content; margin-left: auto; margin-right: auto;
}
.cjob-time-tab { border: none; background: transparent; padding: 7px 16px; border-radius: 999px; font-size: 13px; font-weight: 700; color: var(--ink-soft); cursor: pointer; }
.cjob-time-tab.active { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
.cjob-time-body { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 640px) { .cjob-time-body { grid-template-columns: 1fr; } }
.cjob-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.cjob-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cjob-cal-dow { font-size: 10.5px; font-weight: 700; color: var(--ink-soft); text-align: center; margin-bottom: 4px; }
.cjob-cal-dow span { padding: 4px 0; }
.cjob-cal-day {
  aspect-ratio: 1; border: none; background: transparent; border-radius: 50%;
  font-size: 13px; font-weight: 600; cursor: pointer; color: var(--ink);
}
.cjob-cal-day:hover { background: var(--surface-2); }
.cjob-cal-day.off { color: var(--ink-faint); cursor: default; }
.cjob-cal-day.sel { background: var(--accent); color: #fff; }
.cjob-slots { max-height: 380px; overflow-y: auto; }
.cjob-slot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; margin-bottom: 8px; cursor: pointer;
}
.cjob-slot:hover { border-color: var(--accent); }
.cjob-slot.sel { border-color: var(--accent); background: var(--accent-soft); }

/* NEW+ dropdown (dashboard header) */
.newplus-btn {
  display: inline-flex; align-items: center; gap: 8px; background: var(--accent);
  color: #fff; border: none; border-radius: 999px; padding: 9px 18px;
  font-size: 12.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; cursor: pointer;
}
.newplus-btn svg { width: 16px; height: 16px; }
.newplus-btn:hover { background: var(--accent-strong); }

/* How-requests-work slide modal */
.how-slide-illus { display: flex; align-items: center; justify-content: center; width: 88px; height: 88px; margin: 0 auto 6px; border-radius: 50%; background: var(--surface-2); color: var(--accent); }
.how-slide-illus svg { width: 40px; height: 40px; }
.how-dots { display: flex; gap: 6px; justify-content: center; margin: 10px 0 2px; }
.how-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border); transition: background 0.2s ease; }
.how-dot.on { background: var(--accent); }
/* 0.6s entrance animation for the How-Requests-Work slide modal — and its
   mirror-image exit (same duration/easing, reversed) applied on close. */
.how-modal { animation: howModalIn 0.6s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes howModalIn {
  from { opacity: 0; transform: translateY(16px) scale(0.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.how-modal.closing { animation: howModalOut 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
@keyframes howModalOut {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to { opacity: 0; transform: translateY(16px) scale(0.96); }
}

/* Requests empty state (Zenbooker-style): centered inbox icon, title, subtext,
   and a How Requests Work button — on its own highlighted card surface rather
   than floating on the page background. */
.req-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center; padding: 72px 20px;
  margin-top: 16px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.req-empty-ico { color: var(--border); }
.req-empty-ico svg { width: 56px; height: 56px; stroke-width: 1.5; }
.req-empty-title { font-size: 19px; font-weight: 800; margin-top: 14px; }
.req-empty-sub { font-size: 13.5px; color: var(--ink-soft); margin-top: 8px; max-width: 420px; line-height: 1.55; }

/* Booking-page-behavior 3-up picker (service edit form) */
.behavior-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.behavior-opt {
  display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 10px;
  padding: 12px 8px; cursor: pointer; transition: border-color 0.12s ease, background 0.12s ease;
}
.behavior-opt:hover { border-color: var(--accent); }
.behavior-opt.selected { border-color: var(--accent); background: var(--accent-soft); }
.behavior-ico { color: var(--ink-soft); } .behavior-opt.selected .behavior-ico { color: var(--accent); }
.behavior-ico svg { width: 20px; height: 20px; }
.behavior-label { font-size: 12.5px; font-weight: 700; }
.behavior-opt.selected .behavior-label { color: var(--accent); }
.behavior-desc { font-size: 11px; color: var(--ink-soft); }

/* ---------- Priority badges ---------- */
.badge-high { background: var(--red-soft); color: var(--red); }
.badge-normal { background: var(--blue-soft); color: var(--blue); }
.badge-low { background: var(--surface-2); color: var(--ink-soft); border: 1px solid var(--border); }

/* =========================================================================
   Dashboard visual import (Lovable "Turnhouse" reference project)
   Scoped entirely to .dash-lovable — the wrapper around the owner Dashboard
   page's content in ownerOverview.js. Everything below only ever cascades
   to descendants of that one wrapper, so no other page/route is affected.
   Structure/spacing/typography still match the Lovable source exactly.
   Color palette was intentionally swapped off the source's warm/tan tones
   to Suheib's requested white / dark grey / dark blue / light blue scheme.
   ========================================================================= */
.dash-lovable {
  /* White / dark grey / dark blue / light blue — no warm/tan tones anywhere. */
  --bg: #f5f6f8;                         /* neutral off-white page background */
  --surface: #ffffff;                    /* card bg */
  --surface-2: #eceff3;                  /* neutral light grey secondary surface */
  --border: #dde1e7;
  --ink: #1e2733;                        /* dark grey (neutral, no green/warm tint) */
  --ink-soft: #5b6472;
  --ink-faint: #8b93a0;
  --accent: #1d4ed8;                     /* dark blue — primary */
  --accent-strong: #17399e;
  --accent-soft: #dce7fb;
  --amber: #b7791f;
  --amber-soft: #f6ecd9;
  --red: #c1443c;
  --red-soft: #f7e2e0;
  --blue: #3b82f6;                       /* light/bright blue — distinct secondary accent */
  --blue-soft: #dceafe;
  --green: #1f8a4c;                      /* reserved for stock-health "healthy" tier only —
                                             everything else (Finished/Passed/Resolved, brand
                                             accents) stays on the blue palette, not green */
  --green-soft: #dcefe3;
  --radius-sm: 10px;
  --radius: 20px;
  --radius-lg: 24px;
  --shadow-sm: 0 1px 2px rgba(30, 39, 51, 0.06);
  --shadow: 0 6px 20px rgba(30, 39, 51, 0.08);

  background: var(--bg);
  margin: -28px -32px -80px;
  padding: 28px 32px 80px;
}
@media (max-width: 860px) {
  .dash-lovable { margin: -18px -16px -90px; padding: 18px 16px 90px; }
}

.dash-lovable, .dash-lovable input, .dash-lovable select, .dash-lovable textarea, .dash-lovable button {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.dash-lovable .card-title,
.dash-lovable .stat-title-row,
.dash-lovable .stat-ring-num,
.dash-lovable .sheet-header h3,
.dash-lovable .dash-hero-title,
.dash-lovable .dash-pay-amount,
.dash-lovable .side-card-title h2 {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  letter-spacing: -0.02em;
}
.dash-lovable .stat-val,
.dash-lovable .prop-gap,
.dash-lovable .date-label,
.dash-lovable .mono {
  font-family: 'JetBrains Mono', 'SFMono-Regular', Menlo, monospace;
}

.dash-lovable .stat-card,
.dash-lovable .card { box-shadow: none; }
.dash-lovable .stat-card:hover { box-shadow: var(--shadow-sm); }
.dash-lovable .badge { border-radius: 999px; font-weight: 600; letter-spacing: 0; text-transform: none; }
.dash-lovable .ready-dot { border-color: var(--border); }
.dash-lovable .ready-dot.filled { background: var(--accent); border-color: var(--accent); }

/* ---------- Topbar row: breadcrumb, search, bell, new task, avatar ---------- */
.dash-topbar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.dash-crumb { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 400; flex-shrink: 0; }
.dash-crumb span:not(.faint) { font-weight: 500; }
.dash-crumb svg { width: 16px; height: 16px; color: var(--ink-soft); }
.dash-search-wrap { position: relative; flex: 1; max-width: 576px; margin-left: 16px; }
.dash-search-wrap svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--ink-faint); pointer-events: none; }
.dash-search-wrap input {
  width: 100%; height: 36px; box-sizing: border-box; padding: 0 12px 0 36px; border-radius: 10px; border: 1px solid transparent;
  background: var(--surface-2); font-size: 13.5px; color: var(--ink); font-family: inherit;
}
.dash-search-wrap input:focus { outline: none; background: var(--surface); border-color: var(--border); }
.dash-round-btn {
  position: relative; width: 36px; height: 36px; border-radius: 50%; border: none;
  background: transparent; color: var(--ink-soft); display: flex; align-items: center; justify-content: center;
  cursor: pointer; flex-shrink: 0;
}
.dash-round-btn:hover { background: var(--surface-2); color: var(--ink); }
.dash-dot { position: absolute; top: 6px; right: 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--red); border: 1.5px solid var(--bg); }
.dash-avatar {
  width: 36px; height: 36px; border-radius: 50%; background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800;
  flex-shrink: 0; cursor: pointer; border: 1px solid var(--border);
}

.dash-lovable .dash-toolbar { justify-content: space-between; margin-bottom: 24px; }
.dash-toolbar-left { display: flex; align-items: center; gap: 8px; }
.dash-lovable .dash-toolbar .date-label { min-width: 0; text-align: left; font-weight: 400; font-size: 14px; color: var(--ink-soft); }
.dash-toolbar-right { display: flex; align-items: center; gap: 8px; }

/* Date-nav as one bordered segmented group (Today | divider | ‹ | ›), matching
   the reference's flex items-center rounded-lg border bg-card wrapper exactly —
   not three separate free-floating buttons. */
.date-nav-group { display: flex; align-items: center; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); overflow: hidden; }
.date-nav-today { border: none; background: transparent; padding: 7px 14px; font-size: 13.5px; font-weight: 600; color: var(--ink); cursor: pointer; }
.date-nav-today:hover { background: var(--surface-2); }
.date-nav-divider { width: 1px; height: 20px; background: var(--border); flex-shrink: 0; }
.date-nav-arrow { width: 32px; height: 32px; border: none; background: transparent; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--ink); }
.date-nav-arrow:hover { background: var(--surface-2); }

/* ---------- Hero ---------- */
.dash-hero { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 24px; }
.dash-hero-label { font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-faint); font-weight: 400; margin: 0; }
.dash-hero-title { font-size: 36px; font-weight: 400; margin: 8px 0 0; line-height: 1.1; }
@media (min-width: 900px) { .dash-hero-title { font-size: 48px; } }
.dash-hero-accent { font-style: italic; color: var(--accent); }
.dash-hero-trend { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-soft); }
.dash-hero-trend svg { color: var(--accent); width: 16px; height: 16px; }

/* ---------- Stat rings (4-up) — exact spacing from the reference:
   card = rounded-2xl(20px) p-5(20px) gap-5(20px); title = text-lg(18px) with
   the icon pushed to the far edge via justify-between, not a small gap;
   legend = space-y-1.5(6px) text-sm(14px) rows with h-1.5(6px) dots. ---------- */
.dash-lovable .ring-row { margin-bottom: 24px; }
.dash-lovable .stat-card { align-items: center; padding: 20px; gap: 20px; border-radius: 20px; }
.dash-lovable .stat-title-row { gap: 0; justify-content: space-between; font-size: 18px; }
.dash-lovable .stat-title-row svg { width: 16px; height: 16px; }
.dash-lovable .stat-legend { gap: 6px; }
.dash-lovable .stat-legend-row { font-size: 14px; }
.dash-lovable .stat-dot { width: 6px; height: 6px; }

/* ---------- Cleaning-company dashboard: metric tiles + revenue chart, replacing
   the STR cleaning/inspection/maintenance/damage rings (none of which apply —
   no property inspections, no maintenance, no damage claims for a cleaning co). ---------- */
.cc-metric-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 24px; }
@media (max-width: 900px) { .cc-metric-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cc-metric-row { grid-template-columns: 1fr; } }
.cc-metric-card { background: var(--surface); border: 1px solid var(--border); border-radius: 20px; padding: 20px; box-shadow: var(--shadow-sm); }
.cc-metric-label { font-size: 13px; color: var(--ink-soft); font-weight: 500; }
.cc-metric-value { font-size: 28px; font-weight: 700; margin-top: 6px; letter-spacing: -0.01em; }
.cc-metric-sub { margin-top: 4px; }
.cc-chart-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 24px; align-items: stretch; }
@media (max-width: 900px) { .cc-chart-row { grid-template-columns: 1fr; } }
/* Fixed footprint (not just min-height) so the weekly/monthly cards never
   resize against each other between renders — every piece inside (title,
   standalone number, legend, 160px chart, x-axis labels) has a fixed or
   min height of its own, so this total is reliable rather than a guess. */
.cc-revenue-card { margin-bottom: 0; height: 350px; box-sizing: border-box; }

/* Monthly-revenue (left) + Profit (right) overview row, then the comparison
   sliders row (New vs Repeat customers, One-time vs Recurring jobs). */
.cc-overview-row { display: grid; grid-template-columns: 1.4fr 1fr; gap: 24px; margin-bottom: 24px; align-items: stretch; }
@media (max-width: 900px) { .cc-overview-row { grid-template-columns: 1fr; } }
.cc-overview-row > .card { margin-top: 0; }
.cc-profit-card { display: flex; flex-direction: column; }
.cc-profit-lines { list-style: none; margin: 18px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 9px; }
.cc-profit-lines li { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--ink-soft); }
.cc-profit-lines li .mono { color: var(--ink); font-weight: 600; }

.cc-compare-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 24px; }
@media (max-width: 900px) { .cc-compare-row { grid-template-columns: 1fr; } }
.cc-compare-row > .card { margin-top: 0; }

/* ScheduleDrop-style comparison slider: colored count on each end (green left,
   blue right) over a thin rounded track filled with the same two colors. */
.cmp-bar { margin-top: 14px; }
.cmp-bar-counts { display: flex; justify-content: space-between; margin-bottom: 8px; }
.cmp-count-left { font-size: 17px; font-weight: 800; color: #2f9e44; }
.cmp-count-right { font-size: 17px; font-weight: 800; color: #1c7ed6; }
.cmp-bar-track { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--surface-2); }
.cmp-bar-seg { height: 100%; transition: width 0.3s ease; }
.cmp-seg-left { background: #2f9e44; }
.cmp-seg-right { background: #1c7ed6; }
.cc-chart-standalone { margin-top: 4px; }
.cc-chart-standalone-value { font-size: 32px; font-weight: 700; letter-spacing: -0.01em; }
.cc-chart-standalone-label { margin-top: 2px; }
.cc-chart-legend { display: flex; gap: 16px; font-size: 12px; color: var(--ink-soft); margin-top: 14px; }
.cc-legend-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.cc-line-chart-wrap { margin-top: 12px; position: relative; }
.cc-chart-scale-label { position: absolute; top: -2px; left: 2px; }
.cc-line-chart { width: 100%; height: 160px; display: block; overflow: visible; }
.cc-line-chart circle { transition: r 0.12s ease; cursor: pointer; }
.cc-line-chart circle:hover { r: 3.5; }
.cc-chart-xlabels { display: flex; justify-content: space-between; margin-top: 6px; padding: 0 2px; }
.cc-chart-xlabels span { font-size: 10px; color: var(--ink-faint); text-transform: uppercase; flex: 1; text-align: center; }
.cc-chart-xlabels span:first-child { text-align: left; }
.cc-chart-xlabels span:last-child { text-align: right; }

/* ---------- Two-column: properties + side rail ---------- */
.dash-2col { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; align-items: start; margin-bottom: 24px; }
@media (max-width: 1100px) { .dash-2col { grid-template-columns: 1fr; } }
.dash-props { padding: 0; overflow: hidden; }
.dash-props-head { padding: 16px 20px; margin: 0; border-bottom: 1px solid var(--border); }
.dash-rail { display: flex; flex-direction: column; gap: 24px; }

.prop-list { display: flex; flex-direction: column; }
.prop-row {
  display: grid; grid-template-columns: 4fr 2fr 2fr 1fr 2fr 1fr;
  gap: 12px; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--border);
}
/* STR "Cleans today" is trimmed to property + status + assigned. The card is
   narrowed (see .dash-hero-row) so these three fill it without a trailing gap. */
.prop-list-slim .prop-row {
  grid-template-columns: 2fr 1.1fr 1.1fr;
  gap: 14px;
}

/* Two-column dashboard. Each column flows on its own, so mismatched card heights
   can never leave a hole beside a short card. */
.dash-grid { display: grid; grid-template-columns: minmax(0, 2.05fr) minmax(280px, 1fr); gap: 20px; align-items: start; }
@media (max-width: 1100px) { .dash-grid { grid-template-columns: 1fr; } }
.dash-col-main, .dash-col-side { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.dash-col-main > .card, .dash-col-side > .card { margin: 0; }
/* Maintenance + Damage share a row inside the main column. */
.dash-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 760px) { .dash-pair { grid-template-columns: 1fr; } }
.dash-pair > .stat-card { margin: 0; height: 100%; padding: 18px; gap: 16px; }
.dash-pair .stat-ring-wrap { width: 84px; height: 84px; }
.dash-pair .stat-ring-num { font-size: 22px; }
.dash-pair .stat-ring-of { font-size: 9.5px; }
.dash-pair .stat-title-row { font-size: 16px; }

/* Cleans today is the dashboard hero — full width, above everything else, with
   slightly roomier rows so it reads as the primary surface. */
.dash-props-hero { margin-bottom: 24px; }
.dash-props-hero .card-title { font-size: 19px; }
/* Title, chips and the table were separated by four stacked rules in a short
   space, which read as clutter. Only the table keeps its dividers. */
.dash-props-hero .dash-props-head { border-bottom: none; padding: 20px 22px 4px; }
.dash-props-hero .clean-chips { padding: 14px 22px 16px; }
.dash-props-hero .prop-row-head { background: transparent; border-top: 1px solid var(--border); padding: 10px 22px; }
.dash-props-hero .prop-row { padding: 14px 22px; }
.dash-props-hero .prop-name { font-size: 14px; }
.dash-props-hero .prop-tile { width: 30px; height: 30px; }
.dash-props-hero .prop-tile svg { width: 14px; height: 14px; }
.dash-props-hero .prop-main { gap: 10px; }
.dash-props-hero .prop-list-foot { border-top: none; padding: 10px 22px 16px; }
/* Three equal supporting cards below the hero. Equal height so the row reads as
   one band, and a smaller ring so the stat cards aren't mostly empty. */
.dash-secondary-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px; align-items: stretch; margin-bottom: 24px;
}
@media (max-width: 1100px) { .dash-secondary-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) { .dash-secondary-row { grid-template-columns: 1fr; } }
.dash-secondary-row > .card,
.dash-secondary-row > .stat-card { margin: 0; height: 100%; }
.dash-secondary-row .stat-card { padding: 18px; gap: 16px; align-items: center; }
.dash-secondary-row .stat-ring-wrap { width: 84px; height: 84px; }
.dash-secondary-row .stat-ring-num { font-size: 22px; }
.dash-secondary-row .stat-ring-of { font-size: 9.5px; }
.dash-secondary-row .stat-title-row { font-size: 16px; }
.dash-secondary-row .side-card { display: flex; flex-direction: column; }
.dash-secondary-row .side-card #inbox-list { flex: 1; }

/* A 20-clean day can't push the rest of the dashboard off-screen, so the list
   caps its height and scrolls internally with the column header pinned. */
.prop-list-scroll { max-height: 460px; overflow-y: auto; }
.prop-list-scroll .prop-row-head {
  position: sticky; top: 0; z-index: 3; background: var(--surface);
  box-shadow: 0 1px 0 var(--border);
}

/* Status chips — narrow a long day down to the bucket you're working. */
.clean-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 20px 14px; }
.clean-chip {
  display: inline-flex; align-items: center; gap: 7px; font-family: inherit;
  font-size: 12.5px; font-weight: 600; color: var(--text-soft, #55637a);
  background: var(--surface-2, #f4f7fb); border: 1px solid var(--border);
  border-radius: 999px; padding: 6px 12px; cursor: pointer; transition: 0.15s;
}
.clean-chip:hover { color: var(--text); border-color: var(--accent); }
.clean-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.clean-chip.danger:not(.on) { color: var(--red, #c24a3c); border-color: #f0c8c2; background: #fdf0ee; }
.clean-chip.danger.on { background: var(--red, #c24a3c); border-color: var(--red, #c24a3c); }
.clean-chip-n { font-variant-numeric: tabular-nums; opacity: 0.75; font-weight: 700; }

/* Owner-side read-only mirror of the cleaner checklist (opens in its own tab) */
.cleanerview-banner {
  display: flex; align-items: center; gap: 8px; margin-bottom: 16px;
  background: var(--amber-soft, #fbf0dc); color: var(--amber, #b07a1d);
  border: 1px solid #f0dcb4; border-radius: 10px; padding: 10px 14px;
  font-size: 13px; font-weight: 600;
}
.cleanerview-banner svg { width: 15px; height: 15px; }
.checklist-readonly { opacity: 0.97; }
.checklist-readonly input, .checklist-readonly button, .checklist-readonly textarea { cursor: default !important; }

/* Payout sheet — one group per cleaner, expandable to the individual cleans */
.payout-total-row { display: flex; justify-content: space-between; align-items: baseline; padding: 0 2px 12px; border-bottom: 1px solid var(--border); }
.payout-total { font-size: 24px; font-weight: 700; }
.payout-group { padding: 12px 2px; border-bottom: 1px solid var(--border-2, var(--border)); }
.payout-group-head { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.payout-group-amt { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.payout-toggle { background: none; border: none; padding: 4px 0 0 27px; cursor: pointer; font-family: inherit; text-decoration: underline; }
.payout-jobs { margin: 8px 0 2px 27px; display: flex; flex-direction: column; gap: 6px; }
.payout-job { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; font-size: 13px; align-items: baseline; }

/* Payout history + year-to-date */
.ytd-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border-2, var(--border)); }
.ytd-amt { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.ytd-flag { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--amber-soft, #fbf0dc); color: var(--amber, #b07a1d); white-space: nowrap; }

/* Multi-photo picker for damage reports */
.photo-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.photo-thumb { position: relative; width: 84px; height: 84px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); flex: none; }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-thumb-x {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: 50%;
  border: none; background: rgba(19,35,64,.72); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.photo-thumb-x svg { width: 12px; height: 12px; }
.photo-add {
  width: 84px; height: 84px; flex: none; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px; cursor: pointer;
  border: 1px dashed var(--border-strong, var(--border)); border-radius: 10px;
  background: var(--surface-2, #f4f7fb); color: var(--ink-soft); font-family: inherit;
}
.photo-add:hover { border-color: var(--accent); color: var(--accent); }
.photo-add svg { width: 18px; height: 18px; }
.photo-add .photo-tile-label { font-size: 11px; }

/* Supplies card — one row per item, so height is independent of unit count. */
.supply-summary { padding: 0 20px 10px; }
.supply-item-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 20px; border-top: 1px solid var(--border-2, var(--border)); cursor: pointer;
}
.supply-item-row:hover { background: var(--surface-2, #f4f7fb); }
.supply-item-need { text-align: right; white-space: nowrap; }
.supply-stale-note {
  display: flex; align-items: flex-start; gap: 7px; padding: 10px 20px 14px;
  border-top: 1px solid var(--border); line-height: 1.45;
}
.supply-stale-note svg { width: 13px; height: 13px; flex: none; margin-top: 2px; }

/* Destructive action in the schedule detail panel — quiet until armed. */
.btn-danger-ghost {
  background: transparent; color: var(--red, #c24a3c);
  border: 1px solid #f0c8c2;
}
.btn-danger-ghost:hover { background: #fdf0ee; }
.btn-danger-ghost.armed {
  background: var(--red, #c24a3c); border-color: var(--red, #c24a3c); color: #fff;
}
.prop-row:last-child { border-bottom: none; }
.prop-row-head { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint); font-weight: 400; background: color-mix(in oklch, var(--surface-2) 50%, transparent); padding: 8px 20px; }
.prop-row.clickable-row:hover { background: color-mix(in oklch, var(--surface-2) 50%, transparent); cursor: pointer; }
.prop-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.prop-tile {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 40px; height: 40px; border-radius: 12px;
  background: color-mix(in oklch, var(--accent) 10%, transparent); color: var(--accent);
}
.prop-tile-maintenance { background: color-mix(in oklch, var(--amber) 10%, transparent); color: var(--amber); }
.prop-tile svg { width: 16px; height: 16px; }
.prop-name { font-size: 14px; font-weight: 500; }
.prop-addr { display: flex; align-items: center; gap: 4px; margin-top: 0; font-size: 12px; }
.prop-addr svg { width: 12px; height: 12px; }
.prop-res { margin-top: 2px; font-size: 11px; opacity: 0.8; }
.prop-issue { color: var(--red); font-weight: 700; }
.prop-task-count {
  display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border-radius: 8px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 500;
}
.prop-comment { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.prop-gap { font-family: 'JetBrains Mono', monospace; font-size: 14px; }
.prop-gap-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint); }
.prop-list-foot { text-align: center; padding: 12px 20px; border-top: 1px solid var(--border); font-size: 12px; }

.ready-dots { display: flex; align-items: center; gap: 4px; }
.ready-ico { display: inline-flex; color: var(--ink-faint); opacity: 0.4; }
.ready-ico svg { width: 16px; height: 16px; }
.ready-ico.done { color: var(--accent); opacity: 1; }
.ready-ico.current { color: var(--amber); opacity: 1; }

/* ---------- Reusable side card. Two distinct patterns match the reference
   exactly: Team/Inbox/Payments use uniform p-5(20px) padding on the card
   itself; Damage/Supplies use .side-card-flush (no card padding) with the
   header (px-5 py-4, border-bottom) and each row (px-5 py-3) self-padding,
   like a bordered header sitting above a divide-y list. ---------- */
.side-card { padding: 20px; }
.side-card-flush { padding: 0; }
.side-card-flush .side-card-header { padding: 16px 20px; margin-bottom: 0; border-bottom: 1px solid var(--border); }
.side-card-header-clay { background: color-mix(in oklch, var(--red) 5%, transparent); }
.side-card-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 0; }
.side-card:not(.side-card-flush) > .side-card-header + div { margin-top: 16px; }
.side-card-title { display: flex; align-items: center; gap: 8px; }
.side-card-title svg { width: 16px; height: 16px; color: var(--accent); }
.side-card-header-clay .side-card-title svg { color: var(--red); }
.side-card-title h2 { font-size: 18px; margin: 0; font-weight: 400; }
.dash-see-more { display: block; text-align: center; font-size: 12px; font-weight: 700; color: var(--accent); padding: 10px 0 2px; }

.dmg-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px 20px; border-bottom: 1px solid var(--border); }
.dmg-row:last-child { border-bottom: none; }
.dmg-row:hover { cursor: pointer; }
.dmg-tile { flex-shrink: 0; width: 36px; height: 36px; border-radius: 8px; background: color-mix(in oklch, var(--red) 10%, transparent); color: var(--red); display: flex; align-items: center; justify-content: center; }
.dmg-tile svg { width: 16px; height: 16px; }
.dmg-row-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dmg-title { font-size: 14px; margin: 2px 0; }

.supply-row { padding: 12px 20px; border-bottom: 1px solid var(--border); }
.supply-row:first-child { padding-top: 12px; }
.supply-row:last-child { border-bottom: none; }

/* ---------- Bottom trio ---------- */
.bottom-trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-bottom: 24px; }
@media (max-width: 1100px) { .bottom-trio { grid-template-columns: 1fr; } }

#team-list, #inbox-list { display: flex; flex-direction: column; gap: 12px; }
.team-row { display: flex; align-items: center; gap: 12px; }
.team-avatar {
  width: 36px; height: 36px; border-radius: 50%; background: color-mix(in oklch, var(--accent) 10%, transparent); color: var(--accent);
  display: flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 500; flex-shrink: 0;
}
.team-status { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.team-status-dot { width: 6px; height: 6px; border-radius: 50%; }
.team-status-dot.tone-ready { background: var(--accent); }
.team-status-dot.tone-progress { background: var(--amber); }

.msg-row { display: flex; align-items: flex-start; gap: 12px; }
.msg-dot { width: 8px; height: 8px; border-radius: 50%; background: color-mix(in oklch, var(--ink-faint) 30%, transparent); margin-top: 6px; flex-shrink: 0; }
.msg-dot.unread { background: var(--accent); }
.msg-row-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.msg-row-top .faint { display: flex; align-items: center; gap: 3px; font-size: 11px; white-space: nowrap; }
.msg-row-top .faint svg { width: 12px; height: 12px; }
.msg-body { margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; color: color-mix(in oklch, var(--ink) 80%, transparent); }
.dash-inbox-form { position: relative; margin-top: 16px; }
.dash-inbox-form input {
  width: 100%; padding: 10px 42px 10px 12px; border-radius: 10px; border: 1px solid var(--border);
  background: var(--surface-2); font-size: 13.5px; font-family: inherit; color: var(--ink);
}
.dash-inbox-form input:focus { outline: none; background: var(--surface); border-color: var(--accent); }
.dash-send-btn { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; background: var(--accent); color: #fff; }
.dash-send-btn:hover { background: var(--accent-strong); }

.dash-payments { position: relative; overflow: hidden; }
.dash-pay-blur {
  position: absolute; top: -64px; right: -64px; width: 160px; height: 160px;
  border-radius: 50%; background: var(--accent); opacity: 0.15; filter: blur(40px);
  z-index: -1; pointer-events: none;
}
.dash-pay-hero { margin-bottom: 4px; }
.dash-pay-label { text-transform: uppercase; letter-spacing: 0.08em; font-size: 12px; }
.dash-pay-amount { display: flex; align-items: baseline; gap: 8px; font-size: 36px; margin-top: 4px; }
/* The display serif renders a large "$" awkwardly next to the figure. Set the
   symbol in the UI sans at a smaller size and lift it slightly, which is the
   normal typographic treatment for currency alongside a big number. */
.dash-pay-amount .cur {
  font-family: var(--font-sans, system-ui, sans-serif);
  font-size: 0.55em; font-weight: 600; vertical-align: 0.32em;
  margin-right: 2px; color: var(--ink-soft, inherit);
}
.dash-pay-change { display: flex; align-items: center; gap: 2px; font-size: 12px; font-weight: 500; color: var(--accent); font-family: inherit; }
.dash-pay-change svg { width: 12px; height: 12px; }
.pay-row-list { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.pay-row-list li { display: flex; align-items: center; justify-content: space-between; background: color-mix(in oklch, var(--surface-2) 70%, transparent); border-radius: 8px; padding: 8px 12px; font-size: 14px; }

.dash-footer { text-align: center; padding: 16px 0 32px; font-size: 12px; }

/* ============ Team Members (Zenbooker-style) ============ */
.tm-card { padding: 0; overflow: visible; }
.tm-tabs { display: flex; border-bottom: 1px solid var(--border); }
.tm-tab { flex: 1; background: none; border: none; padding: 16px 10px; font-size: 15px; font-weight: 600; color: var(--ink-soft); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tm-tab:hover { color: var(--ink); }
.tm-tab-active { color: var(--accent); border-bottom-color: var(--accent); }
.tm-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px; }
.tm-filter { position: relative; }
.tm-filter-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 9px 12px; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }
.tm-filter-btn svg { width: 16px; height: 16px; transform: rotate(90deg); color: var(--ink-faint); }
.tm-filter-menu { position: absolute; top: calc(100% + 4px); left: 0; min-width: 190px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(20,30,50,0.12); padding: 6px; z-index: 30; }
.tm-filter-menu button { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; text-align: left; background: none; border: none; padding: 9px 10px; border-radius: 7px; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }
.tm-filter-menu button:hover { background: var(--surface-2); }
.tm-filter-menu button svg { width: 15px; height: 15px; color: var(--accent); }
.tm-search { position: relative; flex: 1; max-width: 320px; }
.tm-search svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--ink-faint); }
.tm-search input { width: 100%; border: 1px solid var(--border); border-radius: 8px; padding: 9px 12px 9px 34px; font-size: 14px; }
.tm-table { border-top: 1px solid var(--border); }
.tm-row { display: grid; grid-template-columns: 2.2fr 1.2fr 1.3fr; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--border); cursor: pointer; }
.tm-row:last-child { border-bottom: none; }
.tm-row:not(.tm-row-head):hover { background: var(--surface-2); }
.tm-row-head { cursor: default; background: var(--surface-2); }
.tm-row-head:hover { background: var(--surface-2); }
.tm-row-head .tm-cell { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; color: var(--ink-faint); text-transform: uppercase; }
.tm-cell-member { display: flex; align-items: center; gap: 12px; min-width: 0; }
.tm-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--green-soft); color: var(--green); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; flex-shrink: 0; }
.tm-row-head .tm-avatar { display: none; }
.tm-name { font-size: 14.5px; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.tm-email { font-size: 13px; color: var(--ink-faint); }
.tm-cell-role { font-size: 14px; color: var(--ink); }
.tm-cell-provider { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 14px; color: var(--ink); }
.tm-row-icons { display: inline-flex; gap: 10px; color: var(--ink-faint); }
.tm-row-icons svg { width: 17px; height: 17px; }
.tm-badge { font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 2px 7px; border-radius: 5px; }
.tm-badge-active { background: var(--green-soft); color: var(--green); }
.tm-badge-invited { background: var(--amber-soft); color: var(--amber); }
.tm-badge-off { background: var(--surface-2); color: var(--ink-faint); }
.tm-empty { text-align: center; padding: 44px 16px; color: var(--ink-faint); }
.tm-empty svg { width: 30px; height: 30px; margin-bottom: 8px; }

/* Add/Edit Team Member modal */
.sheet-lg { max-width: 560px; width: 100%; }
.sheet-body { max-height: 74vh; overflow-y: auto; padding-right: 2px; }
.tm-provider-card { border: 1px solid var(--border); border-radius: 12px; padding: 14px; margin-top: 14px; }
.tm-provider-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tm-toggle { position: relative; width: 68px; height: 30px; border: none; border-radius: 999px; background: #5b6472; cursor: pointer; flex-shrink: 0; transition: background 0.25s ease; }
.tm-toggle-on { background: var(--green); }
.tm-toggle-knob { position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.3); transition: transform 0.25s cubic-bezier(0.34, 1.4, 0.64, 1); }
.tm-toggle-on .tm-toggle-knob { transform: translateX(38px); }
.tm-toggle-label { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); font-size: 11px; font-weight: 700; letter-spacing: 0.04em; color: #fff; transition: left 0.25s ease, right 0.25s ease; }
.tm-toggle-on .tm-toggle-label { left: 12px; right: auto; }
.tm-terr-label { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; color: var(--ink-faint); text-transform: uppercase; margin-top: 14px; margin-bottom: 8px; }
.tm-terr-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.tm-terr-chip { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); background: var(--surface); border-radius: 8px; padding: 7px 11px; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer; }
.tm-terr-chip svg { width: 14px; height: 14px; color: var(--ink-faint); }
.tm-terr-chip-on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); }
.tm-terr-chip-on svg { color: var(--accent); }
.tm-section-title { font-size: 15px; font-weight: 700; color: var(--ink); margin: 20px 0 10px; }
.role-list { display: flex; flex-direction: column; gap: 10px; }
.role-card { display: flex; gap: 12px; border: 1px solid var(--border); border-radius: 12px; padding: 14px; cursor: pointer; align-items: flex-start; }
.role-card input[type=radio] { margin-top: 3px; }
.role-card-active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.role-card-body { flex: 1; min-width: 0; }
.role-card-title { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.role-card-desc { font-size: 13px; color: var(--ink-soft); margin-top: 2px; }
.role-worker-perms { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 12px; }
.perm-row { display: flex; align-items: flex-start; gap: 9px; padding: 5px 0; font-size: 13.5px; color: var(--ink); cursor: pointer; }
.perm-row input { margin-top: 2px; }
.perm-row-lead { font-weight: 600; }
.perm-lead-text { font-size: 13px; color: var(--ink-soft); margin: 8px 0 4px; }
.tm-footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border); }
.btn-danger-ghost { background: none; border: 1px solid var(--red-soft); color: var(--red); }
.btn-danger-ghost:hover { background: var(--red-soft); }

.auth-note { background: var(--green-soft); color: var(--green); font-size: 13px; font-weight: 600; border-radius: 8px; padding: 10px 12px; margin-bottom: 14px; }

/* ============ turnovers brand lockup (auth portal) ============ */
.auth-brand { align-items: flex-start; gap: 12px; }
.auth-brand-col { display: flex; flex-direction: column; min-width: 0; }
.auth-wordmark .tv-word { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); line-height: 1; }
.tv-word-accent { color: var(--accent); }
.auth-cleaners { margin-top: 3px; }
.tv-cleaners-tag { display: inline-flex; align-items: center; gap: 3px; color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: 0.01em; }
.tv-cleaners-arrow { color: var(--accent); flex-shrink: 0; margin-left: 1px; }
.auth-brand-col .brand-sub { margin-top: 8px; }

/* ---- turnovers logo in the sidebar (dark theme) ---- */
.side-wordmark { line-height: 1; }
.side-wordmark .tv-word { font-size: 16px; font-weight: 800; letter-spacing: -0.02em; }
.owner-sidebar .side-wordmark .tv-word { color: #f2f3f5; }
.owner-sidebar .side-wordmark .tv-word-accent { color: #6ea8dc; }
.side-cleaners { margin-top: 2px; }
.owner-sidebar .side-cleaners .tv-cleaners-tag { color: #6ea8dc; font-size: 11px; }
.side-orgname { font-size: 11px; font-weight: 700; color: #8b93a1; margin-top: 3px; letter-spacing: 0.02em; }

/* ---- login portal toggle ---- */
.portal-toggle { display: flex; gap: 6px; background: var(--surface-2); border-radius: 10px; padding: 4px; margin-bottom: 16px; }
.portal-tab { flex: 1; border: none; background: none; padding: 8px 10px; border-radius: 7px; font-size: 13px; font-weight: 600; color: var(--ink-soft); cursor: pointer; transition: background 0.15s, color 0.15s; }
.portal-tab.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,0.08); }

/* Webhook URL block (Settings -> Cleaner Reminders). Long opaque string, so it
   wraps rather than overflowing, and reads as copyable rather than as prose. */
.webhook-url {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 1.5;
  word-break: break-all;
  background: var(--bg-soft, #f4f6f8);
  border: 1px solid var(--line, #e2e7ee);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--ink, #1a2433);
  user-select: all;
}

/* Plain horizontal rule inside a card. */
.divider { height: 1px; background: var(--line, #e2e7ee); border: 0; }

/* Email-verification banner (top of the owner shell) and the confirmation
   notice on the login screen. Amber rather than red: this is a prompt to finish
   setup, not an error the user caused. */
/* The border was #f0d9a0 on a #fff8e6 fill — too close in value to read as an
   edge against a near-white page, so the bottom looked like it just stopped
   rather than closing. Uses the palette's own amber at low alpha instead, which
   holds contrast on all four sides, plus a small shadow so the box sits on the
   page rather than blending into it. */
/* position:relative is load-bearing, not decoration. The next sibling on the
   Dashboard is .dash-lovable, which uses margin:-28px -32px -80px to escape
   .owner-main's padding and go full-bleed, and paints its own background. A
   static element would therefore get its bottom 28px covered — the border and
   both bottom corners disappeared. Positioning lifts the banner into the
   positioned-elements paint layer, above a static sibling's background.
   The 18px bottom margin still resolves to an 18px visual gap, because
   .dash-lovable re-adds 28px of top padding after pulling up 28px. */
.verify-banner {
  position: relative;
  z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  background: var(--amber-soft);
  border: 1px solid rgba(182, 121, 10, 0.32);
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
  padding: 14px 16px; margin: 0 0 18px;
  box-sizing: border-box;
}
.verify-banner-main { display: flex; align-items: flex-start; gap: 10px; min-width: 260px; flex: 1; }
.verify-banner-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--amber, #c98a00);
  flex: none; margin-top: 6px;
}
.verify-banner-title { font-weight: 600; font-size: 13.5px; color: #6b4e00; }
.verify-banner-sub { font-size: 12.5px; color: #8a7333; margin-top: 2px; line-height: 1.45; }
.verify-banner-actions { display: flex; gap: 8px; flex: none; }

.auth-notice { border-radius: 8px; padding: 10px 12px; font-size: 13px; margin-bottom: 14px; line-height: 1.45; }
.auth-notice-ok { background: #e8f5ec; border: 1px solid #b7dcc4; color: #1e5b34; }
.auth-notice-warn { background: var(--amber-soft); border: 1px solid rgba(182, 121, 10, 0.32); color: #6b4e00; }

/* ---------- Dashboard summary circles ---------- */
/* Three counts across the top: cleans today, open maintenance, open damage.
   Buttons rather than divs so they're keyboard-reachable and announce as
   controls — each one navigates to the page holding the detail. */
.dash-rings {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: 24px;
}
@media (max-width: 760px) { .dash-rings { grid-template-columns: repeat(3, 1fr); gap: 10px; } }

.summary-ring {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius, 20px);
  box-shadow: var(--shadow-sm);
  padding: 22px 16px;
  cursor: pointer;
  font: inherit;
  transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.08s ease;
}
.summary-ring:hover { border-color: var(--accent); box-shadow: var(--shadow); }
.summary-ring:active { transform: scale(0.99); }

.summary-ring-wrap { position: relative; width: 96px; height: 96px; flex: none; }
.summary-ring-wrap svg { display: block; width: 100% !important; height: 100% !important; }
.summary-ring-center { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
/* Serif numeral matches the existing stat rings so the two don't look like
   different design systems sitting on the same page. */
.summary-ring-num {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 34px; font-weight: 400; line-height: 1; color: var(--ink);
}
/* A zero is good news here, so it recedes rather than shouting. */
.summary-ring.is-empty .summary-ring-num { color: var(--ink-faint); }
.summary-ring-label {
  font-size: 13px; font-weight: 600; color: var(--ink-soft); text-align: center; line-height: 1.3;
}

@media (max-width: 760px) {
  .summary-ring { padding: 16px 8px; gap: 8px; }
  .summary-ring-wrap { width: 64px; height: 64px; }
  .summary-ring-num { font-size: 22px; }
  .summary-ring-label { font-size: 11.5px; }
}

/* Payouts + supplies pair below the cleans list. Equal columns, equal height. */
.dash-pair-bottom { margin-top: 24px; align-items: stretch; }
.dash-pair-bottom > .card { margin: 0; display: flex; flex-direction: column; }

/* ---------- Team member form: name + active toggle row ---------- */
/* The toggle is intentionally unlabeled — on/off reads from its position and
   colour, and the fields collapsing underneath make the meaning obvious. */
.tm-active-row { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.tm-name-input { flex: 1; min-width: 0; }
.tm-active-row .tm-toggle { flex: none; }

/* Password block: the lock checkbox belongs to the field above it, so they sit
   in one bordered group rather than reading as two unrelated controls. */
.tm-pw-group {
  border: 1px solid var(--border); border-radius: 12px; padding: 14px 14px 4px;
}
.tm-pw-group .field { margin-bottom: 10px; }
.tm-pw-lock {
  display: flex; align-items: center; gap: 9px; cursor: pointer;
  padding: 10px 0 12px; border-top: 1px solid var(--border); margin-top: 4px;
}
.tm-pw-lock input { margin: 0; }
.tm-complaints-btn { margin-top: 18px; }

/* Complaints table */
.cx-cleaner { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.cx-note { max-width: 420px; color: var(--ink-soft); }
.cx-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-strong);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 10.5px; flex: none;
}

/* ---------- Template builder: three fixed groups ---------- */
.tmpl-group { margin-bottom: 26px; }
.tmpl-group-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding-bottom: 8px; margin-bottom: 12px;
  border-bottom: 2px solid var(--border);
}
.tmpl-group-head h3 {
  margin: 0; font-size: 15px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft);
}
.tmpl-group-empty { padding: 14px 2px; }

/* Property-type picker in the generate sheet */
.gen-type { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.gen-type-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 10px; border-radius: 12px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
  font-size: 14px; font-weight: 700; color: var(--ink);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.gen-type-btn svg { width: 18px; height: 18px; }
.gen-type-btn.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); }

/* ---------- Template import wizard ---------- */
.imp-drop {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 26px 18px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink-soft);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.imp-drop:hover, .imp-drop.over { border-color: var(--accent); background: var(--accent-soft); }
.imp-drop svg { width: 26px; height: 26px; color: var(--ink-faint); }
.imp-files { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.imp-file {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); font-size: 13px;
}
.imp-file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }

/* Flagged content is the part people skim past, so it gets the warm border and
   sits above the extracted sections rather than below them. */
.imp-flagged { border-left: 3px solid var(--warn, #d98324); }
.imp-flagged .card-title { display: flex; align-items: center; gap: 8px; }
.imp-flagged .card-title svg { width: 17px; height: 17px; color: var(--warn, #d98324); }
.imp-flag-list { display: flex; flex-direction: column; gap: 8px; }
.imp-flag {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.imp-flag-text { flex: 1; font-size: 13.5px; }
.imp-flag select { flex-shrink: 0; max-width: 220px; }

.imp-groups { display: flex; flex-direction: column; gap: 18px; }
.imp-group > h4 { font-size: 14px; margin-bottom: 8px; display: flex; align-items: baseline; gap: 8px; }
.imp-section {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 12px; margin-bottom: 8px; background: var(--surface);
}
.imp-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.imp-section-head select { max-width: 210px; }
.imp-items { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.imp-items li {
  font-size: 13.5px; color: var(--ink-soft);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 3px 0 3px 14px; position: relative;
}
.imp-items li::before { content: ''; position: absolute; left: 3px; top: 11px; width: 4px; height: 4px; border-radius: 50%; background: var(--ink-faint); }
.imp-items li.uncertain { color: var(--ink); }
.imp-items li .badge { font-size: 10.5px; padding: 1px 6px; }

/* Two ways to fill a template, each with a line explaining what it does. */
.tmpl-actions { display: flex; flex-direction: column; gap: 14px; }
.tmpl-action { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.tmpl-action .small { max-width: 62ch; line-height: 1.45; }

/* ---------- Dashboard status squares ---------- */
/* Four equal squares, one per clean status, each tinted to its own colour so the
   shape of the day reads before any number does. They're also the list filter. */
/* Fixed-size squares in a row, not a stretched grid — across a full-width
   dashboard, four equal columns made each block enormous. */
.dash-status {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-bottom: 18px;
}
.stat-block {
  width: 96px; height: 96px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 8px 6px; cursor: pointer; text-align: center;
  border: 1.5px solid var(--block-line); border-radius: var(--radius);
  background: var(--block-bg); color: var(--block-ink);
  transition: transform 0.12s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.stat-block:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.stat-block.on { border-color: var(--block-ink); box-shadow: 0 0 0 2px var(--block-bg), 0 0 0 3.5px var(--block-ink); }
/* Zero is still worth showing — a stable four-across grid beats one that reflows
   through the day — but it shouldn't compete for attention. */
.stat-block.empty { opacity: 0.55; }
.stat-block.empty:hover { opacity: 1; }
.stat-block-n { font-size: 24px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; }
.stat-block-label { font-size: 11.5px; font-weight: 700; line-height: 1.2; }

.stat-grey  { --block-bg: var(--slate-soft); --block-ink: var(--slate);  --block-line: #d5dee7; }
.stat-blue  { --block-bg: var(--blue-soft);  --block-ink: var(--blue);   --block-line: #c8dcef; }
.stat-green { --block-bg: var(--green-soft); --block-ink: var(--green);  --block-line: #b9dfc9; }
.stat-red   { --block-bg: var(--red-soft);   --block-ink: var(--red);    --block-line: #f2cfc6; }

@media (max-width: 560px) {
  .stat-block { width: calc(50% - 5px); height: 84px; }
}

/* ---------- Payout card: owed, not earned ---------- */
.dash-pay-past {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px; padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--red-soft); color: var(--red); font-weight: 700; font-size: 13.5px;
}
.dash-pay-past span:first-child { display: flex; align-items: center; gap: 7px; }
.dash-pay-past svg { width: 15px; height: 15px; }
.dash-pay-count { margin-top: 10px; }
.dash-pay-clear {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 0; color: var(--green); font-weight: 600; font-size: 14px;
}
.dash-pay-clear-main { display: flex; align-items: center; gap: 8px; }
.dash-pay-clear svg { width: 17px; height: 17px; flex-shrink: 0; }
.dash-pay-clear-date { color: var(--ink-soft); font-weight: 700; white-space: nowrap; }

/* ---------- Payments: bare circles, no card around them ---------- */
.payout-circles { display: flex; gap: 36px; flex-wrap: wrap; padding: 4px 0 8px; }
/* .summary-ring carries a card (surface, border, shadow) for the dashboard. Here
   the circle is the whole thing, so strip the box back off. */
.payout-circles .summary-ring {
  background: none; border: none; box-shadow: none; padding: 0; gap: 10px; cursor: default;
}
.payout-circles .summary-ring:hover { border-color: transparent; box-shadow: none; }
.payout-circles .summary-ring:active { transform: none; }
.payout-circles .summary-ring-wrap { width: 108px; height: 108px; }
/* A money string needs far more room than a two-digit count. */
.summary-ring-num-text {
  font-family: inherit; font-size: 19px; font-weight: 800; letter-spacing: -0.02em;
}

/* ---------- Billing cycle statement ---------- */
.po-status {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.po-sent { background: var(--green-soft); color: var(--green); }
.po-pending { background: var(--amber-soft); color: var(--amber); }
.po-notsent { background: var(--slate-soft); color: var(--slate); }
/* Only the figure is red, not the whole cell or column — the colour is there to
   flag "this comes off", and a tinted column would shout that on empty rows too. */
.po-debit { color: var(--red); font-weight: 700; }
.po-right { text-align: right; }
.po-payout { font-weight: 800; font-variant-numeric: tabular-nums; }
.po-table tfoot td { border-top: 1.5px solid var(--border); font-weight: 700; padding-top: 10px; }

/* Cycle stepper mirrors the dashboard's date nav rather than living in its own card. */
.cycle-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 16px 0 12px;
}
.cycle-toolbar-left { display: flex; align-items: center; gap: 12px; }
.cycle-toolbar .date-label { min-width: 0; text-align: left; }
.date-nav-arrow:disabled { opacity: 0.35; cursor: default; }
.date-nav-arrow:disabled:hover { background: transparent; }
.po-adj-list { display: flex; flex-direction: column; gap: 6px; }
.po-adj {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); font-size: 13.5px;
}
.po-adj .faint { flex: 1; }

@media (max-width: 760px) {
  .payout-circles { gap: 20px; }
  .payout-circles .summary-ring-wrap { width: 84px; height: 84px; }
  .summary-ring-num-text { font-size: 15px; }
}

/* ================= Installed app (PWA) ================= */

/* Sits above the bottom nav so it can't be missed mid-checklist, and clears the
   iPhone home indicator. */
.net-banner {
  position: fixed; left: 12px; right: 12px; z-index: 9998;
  bottom: calc(var(--nav-h, 64px) + 12px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; justify-content: center; gap: 9px;
  padding: 11px 14px; border-radius: 12px;
  background: #6b2f22; color: #fff;
  font-size: 13.5px; font-weight: 600; text-align: center;
  box-shadow: 0 8px 24px rgba(0,0,0,0.28);
  animation: netBannerIn 0.22s ease-out;
}
@keyframes netBannerIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.net-banner-dot {
  width: 8px; height: 8px; border-radius: 50%; background: #ffb4a2; flex-shrink: 0;
  animation: netPulse 1.8s ease-in-out infinite;
}
@keyframes netPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
/* The owner app has no bottom nav, so the banner would otherwise float too high. */
.shell-owner ~ .net-banner, body:has(.shell-owner) .net-banner { bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }

.update-toast {
  position: fixed; left: 12px; right: 12px; z-index: 9999;
  bottom: calc(var(--nav-h, 64px) + 12px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; border-radius: 12px;
  background: var(--accent-strong); color: #fff; font-size: 13.5px; font-weight: 600;
  box-shadow: 0 8px 24px rgba(0,0,0,0.28);
}
.update-toast-btn {
  background: #fff; color: var(--accent-strong); border: none; border-radius: 8px;
  padding: 7px 14px; font-weight: 700; font-size: 13px; cursor: pointer; flex-shrink: 0;
}

/* ---------- Safe areas + touch targets ---------- */
/* Standalone mode has no browser chrome, so the app itself must keep clear of the
   notch and the home indicator. */
.shell-cleaner .topbar, .topbar { padding-top: env(safe-area-inset-top, 0px); }
.bottom-nav {
  padding-bottom: env(safe-area-inset-bottom, 0px);
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
}
@supports (padding: max(0px)) {
  .shell-cleaner { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
}

@media (pointer: coarse) {
  /* Apple and Google both put the floor at ~44px; a cleaner is tapping this with
     wet gloves on. */
  .bottom-nav a, .btn, .icon-btn, .chk, .photo-toggle { min-height: 44px; }
  .icon-btn { min-width: 44px; }
  /* iOS zooms the page when a focused input is under 16px. */
  input, select, textarea { font-size: 16px !important; }
}

/* ---------- Install prompt ---------- */
.install-card {
  position: fixed; left: 12px; right: 12px; z-index: 9997;
  bottom: calc(var(--nav-h, 64px) + 12px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 10px 30px rgba(26,36,51,0.18);
  animation: netBannerIn 0.24s ease-out;
}
.install-card-text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.install-card-text strong { font-size: 14px; }
.install-card-text span { font-size: 12.5px; color: var(--ink-soft); }
.install-card-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
@media (min-width: 760px) {
  /* No bottom nav on desktop, and it shouldn't span the whole window. */
  .install-card { left: auto; right: 20px; bottom: 20px; max-width: 380px; }
}

/* ---------- Role capability summary ---------- */
/* Shown for every role. Previously only Worker had visible options, which read
   as Worker being the most powerful role. */
.role-summary { margin-top: 10px; }
.role-summary ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.role-summary li { font-size: 12.5px; line-height: 1.4; padding-left: 20px; position: relative; }
.role-can li { color: var(--ink-soft); }
.role-can li::before { content: '✓'; position: absolute; left: 2px; color: var(--green); font-weight: 700; }
.role-cannot { margin-top: 6px !important; }
.role-cannot li { color: var(--ink-faint); }
.role-cannot li::before { content: '✕'; position: absolute; left: 3px; color: var(--red); font-weight: 700; }
