@import url("https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700,900&f[]=general-sans@400,500,600,700&display=swap");

/* ============================================================
   CleanGrid — "Operations board"
   ------------------------------------------------------------
   Three surfaces, one job each:
     1. the RAIL   — a deep slate column, dark on purpose. It holds
                     nothing but the brand, "New job", and the seven
                     live alert counters. It is the "what needs me"
                     tower, so it is the one place with real contrast.
     2. the CHROME — white bars (view switcher + page header) that
                     frame the work without competing with it.
     3. the CANVAS — a cool slate field (#F1F4F9) that lets pure-white
                     cards separate from the page instead of dissolving
                     into it, which is what made the old build read flat.

   Color carries meaning, never decoration: zones, cleaner identity,
   and job status own the saturated hues. The indigo→sky gradient is
   rationed to primary actions, the brand mark, and the billing total.
   ============================================================ */
:root {
  /* --- Text & neutral surfaces --- */
  --ink: #0B1220;          /* headings, values */
  --ink-2: #1E293B;        /* body text on white */
  --muted: #64748B;        /* labels, secondary copy */
  --muted-2: #94A3B8;      /* tertiary / placeholder */
  --canvas: #F1F4F9;       /* page field behind the cards */
  --surface: #FFFFFF;      /* cards, bars, menus */
  --surface-2: #F7F9FC;    /* table headers, inset rows, ghost buttons */
  --border: #E2E8F1;       /* card + control hairline */
  --border-soft: #EEF2F7;  /* internal dividers */

  /* --- The navigation rail (the only dark surface) --- */
  --rail: #131C31;
  --rail-2: #0B1220;
  --rail-line: rgba(255, 255, 255, 0.08);
  --rail-text: #C3D0E4;
  --rail-text-dim: #8695B2;

  /* --- Brand --- */
  --brand: #4F46E5;        /* indigo — shared with the cleaner app */
  --brand-hover: #4338CA;
  --brand-lift: #0EA5E9;   /* sky — the far end of the one gradient */
  --brand-soft: #EEF0FF;
  --brand-grad: linear-gradient(135deg, #4F46E5 0%, #0EA5E9 100%);

  /* --- Status signals (always paired with a text label, never colour alone) --- */
  --green: #15803D;  --green-soft: #DCFCE7;
  --amber: #B45309;  --amber-soft: #FEF3C7;
  --red:   #DC2626;  --red-soft:   #FEE2E2;

  /* --- Service zones --- */
  --north: #7C3AED;
  --south: #0F766E;
  --inner: #1D4ED8;

  /* --- Legacy aliases: ~150 call sites still say --teal / --gold / --bg --- */
  --teal: #4F46E5;
  --teal-mid: #6366F1;
  --teal-dark: #0B1220;
  --teal-soft: #EEF0FF;
  --gold: #B45309;
  --gold-soft: #FEF3C7;
  --bg: #F1F4F9;
  --page-bg: #F1F4F9;

  /* --- Shape & depth --- */
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --radius-xs: 8px;
  --radius-pill: 999px;
  --shadow-xs: 0 1px 2px rgba(11, 18, 32, 0.05);
  --shadow-sm: 0 1px 2px rgba(11, 18, 32, 0.04), 0 2px 6px rgba(11, 18, 32, 0.05);
  --shadow-md: 0 2px 4px rgba(11, 18, 32, 0.04), 0 10px 24px rgba(11, 18, 32, 0.08);
  --shadow-lg: 0 24px 60px rgba(11, 18, 32, 0.22);
  --shadow-brand: 0 6px 18px rgba(79, 70, 229, 0.34);

  /* --- Type --- */
  --font-ui: "Satoshi", "General Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-data: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Focus ring: 4.0:1 on white, 4.6:1 on the dark rail — legible on both. */
  --focus: #0284C7;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-ui);
  background: var(--canvas);
  color: var(--ink-2);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
button { font-family: inherit; }
button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, a:focus-visible, [tabindex]:focus-visible {
  outline: 2.5px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
.sidebar button:focus-visible, .sidebar a:focus-visible { outline-color: #38BDF8; }
a { color: var(--brand); }

/* Figures line up in columns everywhere they're compared — payroll totals,
   invoice amounts, job times. Names and prose keep the UI face. */
.kpi-value, .billing-summary-value, .billing-row-amount, .hours-card-head .total,
.shift-row .duration, .day-view-row .time, .util-pct, .payroll-input {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.data-table td, .payroll-table td, .shift-row, .audit-row { font-variant-numeric: tabular-nums; }

/* ---------- Shell layout ---------- */
.app-shell { display: flex; min-height: 100vh; background: var(--canvas); }

/* ============================================================
   THE RAIL — signature element.
   Everything in this column is an interruption: a job to create, or
   a count of things waiting on the owner. Making it dark separates
   "things that want my attention" from "the work I'm looking at",
   which no amount of tinted-white could do, and it gives the alert
   badges somewhere to actually shout from.
   ============================================================ */
.sidebar {
  width: 190px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--rail) 0%, var(--rail-2) 100%);
  color: var(--rail-text);
  border-right: none;
  box-shadow: inset -1px 0 0 var(--rail-line);
  display: flex;
  flex-direction: column;
  padding: 16px 12px 20px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 4px 20px;
}
/* Gradient fill, no glow. The glow is reserved for things you can press —
   otherwise the rail has three light sources and no focal point. */
.sidebar-brand .mark {
  width: 26px; height: 26px; border-radius: 9px; background: var(--brand-grad);
  display: grid; grid-template-columns: 4px 4px; grid-template-rows: 4px 4px; gap: 3px;
  align-content: center; justify-content: center; flex-shrink: 0;
}
.sidebar-brand .mark-dot { width: 4px; height: 4px; background: #fff; border-radius: 1px; }
.sidebar-brand .title { font-weight: 700; font-size: 14px; letter-spacing: -0.015em; color: #fff; }
.sidebar-brand .subtitle { font-size: 10.5px; color: var(--rail-text-dim); margin-top: 1px; letter-spacing: 0.01em; }

.new-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  justify-content: center;
  width: 100%;
  padding: 11px 14px;
  background: var(--brand-grad);
  color: #fff;
  border: none;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.005em;
  cursor: pointer;
  box-shadow: var(--shadow-brand);
  transition: transform 0.12s ease, box-shadow 0.18s ease;
}
.new-btn:hover { box-shadow: 0 8px 24px rgba(79, 70, 229, 0.48); }
.new-btn:active { transform: scale(0.98); }
.new-btn-icon { font-size: 16px; line-height: 1; font-weight: 500; margin-top: -1px; }

.bell-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  width: 100%;
  padding: 7px 8px;
  margin-top: 2px;
  background: transparent;
  color: var(--rail-text);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-weight: 500;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}
.bell-btn .btn-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bell-btn:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
/* A counter that isn't zero lifts its whole row out of the list — the rail
   should be readable as "three things need me" from across the room. */
.bell-btn:has(.badge:not(.hidden)) { background: rgba(255, 255, 255, 0.05); color: #fff; font-weight: 600; }
.bell-btn:has(.badge:not(.hidden)) .icon-chip { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.16); }

/* The assistant is the one thing in the rail that acts rather than counts,
   so it carries the brand gradient in its chip and sits apart from the list. */
.assistant-btn {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--rail-line);
  color: #fff;
  font-weight: 600;
  margin-top: 16px;
}
.assistant-btn:hover { background: rgba(79, 70, 229, 0.32); border-color: rgba(129, 140, 248, 0.55); color: #fff; }
.assistant-btn .icon {
  width: 22px; height: 22px; border-radius: 7px; flex-shrink: 0;
  background: var(--brand-grad); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.assistant-btn .icon svg { width: 13px; height: 13px; }
.assistant-btn .badge { background: #FBBF24; color: #78350F; box-shadow: none; }
/* First counter after the assistant starts the alert list proper. */
.assistant-btn + .bell-btn { margin-top: 14px; }

/* ---------- AI Assistant chat panel ---------- */
.assistant-panel { display: flex; flex-direction: column; width: 460px; padding-bottom: 0 !important; }
.assistant-messages {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;
  padding: 4px 2px 12px; min-height: 200px;
}
.chat-bubble { max-width: 85%; padding: 10px 14px; border-radius: var(--radius-md); font-size: 13.5px; line-height: 1.5; white-space: pre-wrap; }
.chat-bubble.user { align-self: flex-end; background: var(--brand-grad); color: white; border-bottom-right-radius: 4px; }
.chat-bubble.assistant { align-self: flex-start; background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2); border-bottom-left-radius: 4px; }
.chat-bubble.error { align-self: flex-start; background: var(--red-soft); color: var(--red); }
.chat-bubble.thinking { align-self: flex-start; background: var(--surface-2); color: var(--muted); font-style: italic; }
.assistant-input-row {
  display: flex; gap: 8px; padding: 12px 0 20px; border-top: 1px solid var(--border);
  position: sticky; bottom: 0; background: var(--surface);
}
.assistant-input-row input { flex: 1; padding: 10px 14px; border: 1.5px solid var(--border); border-radius: var(--radius-pill); font-size: 13.5px; font-family: inherit; }
.assistant-input-row input:focus { outline: none; border-color: var(--brand); }
.assistant-input-row button { flex-shrink: 0; }
.assistant-empty-state { text-align: center; color: var(--muted); padding: 40px 10px; font-size: 13px; }
.assistant-empty-state a { color: var(--brand); font-weight: 700; }
.badge {
  background: var(--red);
  color: white;
  font-size: 10px;
  font-weight: 800;
  border-radius: var(--radius-pill);
  padding: 2px 6px;
  min-width: 18px;
  text-align: center;
  line-height: 1.4;
  flex-shrink: 0;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18);
}
.badge.hidden { display: none; }

/* Generic fallback — the redesign pass introduced several compound
   .thing.hidden rules (above and below) but never a plain .hidden, so any
   element without one of those specific ancestor classes silently ignored
   classList.add("hidden") entirely (found the hard way in the cash-only
   admin mode and the client-form manual-pin picker). Lower specificity than
   the compound rules, so it never overrides them — it only fills the gap
   they left. */
.hidden { display: none; }

/* ---------- Map tile-loading fallback overlay ---------- */
/* Sits over the Leaflet container itself (added dynamically), so it shows
   up automatically on every map in the app when all tile providers fail —
   not just the one map that happened to have this wired up by hand before. */
.map-tile-fallback {
  position: absolute; inset: 0; z-index: 500; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 8px; background: rgba(255,255,255,0.92); text-align: center; padding: 16px;
  font-size: 13px; color: var(--muted); pointer-events: none;
}
.map-tile-fallback button { pointer-events: auto; }

/* ---------- Client-form address autocomplete ---------- */
.address-suggestions {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 50; background: #fff; border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); max-height: 220px; overflow-y: auto; margin-top: 4px;
}
.address-suggestion { padding: 9px 12px; font-size: 13.5px; cursor: pointer; border-bottom: 1px solid var(--border); }
.address-suggestion:last-child { border-bottom: none; }
.address-suggestion:hover { background: var(--brand-soft); }

.activity-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 11px 13px;
  margin-bottom: 8px;
  font-size: 13px;
  box-shadow: var(--shadow-xs);
}
.activity-item .who { font-weight: 700; }
.activity-item .when { color: var(--muted); font-size: 11.5px; float: right; }
.activity-item .what { color: var(--muted); margin-top: 2px; }
.activity-item.type-checked_in { border-left: 3px solid var(--teal); }
.activity-item.type-completed { border-left: 3px solid var(--green); }
.activity-item.type-assigned { border-left: 3px solid var(--gold); }

.sidebar-nav { margin-top: 14px; display: flex; flex-direction: column; gap: 1px; }

/* ---------- Top nav bar — primary view switcher, moved out of the sidebar
   so it reads as the platform's main navigation rather than one more list
   item among the notification bells. Horizontal row, scrolls on narrow
   screens instead of wrapping. ---------- */
.top-nav-bar {
  display: flex; align-items: center; gap: 4px;
  padding: 9px 22px; background: var(--surface); border-bottom: 1px solid var(--border);
  /* No overflow set here on purpose — the user menu's dropdown is an absolutely
     positioned descendant of this bar, and CSS forces overflow-y to compute as
     "auto" (clipping) whenever overflow-x isn't "visible", even if overflow-y
     is explicitly set to "visible". That silently clipped the dropdown at this
     bar's bottom edge, making it look like clicking the avatar did nothing.
     The horizontal scroll needed for narrow screens lives on .nav-items-scroll
     instead, which the dropdown sits outside of. */
}
/* Only the nav-item buttons scroll horizontally on narrow screens — kept
   separate from .top-nav-bar itself, see comment above. */
.nav-items-scroll {
  display: flex; align-items: center; gap: 4px; min-width: 0;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.top-nav-bar .nav-item { flex-shrink: 0; padding: 7px 12px 7px 7px; }
.top-nav-bar .lang-switcher { margin-left: auto; }
.top-nav-bar .topbar-usermenu { margin-left: 10px; padding-left: 0; flex-shrink: 0; }
.nav-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: var(--radius-pill);
  background: transparent;
  border: none;
  color: #475569;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
/* Active view: filled pill + the icon badge goes solid brand. Two signals,
   neither of them colour alone — the pill shape reads without hue. */
.nav-item.active {
  background: var(--brand-soft);
  color: #3730A3;
  font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(79, 70, 229, 0.16);
}
.nav-item.active .icon-chip { background: var(--brand); color: #fff; }
.nav-item .icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* ---------- Language switcher (EN / ES) ----------
   Lived unstyled in the admin app — style.css never carried a rule for it,
   so it rendered as two raw browser buttons in the middle of the nav bar. */
.lang-switcher {
  display: inline-flex; gap: 2px; flex-shrink: 0;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 2px;
}
.lang-btn {
  border: none; background: transparent; cursor: pointer; font-family: inherit;
  padding: 4px 10px; border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em; color: var(--muted);
}
.lang-btn:hover:not(.active) { color: var(--ink); }
.lang-btn.active { background: var(--surface); color: var(--brand); box-shadow: var(--shadow-xs); }
.nav-item .icon svg, .bell-btn .icon svg, .sidebar-link .icon svg { width: 15px; height: 15px; display: block; flex-shrink: 0; }
.bell-btn .icon, .sidebar-link .icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sidebar-link { display: flex; align-items: center; gap: 6px; }

/* ---------- Icon chips — small colored badges behind icons (nav, bells, user
   menu) so they read as designed elements instead of plain black line icons.
   Mirrors the KPI-chip treatment already used on the Dashboard. Color is
   fixed to the chip regardless of the parent button's hover/active state. */
.icon-chip {
  width: 24px; height: 24px; border-radius: var(--radius-xs); flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
.icon-chip svg { width: 13px; height: 13px; display: block; }
.chip-indigo { background: #E0E7FF; color: #4338CA; }
.chip-blue   { background: #DBEAFE; color: #1D4ED8; }
.chip-teal   { background: #CCFBF1; color: #0F766E; }
.chip-purple { background: #EDE9FE; color: #6D28D9; }
.chip-amber  { background: #FEF3C7; color: #B45309; }
.chip-green  { background: #DCFCE7; color: #15803D; }
.chip-pink   { background: #FCE7F3; color: #BE185D; }
.chip-red    { background: #FEE2E2; color: #B91C1C; }

/* On the dark rail the pastel fills invert: a low-opacity wash of the same
   hue, with the glyph raised to the bright end of that hue so each counter
   is still identifiable by colour at a glance. */
.sidebar .icon-chip { background: rgba(255, 255, 255, 0.08); color: var(--rail-text); }
.sidebar .chip-indigo { background: rgba(129, 140, 248, 0.16); color: #A5B4FC; }
.sidebar .chip-blue   { background: rgba(96, 165, 250, 0.16);  color: #93C5FD; }
.sidebar .chip-teal   { background: rgba(45, 212, 191, 0.16);  color: #5EEAD4; }
.sidebar .chip-purple { background: rgba(167, 139, 250, 0.16); color: #C4B5FD; }
.sidebar .chip-amber  { background: rgba(251, 191, 36, 0.16);  color: #FCD34D; }
.sidebar .chip-green  { background: rgba(52, 211, 153, 0.16);  color: #6EE7B7; }
.sidebar .chip-pink   { background: rgba(244, 114, 182, 0.16); color: #F9A8D4; }
.sidebar .chip-red    { background: rgba(248, 113, 113, 0.16); color: #FCA5A5; }

.sidebar-footer { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--rail-line); }
.sidebar-link {
  display: block;
  font-size: 11px;
  color: var(--rail-text-dim);
  text-decoration: none;
  padding: 5px 4px;
}
.sidebar-link:hover { color: #fff; }
.sidebar-user {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--rail-line);
  font-size: 11px; color: var(--rail-text-dim);
}
.sidebar-user a { color: #FCA5A5; text-decoration: none; font-weight: 700; }
.sidebar-user a:hover { text-decoration: underline; }

/* ---------- Main ---------- */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Page header: the title and the controls that act on it. Sits directly under
   the view switcher, so it keeps the same white surface and closes with the
   single hairline that separates chrome from canvas. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 15px 22px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.topbar-left, .topbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.topbar h1 {
  font-size: 21px; margin: 0 0 0 4px; font-weight: 700;
  letter-spacing: -0.03em; color: var(--ink); min-width: 150px;
}
.topbar-right-group { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

/* ---------- Top-right user menu ---------- */
.topbar-usermenu { position: relative; flex-shrink: 0; }
.user-menu-btn {
  display: flex; align-items: center; gap: 6px; padding: 4px 8px 4px 4px;
  background: none; border: 1px solid transparent; border-radius: 999px; cursor: pointer; color: var(--muted);
}
.user-menu-btn:hover { background: var(--surface-2); border-color: var(--border); }
.user-menu-btn svg { width: 14px; height: 14px; }
.user-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  background: var(--brand-grad); color: white; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
}
.user-menu-dropdown.hidden { display: none; }
.user-menu-dropdown {
  position: absolute; top: calc(100% + 10px); right: 0; width: 250px;
  background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  border: 1px solid var(--border-soft); padding: 8px; z-index: 70;
  animation: slideIn 0.15s ease-out;
}
.user-menu-header {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px 12px;
  margin-bottom: 6px; border-bottom: 1px solid var(--border-soft);
}
.user-menu-header .user-avatar { width: 34px; height: 34px; font-size: 13px; }
.user-menu-header span:last-child { font-weight: 700; font-size: 13px; color: var(--ink); word-break: break-word; }
.user-menu-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; color: var(--ink); text-decoration: none; cursor: pointer;
}
.user-menu-item:hover { background: var(--surface-2); }
.user-menu-item.danger { color: var(--red); }
.user-menu-item.danger:hover { background: var(--red-soft); }
.user-menu-divider { height: 1px; background: var(--border-soft); margin: 6px 4px; }

.icon-btn-round {
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  font-size: 14px;
  color: var(--ink-2);
  box-shadow: var(--shadow-xs);
}
.icon-btn-round:hover { border-color: var(--brand); color: var(--brand); }

.pill-select, select.field, input.field {
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 13px;
  font-family: inherit;
  color: var(--ink-2);
  box-shadow: var(--shadow-xs);
}
.pill-select:hover, select.field:hover, input.field:hover { border-color: #CBD5E1; }
select.field:focus, input.field:focus { border-color: var(--brand); }

/* ---------- Cleaner filter — multi-select dropdown ----------
   Checkbox list instead of a plain <select> so two or more cleaners can be
   picked at once, e.g. to compare routes/times side by side. */
.cleaner-ms { position: relative; display: inline-block; }
.cleaner-ms-btn { cursor: pointer; white-space: nowrap; }
.cleaner-ms-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  width: 220px; max-height: 280px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 6px;
}
.cleaner-ms-panel.hidden { display: none; }
.cleaner-ms-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 8px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; color: var(--ink); cursor: pointer;
}
.cleaner-ms-item:hover { background: var(--border-soft); }
.cleaner-ms-item input[type="checkbox"] { width: auto; margin: 0; flex-shrink: 0; }
.cleaner-ms-all { font-weight: 700; }
.cleaner-ms-divider { height: 1px; background: var(--border-soft); margin: 4px 4px 6px; }
.today-btn {
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  color: var(--ink-2);
  box-shadow: var(--shadow-xs);
}
.today-btn:hover { border-color: var(--brand); color: var(--brand); }

.view-content { padding: 22px 22px 64px; }
.view { display: none; }
.view.active { display: block; }

/* ---------- Month calendar grid ---------- */
.month-grid {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.month-weekday-row { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--border); background: var(--surface-2); }
.month-weekday-row span {
  padding: 10px 0;
  text-align: center;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}
.month-body { display: grid; grid-template-columns: repeat(7, 1fr); }
.month-cell {
  min-height: 116px;
  border-right: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
  padding: 8px;
  cursor: pointer;
  transition: background 0.1s ease;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.month-cell:hover { background: var(--surface-2); }
.month-cell:nth-child(7n) { border-right: none; }
.month-cell.outside { background: #FAFBFD; }
.month-cell.outside .cell-date { color: #C7CCD2; }
.cell-date {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  width: 23px; height: 23px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
}
.month-cell.today .cell-date { background: var(--brand); color: white; }
.month-cell.holiday { background: var(--gold-soft); }
.month-cell.holiday .cell-date { background: var(--gold); color: white; }
.month-cell.holiday.today .cell-date { background: var(--teal); color: white; box-shadow: 0 0 0 2px var(--gold); }
.holiday-label { font-size: 8.5px; font-weight: 700; color: var(--gold); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell-jobs { display: flex; flex-direction: column; gap: 3px; overflow: hidden; }
.job-chip {
  font-size: 10.5px;
  font-weight: 600;
  padding: 3px 7px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: default;
}
.cell-more { font-size: 10.5px; color: var(--muted); font-weight: 600; padding-left: 4px; }
.cell-count-empty { font-size: 10.5px; color: #D5D9DE; }

/* ---------- Week list (existing view, restyled) ---------- */
.day-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 12px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.day-header {
  background: var(--surface-2);
  padding: 10px 16px;
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: -0.01em;
  color: var(--ink);
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid var(--border-soft);
}
.day-header span:last-child { color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.job-row {
  display: grid;
  grid-template-columns: 64px 1fr 90px 120px 150px 170px;
  gap: 10px;
  align-items: center;
  padding: 10px 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 13px;
}
.job-row.cancelled { opacity: 0.45; text-decoration: line-through; }
.job-row.completed { background: #F3FCF6; }
.job-row:hover { background: var(--surface-2); }
.zone-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: white;
}
.zone-badge.north { background: var(--north); }
.zone-badge.inner { background: var(--inner); }
.zone-badge.south { background: var(--south); }
.zone-badge.unzoned, .zone-badge.unknown, .zone-badge.unassigned { background: #9aa5b1; }
.pay-cash { color: var(--green); font-weight: 700; font-size: 12px; }
.pay-invoice { color: var(--muted); font-size: 12px; }
.flag { color: var(--red); font-size: 10.5px; font-weight: 700; }
select.cleaner-select { padding: 5px 7px; font-size: 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); flex: 1; min-width: 0; }
.cleaner-select-wrap { display: flex; align-items: center; gap: 6px; }
.color-dot { display: inline-block; width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 0 1.5px rgba(0,0,0,0.08); vertical-align: middle; }
.color-swatch-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 2px; }
.color-swatch {
  width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent;
}
.color-swatch.selected { border-color: var(--ink); box-shadow: 0 0 0 2px white inset; }
.custom-color-swatch {
  position: relative;
  display: block;
  overflow: hidden;
}
.custom-color-swatch input[type="color"] {
  position: absolute;
  inset: -4px;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  border: none;
  padding: 0;
  cursor: pointer;
  opacity: 0; /* the swatch shows the picked/gradient color; the native picker UI stays invisible but clickable */
}
.job-actions { display: flex; gap: 4px; align-items: center; }
.job-actions button {
  font-size: 11px;
  padding: 4px 9px;
  white-space: nowrap;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  font-weight: 600;
}
.job-actions button:hover { border-color: #CBD5E1; background: var(--surface-2); }
.job-actions button.danger { border-color: #FCA5A5; color: var(--red); background: var(--red-soft); }
.job-actions button.ok { border-color: #86EFAC; color: var(--green); background: var(--green-soft); }
.job-actions button.has-photos { border-color: #A5B4FC; color: var(--brand); background: var(--brand-soft); }

/* ---------- Data tables ---------- */
.data-table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--border); box-shadow: var(--shadow-sm); }
.data-table th, .data-table td { padding: 11px 14px; font-size: 13px; border-top: 1px solid var(--border-soft); text-align: left; }
.data-table th {
  background: var(--surface-2); font-weight: 700; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted);
  border-top: none; white-space: nowrap;
}
.data-table tbody tr:first-child td { border-top: 1px solid var(--border); }
.data-table tr:hover td { background: var(--surface-2); }
.icon-btn { cursor: pointer; border: none; background: none; color: var(--brand); font-size: 12.5px; font-weight: 700; padding: 2px 4px; border-radius: var(--radius-xs); }
.icon-btn:hover { background: var(--brand-soft); }

.geo-cell { display: inline-flex; align-items: center; gap: 7px; }
.tag-icon { display: inline-flex; align-items: center; justify-content: center; }
.tag-icon svg { width: 14px; height: 14px; }
.tag-icon.key { color: #B45309; }   /* amber — has provided a key */
.tag-icon.eco { color: #15803D; }   /* green — eco-friendly products requested */

/* Badged variant — used in the Clients table, where key-holder and
   eco-friendly need to read as two distinct, unmissable signals rather than
   two same-shaped outline icons that only differ by colour. Gives each its
   own tinted "chip" (same badge language as the sidebar/nav icon-chips)
   instead of a bare stroke icon, so they're differentiable at a glance and
   don't blur together even side by side. Left as a separate class (not a
   change to .tag-icon itself) so the compact calendar-chip usage of these
   same icons (month chips, day/week rows) stays small and unbadged. */
.tag-icon-lg {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.04);
}
.tag-icon-lg svg { width: 13px; height: 13px; }
.tag-icon-lg.key { background: #FEF3C7; color: #B45309; } /* amber chip */
.tag-icon-lg.eco { background: #DCFCE7; color: #15803D; } /* green chip */

/* Compact badge variant for the calendar (month chips, day/week rows, the
   day side-panel) — same tinted-circle language as .tag-icon-lg, just small
   enough to sit inline in a dense job chip. Kept opaque (not color:inherit)
   on purpose: a job chip's own background varies per cleaner, and a fixed
   amber/green circle stays legible and recognizable as "the same key/eco
   signal as the Clients table" against any of them, whereas inheriting the
   chip's text color made the two icons blend into the chip and into each
   other. */
.tag-icon-badge {
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0;
  margin-left: 2px; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.55);
}
.tag-icon-badge svg { width: 9px; height: 9px; vertical-align: -1px; }
.tag-icon-badge.key { background: #FEF3C7; color: #B45309; }
.tag-icon-badge.eco { background: #DCFCE7; color: #15803D; }

/* Toolbars sit on the canvas above their card, so the controls carry their own
   white surface and a hairline rather than floating unbounded. */
.toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.toolbar input, .toolbar select {
  padding: 8px 12px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  font-size: 13px; font-family: inherit; background: var(--surface);
  color: var(--ink-2); box-shadow: var(--shadow-xs);
}
.toolbar input::placeholder { color: var(--muted-2); }
.btn {
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
}
.btn:hover { border-color: var(--brand); color: var(--brand); }
/* Primary is the one place the indigo→sky gradient appears in the work area. */
.btn.primary { background: var(--brand-grad); color: white; border-color: transparent; box-shadow: var(--shadow-brand); }
.btn.primary:hover { color: white; border-color: transparent; }
.btn.gold { background: var(--gold-soft); color: var(--amber); border-color: #FCD34D; }
.btn.gold:hover { color: var(--amber); border-color: var(--amber); }
.hint { color: var(--muted); font-size: 12.5px; margin: -8px 0 14px; line-height: 1.5; }
.link-inline { background: none; border: none; padding: 0; color: var(--brand); text-decoration: underline; font-size: inherit; cursor: pointer; font-weight: 700; }

/* ---------- Modal ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(11,18,32,0.52);
  display: flex; align-items: center; justify-content: center; z-index: 60;
  backdrop-filter: blur(3px);
}
.modal-backdrop.hidden { display: none; }
.modal {
  background: var(--surface); border-radius: var(--radius-lg); padding: 24px; width: 520px; max-width: 92vw;
  max-height: 88vh; overflow: auto; box-shadow: var(--shadow-lg);
  border: 1px solid rgba(255,255,255,0.6);
}
.modal h2 { margin-top: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.025em; color: var(--ink); }
.modal label {
  display: block; font-size: 10.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-top: 14px; margin-bottom: 5px;
}
.modal input, .modal select, .modal textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 13.5px; font-family: inherit; color: var(--ink-2); background: var(--surface);
}
.modal input:focus, .modal select:focus, .modal textarea:focus { border-color: var(--brand); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.modal-actions { margin-top: 22px; display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.modal-actions button {
  padding: 9px 18px; border-radius: var(--radius-pill); border: 1px solid var(--border);
  cursor: pointer; font-weight: 600; font-size: 13px; font-family: inherit;
  background: var(--surface); color: var(--ink-2);
}
.modal-actions button:hover { border-color: #CBD5E1; background: var(--surface-2); }
.modal-actions button.primary { background: var(--brand-grad); color: white; border-color: transparent; box-shadow: var(--shadow-brand); font-weight: 700; }
.modal-actions button.danger-btn { border-color: #FCA5A5; color: var(--red); background: var(--red-soft); }
.suggestion-list { list-style: none; padding: 0; margin: 6px 0; }
.suggestion-list li { padding: 4px 0; }
.suggestion-list button { font-size: 12px; padding: 5px 13px; border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface); color: var(--ink-2); cursor: pointer; font-weight: 600; font-family: inherit; }

/* ---------- Day side panel ---------- */
.panel-backdrop {
  position: fixed; inset: 0; background: rgba(11,18,32,0.42); z-index: 55;
  backdrop-filter: blur(2px);
}
.panel-backdrop.hidden { display: none; }
.day-panel {
  position: absolute; top: 0; right: 0; height: 100%; width: 420px; max-width: 92vw;
  background: var(--surface); box-shadow: var(--shadow-lg);
  overflow-y: auto;
  padding: 22px 22px 40px;
  animation: slideIn 0.18s ease-out;
}
@keyframes slideIn { from { transform: translateX(24px); opacity: 0.4; } to { transform: none; opacity: 1; } }
.day-panel h2 { font-size: 18px; margin: 0 0 3px; font-weight: 700; letter-spacing: -0.025em; color: var(--ink); }
.day-panel .panel-sub { color: var(--muted); font-size: 12.5px; margin-bottom: 18px; }
.panel-close {
  position: absolute; top: 20px; right: 20px; width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface); color: var(--muted); cursor: pointer;
}
.panel-close:hover { background: var(--surface-2); color: var(--ink); border-color: #CBD5E1; }

.quick-add-toggle {
  width: 100%;
  padding: 11px;
  border: 1.5px dashed #CBD5E1;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--brand);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  margin-bottom: 16px;
}
.quick-add-toggle:hover { border-color: var(--brand); background: var(--brand-soft); }
.quick-add-form {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px;
  margin-bottom: 18px;
}
.quick-add-form label { display: block; font-size: 10.5px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; margin: 10px 0 4px; }
.quick-add-form input, .quick-add-form select { width: 100%; padding: 8px 10px; border-radius: var(--radius-xs); border: 1px solid var(--border); font-size: 13px; font-family: inherit; background: var(--surface); }
.quick-add-actions { display: flex; gap: 8px; margin-top: 12px; }
.quick-add-actions button { flex: 1; padding: 9px; border-radius: var(--radius-pill); border: none; font-weight: 700; font-size: 13px; cursor: pointer; font-family: inherit; }
.quick-add-actions .save { background: var(--brand-grad); color: white; box-shadow: var(--shadow-brand); }
.quick-add-actions .more { background: var(--surface); border: 1px solid var(--border); color: var(--ink-2); }

.panel-job-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-bottom: 10px;
  box-shadow: var(--shadow-xs);
}
.panel-job-card.cancelled { opacity: 0.5; }
.panel-job-card .row1 { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.panel-job-card .name { font-weight: 700; font-size: 14px; }
.panel-job-card .meta { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.panel-job-card select { width: 100%; margin-bottom: 8px; padding: 6px 8px; border-radius: 7px; border: 1px solid var(--border); font-size: 12.5px; }
.panel-job-card .actions { display: flex; gap: 6px; }
.panel-job-card .actions button { flex: 1; font-size: 11px; padding: 6px; border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface); color: var(--ink-2); cursor: pointer; font-weight: 600; font-family: inherit; }
.panel-job-card .actions button.danger { border-color: #FCA5A5; color: var(--red); background: var(--red-soft); }
.panel-job-card .actions button.ok { border-color: #86EFAC; color: var(--green); background: var(--green-soft); }
.panel-empty { text-align: center; color: var(--muted); font-size: 13px; padding: 30px 10px; }

/* ---------- Bulk add cleaners ---------- */
.bulk-add-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  margin-bottom: 18px;
}
.bulk-add-box { box-shadow: var(--shadow-sm); }
.bulk-add-box textarea { width: 100%; min-height: 90px; padding: 11px; border-radius: var(--radius-sm); border: 1px solid var(--border); font-size: 13px; font-family: inherit; background: var(--surface-2); color: var(--ink-2); line-height: 1.55; }
.bulk-add-box textarea:focus { border-color: var(--brand); background: var(--surface); outline: none; }
.bulk-preview { margin-top: 10px; font-size: 12.5px; color: var(--muted); }
.bulk-preview table { width: 100%; margin-top: 8px; border-collapse: collapse; }
.bulk-preview td { padding: 4px 8px; border-top: 1px solid var(--border-soft); }

/* ---------- Hours / payroll ---------- */
.payroll-heading { font-size: 16px; font-weight: 700; color: var(--ink); margin: 24px 0 8px; letter-spacing: -0.02em; }
.payroll-table th, .payroll-table td { white-space: nowrap; font-size: 13px; }
.payroll-table tfoot td { border-top: 2px solid var(--border); background: var(--surface-2); font-weight: 700; color: var(--ink); }
.payroll-input {
  width: 72px;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  font-family: inherit;
}
.payroll-input:disabled { background: var(--border-soft); color: var(--muted); }
.incomplete-flag { color: var(--red); font-size: 11.5px; font-weight: 700; margin-left: 8px; }
.hours-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  margin-bottom: 14px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.hours-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 18px;
  cursor: pointer;
  background: var(--surface-2);
}
.hours-card-head .name { font-weight: 700; font-size: 14.5px; color: var(--ink); letter-spacing: -0.015em; }
.hours-card-head .total { font-weight: 700; font-size: 16px; color: var(--brand); }
.hours-card-head .incomplete-flag { color: var(--red); font-size: 11.5px; font-weight: 700; margin-left: 8px; }
.hours-shifts { display: none; }
.hours-shifts.open { display: block; }
.shift-row {
  display: grid;
  grid-template-columns: 90px 1fr 90px 90px 80px;
  gap: 10px;
  padding: 9px 18px;
  border-top: 1px solid var(--border-soft);
  font-size: 12.5px;
  align-items: center;
}
.shift-row.incomplete { background: var(--red-soft); }
.shift-row .duration { font-weight: 700; text-align: right; }

/* ---------- Calendar view switcher (Day/Week/Month/Quarter/Year) ---------- */
.view-switch {
  display: flex;
  background: var(--canvas);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 2px;
}
.view-switch button {
  border: none;
  background: transparent;
  padding: 6px 13px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.view-switch button.active { background: var(--surface); color: var(--brand); box-shadow: var(--shadow-xs); font-weight: 700; }
.view-switch button:hover:not(.active) { color: var(--ink); }

/* ---------- Day view ---------- */
.day-view-row {
  display: grid;
  grid-template-columns: 72px 1fr 130px 160px 190px;
  gap: 12px;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin-bottom: 10px;
  box-shadow: var(--shadow-sm);
}
.day-view-row.cancelled { opacity: 0.45; text-decoration: line-through; }
.day-view-row .time { font-weight: 700; font-size: 13.5px; color: var(--ink); }
.day-view-row .client-block .name { font-weight: 600; font-size: 14px; color: var(--ink); letter-spacing: -0.01em; }
.day-view-row .client-block .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.day-view-empty {
  text-align: center;
  padding: 70px 20px;
  color: var(--muted);
  background: var(--surface);
  border: 1px dashed #CBD5E1;
  border-radius: var(--radius-lg);
}

/* ---------- Drag-to-reschedule (Week view) ----------
   Native HTML5 drag-and-drop on the original list rows — dragging a job row
   from one day's block and dropping it on another day's block moves it
   there (same time, editable afterward like any other job). Day view rows
   aren't drop targets since there's only ever one day visible to drop onto. */
.day-view-row[draggable="true"], .job-row[draggable="true"] { cursor: grab; }
.day-view-row.dragging, .job-row.dragging { opacity: 0.4; }
.day-block.drag-over { outline: 2px dashed var(--teal); outline-offset: -2px; background: var(--teal-soft); }

/* ---------- Quarter / Year mini-month grids ---------- */
.quarter-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.year-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.mini-month {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px;
  box-shadow: var(--shadow-sm);
}
.mini-month-title {
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.015em;
  margin-bottom: 8px;
  text-align: center;
  cursor: pointer;
  color: var(--ink);
}
.mini-month-title:hover { text-decoration: underline; }
.mini-weekday-row { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 4px; }
.mini-weekday-row span { text-align: center; font-size: 9px; font-weight: 700; color: var(--muted); }
.mini-body { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mini-cell {
  aspect-ratio: 1;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 9.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  background: var(--surface-2);
  position: relative;
}
.mini-cell.outside { visibility: hidden; }
.mini-cell.today { outline: 1.5px solid var(--brand); color: var(--brand); }
.mini-cell:hover { background: var(--border-soft); }
.mini-dots { display: flex; gap: 1.5px; margin-top: 1px; }
.mini-dot { width: 4px; height: 4px; border-radius: 50%; }
.year-grid .mini-cell { font-size: 7.5px; }
.year-grid .mini-dots { display: none; } /* year view: too small for dots, cell tint conveys density instead */

/* ---------- Holidays ---------- */
.mini-cell.holiday { background: var(--gold-soft) !important; outline: 1.5px solid var(--gold); color: var(--teal-dark) !important; }
.holiday-banner {
  background: var(--gold-soft);
  border: 1.5px solid var(--gold);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin-bottom: 14px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--teal-dark);
  display: flex;
  align-items: center;
  gap: 8px;
}
.day-header.holiday { background: var(--gold-soft); }
.holiday-tag {
  display: inline-block;
  background: var(--amber);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  margin-left: 8px;
}
.day-view-row.on-holiday, .job-row.on-holiday { outline: 2px solid var(--gold); outline-offset: -2px; }

/* ---------- Fill-gap prompt ---------- */
.fill-gap-prompt {
  background: var(--gold-soft);
  border: 1.5px dashed var(--gold);
  border-radius: var(--radius-md);
  padding: 14px;
  text-align: center;
  margin-top: 6px;
}
.fill-gap-prompt button { margin-top: 8px; }

/* ---------- Gaps list ---------- */
.gap-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius-md);
  padding: 11px 13px;
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  box-shadow: var(--shadow-xs);
}
.gap-item .info { font-size: 13px; }
.gap-item .info .date { font-weight: 700; color: var(--ink); }
.gap-item .info .who { color: var(--muted); font-size: 12px; }
.gap-item button { flex-shrink: 0; padding: 6px 13px; border-radius: var(--radius-pill); border: 1px solid var(--brand); color: var(--brand); background: var(--surface); font-weight: 600; font-size: 12px; cursor: pointer; font-family: inherit; }
.gap-item button:hover { background: var(--brand); color: white; }

.leave-actions { display: flex; gap: 6px; flex-shrink: 0; }
.leave-actions button.deny { border-color: var(--red, #B91C1C); color: var(--red, #B91C1C); }
.leave-actions button.deny:hover { background: var(--red, #B91C1C); color: white; }
.leave-actions button.approve { border-color: #15803D; color: #15803D; }
.leave-actions button.approve:hover { background: #15803D; color: white; }
.leave-item-reason { color: var(--muted); font-size: 12px; margin-top: 2px; font-style: italic; }
.leave-section-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin: 16px 0 7px; }
.leave-section-label:first-child { margin-top: 0; }
.leave-decided-pill { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-pill); flex-shrink: 0; }
.leave-decided-pill.approved { background: #DCFCE7; color: #15803D; }
.leave-decided-pill.denied { background: #FEE2E2; color: var(--red, #B91C1C); }

.suggestion-item { border-left-color: var(--gold); }
.suggestion-item.high { border-left-color: var(--red, #B91C1C); }
.suggestion-item.medium { border-left-color: var(--gold); }
.suggestion-item.low { border-left-color: #4338CA; }
.suggestion-item .info { flex: 1; }
.suggestion-item .title { font-weight: 700; font-size: 13px; }
.suggestion-item .detail { color: var(--muted); font-size: 12px; margin-top: 3px; line-height: 1.4; }
.suggestion-severity-pill { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; padding: 3px 9px; border-radius: var(--radius-pill); flex-shrink: 0; margin-left: 10px; }
.suggestion-severity-pill.high { background: #FEE2E2; color: var(--red, #B91C1C); }
.suggestion-severity-pill.medium { background: var(--gold-soft); color: var(--gold); }
.suggestion-severity-pill.low { background: #E0E7FF; color: #4338CA; }

/* ---------- Availability toggles ---------- */
.avail-row { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 2px; }
.avail-day {
  flex: 1;
  min-width: 40px;
  padding: 9px 4px;
  text-align: center;
  border-radius: var(--radius-xs);
  border: 1.5px solid var(--border);
  background: var(--surface);
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
}
.avail-day:hover { border-color: #CBD5E1; }
.avail-day.on { background: var(--green-soft); border-color: var(--green); color: var(--green); }

/* ============================================================
   MOTION & POLISH — a cohesive layer of transitions, hover states,
   and micro-interactions across the whole app. Kept fast (120–200ms)
   and subtle: motion should confirm an action happened, never slow
   the person down.
   ============================================================ */

/* Transitions are declared on the things that actually change state. The old
   build put them on `*`, which meant every table repaint animated and every
   cell carried a compositor cost on a view that can render 500 rows. */
button, a, select, input, textarea, .month-cell, .mini-cell, .job-row, .job-chip,
.day-view-row, .panel-job-card, .hours-card, .gap-item, .activity-item, .kpi-card,
.color-swatch, .cleaner-tile, .nav-item, .icon-chip, .billing-row, .request-card,
.user-menu-item, .cleaner-ms-item, .avail-day, .data-table tr {
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease,
              box-shadow 0.18s ease, transform 0.1s ease, opacity 0.15s ease;
}
button:not(:disabled) { cursor: pointer; }
button:active:not(:disabled) { transform: scale(0.97); }
.new-btn:hover { transform: translateY(-1px); }
.new-btn:active { transform: scale(0.97); }
.btn:hover:not(:disabled) { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.btn.primary:hover:not(:disabled) { box-shadow: 0 8px 22px rgba(79,70,229,0.44); }
.icon-btn-round:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.today-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }

/* Card lift on hover — depth that confirms a target, nothing more. */
.month-cell:hover { box-shadow: inset 0 0 0 1.5px var(--brand); z-index: 1; }
.mini-cell:hover:not(.outside) { transform: scale(1.12); box-shadow: 0 2px 8px rgba(11,18,32,0.14); z-index: 2; }
.day-view-row:hover, .job-row:hover, .panel-job-card:hover { box-shadow: var(--shadow-md); }
.day-view-row:hover, .panel-job-card:hover { border-color: #CBD5E1; }
.hours-card-head:hover { background: var(--border-soft); }
.gap-item:hover, .activity-item:hover, .request-card:hover, .billing-row:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.cleaner-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.cleaner-tile:active { transform: scale(0.97); }
.data-table tr:hover td { transform: none; }
.color-swatch:hover { transform: scale(1.15); }
.job-chip:hover { filter: brightness(1.06); z-index: 1; position: relative; }

/* Badge pulse when a count changes — draws the eye without being obnoxious */
@keyframes badgePulse { 0% { transform: scale(1); } 40% { transform: scale(1.3); } 100% { transform: scale(1); } }
.badge:not(.hidden) { animation: badgePulse 0.35s ease; }

/* Modal: fade + gentle scale-in instead of appearing instantly */
.modal-backdrop:not(.hidden) { animation: fadeIn 0.15s ease; }
.modal-backdrop:not(.hidden) .modal { animation: modalIn 0.2s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: none; } }

/* Panels (day/activity/gaps) already slide in — add a matching backdrop fade */
.panel-backdrop:not(.hidden) { animation: fadeIn 0.15s ease; }

/* View switch: fade the new view's content in so navigation feels alive, not a jump-cut */
@keyframes viewIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.view.active .view-content { animation: viewIn 0.18s ease-out; }

/* Sidebar nav active indicator — the light accent-tinted background (set above)
   is the indicator now; no separate bar needed against a white sidebar. */
.nav-item { position: relative; overflow: hidden; }

/* Toast (admin side) */
.admin-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(140%);
  background: var(--rail);
  color: white;
  padding: 12px 20px;
  border-radius: var(--radius-pill);
  font-size: 13.5px;
  font-weight: 600;
  z-index: 200;
  box-shadow: var(--shadow-lg);
  transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
  max-width: 90vw;
}
.admin-toast.show { transform: translateX(-50%) translateY(0); }
.admin-toast.success { background: var(--green); }
.admin-toast.error { background: var(--red); }

/* Skeleton shimmer used while data loads — shared with the cleaner app's style */
.skeleton-card {
  background: linear-gradient(90deg, var(--border-soft) 25%, #fff 37%, var(--border-soft) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--radius-md);
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* ============================================================
   DASHBOARD
   ============================================================ */
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 26px; }

/* ---------- KPI card ----------
   The number alone never told the owner whether it was good news. Each card
   now closes with a status bar in the metric's own signal colour, sitting
   directly under the sentence that explains it — colour and words together,
   so the reading survives greyscale, and so a glance across the row shows
   which figure needs attention before any of them are actually read. */
.kpi-card {
  position: relative; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 16px 16px 18px; box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.kpi-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi-chip {
  width: 30px; height: 30px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; margin-bottom: 14px;
}
.kpi-chip svg { width: 15px; height: 15px; }
.kpi-label {
  font-size: 10.5px; font-weight: 700; color: var(--muted); margin-bottom: 7px;
  text-transform: uppercase; letter-spacing: 0.07em;
}
.kpi-value { font-size: 27px; font-weight: 700; color: var(--ink); line-height: 1.05; }
.kpi-sub { font-size: 12px; color: var(--muted); margin-top: 6px; line-height: 1.4; }
/* One stripe, full width, four states. An earlier pass filled it
   proportionally, but the proportion meant a different thing on every card
   ("share completed" here, nothing at all there) — a scale nobody could read.
   A solid stripe says only what it can back up: informational, good, watch,
   or attention, and the sentence above it supplies the detail. */
.kpi-card .kpi-bar {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--brand);
}
.kpi-card.tone-good  .kpi-bar { background: var(--green); }
.kpi-card.tone-watch .kpi-bar { background: #D97706; }
.kpi-card.tone-bad   .kpi-bar { background: var(--red); }

.dash-cols { display: grid; grid-template-columns: 1.3fr 1fr; gap: 20px; margin-bottom: 16px; }
@media (max-width: 900px) { .dash-cols { grid-template-columns: 1fr; } }
.dash-panel {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 16px 18px; box-shadow: var(--shadow-sm); margin-bottom: 16px;
}
.dash-panel h3 { margin: 0 0 12px; font-size: 14px; color: var(--ink); font-weight: 700; letter-spacing: -0.015em; }
/* Section captions that sit above (not inside) a card — matches the CleanGrid
   prototype's "Top clients this week" / "Recent activity" treatment. */
.section-label {
  font-size: 10.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.08em; margin: 0 0 10px;
}

.util-row { display: grid; grid-template-columns: 140px 1fr 44px; align-items: center; gap: 10px; padding: 7px 0; }
.util-name { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.util-bar-track { height: 8px; border-radius: var(--radius-pill); background: var(--canvas); overflow: hidden; box-shadow: inset 0 0 0 1px var(--border-soft); }
.util-bar-fill { height: 100%; border-radius: var(--radius-pill); transition: width 0.4s ease; }
.util-pct { font-size: 12px; font-weight: 700; color: var(--ink-2); text-align: right; }

.audit-list { display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow-y: auto; }
.audit-row { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; }
.audit-row:last-child { border-bottom: none; }
.audit-when { color: var(--muted-2); white-space: nowrap; font-weight: 600; min-width: 64px; font-variant-numeric: tabular-nums; }

/* ============================================================
   CLIENT REQUESTS INBOX
   ============================================================ */
.request-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 14px 16px; margin-bottom: 10px; box-shadow: var(--shadow-sm);
}
.request-card.resolved { opacity: 0.55; }
.request-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.request-type { background: var(--amber-soft); color: var(--amber); font-size: 10.5px; font-weight: 700; padding: 4px 10px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: 0.05em; }
.request-msg {
  margin-top: 10px; font-size: 13.5px; color: var(--ink-2); line-height: 1.5;
  background: var(--surface-2); padding: 10px 12px; border-radius: var(--radius-sm);
  border-left: 3px solid var(--border);
}
.request-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 12px; }
.request-foot button { padding: 6px 14px; border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface); color: var(--ink-2); font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; }
.request-foot button.ok { background: var(--green); color: white; border-color: var(--green); }

/* ============================================================
   DAY ROUTE MAP
   ============================================================ */
/* position+z-index here isn't decorative — it gives the map its own stacking
   context so Leaflet's internal z-index values (its zoom controls sit at
   ~1000) stay contained inside the map instead of rendering on top of a
   modal that's open at the same time (modal-backdrop is z-index:60). */
.day-map-container { margin-bottom: 16px; position: relative; z-index: 1; }
.day-map-container.hidden { display: none; }
.day-map { height: 380px; border-radius: var(--radius-md); border: 1px solid var(--border); box-shadow: var(--shadow-sm); }
.map-note { margin: 8px 0 0; }
.map-pin {
  width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  color: white; font-weight: 800; font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.35); border: 2px solid white;
}
#dayMapToggle.active, #weekMapToggle.active, #monthMapToggle.active, #clientsMapToggle.active { background: var(--teal); color: white; border-color: var(--teal); }
.checklist-pill { background: var(--surface-2); color: var(--ink-2); font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: var(--radius-pill); border: 1px solid var(--border); white-space: nowrap; }
.checklist-pill.done { background: var(--green-soft); color: var(--green); border-color: #86EFAC; }

/* Portal link row inside the client edit modal */
.portal-link-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: var(--amber-soft); border: 1px solid #FCD34D; border-radius: var(--radius-sm);
  padding: 10px 12px; margin-bottom: 16px; font-size: 13px; font-weight: 600; color: #78350F;
}
.portal-link-actions { display: flex; gap: 6px; }
.portal-link-actions .btn { padding: 6px 10px; font-size: 12px; }

/* ============================================================
   BILLING
   ============================================================ */
/* The outstanding total is the single figure the owner opens this view for,
   so it gets the one large gradient surface in the app. */
.billing-summary-card {
  background: var(--brand-grad); color: white; border-radius: var(--radius-lg);
  padding: 22px 26px; margin-bottom: 20px; max-width: 340px;
  box-shadow: 0 12px 32px rgba(79, 70, 229, 0.30);
}
.billing-summary-label {
  font-size: 10.5px; color: rgba(255,255,255,0.82); margin-bottom: 8px;
  text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
}
.billing-summary-value { font-size: 32px; font-weight: 700; letter-spacing: -0.03em; }
.billing-summary-sub { font-size: 12.5px; color: rgba(255,255,255,0.82); margin-top: 5px; }

.billing-row {
  display: flex; align-items: center; gap: 16px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 14px 18px; margin-bottom: 10px; box-shadow: var(--shadow-sm);
  border-left: 3px solid var(--border);
}
/* Overdue keeps its red wash but also its own left edge and the word
   "overdue" in the sub-line, so it never depends on the tint alone. */
.billing-row.overdue { border-color: #FCA5A5; border-left-color: var(--red); background: #FFF6F6; }
.billing-row-name { font-weight: 600; font-size: 14.5px; color: var(--ink); letter-spacing: -0.01em; }
.billing-row-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.billing-row.overdue .billing-row-sub { color: var(--red); font-weight: 600; }
.billing-row-amount { font-weight: 700; font-size: 15px; color: var(--ink); margin-left: auto; }
.billing-paid-pill { background: var(--green-soft); color: var(--green); font-size: 11.5px; font-weight: 700; padding: 5px 12px; border-radius: var(--radius-pill); white-space: nowrap; }

/* ============================================================
   RESPONSIVE — desktop (default) / iPad (icon-rail) / mobile (drawer)
   ============================================================ */

/* Wide content scrolls inside its own container — the page itself never
   scrolls sideways, at any breakpoint. */
.table-scroll { overflow-x: auto; }
.table-scroll .data-table { min-width: 640px; }
.month-grid { overflow-x: auto; }
.month-grid > * { min-width: 700px; }
/* Quarter/Year are grids of small month cards — at narrow widths they read
   better stacking into fewer columns than staying fixed-width and scrolling
   sideways (unlike a table, there's no natural "row" to scroll through). */

/* ---------- Job rows below ~1000px ----------
   Day and week rows are fixed six-column grids (~600px of rigid tracks before
   the client name gets a pixel). On an iPad in portrait that pushed the Cancel
   button past the right edge and scrolled the whole page sideways. Below
   1000px they stack into labelled bands instead: time + client on top, then
   zone, then the assignment control, then the actions. Same elements, same
   order, no horizontal scroll. */
@media (max-width: 1000px) {
  .day-view-row {
    grid-template-columns: 58px minmax(0, 1fr);
    grid-template-areas: "time client" "zone zone" "cleaner cleaner" "actions actions";
    row-gap: 9px; column-gap: 12px; align-items: start;
    padding: 13px 14px;
  }
  .day-view-row .time { grid-area: time; padding-top: 1px; }
  .day-view-row .client-block { grid-area: client; }
  .day-view-row .zone-badge { grid-area: zone; }
  .day-view-row .cleaner-select-wrap { grid-area: cleaner; }
  .day-view-row .job-actions { grid-area: actions; flex-wrap: wrap; }

  .job-row {
    grid-template-columns: 58px minmax(0, 1fr);
    grid-template-areas: "time client" "zone pay" "cleaner cleaner" "actions actions";
    row-gap: 8px; column-gap: 12px; align-items: center;
  }
  .job-row > :nth-child(1) { grid-area: time; }
  .job-row > :nth-child(2) { grid-area: client; }
  .job-row > .zone-badge { grid-area: zone; justify-self: start; }
  .job-row > .pay-cash, .job-row > .pay-invoice { grid-area: pay; justify-self: end; }
  .job-row > .cleaner-select-wrap { grid-area: cleaner; }
  .job-row > .job-actions { grid-area: actions; flex-wrap: wrap; }

  .shift-row { grid-template-columns: 1fr 1fr; row-gap: 4px; }
  .shift-row .duration { text-align: left; }
}

.hamburger-btn {
  display: none; width: 36px; height: 36px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface); color: var(--ink-2);
  font-size: 17px; cursor: pointer; flex-shrink: 0; box-shadow: var(--shadow-xs);
}
.sidebar-backdrop {
  position: fixed; inset: 0; background: rgba(11,18,32,0.5); z-index: 90;
  backdrop-filter: blur(2px);
}
.sidebar-backdrop.hidden { display: none; }

/* ---------- iPad: the rail collapses to icons only ---------- */
@media (max-width: 1100px) and (min-width: 641px) {
  .sidebar { width: 72px; padding: 16px 10px; align-items: center; }
  .sidebar-brand { padding: 4px 0 18px; }
  .sidebar-brand > div { display: none; } /* hide title/subtitle text, keep just the mark */
  .sidebar-brand .mark { width: 30px; height: 30px; }
  .new-btn { width: 46px; height: 46px; padding: 0; border-radius: 50%; font-size: 20px; }
  .new-btn-label { display: none; }
  .new-btn-icon { font-size: 22px; }
  .bell-btn { width: 46px; height: 46px; padding: 0; border-radius: 50%; position: relative; justify-content: center; margin-top: 4px; }
  .bell-btn .btn-label { display: none; }
  .bell-btn .icon svg, .assistant-btn .icon svg { width: 15px; height: 15px; }
  .assistant-btn .icon, .sidebar .icon-chip { width: 26px; height: 26px; }
  .sidebar .icon-chip svg { width: 14px; height: 14px; }
  .badge { position: absolute; top: 0; right: 0; }
  /* Top-nav labels stay: .nav-items-scroll already scrolls horizontally, and
     an icon-only view switcher costs more than the row of text it saves. */
  .nav-item .icon svg { width: 18px; height: 18px; }

  .sidebar-footer { padding-top: 12px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
  .sidebar-footer .sidebar-link { padding: 0; }
  .sidebar-footer .sidebar-link .btn-label { display: none; }
  .sidebar-footer .sidebar-link .icon svg { width: 17px; height: 17px; }
  .sidebar-user { flex-direction: column; gap: 4px; border-top: none; padding-top: 0; }
  .sidebar-user span { display: none; }

  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .dash-cols { grid-template-columns: 1fr; }
  .actions-grid, .month-cell .cell-jobs { font-size: 12px; }
  .quarter-grid { grid-template-columns: 1fr; }
  .year-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- Mobile: sidebar becomes an off-canvas drawer ---------- */
@media (max-width: 640px) {
  .app-shell { display: block; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: 250px; z-index: 100;
    transform: translateX(-100%); transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
    overflow-y: auto;
  }
  .sidebar.open { transform: translateX(0); box-shadow: 0 0 60px rgba(11,18,32,0.5); }
  .hamburger-btn { display: block; }
  .main { width: 100%; }
  .top-nav-bar { padding: 8px 12px; }
  .topbar { padding: 12px 16px; gap: 10px; }
  .topbar h1 { font-size: 17px; min-width: 0; margin-left: 0; }
  .topbar-left, .topbar-right { gap: 6px; }
  .view-content { padding: 16px 14px 48px; }

  .kpi-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .kpi-card { padding: 13px 13px 15px; }
  .kpi-value { font-size: 21px; }
  .kpi-chip { width: 26px; height: 26px; margin-bottom: 10px; }
  .dash-cols { grid-template-columns: 1fr; }
  .toolbar { gap: 8px; }
  .toolbar input, .toolbar select, .toolbar .field { flex: 1 1 auto; min-width: 120px; }
  .quarter-grid, .year-grid { grid-template-columns: 1fr; }
  .billing-summary-card { max-width: none; padding: 18px 20px; }
  .modal { padding: 20px 18px; }
}

/* Respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
