:root {
  --bg: #f5f6f8;
  --panel: #ffffff;
  --border: #d9dce2;
  --text: #1f2430;
  --muted: #6b7280;
  --accent: #2563eb;
  --accent-soft: #eaf1ff;
  --ok: #16a34a;
  --err: #dc2626;
  --off: #9ca3af;
  --hover: #fbfcfe;
  /* Night/Day column-group tinting -- Audit Report page (webapp/sweep_audit.py) */
  --night: #3a5a8c;
  --night-tint: #eef3fa;
  --day: #b8860b;
  --day-tint: #fbf4e2;
  color-scheme: light;
}
/* ken, 2026-09-19: select/date-input text going fully blank in dark mode
   once edit revealed them -- without color-scheme telling the browser
   which palette we're actually using, Chrome renders native form-control
   chrome (a select's own painted widget, not just our CSS box) using its
   light-mode assumptions even while the OS is in dark mode, so our
   near-white --text color landed on the browser's own near-white native
   widget background: invisible text, not missing text. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }

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

/* Hub menu (header.topbar) styles live in templates/_topbar.html -- one copy for every page. */

main { padding: 1.25rem 1.5rem 3rem; max-width: 1400px; margin: 0 auto; }

h1 { font-size: 1.3rem; margin: 0 0 0.9rem; }

.toolbar { display: flex; gap: 0.75rem; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; }
.toolbar input[type=search], .toolbar input[data-search-scope] {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  min-width: 240px;
  font-size: 14px;
  width: auto;
}
.count { color: var(--muted); }
.skip-list { display: inline-flex; gap: 0.3rem; flex-wrap: wrap; margin-bottom: 0.3rem; }
.skip-badge {
  display: inline-flex; align-items: center; gap: 0.25rem;
  background: var(--accent-soft); color: var(--accent);
  font-size: 11.5px; padding: 2px 6px; border-radius: 4px;
}
.skip-badge button { background: none; border: none; color: inherit; cursor: pointer; padding: 0; font-size: 11px; }

/* overflow-x:auto directly on <table> turned out not to reliably create a
   scroll region across real mobile browsers (ken, 2026-09-19: "they go to
   the right and don't scroll") -- wrapping in a plain block div is the
   robust cross-browser version of the same idea. Every <table> in the
   Jinja templates is wrapped in one (see templates/*.html). */
.table-scroll { width: 100%; max-width: 100%; overflow-x: auto; }
table { width: 100%; max-width: 100%; border-collapse: collapse; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; }

/* Jobs/Tickets: ken, 2026-09-19: "the alignment is still off... the
   entire section gets larger" in edit mode -- with plain auto table
   layout, swapping a column's content (span -> select/textarea) changes
   that cell's natural content width, and the browser reflows every
   column's width to compensate. A select can end up squeezed down to
   just its arrow, showing no visible text at all. table-layout:fixed
   with explicit per-column widths (below) makes column widths depend
   only on the header row, never on which mode a row is in -- switching
   to edit only ever changes row *height* (the description box growing
   to fit its text), never column width. Columns still shrink together
   on narrow screens via the existing .table-scroll horizontal scroll. */
/* min-width floor: table-layout:fixed's percentage columns always fill
   exactly 100% of whatever space is available, so on a narrower window
   they just crush every column (a select can end up with only its arrow
   visible) instead of triggering .table-scroll's horizontal scrollbar --
   ken, 2026-09-19: reproduced by simply narrowing the browser window,
   nothing to do with the browser itself. A min-width forces the table to
   refuse to shrink past the point its columns are actually usable, which
   is exactly what hands control to .table-scroll's overflow-x:auto. */
table.jobs-table { table-layout: fixed; min-width: 900px; }
/* nth-child(1) is now the drag-handle column added 2026-09-22 -- fixed
   width (not %), so it doesn't eat into the real columns' room; every
   other column shifted down by one from here. Caught by ken: this shift
   was left un-done at first, which squeezed Description down to the old
   5%-wide Qty column's space and left the actions column with no rule
   (and so no room) at all. */
table.jobs-table th:nth-child(1), table.jobs-table td:nth-child(1) { width: 1.8rem; }  /* drag handle */
table.jobs-table th:nth-child(2), table.jobs-table td:nth-child(2) { width: 13%; }  /* Item */
table.jobs-table th:nth-child(3), table.jobs-table td:nth-child(3) { width: 19%; }  /* Description */
table.jobs-table th:nth-child(4), table.jobs-table td:nth-child(4) { width: 5%; }   /* Qty */
table.jobs-table th:nth-child(5), table.jobs-table td:nth-child(5) { width: 6%; }   /* Qty varies? */
table.jobs-table th:nth-child(6), table.jobs-table td:nth-child(6) { width: 6%; }   /* Cost */
table.jobs-table th:nth-child(7), table.jobs-table td:nth-child(7) { width: 12%; }  /* Frequency -- "Every 2 months"/"Every 6 months" need real room */
table.jobs-table th:nth-child(8), table.jobs-table td:nth-child(8) { width: 9%; }   /* Cadence start */
table.jobs-table th:nth-child(9), table.jobs-table td:nth-child(9) { width: 5%; }   /* On */
table.jobs-table th:nth-child(10), table.jobs-table td:nth-child(10) { width: 12%; } /* Skips */
table.jobs-table th:nth-child(11), table.jobs-table td:nth-child(11) { width: 13%; } /* actions */

table.tickets-table { table-layout: fixed; min-width: 1100px; }
/* same fields as an invoice line: item, description, qty, rate, amount (ken, 2026-10-21) */
table.tickets-table th:nth-child(1), table.tickets-table td:nth-child(1) { width: 6%; }  /* Lot */
table.tickets-table th:nth-child(2), table.tickets-table td:nth-child(2) { width: 12%; } /* Date -- native date input needs real room or it clips itself, not just the column */
table.tickets-table th:nth-child(3), table.tickets-table td:nth-child(3) { width: 11%; } /* Item */
table.tickets-table th:nth-child(4), table.tickets-table td:nth-child(4) { width: 19%; } /* Description */
table.tickets-table th:nth-child(5), table.tickets-table td:nth-child(5) { width: 5%; }  /* Qty */
table.tickets-table th:nth-child(6), table.tickets-table td:nth-child(6) { width: 7%; }  /* Rate */
table.tickets-table th:nth-child(7), table.tickets-table td:nth-child(7) { width: 7%; }  /* Amount */
table.tickets-table th:nth-child(8), table.tickets-table td:nth-child(8) { width: 9%; }  /* Performed by */
table.tickets-table th:nth-child(9), table.tickets-table td:nth-child(9) { width: 8%; }  /* Invoice month */
table.tickets-table th:nth-child(10), table.tickets-table td:nth-child(10) { width: 8%; } /* Status */
table.tickets-table th:nth-child(11), table.tickets-table td:nth-child(11) { width: 8%; } /* actions */


thead th {
  text-align: left;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--border);
  background: #fafbfc;
}
tbody td { padding: 0.4rem 0.7rem; border-bottom: 1px solid #eef0f3; vertical-align: middle; }
tbody tr:hover { background: var(--hover); }
tbody tr.saved-flash td { background: #eafaf0; transition: background 1.2s ease; }
tbody tr.error-flash td { background: #fdeceb; transition: background 1.2s ease; }

input[type=text], input[type=number], input[type=date], input[type=month], select {
  width: 100%;
  border: 1px solid transparent;
  background: transparent;
  padding: 0.3rem 0.35rem;
  border-radius: 5px;
  font-size: 13.5px;
  font-family: inherit;
  color: var(--text);
  box-sizing: border-box;
}
input[type=text]:hover, input[type=number]:hover, input[type=date]:hover, input[type=month]:hover, select:hover { border-color: var(--border); }
input[type=text]:focus, input[type=number]:focus, input[type=date]:focus, input[type=month]:focus, select:focus {
  outline: none; border-color: var(--accent); background: var(--accent-soft);
}
input:disabled { color: var(--muted); cursor: not-allowed; }

textarea {
  width: 100%; border: 1px solid var(--border); background: transparent;
  padding: 0.3rem 0.5rem; border-radius: 5px; font-size: 13.5px;
  font-family: inherit; color: var(--text); resize: vertical;
}
textarea:hover { border-color: var(--accent); }
textarea:focus { outline: none; border-color: var(--accent); background: var(--accent-soft); }

/* Jobs/Tickets description: ken, 2026-09-19: "now the description
   doesn't auto size (which used to be great)". Before Edit/Save/Cancel
   gating, this was always an on-screen textarea that auto-sized to its
   content. Gating swapped it for a plain <span> when not editing, which
   lost that auto-fit box. Description keeps its own always-visible
   textarea (never hidden, class "always-visible" -- app.js excludes it
   from the generic view/edit hidden-toggle) and just gets readonly
   toggled instead, so the auto-sized box is there in both states. */
textarea.ticket-desc[readonly] { border-color: transparent; background: transparent; cursor: default; }
textarea.ticket-desc[readonly]:hover { border-color: transparent; }

.cust-detail { padding: 0.6rem 0.8rem 0.8rem; }
.cust-field-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.7rem; margin-bottom: 0.8rem; }
.cust-field-grid label { display: flex; flex-direction: column; gap: 0.25rem; font-size: 12px; color: var(--muted); }
.cust-field-grid input, .cust-field-grid textarea { font-size: 13.5px; color: var(--text); }

/* Edit -> Save/Cancel gating, shared markup convention (app.js) across
   Customers/Jobs/Tickets. */
.field-view { font-size: 13.5px; color: var(--text); white-space: pre-line; word-break: break-word; }
.edit-controls { display: flex; align-items: flex-end; gap: 0.5rem; grid-column: 1 / -1; }

.cust-group-row { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 0.6rem; }

.peer-search {
  display: flex; flex-direction: column; gap: 0.3rem; flex: 1; min-width: 240px;
  background: var(--hover); border: 1px solid var(--border); border-radius: 6px; padding: 0.6rem;
}
.peer-search input[type=text] { border: 1px solid var(--border); }
.peer-search-results { display: flex; flex-direction: column; gap: 0.15rem; max-height: 140px; overflow-y: auto; }
.peer-result { font-size: 12.5px; padding: 0.25rem 0.5rem; border-radius: 4px; cursor: pointer; }
.peer-result:hover { background: var(--accent-soft); color: var(--accent); }

.cust { font-weight: 600; white-space: nowrap; font-family: "IBM Plex Mono", monospace; }
.cust .lot-name { display: block; font-weight: 400; font-family: -apple-system, sans-serif; color: var(--muted); font-size: 11.5px; white-space: normal; }

.toggle { position: relative; display: inline-block; width: 38px; height: 21px; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle .slider {
  position: absolute; cursor: pointer; inset: 0; background: var(--off);
  border-radius: 999px; transition: background 0.15s;
}
.toggle .slider::before {
  content: ""; position: absolute; height: 16px; width: 16px; left: 2.5px; top: 2.5px;
  background: white; border-radius: 50%; transition: transform 0.15s;
}
.toggle input:checked + .slider { background: var(--ok); }
.toggle input:checked + .slider::before { transform: translateX(17px); }

/* A toggle with a visible text label next to it, not just a title tooltip
   -- ken, 2026-09-19: "not sure what the toggle is for" / "toggles need
   labels". */
.toggle-labeled { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.toggle-label { font-size: 11.5px; color: var(--muted); white-space: nowrap; }

.btn {
  border: 1px solid var(--border);
  background: var(--panel);
  padding: 0.35rem 0.75rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.danger { background: var(--err); color: white; border-color: var(--err); }
.btn.danger:hover { opacity: 0.9; color: white; }

/* ken, 2026-09-19: custom delete confirmation (app.js confirmDialog) --
   replaces the plain browser confirm() so it's visually distinct from
   every other popup and forces a deliberate click on a clearly-labeled,
   solid-red button instead of a habitual Enter/click on native "OK". */
.confirm-overlay {
  position: fixed; inset: 0; background: rgba(10, 12, 16, 0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 1rem;
}
.confirm-box {
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  padding: 1.25rem; width: 100%; max-width: 380px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}
.confirm-title { font-weight: 700; font-size: 15px; margin-bottom: 0.5rem; }
.confirm-message { font-size: 13.5px; color: var(--text); line-height: 1.45; margin-bottom: 1rem; white-space: pre-line; max-height: 60vh; overflow-y: auto; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 0.5rem; }
.btn.primary { background: var(--accent); color: white; border-color: var(--accent); }
.btn.primary:hover { opacity: 0.9; color: white; }
a.btn { display: inline-block; text-decoration: none; }
a.btn.btn-disabled { pointer-events: none; opacity: 0.4; }

.pager { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1rem; }

.add-row-form {
  display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 0.75rem; margin-bottom: 1rem;
}
.add-row-form select, .add-row-form input { border: 1px solid var(--border); width: auto; min-width: 120px; }

.invite-link-box {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  background: var(--accent-soft); border: 1px solid var(--accent); border-radius: 8px;
  padding: 0.6rem 0.75rem; margin: -0.4rem 0 1rem;
}
.invite-link-box .invite-link-input {
  flex: 1; min-width: 200px; border: 1px solid var(--border); background: var(--panel);
  border-radius: 5px; padding: 0.3rem 0.5rem; font-family: "IBM Plex Mono", monospace; font-size: 12px;
}

.muted { color: var(--muted); }
.del-btn { color: var(--err); background: none; border: none; cursor: pointer; font-size: 15px; }
.del-btn:hover { text-decoration: underline; }

/* ken, 2026-09-19: "the edit button section line on the right isn't even
   with the line on the left" -- the buttons here were a smaller font-size
   (12px) than the 13.5px text/inputs in every other cell of the same row,
   which throws off the row's shared text baseline even with
   vertical-align:middle on the <td>. Match the row's own font size instead
   of shrinking it, just trim padding a bit for compactness. */
.row-edit-controls { display: flex; align-items: center; gap: 0.4rem; white-space: nowrap; font-size: 13.5px; }
.row-edit-controls .btn { padding: 0.25rem 0.6rem; font-size: 12.5px; line-height: 1.4; }
.row-edit-controls .del-btn { font-size: 14px; line-height: 1.4; }

.home-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 0.9rem; align-items: start; }
.home-card { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 0.8rem 0.9rem 0.6rem; }
.home-card h2 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 0 0 0.4rem; }
.home-card h2 a { color: inherit; }
.home-row { display: flex; gap: 0.7rem; align-items: baseline; padding: 0.4rem 0.3rem; border-radius: 6px; text-decoration: none; color: var(--text); }
.home-row:hover { background: var(--hover); }
.home-n { min-width: 3.4rem; text-align: right; font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.home-dot { color: var(--muted); font-weight: 400; }
.home-warn .home-n { color: var(--err); }
.home-text { font-size: 14px; }
.home-detail { display: block; font-size: 12.5px; color: var(--muted); }
.home-none { margin: 0.3rem 0.3rem 0.4rem; font-size: 13px; }
.home-day { font-size: 13px; margin: 0.5rem 0.3rem 0.2rem; }
.home-day span { color: var(--muted); font-weight: 400; margin-left: 0.4rem; }
.home-shift { padding: 0.45rem 0.3rem; border-top: 1px solid var(--border); }
.home-shift-head { font-size: 15px; display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
.home-shift-n { margin-left: auto; font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.home-codes { font-size: 13px; line-height: 1.5; color: var(--text); margin-top: 0.15rem; overflow-wrap: anywhere; }
@media (max-width: 700px) {
  .home-grid { gap: 0.7rem; }
  .home-card { padding: 0.7rem 0.7rem 0.5rem; }
  .home-row { padding: 0.6rem 0.2rem; }
  .home-n { min-width: 2.6rem; }
  .home-text { font-size: 15px; }
  .home-detail { font-size: 13px; }
}
.home-housekeeping { margin-top: 1rem; font-size: 13px; }
.todo-add { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; }
.todo-item { display: flex; gap: 0.7rem; align-items: flex-start; padding: 0.55rem 0.3rem; border-bottom: 1px solid var(--border); scroll-margin-top: 5rem; }
.todo-item:target { background: var(--hover); }
.todo-item input[type="checkbox"] { width: auto; margin-top: 0.2rem; }
.todo-body { flex: 1; font-size: 14px; }
.todo-who { font-size: 12px; color: var(--muted); border: 1px solid var(--border); border-radius: 10px; padding: 0 0.45rem; margin-left: 0.3rem; white-space: nowrap; }
.todo-done { margin-top: 1.2rem; }

.day-tabs { display: flex; gap: 0.35rem; flex-wrap: wrap; margin-bottom: 1rem; }
.day-tab {
  border: 1px solid var(--border); background: var(--panel); color: var(--muted);
  padding: 0.4rem 0.8rem; border-radius: 999px; cursor: pointer; font-size: 13px;
}
.day-tab .tab-count { font-variant-numeric: tabular-nums; color: var(--muted); margin-left: 0.3rem; }
.day-tab.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.day-tab.active .tab-count { color: var(--accent); }

.shift-block { margin-bottom: 1.5rem; }
.shift-heading {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted);
  margin: 0 0 0.6rem; padding-bottom: 0.3rem; border-bottom: 1px solid var(--border);
}
.shift-heading.shift-night::before { content: "● "; color: #4a5a8a; }
.shift-heading.shift-day::before { content: "● "; color: var(--accent); }

/* ken, 2026-09-22: "this doesn't need to be all squeezed on one page; we
   can widen each truck/table" -- was 300px, cramping Note especially;
   fewer cards per row now, each with real room. */
.truck-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); gap: 0.85rem; }
.truck-card { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.truck-card.backup { border-left: 3px solid #b45a56; }
.truck-card.special { border-left: 3px solid #6f7fa8; }
.truck-card-head {
  font-weight: 600; font-size: 13px; padding: 0.5rem 0.7rem;
  background: var(--hover); border-bottom: 1px solid var(--border);
}
.truck-card table { border: none; border-radius: 0; font-size: 12.5px; }
.truck-card thead th { padding: 0.35rem 0.4rem; font-size: 10px; }
.truck-card tbody td { padding: 0.3rem 0.4rem; }
.truck-card input[type=number] { min-width: 2.6em; }
.svc-cell { white-space: nowrap; }
.svc-cell label { display: inline-flex; align-items: center; gap: 2px; margin-right: 0.4rem; font-size: 11.5px; color: var(--muted); cursor: pointer; }
.svc-cell input[type=checkbox] { width: auto; margin: 0; }
.no-stops { color: var(--muted); font-style: italic; padding: 0.6rem 0.7rem; font-size: 12.5px; }

/* Note, ken 2026-09-22: "note is barely readible. i need that to not
   scroll" -- was a plain single-line input squeezed by whatever room SW/P/
   DOCK and T-Cans left over. A small auto-growing box (autoResize, same
   trick the Jobs page description uses) wraps a longer note onto a second
   line instead of needing a horizontal scroll to read it. */
textarea.note-field {
  width: 100%; min-width: 8em; resize: none; overflow: hidden; font-family: inherit;
  font-size: 12.5px; padding: 0.25rem 0.4rem; border: 1px solid var(--border); border-radius: 5px;
  background: var(--panel); color: var(--text); line-height: 1.3;
}

/* Master Edit routes button, ken 2026-09-22: "a master edit button. Not
   per line... Cancel returns to what it was before." Nothing on the page
   can change until body carries .routes-editing (enterRoutesEdit) --
   drag included. Replaces the earlier per-row lock, which ken pointed out
   didn't even line up row to row. */
tr[data-id] input:disabled, tr[data-id] textarea:disabled { opacity: 0.55; cursor: default; }
body:not(.routes-editing) .drag-handle { opacity: 0.3; cursor: default; pointer-events: none; }
.routes-edit-controls { display: flex; gap: 0.5rem; margin-left: auto; }
tr.pending-delete { opacity: 0.45; text-decoration: line-through; }
tr.pending-delete .del-btn { text-decoration: none; }

/* touch-action:none is what actually makes touch dragging work -- without
   it the browser claims the gesture for page-scrolling before our own
   pointermove handler ever sees it (ken, 2026-09-22: mobile reordering). */
.drag-handle { cursor: grab; color: var(--muted); text-align: center; width: 1.4em; touch-action: none; }
.drag-handle:active { cursor: grabbing; }
/* ken, 2026-09-22: "we shouldn't be able to rearrange unless editing" --
   only applies where the drag handle's row IS the edit-scope (the Jobs
   page); Manage Routes' rows have no data-edit-scope at all, so this rule
   never matches there and its handles stay always-draggable as before. */
tr[data-edit-scope]:not(.editing) .drag-handle { opacity: 0.3; cursor: default; pointer-events: none; }
tr.dragging { opacity: 0.35; }
tbody[data-truck].drag-over, tbody.jobs-dragzone.drag-over { outline: 2px dashed var(--accent); outline-offset: -2px; }
.day-section.empty-day { color: var(--muted); font-style: italic; padding: 1rem 0; }

.lot-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 0.6rem; overflow: hidden; transition: background 1.2s ease;
}
.lot-card.saved-flash { background: #eafaf0; }
.lot-card[open] { padding-bottom: 0.5rem; }
.lot-card summary {
  cursor: pointer; padding: 0.6rem 0.8rem; display: flex; align-items: center;
  gap: 0.9rem; flex-wrap: wrap; list-style: none;
}
.lot-card summary::-webkit-details-marker { display: none; }
.lot-card summary::before { content: "▸"; color: var(--muted); margin-right: 0.2rem; }
.lot-card[open] summary::before { content: "▾"; }
.lot-summary-bit { font-size: 12px; }
.qty-review-badge {
  font-size: 11.5px; color: var(--err); background: color-mix(in srgb, var(--err) 12%, transparent);
  padding: 2px 7px; border-radius: 999px; font-weight: 600;
}
.lot-summary-toggle { margin-left: auto; }
.lot-card table { border: none; border-radius: 0; margin-top: 0.4rem; font-size: 12.5px; }
.lot-card thead th { padding: 0.35rem 0.5rem; font-size: 10px; }
.lot-card tbody td { padding: 0.3rem 0.5rem; }

.login-wrap { display: flex; align-items: center; justify-content: center; height: 100vh; }
.login-box { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 2rem; width: 300px; }
.login-box h1 { text-align: center; }
.login-box input { width: 100%; padding: 0.5rem; margin: 0.6rem 0; border: 1px solid var(--border); border-radius: 6px; }
.login-box .btn { width: 100%; text-align: center; }
.login-error { color: var(--err); font-size: 13px; margin-top: 0.4rem; }
.note { color: var(--ok); font-size: 13px; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #14161c; --panel: #1b1e26; --border: #2c303b; --text: #e7e9ee;
    --muted: #8b909c; --accent: #5b9dff; --accent-soft: #1c2b47; --off: #444a58;
    --hover: #262b35;
    --night: #7fa3d9; --night-tint: #1c2532; --day: #e0b84f; --day-tint: #2b2418;
  }
}
:root[data-theme="dark"] {
  --bg: #14161c; --panel: #1b1e26; --border: #2c303b; --text: #e7e9ee;
  --muted: #8b909c; --accent: #5b9dff; --accent-soft: #1c2b47; --off: #444a58;
  --hover: #262b35;
  --night: #7fa3d9; --night-tint: #1c2532; --day: #e0b84f; --day-tint: #2b2418;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) thead th { background: #20232c; }
  :root:not([data-theme="light"]) tbody tr.saved-flash td { background: #123521; }
  :root:not([data-theme="light"]) tbody tr.error-flash td { background: #3a1c1c; }
  :root:not([data-theme="light"]) .lot-card.saved-flash { background: #123521; }
}
:root[data-theme="dark"] thead th { background: #20232c; }
:root[data-theme="dark"] tbody tr.saved-flash td { background: #123521; }
:root[data-theme="dark"] tbody tr.error-flash td { background: #3a1c1c; }
:root[data-theme="dark"] .lot-card.saved-flash { background: #123521; }

/* Tickets without the Cost column (managers never see prices) -- the
   nth-child widths above assume 9 columns, so this is its own 8-column set. */
table.tickets-table.tickets-nocost { min-width: 900px; }
table.tickets-nocost th:nth-child(1), table.tickets-nocost td:nth-child(1) { width: 8%; }
table.tickets-nocost th:nth-child(2), table.tickets-nocost td:nth-child(2) { width: 12%; }
table.tickets-nocost th:nth-child(3), table.tickets-nocost td:nth-child(3) { width: 13%; }
table.tickets-nocost th:nth-child(4), table.tickets-nocost td:nth-child(4) { width: 22%; }
table.tickets-nocost th:nth-child(5), table.tickets-nocost td:nth-child(5) { width: 6%; }
table.tickets-nocost th:nth-child(6), table.tickets-nocost td:nth-child(6) { width: 11%; }
table.tickets-nocost th:nth-child(7), table.tickets-nocost td:nth-child(7) { width: 10%; }
table.tickets-nocost th:nth-child(8), table.tickets-nocost td:nth-child(8) { width: 9%; }
table.tickets-nocost th:nth-child(9), table.tickets-nocost td:nth-child(9) { width: 9%; }

/* Internal note under a job's description (Jobs page) -- staff-only, never on the invoice. */
textarea.internal-note { font-size: 12px; font-style: italic; color: var(--muted); padding: 0.2rem 0.35rem; margin-top: 2px; border-radius: 5px; }
textarea.internal-note[readonly] { border-left: 2px solid var(--accent); border-radius: 0 5px 5px 0; }

/* Invoicing page (create / review / send / print) */
h2.inv-step { font-size: 1.05rem; margin: 1.6rem 0 0.3rem; }
h3.inv-sub { font-size: 0.95rem; margin: 1.3rem 0 0.5rem; }
.inv-log { margin-bottom: 0.5rem; }
.inv-log pre { white-space: pre-wrap; margin: 0.4rem 0 0; font-family: "IBM Plex Mono", monospace; font-size: 12.5px; background: var(--hover); padding: 10px 12px; border-radius: 6px; max-height: 60vh; overflow: auto; }
.inv-chips { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.6rem 0; }
.chip-inv { background: var(--hover); border: 1px solid var(--border); border-radius: 999px; padding: 0.15rem 0.7rem; font-size: 12.5px; }
.chip-inv.chip-bad { border-color: var(--err); color: var(--err); }
.inv-note { background: var(--accent-soft); border: 1px solid var(--accent); border-radius: 6px; padding: 0.5rem 0.75rem; font-size: 13px; margin: 0.5rem 0; }
.inv-results { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 0.7rem 0.9rem; margin: 0.6rem 0; font-size: 13.5px; }
.inv-results ul { margin: 0.4rem 0 0.4rem 1.1rem; padding: 0; }
table.inv-table td, table.inv-table th { padding: 0.35rem 0.6rem; }
table.inv-table td { font-size: 13px; }
tr.grp-row td { background: var(--hover); font-weight: 600; font-size: 12.5px; padding-top: 0.45rem; }
td.grp-child { padding-left: 1.4rem !important; }

.inv-sticky { position: sticky; top: 0; z-index: 5; box-shadow: 0 2px 8px rgba(0,0,0,.12); }
.inv-progress-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.inv-bar { height: 8px; background: var(--hover); border-radius: 4px; overflow: hidden; margin: 0.3rem 0 0.5rem; }
.inv-bar > div { height: 100%; background: var(--accent); transition: width .3s; }
.spinner { width: 14px; height: 14px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: kspin .8s linear infinite; }
@keyframes kspin { to { transform: rotate(360deg); } }
.badge.sending { background: var(--accent-soft); color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }

/* Audit Report page (webapp/sweep_audit.py, templates/audit_report.html),
   2026-09-25: "put this on hub please" -- promoted from a standalone
   Claude artifact. Frozen-header spreadsheet-style table, Night/Day
   column groups tinted with the --night/--day tokens above. */
.audit-deploy-stamp { font-size: 11px; color: var(--muted); margin: -0.4rem 0 0.7rem; }
.audit-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin-bottom: 12px; }
.audit-tile {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
  cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.audit-tile.active { outline: 2px solid var(--accent); outline-offset: -2px; }
.audit-tile .n { font-weight: 700; font-size: 20px; line-height: 1; margin-bottom: 3px; }
.audit-tile .l { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.audit-tile.stat-mismatch .n, .audit-tile.stat-diff .n { color: var(--err); }
.audit-tile.stat-match .n { color: var(--ok); }
.audit-tile.stat-periodic .n, .audit-tile.stat-no-billing .n { color: var(--muted); }

.audit-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; }
.audit-toolbar input[type="search"] { flex: 1; min-width: 200px; }
.audit-toolbar label { font-size: 12.5px; color: var(--muted); display: flex; align-items: center; gap: 5px; cursor: pointer; white-space: nowrap; }
.audit-legend { display: flex; gap: 16px; font-size: 12px; color: var(--muted); margin: 0 0 10px; flex-wrap: wrap; }
.audit-legend i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; vertical-align: -1px; margin-right: 4px; }
.audit-legend i.lg-night { background: var(--night-tint); border: 1px solid var(--night); }
.audit-legend i.lg-day { background: var(--day-tint); border: 1px solid var(--day); }

.audit-scroll {
  overflow: auto; border: 1px solid var(--border); border-radius: 8px; background: var(--panel);
  max-height: calc(100vh - 280px); min-height: 320px;
}
table.audit-table { width: 100%; border-collapse: collapse; font-size: 12.5px; min-width: 1180px; }
table.audit-table thead th {
  position: sticky; background: var(--hover); text-align: left; padding: 6px 9px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); font-weight: 600;
  border-bottom: 1px solid var(--border); white-space: nowrap; z-index: 2;
}
table.audit-table thead tr:first-child th { top: 0; }
table.audit-table thead tr:last-child th { top: 27px; }
table.audit-table thead th.num, table.audit-table td.num-cell { text-align: right; }
table.audit-table thead th.grp-head { text-align: center; font-size: 11px; letter-spacing: 0.05em; }
table.audit-table thead th.grp-head.night { background: var(--night-tint); color: var(--night); }
table.audit-table thead th.grp-head.day { background: var(--day-tint); color: var(--day); }
table.audit-table thead th.night { background: var(--night-tint); }
table.audit-table thead th.day { background: var(--day-tint); }
table.audit-table thead th.total-col { font-weight: 700; text-align: right; }
table.audit-table thead th.sep-left, table.audit-table td.sep-left { border-left: 2px solid var(--border); }
table.audit-table tbody td { padding: 5px 9px; border-bottom: 1px solid var(--border); vertical-align: top; font-variant-numeric: tabular-nums; }
/* A lot's data row and its note/analysis row underneath are two separate
   <tr>s (so the detail row can span/collapse independently), but they
   read as one unit -- ken, 2026-09-29: "can we combine those when
   highlighting as we hover over instead of making them different rows?"
   :has() reaches "backwards" to the data row from a hover on the detail
   row below it; the adjacent-sibling rule handles the other direction. */
/* ken, 2026-09-29: "it blends all together and is hard to see... maybe
   alternate rows between lots in color? or bigger divider?" -- both:
   each lot is 2 <tr>s (data + detail), so the stripe alternates in pairs
   (every 4 table rows = 2 lots), and the border between a lot's own pair
   stays a hairline while the border after its detail row (or after its
   data row, if details are toggled off) is doubled to read as the real
   lot-to-lot boundary. */
table.audit-table tbody tr:nth-child(4n+3) td,
table.audit-table tbody tr:nth-child(4n) td { background: var(--bg); }
table.audit-table tbody tr.audit-row td { border-bottom: 1px solid transparent; }
table.audit-table tbody tr.audit-detail-row td { border-bottom: 2px solid var(--border); }
body.hide-audit-detail table.audit-table tbody tr.audit-row td { border-bottom: 2px solid var(--border); }

table.audit-table tbody tr.audit-row:hover td,
table.audit-table tbody tr.audit-row:has(+ tr.audit-detail-row:hover) td,
table.audit-table tbody tr.audit-row:hover + tr.audit-detail-row td,
table.audit-table tbody tr.audit-detail-row:hover td { background: var(--hover); }
table.audit-table tbody tr td.night { background: var(--night-tint); }
table.audit-table tbody tr td.day { background: var(--day-tint); }
table.audit-table tbody td.total-col { font-weight: 700; text-align: right; }
.audit-code { font-weight: 600; }
.audit-name { color: var(--muted); font-size: 11px; display: block; }
.audit-route-cell { white-space: nowrap; }
.audit-route-cell.empty { color: var(--muted); opacity: .4; }
.audit-route-cell .flag-day { color: var(--err); font-weight: 700; }
.audit-priority { color: #c97a12; margin-right: 3px; }
table.audit-table td.bool-cell { text-align: center; color: var(--muted); }
tr.audit-detail-row td { padding: 2px 9px 9px; border-bottom: 1px solid var(--border); }
tr.audit-detail-row .detail { font-size: 11.5px; color: var(--muted); line-height: 1.55; display: flex; flex-wrap: wrap; gap: 4px 18px; }
tr.audit-detail-row .detail b { color: var(--text); font-weight: 600; }
tr.audit-detail-row .detail .analysis-text { flex-basis: 100%; }
tr.audit-detail-row .detail .priority-note { flex-basis: 100%; color: #c97a12; }
tr.audit-detail-row .detail .priority-note b { color: #c97a12; }
body.hide-audit-detail tr.audit-detail-row { display: none; }
.audit-empty { padding: 40px 16px; text-align: center; color: var(--muted); font-size: 14px; }
.badge { display: inline-block; padding: 2px 8px; border-radius: 99px; font-size: 10.5px; font-weight: 600; white-space: nowrap; }
.badge.match, .badge.sheet-match { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.badge.mismatch, .badge.sheet-diff { background: color-mix(in srgb, var(--err) 14%, transparent); color: var(--err); }
.badge.periodic, .badge.no-billing, .badge.no-sheet { background: var(--hover); color: var(--muted); border: 1px solid var(--border); }

/* Employees page -- reuses the lot-card / cust-field-grid edit pattern */
.employee-card .emp-head { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.employee-card.inactive { opacity: 0.6; }

/* To Schedule page */
.to-sched-jump { display: flex; flex-wrap: wrap; gap: 0.5rem 1.2rem; margin: 0.4rem 0 1.2rem; font-size: 14px; }
.to-sched-section { margin-bottom: 2rem; }
.to-sched-section h3 { margin: 1rem 0 0.4rem; font-size: 15px; }
.to-sched-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.to-sched-table th, .to-sched-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border, #e3e0d8); text-align: left; vertical-align: top; }
.to-sched-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.to-sched-table td.short { color: var(--err); font-weight: 600; }
.to-sched-table tr.not-this-month td { color: var(--muted); }
.to-sched-table .lot-name { display: block; font-size: 12px; color: var(--muted); }
.to-sched-list { padding-left: 1.2rem; font-size: 14px; }

/* Checks (check intake) page */
.checks-status { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; margin: 0.3rem 0 1.2rem; font-size: 13px; color: var(--muted); }
.checks-section { margin-bottom: 2rem; }
.checks-section h2 { font-size: 16px; margin: 0 0 0.6rem; }
.check-form { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: flex-end; }
.check-form label, .check-actions label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 12px; color: var(--muted); }
.check-form label.grow { flex: 1 1 240px; }
.check-form input[type="text"], .check-form input[type="date"] { font-size: 15px; }
.check-form #c-amount { width: 8.5em; font-variant-numeric: tabular-nums; }
.check-form #c-number { width: 7em; }
.check-suggest { margin: 0.8rem 0 0; display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; font-size: 13px; }
.suggest-chip { border: 1px solid var(--border); background: var(--panel); border-radius: 999px; padding: 0.3rem 0.7rem; cursor: pointer; font: inherit; font-size: 13px; color: var(--text); }
.suggest-chip:hover { border-color: var(--accent); }
.suggest-chip em { font-style: normal; color: var(--muted); font-size: 12px; margin-left: 0.3rem; }
.check-pick { margin-top: 0.9rem; border: 1px solid var(--border); border-radius: 6px; padding: 0.7rem 0.8rem; background: var(--panel); }
.check-pick-head { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.4rem; font-size: 13px; }
.check-pick-head .ok, .check-actions .ok { color: var(--ok, #15803d); font-weight: 600; }
.check-actions .short { color: var(--err); font-weight: 600; }
.check-pick-head .short, .checks-table .short { color: var(--err); font-weight: 600; }
.check-add-invoice { position: relative; margin-top: 0.5rem; }
.check-add-invoice input { width: 100%; }
.inv-results { position: absolute; z-index: 20; left: 0; right: 0; top: 100%; background: var(--panel); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,0.12); max-height: 300px; overflow-y: auto; padding: 0.3rem; }
.inv-results button { display: block; width: 100%; text-align: left; background: none; border: none; padding: 0.4rem 0.5rem; font: inherit; font-size: 13px; color: var(--text); cursor: pointer; border-radius: 4px; }
.inv-results button:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.check-actions { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: flex-end; margin-top: 0.9rem; }
.checks-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.checks-table th, .checks-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; }
.checks-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.checks-table .apply-amt { width: 7em; text-align: right; }
.checks-table .row-btns { white-space: nowrap; text-align: right; }
.checks-table .lot-name { display: block; font-size: 12px; color: var(--muted); }
.check-form input[type="text"], .check-form input[type="date"], .check-actions input[type="date"],
.check-add-invoice input, .checks-table .apply-amt {
  border: 1px solid var(--border); border-radius: 5px; padding: 0.4rem 0.55rem; background: var(--bg, transparent); color: var(--text);
}
.check-form input:focus, .check-add-invoice input:focus, .checks-table .apply-amt:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.open-list { margin-top: 0.9rem; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); }
.open-list-head { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; padding: 0.6rem 0.8rem; font-size: 13px; }
.open-list-head input { flex: 1 1 260px; border: 1px solid var(--border); border-radius: 5px; padding: 0.4rem 0.55rem; background: var(--bg, transparent); color: var(--text); }
.open-list-scroll { max-height: 340px; overflow-y: auto; border-top: 1px solid var(--border); }
.open-table thead th { position: sticky; top: 0; background: var(--panel); z-index: 1; }
.open-table tbody tr[data-id] { cursor: pointer; }
.open-table tbody tr[data-id]:hover td { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.open-table tbody tr.picked td { background: color-mix(in srgb, var(--ok, #16a34a) 14%, transparent); font-weight: 600; }
.open-table .tick { width: 1.6em; color: var(--ok, #16a34a); font-weight: 700; }
.sort-btn { background: none; border: none; padding: 0; font: inherit; color: inherit; cursor: pointer; text-transform: inherit; letter-spacing: inherit; }
.sort-btn.sorted::after { content: " ↕"; opacity: 0.6; }
.open-hint { margin: 0; padding: 0.5rem 0.8rem; font-size: 12px; border-top: 1px solid var(--border); }
.check-pick .check-form { margin-top: 0.8rem; padding-top: 0.8rem; border-top: 1px solid var(--border); }
.check-pick .check-form .check-actions { margin-top: 0; margin-left: auto; }
.check-pick #picked-empty { margin: 0.2rem 0 0; font-size: 13px; }
.check-pick #save-msg { display: block; margin-top: 0.4rem; font-size: 13px; }
.checks-section .open-list { margin-top: 0; }

/* Past Due page */
.pd-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.pd-actions { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; font-size: 13px; }
.pd-stats { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.6rem 0 1.2rem; }
.pd-stat { border: 1px solid var(--border); border-radius: 6px; padding: 0.55rem 0.9rem; background: var(--panel); min-width: 120px; }
.pd-stat .n { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pd-stat .l { font-size: 12px; color: var(--muted); }
.pd-stat.month .n { font-size: 16px; font-weight: 600; }
.pd-toolbar { align-items: center; }
.pd-toolbar input[type="text"] { flex: 1 1 280px; border: 1px solid var(--border); border-radius: 5px; padding: 0.4rem 0.55rem; background: var(--bg, transparent); color: var(--text); }
.pd-toolbar label { display: flex; align-items: center; gap: 0.4rem; font-size: 13px; color: var(--muted); }
.pd-table tbody.pd-cust { border-top: 2px solid var(--border); }
.pd-table .pd-cust-cell { width: 38%; }
.pd-table .pd-subtotal { display: block; margin-top: 0.3rem; font-size: 12px; font-weight: 600; }
.pd-table .pd-old { color: var(--err); font-weight: 600; }
.pd-table .pd-tag { font-size: 11px; padding: 0 0.4rem; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.pd-table tfoot td { border-top: 2px solid var(--text); border-bottom: none; font-weight: 700; font-size: 15px; }
@media print {
  header.topbar, .pd-actions, .pd-toolbar { display: none !important; }
  body { background: #fff; color: #000; }
  .pd-table tbody.pd-cust { break-inside: avoid; }
}

/* Invoicing: purchase-order panel */
.po-rows { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.6rem; }
.po-row { display: grid; grid-template-columns: minmax(11rem, 1.1fr) minmax(16rem, 2fr) 13rem auto minmax(8rem, 1.2fr); gap: 0.6rem; align-items: center; font-size: 13px; }
.po-row input { width: 100%; }
.po-row .po-msg { font-size: 12.5px; }
@media (max-width: 900px) { .po-row { grid-template-columns: 1fr; gap: 0.25rem; padding: 0.4rem 0; border-top: 1px solid var(--border); } }
.po-summary { font-size: 13.5px; }
.po-flash { font-size: 13px; padding: 0.4rem 0.6rem; border: 1px solid var(--border); border-radius: 6px; }
.po-row .po-btns { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.po-row .po-status { overflow-wrap: anywhere; }
.po-done { margin-top: 0.4rem; border-top: 1px solid var(--border); padding-top: 0.4rem; }
.po-done > summary { cursor: pointer; color: var(--muted); font-size: 13px; padding: 0.15rem 0; }
.po-done > .po-row { padding: 0.2rem 0; }
.po-row-done { grid-template-columns: minmax(11rem, 1.1fr) minmax(16rem, 2fr) auto; }
.po-row-done .po-status { white-space: nowrap; overflow-wrap: normal; }
.po-row-done input, .po-row-done .po-save { display: none; }
.po-row-done.editing { grid-template-columns: minmax(11rem, 1.1fr) minmax(16rem, 2fr) auto 13rem auto; }
.po-row-done.editing input, .po-row-done.editing .po-save { display: inline-block; }
.po-row-done.editing input { display: block; }
.po-row-done .po-msg { grid-column: 1 / -1; }
@media (max-width: 900px) { .po-row-done { grid-template-columns: 1fr; } .po-row-done .po-status { white-space: normal; } }

/* Invoicing: needs-attention panel + PO kind tag */
.inv-attention { border: 1px solid var(--err); border-left-width: 4px; border-radius: 6px; padding: 0.7rem 0.9rem; margin: 0.4rem 0 1.2rem; background: color-mix(in srgb, var(--err) 7%, transparent); font-size: 13.5px; }
.inv-attention .att-group { margin-top: 0.5rem; }
.inv-attention .att-title { font-weight: 600; display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.inv-attention .att-row { display: grid; grid-template-columns: minmax(14rem, 1.2fr) 2fr auto; gap: 0.6rem; align-items: center; padding: 0.3rem 0; border-top: 1px solid color-mix(in srgb, var(--err) 25%, transparent); }
.inv-attention .att-detail { color: var(--err); }
.inv-attention .att-line { font-family: ui-monospace, Menlo, monospace; font-size: 12px; padding: 0.15rem 0; overflow-wrap: anywhere; }
.po-kind { font-size: 11px; padding: 0 0.4rem; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
@media (max-width: 900px) { .inv-attention .att-row { grid-template-columns: 1fr; gap: 0.2rem; } }
.est-bar { margin-top: 0.6rem; padding: 0.6rem 0.7rem; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); font-size: 13px; }
.est-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-top: 0.45rem; }
.est-controls input[type="email"] { width: 17rem; }

/* Checks: scanned pages shown under their row, and the reader's note */
.read-note { display: block; font-size: 12.5px; margin-top: 0.15rem; }
.read-note.read-red { color: var(--err); font-weight: 600; }
.read-note.read-yellow { color: #a16207; }
.checks-table tr.scan-row td { padding: 0.4rem 0 0.8rem; background: transparent; }
.checks-table tr.scan-row img { max-width: 100%; max-height: 80vh; border: 1px solid var(--border); border-radius: 4px; }
.checks-table tr.scan-row iframe { width: 100%; height: 75vh; border: 1px solid var(--border); border-radius: 4px; }

/* Contacts */
.contacts-table input[type="text"], .contacts-table select { font-size: 13px; padding: 0.25rem 0.4rem; min-width: 7rem; width: 100%; }
.contacts-table td.c-custs { min-width: 16rem; }
.c-chip { display: inline-block; font-size: 12px; border: 1px solid var(--border); border-radius: 10px; padding: 0 0.45rem; margin: 0 0.25rem 0.25rem 0; white-space: nowrap; }
.c-chip a { text-decoration: none; color: var(--err); }
.contacts-table select.c-link { margin-top: 0.2rem; font-size: 12px; }

.checks-section h3.checks-sub { font-size: 14px; margin: 1rem 0 0.4rem; }
.ready-list { margin-top: 0.5rem; }
.ready-list > summary { cursor: pointer; padding: 0.3rem 0; }
.credit-opt { display: flex; align-items: center; gap: 0.35rem; font-size: 13px; }
.credit-opt input { width: auto; }

/* Lot page + finder (lot.html, lots.html) -- larger type, plain words, the two
   most-asked answers on top (ken, 2026-10-08: "clean and organized") */
.lotp { max-width: 1080px; margin: 0 auto; font-size: 17px; line-height: 1.5; }
.lotp h1 { font-size: 30px; margin: 0 0 0.2rem; text-wrap: balance; }
.lot-back { margin: 0 0 0.8rem; font-size: 15px; }
.lot-head { display: flex; justify-content: space-between; gap: 1rem; align-items: flex-start; margin-bottom: 1.2rem; }
.lot-code { font-size: 15px; font-weight: 600; color: var(--muted); border: 1px solid var(--border); border-radius: 6px; padding: 0.1rem 0.5rem; vertical-align: middle; white-space: nowrap; }
.lot-addr, .lot-pm { margin: 0.15rem 0 0; color: var(--muted); }
.lot-pm b { color: var(--text); }
.lot-tags { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.lot-tag { display: inline-block; font-size: 13px; font-weight: 600; border-radius: 999px; padding: 0.1rem 0.6rem; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.lot-tag-off { color: var(--err); border-color: var(--err); }
.lot-tag-due { color: #fff; background: var(--err); border-color: var(--err); }
.lot-tag-ok { color: var(--ok); border-color: var(--ok); }
.lot-top { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 1rem; margin-bottom: 1rem; }
.lot-top > :only-child { grid-column: 1 / -1; }
.lot-card, .lot-sec { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 1.1rem 1.3rem; }
.lot-card h2 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin: 0 0 0.3rem; }
.lot-card h3 { font-size: 15px; margin: 1rem 0 0.3rem; }
.lot-big { font-size: 28px; font-weight: 700; margin: 0; font-variant-numeric: tabular-nums; }
.lot-due { color: var(--err); }
.lot-ok { color: var(--ok); }
.lot-sub { margin: 0.2rem 0 0; color: var(--muted); font-size: 15.5px; }
.lot-asof { margin: 0.8rem 0 0; color: var(--muted); font-size: 13px; }
.lot-note { color: var(--muted); font-size: 14px; }
.lot-list { margin: 0; padding-left: 1.2rem; }
.week { display: grid; grid-template-columns: 4.2rem repeat(7, minmax(0, 1fr)); gap: 0.3rem; margin-top: 0.9rem; }
.week-name { font-weight: 700; font-size: 15px; text-align: center; padding-bottom: 0.1rem; }
.week-name.off { color: var(--muted); font-weight: 400; }
.week-label { display: flex; flex-direction: column; justify-content: center; font-weight: 700; font-size: 15px; border-radius: 8px 0 0 8px; padding: 0.4rem 0.5rem; }
.week-label span { font-weight: 400; font-size: 12px; opacity: 0.85; }
.week-cell { border-radius: 8px; padding: 0.45rem 0.3rem; text-align: center; min-height: 3.6rem; border: 1px solid transparent; }
.week-cell.off { border: 1px dashed var(--border); }
/* night on top, day below: the working day starts the night before (ken, 2026-10-08) */
.week-label.week-night { background: var(--night); color: var(--bg); }
.week-cell.week-night.on { background: var(--night-tint); border-color: var(--night); }
.week-label.week-day { background: var(--day); color: var(--bg); }
.week-label.week-backup { background: var(--muted); color: var(--bg); }
.week-cell.week-backup.on { border: 1px dashed var(--muted); }
.week-cell.week-day.on { background: var(--day-tint); border-color: var(--day); }
.week-visit { font-size: 14px; line-height: 1.3; }
.week-visit + .week-visit { margin-top: 0.35rem; padding-top: 0.35rem; border-top: 1px solid var(--border); }
.week-visit span { display: block; }
.week-who { font-weight: 700; }
.week-what { color: var(--muted); font-size: 12.5px; }
.week-who span { display: inline; }
.week-cell.on { cursor: pointer; }
.week-cell.picked { outline: 2px solid var(--text); outline-offset: 1px; }
.week-cell:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; }
.week-hint { display: none; margin: 0.5rem 0 0; color: var(--muted); font-size: 13px; }
.week-detail { margin-top: 0.7rem; padding: 0.7rem 0.9rem; border: 1px solid var(--border); border-radius: 8px; }
.week-detail h3 { margin: 0 0 0.3rem; }
.week-detail p { margin: 0.15rem 0; font-size: 15px; }
.week-detail-note { color: var(--muted); font-size: 14px; }
.lot-table { width: 100%; border-collapse: collapse; margin-top: 0.8rem; font-size: 16px; }
.lot-table th { text-align: left; font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--border); }
.lot-table td { padding: 0.5rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.lot-table tr:last-child td { border-bottom: none; }
.lot-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lot-sec { margin-bottom: 0.7rem; padding: 0; }
.lot-sec > summary { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; cursor: pointer; padding: 0.95rem 1.3rem; font-weight: 700; font-size: 18px; list-style: none; }
.lot-sec > summary::-webkit-details-marker { display: none; }
.lot-sec > summary::before { content: "▸"; color: var(--muted); margin-right: 0.6rem; }
.lot-sec[open] > summary::before { content: "▾"; }
.lot-sec > summary > span:first-child { flex: 1; }
.lot-sum { font-weight: 400; font-size: 15px; color: var(--muted); text-align: right; }
.lot-sec > :not(summary) { margin: 0 1.3rem 1rem; }
.lot-sec > .lot-table { width: calc(100% - 2.6rem); }
.lot-person { padding: 0.5rem 0; border-top: 1px solid var(--border); }
.lot-person-top { display: flex; justify-content: space-between; gap: 1rem; align-items: flex-start; }
.lot-edit { white-space: nowrap; }
.lot-h3-edit { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.lot-form { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 0.7rem; padding: 0.9rem 1rem; border: 1px solid var(--border); border-radius: 8px; background: var(--bg); max-width: 34rem; }
.lot-form[hidden] { display: none; }
.lot-form-row > td { padding: 0 !important; border: none !important; }
.lot-form-row .lot-form { margin: 0.2rem 0 0.9rem; }
.lot-form-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.lot-form-pair > div { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.lot-form-more { margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 0.4rem; }
.lot-form-skip { display: grid; grid-template-columns: 1fr auto; gap: 0.3rem 0.6rem; align-items: end; }
.lot-form-skip label { grid-column: 1 / -1; }
.lot-actions { text-align: right; white-space: nowrap; }
.lot-form-top { margin: -0.4rem 0 1.2rem; }
.lot-form label { font-size: 13px; color: var(--muted); margin-top: 0.4rem; }
.lot-form input[type=text], .lot-form input[type=number], .lot-form input[type=time], .lot-form select, .lot-form textarea {
  font-size: 16px; padding: 0.5rem 0.6rem; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text); width: 100%; box-sizing: border-box; font-family: inherit; }
.lot-form label.lot-check { display: flex; align-items: center; gap: 0.5rem; font-size: 16px; color: var(--text); }
.lot-form label.lot-check input { width: 1.2rem; height: 1.2rem; }
.lot-form-hint { margin: 0.2rem 0 0; font-size: 13px; color: var(--muted); }
.lot-form-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-top: 0.7rem; }
.lot-form-actions .btn { font-size: 15px; padding: 0.5rem 1rem; }
.lot-form-msg { font-size: 14px; color: var(--err); }
.lot-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1.2rem; }
.lot-facts dt { color: var(--muted); }
.lot-facts dd { margin: 0; overflow-wrap: anywhere; }
.lot-search { width: 100%; font-size: 20px; padding: 0.8rem 1rem; border: 2px solid var(--border); border-radius: 10px; background: var(--panel); color: var(--text); }
.lot-search:focus { outline: none; border-color: var(--accent); }
.lot-hint { color: var(--muted); margin: 0.5rem 0 1rem; }
.pm-group { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; margin-bottom: 0.5rem; }
.pm-group > summary { display: flex; justify-content: space-between; cursor: pointer; padding: 0.8rem 1.2rem; font-weight: 700; }
.pm-count { font-weight: 400; color: var(--muted); font-size: 15px; }
.lot-row { display: grid; grid-template-columns: 7.5rem minmax(12rem, 2fr) 3fr auto; gap: 0.8rem; align-items: baseline; padding: 0.6rem 1.2rem; border-top: 1px solid var(--border); text-decoration: none; color: var(--text); }
.lot-row:hover { background: var(--hover); }
.lot-row[hidden], .pm-group[hidden] { display: none; }   /* display:grid would otherwise override the hidden attribute */
.lot-row-name { font-weight: 600; }
.lot-row-code { font-weight: 700; }
.lot-row-addr { color: var(--muted); font-size: 15px; }
@media (max-width: 820px) {
  .lot-top { grid-template-columns: 1fr; }
  /* phone: the whole week still on one screen (ken, 2026-10-08) -- route number over the driver, tap for the rest */
  .week { grid-template-columns: 2.9rem repeat(7, minmax(0, 1fr)); gap: 3px; }
  .week-name { font-size: 12px; }
  .week-label { font-size: 11.5px; padding: 0.3rem 0.25rem; border-radius: 6px 0 0 6px; }
  .week-label span { display: none; }
  .week-cell { padding: 0.3rem 0.05rem; min-height: 2.9rem; border-radius: 6px; overflow: hidden; }
  .week-what, .week-dash { display: none; }
  .week-who .week-route { display: block; font-size: 16px; line-height: 1.15; }
  .week-who .week-driver { display: block; font-size: 10.5px; font-weight: 600; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .week-visit + .week-visit { margin-top: 0.2rem; padding-top: 0.2rem; }
  .week-hint { display: block; }
  .lot-row { grid-template-columns: 7.5rem 1fr; }
  .lot-row-addr { grid-column: 1 / -1; }
  .lot-head { flex-direction: column; }
}
.lot-part { font-size: 16px; margin: 1.1rem 1.3rem 0.2rem; }
.lot-part .lot-code { font-size: 13px; }

/* Payments: an ACH payment read from a remittance email */
.ach-tag { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 0.04em; padding: 0 0.4rem; border-radius: 4px; border: 1px solid var(--accent); color: var(--accent); }
.ach-email { margin-top: 0.25rem; font-size: 12.5px; }
.ach-email summary { cursor: pointer; color: var(--muted); }
.ach-email pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 16rem; overflow: auto; margin: 0.3rem 0 0; padding: 0.5rem; border: 1px solid var(--border); border-radius: 6px; font: inherit; }

/* Lot page: one-off invoice form */
.oneoff-line { border: 1px solid var(--border); border-radius: 8px; padding: 0.5rem 0.8rem 0.8rem; margin: 0.5rem 0 0; display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.oneoff-line legend { font-size: 13px; color: var(--muted); padding: 0 0.3rem; }
.lot-form input[type=date] { font-size: 16px; padding: 0.5rem 0.6rem; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text); width: 100%; box-sizing: border-box; font-family: inherit; }
.oneoff-total { margin: 0.7rem 0 0; font-size: 18px; }

/* Find a lot: the row that opens a whole customer (property manager or shared invoice) */
.lot-row-all { background: var(--hover); }

/* Past Due Report: laid out like QuickBooks' report (plain rows, centred heading, click a heading to sort) */
.pdr { max-width: 1100px; margin: 0 auto; }
.pdr-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; justify-content: flex-end; margin-bottom: 0.6rem; }
.pdr-actions input { flex: 1 1 16rem; max-width: 24rem; margin-right: auto; border: 1px solid var(--border); padding: 0.45rem 0.6rem; font-size: 15px; }
.pdr-head { text-align: center; margin: 0.4rem 0 1rem; }
.pdr-head h1 { font-size: 26px; margin: 0; }
.pdr-title { font-size: 17px; margin: 0.25rem 0 0; color: var(--muted); }
.pdr-period { font-size: 18px; margin: 0.25rem 0 0; }
.pdr-note { font-size: 13px; margin: 0.3rem 0 0; color: var(--muted); }
.pdr-table { width: 100%; border-collapse: collapse; border: 1px solid var(--border); background: var(--panel); font-size: 16px; font-variant-numeric: tabular-nums; }
.pdr-table th, .pdr-table td { padding: 0.55rem 0.9rem; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; }
.pdr-table th { border-right: 1px solid var(--border); border-bottom-width: 2px; padding: 0; }
.pdr-table th:last-child { border-right: none; }
.pdr-table th button { all: unset; display: block; width: 100%; box-sizing: border-box; padding: 0.6rem 0.9rem; font-weight: 700; cursor: pointer; }
.pdr-table th button::after { content: " \2195"; color: var(--muted); font-weight: 400; }
.pdr-table th.sorted.asc button::after { content: " \2191"; color: var(--text); }
.pdr-table th.sorted.desc button::after { content: " \2193"; color: var(--text); }
.pdr-table th button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pdr-table .num { text-align: right; }
.pdr-table th.num button { text-align: right; }
.pdr-table tbody tr[hidden] { display: none; }
.pdr-table tfoot td { font-weight: 700; border-top: 2px solid var(--border); border-bottom: none; }
.pdr-email { overflow-wrap: anywhere; }
.pdr-email a { color: inherit; text-decoration: none; }
.pdr-flag { font-size: 12.5px; color: var(--muted); }
.pdr-none { text-align: center; }
@media print {
  .pdr-actions, .hubnav { display: none !important; }
  .pdr { max-width: none; }
  .pdr-table { font-size: 11pt; border-color: #999; }
  .pdr-table th button::after { content: ""; }
}

/* Printing, anywhere in the Hub: always black on white, whatever theme the screen is in. Terry prints
   pages (ken, 2026-10-12: "if he prints this will it be black?"); a dark-mode screen must not come out
   as pale grey text on paper. Same weight as the dark-theme rules above, and later, so it wins. */
@media print {
  :root:not([data-theme="zz"]), :root[data-theme="dark"] {
    --bg: #fff; --panel: #fff; --border: #888; --text: #000; --muted: #333; --accent: #000; --accent-soft: #fff;
    --hover: #fff; --off: #666; --err: #000; --ok: #000; color-scheme: light;
  }
  html, body { background: #fff !important; color: #000 !important; }
  :root:not([data-theme="zz"]) thead th, :root[data-theme="dark"] thead th { background: #fff !important; color: #000 !important; }
  .hubnav, header.topbar { display: none !important; }
  a { color: #000 !important; text-decoration: none !important; }
}

/* Past Due on paper: the column headings repeat at the top of every page. The on-screen headings are sort
   buttons, which the browser left blank when it repeated them (ken, 2026-10-12: "they are there but no
   text"), so paper gets plain text headings instead. */
.pdr-th-print { display: none; }
@media print {
  .pdr-table thead { display: table-header-group; }
  .pdr-table tfoot { display: table-row-group; }          /* the total prints once, at the end, not on every page */
  .pdr-table th button { display: none !important; }
  .pdr-table th .pdr-th-print { display: block; padding: 0.45rem 0.9rem; font-weight: 700; color: #000; }
  .pdr-table th.num .pdr-th-print { text-align: right; }
  .pdr-table tr { break-inside: avoid; }
}

.lot-send { margin-left: 0.4rem; padding: 0.15rem 0.55rem; font-size: 12.5px; }

/* An invoice number that opens the invoice's PDF: reads as the number it always was, underlined so it looks clickable */
a.inv-link { color: inherit; text-decoration: underline; text-decoration-color: var(--muted); text-underline-offset: 2px; white-space: nowrap; }
a.inv-link:hover, a.inv-link:focus-visible { color: var(--accent); text-decoration-color: currentColor; }
@media print { a.inv-link { text-decoration: none; } }

/* Tickets from the book: each line of the brown book as a card to check, edit and approve */
.bk { max-width: 1100px; }
.bk-box { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.1rem; margin: 1rem 0; }
.bk-box h2 { margin: 0 0 0.5rem; font-size: 18px; }
.bk-upload, .bk-bar, .bk-head, .bk-foot { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.bk-bar { position: sticky; top: 0; z-index: 2; background: var(--panel); padding: 0.5rem 0; border-bottom: 1px solid var(--border); }
.bk-grow { flex: 1 1 auto; }
.bk-pages, .bk-notes { list-style: none; padding: 0; margin: 0.4rem 0 0; display: flex; flex-direction: column; gap: 0.4rem; }
.bk-pages li, .bk-notes li { display: flex; gap: 0.8rem; align-items: center; justify-content: space-between; border-top: 1px solid var(--border); padding-top: 0.4rem; }
.bk-card { border: 1px solid var(--border); border-left: 5px solid var(--border); border-radius: 6px; padding: 0.7rem 0.8rem; margin: 0.7rem 0; display: flex; flex-direction: column; gap: 0.5rem; }
.bk-card.bk-yellow { border-left-color: #d9a400; }
.bk-card.bk-red { border-left-color: var(--err); }
.bk-card.bk-dirty { outline: 2px dashed var(--accent); outline-offset: 2px; }
.bk-card p { margin: 0; }
.bk-card .read-note { display: block; }
.bk-head label { display: flex; gap: 0.35rem; align-items: center; font-size: 13px; color: var(--muted); }
.bk-head select, .bk-head input[type=date], .bk-line select, .bk-line textarea, .bk-line input, #bk-month {
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text); padding: 0.35rem 0.5rem; font: inherit; }
.bk-head .bk-lot { max-width: 19rem; }
.bk-book { font-size: 14px; color: var(--muted); }
.bk-book b { color: var(--text); }
.bk-lines { display: flex; flex-direction: column; gap: 0.4rem; }
/* same fields as an invoice line: item, wording, qty, rate, amount (ken, 2026-10-21) */
.bk-line, .bk-colhead { display: grid; grid-template-columns: 4.6rem 9.5rem minmax(0, 1fr) 4.6rem 7rem 6.2rem 2.2rem; gap: 0.5rem; align-items: start; }
.bk-colhead { font-size: 12px; color: var(--muted); }
.bk-colhead span:nth-child(n+4) { text-align: right; }
.bk-qty { width: 100%; text-align: right; }
.bk-amt { padding-top: 0.45rem; text-align: right; font-variant-numeric: tabular-nums; }
.bk-tag { font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); padding-top: 0.5rem; }
.bk-line textarea { resize: vertical; min-height: 2.2rem; width: 100%; }
.bk-money { display: flex; align-items: center; gap: 0.2rem; font-variant-numeric: tabular-nums; }
.bk-money input { width: 100%; text-align: right; }
.bk-x { padding: 0.25rem 0.55rem; }
.bk-total { font-variant-numeric: tabular-nums; }
.bk-total.bk-off { color: var(--err); }
.bk-total.bk-off::after { content: " (not what the book says)"; font-size: 12px; }
.bk-err { color: var(--err); }
@media (max-width: 700px) {
  .bk-colhead { display: none; }
  .bk-line { grid-template-columns: 1fr 3.8rem 6rem 2.2rem; }
  .bk-line .bk-tag { grid-column: 1 / -1; padding-top: 0; }
  .bk-line .bk-item { grid-column: 1 / 2; }
  .bk-line textarea { grid-column: 1 / -1; grid-row: 3; }
  .bk-line .bk-amt { grid-column: 1 / -1; grid-row: 4; padding-top: 0; }
}

/* Tickets page: lots with tickets not on an invoice yet (ken, 2026-10-21) */
.tk-waiting { margin: 0.8rem 0 1.2rem; padding: 0.8rem 1rem; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); }
.tk-waiting h2 { margin: 0 0 0.3rem; font-size: 1.05rem; }
.tk-waiting .tk-date { display: inline-flex; gap: 0.4rem; align-items: center; margin: 0.4rem 0; font-size: 13px; color: var(--muted); }
.tk-waiting-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tk-waiting-table th, .tk-waiting-table td { padding: 0.35rem 0.5rem; border-top: 1px solid var(--border); text-align: left; }
.tk-waiting-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.tk-waiting-table .lot-name { display: block; font-size: 12px; color: var(--muted); }
.tk-waiting-table tr.tk-alone td { background: color-mix(in srgb, var(--err) 6%, transparent); }

/* Lot Logs page + the "Time on the lot" section of a Lot page (webapp/lot_logs.py) */
.lt-filter { margin: 0.3rem 0 0.6rem; max-width: 20rem; width: 100%; }
.lt-scroll { overflow-x: auto; }
.lt-table { min-width: 760px; }
.lt-table th.lt-gh { text-align: center; }
.lt-night-h { color: var(--night); }
.lt-day-h { color: var(--day); }
.lt-tag { display: inline-block; font-size: 11.5px; font-weight: 600; padding: 0 0.4rem; border-radius: 999px; }
.lt-over { background: color-mix(in srgb, var(--err) 14%, transparent); color: var(--err); }
.lt-under { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
.lt-chart { width: 100%; height: auto; display: block; margin: 0.6rem 0 0.2rem; }
.lt-chart .lt-grid { stroke: var(--border); stroke-width: 1; }
.lt-chart .lt-axis { fill: var(--muted); font-size: 11px; }
.lt-chart .lt-dot { fill-opacity: 0.8; }
.lt-chart .lt-dot.lt-night { fill: var(--night); }
.lt-chart .lt-dot.lt-day { fill: var(--day); }
.lt-chart .lt-dot.lt-alt { fill: none; stroke-width: 1.8; }
.lt-chart .lt-dot.lt-alt.lt-night { stroke: var(--night); }
.lt-chart .lt-dot.lt-alt.lt-day { stroke: var(--day); }
.lt-chart .lt-med { stroke-width: 1.5; stroke-dasharray: 5 4; }
.lt-chart .lt-med.lt-night { stroke: var(--night); }
.lt-chart .lt-med.lt-day { stroke: var(--day); }
.lt-key { font-size: 13px; color: var(--muted); }
.lt-key i { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin: 0 0.25rem 0 0.8rem; vertical-align: -1px; }
.lt-key i.n { background: var(--night); } .lt-key i.d { background: var(--day); }
.lt-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; margin-top: 0.2rem; }
.lt-stat { border: 1px solid var(--border); border-radius: 8px; padding: 0.2rem 0.5rem; font-size: 13px; line-height: 1.25; }
.lt-stat h4 { display: inline; margin: 0 0.35rem 0 0; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.04em; }
.lt-stat .lt-big { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.lt-stat .lt-range { color: var(--muted); font-size: 12.5px; }
#lot-times { padding: 0.4rem 0.6rem; }

/* Lot page: "Update this month's invoice" before / after (ken, 2026-10-22) */
.rf-box { margin: 0.5rem 0 0.8rem; padding: 0.7rem 0.9rem; border: 1px solid var(--border); border-radius: 8px; }
.rf-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.rf-cols h4 { margin: 0.2rem 0; font-size: 13px; color: var(--muted); }
.rf-changed td { background: color-mix(in srgb, var(--accent, #c97a12) 14%, transparent); }
@media (max-width: 700px) { .rf-cols { grid-template-columns: 1fr; } }

/* Paper lists (Billing > Lot Sheet / Delivery Method): read-only, ordered by lot code, made to print
   (ken, 2026-10-23: Terry and June still work from the old typed sheets). Headings repeat on every page, a row
   never splits across pages, and the filter / Print buttons and links don't print. */
.pl { max-width: 1250px; }
.pl-head { display: flex; flex-direction: column; gap: 0.6rem; align-items: flex-start; }
.pl-head h1 { margin-bottom: 0.2rem; }
.pl-head p { margin: 0.15rem 0; }
.pl-legend { font-size: 13px; color: var(--muted); max-width: 52rem; }
.pl-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.pl-filter { width: 14rem; }
.pl-table { width: 100%; border-collapse: collapse; margin-top: 0.8rem; font-size: 14px; border: none; border-radius: 0; background: transparent; }
.pl-table th, .pl-table td { text-align: left; vertical-align: top; padding: 0.35rem 0.55rem; border-bottom: 1px solid var(--border); }
.pl-table thead th { font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); border-bottom: 2px solid var(--border); }
.pl-sort { display: inline-flex; gap: 0.3rem; }
.pl-sort .btn.active, .pl-sort .btn.active:hover { background: var(--accent); color: #fff; }
.pl-table tr.pl-first td { border-top: 2px solid var(--border); }
.pl-table .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pl-code { font-weight: 700; white-space: nowrap; }
.pl-code a { color: inherit; text-decoration: none; }
.pl-code a:hover { text-decoration: underline; }
.pl-days { font-weight: 700; white-space: nowrap; letter-spacing: 0.05em; font-variant-numeric: tabular-nums; }
.pl-note, .pl-sub, .pl-qty { font-size: 12.5px; color: var(--muted); }
.pl-check { width: 1.6rem; }
.pl-box { display: inline-block; width: 0.9rem; height: 0.9rem; border: 1.5px solid var(--muted); border-radius: 2px; }
.pl-often { white-space: nowrap; }
.pl-extra-cell { font-size: 13px; }
.pl-x + .pl-x { margin-top: 0.2rem; }
.pl-x[hidden] { display: none; }
.pl-table .pl-m { width: 1.35rem; padding-left: 0.1rem; padding-right: 0.1rem; text-align: center; font-size: 12px; }
.pl-table td.pl-m.on { color: var(--accent); }
.pl-table .pl-now { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.pl-method { white-space: nowrap; font-weight: 600; }
.pl-to { overflow-wrap: anywhere; font-size: 13.5px; }
.pl-delivery .pl-to { width: 38%; }
.pl-mail { color: var(--muted); }
.pl-missing { color: var(--err); }
@media screen and (max-width: 760px) {
  .pl-table { font-size: 13px; }
  .pl-table, .pl-table tbody, .pl-table tr, .pl-table td { display: block; }
  .pl-table thead { display: none; }
  .pl-table tr { border-bottom: 1px solid var(--border); padding: 0.4rem 0; }
  .pl-table td { border: none; padding: 0.1rem 0; }
  .pl-table td.pl-m, .pl-check { display: none; }
  .pl-table .num { text-align: left; }
  .pl-filter { width: 100%; }
}
@media print {
  @page { margin: 0.45in 0.4in; }
  .pl { max-width: none; }
  .pl-actions { display: none !important; }
  .pl-head h1 { font-size: 18pt; }
  .pl-legend { color: #000; }
  .pl-table { font-size: 9.5pt; margin-top: 0.4rem; }
  .pl-table th, .pl-table td { padding: 0.18rem 0.35rem; border-bottom: 1px solid #bbb; }
  .pl-table thead { display: table-header-group; }
  .pl-table thead th { color: #000; border-bottom: 1.5px solid #000; }
  .pl-table tr { break-inside: avoid; page-break-inside: avoid; }
  .pl-table tr[hidden] { display: none; }
  .pl-table .pl-now { background: none; }
  .pl-table td.pl-m.on { color: #000; }
  .pl-box { border-color: #000; }
  .pl-note, .pl-sub, .pl-qty, .pl-mail { color: #000; }
}

/* Lot page on a phone (ken, 2026-10-24): section titles no longer squeezed to a word a line by their summary, tables
   stay inside their box (they scroll sideways if they must), and the "What they owe" rows stack. */
.lot-tag { max-width: 100%; }
@media screen and (max-width: 640px) {
  .lot-sec > summary { flex-wrap: wrap; gap: 0.15rem 1rem; }
  .lot-sec > summary > span:first-child { flex: 1 1 auto; }
  .lot-sum { flex: 1 1 100%; text-align: left; font-size: 14px; margin-left: 1.2rem; }
  .lot-sec > .lot-table, .lot-card > .lot-table { display: block; overflow-x: auto; max-width: 100%; }
  .lot-table { font-size: 14.5px; }
  .lot-table th, .lot-table td { padding: 0.4rem 0.3rem; }
  /* What they owe: one line per invoice, the table scrolls sideways if it must (ken, 2026-11-06) */
  .lot-owe td, .lot-owe th { white-space: nowrap; }
  .lot-owe .lot-tag, .lot-owe .btn { font-size: 12px; padding: 0.15rem 0.5rem; }
  .lot-btnrow { flex-wrap: nowrap; gap: 0.4rem; }
  .lot-btnrow .btn { flex: 1 1 0; min-width: 0; padding: 0.5rem 0.4rem; font-size: 14px; }
}

/* Sortable / scrollable tables (static/app.js): a heading you can tap, and a wide table that scrolls inside its box. */
table.sortable > thead th { cursor: pointer; user-select: none; }
table.sortable > thead th.s-asc::after { content: " ▲"; font-size: 0.7em; }
table.sortable > thead th.s-desc::after { content: " ▼"; font-size: 0.7em; }
@media screen { table.tbl-wide { display: block; overflow-x: auto; max-width: 100%; min-width: 0; } }
@media print { table.sortable > thead th::after { content: none !important; } }

/* Lot Sheet on paper: same type size, fewer pages (ken, 2026-10-25: it was 10) -- tighter rows and margins. */
@media print {
  @page { margin: 0.4in 0.25in; }
  .pl-sheet:not(.pl-auto) { table-layout: fixed; }
  .pl-sheet { font-size: 10pt; line-height: 1.2; }          /* 10pt with tight rows ~ 5.5 pages (ken, 2026-10-25: aim for 6) */
  .pl-sheet th, .pl-sheet td { padding: 0.05rem 0.4rem; overflow-wrap: anywhere; }
  .pl-sheet thead th { text-transform: none; letter-spacing: 0; font-size: inherit; }
  .pl-sheet .pl-code { white-space: normal; }
  main:has(.pl-sheet) { padding: 0 !important; }          /* the screen's bottom padding pushed an empty last page */
  .pl-sheet + *, .pl:has(.pl-sheet) { margin-bottom: 0; padding-bottom: 0; }
  .pl-sheet tr { break-inside: avoid; }
  .pl-sheet thead { display: table-header-group; }
}

/* What Happened: one tidy row of  [<- prev]  [date]  [next ->]  on any width */
.day-nav { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.5rem; align-items: center; margin: 0.6rem 0 0.2rem; max-width: 30rem; }
.day-nav .btn { white-space: nowrap; text-align: center; }
.day-nav input[type=date] { width: 100%; min-width: 0; text-align: center; }
.day-today { margin: 0.1rem 0 0; font-size: 13px; }

/* Lot page: "At a glance" card, Notes, and the two layouts (ken, 2026-10-29) */
.lot-glance h2 { margin-top: 0; }
.glance-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
.glance-tile { border: 1px solid var(--border); border-radius: 10px; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.glance-tile span, .glance-tile small { color: var(--muted); font-size: 0.85em; }
.glance-tile b { font-size: 1.2em; overflow-wrap: anywhere; }
.glance-watch { margin: 0.8rem 0 0; padding: 0.6rem 0.7rem; border-radius: 10px; background: #fff7ed; color: #7c2d12; border: 1px solid #fdba74; }
@media (prefers-color-scheme: dark) { .glance-watch { background: #3a2410; color: #fed7aa; border-color: #9a3412; } }
.lot-group { margin: 1.4rem 0 0.5rem; font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.lot-tabbar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0.4rem; margin: 0 0 1rem; }
.lot-tabbar button { font: inherit; font-size: 1rem; min-height: 48px; border-radius: 10px; border: 2px solid var(--border); background: var(--panel); color: inherit; cursor: pointer; padding: 0 0.3rem; }
.lot-tabbar button[aria-pressed="true"] { background: var(--accent, #2563eb); border-color: var(--accent, #2563eb); color: #fff; font-weight: 700; }
.lotp.lot-tabs [data-tab]:not(.tab-on) { display: none; }
@media (max-width: 640px) { .lot-tabbar { gap: 0.25rem; } .lot-tabbar button { font-size: 0.82rem; min-height: 42px; padding: 0 0.1rem; } }
.lot-edit-icon { padding: 4px; min-width: 32px; min-height: 32px; display: inline-flex; align-items: center; justify-content: center; background: none; border: 0; color: var(--muted); }
.lot-edit-icon svg { width: 16px; height: 16px; }
.lot-pm-in { margin: 0 0 0.3rem; }
.lot-group-sub { margin: -0.2rem 0 0.6rem; }
.week-who { font-size: 18px; }
.lot-head > div:first-child { flex: 1; min-width: 0; }
.lot-addr { display: flex; align-items: center; gap: 0.3rem; }
.lot-addr .lot-edit-icon { margin-left: auto; flex-shrink: 0; }
.lot-head .lot-tags:empty { display: none; }

.note-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.note-row .note-text { flex: 1 1 14rem; }

.nav-loading {
  position: fixed; top: 0.75rem; left: 50%; transform: translateX(-50%); z-index: 1000;
  background: var(--accent); color: #fff; padding: 0.35rem 1rem; border-radius: 999px;
  font-size: 0.9rem; box-shadow: 0 2px 8px rgba(0,0,0,0.25); pointer-events: none;
}
.nav-loading[hidden] { display: none; }

.page-tabs { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.2rem 0 0.9rem; }
.page-tabs a { padding: 0.5rem 0.95rem; color: var(--text); text-decoration: none; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); font-size: 15px; }
.page-tabs a:hover { border-color: var(--accent); }
.page-tabs a.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.subnav { margin: 0 0 0.6rem; }

/* ken, 2026-11-06: every collapsible section looks the same -- big arrow, then the title -- and opens/closes from either (app.js), not from the blank space */
details > summary { list-style: none; cursor: default !important; }   /* !important: older per-section rules gave the whole bar a pointer */
details > summary::-webkit-details-marker { display: none; }
details > summary::before { content: "▸"; color: var(--muted); display: inline-block; min-width: 1.6rem; padding: 0.3rem 0.4rem 0.3rem 0; font-size: 1.25em; line-height: 1; cursor: pointer !important; margin-right: 0; }
details[open] > summary::before { content: "▾"; }
details > summary > :not(.lot-sum):not(.lot-summary-bit):not(.lot-summary-toggle):not(button):not(a) { cursor: pointer !important; }
.lot-sec > summary::before { margin-right: 0.3rem; }
.lot-btnrow { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.lot-btnrow .btn { white-space: nowrap; }
.lot-owe, .lot-owe td, .lot-owe th { white-space: nowrap; }
.gv-ctl .btn { min-height: 44px; font-size: 16px; padding: 0 0.9rem; }

/* "What they owe": the invoice buttons share the "From QuickBooks" line, right-justified (ken, 2026-11-07) */
.lot-owe-foot { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.8rem; }
.lot-owe-foot .lot-asof { margin: 0; }
.lot-owe-foot .lot-btnrow { margin: 0 0 0 auto; flex-wrap: nowrap; }
.lot-owe-foot .lot-btnrow .btn { flex: 0 0 auto; }
.lot-wording { white-space: pre-line; }

/* Lot page > Visits > Metrics: a plain table, labels left, numbers right (ken, 2026-11-07) */
.lt-metrics { max-width: 28rem; }
.lt-metrics th { text-align: left; font-weight: 400; color: var(--muted); }
.lt-metrics thead th { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.lt-metrics thead th.num { text-align: right; }
.lt-metrics td.num { font-variant-numeric: tabular-nums; }
.lt-metrics .lt-main th, .lt-metrics .lt-main td { color: var(--text); font-weight: 700; }
