/* Peddys Field — mobile-first, big touch targets, the same calm look as Mini AR. */
:root {
  --accent: #0e7490;
  --accent-dark: #155e75;
  --bg: #f4f6f8;
  --card: #ffffff;
  --text: #1f2933;
  --muted: #5f6b7a;
  --line: #dde3ea;
  --danger: #b42318;
  --warn-bg: #fff7e6;
  --warn-line: #f0c36d;
  --radius: 12px;
  --nav-h: 60px;
}
* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
}
h1,
h2,
h3 {
  margin: 0 0 8px;
  line-height: 1.25;
}
h1 {
  font-size: 22px;
}
h2 {
  font-size: 17px;
}
p {
  margin: 0 0 10px;
}
a {
  color: var(--accent-dark);
}
code {
  background: #eef2f5;
  padding: 1px 4px;
  border-radius: 4px;
}
.muted {
  color: var(--muted);
}
.pre {
  white-space: pre-line;
}

/* boot / full-page states */
.boot {
  padding: 48px 20px;
  text-align: center;
  color: var(--muted);
}
.boot-card {
  max-width: 420px;
  margin: 40px auto;
  background: var(--card);
  border-radius: var(--radius);
  padding: 24px;
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

/* shell */
.shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.devbar {
  background: #fde68a;
  color: #78350f;
  font-size: 12px;
  text-align: center;
  padding: 3px 8px;
  letter-spacing: 0.02em;
}
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  padding-top: calc(10px + env(safe-area-inset-top));
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  /* Above the bottom bar (5) and the bulk bar (6), below page modals (20): the name menu's
     "Send to the office" modal lives inside the top bar, so it can only stack as high as the bar
     (2026-09-30: the bottom bar hid its Submit button on an iPhone). */
  z-index: 7;
}
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
  font-size: 17px;
}
.brand-mark {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: var(--accent);
  color: #fff;
  font-weight: 800;
}
.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.topbar-refresh {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: -4px -8px -4px 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.topbar-refresh:hover,
.topbar-refresh:active {
  background: var(--bg);
  color: var(--text);
}
.topbar-user {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 14px;
}
.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
}
.main {
  flex: 1;
  padding: 16px;
  padding-bottom: calc(var(--nav-h) + 24px + env(safe-area-inset-bottom));
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
}
.page-title {
  margin-top: 4px;
}
.bottomnav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--nav-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--card);
  border-top: 1px solid var(--line);
  display: flex;
  z-index: 5;
}
.navitem {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  text-decoration: none;
  color: var(--muted);
  font-size: 12px;
}
.navitem.active {
  color: var(--accent-dark);
  font-weight: 600;
}
.navicon {
  font-size: 20px;
  line-height: 1;
}
/* Phones: the bottom menu slides away on scroll down, back on scroll up (web/app/ui/autohide-nav.js).
   .main keeps its padding, so nothing sits under the menu when it's showing. */
@media not all and (min-width: 700px) {
  .bottomnav {
    transition: transform 0.2s ease;
  }
  .nav-hidden .bottomnav {
    transform: translateY(100%);
  }
  .nav-hidden .bulkbar {
    bottom: calc(8px + env(safe-area-inset-bottom));
  }
}
@media (prefers-reduced-motion: reduce) {
  .bottomnav {
    transition: none;
  }
}
@media (min-width: 700px) {
  .bottomnav {
    position: sticky;
    top: 0;
    bottom: auto;
    height: auto;
    order: -1;
    border-top: 0;
    border-bottom: 1px solid var(--line);
    padding: 0 16px;
    justify-content: flex-start;
    gap: 4px;
  }
  .navitem {
    flex: none;
    flex-direction: row;
    gap: 6px;
    padding: 10px 12px;
    font-size: 14px;
  }
  .navicon {
    font-size: 16px;
  }
  .main {
    padding-bottom: 32px;
  }
}

/* cards & rows */
.card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 16px;
  margin: 0 0 14px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
}
.card-warn {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
}
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.card-head h2 {
  margin: 0;
}
.rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.row:first-child {
  border-top: 0;
}
.row-muted {
  opacity: 0.6;
}
/* A row opened in place (a Hayward payment's claims): the details take a full line under it. */
.row-open {
  flex-wrap: wrap;
}
.row-detail {
  flex: 0 0 100%;
  min-width: 0;
  margin-top: 6px;
}
/* "Past jobs (N)": a whole-width row under the open jobs that opens the list (web/app/ui/past-jobs.js). */
.past-toggle {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-top: 1px solid var(--line);
  margin-top: 4px;
  padding: 12px 0 6px;
  font: inherit;
  color: var(--text);
  cursor: pointer;
}
.past-toggle.alone {
  border-top: 0;
  margin-top: 0;
  padding-top: 0;
}
.past-caret {
  display: inline-block;
  width: 1.2em;
  color: var(--muted);
}
.past-jobs .linkbtn {
  margin-top: 6px;
}
/* A note above the page (a customer record merged into another). Themed by --warn-*. */
.notice {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 0 0 12px;
}
.row-main {
  flex: 1;
  min-width: 0;
}
.row-title {
  font-weight: 600;
}
.row-sub {
  color: var(--muted);
  font-size: 14px;
  overflow-wrap: anywhere;
}
.linklist {
  padding-left: 18px;
  margin: 0;
}
.linklist li {
  margin: 6px 0;
}
.kv {
  border-collapse: collapse;
  width: 100%;
}
.kv th {
  text-align: left;
  color: var(--muted);
  font-weight: 500;
  padding: 6px 12px 6px 0;
  white-space: nowrap;
  vertical-align: top;
  width: 1%;
}
.kv td {
  padding: 6px 0;
}
.empty {
  color: var(--muted);
  padding: 20px;
  text-align: center;
}
.spinner {
  color: var(--muted);
  padding: 12px 0;
}
.errorbox {
  background: #fef3f2;
  border: 1px solid #fda29b;
  color: var(--danger);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 8px 0;
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.badge {
  display: inline-block;
  font-size: 12px;
  padding: 1px 8px;
  border-radius: 999px;
  background: #e5e9ef;
  color: var(--muted);
  vertical-align: middle;
}
.badge-warn {
  background: #fde68a;
  color: #78350f;
}

/* buttons & forms */
.btn {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
  border-radius: 10px;
  min-height: 44px;
  padding: 8px 16px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.btn:disabled {
  opacity: 0.55;
  cursor: default;
}
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn-danger {
  background: #fff;
  border-color: #fda29b;
  color: var(--danger);
}
.iconbtn {
  appearance: none;
  border: 0;
  background: transparent;
  font-size: 26px;
  line-height: 1;
  width: 44px;
  height: 44px;
  cursor: pointer;
  color: var(--muted);
}
.form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.form-inline {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
.form-inline input {
  flex: 1;
  min-width: 160px;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.field-label {
  font-size: 14px;
  font-weight: 600;
}
.field-hint {
  font-size: 13px;
  color: var(--muted);
}
input,
select,
textarea {
  font: inherit;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--text);
  width: 100%;
}
input[type="color"] {
  padding: 4px;
  width: 64px;
}
/* Radio buttons and checkboxes never take the text-box sizing above: a radio inside a chip grew to
   the chip's full width and covered the next one (the Hayward form's "Type of repair" read "Ir fi",
   CJ's ticket 2026-10-01). `.check input` below still sizes the ones in .check rows. */
input[type="radio"],
input[type="checkbox"] {
  width: auto;
  min-height: 0;
  padding: 0;
  flex: none;
}
.chip input[type="radio"],
.chip input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
}
input:focus,
select:focus,
textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.check {
  display: flex;
  align-items: center;
  gap: 8px;
}
.check input {
  width: 22px;
  height: 22px;
  min-height: 0;
}
/* New job's "📷 Fill from a photo" (owner, 2026-10-05; web/app/ui/paper-fill.js). */
.paper-fill { display: flex; flex-direction: column; gap: 6px; }
.paper-fill-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.paper-fill .error { color: var(--danger); }
.paper-fill-box { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; display: flex; flex-direction: column; gap: 4px; }
.paper-match { font-weight: 600; }
.paper-notes { margin: 0; padding-left: 18px; color: var(--muted); }
.paper-read { display: grid; grid-template-columns: max-content 1fr; gap: 2px 10px; margin: 6px 0 0; }
.paper-read dt { color: var(--muted); }
.paper-read dd { margin: 0; overflow-wrap: anywhere; white-space: pre-line; }
.from-tag { display: inline-block; font-size: 11px; font-weight: 500; padding: 0 6px; border-radius: 999px; background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--text); vertical-align: 1px; }
.from-tag.from-records { background: transparent; border-color: var(--line); color: var(--muted); }
/* New job's "This is an estimate" box (owner, 2026-10-01). */
.check.est-check {
  min-height: 44px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}
.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

/* modal */
.modal-back {
  position: fixed;
  inset: 0;
  background: rgba(16, 24, 40, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 20;
}
.modal {
  background: var(--card);
  width: 100%;
  max-width: 560px;
  max-height: 92vh;
  overflow: auto;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
}
.modal-wide {
  max-width: 900px;
}
@media (min-width: 700px) {
  .modal-back {
    align-items: center;
  }
  .modal {
    border-radius: var(--radius);
  }
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.modal-head h2 {
  margin: 0;
}

/* toasts */
.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-h) + 16px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 30;
  pointer-events: none;
}
.toast {
  background: #1f2933;
  color: #fff;
  padding: 10px 16px;
  border-radius: 10px;
  font-size: 14px;
  max-width: 90vw;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.toast-error {
  background: var(--danger);
}
/* a toast with a button (Undo): tappable, the button big enough for a thumb */
.toast-act {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 4px 4px 16px;
}
.toast-btn {
  background: transparent;
  border: 0;
  color: #7dd3fc;
  font: inherit;
  font-weight: 700;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
}
.toast-btn:hover,
.toast-btn:focus-visible {
  background: rgba(255, 255, 255, 0.12);
}
@media (min-width: 700px) {
  .toasts {
    bottom: 24px;
  }
}

/* page bits */
.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.back {
  display: inline-block;
  margin-bottom: 8px;
  text-decoration: none;
  color: var(--muted);
}
.center {
  text-align: center;
  margin: 8px 0 16px;
}
.small {
  font-size: 13px;
}
.left {
  justify-content: flex-start;
}
.grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 12px;
}
.self-end {
  align-self: end;
  min-height: 44px;
}
@media (max-width: 480px) {
  .grid2 {
    grid-template-columns: 1fr;
  }
}
.search {
  display: flex;
  gap: 10px;
  align-items: center;
  margin: 8px 0 12px;
  flex-wrap: wrap;
}
.search input[type="search"] {
  flex: 1;
  min-width: 200px;
  font-size: 17px;
}
.row-link {
  text-decoration: none;
  color: inherit;
}
.rows.card {
  padding: 4px 16px;
}
.badge-owed {
  background: #fde68a;
  color: #78350f;
  font-weight: 600;
}
.badge-ok {
  background: #d1fae5;
  color: #065f46;
}
.badge-bad {
  background: #fee2e2;
  color: #991b1b;
}
.chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.cust-title {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}
.cust-title h1 {
  margin: 0 0 6px;
}
/* Job page: "📷 Add photo" (and Edit for the office) at the top, thumb-sized on a phone. */
.job-head-btns {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.job-head-btns .btn {
  min-height: 44px;
}
.maplink {
  white-space: nowrap;
  margin-left: 6px;
}
.balance {
  font-size: 20px;
  font-weight: 700;
  margin: 4px 0 10px;
}
.balance.owed {
  color: #b45309;
}
.progress {
  color: var(--accent-dark);
  font-weight: 600;
}
a.btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* photos */
.photo-adder {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.photo-adder .btn {
  flex: 1;
  min-width: 150px;
}
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px;
}
.photo-thumb {
  position: relative;
  padding: 0;
  border: 0;
  background: #e5e9ef;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 1;
  cursor: pointer;
}
.photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.photo-kind {
  position: absolute;
  left: 6px;
  bottom: 6px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 999px;
}
.shots {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  margin-bottom: 10px;
}
.shots img {
  height: 90px;
  border-radius: 8px;
}
.outbox {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: 8px;
  padding: 8px 12px;
  margin: 0 0 10px;
  font-size: 14px;
}
.outbox-stuck {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 6px;
}
.outbox.is-done {
  background: var(--card);
  border-color: var(--accent);
  color: var(--accent-dark);
  font-weight: 600;
}
.outbox-line {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.outbox-bar {
  height: 4px;
  background: var(--line);
  border-radius: 2px;
  margin: 6px 0;
  overflow: hidden;
}
.outbox-bar span {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 0.3s;
}
.outbox-thumbs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  margin: 4px 0;
}
.outbox-thumb {
  position: relative;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--line);
  opacity: 0.6;
}
.outbox-thumb.is-up {
  opacity: 1;
  outline: 2px solid var(--accent);
}
.outbox-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.outbox-thumb-tag {
  position: absolute;
  right: 2px;
  bottom: 1px;
  font-size: 11px;
  color: #fff;
  text-shadow: 0 0 3px #000;
}
.lightbox img {
  width: 100%;
  max-height: 60vh;
  object-fit: contain;
  background: #111;
  border-radius: 8px;
}
.lightbox-meta {
  margin: 8px 0;
}

/* camera */
.camera {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 50;
  display: flex;
  flex-direction: column;
}
.camera-view {
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
}
.camera-view video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.camera-error {
  color: #fff;
  text-align: center;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.camera-strip {
  display: flex;
  gap: 6px;
  padding: 6px;
  overflow-x: auto;
  background: #111;
}
.camera-strip img {
  height: 56px;
  border-radius: 6px;
}
.camera-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  padding-bottom: calc(14px + env(safe-area-inset-bottom));
  background: #111;
}
.camera-link {
  background: none;
  border: 0;
  color: #fff;
  font: inherit;
  font-size: 15px;
  padding: 10px;
  min-width: 110px;
  text-align: left;
}
.camera-done {
  text-align: right;
  font-weight: 700;
}
.camera-shutter {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 5px solid #fff;
  background: #fff;
  box-shadow: 0 0 0 3px #111 inset;
  cursor: pointer;
}
.camera-shutter:disabled {
  opacity: 0.4;
}

/* history modal */
.hist {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 14px;
}
@media (max-width: 700px) {
  .hist {
    grid-template-columns: 1fr;
  }
}
.hist-rail {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 60vh;
  overflow: auto;
}
@media (max-width: 700px) {
  .hist-rail {
    flex-direction: row;
    max-height: none;
    overflow-x: auto;
  }
  .hist-item {
    min-width: 200px;
  }
}
.hist-item {
  text-align: left;
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 10px;
  padding: 8px 10px;
  font: inherit;
  display: flex;
  flex-direction: column;
  gap: 2px;
  cursor: pointer;
}
.hist-item.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.15);
}
.hist-top {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
}
.hist-label {
  font-size: 12px;
  color: var(--accent-dark);
  font-weight: 600;
}
.hist-summary {
  font-size: 13px;
}
.hist-by {
  font-size: 12px;
  color: var(--muted);
}
.hist-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.hist-modes {
  display: flex;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.hist-mode {
  background: #fff;
  border: 0;
  padding: 8px 10px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.hist-mode.on {
  background: var(--accent);
  color: #fff;
}
.hist-mode:disabled {
  opacity: 0.5;
  cursor: default;
}
.hist-caption {
  color: var(--muted);
  font-size: 14px;
  margin: 8px 0;
}
.hist-caption.has-changes {
  color: var(--accent-dark);
  font-weight: 600;
}
.hist-fields {
  border-top: 1px solid var(--line);
}
.hist-row {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.hist-row.changed {
  background: #fffbeb;
}
.hist-flabel {
  color: var(--muted);
  font-size: 14px;
}
.hist-fval {
  overflow-wrap: anywhere;
}
.hist-old {
  background: #fee2e2;
  color: #991b1b;
  text-decoration: line-through;
  padding: 1px 4px;
  border-radius: 4px;
}
.hist-new {
  background: #d1fae5;
  color: #065f46;
  padding: 1px 4px;
  border-radius: 4px;
}
.hist-arrow {
  margin: 0 6px;
  color: var(--muted);
}
.hist-old em,
.hist-new em {
  opacity: 0.7;
}
.hist-foot {
  align-items: center;
  margin-top: 10px;
}
.hist-foot .muted {
  margin-right: auto;
  font-size: 13px;
}

/* jobs */
.tabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  margin: 6px 0 8px;
  padding-bottom: 2px;
}
.tab {
  flex: none;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 999px;
  padding: 8px 14px;
  font: inherit;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  min-height: 40px;
}
.tab.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.search select {
  width: auto;
  min-width: 140px;
}
.row-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex: none;
}
.jobno {
  color: var(--muted);
  font-weight: 600;
}
.jobno.big {
  font-size: 15px;
  padding-right: 4px;
}
.badge-info {
  background: #dbeafe;
  color: #1e40af;
}
.badge-purple {
  background: #ede9fe;
  color: #5b21b6;
}
/* An estimate (src/estimates.js), not yet a job */
.badge-estimate {
  background: #ccfbf1;
  color: #115e59;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  background: #eef2f5;
  border-radius: 999px;
  padding: 2px 10px 2px 6px;
  white-space: nowrap;
}
.chip-empty {
  color: var(--muted);
  padding-left: 10px;
}
.actions .btn {
  margin-bottom: 4px;
}
.btn-small {
  min-height: 34px;
  padding: 4px 10px;
  font-size: 13px;
  margin-right: 6px;
}
.seg {
  display: flex;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.seg-btn {
  flex: 1;
  border: 0;
  background: #fff;
  min-height: 44px;
  font: inherit;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.seg-btn.on {
  background: var(--accent);
  color: #fff;
}
.picked {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.linkbtn {
  background: none;
  border: 0;
  color: var(--accent-dark);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
}
/* The job page's Warranty / Customer pay badge, a button for the office: opens Edit at Billing. */
.bill-switch {
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
  padding: 0;
}
.bill-switch .badge::after {
  content: " ▾";
}
.picker {
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-top: 4px;
  overflow: hidden;
}
.picker-item {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  border-top: 1px solid var(--line);
  background: #fff;
  padding: 10px 12px;
  font: inherit;
  cursor: pointer;
}
.picker-item:first-child {
  border-top: 0;
}
.new-cust {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.picker-item:hover {
  background: #f1f5f9;
}

/* parts & labour lines */
.lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.line {
  display: grid;
  grid-template-columns: 1fr 110px 64px 90px 90px auto auto;
  gap: 6px;
  align-items: center;
  padding: 6px;
  border-radius: 10px;
  background: #f8fafc;
}
.line.warranty {
  background: #f5f3ff;
}
.line input {
  min-height: 40px;
  padding: 6px 8px;
}
.line-amt {
  text-align: right;
  font-weight: 600;
  white-space: nowrap;
}
.billbtn {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 999px;
  min-height: 36px;
  padding: 4px 10px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.billbtn.warranty {
  background: #ede9fe;
  color: #5b21b6;
  border-color: #ddd6fe;
}
@media (max-width: 700px) {
  .line {
    grid-template-columns: 1fr 1fr;
  }
  .line-desc {
    grid-column: 1 / -1;
  }
}
/* a line's description / part box and its suggestion list (web/app/ui/part-picker.js) */
.partbox {
  position: relative;
  min-width: 0;
}
.partbox input {
  width: 100%;
}
.part-sug {
  position: absolute;
  z-index: 30;
  top: 100%;
  left: 0;
  width: max(100%, 280px);
  max-width: calc(100vw - 32px);
  max-height: 60vh;
  overflow-y: auto;
  background: var(--card, #fff);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
}
.part-sug-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 52px;
  padding: 8px 12px;
}
.part-sug-item.on {
  background: #e0f2fe;
}
.ps-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.ps-top b {
  overflow-wrap: anywhere;
}
.ps-price {
  font-weight: 600;
  white-space: nowrap;
}
.line-note {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: 13px;
  color: var(--muted, #64748b);
}
.line-note.warranty {
  color: #5b21b6;
}
.totals {
  display: flex;
  gap: 18px;
  margin-top: 10px;
  flex-wrap: wrap;
}

/* my day */
.stop {
  border-left: 5px solid var(--line);
}
.stop.in_progress {
  border-left-color: #f59e0b;
}
.stop.completed {
  border-left-color: #10b981;
  opacity: 0.75;
}
.stop-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.stop-no {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  flex: none;
}
.stop-no.small {
  width: 24px;
  height: 24px;
  font-size: 12px;
}
.stop-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.stop-actions .btn {
  flex: 1;
  min-width: 100px;
  justify-content: center;
}
/* Tighter stop cards; the map and call shortcuts are one row of icons (owner, 2026-10-13; web/app/ui/nav-icons.js) */
.card.stop {
  padding: 10px 12px;
  margin-bottom: 10px;
}
.stop .stop-head {
  gap: 10px;
}
.stop .row-sub {
  line-height: 1.35;
}
.nav-icons {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}
.nav-icon {
  flex: 1 1 0;
  min-width: 46px;
  max-width: 88px;
  min-height: 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 4px 2px 3px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--muted);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.nav-icon:hover,
.nav-icon:focus-visible {
  border-color: var(--accent);
}
.nav-icon:active {
  background: var(--bg);
}
.nav-icon-svg {
  width: 24px;
  height: 24px;
  flex: none;
}
.nav-icon-label {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stop .nav-icons {
  margin-left: 42px; /* lines up under the name, past the stop number */
}
@media (max-width: 359px) {
  .stop .nav-icons {
    margin-left: 0;
  }
  .route-tools .btn {
    padding: 8px 10px;
    font-size: 15px;
  }
}
.route-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
}
.route-btn .nav-icon-svg {
  width: 20px;
  height: 20px;
}
.route-note {
  margin: 0 0 8px;
}
/* My routes: the next days, each folding open or shut */
.route-day {
  margin-top: 14px;
}
.route-day-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card, transparent);
  color: inherit;
  font: inherit;
  font-weight: 600;
  font-size: 16px;
  text-align: left;
  cursor: pointer;
}
.route-day-arrow {
  width: 14px;
  color: var(--muted);
}
.route-day-route {
  margin: 10px 0 4px;
}
.route-day-empty {
  margin: 14px 0 0;
  padding: 0 12px;
}
/* My routes: "Change order" for a day's stops (Colten's ticket, 2026-10-05; web/app/ui/day-order.js) */
.route-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 10px 0 8px;
}
.route-tools .route-order {
  margin-left: auto;
}
.order-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}
.order-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.order-row.order-moved {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-radius: 8px;
}
.order-row.order-done .order-main {
  opacity: 0.6;
}
select.order-no,
[data-theme="dark"] select.order-no {
  flex: none;
  width: 58px;
  padding: 6px 4px;
  text-align: center;
  text-align-last: center;
  font-weight: 700;
  font-size: 17px;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.order-main {
  flex: 1;
  min-width: 0;
}
.order-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.order-sub {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.order-btn {
  flex: none;
  width: 44px;
  padding: 0;
  font-size: 20px;
}
.order-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.order-actions .btn {
  flex: 1;
}

/* planner */
.datenav {
  display: flex;
  gap: 6px;
  align-items: center;
}
.datenav input {
  width: auto;
}
.plan-tools {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.spacer {
  flex: 1;
}
.plan-map {
  height: 42vh;
  min-height: 260px;
  border-radius: var(--radius);
  overflow: hidden;
  background: #dfe7ee;
  margin-bottom: 12px;
}
.plan-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
}
.plan-col {
  background: var(--card);
  border-radius: var(--radius);
  padding: 10px;
  min-height: 120px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
}
.plan-col-none {
  background: #f1f5f9;
}
.plan-col-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.plan-stop {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: flex-start;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-bottom: 6px;
  background: #fff;
  cursor: grab;
}
.plan-stop.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.2);
}
.plan-stop.locked {
  background: #fffbeb;
}
.plan-stop.completed {
  opacity: 0.65;
}
.plan-stop-tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  width: 100%;
}
.plan-stop .row-main {
  min-width: 160px;
}
.iconbtn.small {
  width: 32px;
  height: 32px;
  font-size: 15px;
}
.moveto {
  width: auto;
  min-height: 32px;
  padding: 2px 6px;
  font-size: 13px;
}
.pin {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid #fff;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: grid;
  place-items: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
  cursor: pointer;
}
.pin-job.selected {
  transform: scale(1.3);
  z-index: 2;
}
.pin-job.done {
  opacity: 0.55;
}
.pin-base {
  background: #1f2933;
  border-radius: 6px;
}
.pin-tech {
  background: #fff;
  color: #1f2933;
  border-width: 3px;
}

/* claims & mail */
.grid3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 12px;
}
@media (max-width: 600px) {
  .grid3 {
    grid-template-columns: 1fr;
  }
}
.copyrows {
  display: flex;
  flex-direction: column;
}
.copyrow {
  display: grid;
  grid-template-columns: 140px 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 6px 0;
  border-top: 1px solid var(--line);
}
.copyrow-label {
  color: var(--muted);
  font-size: 14px;
}
.copyrow-value {
  overflow-wrap: anywhere;
}
@media (max-width: 600px) {
  .copyrow {
    grid-template-columns: 1fr auto;
  }
  .copyrow-label {
    grid-column: 1 / -1;
    padding-top: 4px;
  }
}
.rowbtn {
  background: none;
  border: 0;
  text-align: left;
  font: inherit;
  padding: 0;
  cursor: pointer;
  color: inherit;
}
.mailtext {
  white-space: pre-wrap;
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  max-height: 45vh;
  overflow: auto;
  margin: 8px 0;
}
/* Mailbox search: the words found, and a line of the email around them. */
mark {
  background: var(--warn-line);
  color: inherit;
  border-radius: 2px;
  padding: 0 1px;
}
.mail-snippet {
  font-style: italic;
  overflow-wrap: anywhere;
}
/* An email's attachments: one per line, the name a link (view in a tab, or download). */
.attachments {
  margin: 8px 0;
}
/* A job's Emails list (ui/job-emails.js) sits between the job's cards. */
.job-emails {
  margin-bottom: 16px;
}
/* The reply box under an email (ui/reply.js). */
.reply {
  border-top: 1px solid var(--line);
  margin-top: 12px;
  padding-top: 8px;
}
.reply-title {
  margin: 4px 0 8px;
  font-size: 17px;
}
.reply-picks {
  margin: 6px 0 10px;
}
.reply-picks .chips {
  margin-top: 4px;
}
.reply-quote {
  max-height: 22vh;
  font-size: 13px;
  opacity: 0.85;
}
.att-list {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
}
.att-list li {
  padding: 3px 0;
  overflow-wrap: anywhere;
}
.att-list li::before {
  content: "📎";
  margin-right: 6px;
}
.att {
  font-weight: 600;
}
.att-meta {
  margin-left: 8px;
}
.att-blocked {
  color: var(--muted);
  text-decoration: line-through;
}
a.badge {
  text-decoration: none;
}

/* pay */
.period-detail {
  margin-top: 10px;
  border-top: 1px solid var(--line);
}
.period-tech {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.period-tech-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}
.lines-table-wrap {
  overflow-x: auto;
}
.table {
  border-collapse: collapse;
  width: 100%;
  font-size: 14px;
}
.table th,
.table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  white-space: nowrap;
}
.table th.num,
.table td.num {
  text-align: right;
}
.table thead th {
  color: var(--muted);
  font-weight: 600;
}

/* A/R */
.subhead {
  margin: 14px 0 6px;
  font-size: 15px;
}
.line.inv {
  grid-template-columns: 1fr 70px 100px 90px auto;
}
@media (max-width: 700px) {
  .line.inv {
    grid-template-columns: 1fr 1fr;
  }
}
.ellipsis {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row-tools .linkbtn {
  margin-right: 8px;
}
.alloc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 6px 0;
}
.alloc-input {
  width: 110px;
  min-height: 36px;
  padding: 4px 8px;
  text-align: right;
}
.bad {
  color: var(--danger);
  font-weight: 600;
}

/* Hayward request card (mailbox) */
.request-card {
  border: 1px solid #ddd6fe;
  background: #faf8ff;
  border-radius: 10px;
  padding: 10px 12px;
  margin: 10px 0;
}
.request-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.choices {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.choices .check {
  align-items: flex-start;
}
.choices .check input {
  margin-top: 2px;
  flex: none;
}

/* history: line items */
.hist-lines {
  border-top: 1px solid var(--line);
  padding-top: 8px;
  margin-top: 4px;
}
.hist-line {
  padding: 4px 0;
  font-size: 14px;
}

/* blocking overlay */
.block {
  position: fixed;
  inset: 0;
  background: rgba(16, 24, 40, 0.7);
  display: grid;
  place-items: center;
  z-index: 100;
  padding: 20px;
}
.block-box {
  background: var(--card);
  border-radius: var(--radius);
  padding: 24px;
  max-width: 420px;
  text-align: center;
}

/* bulk selection (jobs board, planner) */
.head-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.select-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  margin: 4px 0 8px;
}
.row-check {
  display: flex;
  align-items: center;
  align-self: stretch;
  padding: 0 2px 0 4px;
  cursor: pointer;
}
.row-check input,
.pick input {
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--accent);
}
.row-selected {
  background: #e0f2fe;
  border-radius: 8px;
}
.bulkbar {
  position: sticky;
  bottom: calc(var(--nav-h) + 8px + env(safe-area-inset-bottom));
  z-index: 6;
  display: grid;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 -6px 20px rgba(16, 24, 40, 0.14);
}
@media (min-width: 700px) {
  .bulkbar {
    bottom: 8px;
  }
}
.bulkbar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.bulkbar-label {
  width: 40px;
  font-size: 13px;
  color: var(--muted);
}
.bulkbar .btn {
  min-height: 38px;
  padding: 6px 12px;
}
.bulk-date {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}
.bulk-date input {
  width: auto;
  min-height: 38px;
  padding: 4px 6px;
}
.pick {
  display: flex;
  align-items: center;
  padding-right: 4px;
}

/* planner pins: tech tag in the pin, stop number in the corner, hollow = unscheduled */
.pin-job {
  position: relative;
}
.pin-seq {
  position: absolute;
  top: -7px;
  right: -8px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 8px;
  background: #fff;
  color: #1f2933;
  border: 1px solid #1f2933;
  font-size: 10px;
  line-height: 14px;
  text-align: center;
}
.pin-pending {
  background: #fff;
  border: 2px dashed #9aa4b2;
  color: #5f6b7a;
}
/* Not ready to go out (web/shared/job-ready.js): yellow with "!", ringed in the tech's colour. */
.pin.pin-held {
  background: #facc15;
  color: #1f2937;
  border: 2px solid #9aa4b2;
  font-weight: 800;
}
.map-card-held {
  margin-top: 4px;
  padding: 4px 6px;
  border-radius: 6px;
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  font-size: 12px;
}
.held-box {
  margin: 8px 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  box-shadow: inset 4px 0 0 #facc15;
}
/* A customer-pay job missing something: flagged only, so a lighter box. */
.held-box.flag-box {
  background: none;
}
/* "Keep the old parts: Hayward wants them back" (web/app/ui/parts-return.js): red edge, so it's never missed. */
.held-box.parts-back-box {
  box-shadow: inset 4px 0 0 var(--danger);
}
.held-box.parts-back-box b {
  color: var(--danger);
}
.check.parts-check {
  margin: 4px 0;
}
.row.row-held-job {
  background: var(--warn-bg);
  box-shadow: inset 4px 0 0 #facc15;
}
.row-held b {
  color: #b45309;
}
/* "CJ1", "A12": a pill instead of a circle. */
.pin.pin-wide {
  width: auto;
  min-width: 26px;
  padding: 0 5px;
  border-radius: 13px;
  font-size: 11px;
  white-space: nowrap;
}
.pin.sel {
  transform: scale(1.3);
  box-shadow: 0 0 0 3px #111827, 0 1px 6px rgba(0, 0, 0, 0.4);
  z-index: 3;
}
.pin-mini {
  width: 22px;
  height: 22px;
  font-size: 10px;
  border-width: 2px;
  box-shadow: none;
  cursor: default;
  flex: none;
}
.map-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: center;
  margin: -4px 0 6px;
  font-size: 14px;
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.legend-line {
  width: 22px;
  border-top: 3px dashed #334155;
}
.split-label {
  padding: 2px 8px;
  border-radius: 10px;
  border: 2px solid #334155;
  background: rgba(255, 255, 255, 0.92);
  color: #1f2933;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  pointer-events: none;
}

/* Fit the phone screen: nothing may make the page wider than the device. On Android Chrome a
   single too-wide element also stretches every full-screen overlay (the camera's Done button
   ended up off-screen), so clip at the root and let rows wrap instead. */
/* Clip the content area, not <html>: overflow on the root breaks position:fixed on iPhone
   Safari (the bottom nav scrolled away with the page). clip (unlike hidden) doesn't make .main a
   scroll container, so the sticky bulk bar keeps working. */
.main {
  overflow-x: clip;
  min-width: 0;
}
.page-head,
.form-actions,
.datenav {
  flex-wrap: wrap;
}
.datenav input {
  flex: 1 1 130px;
  min-width: 0;
}
.row-title,
.row-sub,
.kv td,
.pre,
.card p,
.badge {
  overflow-wrap: anywhere;
}
.camera {
  width: 100%;
}
.camera-bar {
  gap: 8px;
  padding-left: 12px;
  padding-right: 12px;
}
.camera-link {
  flex: 1 1 0;
  min-width: 0;
}
.camera-shutter {
  flex: none;
}
.camera-done {
  font-size: 17px;
}
.big-number {
  font-size: 28px;
  font-weight: 700;
  margin: 4px 0 8px;
}
.tab-count {
  display: inline-block;
  min-width: 20px;
  padding: 0 6px;
  margin-left: 2px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.08);
  font-size: 12px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}
.tab.on .tab-count {
  background: rgba(255, 255, 255, 0.25);
}
.empty .btn {
  margin: 4px;
}
.select-day {
  margin-left: 4px;
}
.plan-col-head .linkbtn {
  margin-left: auto;
}

/* jobs map (Jobs page, Map view) */
.jobs-map {
  height: 60vh;
  min-height: 320px;
}
.pin-day {
  position: absolute;
  left: 50%;
  bottom: -15px;
  transform: translateX(-50%);
  padding: 0 4px;
  border-radius: 6px;
  background: #fff;
  color: #1f2933;
  border: 1px solid #1f2933;
  font-size: 9px;
  font-weight: 700;
  line-height: 12px;
  white-space: nowrap;
}
/* An estimate's pin (owner, 2026-10-05): "Est" above it, in the estimate badge's teal. */
.pin-est {
  position: absolute;
  left: 50%;
  top: -14px;
  transform: translateX(-50%);
  padding: 0 4px;
  border-radius: 6px;
  background: #ccfbf1;
  color: #115e59;
  border: 1px solid #115e59;
  font-size: 9px;
  font-weight: 700;
  line-height: 11px;
  white-space: nowrap;
}
.pin-dim {
  opacity: 0.45;
}
.map-card {
  display: grid;
  gap: 4px;
  font-size: 13px;
  color: #1f2933;
}
.map-card .btn {
  justify-self: start;
  margin-top: 4px;
}
.reach-label {
  border-color: #ea580c;
  color: #c2410c;
  font-weight: 700;
}
.legend-reach {
  border-top: 4px solid #ea580c;
}
.seg-small .seg-btn {
  min-height: 38px;
  padding: 6px 12px;
}
.photo-kind {
  max-width: calc(100% - 12px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  margin-top: 4px;
}
.map-card-row input[type="date"] {
  width: auto;
  min-height: 34px;
  padding: 2px 6px;
  font-size: 13px;
}
.map-card {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.tech-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.tech-switch select {
  width: auto;
  min-height: 38px;
  padding: 4px 8px;
}
.map-card-row select {
  width: auto;
  min-height: 34px;
  padding: 2px 6px;
  font-size: 13px;
}
.subhead {
  font-size: 15px;
  margin: 16px 0 4px;
}
.viewbar {
  background: #1e3a8a;
  color: #fff;
  font-size: 13px;
  text-align: center;
  padding: 6px 10px;
}
.viewbar button {
  margin-left: 8px;
  border: 1px solid #fff;
  background: transparent;
  color: #fff;
  border-radius: 8px;
  padding: 2px 10px;
  font: inherit;
  cursor: pointer;
}

/* Jobs, Map view on a phone: everything on one screen (owner, 2026-09-25). The map takes the
   height that's left between the header/filters and the bottom menu; the legend is one strip
   that scrolls sideways; the explanation line is left to the legend. */
@media (max-width: 700px) {
  .jobs-mapview .page-head {
    flex-wrap: nowrap;
    gap: 6px;
  }
  .jobs-mapview .page-title {
    font-size: 22px;
    margin: 0;
  }
  .jobs-mapview .head-actions {
    flex-wrap: nowrap;
    gap: 6px;
  }
  .jobs-mapview .head-actions .btn,
  .jobs-mapview .seg-small .seg-btn {
    min-height: 36px;
    padding: 4px 10px;
    font-size: 15px;
  }
  .jobs-mapview .map-help {
    display: none;
  }
  .jobs-mapview .search {
    margin: 8px 0;
  }
  .jobs-mapview .search input,
  .jobs-mapview .search select {
    min-height: 40px;
  }
  .jobs-mapview .jobs-map {
    /* screen - top bar - title row - filters - page padding (222 in all) - bottom menu */
    height: calc(100vh - 222px - var(--nav-h) - env(safe-area-inset-bottom));
    height: calc(100dvh - 222px - var(--nav-h) - env(safe-area-inset-bottom));
    min-height: 260px;
    margin-bottom: 6px;
  }
}
.map-legend.compact {
  flex-wrap: nowrap;
  overflow-x: auto;
  white-space: nowrap;
  font-size: 13px;
  gap: 4px 14px;
  margin: 0;
  padding-bottom: 2px;
  scrollbar-width: none;
}
.map-legend.compact::-webkit-scrollbar {
  display: none;
}
.map-legend.compact .pin-mini {
  width: 20px;
  height: 20px;
  font-size: 9px;
}

/* Map card: compact so the day buttons, tech picker and Open job fit above the pin on a phone. */
.map-card {
  gap: 2px;
  font-size: 13px;
  line-height: 1.3;
}
.map-card b {
  font-size: 14px;
}
.map-card .btn,
.map-card .btn-small {
  min-height: 32px;
  padding: 3px 9px;
  font-size: 13px;
  margin-top: 0;
}
.map-card-row {
  gap: 4px;
  margin-top: 5px;
}
.map-card-row input[type="date"] {
  min-height: 32px;
  max-width: 132px;
  padding: 2px 4px;
  font-size: 13px;
}
.map-card-row select {
  min-height: 32px;
  max-width: 120px;
  padding: 2px 4px;
  font-size: 13px;
}
.maplibregl-popup-content {
  padding: 10px 12px 8px;
}

/* Dark mode (Settings -> Appearance, saved on this device; web/index.html applies it before the
   page draws). The map switches to OpenFreeMap's dark style (web/app/ui/jobmap.js). */
:root[data-theme="dark"] {
  --accent: #22a3c4;
  --accent-dark: #67c8e0;
  --bg: #0f1418;
  --card: #182028;
  --text: #e6ebf0;
  --muted: #9aa7b4;
  --line: #2c3845;
  --danger: #f97066;
  --warn-bg: #3a2e12;
  --warn-line: #8a6d24;
  color-scheme: dark;
}
[data-theme="dark"] body {
  background: var(--bg);
  color: var(--text);
}
[data-theme="dark"] code {
  background: #243040;
}
[data-theme="dark"] .errorbox {
  background: #3a1c1a;
  color: #fecaca;
}
[data-theme="dark"] .badge,
[data-theme="dark"] .chip,
[data-theme="dark"] .photo-thumb {
  background: #243040;
  color: var(--text);
}
[data-theme="dark"] .badge-warn,
[data-theme="dark"] .badge-owed {
  background: #4a3b12;
  color: #fde68a;
}
[data-theme="dark"] .badge-ok {
  background: #12382c;
  color: #6ee7b7;
}
[data-theme="dark"] .badge-bad {
  background: #4a1d1d;
  color: #fca5a5;
}
[data-theme="dark"] .badge-info {
  background: #1e2f4f;
  color: #93c5fd;
}
[data-theme="dark"] .badge-purple {
  background: #2e2350;
  color: #c4b5fd;
}
[data-theme="dark"] .badge-estimate {
  background: #12393a;
  color: #5eead4;
}
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea {
  background: #111820;
  color: var(--text);
  border-color: var(--line);
}
[data-theme="dark"] .btn-danger,
[data-theme="dark"] .hist-item,
[data-theme="dark"] .hist-mode,
[data-theme="dark"] .seg-btn,
[data-theme="dark"] .picker-item,
[data-theme="dark"] .billbtn,
[data-theme="dark"] .plan-stop {
  background: var(--card);
  color: var(--text);
}
[data-theme="dark"] .seg-btn.on {
  background: var(--accent);
  color: #fff;
}
[data-theme="dark"] .picker-item:hover,
[data-theme="dark"] .plan-col-none,
[data-theme="dark"] .line,
[data-theme="dark"] .mailtext {
  background: #141b22;
}
[data-theme="dark"] .hist-row.changed,
[data-theme="dark"] .plan-stop.locked {
  background: #2e2710;
}
[data-theme="dark"] .hist-old {
  background: #3a1c1c;
}
[data-theme="dark"] .hist-new {
  background: #12301f;
}
[data-theme="dark"] .line.warranty,
[data-theme="dark"] .billbtn.warranty,
[data-theme="dark"] .request-card {
  background: #221c33;
}
[data-theme="dark"] .row-selected {
  background: #12324a;
}
[data-theme="dark"] .bottomnav,
[data-theme="dark"] .topbar {
  background: var(--card);
  border-color: var(--line);
}
[data-theme="dark"] .maplibregl-popup-content {
  background: var(--card);
  color: var(--text);
}
[data-theme="dark"] .maplibregl-popup-anchor-bottom .maplibregl-popup-tip {
  border-top-color: var(--card);
}
[data-theme="dark"] .maplibregl-popup-anchor-top .maplibregl-popup-tip {
  border-bottom-color: var(--card);
}
[data-theme="dark"] .maplibregl-popup-close-button {
  color: var(--text);
}
[data-theme="dark"] .map-card {
  color: var(--text);
}
[data-theme="dark"] .picker-item:hover {
  background: #202a35;
}
[data-theme="dark"] .part-sug-item.on {
  background: #12324a;
}
[data-theme="dark"] .line-note.warranty {
  color: #c4b5fd;
}

/* Customers | Warranty switch at the top of both lists (they share the Customers tab). */
.section-switch {
  flex: 1 1 180px;
  max-width: 360px;
}
.section-switch .seg-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  white-space: nowrap;
}
[data-theme="dark"] .jobs-map {
  background: #364250;
}

/* Customers list as a table like Mini AR's (owner, 2026-09-29): customer, contact, last service,
   latest email, invoices and amount owed (office). Phones: stacked, amount on the right. */
.cust-table { padding: 0; overflow: hidden; }
.cust-row {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 2fr);
  gap: 14px;
  align-items: center;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
}
.cust-row.office { grid-template-columns: minmax(0, 2fr) minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
.cust-row:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.cust-row > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cust-row small, .cust-row .clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cust-row small { color: var(--muted); font-size: 13px; }
.cust-row b { font-weight: 700; }
.cust-row .num { align-items: flex-end; text-align: right; }
.cust-row .num .badge { align-self: flex-end; }
.cust-row .owed { color: var(--danger); font-weight: 700; }
.cust-row .cust-owed:not(.owed) { color: var(--muted); }
/* The lists' column headers only: "cust-head" is also the customer page's top card (it was hidden on phones). */
.cust-row.cust-head { border-top: 0; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.cust-row.cust-head:hover { background: none; }
.row-extra { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 760px) {
  .cust-row.cust-head { display: none; }
  .cust-row, .cust-row.office { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 12px 14px; }
  .cust-row > span { grid-column: 1; }
  .cust-row .cust-owed { grid-column: 2; grid-row: 1; }
  .cust-row .cust-inv { grid-column: 2; grid-row: 2; }
  .cust-row .cust-contact, .cust-row .cust-service { flex-direction: row; gap: 8px; }
}
/* The customers table gets the room Mini AR's list has on a computer screen. */
.main:has(.cust-table) { max-width: 1280px; }
/* The Warranty view (ui/warranty-list.js): name and status are links of their own, not the whole row. */
.cust-row.warranty { grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1.3fr) minmax(0, 1.3fr) minmax(0, 0.9fr); }
.cust-row > a { display: flex; flex-direction: column; gap: 2px; min-width: 0; color: inherit; text-decoration: none; }
.cust-row > a:hover b, .cust-row > a:hover small { text-decoration: underline; }
.cust-row .cust-status .badge { align-self: flex-start; }
@media (max-width: 760px) {
  .cust-row.warranty { grid-template-columns: minmax(0, 1fr) auto; }
  .cust-row.warranty > * { grid-column: 1; }
  .cust-row.warranty .cust-status { grid-column: 2; grid-row: 1; align-items: flex-end; }
  .cust-row.warranty .cust-status .badge { align-self: flex-end; }
  .cust-row.warranty .cust-claims { grid-column: 2; grid-row: 2; }
  .cust-row .cust-last { display: block; }
  .cust-row .cust-last::before { content: "Last action: "; color: var(--muted); }
}
@media (max-width: 760px) {
  .cust-row .dash { display: none; }
  .cust-row .svc::before { content: "Last service "; color: var(--muted); }
  .cust-row .cust-service, .cust-row .cust-mail { font-size: 14px; }
}

/* Setup uploads (Settings): photos of forms waiting to be set up. */
.setup-form { display: grid; gap: 8px; margin-bottom: 12px; }
.setup-row { align-items: flex-start; }
.setup-thumb { flex: none; width: 64px; height: 64px; padding: 0; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--bg); cursor: pointer; }
.setup-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.setup-pdf { display: flex; align-items: center; justify-content: center; height: 100%; font-weight: 700; color: var(--muted); }
.setup-row { cursor: pointer; }
.setup-thumb { position: relative; }
.setup-picked, .setup-gallery { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 8px; }
.setup-gallery .setup-thumb { width: 96px; height: 96px; }
.setup-remove { position: absolute; top: 2px; right: 2px; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; line-height: 22px; cursor: pointer; }
.setup-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.setup-desc, .setup-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.setup-clip { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.setup-thread { list-style: none; padding: 0; margin: 0 0 10px; display: grid; gap: 8px; }
.setup-thread li { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; }
.setup-thread li.from-claude { border-left: 3px solid var(--accent, #2563eb); }
.setup-finished summary { cursor: pointer; margin: 12px 0 6px; color: var(--muted); }
/* Waiting on an answer to Claude's question (setup_tickets.needs_reply_at): red in the lists and the thread. */
.setup-row.needs-reply { box-shadow: inset 3px 0 0 var(--danger); }
.setup-needs-reply { font-weight: 700; }
.setup-thread li.needs-reply { border: 2px solid var(--danger); background: #fef2f2; }
[data-theme="dark"] .setup-thread li.needs-reply { background: #3a1717; }
.setup-asked { color: var(--danger); font-weight: 700; font-size: 0.85em; margin-bottom: 2px; }
/* "Needs you" group and the search box over tickets (owner, 2026-10-13). */
.setup-search { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.setup-search input { flex: 1; min-width: 0; width: 100%; font-size: 16px; }
.setup-count { margin: 0 0 4px; }
.setup-needs-you-h { color: var(--danger); }
.setup-row.needs-you { box-shadow: inset 3px 0 0 var(--danger); }
/* Held until someone replies on their What's-new ticket (migration 0085), and the button to it once released. */
.setup-held { background: var(--warn-bg); border: 1px solid var(--warn-line); white-space: normal; }
.setup-holds { margin: 0 0 10px; }
.setup-released { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 8px 10px; border: 2px solid var(--accent, #2563eb); border-radius: 8px; }

/* "Same customer in Mini AR?" folds its list away so Settings stays short. */
.link-list > summary { cursor: pointer; font-weight: 600; padding: 6px 0; }
.link-list > summary::marker { color: var(--muted); }
.link-list[open] > summary { margin-bottom: 6px; }

/* Setup tickets from the name menu: the "what they were doing" trail and the name menu itself. */
.setup-share { display: flex; gap: 8px; align-items: flex-start; font-size: 14px; color: var(--muted); }
/* Not the full-width text-box size every input gets: that squeezed the label into one letter a line. */
.setup-share input { flex: none; width: 22px; height: 22px; min-height: 0; margin-top: 1px; }
.setup-trail { margin: 8px 0; }
.setup-trail summary { cursor: pointer; font-weight: 600; }
.setup-trail ol { list-style: none; padding: 0; margin: 6px 0; max-height: 320px; overflow: auto; font-size: 13px; border: 1px solid var(--line); border-radius: 8px; }
.setup-trail li { display: grid; grid-template-columns: 88px 1fr; gap: 8px; padding: 4px 8px; border-top: 1px solid var(--line); overflow-wrap: anywhere; }
.setup-trail li:first-child { border-top: 0; }
.setup-trail li.bad { background: color-mix(in srgb, #dc2626 10%, transparent); }
.user-menu { position: relative; }
.user-menu > button.topbar-user { background: none; border: 0; padding: 6px 8px; margin: -6px -8px; border-radius: 8px; cursor: pointer; font: inherit; }
.user-menu > button.topbar-user:hover, .user-menu > button.topbar-user[aria-expanded="true"] { background: var(--bg); color: var(--text); }
.user-menu-pop { position: absolute; right: 0; top: calc(100% + 8px); z-index: 50; min-width: 240px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.15); padding: 6px; display: grid; }
.user-menu-pop .who { padding: 6px 10px 8px; border-bottom: 1px solid var(--line); margin-bottom: 4px; font-size: 13px; color: var(--muted); overflow-wrap: anywhere; }
.user-menu-pop button, .user-menu-pop a { text-align: left; background: none; border: 0; padding: 10px; border-radius: 8px; font: inherit; color: inherit; cursor: pointer; text-decoration: none; }
.user-menu-pop button:hover, .user-menu-pop a:hover { background: var(--bg); }

/* Settings → "Same house twice?": each address with its history and a Keep button. */
.samehouse .row-main { width: 100%; }
.samehouse-opt { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0; border-top: 1px dashed var(--line); }
.samehouse-opt:first-of-type { margin-top: 6px; }

/* A claim's pending-denial row: something to answer, by a date. */
.kv tr.warn-row th, .kv tr.warn-row td { background: var(--warn-bg); }

/* Hayward's claim form on the job (web/app/ui/hayward-form.js) */
.row-stack { flex-direction: column; align-items: stretch; }
.hf { margin-top: 8px; border-top: 1px solid var(--line, #e5e5e5); padding-top: 8px; }
.hf-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 6px; }
/* min-width 0: a fieldset is as wide as its widest dropdown by default, which ran section 4 off a
   phone; Hayward's long problem codes wrap instead of running off it too. */
.hf-section { border: 1px solid var(--line, #e5e5e5); border-radius: 8px; padding: 8px 12px; margin: 8px 0; min-width: 0; }
.hf-section legend { font-weight: 600; padding: 0 4px; }
.hf-section .chip { white-space: normal; }
.hf-field { margin: 6px 0; }
.hf-field input[type="text"], .hf-field input[type="date"], .hf-field select, .hf-field textarea { width: 100%; max-width: 480px; }
.hf-field .addr-box { width: 100%; max-width: 480px; }
.hf-field .addr-box input { width: 100%; }
.hf-pick { display: flex; flex-wrap: wrap; gap: 6px; }
.hf-pick select { flex: 1 1 200px; min-width: 0; }
.hf-pick input { flex: 1 1 160px; min-width: 0; }
.hf-parts td input[type="text"] { width: 100%; }
/* The parts rows on a phone (CJ's ticket, 2026-10-01): the quantity box was 26px wide with 24px of
   padding, so its "1" and anything typed were hidden; 16px text so an iPhone doesn't zoom in on a tap
   (it does under 16px, and the table is 14px); a Replace box big enough for a thumb. */
.hf-parts th, .hf-parts td { padding: 6px 4px; }
.hf-parts input { font-size: 16px; }
.hf-parts td input.hf-qty { width: 3.2em; min-width: 48px; padding: 8px 4px; text-align: center; }
.hf-parts th:last-child, .hf-parts td:last-child { text-align: center; }
.hf-parts input[type="checkbox"] { width: 24px; height: 24px; margin: 0; vertical-align: middle; }
/* The part rows' suggestions (web/app/ui/claim-parts.js, owner 2026-10-07): "Likely parts" chips above the table, and
   the matches for the box being typed in as a full-width row under it (a dropdown in a narrow cell ran off a phone). */
.cp { min-width: 0; }
.cp-likely { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 6px; }
.cp-chip { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px; min-height: 40px; padding: 6px 10px; text-align: left; cursor: pointer; }
.cp-why { font-size: 12px; opacity: 0.75; }
.hf-parts tr.cp-sug-row > td { padding: 0 4px 6px; }
.cp-sug { display: flex; flex-direction: column; border: 1px solid var(--line, #d0d7de); border-radius: 8px; overflow: hidden; background: var(--card, #fff); box-shadow: 0 6px 18px rgba(15, 23, 42, 0.12); }
.cp-sug-item { display: flex; flex-direction: column; gap: 2px; min-height: 48px; padding: 8px 12px; border: 0; border-top: 1px solid var(--line, #e5e7eb); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cp-sug-item:first-child { border-top: 0; }
.cp-sug-item:hover, .cp-sug-item:focus { background: #e0f2fe; }
[data-theme="dark"] .cp-sug-item:hover, [data-theme="dark"] .cp-sug-item:focus { background: rgba(56, 189, 248, 0.18); }
.cp-sug-item b { overflow-wrap: anywhere; }
.cp-source { margin: 2px 0 0; }
.hf-warn { margin: 6px 0; padding-left: 20px; color: var(--warn-text, #8a5a00); }
/* Pick-one fields (type of repair, bought, installed by a pro, gas) as the app's slide tabs, the `.seg`
   of Jobs' List | Map, not radio buttons (CJ's ticket, 2026-10-01). As wide as the text boxes; a line
   between tabs so "Yes | No" with neither picked still reads as two; a long name wraps in its tab.
   Dark mode comes with .seg-btn's own [data-theme="dark"] rules. */
.hf-seg { max-width: 480px; }
.hf-seg .seg-btn { padding: 6px 10px; line-height: 1.2; }
.hf-seg .seg-btn + .seg-btn { border-left: 1px solid var(--line); }
.hf-seg .seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
/* Photos for the claim (web/app/ui/claim-photos.js, CJ's ticket 2026-10-01): the job's photo tiles with a
   round tick in the corner, big enough for a thumb, showing the pick's number; a picked tile is ringed. */
.cp-group { margin: 8px 0 4px; font-size: 13px; font-weight: 600; color: var(--muted); }
.cp-tile { position: relative; }
.cp-tile .cp-thumb { width: 100%; display: block; }
.cp-tile.on .cp-thumb { outline: 3px solid var(--accent); outline-offset: -3px; }
.cp-tile .photo-kind { max-width: calc(100% - 12px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-tick { position: absolute; top: 4px; right: 4px; width: 40px; height: 40px; padding: 0; border-radius: 50%; border: 2px solid #fff; background: rgba(0, 0, 0, .35); color: #fff; font-size: 16px; font-weight: 700; line-height: 1; display: grid; place-items: center; cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, .45); }
.cp-tick[aria-pressed="true"] { background: var(--accent); }
.cp-tick:disabled { cursor: default; }
.cp-tick:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.cp-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 10px; }
.cp-bar .btn { margin-left: auto; }
/* Photos at the house (web/app/ui/house-photos.js, owner 2026-10-01): the house's earlier photos folded
   under the job's, and a photo a claim already sent to Hayward greyed with a "Used: claim W…" badge. */
.house-photos { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 6px; }
.house-photos > summary { cursor: pointer; padding: 8px 0; font-weight: 600; min-height: 32px; }
.house-photos .badge { margin-left: 6px; font-weight: 500; }
.house-group + .house-group { margin-top: 6px; }
.photo-thumb.is-used img, .cp-tile.is-used:not(.on) .cp-thumb img { opacity: .45; filter: grayscale(.8); }
.photo-used { position: absolute; left: 4px; right: 4px; top: 4px; background: #9a3412; color: #fff; font-size: 11px; font-weight: 600; line-height: 1.25; padding: 2px 6px; border-radius: 6px; text-align: left; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.cp-tile .photo-used { right: 48px; -webkit-line-clamp: 3; }
/* The claim's photo picker (2026-10-06): each photo's label read under it, and where it came from. */
.cp-read { margin-top: 3px; font-size: 12px; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.cp-whence { font-size: 11px; line-height: 1.25; overflow-wrap: anywhere; }
.cp-also { color: var(--warn-text, #9a3412); }
.cp-read-big { margin: 6px 0; overflow-wrap: anywhere; }
.cc-pick { margin: 6px 0 10px; }
.photo-used-line { margin: 6px 0; padding: 6px 10px; border-radius: 8px; background: var(--warn-bg); border: 1px solid var(--warn-line); font-weight: 600; }

/* Settings → Go-live (web/app/pages/golive.js): live reconcile counts and the checklist, each line opens. */
.golive-sec { margin: 14px 0 2px; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.golive > details { border-top: 1px solid var(--line); }
.golive > details > summary { display: flex; align-items: center; gap: 8px; padding: 10px 0; cursor: pointer; list-style: none; }
.golive > details > summary::-webkit-details-marker { display: none; }
.golive > details > summary .t { flex: 1; min-width: 0; font-weight: 600; }
.golive summary .t small { display: block; font-weight: 400; font-size: 13px; color: var(--muted); }
.golive .caret::before { content: "▸"; color: var(--muted); display: inline-block; width: 1em; transition: transform .15s; }
.golive details[open] > summary > .caret::before { transform: rotate(90deg); }
.golive .who { font-size: 12px; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; white-space: nowrap; }
.golive .n { min-width: 2.4em; text-align: center; }
.golive .body { padding: 0 0 12px 1.4em; }
.golive .addr { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: 8px 0; }
.golive .addr .chips { margin-top: 8px; }
.golive .addr-pick { margin-top: 8px; display: grid; gap: 6px; }
.golive .pair-people { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px; margin: 8px 0; }
.golive .pair-people .person { border-left: 3px solid var(--line); padding-left: 8px; min-width: 0; overflow-wrap: anywhere; }
.golive .check { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; border-top: 1px dashed var(--line); }
.golive .check input[type="checkbox"] { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.golive .check .t { font-weight: 600; }
.golive .check summary { cursor: pointer; }
.golive .check.done .t { text-decoration: line-through; color: var(--muted); font-weight: 500; }
/* Go-live → Questions (2026-10-12): filter chips, the answer under each question, its history. */
.golive .golive-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.golive .golive-filter .chip { border: 1px solid var(--line); cursor: pointer; padding: 6px 12px; min-height: 36px; font: inherit; font-size: 14px; color: var(--text); }
.golive .golive-filter .chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.golive .golive-q { border-top: 1px solid var(--line); }
.golive .golive-q > summary { display: flex; align-items: center; gap: 8px; padding: 10px 0; cursor: pointer; list-style: none; }
.golive .golive-q > summary::-webkit-details-marker { display: none; }
.golive .golive-q > summary .t { flex: 1; min-width: 0; font-weight: 600; }
.golive .golive-q[open] > summary > .caret::before { transform: rotate(90deg); }
.golive .golive-answer { margin-top: 6px; min-width: 0; }
.golive .golive-answer .a-text { white-space: pre-wrap; overflow-wrap: anywhere; border-left: 3px solid var(--accent); padding: 2px 0 2px 8px; }
.golive .golive-answer textarea { font-size: 16px; min-height: 80px; resize: vertical; }
.golive .golive-history { margin-top: 6px; overflow-wrap: anywhere; }
.golive .row-main { min-width: 0; flex: 1; }
.golive button.linkish { background: none; border: 0; padding: 4px 0; color: var(--accent); font: inherit; font-size: 14px; cursor: pointer; text-decoration: underline; }
/* The merged questions (2026-10-12): context, suggested default, the items each covers; dropped items
   greyed; "Ready to tick" badges; "What we did" lines. */
.golive .golive-merged { padding: 10px 0; border-top: 1px dashed var(--line); min-width: 0; overflow-wrap: anywhere; }
.golive .golive-merged > .t { font-weight: 600; }
.golive .golive-merged .suggested { margin-top: 4px; }
.golive .golive-covers { margin: 6px 0 0; padding-left: 8px; border-left: 3px solid var(--line); }
.golive .golive-covers label { display: flex; gap: 8px; align-items: flex-start; padding: 3px 0; font-size: 14px; cursor: pointer; }
.golive .golive-covers input[type="checkbox"] { margin-top: 2px; width: 16px; height: 16px; flex: none; }
.golive .golive-covers .done-t { text-decoration: line-through; color: var(--muted); }
.golive .check.dropped .t { color: var(--muted); font-weight: 500; }
.golive .check.dropped { opacity: .75; }
.golive .golive-tag { display: inline-block; margin-top: 4px; padding: 2px 8px; border-radius: 999px; font-size: 13px; border: 1px solid var(--line); color: var(--muted); }
.golive .golive-tag.ready { border-color: var(--warn-line); background: var(--warn-bg); color: var(--text); }
.golive .golive-outcomes { margin-top: 6px; overflow-wrap: anywhere; }
.golive .golive-outcomes .o { border-left: 3px solid #2e9e5b; padding: 2px 0 2px 8px; margin-top: 3px; font-size: 14px; white-space: pre-wrap; }

/* The bell left of the name (web/app/ui/attention.js, owner 2026-10-01): what needs attention, with a
   count badge, red while something urgent or new is waiting. Its list hangs from the top bar's right
   edge (the bar is its containing block), so on a phone it never runs off the left side. */
.topbar-bell { position: relative; display: inline-grid; place-items: center; width: 36px; height: 36px; margin: -4px 0 -4px -4px; border: 0; border-radius: 8px; background: none; font-size: 19px; line-height: 1; cursor: pointer; }
.topbar-bell > span[aria-hidden] { filter: grayscale(1); opacity: .7; }
.topbar-bell:hover, .topbar-bell[aria-expanded="true"] { background: var(--bg); }
.bell-count { position: absolute; top: 0; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--line); color: var(--muted); font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
.bell-count.hot { background: var(--danger); color: #fff; }
[data-theme="dark"] .bell-count.hot { color: #2a0d0b; }
/* Anchored to the top bar's right edge (the bar is the positioned box), never wider than the screen; long lines wrap
   (owner 2026-10-13: "cutoff and needs to be scrolled right… the text isn't wrapping"): the one grid column can't grow
   past the box, and a long W number, address or link breaks anywhere instead of pushing the box sideways. */
.bell-pop { right: 12px; left: auto; top: 100%; min-width: 0; width: min(420px, calc(100vw - 24px)); max-width: calc(100vw - 24px); box-sizing: border-box; grid-template-columns: minmax(0, 1fr); overflow-x: hidden; }
.bell-pop a, .bell-pop button { display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; white-space: normal; }
.bell-label { flex: 1; min-width: 0; white-space: normal; overflow-wrap: anywhere; word-break: normal; }
/* /bell/<key> (web/app/pages/bell-list.js): the actions under each Hayward change. */
.bell-list-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.bell-list-money { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.bell-list .row-title, .bell-list .row-sub { overflow-wrap: anywhere; }
.bell-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); flex: none; }
.bell-dot.urgent { background: var(--danger); }
.bell-new { flex: none; font-size: 12px; font-weight: 600; padding: 0 7px; border-radius: 999px; background: var(--warn-bg); border: 1px solid var(--warn-line); white-space: nowrap; }
.bell-none { margin: 0; padding: 10px; color: var(--muted); }
/* "For your info" (2026-10-13): below the To do lines, grey, never counted in the red number. */
.bell-pop .who.bell-info-head { margin-top: 6px; border-top: 1px solid var(--line); padding-top: 8px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }
.bell-pop .bell-info { color: var(--muted); font-size: 14px; }
.bell-pop { max-height: min(70vh, 560px); overflow-y: auto; overflow-x: hidden; }
/* A card a link scrolls to (Settings → Setup tickets): clear of the sticky bars. */
.anchor { scroll-margin-top: 72px; }
/* The health line at the top of Settings (web/app/ui/health-line.js, owner 2026-10-01): green / amber /
   red, tap to open the details. */
.health-line { --h-bg: var(--card); --h-line: var(--line); background: var(--h-bg); border: 1px solid var(--h-line); border-radius: var(--radius); margin: 0 0 14px; }
.health-line.green { --h-bg: #ecfdf3; --h-line: #75e0a7; }
.health-line.amber { --h-bg: var(--warn-bg); --h-line: var(--warn-line); }
.health-line.red { --h-bg: #fef3f2; --h-line: #f97066; }
[data-theme="dark"] .health-line.green { --h-bg: #10291f; --h-line: #2d6a4f; }
[data-theme="dark"] .health-line.red { --h-bg: #3a1c1a; --h-line: #b42318; }
.health-sum { display: flex; align-items: flex-start; gap: 8px; width: 100%; min-height: 44px; padding: 10px 12px; border: 0; background: none; color: var(--text); font: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.health-sum:disabled { cursor: default; color: var(--muted); font-weight: 500; }
.health-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.health-chev { flex: none; color: var(--muted); }
.health-details { margin: 0 12px 10px; width: calc(100% - 24px); font-size: 14px; }
.health-details td { overflow-wrap: anywhere; }
.health-details tr.h-warn th, .health-details tr.h-warn td { color: #8a5a00; }
.health-details tr.h-bad th, .health-details tr.h-bad td { color: var(--danger); }
[data-theme="dark"] .health-details tr.h-warn th, [data-theme="dark"] .health-details tr.h-warn td { color: #fde68a; }
@media (max-width: 480px) {
  .health-details th { white-space: normal; width: 34%; }
}
/* The job's basics, tap a row to fill it in (Colten's ticket, 2026-10-01; web/app/pages/job.js EditRow). */
.kv-tap { display: flex; align-items: flex-start; gap: 8px; width: 100%; min-height: 32px; cursor: pointer; }
.kv-tap .kv-val { flex: 1; min-width: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
.kv-tap .kv-pen { flex: none; padding: 2px 4px; margin: -2px -4px 0 0; border: 0; background: none; color: var(--accent, #2563eb); font: inherit; font-size: 13px; cursor: pointer; }
.kv-tap:hover .kv-pen, .kv-tap:focus-visible .kv-pen { text-decoration: underline; }
.kv tr.kv-missing th, .kv tr.kv-missing .kv-val { color: #b45309; }
[data-theme="dark"] .kv tr.kv-missing th, [data-theme="dark"] .kv tr.kv-missing .kv-val { color: #fde68a; }
.kv-form { display: flex; flex-direction: column; gap: 6px; }
.kv-form input, .kv-form select, .kv-form textarea { width: 100%; box-sizing: border-box; }
.kv-form .chips { margin: 0; }
/* "What's missing" as buttons (CJ's ticket, 2026-10-01): the job's yellow box and the claim form's red
   "Still needed" list. Thumb-sized; a tap scrolls to the row or field (web/app/ui/jump.js), which
   stops clear of the sticky top bar and flashes yellow for a moment. */
.need-btns { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 6px; }
.need-btn { min-height: 44px; padding: 8px 14px; border-radius: 999px; border: 1px solid #d97706; background: var(--card); color: #92400e; font: inherit; font-weight: 600; text-align: left; cursor: pointer; }
.need-btn:active { transform: scale(0.98); }
.need-btn-plain { display: inline-flex; align-items: center; cursor: default; font-weight: 500; }
.need-btn-bad { border-color: var(--danger); color: var(--danger); }
.need-sec { font-weight: 400; opacity: 0.8; }
[data-theme="dark"] .need-btn { color: #fde68a; border-color: #b45309; }
[data-theme="dark"] .need-btn-bad { color: var(--danger); border-color: var(--danger); }
.hf-needed { margin: 8px 0; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--danger); background: #fef2f2; color: var(--danger); }
.hf-ready { margin: 8px 0; padding: 10px 12px; border-radius: 8px; border: 1px solid #75e0a7; background: #ecfdf3; color: #067647; }
[data-theme="dark"] .hf-needed { background: #3a1616; }
[data-theme="dark"] .hf-ready { background: #0f2e1f; border-color: #2f7d55; color: #75e0a7; }
.hf-field.hf-need { outline: 2px solid var(--danger); outline-offset: 4px; border-radius: 4px; }
.hf-need-tag { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 999px; background: var(--danger); color: #fff; font-size: 12px; font-weight: 600; }
.jump-target { scroll-margin-top: 80px; scroll-margin-bottom: 24px; }
.jump-flash { animation: jump-flash 1.8s ease-out; }
@keyframes jump-flash { 0%, 40% { background-color: rgba(250, 204, 21, 0.45); } 100% { background-color: transparent; } }
@media (prefers-reduced-motion: reduce) { .jump-flash { animation: none; background-color: rgba(250, 204, 21, 0.3); } }
/* Money box on a customer's page and Owes/Paid per job (CJ's ticket, 2026-10-01; web/app/ui/job-money.js). */
.money-big { font-size: 24px; font-weight: 800; margin: 2px 0 4px; }
.money-big.owes { color: var(--danger); }
.money-big.paid { color: #047857; }
[data-theme="dark"] .money-big.paid { color: #6ee7b7; }
.money-sums { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 6px 0; }
.money-sums b { font-variant-numeric: tabular-nums; }
.row-side .money-tag { white-space: nowrap; }
/* New job's "Already open here?" (2026-10-05, web/app/ui/open-here.js): a notice inside the form's own spacing. */
.notice.open-here { margin: 0; display: flex; flex-direction: column; gap: 4px; }
/* Billing (owner, 2026-10-05; web/app/pages/billing.js): To bill · Billed · Paid side by side on a computer,
   one at a time on a phone (the pills pick it); the job page's "Work done → Billed → Paid" (web/app/ui/bill-stage.js). */
.main:has(.bill-board) { max-width: 1280px; }
.bill-cols { display: grid; gap: 14px; align-items: start; }
.bill-col { display: none; }
.bill-type { flex: none; }
.bill-type .seg-btn { white-space: nowrap; }
.bill-col.on { display: block; }
@media (min-width: 900px) {
  .bill-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .bill-col { display: block; }
  .bill-tabs { display: none; }
}
.bill-row { align-items: flex-start; }
.bill-row .row-side { max-width: 45%; text-align: right; }
.bill-row .row-side b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.bill-steps { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
.bill-step { color: var(--muted); }
.bill-step.done { color: var(--text); }
.bill-step.now { color: var(--accent-dark); font-weight: 700; }
.bill-arrow { color: var(--muted); }
@media (max-width: 700px) {
  .jobs-mapview .bill-link { display: none; } /* the map's one-line header on a phone has no room; the list view shows it */
}
/* Ready to file (owner, 2026-10-05; web/app/ui/claim-ready.js): the checklist on the claim form and the job
   page (the .hf-needed / .hf-ready boxes), the board's chip and filter, the claim photos' "This photo shows". */
.ready-box .need-btns { margin-bottom: 4px; }
.ready-list { margin: 6px 0 4px; padding-left: 20px; }
.ready-list li { margin: 2px 0; }
.ready-list .ready-wait { color: var(--muted); }
.ready-ok { display: flex; flex-wrap: wrap; gap: 2px 12px; margin-top: 6px; color: var(--muted); }
.hf-ready .ready-ok { color: inherit; opacity: .85; }
.ready-chip { max-width: 100%; white-space: normal; text-align: left; }
.bill-ready-filter { margin: 0 0 10px; }
.bill-outside .past-toggle { margin: 0; }
.photo-kind.photo-shows { background: rgba(6, 118, 71, .85); font-weight: 600; }
.cp-shows { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 8px 0; }
.cp-shows .seg-btn { white-space: nowrap; }
/* The claim checklist at Work done (owner, 2026-10-05; web/app/ui/claim-checklist.js), in CompleteModal. */
.cc { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 4px; padding-top: 12px; border-top: 1px solid var(--line); min-width: 0; }
.cc-title { margin: 0; font-size: 16px; }
.cc p { margin: 0; }
.cc-shot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-height: 44px; }
.cc-shot-name { flex: 1 1 150px; min-width: 0; font-weight: 600; }
.cc-shot-btns { display: flex; flex-wrap: wrap; gap: 6px; }
.cc-mark { width: 20px; text-align: center; color: var(--muted); }
.cc-mark.cc-ok { color: #067647; font-weight: 700; }
.cc .chip { white-space: normal; padding: 6px 12px 6px 8px; font-size: 14px; }
.cc .chips { gap: 6px 8px; }
.cc .chip input[type="checkbox"] { width: 20px; height: 20px; }
.cc-need { font-size: 12px; font-weight: 600; color: var(--danger); }
.cc-warn { color: var(--danger); }
.cc .field-hint .btn-small { margin-left: 4px; }
/* Ready to file: a warning (a serial made after its install date) is amber and never blocks. */
.ready-list.ready-warn { color: var(--warn-text, #8a5a00); }
.ready-list.ready-warn li::marker { content: "⚠ "; }
[data-theme="dark"] .ready-list.ready-warn { color: #fbbf24; }
/* "Double-check" (owner, 2026-10-06): amber warnings at the top of the Ready to file box and the Work-done checklist, each with "✓ Checked". */
.double-checks { margin: 0 0 8px; padding: 8px 10px; background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 8px; color: var(--text); }
.double-list { margin: 6px 0 0; padding-left: 20px; }
.double-list li { margin: 4px 0; color: var(--warn-text, #8a5a00); }
.double-list li::marker { content: "⚠ "; }
.double-list li > span { margin-right: 8px; overflow-wrap: anywhere; }
.double-list .double-ok { vertical-align: baseline; }
[data-theme="dark"] .double-list li { color: #fbbf24; }
.claim-labor-rate { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin: 10px 0 4px; }
.claim-labor-rate .field { margin: 0; }
.claim-labor-rate input { max-width: 9em; }
/* The submission queue on the billing board (owner, 2026-10-05; web/app/ui/claim-queue.js): the ready claims,
   what will be typed on Hayward's portal, and the owner's "Approve and submit these N". */
.claim-queue .past-toggle.alone { margin: 0; }
.cq-body { margin-top: 8px; min-width: 0; }
.cq-notdup { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
.cq-notdup input { flex: 1 1 220px; min-width: 0; max-width: 100%; }
.cq-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.cq-head { margin: 10px 0 4px; overflow-wrap: anywhere; }
.cq-id { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.cq-item { align-items: flex-start; }
.cq-item .row-side { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; max-width: 40%; text-align: right; }
.cq-fields th { white-space: normal; width: 38%; }
.cq-fields td { overflow-wrap: anywhere; white-space: pre-wrap; }
.cq-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cq-confirm p { margin: 0; flex: 0 0 100%; }
.cq-older { margin-top: 8px; overflow-wrap: anywhere; }
/* "Read from photos" on a job (web/app/ui/photo-reads.js; CJ's ticket, 2026-10-05): one card per label,
   its photo beside its model and serial, so the two that go together are read together. */
.pr-card { align-items: flex-start; }
.pr-thumb { flex: none; width: 72px; height: 72px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--bg); }
.pr-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pr-body { flex: 1; min-width: 0; }
.pr-pair { margin: 0 0 4px; display: grid; gap: 2px; }
.pr-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.pr-line dt { flex: none; width: 3.4em; font-weight: 600; }
.pr-line dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.pr-tag { font-size: 12px; color: var(--muted); }
.pr-code { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 4px 0; font-size: 14px; overflow-wrap: anywhere; }
.pr-code-btns .btn-small { margin-right: 4px; }
.pr-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.pr-actions .btn { max-width: 100%; overflow-wrap: anywhere; text-align: left; }

/* The read-back after filing: Hayward's copy differs from what the robot sent, still on the bell (src/claim-readback.js). */
.notice.notice-bad { background: color-mix(in srgb, #dc2626 10%, transparent); border-color: color-mix(in srgb, #dc2626 55%, transparent); }

/* Auto-save's line (web/app/ui/autosave.js, owner 2026-10-07): "Saving…", "✓ Saved", "Not saved…". */
.autosave { font-size: 13px; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.autosave-saving, .autosave-saved { color: var(--muted, #6b7280); }
.autosave-bad { color: var(--danger); font-weight: 600; }
.autosave-bad .muted { font-weight: 400; }
.autosave-line { display: flex; justify-content: flex-end; min-height: 18px; margin-top: 4px; }

/* Approximate pins (owner, 2026-10-12; web/shared/approx-pin.js): a dashed ring and a red "!" on the
   pin's corner, a red-edged "! Address not found exactly" badge in lists and on the job page. */
.pin.pin-approx { outline: 2px dashed #dc2626; outline-offset: 2px; }
.pin-bang {
  position: absolute; top: -9px; right: -9px; width: 16px; height: 16px; border-radius: 50%;
  background: #dc2626; color: #fff; border: 1.5px solid #fff; font-size: 11px; font-weight: 800;
  line-height: 13px; text-align: center; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.map-card-approx {
  margin-top: 4px; padding: 4px 6px; border-radius: 6px; font-size: 12px;
  background: var(--warn-bg); border: 1px solid var(--warn-line); box-shadow: inset 3px 0 0 #dc2626;
}
.map-card-approx a { font-weight: 600; }
.badge.badge-approx { background: var(--warn-bg); border: 1px solid #dc2626; color: var(--text, #1f2937); white-space: nowrap; }
.badge.badge-approx b, .approx-bang { color: #dc2626; font-weight: 800; }
.held-box.approx-box { box-shadow: inset 4px 0 0 #dc2626; }
.approx-tools { margin: 6px 0; }

/* The jobs map's own status over it (web/app/ui/jobmap.js): loading, slow, didn't load + Try again. */
.jobs-map-box { position: relative; }
.map-status {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 4;
  width: max-content; max-width: calc(100% - 32px); padding: 10px 14px; border-radius: 10px; text-align: center;
  background: var(--card, #fff); color: var(--text, #1f2937); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18); font-size: 14px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}

/* Open jobs that couldn't be placed on the map, listed under it (web/app/pages/jobs.js OffMap). */
.offmap { margin-top: 10px; }
.offmap-list { list-style: none; margin: 6px 0 0; padding: 0; }
.offmap-list li { padding: 4px 0; border-top: 1px solid var(--line, #e5e5e5); display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
/* The flag on top of the map that points down to that list (OffMapFlag; on a phone the list is below the fold). */
.jobs-map-wrap { position: relative; }
.offmap-flag {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 5;
  max-width: calc(100% - 120px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: 6px 12px; border-radius: 999px; font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--text, #1f2937);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}

/* ---- The Mailbox, laid out like Yahoo Mail (owner, 2026-10-12, for Clint; web/app/pages/mail.js) ----
   Folders on the left, the list in the middle, the open email in a reading pane on the right (≥1100px);
   narrower, the email takes the list's place; on phones the folders slide in from ☰. */
.main:has(.ymail) {
  max-width: none;
  padding: 0;
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom));
}
.ymail {
  --y-accent: #6001d2;
  --y-accent-bg: #efe6fd;
  --y-hover: #f3f5f8;
  --y-line: #e3e6ea;
  --y-field: #f0f3f5;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--card);
  color: var(--text);
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  min-height: calc(100vh - 120px);
}
:root[data-theme="dark"] .ymail {
  --y-accent: #b48cff;
  --y-accent-bg: #2d2342;
  --y-hover: #1f2933;
  --y-line: var(--line);
  --y-field: var(--bg);
}
.ymail .btn-primary,
.ymail .ymail-primary {
  background: var(--y-accent);
  border-color: var(--y-accent);
  color: #fff;
}
:root[data-theme="dark"] .ymail .btn-primary,
:root[data-theme="dark"] .ymail .ymail-primary {
  color: #160b2b;
}
/* Folders */
.ymail-folders {
  display: none;
  padding: 12px 8px;
  border-right: 1px solid var(--y-line);
  background: var(--card);
}
.ymail-folders-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  font-size: 18px;
  padding: 4px 12px 10px;
}
.ymail-folderlist {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ymail-folder {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 40px;
  padding: 6px 12px;
  border-radius: 20px;
  cursor: pointer;
  text-align: left;
}
.ymail-folder:hover {
  background: var(--y-hover);
}
.ymail-folder.on {
  background: var(--y-accent-bg);
  color: var(--y-accent);
  font-weight: 700;
}
.ymail-folder-icon {
  width: 20px;
  text-align: center;
  flex: none;
}
.ymail-folder-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* "Work folders", "Yahoo folders": the headings between the Mailbox's folder groups (CJ's ticket, 2026-10-13). */
.ymail-folder-group {
  margin: 12px 12px 2px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.ymail-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}
.ymail-folder.on .ymail-count {
  color: var(--y-accent);
}
.ymail-status {
  padding: 16px 12px 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ymail-drawer-close {
  display: none;
}
.ymail-status .badge {
  border-radius: 8px;
  white-space: normal;
}
/* The list */
.ymail-list {
  min-width: 0;
  container-type: inline-size;
}
.ymail-searchbar {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
}
.ymail-search {
  flex: 1;
  min-width: 0;
  height: 40px;
  border: 1px solid transparent;
  border-radius: 20px;
  background: var(--y-field);
  padding: 0 16px;
  font: inherit;
  color: var(--text);
}
.ymail-search:focus {
  outline: none;
  border-color: var(--y-accent);
  background: var(--card);
}
.ymail-menu {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 700;
  color: var(--y-accent);
  height: 40px;
  padding: 0 6px;
  cursor: pointer;
  white-space: nowrap;
  flex: none;
}
.ymail-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 6px;
  min-height: 44px;
  padding: 4px 12px;
  border-top: 1px solid var(--y-line);
  border-bottom: 1px solid var(--y-line);
}
.ymail-tool {
  appearance: none;
  border: 1px solid transparent;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  min-height: 34px;
  padding: 4px 10px;
  border-radius: 17px;
  cursor: pointer;
}
.ymail-tool:hover:not(:disabled) {
  background: var(--y-hover);
}
.ymail-tool.ymail-primary:hover:not(:disabled) {
  background: var(--y-accent);
  filter: brightness(1.1);
}
.ymail-tool:disabled {
  opacity: 0.55;
  cursor: default;
}
.ymail-folder-title,
.ymail-picked {
  font-size: 14px;
  font-weight: 700;
  padding: 0 4px;
}
.ymail-spacer {
  flex: 1;
}
.ymail-check {
  width: 18px;
  height: 18px;
  margin: 0 4px;
  flex: none;
  accent-color: var(--y-accent);
  cursor: pointer;
}
.ymail-note {
  padding: 8px 16px 0;
}
.ymail-list .errorbox,
.ymail-list .empty {
  margin: 12px 16px;
}
.ymail-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* A row: two lines when the list is narrow (phones, beside the reading pane) … */
.ymail-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "check from date" "check line tags";
  align-items: center;
  column-gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--y-line);
  cursor: pointer;
  font-size: 14px;
  line-height: 1.35;
}
.ymail-row .ymail-check {
  grid-area: check;
}
.ymail-from {
  grid-area: from;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}
.ymail-line {
  grid-area: line;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ymail-subj {
  font-weight: 600;
}
.ymail-snip {
  color: var(--muted);
  margin-left: 8px;
}
.ymail-tags {
  grid-area: tags;
  display: flex;
  align-items: center;
  gap: 4px;
  justify-content: flex-end;
}
.ymail-tags .badge {
  font-size: 11px;
  padding: 0 6px;
}
.ymail-clip {
  font-size: 13px;
}
.ymail-date {
  grid-area: date;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  text-align: right;
}
.ymail-row:hover {
  background: var(--y-hover);
}
.ymail-row:focus-visible {
  outline: 2px solid var(--y-accent);
  outline-offset: -2px;
}
.ymail-row.ticked {
  background: var(--y-accent-bg);
}
.ymail-row.on {
  background: var(--y-accent-bg);
  box-shadow: inset 3px 0 0 var(--y-accent);
}
.ymail-row.unread .ymail-from {
  font-weight: 700;
}
.ymail-row.unread .ymail-subj {
  font-weight: 700;
}
.ymail-row.unread .ymail-date {
  color: var(--text);
  font-weight: 700;
}
.ymail-row:not(.unread) .ymail-from {
  color: var(--muted);
}
/* Move / Trash on a row (the office's ticket, 2026-10-16): in the date's place while the mouse is over it, like Yahoo.
   Phones (no hover) tick rows and use the toolbar, or open the email. */
.ymail-hover {
  display: none;
  grid-area: date;
  gap: 2px;
  justify-content: flex-end;
  min-width: 72px;
}
.ymail-hover-btn {
  border: 0;
  background: transparent;
  border-radius: 6px;
  padding: 2px 6px;
  font-size: 15px;
  line-height: 1.2;
  cursor: pointer;
}
.ymail-hover-btn:hover,
.ymail-hover-btn:focus-visible {
  background: var(--y-accent-bg);
}
@media (hover: hover) {
  .ymail-row.can-move:hover .ymail-hover,
  .ymail-row.can-move:focus-within .ymail-hover {
    display: flex;
  }
  .ymail-row.can-move:hover .ymail-date,
  .ymail-row.can-move:focus-within .ymail-date {
    display: none;
  }
}
.ymail-movelist {
  display: grid;
  gap: 4px;
  max-height: 60vh;
  overflow-y: auto;
}
.ymail-moveto {
  text-align: left;
  border: 1px solid var(--y-line, var(--line));
  background: var(--card);
  color: var(--text);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 15px;
  cursor: pointer;
}
.ymail-moveto:hover,
.ymail-moveto:focus-visible {
  background: var(--y-accent-bg, var(--hover));
}
/* … one dense line (~44px) when there's room, like Yahoo on a computer. */
@container (min-width: 620px) {
  .ymail-row {
    display: flex;
    gap: 10px;
    min-height: 44px;
    padding: 4px 16px 4px 12px;
  }
  .ymail-from {
    flex: 0 0 190px;
  }
  .ymail-line {
    flex: 1;
  }
  .ymail-tags {
    flex: none;
  }
  .ymail-date {
    flex: 0 0 auto;
    min-width: 72px;
  }
}
/* The reading pane */
.ymail-reader {
  min-width: 0;
  padding: 0 20px 24px;
  background: var(--card);
}
.ymail-readbar {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 0;
  margin-bottom: 4px;
  background: var(--card);
  border-bottom: 1px solid var(--y-line);
}
.ymail-back {
  appearance: none;
  border: 0;
  background: none;
  font-size: 22px;
  line-height: 1;
  width: 40px;
  height: 40px;
  border-radius: 20px;
  color: var(--y-accent);
  cursor: pointer;
}
.ymail-back:hover {
  background: var(--y-hover);
}
.ymail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ymail-actions .btn {
  min-height: 36px;
  padding: 4px 14px;
  border-radius: 18px;
  font-size: 14px;
}
.ymail-subject {
  font-size: 22px;
  font-weight: 600;
  margin: 14px 0 12px;
  overflow-wrap: anywhere;
}
.ymail-sender {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
}
.ymail-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--y-accent);
  color: #fff;
  font-weight: 700;
}
.ymail-sender-who {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.ymail-when {
  flex: none;
  white-space: nowrap;
}
.ymail-reader .mailtext {
  max-height: none;
  background: none;
  border: 0;
  padding: 8px 0;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
}
:root[data-theme="dark"] .ymail-reader .mailtext {
  background: none;
}
/* Phones and narrow windows: the open email takes the list's place (← goes back). */
@media (max-width: 1099px) {
  .ymail.has-open .ymail-list {
    display: none;
  }
}
@media (max-width: 699px) {
  .ymail.drawer-open .ymail-folders {
    display: block;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(280px, 85vw);
    z-index: 31;
    overflow: auto;
    padding-top: calc(12px + env(safe-area-inset-top));
    box-shadow: 4px 0 16px rgba(0, 0, 0, 0.2);
  }
  .ymail-drawer-back {
    position: fixed;
    inset: 0;
    background: rgba(16, 24, 40, 0.45);
    z-index: 30;
  }
  .ymail-drawer-close {
    display: inline-block;
  }
  .ymail-reader {
    padding: 0 12px 16px;
  }
  .ymail-sender {
    flex-wrap: wrap;
  }
  .ymail-when {
    flex-basis: 100%;
    padding-left: 46px;
  }
  .ymail-folder-title {
    display: none; /* the ☰ button already names the folder */
  }
}
@media (min-width: 700px) {
  .main:has(.ymail) {
    padding-bottom: 0;
  }
  .ymail {
    grid-template-columns: 220px minmax(0, 1fr);
    height: calc(100vh - 96px);
    min-height: 420px;
  }
  .ymail-folders {
    display: block;
    overflow: auto;
  }
  .ymail-menu {
    display: none;
  }
  .ymail-list,
  .ymail-reader {
    overflow: auto;
  }
}
@media (min-width: 1100px) {
  .ymail.has-open {
    grid-template-columns: 220px minmax(360px, 1fr) minmax(440px, 1.25fr);
  }
  .ymail-reader {
    border-left: 1px solid var(--y-line);
  }
}
/* Paging back through a folder (owner, 2026-10-12): "1–50 of 2,153 ‹ ›" and "Load older emails". */
.ymail-range {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
  padding: 0 2px 0 8px;
}
.ymail-arrow {
  font-size: 20px;
  line-height: 1;
  min-width: 34px;
  padding: 2px 8px;
}
.ymail-more {
  display: flex;
  justify-content: center;
  padding: 12px;
}
.ymail-more .ymail-tool {
  border-color: var(--y-line);
  color: var(--y-accent);
  padding: 6px 18px;
}
.ymail-end {
  text-align: center;
  padding: 12px;
  margin: 0;
}

/* What breaks, by model (web/app/pages/what-breaks.js) */
.breaks-model { border-top: 1px solid var(--line, rgba(127,127,127,.25)); padding: 8px 0; }
.breaks-model > summary { cursor: pointer; }
.breaks-model .table { margin-top: 6px; }

/* The shared preview notice (owner, 2026-10-13 "Dummy UI first"; web/app/ui/preview-notice.js). Themed by --warn-*. */
.preview-banner { background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--text); border-radius: 8px; padding: 8px 12px; margin: 0 0 12px; font-size: 14px; line-height: 1.35; overflow-wrap: anywhere; }
.preview-pop-back { position: fixed; inset: 0; z-index: 1000; background: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; padding: 16px; }
.preview-pop { background: var(--card); color: var(--text); border: 2px solid var(--warn-line); border-radius: var(--radius); padding: 18px; max-width: 360px; width: 100%; }
.preview-pop h3 { margin: 0 0 8px; font-size: 18px; }
.preview-pop p { margin: 0 0 14px; }
.preview-pop .btn { width: 100%; min-height: 44px; }

/* Parts used and labor at a customer-pay Work done (owner, 2026-10-13; web/app/ui/work-done-pricing.js). */
.wdp { border-top: 1px solid var(--line); margin-top: 12px; padding-top: 8px; }
.wdp-sec { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.wdp-sec input[type="text"], .wdp-sec input[type="search"] { width: 100%; min-height: 40px; }
.wdp-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.wdp-hits { display: flex; flex-direction: column; gap: 4px; }
.wdp-hit { display: flex; justify-content: space-between; align-items: center; gap: 8px; text-align: left; width: 100%; min-height: 44px; padding: 6px 10px; background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 8px; font: inherit; cursor: pointer; }
.wdp-pick { border: 1px solid var(--line); border-radius: 8px; padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.wdp-qty { width: 5em; min-height: 36px; }
.wdp-money { width: 7em; min-height: 36px; }
.wdp-lines { border-top: 1px dashed var(--line); padding-top: 6px; display: flex; flex-direction: column; gap: 2px; }
.wdp-total { border-top: 1px solid var(--line); padding-top: 6px; font-size: 16px; }
.wdp-did { display: block; width: 100%; box-sizing: border-box; font-size: 16px; min-height: 88px; resize: vertical; margin: 4px 0 6px; }
.bill-did { white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* Tech pay → Board (owner, 2026-10-12; web/app/pages/pay-board.js): the office whiteboard as a month. The calendar's
   days (count, amber = jobs without a W# / invoice # yet), then each day's jobs per tech: side by side on a computer,
   stacked on a phone. */
.main:has(.pay-board) { max-width: 1280px; }
.pb-nav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 4px 0 8px; }
.pb-nav .btn-small { margin-right: 0; min-width: 40px; font-size: 18px; line-height: 1; }
.pb-nav .btn-small:last-child:not(:nth-child(3)) { font-size: 13px; }
.pb-month { margin: 0; min-width: 9.5em; text-align: center; font-size: 18px; }
.pb-techs .tab { display: inline-flex; align-items: center; gap: 6px; }
.pb-count { font-weight: 700; opacity: .8; font-variant-numeric: tabular-nums; }
.pb-sum { margin: 2px 0 8px; }
.pb-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin: 0 0 12px; }
.pb-wd { text-align: center; font-size: 12px; font-weight: 600; color: var(--muted); }
.pb-cell { position: relative; min-height: 52px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--muted); font: inherit; padding: 3px 4px; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; text-align: left; }
.pb-blank { border: 0; background: none; }
.pb-cell.has { color: var(--text); cursor: pointer; border-color: var(--accent); }
.pb-cell.on { background: var(--accent); color: #fff; }
.pb-cell:disabled { opacity: .55; }
.pb-dn { font-size: 12px; }
.pb-n { font-size: 18px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.pb-miss { position: absolute; top: 3px; right: 4px; min-width: 18px; padding: 0 4px; border-radius: 999px; background: #fde68a; color: #78350f; font-size: 11px; font-weight: 700; text-align: center; }
.pb-who { display: flex; flex-wrap: wrap; gap: 0 6px; font-size: 11px; line-height: 1.3; }
.pb-who-t { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }
.pb-who-t .dot { width: 7px; height: 7px; }
.pb-showing { margin: 0 0 8px; }
.pb-day { margin: 0 0 14px; }
.pb-day-h { font-size: 16px; margin: 0 0 6px; }
.pb-lanes { display: grid; gap: 10px; align-items: start; }
.pb-lanes.multi { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.pb-lane { margin: 0; padding: 10px 12px; }
.pb-lane-h { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.pb-jobs { list-style: none; margin: 0; padding: 0; }
.pb-job { padding: 6px 0; border-top: 1px solid var(--line); }
.pb-job:first-child { border-top: 0; padding-top: 2px; }
.pb-refs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.pb-ref { font-weight: 700; font-size: 17px; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.pb-inv { color: var(--accent-dark); }
.pb-guess { color: #92400e; border-bottom: 1px dashed currentColor; cursor: help; }
[data-theme="dark"] .pb-guess { color: #fbbf24; }
[data-theme="dark"] .pb-miss { background: #8a6d24; color: #fff7e6; }
.pb-none { font-size: 13px; font-weight: 700; }
.pb-line { font-size: 14px; overflow-wrap: anywhere; }
.pb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; font-size: 13px; margin-top: 2px; }
@media (max-width: 699px) {
  .pb-cell { min-height: 46px; padding: 2px 3px; }
  .pb-who { display: none; }
  .pb-n { font-size: 16px; }
}
.pb-mine-h { margin: 18px 0 4px; }

/* Texts from the iPhone (web/app/pages/texts.js, owner 2026-10-13): the Texts folder's view buttons, the setup page. */
.ymail-tool.ymail-tool-on { background: var(--y-hover); font-weight: 600; }
.texts-setup .card { overflow-wrap: anywhere; }
.texts-steps { padding-left: 1.4em; line-height: 1.5; }
.texts-steps > li { margin: 0 0 10px; }
.texts-steps ul { padding-left: 1.2em; margin: 6px 0; }
.texts-limits { padding-left: 1.2em; line-height: 1.5; }
.texts-limits > li { margin: 0 0 8px; }
.texts-fields { margin: 8px 0; }
.texts-fields td, .texts-fields th { vertical-align: top; }
.texts-copy { margin: 10px 0; }
.texts-copy-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.texts-copy-value { flex: 1 1 220px; min-width: 0; word-break: break-all; padding: 6px 8px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line); font-size: 13px; }

/* @mentions on setup tickets (web/app/ui/mention-box.js, owner 2026-10-13): the list that opens on "@", a tag in a ticket. */
.mention-wrap { position: relative; }
.mention-wrap > textarea { width: 100%; box-sizing: border-box; }
.mention-list { position: absolute; left: 0; right: 0; top: 100%; z-index: 50; margin: 2px 0 0; padding: 4px 0; list-style: none; background: var(--card); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); max-height: 220px; overflow-y: auto; }
.mention-list > li { padding: 10px 14px; min-height: 24px; cursor: pointer; font-size: 15px; }
.mention-list > li.on, .mention-list > li:hover { background: var(--accent); color: #fff; }
.mention { color: var(--accent-dark); background: rgba(14, 116, 144, 0.12); border-radius: 4px; padding: 0 3px; font-weight: 600; }
[data-theme="dark"] .mention { color: #7dd3fc; background: rgba(125, 211, 252, 0.15); }

/* Tech pay > Payday: the ready check (red: blocks a tech's pay; amber: worth a look). */
.pay-checks { margin: 0; padding-left: 1.2em; }
.pay-checks li { margin: 4px 0; }
.pay-checks li.bad { color: #dc2626; font-weight: 600; }
.pay-checks li.warn { color: #b45309; }
/* Tech pay > Payday: Flagged by techs (owner, 2026-10-13; web/app/pages/pay-flags.js). */
.pay-flags { list-style: none; margin: 0; padding: 0; }
.pay-flag { padding: 10px 0; border-top: 1px solid var(--line); }
.pay-flag:first-child { border-top: 0; }
.pay-flag-head { line-height: 1.5; }
.pay-flag-pay { margin-left: 4px; }
.pay-flag-words { margin: 6px 0; padding: 4px 10px; border-left: 3px solid var(--warn-line); font-size: 1.02em; overflow-wrap: anywhere; }
.pay-flag-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.pay-flag-actions select, .pay-line-act select { width: auto; max-width: 100%; padding: 4px 6px; font: inherit; font-size: 0.9em; }
.pay-flags-done summary { cursor: pointer; margin-top: 8px; }
.pay-flags-recent { margin: 6px 0 0; padding-left: 1.2em; }
.pay-flags-recent li { margin: 6px 0; }
.pay-flags-recent .btn { margin-left: 6px; }
.pay-line-act { white-space: nowrap; }

/* Customers: All / Warranty / Owes money (web/app/pages/customers.js, office ticket 2026-10-14). */
.cust-filter .seg-btn { white-space: nowrap; }
/* A search looks through all customers whatever chip is on (office ticket 2026-10-16). */
.cust-search-note { font-size: 13px; white-space: nowrap; }

/* Work done claim prefill (web/app/ui/claim-checklist.js, 2026-10-14): which unit, suggestion chips, claim-card dates. */
.cc-new { display: flex; flex-direction: column; gap: 10px; padding: 10px; border: 1px dashed var(--warn-line); border-radius: 10px; }
.cc-new .preview-banner { margin: 0; }
.cc-unit-list { display: flex; flex-direction: column; gap: 6px; }
.cc-unit { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cc-unit-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; min-height: 48px; padding: 8px 12px; text-align: left; background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; font: inherit; overflow-wrap: anywhere; }
.cc-unit.cc-on .cc-unit-btn { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.cc-unit > .small { padding: 0 4px; }
.cc-unit-else { color: var(--accent-dark); font-weight: 600; justify-content: center; }
.cc-unit-done { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.cc-tag { display: inline-block; font-size: 11px; font-weight: 600; padding: 0 6px; border-radius: 999px; background: var(--warn-bg); border: 1px solid var(--warn-line); vertical-align: 1px; }
.cc-sugs { display: flex; flex-wrap: wrap; gap: 6px; }
.cc .cc-sug { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 2px; min-height: 40px; padding: 6px 12px; text-align: left; cursor: pointer; border: 1px dashed #9aa5b1; color: var(--text); font: inherit; font-size: 14px; border-radius: 14px; }
.cc .cc-sug.cc-on { border: 1px solid var(--accent); background: #e0f2f6; }
.cc-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-height: 40px; }
.cc input[type="date"] { max-width: 220px; }
[data-theme="dark"] .cc .cc-sug.cc-on { background: #123a45; }

/* ---- Help Desk (owner, 2026-10-16; web/app/pages/helpdesk.js): the first tab and its cards ---- */
.hd-tabicon { position: relative; display: inline-block; }
.hd-tabcount { position: absolute; top: -6px; right: -12px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--danger); color: #fff; font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; font-style: normal; }
.hd-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hd-head h1 { margin: 4px 0; }
.hd-intro { margin: 2px 0 4px; }
.hd-sec { margin: 18px 0 8px; }
.hd-sec-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.hd-sec-head h2 { margin: 0; font-size: 18px; }
.hd-sec-count { display: inline-block; min-width: 22px; padding: 0 7px; border-radius: 11px; background: var(--line); color: var(--text); font-size: 13px; line-height: 22px; text-align: center; vertical-align: 2px; }
.hd-sec-count.hot { background: var(--danger); color: #fff; }
.hd-empty { margin: 4px 0 0; }
.hd-card { background: var(--card); border: 1px solid var(--line); border-left: 4px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin: 0 0 10px; cursor: pointer; min-width: 0; overflow-wrap: anywhere; }
.hd-card:hover { border-color: var(--accent); border-left-color: inherit; }
.hd-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hd-todo, .hd-todo:hover { border-left-color: var(--danger); }
.hd-info, .hd-info:hover { border-left-color: var(--accent); }
.hd-seen { opacity: 0.72; }
.hd-seen:hover { opacity: 1; }
.hd-open { cursor: default; opacity: 1; }
.hd-card-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; }
.hd-kind, .hd-status { display: inline-block; padding: 1px 8px; border-radius: 999px; font-weight: 600; font-size: 12px; line-height: 18px; }
.hd-kind { background: #e5e9ef; color: #334155; }
.hd-kind-claim { background: #dbeafe; color: #1e3a8a; }
.hd-kind-hayward { background: #ede9fe; color: #4c1d95; }
.hd-kind-pay { background: #dcfce7; color: #14532d; }
.hd-kind-ticket { background: #fef3c7; color: #78350f; }
.hd-kind-system { background: #fee2e2; color: #7f1d1d; }
.hd-status { background: transparent; border: 1px solid var(--line); color: var(--muted); }
.hd-status.hot { border-color: var(--danger); color: var(--danger); }
.hd-when { margin-left: auto; color: var(--muted); }
.hd-title { margin: 6px 0 2px; font-size: 16px; line-height: 1.3; }
.hd-title-big { font-size: 22px; }
.hd-jobs { display: flex; flex-wrap: wrap; gap: 4px; align-items: baseline; font-size: 14px; color: var(--muted); }
.hd-job { font-weight: 600; color: var(--accent-dark); }
.hd-sep { color: var(--line); }
.hd-what { margin: 6px 0 4px; font-size: 15px; }
.hd-from { font-size: 13px; color: var(--muted); }
.hd-from b { color: var(--text); font-weight: 600; }
.hd-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.hd-actions .btn { min-height: 38px; padding: 6px 12px; font-size: 14px; }
.hd-actions .btn-ghost { border-color: transparent; color: var(--muted); background: transparent; }
.hd-facts { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; margin: 12px 0; font-size: 14px; }
.hd-facts dt { color: var(--muted); }
.hd-facts dd { margin: 0; }
.hd-h { font-size: 14px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); margin: 14px 0 4px; }
.hd-body { margin: 0; white-space: pre-wrap; }
.hd-stays { align-self: center; font-size: 13px; color: var(--muted); font-style: italic; }
.hd-bell { text-decoration: none; }
.hd-detail .back { display: inline-block; margin: 4px 0 10px; }
[data-theme="dark"] .hd-kind { background: #243040; color: #cbd5e1; }
[data-theme="dark"] .hd-kind-claim { background: #1e3a5f; color: #bfdbfe; }
[data-theme="dark"] .hd-kind-hayward { background: #352a5c; color: #ddd6fe; }
[data-theme="dark"] .hd-kind-pay { background: #173d2a; color: #bbf7d0; }
[data-theme="dark"] .hd-kind-ticket { background: #3f3112; color: #fde68a; }
[data-theme="dark"] .hd-kind-system { background: #4a1d1d; color: #fecaca; }
@media (min-width: 700px) {
  .hd-tabicon { padding-right: 16px; }
  .hd-tabcount { top: -7px; right: -4px; }
}
@media (max-width: 699px) {
  .hd-tabcount { top: -4px; right: -14px; }
  .hd-title-big { font-size: 19px; }
  .hd-card { padding: 12px; }
}
/* The header's Help Desk button (owner, 2026-10-16): between the name and ⟳, the red To do number; word hidden on narrow phones. */
.topbar-helpdesk { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 36px; margin: -4px 0; padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; color: var(--text); text-decoration: none; font-size: 14px; font-weight: 600; white-space: nowrap; }
.topbar-helpdesk:hover, .topbar-helpdesk.on { background: var(--bg); border-color: var(--accent); }
.hd-btn-icon { font-size: 16px; line-height: 1; }
.hd-btn-count { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--danger); color: #fff; font-size: 12px; font-weight: 700; line-height: 20px; text-align: center; }
[data-theme="dark"] .hd-btn-count { color: #2a0d0b; }
@media (max-width: 430px) {
  .hd-btn-text { display: none; }
  .topbar-helpdesk { padding: 4px 8px; gap: 4px; }
  .topbar-right { gap: 10px; }
}
/* "Viewing as …" and the local-dev bar: always the very top of the page, above the top nav on desktop too (owner,
   2026-10-16: "shouldn't the blue bar be at the top so I could see exactly what they are seeing?"). */
.shell > .devbar, .shell > .viewbar { order: -2; }

/* On hold (Colten's ticket "Job Hold Option", 2026-10-16; web/shared/job-hold.js): a slate look apart from the yellow
   "still needs" and the red approximate pin. On the map: a striped hollow pin with a solid ring in the tech's colour, a
   pause badge on its corner and "hold" under it; in lists and on the job page an "On hold" badge and a slate-edged box. */
.pin.pin-onhold {
  background: repeating-linear-gradient(135deg, #ffffff 0 4px, #cbd5e1 4px 8px);
  border-style: solid;
  border-width: 3px;
  color: #1e293b;
}
.pin-pause {
  position: absolute; top: -9px; left: -9px; width: 16px; height: 16px; border-radius: 50%;
  background: #334155; color: #fff; border: 1.5px solid #fff; font-size: 8px; line-height: 13px; text-align: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.pin-day.pin-hold-tag { background: #334155; color: #fff; border-color: #334155; text-transform: uppercase; letter-spacing: 0.02em; }
.badge.badge-hold { background: #e2e8f0; color: #1e293b; border: 1px solid #64748b; white-space: nowrap; }
.map-card-hold {
  margin-top: 4px; padding: 4px 6px; border-radius: 6px; font-size: 12px;
  background: #f1f5f9; border: 1px solid #94a3b8; box-shadow: inset 3px 0 0 #334155; color: #1e293b;
}
.held-box.hold-box { background: #f1f5f9; border-color: #94a3b8; box-shadow: inset 4px 0 0 #334155; color: #1e293b; }
.held-box.hold-box.hold-due { box-shadow: inset 4px 0 0 #dc2626; }
.hold-due-text { color: #b91c1c; }
.hold-icon { font-size: 0.9em; }
.hold-btns { margin: 8px 0 4px; flex-wrap: wrap; }
.row-hold { color: #334155; }
.hold-views { margin: 0 0 8px; max-width: 520px; }
.hold-views .seg-btn { white-space: nowrap; }
@media (max-width: 420px) { .hold-views .seg-btn { padding: 6px 6px; font-size: 13px; } }
.hold-picks { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 10px; }
.hold-pick {
  appearance: none; font: inherit; font-size: 14px; min-height: 40px; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); cursor: pointer;
}
.hold-pick.on { background: #334155; border-color: #334155; color: #fff; font-weight: 600; }
.hold-form .error { color: var(--danger); margin: 0 0 8px; }
[data-theme="dark"] .badge.badge-hold { background: #273445; color: #e2e8f0; border-color: #94a3b8; }
[data-theme="dark"] .map-card-hold,
[data-theme="dark"] .held-box.hold-box { background: #1f2a37; color: var(--text); border-color: #475569; box-shadow: inset 4px 0 0 #94a3b8; }
[data-theme="dark"] .held-box.hold-box.hold-due { box-shadow: inset 4px 0 0 #f87171; }
[data-theme="dark"] .hold-due-text { color: #fca5a5; }
[data-theme="dark"] .row-hold { color: #cbd5e1; }
[data-theme="dark"] .hold-pick.on { background: #94a3b8; border-color: #94a3b8; color: #0f172a; }

/* The job page's Builder card (web/app/ui/builder-card.js; CJ's ticket, 2026-10-16): folded to the name and one line,
   unfolded to the whole block; editing is the claim's installer box. */
.bc-card { width: 100%; }
.bc-head { display: flex; align-items: flex-start; gap: 8px; min-height: 32px; }
.bc-fold { flex: 1; min-width: 0; display: flex; align-items: flex-start; gap: 6px; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.bc-fold:disabled { cursor: default; }
.bc-caret { flex: none; display: inline-block; width: 1em; color: var(--muted, #64748b); transition: transform 0.15s; }
.bc-caret.on { transform: rotate(90deg); }
.bc-fold:disabled .bc-caret { visibility: hidden; }
.bc-name { overflow-wrap: anywhere; font-weight: 600; }
.bc-head .kv-pen { flex: none; padding: 2px 4px; margin: -2px -4px 0 0; border: 0; background: none; color: var(--accent, #2563eb); font: inherit; font-size: 13px; cursor: pointer; }
.bc-summary { margin: 2px 0 0 calc(1em + 6px); overflow-wrap: anywhere; cursor: pointer; }
.bc-body { margin: 4px 0 0 calc(1em + 6px); display: grid; gap: 4px; overflow-wrap: anywhere; }
.bc-warn { color: #b45309; }
.bc-edit input { width: 100%; box-sizing: border-box; font-size: 16px; } /* 16px: iOS doesn't zoom into the box */
.bc-edit .field { display: block; }
.bc-ask { display: grid; gap: 4px; }
.bc-edit-title { font-weight: 600; margin-bottom: 4px; }
.bc-edit .field-label { display: block; }
