:root {
  /* Design tokens. Every company's theme (companies.settings.theme) overrides
     these at runtime via theme.js, so screens never hard-code colors or fonts. */
  --primary: #14301c;
  --primary-hover: #1f5c2e;
  --link: #2f7d3f;
  --accent: #e8b931;
  --accent-text: #745d19;   /* the accent as readable text (theme.js accentTextColor) */
  --bg: #f7f4ea;
  --card: #ffffff;
  --text: #24291f;
  --text-soft: #5b6156;
  --border: #e3dfd3;
  --error: #a63e29;
  --error-bg: #fbeae5;
  --ok-bg: #e7f2e4;
  --radius: 14px;
  --font-heading: 'Fraunces', Georgia, serif;
  --font-body: 'Work Sans', system-ui, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
h1, h2 { font-family: var(--font-heading); font-weight: 600; margin: 0; line-height: 1.15; }
h1 { font-size: 28px; }
h2 { font-size: 21px; }
.wrap { max-width: 480px; margin: 0 auto; padding: 20px 16px 48px; }
.top { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.top img { height: 46px; width: auto; max-width: 130px; object-fit: contain; }
.top .who { margin-left: auto; font-size: 13px; color: var(--text-soft); text-align: right; }
.sub { color: var(--text-soft); margin: 6px 0 20px; font-size: 15px; }
.card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px; margin-bottom: 14px;
}
label { display: block; font-weight: 600; font-size: 14px; margin: 12px 0 6px; }
.hint { font-weight: 400; color: var(--text-soft); font-size: 13px; }
/* Every text box looks the same: full width, 16px text (so iPhones don't zoom), one radius, one focus ring.
   Text that can run long is a <textarea> (class "one-line" for one line that wraps); web/autogrow.js makes it
   grow so everything typed stays in view. */
input, select, textarea {
  width: 100%; max-width: 100%; min-width: 0; font: inherit; font-size: 16px; line-height: 1.35; padding: 12px 14px;
  border: 1.5px solid var(--border); border-radius: 10px; background: var(--card); color: var(--text);
}
textarea { display: block; resize: vertical; overflow-wrap: break-word; }
textarea.one-line { resize: none; overflow: hidden; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 18%, transparent); }
.code-input { letter-spacing: 8px; font-size: 24px; text-align: center; font-variant-numeric: tabular-nums; }
button { font: inherit; cursor: pointer; }
.btn {
  display: block; width: 100%; padding: 13px 16px; margin-top: 16px; border: 0; border-radius: 10px;
  background: var(--primary); color: var(--on-primary, #fff); font-weight: 600; font-size: 16px; min-height: 44px;
}
.btn:hover { background: var(--primary-hover); }
.btn[disabled] { opacity: .6; cursor: default; }
.btn.secondary { background: var(--card); color: var(--text); border: 1.5px solid var(--border); }
.btn.secondary:hover { border-color: var(--text-soft); }
.btn.google { display: flex; align-items: center; justify-content: center; gap: 10px; }
.btn.google svg { width: 18px; height: 18px; }
.link { background: none; border: 0; color: var(--link); font-weight: 600; padding: 0; text-decoration: underline; text-underline-offset: 3px; }
.row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 12px; font-size: 14px; }
.or { display: flex; align-items: center; gap: 12px; color: var(--text-soft); font-size: 13px; margin: 18px 0 2px; }
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.msg { padding: 11px 14px; border-radius: 10px; font-size: 14px; margin-top: 14px; }
.msg:not(:last-child) { margin-bottom: 14px; } /* never touch the box under a notice */
.msg.error { background: color-mix(in srgb, var(--error) 13%, var(--card)); color: var(--text); border-left: 4px solid var(--error); }
.msg.ok { background: color-mix(in srgb, var(--link) 13%, var(--card)); color: var(--text); border-left: 4px solid var(--link); }
/* 44px tall to tap (phones), drawn the same size as before: the extra height hangs into the margins */
.back { background: none; border: 0; color: var(--text-soft); font-weight: 600; padding: 12px 0; margin: -8px 0 4px; min-height: 44px; }
.menu { display: grid; gap: 12px; }
.menu-card {
  display: block; width: 100%; text-align: left; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px 18px; color: var(--text);
}
.menu-card:hover { border-color: var(--link); }
.menu-card .t { font-weight: 600; font-size: 17px; }
.menu-card .d { color: var(--text-soft); font-size: 14px; margin-top: 3px; }
.menu-card.soon { opacity: .55; cursor: default; }
.menu-card.soon:hover { border-color: var(--border); }
.pill { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 99px; background: var(--bg); color: var(--text-soft); margin-left: 6px; vertical-align: 2px; }
.pill.owner { background: #fdf3d6; color: #7a5a00; }
.person { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--border); }
.person:first-child { border-top: 0; padding-top: 0; }
.person .n { font-weight: 600; }
.person .m { color: var(--text-soft); font-size: 13px; margin-top: 2px; word-break: break-all; }
.person .act { margin-left: auto; flex-shrink: 0; }
.small-btn { padding: 7px 12px; border-radius: 8px; border: 1.5px solid var(--border); background: var(--card); font-weight: 600; font-size: 13px; color: var(--text); }
.foot { text-align: center; color: var(--text-soft); font-size: 12px; margin-top: 28px; }
.hidden { display: none !important; }
.badge { font-size: 12px; color: var(--text-soft); }
.brand-name { font-family: var(--font-heading); font-weight: 600; font-size: 21px; line-height: 1.15; }
.swatches { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.swatch { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.swatch input[type=color] { width: 44px; height: 36px; padding: 2px; border-radius: 8px; cursor: pointer; }
.logo-preview { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.logo-preview img { height: 48px; max-width: 160px; object-fit: contain; background: var(--bg); border-radius: 8px; padding: 4px; }
input[type=file] { padding: 9px; font-size: 14px; }
/* iPhone draws date/time boxes wider than the screen and centers the text: keep them inside the card */
input[type=date], input[type=time], input[type=datetime-local], input[type=month] {
  -webkit-appearance: none; appearance: none; display: block; width: 100%; max-width: 100%; min-width: 0;
  box-sizing: border-box; text-align: left; min-height: 44px; }
input[type=date]::-webkit-date-and-time-value, input[type=time]::-webkit-date-and-time-value,
input[type=datetime-local]::-webkit-date-and-time-value { text-align: left; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
.small-btn.on { background: var(--primary); color: var(--on-primary, #fff); border-color: var(--primary); }
.row-btn { width: 100%; min-height: 44px; background: none; border: 0; border-top: 1px solid var(--border); text-align: left; cursor: pointer; color: var(--text); font: inherit; }
.row-btn:first-child { border-top: 0; }
.pill.ok { background: var(--ok-bg); color: var(--primary); }
.btn.danger { background: var(--error); color: var(--on-error, #fff); }
.btn.danger:hover { background: var(--error); filter: brightness(.92); }
a { color: var(--link); }
.rate-hint { margin-top: 7px; font-size: 13px; color: var(--text-soft); min-height: 16px; }
.rate-hint strong { color: var(--primary); }
/* 0152: what goes with a line (add-on / "goes with" services, a stack of products) */
.comp { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); min-width: 0; }
.comp-h { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.comp-label { margin-top: 10px; font-weight: 600; }
.comp-pick { margin-top: 8px; min-width: 0; }
.comp-pick + .comp-pick { padding-top: 8px; border-top: 1px dashed var(--border); }
.comp-row { display: flex; gap: 8px; align-items: center; min-width: 0; }
.comp-row select { flex: 1; min-width: 0; }
.comp-acts { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px; }
.comp-sug { margin-top: 10px; max-width: 100%; white-space: normal; text-align: left; }
.comp-skip { margin-top: 6px; }
.results { margin-top: 6px; }
.results .row-btn { padding: 10px 4px; }
.checklist { max-height: 340px; overflow-y: auto; border: 1.5px solid var(--border); border-radius: 10px; margin-top: 8px; }
.check-row { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-top: 1px solid var(--border); font-weight: 400; margin: 0; cursor: pointer; }
.check-row:first-child { border-top: 0; }
.check-row input { width: 18px; height: 18px; margin-top: 2px; flex-shrink: 0; }
.check-row .n { display: block; font-weight: 600; }
.check-row .m { display: block; font-size: 13px; color: var(--text-soft); }
.sticky { position: sticky; top: 0; z-index: 5; box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.stop.done { opacity: .75; }
/* route stops: one short row each; the open one has its briefing + work order (web/routes.js) */
.card.stop { padding: 0; }
.stop-head { display: flex; gap: 10px; align-items: flex-start; width: 100%; min-height: 44px; padding: 12px 14px; background: none; border: 0; text-align: left; font: inherit; color: var(--text); cursor: pointer; }
.stop-head .pill { flex-shrink: 0; margin-left: auto; }
.stop-num { flex: 0 0 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; background: var(--primary); color: var(--on-primary, #fff); }
.card.stop.done .stop-num { background: var(--border); color: var(--text); }
.stop-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.stop-where, .stop-sum { font-size: 13px; color: var(--text-soft); }
.stop-sum { color: var(--text); }
.stop-sum .sum-it.ticked, .stop-sum .sum-svc.ticked { color: var(--text-soft); text-decoration: line-through; text-decoration-thickness: 1px; }
.stop-sum .sum-svc.ticked .sum-it { text-decoration: none; }
.stop-sum b { font-weight: 600; }
.stop-flags { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 12px; font-weight: 600; color: var(--accent-text); }
.card.stop.open .stop-head { border-bottom: 1px solid var(--border); }
.stop-body { padding: 4px 14px 14px; }
.stop-body .small-btn { min-height: 44px; }
.stop-acts { flex-wrap: wrap; gap: 8px; }
.stop-acts > span { display: flex; flex-wrap: wrap; gap: 8px; }
.sb-sec { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.sb-sec:first-of-type { border-top: 0; }
.sb-h { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); margin-bottom: 4px; }
.sb-tick { padding: 10px 0; min-height: 44px; }
.sb-tick input { width: 22px; height: 22px; }
.sb-call { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: space-between; margin-top: 6px; }
.sb-sheet { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.4); display: flex; align-items: flex-end; justify-content: center; padding: 16px; }
.sb-sheet-card { width: 100%; max-width: 520px; max-height: 80vh; overflow: auto; margin: 0; }
.sb-hu { margin: 8px 0 0; padding-left: 18px; font-size: 15px; }
.sb-hu li { margin: 4px 0; overflow-wrap: anywhere; }
.sb-sheet-acts { flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.sb-sheet-acts .small-btn { min-height: 44px; }
/* Log visit from a stop: the review before it's saved (web/visits.js) */
.vr-line { padding: 8px 0; border-top: 1px solid var(--border); }
.vr-line:first-of-type { border-top: 0; }
.vr-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.vr-acts .btn { flex: 1 1 160px; margin: 0; }
.m { color: var(--text-soft); font-size: 13px; }
.announce.unread { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.note { padding: 10px 0; border-top: 1px solid var(--border); }
.note:first-of-type { border-top: 0; }
.note.pinned { color: var(--text); font-weight: 500; }
.headsup { background: color-mix(in srgb, var(--accent) 14%, var(--card)); border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); border-radius: 10px; padding: 10px 12px; font-size: 14px; margin-bottom: 10px; }
.add-note { margin-top: 10px; }
.prod-row { border-top: 1px solid var(--border); padding: 12px 0; }
.gw-row { border-top: 1px solid var(--border); padding: 10px 0; display: grid; gap: 4px; min-width: 0; }
.gw-row select { width: 100%; min-width: 0; }
.prod-row:first-of-type { border-top: 0; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 8px; }
.grid3 label { margin: 0; font-size: 12px; font-weight: 600; color: var(--text-soft); }
.grid3 input, .grid3 select, .grid3 textarea { margin-top: 4px; padding: 9px 10px; }
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.grid2 label { margin: 0; font-size: 12px; font-weight: 600; color: var(--text-soft); }
.grid2 input, .grid2 textarea, .grid2 select { margin-top: 4px; }
/* State + ZIP on one row: both short by nature; ZIP fits 12345-6789 */
.st-zip { display: grid; grid-template-columns: minmax(0, 1fr) 8.5em; gap: 10px; }
.picker { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; }
.new-prod { margin-top: 12px; padding: 10px 12px; background: var(--bg); border-radius: 10px; }
.pin-label { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 3px 9px; border-radius: 99px; margin-bottom: 8px; }
.thread { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.comment { padding: 8px 10px; border-radius: 10px; background: var(--bg); margin-bottom: 8px; font-size: 14.5px; }
.comment.mine { background: color-mix(in srgb, var(--link) 10%, var(--card)); }
.comment .who { font-size: 13px; margin-bottom: 3px; }
.reply { display: flex; gap: 8px; align-items: flex-end; }
.reply textarea { flex: 1; }
/* announcements: look comes from Settings > Announcements (pin style/color/label, photo side) */
.announce { --pin: var(--accent); }
.announce.pinned.pin-highlight { border: 2px solid var(--pin); background: color-mix(in srgb, var(--pin) 12%, var(--card)); }
.announce.pinned.pin-border { border: 1px solid var(--border); border-left: 6px solid var(--pin); }
.announce.pinned.pin-banner { padding-top: 0; overflow: hidden; border: 2px solid var(--pin); }
.announce.pinned.pin-banner .pin-label { display: block; margin: 0 -18px 12px; border-radius: 0; padding: 7px 18px; }
.announce.pinned .pin-label { background: var(--pin); color: var(--pin-ink, #1d1a10); }
.ann-main { display: flex; gap: 12px; align-items: flex-start; }
.ann-text { flex: 1; min-width: 0; }
.photos-left .ann-main { flex-direction: row-reverse; }
.photos-below .ann-main { flex-direction: column; }
.photos-below .ann-photos { flex-direction: row; flex-wrap: wrap; width: 100%; }
.ann-photos { display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; }
.thumb { width: 88px; height: 88px; padding: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--bg); cursor: zoom-in; position: relative; display: inline-block; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb.missing { display: none; }
.thumb.small { width: 70px; height: 70px; }
.thumb.add { display: flex; align-items: center; justify-content: center; font-size: 26px; color: var(--text-soft); cursor: pointer; margin: 0; font-weight: 400; border-style: dashed; }
.thumb .x { position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; border-radius: 50%; border: 0; background: rgba(0,0,0,.65); color: #fff; font-size: 12px; line-height: 22px; padding: 0; }
/* job photos (job-photos.js): stop card, Log a visit, review, recap */
.ph-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.ph-tile { position: relative; display: inline-block; }
.ph-x { position: absolute; top: -6px; right: -6px; width: 32px; height: 32px; min-height: 0; border-radius: 50%; border: 2px solid var(--card, #fff); background: rgba(0,0,0,.72); color: #fff; font-size: 14px; line-height: 1; padding: 0; margin: 0; cursor: pointer; }
.ph-wait { position: absolute; left: 0; right: 0; bottom: 0; font-size: 11px; text-align: center; background: rgba(0,0,0,.55); color: #fff; border-radius: 0 0 10px 10px; pointer-events: none; }
.ph-add { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; cursor: pointer; min-height: 44px; }
.ph-add-btn { display: flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; margin-top: 8px; }
.ph-list { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.ph-row { display: flex; gap: 12px; align-items: flex-start; }
.ph-cap { flex: 1 1 auto; min-width: 0; }
.ph-cap textarea { width: 100%; margin: 0; }
.thumb.tiny { width: 44px; height: 44px; border-radius: 8px; cursor: default; }
.ph-mini { gap: 6px; margin-top: 4px; }
.photo-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.rich { margin-top: 4px; font-size: 15px; line-height: 1.45; overflow-wrap: anywhere; }
.rich p, .rich ul, .rich ol, .rich blockquote, .rich h3 { margin: 0 0 6px; }
.rich ul, .rich ol { padding-left: 22px; }
.rich h3 { font-size: 17px; font-family: var(--font-heading); }
.rich blockquote { border-left: 3px solid var(--border); padding-left: 10px; color: var(--text-soft); }
@media (max-width: 380px) { .thumb { width: 72px; height: 72px; } }
/* text editor */
.rte { border: 1.5px solid var(--border); border-radius: 10px; background: var(--card); overflow: hidden; }
.rte:focus-within { border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 18%, transparent); }
.rte-bar { display: flex; flex-wrap: wrap; gap: 2px; padding: 5px; border-bottom: 1px solid var(--border); background: var(--bg); }
.rte-bar button { min-width: 34px; height: 32px; border: 0; border-radius: 6px; background: none; color: var(--text); font-size: 15px; }
.rte-bar button:hover { background: var(--card); }
.rte-bar button.on { background: var(--primary); color: var(--on-primary, #fff); }
.rte-box { min-height: 110px; max-height: 50vh; overflow-y: auto; padding: 12px 14px; font-size: 16px; line-height: 1.45; outline: none; }
.rte-box:empty::before { content: attr(data-placeholder); color: var(--text-soft); }
.rte-box p, .rte-box ul, .rte-box ol, .rte-box blockquote, .rte-box h3 { margin: 0 0 6px; }
.rte-box blockquote { border-left: 3px solid var(--border); padding-left: 10px; color: var(--text-soft); }
/* reactions */
.reacts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.react { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 99px; border: 1.5px solid var(--border); background: var(--card); font-size: 14px; color: var(--text); line-height: 1.3; }
.react span { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.react.mine { border-color: var(--link); background: color-mix(in srgb, var(--link) 12%, var(--card)); }
.react.mine span { color: var(--link); }
.react.add { color: var(--text-soft); font-size: 13px; }
.comment .reacts { margin-top: 6px; }
.comment .react { padding: 1px 7px; font-size: 13px; }
.react-pick { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; padding: 6px; margin-top: 6px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); box-shadow: 0 8px 24px rgba(0,0,0,.12); max-width: 340px; }
.react-pick button { border: 0; background: none; font-size: 20px; padding: 5px 0; border-radius: 8px; }
.react-pick button:hover { background: var(--bg); }
/* photo viewer */
.lightbox { position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,.9); display: flex; align-items: center; justify-content: center; }
.lightbox img { max-width: 94vw; max-height: 86vh; object-fit: contain; border-radius: 6px; }
.lb-x { position: absolute; top: max(12px, env(safe-area-inset-top)); right: 12px; width: 44px; height: 44px; border-radius: 50%; border: 0; background: rgba(255,255,255,.18); color: #fff; font-size: 20px; }
.lb-prev, .lb-next { position: absolute; top: 50%; transform: translateY(-50%); width: 44px; height: 64px; border: 0; background: rgba(255,255,255,.12); color: #fff; font-size: 32px; border-radius: 10px; }
.lb-prev { left: 8px; } .lb-next { right: 8px; }
.lb-count { position: absolute; bottom: max(14px, env(safe-area-inset-bottom)); color: #ddd; font-size: 14px; }
.ann-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
fieldset.plain { border: 0; padding: 0; margin: 8px 0 0; }
fieldset.plain legend { padding: 0; margin-bottom: 2px; }
.thumb.sample { cursor: default; }
.thumb.sample svg { width: 100%; height: 100%; display: block; }
.sample-tag { position: absolute; left: 4px; bottom: 4px; background: rgba(0,0,0,.6); color: #fff; font-size: 9.5px; font-weight: 600; padding: 2px 5px; border-radius: 5px; letter-spacing: .01em; }
/* popup sheet (replies from the home screen) */
.sheet-bg { position: fixed; inset: 0; z-index: 90; background: rgba(0,0,0,.45); display: flex; align-items: flex-end; justify-content: center; }
.sheet { background: var(--bg); width: 100%; max-width: 560px; max-height: 88vh; display: flex; flex-direction: column; border-radius: 18px 18px 0 0; box-shadow: 0 -8px 30px rgba(0,0,0,.2); animation: sheet-up .18s ease-out; }
@media (min-width: 700px) { .sheet-bg { align-items: center; } .sheet { border-radius: 18px; } }
@keyframes sheet-up { from { transform: translateY(30px); opacity: .6; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sheet { animation: none; } }
.sheet-head { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.sheet-head b { flex: 1; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-x { width: 36px; height: 36px; border-radius: 50%; border: 0; background: var(--card); color: var(--text); font-size: 16px; flex-shrink: 0; }
.sheet-body { overflow-y: auto; padding: 14px 16px max(16px, env(safe-area-inset-bottom)); overscroll-behavior: contain; }
.sheet-body .announce { margin-bottom: 0; }
.google-link { display: inline-flex; align-items: center; gap: 6px; }
.google-link svg { width: 15px; height: 15px; }
/* breathing room when a full-width button sits between cards */
.btn + .card, .btn + form.card { margin-top: 14px; }
.act-group { margin-left: auto; display: flex; gap: 6px; flex-shrink: 0; }
.small-btn.danger { background: var(--error); border-color: var(--error); color: var(--on-error, #fff); }
.confirm-del { background: var(--error-bg); border-radius: 10px; padding: 12px; margin: 4px 0 10px; }
.confirm-del .row { justify-content: flex-end; }
.msg + .card, .msg + form.card { margin-top: 14px; }
/* ---------- Messages ---------- */
.unread-pill { background: var(--error); color: var(--on-error, #fff); }
.setup-hint { border-color: color-mix(in srgb, var(--accent) 50%, var(--border)); background: color-mix(in srgb, var(--accent) 8%, var(--card)); }
.inbox-tools { display: flex; gap: 8px; align-items: center; margin-top: 14px; }
.inbox-tools input, .inbox-tools textarea { flex: 1; }
.inbox-tools .small-btn { padding: 12px 14px; flex-shrink: 0; }
.conv-list { padding: 4px 0; }
.conv-row { display: flex; gap: 12px; align-items: center; width: 100%; padding: 12px 16px; border: 0; border-top: 1px solid var(--border); background: none; text-align: left; color: var(--text); font: inherit; cursor: pointer; }
.conv-row:first-child { border-top: 0; }
.conv-row:hover { background: color-mix(in srgb, var(--bg) 60%, var(--card)); }
.avatar { width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; background: color-mix(in srgb, var(--primary) 14%, var(--card)); color: var(--primary); }
.conv-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.conv-name { font-weight: 600; display: flex; align-items: center; gap: 6px; min-width: 0; }
.conv-name .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-name .pill { margin-left: 0; flex-shrink: 0; }
.conv-prev { font-size: 13.5px; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-row.unread .conv-name { font-weight: 800; }
.conv-row.unread .conv-prev { color: var(--text); font-weight: 500; }
.conv-time { font-size: 12px; color: var(--text-soft); display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.dot { width: 10px; height: 10px; border-radius: 50%; background: var(--link); }
.convo-head { display: flex; gap: 12px; align-items: center; }
.convo-title { font-size: 22px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.convo-actions { display: flex; gap: 6px; flex-wrap: wrap; margin: 12px 0 4px; }
.thread-list { margin: 14px 0; display: flex; flex-direction: column; gap: 2px; }
.day-sep { text-align: center; margin: 12px 0 6px; font-size: 12px; color: var(--text-soft); }
.day-sep span { background: var(--bg); padding: 0 8px; }
.msg-row { display: flex; flex-direction: column; max-width: 84%; margin-bottom: 8px; }
.msg-row.in { align-self: flex-start; align-items: flex-start; }
.msg-row.out { align-self: flex-end; align-items: flex-end; }
.msg-row.note-msg { align-self: center; align-items: center; max-width: 92%; }
.bubble { padding: 9px 13px; border-radius: 16px; font-size: 15px; line-height: 1.4; overflow-wrap: anywhere; }
.msg-row.in .bubble { background: var(--card); border: 1px solid var(--border); border-bottom-left-radius: 5px; }
.msg-row.out .bubble { background: var(--primary); color: var(--on-primary, #fff); border-bottom-right-radius: 5px; }
.msg-row.out .bubble a { color: var(--on-primary, #fff); }
.msg-row.note-msg .bubble { background: color-mix(in srgb, var(--accent) 18%, var(--card)); border: 1px dashed color-mix(in srgb, var(--accent) 60%, var(--border)); }
.bubble .body { white-space: pre-wrap; }
.bubble .subj { font-weight: 700; margin-bottom: 3px; }
.bubble .files { margin-top: 6px; font-size: 13px; display: flex; gap: 10px; flex-wrap: wrap; }
.note-tag { font-size: 12px; font-weight: 700; color: var(--text-soft); margin-bottom: 3px; }
.msg-row .meta { font-size: 11.5px; color: var(--text-soft); margin-top: 3px; padding: 0 4px; }
.msg-row .meta .fail { color: var(--error); font-weight: 600; }
.msg-row .reacts { margin-top: 3px; }
.msg-row .reacts .react { padding: 1px 7px; font-size: 13px; }
.msg-row .reacts .react.add { opacity: 0; transition: opacity .15s; }
.msg-row:hover .reacts .react.add, .msg-row:focus-within .reacts .react.add, .msg-row .reacts .react.add:focus { opacity: 1; }
@media (hover: none) { .msg-row .reacts .react.add { opacity: .7; } }
.composer { position: sticky; bottom: 0; z-index: 5; margin-bottom: 0; border-radius: var(--radius) var(--radius) 0 0; box-shadow: 0 -6px 18px rgba(0,0,0,.06); padding: 12px 14px max(12px, env(safe-area-inset-bottom)); }
.composer .chips { margin: 0 0 8px; }
.composer textarea, .composer input { margin-bottom: 0; }
.composer #csub { margin-bottom: 8px; }
.notice { background: var(--error-bg); color: var(--error); border-radius: 10px; padding: 9px 12px; font-size: 13.5px; margin-bottom: 8px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.copy-row { display: flex; gap: 8px; }
.copy-row input { flex: 1; color: var(--text-soft); }
.conv-prev .newc { color: var(--link); font-weight: 600; }
.test-banner { background: color-mix(in srgb, var(--accent) 22%, var(--card)); border: 1px solid color-mix(in srgb, var(--accent) 60%, var(--border)); border-radius: 10px; padding: 9px 12px; font-size: 13.5px; margin: 12px 0; }
.test-card { border: 2px solid var(--accent); }
/* setup walkthroughs */
.ready-line { margin: 8px 0 4px; font-size: 14.5px; }
.pill.fail { background: var(--error-bg); color: var(--error); }
.subsection { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.addr-row { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.addr-row input { flex: 1; min-width: 0; }
.addr-row input#em-local { flex: 0 0 34%; }
.howto { padding-left: 20px; font-size: 14px; margin: 8px 0; }
.howto li { margin-bottom: 4px; }
.dns-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 10px; margin-top: 8px; }
table.dns { border-collapse: collapse; width: 100%; font-size: 13px; }
table.dns th, table.dns td { padding: 8px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
table.dns tr:last-child td { border-bottom: 0; }
table.dns code { font-size: 12px; word-break: break-all; }
table.dns .dns-val code { display: inline-block; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
ol.steps { list-style: none; padding: 0; margin: 12px 0 0; counter-reset: st; }
ol.steps li { position: relative; padding: 0 0 14px 38px; counter-increment: st; }
ol.steps li::before { content: counter(st); position: absolute; left: 0; top: -2px; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; background: var(--bg); border: 1.5px solid var(--border); color: var(--text-soft); }
ol.steps li.done::before { content: "✓"; background: var(--primary); border-color: var(--primary); color: var(--on-primary, #fff); }
ol.steps li.wait::before { background: color-mix(in srgb, var(--accent) 30%, var(--card)); border-color: var(--accent); color: var(--text); }
ol.steps li.fail::before { content: "!"; background: var(--error); border-color: var(--error); color: var(--on-error, #fff); }
ol.steps li:not(:last-child)::after { content: ""; position: absolute; left: 12px; top: 28px; bottom: 2px; width: 2px; background: var(--border); }
.st-h { display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap; align-items: baseline; }
.st-h span { font-size: 13px; color: var(--text-soft); }
ol.steps .small-btn { margin-top: 8px; }
.m.fail { color: var(--error); }
.num-list { margin-top: 8px; border: 1px solid var(--border); border-radius: 10px; max-height: 300px; overflow-y: auto; }
.num-list .row-btn { padding: 10px 12px; }
.num-list .row-btn.confirming { background: color-mix(in srgb, var(--accent) 16%, var(--card)); }
details.adv summary { cursor: pointer; list-style: none; }
details.adv summary::-webkit-details-marker { display: none; }
details.adv summary::after { content: " ▸"; color: var(--text-soft); }
details.adv[open] summary::after { content: " ▾"; }
.sheet.tall { max-height: 94vh; height: 94vh; }
/* confirmation popup (Saved / Logged!) */
.done-pop { position: fixed; inset: 0; z-index: 120; pointer-events: none; display: none; align-items: center; justify-content: center; padding: 30px; background: color-mix(in srgb, var(--primary) 45%, transparent); }
.done-pop.show { display: flex; animation: dp-fade .18s ease-out; }
.done-card { pointer-events: auto; cursor: pointer; background: var(--card); border-radius: 22px; padding: 28px 24px 24px; text-align: center; max-width: 320px; width: 100%; box-shadow: 0 20px 50px rgba(0,0,0,.3); animation: dp-pop .3s cubic-bezier(.2,1.4,.4,1); }
.done-check { width: 80px; height: 80px; border-radius: 50%; background: var(--accent); margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 25%, transparent); }
.done-check svg { width: 42px; height: 42px; stroke: var(--primary); stroke-width: 4; fill: none; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 60; stroke-dashoffset: 60; animation: dp-draw .45s .15s ease-out forwards; }
.done-card h2 { color: var(--primary); margin: 0 0 4px; font-size: 26px; }
.done-card p { margin: 0; color: var(--text-soft); }
.done-card p:empty { display: none; }
@keyframes dp-pop { from { transform: scale(.85); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes dp-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes dp-draw { to { stroke-dashoffset: 0 } }
@media (prefers-reduced-motion: reduce) { .done-pop.show, .done-card { animation: none; } .done-check svg { animation: none; stroke-dashoffset: 0; } }

/* notes in a conversation: quick list + jump-to highlight */
#notelist b { display: block; margin-bottom: 4px; }
.note-jump { display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid var(--border); padding: 9px 2px; cursor: pointer; color: inherit; font: inherit; }
.note-jump:first-of-type { border-top: 0; }
.note-jump:hover .nj-body { text-decoration: underline; }
.note-jump .nj-body { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.msg-row.flash .bubble { animation: msgflash 2.4s ease-out; }
@keyframes msgflash { 0%, 35% { box-shadow: 0 0 0 3px var(--accent, #e3b341); } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .msg-row.flash .bubble { animation: none; outline: 3px solid var(--accent, #e3b341); } }

/* conversation: name + buttons stay pinned at the top while you scroll (reply box is pinned at the bottom) */
.convo-top { position: sticky; top: 0; z-index: 6; background: var(--bg); margin: 0 -16px; padding: 10px 16px 8px; border-bottom: 1px solid var(--border); box-shadow: 0 6px 14px -10px rgba(0,0,0,.18); }
.convo-top .convo-head .avatar { width: 38px; height: 38px; font-size: 14px; }
.convo-top .convo-title { font-size: 19px; margin: 0; }
.convo-top .convo-actions { flex-wrap: nowrap; overflow-x: auto; margin: 8px 0 0; padding-bottom: 2px; scrollbar-width: none; }
.convo-top .convo-actions::-webkit-scrollbar { display: none; }
.convo-top .convo-actions .small-btn { flex: 0 0 auto; }
.convo-top #notelist, .convo-top #linkbox { margin: 8px 0 0; max-height: 45vh; overflow-y: auto; }
.convo-top #m:not(.hidden) { margin: 8px 0 0; }
.convo .thread-list { padding-top: 10px; }
.msg-row { scroll-margin-top: 170px; scroll-margin-bottom: 230px; }

/* client notes: about 5 show, the rest scroll inside the box; search on top */
.nsearch { margin: 0 0 8px; }
.notes-scroll { position: relative; overflow-y: auto; overscroll-behavior: contain; }
.notes-scroll.scrolls { border-bottom: 1px solid var(--border); padding-right: 4px; }
.note.hidden { display: none; }

/* email replies: which email you're answering */
.reply-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; font-size: 13.5px; background: color-mix(in srgb, var(--primary) 6%, var(--card)); border: 1px solid var(--border); border-radius: 10px; padding: 7px 10px; margin-bottom: 8px; }
.reply-bar > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.reply-bar .small-btn { flex: 0 0 auto; }
.reply-link { font-size: inherit; }
.msg-row.replying .bubble { outline: 2px dashed color-mix(in srgb, var(--accent) 80%, var(--border)); outline-offset: 2px; }

/* full-screen conversation (like iMessage / GoHighLevel): top bar and reply box fixed,
   only the messages scroll in between; the page itself never scrolls */
.wrap.convo { height: 100vh; height: 100dvh; display: flex; flex-direction: column; padding-bottom: 0; overflow: hidden; box-sizing: border-box; }
.wrap.convo > * { flex-shrink: 0; }
.wrap.convo .top { margin-bottom: 8px; }
.wrap.convo .convo-top { position: static; margin: 0 -16px; }
.wrap.convo #thread { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; margin: 0 -16px; padding: 10px 16px 12px; display: flex; flex-direction: column; }
.wrap.convo .test-banner { margin: 0 0 8px; font-size: 12.5px; padding: 6px 10px; }
.wrap.convo .composer { position: static; margin: 0 -16px; border-radius: 0; border-left: 0; border-right: 0; }
.wrap.convo .composer .rte-box { max-height: 28vh; min-height: 80px; }
.wrap.convo .composer textarea { max-height: 28vh; }
@media (min-width: 520px) { .wrap.convo .composer, .wrap.convo .convo-top, .wrap.convo #thread { margin-left: 0; margin-right: 0; } .wrap.convo .composer { border-radius: var(--radius) var(--radius) 0 0; border: 1px solid var(--border); border-bottom: 0; } }
.wrap.convo .msg-row { scroll-margin: 12px; }

/* calendar: month grid like v1 */
.cal-card { padding: 16px 14px; }
.cal-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.cal-month { font-family: var(--font-heading); font-size: 17px; color: var(--primary); }
.cal-arrow { width: 36px; height: 36px; border-radius: 50%; border: 0; background: color-mix(in srgb, var(--primary) 8%, var(--card)); color: var(--primary); font-size: 16px; cursor: pointer; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-week div { text-align: center; font-size: 10.5px; font-weight: 700; color: var(--text-soft); text-transform: uppercase; letter-spacing: .03em; padding-bottom: 6px; }
.cal-day { aspect-ratio: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 9px; font-size: 13px; color: var(--text); background: color-mix(in srgb, var(--card) 70%, var(--bg)); border: 1px solid transparent; padding: 0; font: inherit; }
.cal-day.empty { background: none; }
.cal-day.has { cursor: pointer; background: color-mix(in srgb, var(--link) 14%, var(--card)); border-color: color-mix(in srgb, var(--link) 30%, var(--border)); font-weight: 700; }
.cal-day.has:hover { background: color-mix(in srgb, var(--link) 22%, var(--card)); }
.cal-day.today { border-color: var(--accent); border-width: 2px; }
.cal-n { font-size: 13px; line-height: 1; }
.cal-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--link); margin-top: 3px; }
.cal-count { font-size: 9px; color: var(--primary); margin-top: 1px; line-height: 1; }
.cal-tech { font-size: 8px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: var(--text-soft); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 2px; margin-top: 1px; }
.pick-list { border: 1px solid var(--border); border-radius: 10px; margin: 6px 0 10px; overflow: hidden; }
.hist-list { margin-top: 6px; }
.hist-row { display: flex; justify-content: space-between; gap: 10px; width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid var(--border); padding: 10px 4px; font: inherit; color: inherit; cursor: pointer; }
.hist-row:first-child { border-top: 0; }
.hist-row:hover { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.hist-row .n { font-weight: 600; }
.hist-row .m { white-space: nowrap; color: var(--text-soft); font-size: 13px; }
.day-visit { display: block; width: 100%; text-align: left; background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; font: inherit; color: inherit; cursor: pointer; }
.day-visit:hover { border-color: var(--link); }
.day-visit .n { font-weight: 700; margin-bottom: 3px; }
.day-visit .n .m { font-weight: 400; }
.day-visit .m { font-size: 13.5px; color: var(--text-soft); }
.dv-who { font-size: 12.5px; font-weight: 600; color: var(--text-soft); margin-bottom: 3px; }
.dv-rate { color: var(--primary); font-weight: 600; }
.dv-notes { margin-top: 6px; font-size: 13px; background: var(--bg); border-radius: 8px; padding: 6px 8px; white-space: pre-wrap; }
.hits-h { font-size: 12.5px; font-weight: 700; color: var(--text-soft); text-transform: uppercase; letter-spacing: .03em; margin: 10px 2px 4px; }
.note-hit { display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left; background: none; border: 0; border-top: 1px solid var(--border); padding: 10px 12px; font: inherit; color: inherit; cursor: pointer; }
.note-hit:first-child { border-top: 0; }
.note-hit:hover { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.note-hit .n { font-weight: 600; font-size: 14px; }
.note-hit .n .m { font-weight: 400; color: var(--text-soft); font-size: 12.5px; }
.note-hit .snip { font-size: 13.5px; color: var(--text); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.note-hit.open .snip { -webkit-line-clamp: unset; }
.note-hit mark { background: color-mix(in srgb, var(--accent) 55%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }

/* ===== v1 look, for every company (colors come from the company's theme) ===== */
:root { --soil: #5b3a1f; --shadow: 0 6px 20px rgba(20, 48, 28, .07); }
body { overflow-x: clip; }
/* page header: logo, small label, big title, subtitle, grass edge */
.hero { position: relative; margin: -20px calc(50% - 50vw) 18px; padding: calc(16px + env(safe-area-inset-top)) calc(50vw - 50%) 44px; }
.hero .top { margin-bottom: 14px; }
.hero .top img { height: 54px; max-width: 190px; }
.hero .top img + .brand-name { display: none; }        /* the logo already says the name */
.hero .eyebrow { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--soil); font-weight: 600; margin-bottom: 6px; }
.hero h1 { color: var(--primary); font-size: 28px; }
.hero .sub { margin: 6px 0 0; font-size: 14.5px; }
.grass { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 30px; display: block; }
.grass .g-blades { fill: var(--grass, var(--link)); }
.grass .g-soil { fill: var(--soil); }
.hero + .back { margin-top: -8px; }
/* cards: soft shadow like v1 */
.card, .menu-card { box-shadow: var(--shadow); border-color: color-mix(in srgb, var(--border) 70%, var(--card)); }
/* home menu: icon tile + serif title */
.menu { gap: 14px; }
.menu-card { display: grid; grid-template-columns: 44px 1fr; column-gap: 14px; align-items: center; padding: 20px 18px; transition: transform .08s; }
.menu-card > .t, .menu-card > .d { grid-column: 2; }
.menu-card .t { font-family: var(--font-heading); font-size: 19px; color: var(--primary); }
.menu-card:not(:disabled):active { transform: scale(.985); }
.menu-ic { grid-row: span 2; width: 44px; height: 44px; border-radius: 12px; background: color-mix(in srgb, var(--link) 13%, var(--card)); display: flex; align-items: center; justify-content: center; }
.menu-ic svg { width: 24px; height: 24px; stroke: var(--link); fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.menu-card.soon .menu-ic { filter: grayscale(1); opacity: .6; }
/* form labels: small caps like v1 (not checkbox labels) */
label:not(.swatch):not(.upl-btn):not(.color-row):not(:has(> input[type=checkbox])):not(:has(> input[type=radio])) { font-size: 12.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--soil); }
input:not([type=checkbox]):not([type=radio]):not([type=color]), select, textarea { background-color: color-mix(in srgb, var(--card) 80%, var(--bg)); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 18%, transparent); }
.foot { line-height: 1.6; }
.foot b { font-family: var(--font-heading); font-size: 14px; color: var(--primary); }
/* bottom tab bar (v1) */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; background: color-mix(in srgb, var(--card) 96%, transparent); backdrop-filter: blur(6px); border-top: 1px solid var(--border); display: flex; justify-content: space-around; padding: 6px 4px calc(6px + env(safe-area-inset-bottom)); box-shadow: 0 -4px 18px rgba(20, 48, 28, .08); }
.tabbar button { flex: 1; max-width: 110px; background: none; border: 0; padding: 6px 2px; display: flex; flex-direction: column; align-items: center; gap: 3px; font: 600 11px var(--font-body); color: var(--text-soft); cursor: pointer; border-radius: 10px; position: relative; }
.tabbar button svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tabbar button.active { color: var(--link); }
.tabbar button.active::after { content: ""; position: absolute; bottom: 0; width: 4px; height: 4px; border-radius: 50%; background: var(--accent); }
body.has-tabs .wrap { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
.card.line > .row > b { font-size: 12.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--primary); }
/* home: one big main action, everything else as small tiles */
.menu-card.main { padding: 22px 18px; background: color-mix(in srgb, var(--link) 7%, var(--card)); border-color: color-mix(in srgb, var(--link) 25%, var(--border)); }
.menu-card.main .menu-ic { background: var(--primary); }
.menu-card.main .menu-ic svg { stroke: var(--on-primary, #fff); }
.menu.tiles { grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px; }
.menu-card.tile { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 8px; text-align: center; padding: 14px 3px 12px; min-width: 0; }
.menu-card.tile .menu-ic { width: 42px; height: 42px; grid-row: auto; }
.menu-card.tile .t { font-family: var(--font-body); font-size: 12.5px; font-weight: 600; color: var(--text); line-height: 1.25; overflow-wrap: normal; word-break: normal; hyphens: manual; letter-spacing: -.01em; }
.menu-card.tile .unread-pill { display: block; margin: 4px auto 0; width: fit-content; }
@media (max-width: 340px) { .menu.tiles { grid-template-columns: repeat(2, 1fr); } }
/* phones show the first 5 shortcuts; computers show them all (up to 8) */
.tabbar button:nth-child(n+6) { display: none; }
/* desktop: the tab bar becomes a slim left sidebar (bottom bars are a phone thing) */
@media (min-width: 900px) {
  .tabbar button:nth-child(n+6) { display: flex; }
  .tabbar { top: 0; bottom: 0; right: auto; width: 88px; flex-direction: column; justify-content: flex-start; gap: 6px; padding: 24px 8px; border-top: 0; border-right: 1px solid var(--border); box-shadow: 4px 0 18px rgba(20, 48, 28, .05); }
  .tabbar button { flex: 0 0 auto; max-width: none; padding: 10px 2px; }
  .tabbar button:hover { background: color-mix(in srgb, var(--link) 8%, transparent); color: var(--link); }
  .tabbar button.active { background: color-mix(in srgb, var(--link) 12%, transparent); }
  .tabbar button.active::after { display: none; }
  body.has-tabs { padding-left: 88px; }
  body.has-tabs .wrap { padding-bottom: 48px; }
  body.has-tabs .hero { margin-left: calc(50% - 50vw + 44px); margin-right: calc(50% - 50vw + 44px); padding-left: calc(50vw - 50% - 44px); padding-right: calc(50vw - 50% - 44px); }
}

/* shortcut bar editor */
.tabs-ed { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.te-row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--border); background: var(--card); }
.te-row:first-child { border-top: 0; }
.te-ic { width: 34px; height: 34px; border-radius: 9px; background: color-mix(in srgb, var(--link) 12%, var(--card)); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.te-ic svg { width: 20px; height: 20px; stroke: var(--link); fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.te-n { flex: 1; font-weight: 600; min-width: 0; }
.te-tag { display: inline-block; font-size: 11px; font-weight: 600; color: var(--text-soft); background: var(--bg); border-radius: 6px; padding: 1px 6px; margin-left: 4px; white-space: nowrap; }
.te-b { width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--border); background: var(--card); color: var(--text); font-size: 15px; padding: 0; flex-shrink: 0; cursor: pointer; }
.te-b:disabled { opacity: .3; cursor: default; }
.te-x { color: var(--error); }
.te-lock { border-color: transparent; background: none; }
.te-add { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 12px; }
.chip-btn { border: 1px dashed color-mix(in srgb, var(--link) 50%, var(--border)); background: none; color: var(--link); font: 600 13px var(--font-body); border-radius: 999px; padding: 6px 12px; cursor: pointer; }
.chip-btn:disabled { opacity: .4; cursor: default; }
.te-note { margin: 10px 2px 0; }
/* pinned announcement, shrunk to one line after you've seen it */
.announce-mini { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; color: var(--text); background: color-mix(in srgb, var(--pin) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--pin) 45%, var(--border)); border-left: 5px solid var(--pin); border-radius: 12px; padding: 10px 12px; margin-bottom: 14px; cursor: pointer; box-shadow: var(--shadow); }
.announce-mini:hover { border-color: var(--pin); }
.am-pin { flex-shrink: 0; }
.am-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14px; }
.am-t { font-weight: 700; }
.am-s { color: var(--text-soft); }
.am-c { flex-shrink: 0; font-size: 12.5px; color: var(--text-soft); }
.am-more { flex-shrink: 0; font-size: 12.5px; font-weight: 700; color: var(--link); }

/* ===== theme editor choices (set on <html data-*> by the company's theme) ===== */
.g-soft { fill: var(--grass); opacity: .5; }
.divider-img { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 36px; object-fit: cover; display: block; }
html[data-divider=none] .hero { padding-bottom: 18px; border-bottom: 1px solid var(--border); }
/* header: colored band (v1's original striped header) */
html[data-header=band] .hero { background: repeating-linear-gradient(100deg, var(--primary) 0 46px, var(--primary-hover) 46px 92px); color: var(--on-primary); padding-top: calc(22px + env(safe-area-inset-top)); }
html[data-header=band] .hero h1, html[data-header=band] .hero .brand-name { color: var(--on-primary); }
html[data-header=band] .hero .sub, html[data-header=band] .hero .who, html[data-header=band] .hero .who a, html[data-header=band] .hero .who button { color: color-mix(in srgb, var(--on-primary) 82%, transparent); }
html[data-header=band] .hero .eyebrow { color: var(--accent); }
/* header: your picture behind it */
html[data-header=image] .hero { background: linear-gradient(180deg, rgba(0,0,0,.30), rgba(0,0,0,.58)), var(--header-img) center / cover no-repeat; color: #fff; padding-top: calc(26px + env(safe-area-inset-top)); }
html[data-header=image] .hero h1, html[data-header=image] .hero .brand-name { color: #fff; }
html[data-header=image] .hero .sub, html[data-header=image] .hero .who, html[data-header=image] .hero .who a, html[data-header=image] .hero .who button { color: rgba(255,255,255,.88); }
html[data-header=image] .hero .eyebrow { color: var(--accent); }
/* cards */
html[data-cards=border] .card, html[data-cards=border] .menu-card { box-shadow: none; border-color: var(--border); }
html[data-cards=flat] .card, html[data-cards=flat] .menu-card { box-shadow: none; border-color: transparent; background: color-mix(in srgb, var(--card) 72%, var(--bg)); }
html[data-cards=lifted] .card, html[data-cards=lifted] .menu-card { box-shadow: 0 14px 34px rgba(20, 48, 28, .13); border-color: transparent; }
html[data-cards=lifted] .menu-card:not(:disabled):hover { transform: translateY(-2px); }
/* spacing */
html[data-density=compact] .card { padding: 13px 14px; margin-bottom: 10px; }
html[data-density=compact] .menu-card { padding: 14px; }
html[data-density=compact] .menu-card.tile { padding: 10px 3px 9px; }
html[data-density=compact] .menu.tiles { gap: 8px; }
html[data-density=compact] .hero { padding-bottom: 38px; }
html[data-density=compact] .hero h1 { font-size: 25px; }
/* icons */
.menu-ic .ic-img, .te-ic .ic-img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.menu-ic:has(.ic-img), .te-ic:has(.ic-img) { background: none; overflow: hidden; }
html[data-icons=circle] .menu-ic, html[data-icons=circle] .te-ic { border-radius: 50%; }
html[data-icons=plain] .menu-ic, html[data-icons=plain] .te-ic { background: none; }
html[data-icons=plain] .menu-card.tile .menu-ic svg { width: 30px; height: 30px; }
html[data-icons=solid] .menu-ic, html[data-icons=solid] .te-ic { background: var(--primary); }
html[data-icons=solid] .menu-ic svg, html[data-icons=solid] .te-ic svg { stroke: var(--on-primary); }
/* home tiles per row */
.menu.tiles { grid-template-columns: repeat(var(--tiles, 3), minmax(0, 1fr)); }
html[style*="--tiles: 4"] .menu-card.tile .t { font-size: 11.5px; }
.foot-art { display: block; max-width: 220px; max-height: 90px; margin: 26px auto 0; object-fit: contain; }
/* tab bar styles */
.tabbar .ic-img { width: 24px; height: 24px; border-radius: 6px; object-fit: cover; }
html[data-tabbar=minimal] .tabbar button span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
html[data-tabbar=minimal] .tabbar button { padding: 10px 2px; }
@media (max-width: 899px) {
  html[data-tabbar=floating] .tabbar { left: 12px; right: 12px; bottom: calc(10px + env(safe-area-inset-bottom)); border: 1px solid var(--border); border-radius: 22px; padding: 6px 4px; box-shadow: 0 10px 30px rgba(20, 48, 28, .18); }
  html[data-tabbar=floating] body.has-tabs .wrap { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
}
@media (min-width: 900px) {
  html[data-tabbar=floating] .tabbar { top: 12px; bottom: 12px; left: 12px; border: 1px solid var(--border); border-radius: 22px; box-shadow: 0 10px 30px rgba(20, 48, 28, .12); }
  html[data-tabbar=floating] body.has-tabs { padding-left: 100px; }
  /* the header band spans the page beside the wider floating side bar (was 6px too wide: sideways scroll) */
  html[data-tabbar=floating] body.has-tabs .hero { margin-left: calc(50% - 50vw + 50px); margin-right: calc(50% - 50vw + 50px); padding-left: calc(50vw - 50% - 50px); padding-right: calc(50vw - 50% - 50px); }
}

/* ===== theme editor ===== */
.wrap.te-wrap { max-width: 1120px; padding-bottom: 120px; }
.te-grid { display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) {
  .te-grid { grid-template-columns: minmax(0, 1fr) 390px; align-items: start; }
  .te-preview { order: 2; position: sticky; top: 16px; }
  .te-controls { order: 1; }
}
.tp-label { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--soil); margin: 0 4px 8px; }
.tp-phone { border: 10px solid #1d1f1c; border-radius: 34px; background: var(--bg); overflow: hidden; height: 640px; max-height: 70vh; position: relative; box-shadow: 0 18px 50px rgba(0,0,0,.18); }
@media (max-width: 899px) { .tp-phone { height: 430px; } }
.tp-screen { height: 100%; overflow-y: auto; overflow-x: hidden; position: relative; font-size: 15px; }
.tp-screen .hero.tp-hero { margin: 0; padding: 16px 14px 40px; }
.tp-screen .hero .top { margin-bottom: 10px; }
.tp-screen .hero .top img { height: 40px; }
.tp-screen .hero h1 { font-size: 22px; }
.tp-screen .hero .sub { font-size: 13px; }
.tp-screen .grass, .tp-screen .divider-img { height: 22px; }
.tp-body { padding: 14px 12px 90px; }
.tp-body .announce-mini { margin-bottom: 10px; padding: 8px 10px; }
.tp-body .menu-card.main { padding: 14px 12px; grid-template-columns: 38px 1fr; }
.tp-body .menu-card.main .menu-ic, .tp-body .menu-ic { width: 38px; height: 38px; }
.tp-body .menu-card .t { font-size: 16px; }
.tp-body .menu-card .d { font-size: 12px; }
.tp-body .menu-card.tile .t { font-size: 11px; }
.tp-body .menu.tiles { gap: 8px; margin-top: 10px; }
.tp-body .foot { margin-top: 16px; }
.tabbar.tp-tabbar { position: absolute; left: 0; right: 0; bottom: 0; top: auto; width: auto; flex-direction: row; padding: 6px 2px 8px; border-right: 0; border-top: 1px solid var(--border); box-shadow: 0 -4px 18px rgba(20,48,28,.08); }
.tabbar.tp-tabbar > span { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; font: 600 10px var(--font-body); color: var(--text-soft); position: relative; }
.tabbar.tp-tabbar > span.active { color: var(--link); }
.tabbar.tp-tabbar svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tabbar.tp-tabbar .ic-img { width: 21px; height: 21px; }
html[data-tabbar=floating] .tabbar.tp-tabbar { left: 8px; right: 8px; bottom: 8px; top: auto; border: 1px solid var(--border); border-radius: 18px; }
html[data-tabbar=minimal] .tabbar.tp-tabbar > span > span { display: none; }
/* sections */
.te-sec { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 12px; box-shadow: var(--shadow); padding: 0 18px; }
.te-sec[open] { padding-bottom: 18px; }
.te-sec > summary { cursor: pointer; padding: 15px 18px; margin: 0 -18px; font-weight: 700; font-size: 16px; list-style: none; display: flex; align-items: center; justify-content: space-between; }
.te-sec > summary::-webkit-details-marker { display: none; }
.te-sec > summary::after { content: "▾"; color: var(--text-soft); transition: transform .15s; }
.te-sec[open] > summary::after { transform: rotate(180deg); }
.te-sec label:first-of-type { margin-top: 0; }
/* segmented choices */
.seg { display: flex; flex-wrap: wrap; gap: 6px; }
.seg button { flex: 1 1 auto; min-width: 72px; padding: 9px 10px; border-radius: 10px; border: 1.5px solid var(--border); background: var(--card); color: var(--text); font: 600 13.5px var(--font-body); cursor: pointer; }
.seg button.on { border-color: var(--link); background: color-mix(in srgb, var(--link) 12%, var(--card)); color: var(--link); }
/* presets */
.presets { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.preset { text-align: left; border: 1.5px solid var(--border); border-radius: 12px; background: var(--card); padding: 10px; font: inherit; color: var(--text); cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
.preset:hover { border-color: var(--link); }
.preset.on { border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 20%, transparent); }
.preset .m { font-size: 12px; }
.pr-sw { display: flex; height: 22px; border-radius: 6px; overflow: hidden; margin-bottom: 4px; border: 1px solid rgba(0,0,0,.08); }
.pr-sw i { flex: 1; }
/* dividers */
.dividers { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.dv { border: 1.5px solid var(--border); border-radius: 10px; background: var(--card); padding: 6px 6px 7px; font: 600 12px var(--font-body); color: var(--text); cursor: pointer; display: flex; flex-direction: column; gap: 5px; align-items: stretch; }
.dv.on { border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 20%, transparent); }
.dv-art { position: relative; height: 26px; border-radius: 6px; background: var(--bg); overflow: hidden; display: flex; align-items: center; justify-content: center; }
.dv-art .grass, .dv-art .divider-img { height: 22px; }
/* colors */
.colors { display: grid; gap: 6px; }
@media (min-width: 600px) { .colors { grid-template-columns: 1fr 1fr; } }
label.color-row { display: flex; align-items: center; gap: 10px; margin: 0; padding: 6px 8px; border: 1px solid var(--border); border-radius: 10px; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--text); cursor: pointer; }
label.color-row input[type=color] { width: 38px; height: 34px; padding: 0; border: 0; border-radius: 8px; background: none; flex-shrink: 0; cursor: pointer; }
label.color-row > span { flex: 1; display: flex; flex-direction: column; min-width: 0; }
label.color-row .m { font-size: 12px; font-weight: 400; }
label.color-row code { font-size: 12px; color: var(--text-soft); }
.ok-line { color: var(--link); font-weight: 600; }
.font-sample { margin-top: 12px; padding: 12px; border-radius: 10px; background: var(--bg); display: flex; flex-direction: column; gap: 4px; }
.font-sample b { font-size: 20px; color: var(--primary); }
/* uploads */
.upl { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 12px 0 0; }
.upl > .m { flex-basis: 100%; }
.upl-img { max-height: 48px; max-width: 180px; border-radius: 8px; border: 1px solid var(--border); object-fit: contain; background: var(--bg); }
label.upl-btn { margin: 0; text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--text); cursor: pointer; display: inline-block; }
/* menu rows */
.te-menu { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.tm-row { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-top: 1px solid var(--border); background: var(--card); }
.tm-row:first-child { border-top: 0; }
.tm-row.off { opacity: .5; }
.tm-row .tm-name { flex: 1; min-width: 0; padding: 8px 10px; font-size: 14px; }
.tm-row .tm-n { flex: 1; font-weight: 600; font-size: 14px; }
/* save bar */
.savebar { position: fixed; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom)); transform: translate(-50%, 140%); z-index: 60; display: flex; align-items: center; gap: 8px; background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 10px 12px; box-shadow: 0 14px 40px rgba(0,0,0,.2); transition: transform .2s ease; max-width: calc(100vw - 24px); flex-wrap: wrap; justify-content: center; }
.savebar.show { transform: translate(-50%, 0); }
.savebar .sb-t { font-weight: 700; font-size: 14px; margin-right: 4px; }
@media (prefers-reduced-motion: reduce) { .savebar { transition: none; } }

label .hint { text-transform: none; letter-spacing: 0; font-weight: 400; }
input[type=range], input[type=checkbox], input[type=radio] { accent-color: var(--link); }
.ai-sec { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 14%, var(--card)), var(--card) 60%); }
.ai-ex { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.ai-sec .btn { margin-top: 12px; }

/* visit form: the card with the problem gets a red outline */
.card.bad { border-color: var(--error) !important; box-shadow: 0 0 0 2px color-mix(in srgb, var(--error) 30%, transparent); }
.day-visit .dv-rate, .person .dv-rate { font-size: 12.5px; margin: 1px 0 3px; }
.act-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 14px; }
.act-row .btn { margin: 0; flex: 1 1 140px; }
a.small-btn { text-decoration: none; display: inline-flex; align-items: center; flex-shrink: 0; }
.stop-note { margin-top: 8px; font-size: 13px; color: var(--text-soft); white-space: pre-wrap; border-left: 3px solid var(--border); padding-left: 8px; }
.person.off { opacity: .6; }
.person-acts { display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.person-acts { margin-left: auto; }
/* computers: use more of the screen (phones keep the narrow column) */
@media (min-width: 900px) {
  .wrap:not(.te-wrap) { max-width: 720px; }
}
a.btn { display: block; text-align: center; text-decoration: none; box-sizing: border-box; }

/* ---------- loading animation (style picked in the theme editor, colors from the theme) */
.loader { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 44px 0 24px; color: var(--text-soft); font-size: 14px; }
.ld { display: inline-flex; align-items: flex-end; justify-content: center; gap: 5px; width: 40px; height: 36px; }
.ld i { display: none; }
/* spinner (default) */
.ld { box-sizing: border-box; }
html:not([data-loader]) .ld, html[data-loader=spin] .ld { width: 36px; border-radius: 50%; border: 4px solid color-mix(in srgb, var(--link) 18%, transparent); border-top-color: var(--link); animation: ld-spin .8s linear infinite; }
/* bouncing dots */
html[data-loader=dots] .ld { align-items: center; width: auto; }
html[data-loader=dots] .ld i:nth-child(-n+3) { display: block; width: 11px; height: 11px; border-radius: 50%; background: var(--link); animation: ld-bounce .9s ease-in-out infinite; }
html[data-loader=dots] .ld i:nth-child(2) { animation-delay: .15s; }
html[data-loader=dots] .ld i:nth-child(3) { animation-delay: .3s; }
/* growing grass */
html[data-loader=grass] .ld { width: auto; gap: 3px; border-bottom: 4px solid var(--soil); padding: 0 4px; }
html[data-loader=grass] .ld i { display: block; width: 7px; height: 30px; background: var(--grass); clip-path: polygon(0 100%, 45% 0, 100% 100%); transform-origin: bottom; animation: ld-grow 1.1s ease-in-out infinite; }
html[data-loader=grass] .ld i:nth-child(2) { animation-delay: .12s; height: 24px; }
html[data-loader=grass] .ld i:nth-child(3) { animation-delay: .24s; }
html[data-loader=grass] .ld i:nth-child(4) { animation-delay: .36s; height: 22px; }
html[data-loader=grass] .ld i:nth-child(5) { animation-delay: .48s; }
/* pulse */
html[data-loader=pulse] .ld { width: 36px; height: 36px; border-radius: 50%; background: var(--link); animation: ld-pulse 1.1s ease-in-out infinite; }
@keyframes ld-spin { to { transform: rotate(360deg); } }
@keyframes ld-bounce { 0%, 80%, 100% { transform: translateY(0); opacity: .5; } 40% { transform: translateY(-12px); opacity: 1; } }
@keyframes ld-grow { 0%, 100% { transform: scaleY(.35); } 50% { transform: scaleY(1); } }
@keyframes ld-pulse { 0% { transform: scale(.55); opacity: .9; } 100% { transform: scale(1.15); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .ld, .ld i { animation-duration: 2.4s !important; } }
/* while switching screens: a small loader floats in so you know the tap worked */
#navload { position: fixed; left: 50%; top: 38%; transform: translate(-50%, -50%); z-index: 70; background: var(--card); border: 1px solid var(--border); border-radius: 18px; padding: 4px 28px 0; box-shadow: 0 14px 40px rgba(0,0,0,.16); opacity: 0; pointer-events: none; transition: opacity .15s; }
#navload.show { opacity: 1; }
#navload .loader { padding: 18px 0 16px; }
body.has-tabs #navload { margin-left: 0; }
@media (min-width: 900px) { body.has-tabs #navload { left: calc(50% + 44px); } }
.loader-demo { border: 1px dashed var(--border); border-radius: 12px; margin-top: 8px; }
.loader-demo .loader { padding: 16px 0 12px; }

/* ---------- campaigns */
.step { position: relative; }
.step-wait { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; color: var(--text-soft); }
.step-wait input { width: 70px; margin: 0; }
.step-wait select { width: auto; margin: 0; }
.step + .step::before { content: ""; position: absolute; left: 26px; top: -15px; width: 2px; height: 14px; background: var(--border); }
.field-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.field-chips .chip-btn { padding: 4px 10px; font-size: 12px; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.stat { background: color-mix(in srgb, var(--link) 7%, var(--card)); border-radius: 10px; padding: 10px; text-align: center; }
.stat b { display: block; font-size: 20px; color: var(--primary); }
.stat span { font-size: 12px; color: var(--text-soft); }
.step-res { margin-top: 10px; }
.step-res summary { cursor: pointer; color: var(--link); font-weight: 600; font-size: 14px; }
/* campaign step that sends a newsletter */
.nl-use { margin-top: 10px; }
.nl-pick { display: flex; gap: 10px; align-items: flex-start; }
.nl-pick-thumb { flex: 0 0 56px; width: 56px; height: 56px; border-radius: 10px; border: 1px solid var(--border); background: var(--bg); overflow: hidden; display: grid; place-items: center; font-size: 24px; }
.nl-pick-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nl-pick-main { flex: 1; min-width: 0; }
.nl-pick-main select { margin-top: 0; }
.nl-pick-sub { overflow-wrap: anywhere; }
.nl-mode button { flex: 1 1 140px; min-width: 0; white-space: normal; }
.nl-mode button[disabled] { opacity: .45; cursor: not-allowed; }
.nl-step [data-nlrm] { margin-top: 12px; }
.empty-state p { margin: 6px 0 0; }
/* space between a message box and buttons right under it */
.msg + .seg, .msg + .act-row, .msg + details, .msg + .btn { margin-top: 14px; }
/* the picked choice in a row of buttons is clearly picked (it looked greyed out in some themes) */
.seg button.on { background: var(--primary); border-color: var(--primary); color: var(--on-primary, #fff); }

/* ---------- credits (theme colors only) */
.msg.info { background: color-mix(in srgb, var(--primary) 8%, var(--card)); color: var(--text); border-left: 4px solid var(--primary); }
.cr-top { text-align: center; }
.cr-big { font-family: var(--font-heading); font-size: 56px; font-weight: 700; line-height: 1; color: var(--primary); overflow-wrap: anywhere; }
.cr-big-l { color: var(--text-soft); font-size: 14px; margin-top: 4px; }
.cr-bar { height: 10px; border-radius: 99px; background: var(--border); overflow: hidden; margin: 18px 0 8px; }
.cr-bar span { display: block; height: 100%; border-radius: inherit; background: var(--primary); }
.cr-line { margin: 6px 0 0; font-size: 14px; color: var(--text); }
.cr-plan { margin: 10px 0 0; }
.cr-top .btn { margin-top: 16px; }
.cr-h2 { font-size: 19px; margin: 22px 0 10px; }
.cr-list { list-style: none; margin: 0; padding: 0; }
.cr-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-top: 1px solid var(--border); }
.cr-row:first-child { border-top: 0; padding-top: 0; }
.cr-what { min-width: 0; flex: 1; }
.cr-what .n { font-weight: 600; overflow-wrap: anywhere; }
.cr-what .m { margin-top: 2px; }
.cr-amt { flex-shrink: 0; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text); }
.cr-amt.plus { color: var(--primary); }
.cr-amt.minus { color: var(--text-soft); }
.cr-note { margin: 12px 0 0; }
.credit-line { margin: 8px 0 0; }
.credit-line.low { color: var(--text); font-weight: 600; }
.msg.credit-out a { color: inherit; font-weight: 700; text-decoration: underline; }

/* list rows with rename / copy / delete on the right (web/rowactions.js) */
.ra-row { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--border); }
.ra-row:first-child { border-top: 0; }
.ra-row > .row-btn { border-top: 0; flex: 1 1 auto; min-width: 0; padding: 12px 4px; }
.ra-acts { display: flex; gap: 6px; flex-shrink: 0; padding-right: 4px; }
.ra-acts .te-b.sure { width: auto; padding: 0 10px; font-size: 13px; font-weight: 600; background: color-mix(in srgb, var(--accent) 22%, var(--card)); }
@media (max-width: 480px) { .ra-row { flex-wrap: wrap; } .ra-acts { width: 100%; justify-content: flex-end; padding: 0 4px 10px; } }

/* photo library (web/library.js): picker sheet + Photos page */
.lib-bar { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.lib-bar .lib-q { margin: 0; width: 100%; box-sizing: border-box; }
.lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 6px; }
.lib-grid[aria-busy=true] { opacity: .6; }
.lib-cell { min-width: 0; }
.lib-pick { position: relative; display: block; width: 100%; aspect-ratio: 1; padding: 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: color-mix(in srgb, var(--text) 6%, var(--bg)); cursor: pointer; }
.lib-pick img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lib-pick:focus-visible { outline: 3px solid var(--link); outline-offset: 2px; }
.lib-tag { position: absolute; left: 4px; bottom: 4px; padding: 1px 6px; border-radius: 6px; background: rgba(0,0,0,.6); color: #fff; font: 600 11px var(--font-body); }
.lib-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 5px; background: rgba(0,0,0,.6); color: #fff; font: 600 11px/1.3 var(--font-body); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-pick.busy { opacity: .55; cursor: progress; }
.lib-pick.missing img, .lib-big.missing img { visibility: hidden; }
.lib-note { margin: 0; font-size: 13px; }
.lib-share-box { margin: 4px 0 10px; }
.lib-share-box .btn { width: 100%; }
.lib-more { display: block; margin: 12px auto 0; }
.vd-photos .photo-pick { margin-top: 8px; }
.vd-photos .msg { margin-top: 8px; }
.lib-more[hidden], .lib-empty[hidden] { display: none; }
.lib-empty { margin: 10px 0; }
.lib-top { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 10px; }
.lib-big { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.lib-big img { width: 100%; max-height: 46vh; object-fit: contain; border-radius: 8px; display: block; background: color-mix(in srgb, var(--text) 6%, var(--bg)); }
.lib-detail .sheet-body textarea, .lib-detail .sheet-body input { width: 100%; box-sizing: border-box; }
.lib-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.lib-acts .btn { flex: 1 1 140px; width: auto; }
.lib-acts .btn.sure { background: var(--error); border-color: var(--error); color: var(--on-error, #fff); }
.lib-page .msg .lib-undo { margin-left: 8px; }

/* importer (web/importer.js): where it comes from + the review table */
.imp-lead { margin: 0 0 10px; }
.imp-q { font-weight: 600; margin: 6px 0 8px; }
.imp-docs { display: grid; gap: 8px; margin-bottom: 14px; }
.imp-doc { display: flex; gap: 10px; align-items: flex-start; margin: 0; padding: 10px 12px; border: 1.5px solid var(--border); border-radius: 10px; cursor: pointer; font-weight: 400; }
.imp-doc:has(input:checked) { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 6%, var(--card)); }
.imp-doc input { width: auto; margin: 3px 0 0; flex-shrink: 0; }
.imp-doc b { display: block; font-weight: 600; }
.imp-doc .m { display: block; font-size: 13px; color: var(--text-soft); }
.imp-pick { margin-right: 8px; }
.imp-files { display: inline-block; margin: 8px 0; overflow-wrap: anywhere; }
.imp-tip { margin-top: 12px; }
.rv-only { display: flex; align-items: center; gap: 8px; margin: 4px 0 12px; font-weight: 500; }
.rv-only input { width: auto; margin: 0; }
.rv-list { display: grid; gap: 10px; }
.rv-row { background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--border); border-radius: 12px; padding: 12px; min-width: 0; }
.rv-row.check { border-left-color: var(--accent); }
.rv-row.bad { border-left-color: var(--error); }
.rv-row.off { opacity: .55; }
.rv-keep { display: flex; align-items: center; gap: 8px; margin: 0; font-weight: 600; font-size: 14px; }
.rv-keep input { width: auto; margin: 0; }
.rv-flags { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.rv-flags:empty { display: none; }
.rv-flag { font-size: 13px; padding: 4px 8px; border-radius: 6px; background: color-mix(in srgb, var(--text) 5%, var(--card)); color: var(--text-soft); overflow-wrap: anywhere; }
.rv-flag.error { background: var(--error-bg); color: var(--error); font-weight: 600; }
.rv-flag.warn { background: color-mix(in srgb, var(--accent) 18%, var(--card)); color: var(--text); }
.rv-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 10px; }
label.rv-f { margin: 10px 0 0; min-width: 0; }
.rv-f.wide { grid-column: 1 / -1; }
.rv-f input, .rv-f textarea { margin-top: 4px; width: 100%; min-width: 0; padding: 10px 12px; }
.rv-more { display: block; margin: 12px auto 0; }
.rv-more[hidden] { display: none; }
.rv-sum .n { font-weight: 600; }
.rv-note { margin: 0 0 14px; }
.svc-price { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 8px; }
.vp-amt { margin-left: auto; padding-left: 12px; white-space: nowrap; }
/* "New update ready" (app.js): sits above the shortcut bar; tap to load, with a progress bar */
.update-bar { position: fixed; left: 12px; right: 12px; bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 60; max-width: 520px; margin: 0 auto;
  padding: 12px 16px; border-radius: 12px; background: var(--ink, #2f2a24); color: #fff; box-shadow: 0 6px 24px rgba(0,0,0,.25); font-weight: 600; }
.update-bar .ub-btn { all: unset; display: block; width: 100%; cursor: pointer; text-align: center; font: inherit; color: inherit; }
.update-bar .ub-t { font-size: 14px; margin-bottom: 8px; }
.update-bar .ub-track { height: 6px; border-radius: 99px; background: rgba(255,255,255,.25); overflow: hidden; }
.update-bar .ub-fill { height: 100%; background: #fff; border-radius: 99px; transition: width .2s; }
/* Home: today's route card, My tools, All tools, pin editor (theme colors only) */
.rc-wrap { margin-top: 12px; }
.rc-wrap:empty { display: none; }
.rc.card { padding: 14px 16px; margin: 0; }
.rc-t { font-family: var(--font-heading); font-size: 19px; font-weight: 600; color: var(--primary); }
.rc-sub { color: var(--text-soft); font-size: 14px; margin-top: 2px; overflow-wrap: anywhere; }
.rc-bar { height: 6px; border-radius: 99px; background: color-mix(in srgb, var(--link) 15%, var(--card)); overflow: hidden; margin-top: 10px; }
.rc-bar i { display: block; height: 100%; background: var(--link); border-radius: inherit; }
.rc-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.rc-acts .small-btn { min-height: 44px; padding: 10px 14px; display: inline-flex; align-items: center; text-decoration: none; }
.rc-acts .small-btn.act { background: var(--primary); color: var(--on-primary, #fff); border-color: var(--primary); }
.rc-done .rc-t { color: var(--link); }
.rc-addlink { display: inline-block; margin-top: 6px; min-height: 44px; font-size: 14px; }
.btn.rc-build { margin: 0; display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 52px; }
.rc-ic { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tools-head { display: flex; align-items: center; justify-content: space-between; margin: 22px 2px 0; }
.tools-head h2 { font-size: 18px; margin: 0; }
.tools-head .link { min-height: 44px; min-width: 44px; font-size: 15px; }
.menu.tiles.mytools { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 8px; }
.menu-card.tile { min-height: 44px; }
.tools-h { font-size: 17px; margin: 20px 2px 8px; color: var(--text-soft); text-transform: uppercase; letter-spacing: .06em; font-family: var(--font-body); }
.tools-list { gap: 10px; }
.tools-list .menu-card { padding: 14px 16px; }
#mytools .tabs-ed { margin-top: 8px; }
.pe-note { margin: 8px 2px; }
.pe-empty { padding: 12px; }
.pe-star { color: var(--accent); font-size: 18px; }
.te-b.pe-star.on { color: var(--accent); width: 44px; height: 44px; }
#mytools .te-b, .card .pe-list .te-b { width: 44px; height: 44px; }
.pe-lock { width: 44px; text-align: center; border: 0; font-size: 14px; }
.pe-all { background: color-mix(in srgb, var(--card) 80%, var(--bg)); }
.pe-more { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.pe-more .m { width: 100%; }
.pe-add { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; border: 1px dashed color-mix(in srgb, var(--link) 50%, var(--border)); background: var(--card); color: var(--text); font: 600 14px var(--font-body); border-radius: 999px; padding: 6px 14px; cursor: pointer; }
.pe-add:disabled { opacity: .45; cursor: default; }
.pe-acts { gap: 8px; margin-top: 12px; flex-wrap: wrap; align-items: center; }

/* fixing a visit (0076): Edit / Delete side by side, the billed lock, the change history */
.vd-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.vd-acts .btn { margin-top: 0; min-height: 44px; }
.vd-lock .link { min-height: 44px; display: inline-flex; align-items: center; }
.vd-change { padding: 8px 0; border-top: 1px solid var(--border); line-height: 1.4; }
.vd-change:first-of-type { border-top: 0; }
#vd-delf .btn { min-height: 44px; }
.cl-visit { min-height: 44px; }
/* crews (0101) */
.crew-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: middle; flex-shrink: 0; }
.crew-pill { display: inline-flex; align-items: center; font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.crew-line { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 4px; }
.skill-tag { display: inline-block; font-size: 11.5px; padding: 1px 8px; border-radius: 999px; background: var(--ok-bg); color: var(--primary); }
.crew-swatch { width: 34px; height: 34px; border-radius: 50%; border: 3px solid transparent; cursor: pointer; padding: 0; }
.crew-swatch.on { border-color: var(--text); box-shadow: 0 0 0 2px var(--card) inset; }
.crew-filter { display: flex; gap: 6px; flex-wrap: wrap; margin: 6px 0 2px; }
.crew-filter button { font-size: 13px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--border); background: transparent; cursor: pointer; display: inline-flex; align-items: center; }
.crew-filter button.on { background: var(--ok-bg); border-color: var(--primary); color: var(--primary); font-weight: 600; }

/* 0124: Plan & billing (the app's own billing) + the banner on every screen */
.bill-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: -8px 0 16px; }
.bill-banner .small-btn { flex-shrink: 0; }
.pb-now .small-btn { margin-top: 12px; }
.pb-plan-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pb-plan-name, #pb-cur { font-size: 18px; overflow-wrap: anywhere; }
.pb-price { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--primary); }
.pb-plan { margin-top: 12px; }
.pb-plan.mine { border-color: var(--primary); border-width: 2px; }
.pb-plan .m { margin: 4px 0 0; }
.pb-facts { margin: 10px 0 12px; padding-left: 18px; font-size: 14px; }
.pb-facts li { margin: 3px 0; }
.pb-choose { width: 100%; }
.pb-toggle { display: flex; gap: 8px; margin-bottom: 4px; }
.pb-note { margin: 12px 0 0; }
#pb-packs .small-btn, #pb-invoices .small-btn { flex-shrink: 0; text-decoration: none; }

/* ---- tap-to-edit values (web/inline-edit.js): the one way a single value is edited, everywhere */
.ie { cursor: pointer; border-radius: 4px; text-decoration: underline dotted color-mix(in srgb, var(--text-soft) 75%, transparent);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px; overflow-wrap: anywhere; -webkit-tap-highlight-color: transparent;
  transition: background-color .12s; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
@media (hover: hover) { .ie:hover { background: color-mix(in srgb, var(--primary) 9%, transparent); text-decoration-color: var(--link); } }
.ie:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.ie[hidden] { display: none; }
.ie-ed { display: inline-flex; align-items: center; gap: 4px 6px; flex-wrap: wrap; max-width: 100%; min-width: 0; vertical-align: middle; }
.ie-ed.wide { display: flex; width: 100%; }
.ie-ed .ie-in:not([type=checkbox]), .ie-ed input:not([type=checkbox]), .ie-ed select, .ie-ed textarea {
  width: auto; max-width: 100%; min-width: 7ch; margin: 0; padding: 5px 8px; font-size: 16px; line-height: 1.3; border-radius: 8px; font-weight: 400; }
.ie-ed.wide > .ie-in, .ie-ed textarea { flex: 1 1 200px; width: 100%; }
.ie-ed textarea.ie-line { font-weight: inherit; }
.ie-ed input[type=date] { min-width: 10.5em; }
.ie-ed.saving { opacity: .6; }
.ie-ed.bad .ie-in { border-color: var(--error); }
.ie-x { width: 30px; height: 30px; flex: 0 0 auto; border: 0; border-radius: 50%; background: transparent; color: var(--text-soft); font-size: 15px; line-height: 1; padding: 0; }
@media (hover: hover) { .ie-x:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); } }
.ie-x:focus-visible { outline: 2px solid var(--link); }
.ie-err { flex: 1 1 100%; color: var(--error); font-size: 13px; font-weight: 600; }
.ie-check { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--text); }
.ie-check input { width: 22px; height: 22px; margin: 0; }
.ie-ok { margin-left: 6px; font-size: 12.5px; font-weight: 600; color: var(--link); white-space: nowrap; animation: ie-ok 1.8s ease forwards; }
@keyframes ie-ok { 0%, 70% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .ie, .ie-ok { transition: none; animation: none; } }
.row-btn[role=button]:focus-visible { outline: 2px solid var(--link); outline-offset: -2px; }
/* one-field-at-a-time grids built from tap-to-edit values (label on the left, value on the right) */
.ie-list { display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr); gap: 8px 12px; align-items: baseline; }
.ie-list > .k { color: var(--text-soft); font-size: 13.5px; }
.ra-row .row-btn > div:has(.ie-ed) { flex: 1 1 auto; min-width: 0; }   /* renaming: the name box gets the row's width */
.rte-link { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--border); }
.rte-link input { flex: 1 1 180px; min-width: 0; margin: 0; padding: 6px 10px; }

/* ---------- desktop Home (web/desk.js): on a computer Home fits the window like an app (Jobber / Housecall Pro
   desktop dashboards). One slim header row, then columns that each scroll on their own; the page never scrolls.
   Only Home gets body.desk-home (at DESK_QUERY in web/desk.js); phones and every other screen are unchanged. */
body.desk-home { height: 100vh; height: 100dvh; overflow: hidden; }
body.desk-home .wrap.home { max-width: 1480px; height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; padding: 20px 24px 0; }
body.desk-home .wrap.home > * { flex-shrink: 0; }
body.desk-home .wrap.home > .hero, body.desk-fit .wrap[data-desk] > .hero, body.desk-page .wrap > .hero { display: flex; align-items: center; gap: 8px 18px; padding-top: calc(10px + env(safe-area-inset-top)); padding-bottom: 26px; margin-bottom: 16px; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .top { display: contents; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .top img { height: 44px; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .eyebrow { display: none; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero h1 { flex: none; white-space: nowrap; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .sub { margin: 0; min-width: 0; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .who { order: 9; flex: none; margin-left: auto; font-size: 16px; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .who button { font-size: 16px !important; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .grass { height: 16px; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .divider-img { height: 18px; }
body.desk-home .hcols { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1fr); gap: 16px; margin: 0 -8px; }
body.desk-home .hcols[data-n="2"] { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
body.desk-home .hcols[data-n="1"] { grid-template-columns: minmax(0, 720px); justify-content: center; }
/* each column scrolls on its own when it's taller than the window (room for card shadows and focus rings) */
body.desk-home .hcol { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 8px 24px; }
body.desk-home .hcol > :first-child, body.desk-home .hcol > :is(.hidden, :empty):first-child + * { margin-top: 0; }
body.desk-home .hcol .tools-head { margin-top: 0; }
body.desk-home .hcol[data-col=notes]:not(:has(> :not(.hidden):not(:empty)))::before { content: "Nothing needs you right now."; display: block; padding: 18px; text-align: center; color: var(--text-soft); font-size: 16px; border: 1px dashed var(--border); border-radius: var(--radius); }
/* more room on a computer: 16px text */
body.desk-home .msg, body.desk-home .menu-card .d, body.desk-home .foot, body.desk-home .tools-head .link, body.desk-home .menu-card.tile .t { font-size: 16px; }
body.desk-home .menu-card.tile { padding: 18px 6px 16px; }
/* Simple view: the big buttons in a grid */
body.desk-home .sv-big { grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; }
body.desk-home .sv-btn { min-height: 120px; flex-direction: column; justify-content: center; text-align: center; }
body.desk-home .hcol > #wx { margin-top: 14px; }

/* Desktop screens that fit the window (opt in: .wrap[data-desk], body.desk-fit set by web/desk.js at DESK_QUERY).
   The header rows stay put; .dfill takes the rest of the window and its .dpane columns each scroll on their own.
   A screen sets its own columns: body.desk-fit .wrap[data-desk=routes] > .dfill { grid-template-columns: … } */
.dfill, .dpane { display: contents; }
body.desk-fit { height: 100vh; height: 100dvh; overflow: hidden; }
body.desk-fit .wrap[data-desk] { max-width: 1480px; height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; padding: 20px 24px 0; }
body.desk-fit .wrap[data-desk] > * { flex-shrink: 0; }
body.desk-fit .wrap[data-desk] > .dfill { flex: 1 1 auto; min-height: 0; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 16px; margin: 0 -8px; }
body.desk-fit .dfill > .dpane { display: block; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 8px 24px; }
body.desk-fit .dfill > .dpane > :first-child { margin-top: 0; }
/* Back sits small at the left under the header row, not a full-width row in the middle */
body.desk-fit .wrap[data-desk] > .back { align-self: flex-start; margin: -14px 0 2px; padding: 0; min-height: 44px; }

/* Desktop: Dispatch board (web/dispatch.js) — like Housecall Pro / Jobber dispatch: each worker's route is a column
   side by side (each scrolls on its own; the row of columns scrolls sideways only when there are too many), with
   Unscheduled, routes for nobody and the board's buttons in a side pane on the left. */
body.desk-fit .wrap[data-desk=dispatch] > h1 { margin: 0 0 2px; }
body.desk-fit .wrap[data-desk=dispatch] > .sub { margin: 0; font-size: 16px; }
body.desk-fit .wrap[data-desk=dispatch] > .dp-days { margin: 8px 0 12px; }
body.desk-fit .wrap[data-desk=dispatch] > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=dispatch] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(240px, 260px) minmax(0, 1fr); grid-template-rows: fit-content(55%) minmax(0, 1fr); }
body.desk-fit .wrap[data-desk=dispatch] .dp-side { grid-column: 1; grid-row: 1; padding-bottom: 8px; }
body.desk-fit .wrap[data-desk=dispatch] .dp-side2 { grid-column: 1; grid-row: 2; }
body.desk-fit .wrap[data-desk=dispatch] .dp-side > .rs-tray { margin: 0; }
body.desk-fit .wrap[data-desk=dispatch] .dp-side2 > .dp-w { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=dispatch] .dp-side2 > .dp-more { margin-top: 0 !important; }
body.desk-fit .wrap[data-desk=dispatch] .dp-side2 > .dp-more .btn { width: 100% !important; }
/* the board: the row of columns scrolls sideways, each column up and down */
body.desk-fit .wrap[data-desk=dispatch] .dp-board { grid-column: 2; grid-row: 1 / 3; overflow: auto hidden; padding-bottom: 12px; }
body.desk-fit .wrap[data-desk=dispatch] .dp-board > .dp-grid { height: 100%; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(240px, 1fr); gap: 12px; align-items: stretch; }
body.desk-fit .wrap[data-desk=dispatch] .dp-board .dp-w { min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 0; }
body.desk-fit .wrap[data-desk=dispatch] .dp-w > .dp-h { position: sticky; top: -18px; z-index: 1; margin: -18px -18px 0; padding: 14px 18px 10px; background: var(--card); border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; }
body.desk-fit .wrap[data-desk=dispatch] .dp-w > .dp-h + * { margin-top: 10px; }
/* more room on a computer: 16px text */
body.desk-fit .wrap[data-desk=dispatch] :is(.m, .small-btn, .dp-chip, .msg, .hint, .dfill select, .rs-tray) { font-size: 16px; }
body.desk-fit .wrap[data-desk=dispatch] .dp-name { font-size: 19px; }
/* Desktop: Billing (web/invoices.js) — on a computer the bills list and one bill fit the window (like the Jobber /
   Housecall Pro invoice screens). Billing: totals + tabs fixed at top; month-end cards (checklist, Build, Send all
   approved) in a left pane, the bills in a wider right pane; the other Billing buttons in one row at the bottom.
   One bill: the bill itself (dates, lines, totals, note) on the left; preview, approve, send, payments, reminders
   on the right. On phones .bl-more is display: contents like .dfill/.dpane, so nothing changes there. */
.bl-more { display: contents; }
body.desk-fit .wrap[data-desk=billing] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(0, 960px); }
body.desk-fit .wrap[data-desk=billing] > .dfill:has(> .bl-side) { grid-template-columns: minmax(300px, 2fr) minmax(0, 3fr); }
body.desk-fit .wrap[data-desk=billing] .bl-stats { margin: 0 0 4px; }
body.desk-fit .wrap[data-desk=billing] .bl-stat { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 10px 16px; }
body.desk-fit .wrap[data-desk=billing] .bl-stat .v { font-size: 22px; }
body.desk-fit .wrap[data-desk=billing] .bl-tabs { margin: 10px 0 12px; }
body.desk-fit .wrap[data-desk=billing] .bl-tabs .small-btn { font-size: 16px; padding: 8px 14px; }
body.desk-fit .wrap[data-desk=billing] .bl-side > .card:first-child { margin-top: 0; }
body.desk-fit .wrap[data-desk=billing] .bl-listpane > .card:last-child { margin-bottom: 0; }
body.desk-fit .wrap[data-desk=billing] > .bl-more { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0 14px; border-top: 1px solid var(--border); }
body.desk-fit .wrap[data-desk=billing] > .bl-more > .btn { width: auto; flex: 1 1 0; min-width: max-content; margin: 0; }
body.desk-fit .wrap[data-desk=bill] > .dfill { grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); }
body.desk-fit .wrap:is([data-desk=billing], [data-desk=bill]) > .back { align-self: flex-start; }
body.desk-fit .wrap[data-desk=bill] .bl-actpane > .bl-acts { margin-top: 0; }
/* the totals stay in sight at the bottom of the bill pane while the lines scroll under them */
@media (min-height: 800px) { body.desk-fit .wrap[data-desk=bill] .bl-billpane > .bl-tots { position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -6px 16px rgba(0, 0, 0, .08); } }
body.desk-fit .wrap[data-desk=bill] .bl-actpane > .bl-h2 { margin-top: 14px; }
/* text 16px+ on a computer */
body.desk-fit .bl-wrap :is(.bl-main .m, .bl-warn, .bl-stat .k, .bl-stat .m, .bl-listhead, .bl-listhead b, .card .m, .bl-sendbox .m, .bl-acts .m, .bl-dates .k, .bl-dates b,
  .bl-notes .k, .bl-flag, .bl-sugg, .bl-crew, .bl-crew .k, .mr-only, .bl-ldesc, .bl-ldesc .hint, .bl-dates .hint, .bl-notes .hint, .bl-main .n, .bl-amt, .person .m) { font-size: 16px; }
body.desk-fit .bl-wrap :is(.bl-stat .k, .bl-dates .k, .bl-notes .k, .bl-crew .k) { letter-spacing: .03em; }
/* Desktop: Route builder (web/routes.js) — like Jobber's route view: the stops (or, building a route, the clients to pick)
   scroll on the left; the day's summary (date, Best order, Day map, load totals, weather, call-ahead) on the right, with
   the tools under it (Add stops, the truck; Build route). Three panes in the phone order: .rt-side, .rt-list, .rt-tools. */
body.desk-fit .wrap[data-desk=routes] > form { display: contents; }
body.desk-fit .wrap[data-desk=routes] > form > .dfill { flex: 1 1 auto; min-height: 0; display: grid; gap: 16px; margin: 0 -8px; }
body.desk-fit .wrap[data-desk=routes] > :is(.dfill, form > .dfill) {
  grid-auto-flow: row; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); grid-template-rows: minmax(0, max-content) minmax(min(35%, 170px), 1fr); }
/* (the tools keep at least 170px, so the day's summary and its notice show whole instead of scrolling under the tools) */
body.desk-fit .wrap[data-desk=routes] .dfill > .rt-list { grid-column: 1; grid-row: 1 / span 2; }
body.desk-fit .wrap[data-desk=routes] .dfill > .rt-side { grid-column: 2; grid-row: 1; padding-bottom: 8px; }
body.desk-fit .wrap[data-desk=routes] .dfill > .rt-tools { grid-column: 2; grid-row: 2; }
body.desk-fit .wrap[data-desk=routes] > h1 { margin-bottom: 12px; }
/* the summary has its own pane, so it doesn't need to stick */
body.desk-fit .wrap[data-desk=routes] .rt-side > .sticky { position: static; }
/* the clients to pick fill the left pane, not a small box in it */
body.desk-fit .wrap[data-desk=routes].rt-setup .rt-list .checklist { max-height: none; }
/* more room on a computer: 16px text */
body.desk-fit .wrap[data-desk=routes] :is(.m, .badge, .hint, .msg, .row, label, .small-btn, .stop-where, .stop-sum, .stop-flags, .pill, .stop-num, .sb-h, .headsup, input, select, textarea) { font-size: 16px; }
body.desk-fit .wrap[data-desk=routes] .dfill .dpane label:not(.swatch) { font-size: 16px; }   /* beats the small capital field labels */
body.desk-fit .wrap[data-desk=routes] .stop-num { flex-basis: 32px; height: 32px; }

/* Desktop: Clients (web/clients.js) — list: search + filters and the buttons stay put, the list scrolls as name | address rows.
   A client's page (like Jobber's): contact, properties and info on the left, billing, notes, calls and visits on the right,
   each scrolling on its own; Edit / Delete stay under the left side. Phones: .cl-find/.cl-acts/.cl-foot are display: contents. */
.cl-find, .cl-acts, .cl-foot { display: contents; }
body.desk-fit .wrap[data-desk=clients] > .cl-find { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
body.desk-fit .wrap[data-desk=clients] > .cl-find > #q { flex: 1 1 320px; max-width: 520px; margin: 0 !important; }
body.desk-fit .wrap[data-desk=clients] > .cl-find > .chips { margin: 0; }
body.desk-fit .wrap[data-desk=clients] > .cl-find > p { flex: 1 1 100%; margin: 0; }
body.desk-fit .wrap[data-desk=clients] > .cl-acts { order: 1; display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
body.desk-fit .wrap[data-desk=clients] > .cl-acts > .btn { width: auto; margin: 0; padding-left: 18px; padding-right: 18px; }
body.desk-fit .wrap[data-desk=clients] > .dfill { order: 2; }
body.desk-fit .wrap[data-desk=clients] #rows { margin-top: 0; }
body.desk-fit .wrap[data-desk=clients] #rows .person > div:first-child { flex: 1 1 auto; min-width: 0; display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 4px 20px; align-items: baseline; text-align: left; }
body.desk-fit .wrap[data-desk=clients] #rows :is(.n, .m) { font-size: 16px; }
body.desk-fit .wrap[data-desk=client] > .dfill { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); grid-template-rows: minmax(0, 1fr) auto; grid-auto-flow: row; }
body.desk-fit .wrap[data-desk=client] > .dfill > .dpane:first-child { grid-column: 1; grid-row: 1; }
body.desk-fit .wrap[data-desk=client] > .dfill > .dpane:nth-child(2) { grid-column: 2; grid-row: 1 / span 2; }
body.desk-fit .wrap[data-desk=client] > .dfill > .dpane > h2:first-child { margin-top: 0 !important; }
body.desk-fit .wrap[data-desk=client] > .dfill > .cl-foot { grid-column: 1; grid-row: 2; display: flex; gap: 8px; padding: 8px 8px 16px; border-top: 1px solid var(--border); }
body.desk-fit .wrap[data-desk=client] > .dfill > .cl-foot > .btn { flex: 1 1 0; margin: 0; }
body.desk-fit .wrap[data-desk=client] .dpane .person :is(.n, .m) { font-size: 16px; }

/* Desktop: Calendar (web/visits.js) — like Jobber's calendar: the month grid fills the window on the left (rows
   shrink to fit, each day lists its first customers then "+3 more"), the picked day's visits in a pane on the right
   with the service-history search under it. Phones: unchanged (the day pane and names stay hidden, tap = popup). */
.cal-dayp, .cal-names, .cal-more { display: none; }
body.desk-fit .wrap[data-desk=calendar] > .back { align-self: flex-start; margin: -8px 0 6px; padding: 0; min-height: 44px; font-size: 16px; }
body.desk-fit .wrap[data-desk=calendar] > .dfill { grid-template-columns: minmax(0, 2fr) minmax(300px, 1fr); }
/* the month: a card that fills its pane, the day rows share the height */
body.desk-fit .wrap[data-desk=calendar] .cal-main { display: flex; flex-direction: column; }
body.desk-fit .wrap[data-desk=calendar] .cal-card { flex: 1 1 auto; min-height: 440px; display: flex; flex-direction: column; margin-bottom: 0; padding: 12px; }
body.desk-fit .wrap[data-desk=calendar] .cal-card > * { flex-shrink: 0; }
body.desk-fit .wrap[data-desk=calendar] .cal-nav { margin-bottom: 4px; }
body.desk-fit .wrap[data-desk=calendar] .cal-arrow { width: 34px; height: 34px; }
body.desk-fit .wrap[data-desk=calendar] .cal-card > p.m { margin: 6px 2px 0 !important; }
body.desk-fit .wrap[data-desk=calendar] .cal-month { font-size: 20px; }
body.desk-fit .wrap[data-desk=calendar] .cal-card .m, body.desk-fit .wrap[data-desk=calendar] .crew-filter button { font-size: 16px; }
body.desk-fit .wrap[data-desk=calendar] .cal-week div { font-size: 13px; padding-bottom: 3px; }
body.desk-fit .wrap[data-desk=calendar] .cal-card > .cal-grid:not(.cal-week) { flex: 1 1 auto; min-height: 0; grid-auto-rows: minmax(0, 1fr); gap: 4px; }
body.desk-fit .wrap[data-desk=calendar] .cal-day { aspect-ratio: auto; min-height: 0; overflow: hidden; align-items: stretch; justify-content: flex-start; text-align: left; padding: 3px 6px; gap: 0; position: relative; }
body.desk-fit .wrap[data-desk=calendar] .cal-day.empty { padding: 0; }
body.desk-fit .wrap[data-desk=calendar] .cal-n { font-size: 16px; line-height: 1.2; flex: none; }
body.desk-fit .wrap[data-desk=calendar] .cal-dot, body.desk-fit .wrap[data-desk=calendar] .cal-tech { display: none; }
body.desk-fit .wrap[data-desk=calendar] .cal-count { position: absolute; top: 3px; right: 5px; font-size: 13px; font-weight: 700; line-height: 1.4; margin: 0; padding: 0 7px; border-radius: 99px; background: color-mix(in srgb, var(--link) 18%, var(--card)); }
body.desk-fit .wrap[data-desk=calendar] .cal-day.has { font-weight: 400; }
body.desk-fit .wrap[data-desk=calendar] .cal-day.has .cal-n { font-weight: 700; }
body.desk-fit .wrap[data-desk=calendar] .cal-day.picked { border-color: var(--primary); border-width: 2px; box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 18%, transparent); }
body.desk-fit .wrap[data-desk=calendar] .cal-names { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
body.desk-fit .wrap[data-desk=calendar] :is(.cal-names > span, .cal-more) { flex: none; font-size: 16px; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); }
body.desk-fit .wrap[data-desk=calendar] .cal-more { display: block; color: var(--link); font-weight: 700; }
body.desk-fit .wrap[data-desk=calendar] :is(.cal-names > span, .cal-more)[hidden] { display: none; }
/* the picked day's visits, then the service history search */
body.desk-fit .wrap[data-desk=calendar] .cal-dayp { display: block; }
body.desk-fit .wrap[data-desk=calendar] .cal-dayt { font-size: 20px; margin: 0 0 10px; }
body.desk-fit .wrap[data-desk=calendar] #cal-sel { font-size: 16px; margin-bottom: 12px; }
body.desk-fit .wrap[data-desk=calendar] .cal-side .day-visit { margin-bottom: 8px; }
body.desk-fit .wrap[data-desk=calendar] .cal-side :is(.day-visit .m, .day-visit .dv-rate, .dv-who, .dv-notes, .badge) { font-size: 16px; }
body.desk-fit .wrap[data-desk=calendar] .cal-side h2 { font-size: 20px !important; }

/* Desktop: Messages (web/inbox.js) — two panes like every desktop inbox (Front, GoHighLevel, Gmail): the conversation list
   on the left (search + filters stay at its top), the open conversation on the right with the reply box pinned to the bottom.
   Phones: unchanged (the panes are display: contents; the list beside a conversation is only filled in on a computer). */
.conv-tools { display: contents; }
.conv-pick { display: none; }
body:not(.desk-fit) .wrap.convo .conv-side { display: none; }
.wrap.convo > .dfill > .dpane > * { flex-shrink: 0; }
body.desk-fit .wrap[data-desk=messages] > .dfill { grid-template-columns: minmax(320px, 420px) minmax(0, 1fr); }
body.desk-fit .wrap[data-desk=messages] > .test-banner { margin: 0 0 12px; font-size: 16px; }
body.desk-fit .wrap[data-desk=messages] > .setup-hint { margin: 0 0 12px; padding: 12px 16px; }
body.desk-fit .conv-side { padding-top: 0; }
body.desk-fit .conv-tools { display: block; position: sticky; top: 0; z-index: 2; background: var(--bg); padding-top: 2px; }
body.desk-fit .conv-tools .inbox-tools { margin-top: 0; }
body.desk-fit .conv-tools .chips { margin: 10px 0 12px; padding-bottom: 2px; }
body.desk-fit .conv-side .conv-list { margin-top: 0; }
body.desk-fit .conv-side .conv-row { font-size: 16px; padding: 12px 14px; }
body.desk-fit .conv-side .conv-prev { font-size: 16px; }
body.desk-fit .conv-side .conv-time { font-size: 14px; }
body.desk-fit .conv-side .conv-row.sel { background: color-mix(in srgb, var(--primary) 12%, var(--card)); box-shadow: inset 4px 0 0 var(--primary); }
body.desk-fit .conv-side .small-btn, body.desk-fit .conv-side .badge { font-size: 16px; }
body.desk-fit .conv-pick { display: flex; height: 100%; min-height: 200px; box-sizing: border-box; align-items: center; justify-content: center; text-align: center; padding: 24px; color: var(--text-soft); font-size: 17px; border: 1px dashed var(--border); border-radius: var(--radius); }
/* the open conversation: header row, thread that scrolls, reply box at the bottom */
body.desk-fit .wrap.convo .top { margin-bottom: 10px; }
body.desk-fit .wrap.convo > .back { margin-bottom: 10px; }
body.desk-fit .wrap.convo .conv-main { display: flex; flex-direction: column; overflow: hidden; padding-bottom: 0; }
body.desk-fit .wrap.convo .conv-main > #thread { flex: 1 1 auto; min-height: 0; margin: 0; padding: 10px 6px 12px; }
body.desk-fit .wrap.convo .conv-main > .convo-top { margin: 0; padding: 0 0 10px; }
body.desk-fit .wrap.convo .conv-main > .composer { margin: 0; }
body.desk-fit .wrap.convo .conv-main > .test-banner { font-size: 16px; }
body.desk-fit .wrap.convo .convo-title { font-size: 22px; }
body.desk-fit .wrap.convo .convo-top .m, body.desk-fit .wrap.convo .convo-actions .small-btn { font-size: 16px; }
body.desk-fit .wrap.convo .bubble { font-size: 16px; }
body.desk-fit .wrap.convo .msg-row { max-width: 72%; }
body.desk-fit .wrap.convo .msg-row .meta, body.desk-fit .wrap.convo .day-sep { font-size: 14px; }
body.desk-fit .wrap.convo .composer .small-btn, body.desk-fit .wrap.convo .composer .m, body.desk-fit .wrap.convo .notice { font-size: 16px; }
body.desk-fit .wrap.convo .composer .rte-box, body.desk-fit .wrap.convo .composer textarea { max-height: 24vh; }

/* Desktop: Timesheets (web/timeclock.js) — the week picker stays at the top, the people list scrolls on the left,
   the week's totals (team hours, overtime, hours by day) sit in a pane on the right. Phones: unchanged. */
.tc-byday { display: none; }
body.desk-fit .wrap[data-desk=timesheets] > .dfill { grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); }
body.desk-fit .wrap[data-desk=timesheets] > .dfill > .tc-side { order: 2; }
body.desk-fit .wrap[data-desk=timesheets] > .tc-nav { max-width: 520px; margin: 0 0 14px; }
body.desk-fit .wrap[data-desk=timesheets] .tc-nav b { font-size: 18px; }
body.desk-fit .tc-side .tc-stats { grid-template-columns: 1fr; margin: 0 0 12px; }
body.desk-fit .tc-side .tc-stat .m { font-size: 16px; }
body.desk-fit .tc-side .tc-stat .n { font-size: 28px; }
body.desk-fit .tc-side .tc-byday { display: block; padding: 6px 16px 12px; }
body.desk-fit .tc-side .tc-byday .row { font-size: 16px; margin-top: 8px; }
body.desk-fit .tc-main #tc-people { margin-top: 0; }
body.desk-fit .tc-main .tc-row { font-size: 16px; padding: 14px 4px; }
body.desk-fit .tc-main .tc-row .tot { font-size: 18px; }
body.desk-fit .tc-main .tc-mini { font-size: 14px; max-width: 520px; }
body.desk-fit .tc-main .hint { font-size: 16px; }

/* Desktop: every other screen (body.desk-page, web/desk.js) keeps the same slim header row pinned at the top
   while the screen under it scrolls, so the app doesn't feel like a web page sliding away */
body.desk-page .wrap > .hero { position: sticky; top: 0; z-index: 30; background: var(--bg); }
html[data-header=band] body.desk-page .wrap > .hero { background: repeating-linear-gradient(100deg, var(--primary) 0 46px, var(--primary-hover) 46px 92px); }
html[data-header=image] body.desk-page .wrap > .hero { background: linear-gradient(180deg, rgba(0,0,0,.30), rgba(0,0,0,.58)), var(--header-img) center / cover no-repeat; }
body.desk-page .wrap > .back { margin-top: -14px; padding: 0; min-height: 44px; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .brand-name { white-space: nowrap; }

/* Desktop: Weather (web/weather.js) — a weather dashboard that fits the window: the place line (and Change) stays at the top,
   today (now, lawn notes, spray window, next 12 hours) is the big pane on the left, the 7 days are a column on the right.
   Each pane scrolls on its own if the window is short. Phones: unchanged (the panes are display: contents). */
body.desk-fit .wrap[data-desk=weather] > .dfill { grid-template-columns: minmax(0, 1.5fr) minmax(340px, 1fr); }
body.desk-fit .wrap[data-desk=weather] > h1 { margin-bottom: 4px; }
body.desk-fit .wrap[data-desk=weather] > .wx-placeline { font-size: 16px; margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=weather] > .wx-placeline .link { font-size: 16px; }
body.desk-fit .wrap[data-desk=weather] > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=weather] > #wx-pick { max-width: 560px; margin: 0 0 12px; }
body.desk-fit #wx-page .wx-sub, body.desk-fit #wx-page .wx-opt, body.desk-fit #wx-page .sub { font-size: 16px; }
body.desk-fit #wx-page .wx-h { font-size: 20px; margin: 20px 0 8px; }
body.desk-fit #wx-page .dpane > .wx-h:first-child { margin-top: 0; }
body.desk-fit #wx-page .wx-big { display: flex; align-items: center; justify-content: space-between; gap: 14px 28px; flex-wrap: wrap; }
body.desk-fit #wx-page .wx-big .wx-main { flex: 0 1 auto; }
body.desk-fit #wx-page .wx-big .wx-temp { font-size: 54px; }
body.desk-fit #wx-page .wx-facts { flex: 1 1 340px; margin-top: 0; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
body.desk-fit #wx-page .wx-facts span { font-size: 15px; }
body.desk-fit #wx-page .wx-facts b { font-size: 18px; }
body.desk-fit #wx-page .wx-pill { font-size: 16px; padding: 5px 12px; }
body.desk-fit #wx-page .wx-cell span { display: block; margin-top: 3px; font-size: 13px; white-space: nowrap; }
body.desk-fit #wx-page .wx-cell i { height: 30px; }
body.desk-fit #wx-page .wx-legend { font-size: 16px; }
/* next 12 hours: all of them in view (wraps to a second row in a narrow window) instead of a sideways scroll */
body.desk-fit #wx-page .wx-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(54px, 1fr)); gap: 12px 4px; overflow: visible; }
body.desk-fit #wx-page .wx-hr { min-width: 0; font-size: 17px; }
body.desk-fit #wx-page .wx-k, body.desk-fit #wx-page .wx-rain { font-size: 15px; white-space: nowrap; }
/* the week: one roomy row per day */
body.desk-fit #wx-page .wx-week .wx-days { padding: 4px 16px; }
body.desk-fit #wx-page .wx-day { grid-template-columns: 60px 36px 1fr auto; padding: 12px 0; font-size: 17px; }
body.desk-fit #wx-page .wx-dt b { font-size: 20px; }
body.desk-fit #wx-page .wx-chips .wx-pill { font-size: 14px; padding: 3px 10px; }
body.desk-fit #wx-page #wx-settings { font-size: 16px; margin-top: 12px; }
/* Desktop: Quotes (web/quotes.js) — like Jobber's quotes screens. List: search + status filters stay at the top, the
   quotes scroll in one pane as customer | quote | status | amount rows, New quote stays in a row at the bottom.
   One quote: the builder (title, lawn, billing, lines, add a line, upgrades) or the quote's lines on the left; totals,
   notes, Save, status and Send / Print / Copy link / the other actions on the right, each pane scrolling on its own.
   Phones: unchanged (.q-find is display: contents like .dfill/.dpane). */
.q-find { display: contents; }
body.desk-fit .wrap[data-desk=quotes] > h1 { margin-bottom: 2px; }
body.desk-fit .wrap[data-desk=quotes] > .sub { margin: 0 0 10px; font-size: 16px; }
body.desk-fit .wrap[data-desk=quotes] > .msg { margin: 0 0 10px; }
body.desk-fit .wrap[data-desk=quotes] > .q-find { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-bottom: 12px; }
body.desk-fit .wrap[data-desk=quotes] > .q-find > #q-search { flex: 1 1 320px; max-width: 520px; margin: 0 !important; }
body.desk-fit .wrap[data-desk=quotes] > .q-find > .chips { margin: 0; }
body.desk-fit .wrap[data-desk=quotes] > .q-find .small-btn { font-size: 16px; }
body.desk-fit .wrap[data-desk=quotes] > .dfill { grid-template-columns: minmax(0, 1100px); }
body.desk-fit .wrap[data-desk=quotes] #q-rows { margin: 0; }
body.desk-fit .wrap[data-desk=quotes] #q-rows .q-row > div:first-child { flex: 1 1 auto; display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 4px 20px; align-items: baseline; text-align: left; }
body.desk-fit .wrap[data-desk=quotes] #q-rows .q-row .q-right { flex-direction: row; align-items: center; justify-content: flex-end; gap: 16px; width: 250px; }
body.desk-fit .wrap[data-desk=quotes] #q-rows .q-row .q-right b { min-width: 110px; }
body.desk-fit .wrap[data-desk=quotes] #q-rows :is(.n, .m, .q-right b, .badge) { font-size: 16px; }
body.desk-fit .wrap[data-desk=quotes] #q-rows .q-row .n { white-space: nowrap; }
body.desk-fit .wrap[data-desk=quotes] > #q-new { width: auto; align-self: flex-start; margin: 0; padding-left: 22px; padding-right: 22px; }
body.desk-fit .wrap[data-desk=quotes] > .dfill + #q-new { margin: 10px 0 16px; }
body.desk-fit :is(.wrap[data-desk=quotes], .wrap[data-desk=quote]) .q-chip { font-size: 13px; }
/* one quote: builder left, totals + actions right */
body.desk-fit .wrap[data-desk=quote] > .dfill { grid-template-columns: minmax(0, 3fr) minmax(340px, 2fr); }
body.desk-fit .wrap[data-desk=quote] > h1 { margin-bottom: 2px; }
body.desk-fit .wrap[data-desk=quote] > .sub { margin: 0 0 10px; font-size: 16px; }
body.desk-fit .wrap[data-desk=quote] > :is(.msg, .headsup) { margin: 0 0 10px; font-size: 16px; }
body.desk-fit .wrap[data-desk=quote] .q-build > .card:first-child { margin-top: 0; }
body.desk-fit .wrap[data-desk=quote] .q-side > .card:first-child { margin-top: 0; }
body.desk-fit .wrap[data-desk=quote] .q-side > .q-bar { margin-top: 0; bottom: 0; box-shadow: 0 2px 10px rgba(0, 0, 0, .06); }
body.desk-fit .wrap[data-desk=quote] .q-side > #q-status { margin: 12px 2px !important; }
body.desk-fit .wrap[data-desk=quote] .q-tot .grand { font-size: 22px; }
/* text 16px+ on a computer */
body.desk-fit .wrap[data-desk=quote] :is(.q-nums label, .q-flags label, .q-desc, .q-lawn, .q-up .m, .q-tot .m, .q-tot > div, .q-state, .q-ro .m, .q-ro .n, .q-ro .q-amtv,
  .q-confirm .m, .q-confirm p, .card > .m, .badge, .hint, .seg button, #q-upg .small-btn, .q-lawn .small-btn, .q-add select) { font-size: 16px !important; }
body.desk-fit .wrap[data-desk=quote] .q-amt span { font-size: 16px; }
/* Desktop: Application records (web/records.js) — like the Jobber / Shopify report screens: the filters sit in a side
   pane on the left with the applicator licenses and record settings under it; the records fill a wide pane on the right,
   their count with Download CSV / Print state report pinned at the top of that pane while the list scrolls under it.
   One person's licenses: the license cards on the left, who supervises them and Save on the right. Phones: unchanged. */
body.desk-fit .wrap[data-desk=records] > h1, body.desk-fit .wrap[data-desk=licenses] > h1 { margin: 0 0 2px; }
body.desk-fit .wrap:is([data-desk=records], [data-desk=licenses]) > .sub { margin: 0 0 12px; font-size: 16px; }
body.desk-fit .wrap:is([data-desk=records], [data-desk=licenses]) > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=records] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
  grid-template-rows: minmax(0, max-content) minmax(min(30%, 160px), 1fr); }
body.desk-fit .wrap[data-desk=records] .dfill > .ar-filt { grid-column: 1; grid-row: 1; padding-bottom: 8px; }
body.desk-fit .wrap[data-desk=records] .dfill > .ar-more { grid-column: 1; grid-row: 2; }
body.desk-fit .wrap[data-desk=records] .dfill > .ar-res { grid-column: 2; grid-row: 1 / span 2; }
body.desk-fit .wrap[data-desk=records] .ar-filt > .card { margin-bottom: 0; }
body.desk-fit .wrap[data-desk=records] #ar-go { margin-top: 14px !important; }
/* nothing shown yet: say what to do instead of an empty pane */
body.desk-fit .wrap[data-desk=records] .ar-res:has(> #ar-out:empty)::before { content: "Pick the dates, then Show records."; display: flex; align-items: center; justify-content: center;
  height: 100%; min-height: 200px; box-sizing: border-box; padding: 24px; text-align: center; color: var(--text-soft); font-size: 17px; border: 1px dashed var(--border); border-radius: var(--radius); }
/* the count + Download CSV / Print stay at the top of the records pane */
body.desk-fit .wrap[data-desk=records] .ar-rescard { padding-top: 0; margin-bottom: 0; }
body.desk-fit .wrap[data-desk=records] .ar-reshead { position: sticky; top: -2px; z-index: 2; margin: 0 -18px; padding: 14px 18px 12px; background: var(--card);
  border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; }
body.desk-fit .wrap[data-desk=records] .ar-reshead .act-row { margin-top: 8px !important; }
body.desk-fit .wrap[data-desk=records] .ar-list { margin-top: 0; }
body.desk-fit .wrap[data-desk=records] .ar-item:first-child { border-top: 0; }
body.desk-fit .wrap[data-desk=records] .ar-item { padding: 12px 0; }
body.desk-fit .wrap[data-desk=records] .ar-item.ar-bad { padding-left: 10px; }
/* licenses */
body.desk-fit .wrap[data-desk=licenses] > .dfill { grid-template-columns: minmax(0, 3fr) minmax(300px, 2fr); }
body.desk-fit .wrap[data-desk=licenses] .ar-licpane > .btn { margin-top: 0; }
body.desk-fit .wrap[data-desk=licenses] .ar-suppane > .card { margin-bottom: 14px; }
/* text 16px+ on a computer */
body.desk-fit .wrap:is([data-desk=records], [data-desk=licenses]) :is(.m, .n, .hint, .msg, .badge, .small-btn, .swatch, .ar-misst, .ar-soon, summary, input, select, textarea) { font-size: 16px; }
body.desk-fit .wrap:is([data-desk=records], [data-desk=licenses]) .dfill .dpane label:not(.swatch) { font-size: 16px; }   /* beats the small capital field labels */
body.desk-fit .wrap[data-desk=records] .pill { font-size: 14px; }
body.desk-fit .wrap:is([data-desk=records], [data-desk=licenses]) :is(.ar-reshead .row, .ar-licrow > .row) { font-size: 16px; }
body.desk-fit .wrap[data-desk=records] .ar-more .person .m { word-break: normal; overflow-wrap: anywhere; }
body.desk-fit .wrap[data-desk=licenses] .ar-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
body.desk-fit .wrap[data-desk=records] .ar-filt label:not(.swatch) { margin: 8px 0 4px; }
body.desk-fit .wrap[data-desk=records] .ar-filt .card { padding-top: 10px; }
/* phones: the cards keep the space they had after the message line / Add a license (.msg + .card, .btn + .card) */
body:not(.desk-fit) .wrap[data-desk=records] .ar-filt > .card:first-child, body:not(.desk-fit) .wrap[data-desk=licenses] :is(.ar-licpane, .ar-suppane) > .card:first-child { margin-top: 14px; }
/* Desktop: Rounds (web/rounds.js) — like Real Green's production screens: the Rounds tabs stay at the top; the rounds
   list (with % done) scrolls on the left, hold reasons on the right. One round: the lawns (filters pinned at the top,
   pick boxes) fill a big pane on the left; the round's totals and products, held lawns and Make a route / Move the round
   sit in a side pane on the right. Call-ahead and Production: the day / dates stay up top, the list scrolls under them.
   Phones: unchanged (.rd-dk side cards are desktop only; the panes are display: contents). */
.rd-dk { display: none; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) > h1 { margin: 0 0 2px; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) > .sub { margin: 0 0 10px; font-size: 16px; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) > .msg:not(.hidden) { margin: 0 0 10px; }
body.desk-fit .wrap[data-desk=rounds] > .rd-tabs { margin: 0 0 12px; max-width: 640px; }
body.desk-fit .wrap[data-desk=rounds] > .rd-tabs button { font-size: 16px; }
body.desk-fit .wrap[data-desk=rounds] > .card { margin-bottom: 12px; max-width: 960px; width: 100%; box-sizing: border-box; }
body.desk-fit .wrap[data-desk=rounds] > .dfill { grid-template-columns: minmax(0, 960px); }
body.desk-fit .wrap[data-desk=rounds] > .dfill:has(> .rd-rpane) { grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); }
body.desk-fit .wrap[data-desk=rounds] .rd-rpane > h2:first-child { margin-top: 0 !important; }
body.desk-fit .wrap[data-desk=rounds] .rd-round { padding: 14px 4px; }
body.desk-fit .wrap[data-desk=rounds] .rd-round .n { font-size: 18px; }
body.desk-fit .wrap[data-desk=rounds] .rd-pct { font-size: 20px; }
body.desk-fit .wrap[data-desk=rounds] .rd-filters { grid-template-columns: repeat(3, minmax(0, 220px)); }
body.desk-fit .wrap[data-desk=rounds] .rd-filters > [style*="grid-column"] { grid-column: auto !important; }
body.desk-fit .wrap[data-desk=rounds] .rd-tbl :is(th, td) { font-size: 16px; padding: 10px 8px; }
/* one round: lawns on the left (big), totals + actions on the right */
body.desk-fit .wrap[data-desk=round] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr) clamp(300px, 31%, 420px); grid-template-rows: minmax(0, max-content) minmax(30%, 1fr); }
body.desk-fit .wrap[data-desk=round] .dfill > .rd-main { grid-column: 1; grid-row: 1 / span 2; }
body.desk-fit .wrap[data-desk=round] .dfill > .rd-sum { grid-column: 2; grid-row: 1; padding-bottom: 8px; }
body.desk-fit .wrap[data-desk=round] .dfill > .rd-side { grid-column: 2; grid-row: 2; }
body.desk-fit .wrap[data-desk=round] .rd-sum > .card { margin-bottom: 0; }
body.desk-fit .wrap[data-desk=round] .rd-main > .card { margin-bottom: 0; padding-top: 0; }
body.desk-fit .wrap[data-desk=round] .rd-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* the filters stay at the top of the lawns pane while the lawns scroll under them */
body.desk-fit .wrap[data-desk=round] .rd-main .rd-filters { position: sticky; top: -2px; z-index: 3; background: var(--card); margin: 0 -18px; padding: 16px 18px 10px; border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; grid-template-columns: repeat(3, minmax(0, 1fr)); }
body.desk-fit .wrap[data-desk=round] .rd-held { display: none; }
body.desk-fit .wrap[data-desk=round] .rd-dk { display: block; margin-bottom: 12px; }
/* a lawn (wide windows): name and flags on the left, address / product / planned day on the right */
body.desk-fit .wrap[data-desk=round] .rd-row { padding: 12px 0; align-items: center; }
@media (min-width: 1200px) {
  body.desk-fit .wrap[data-desk=round] .rd-row .body { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); grid-auto-flow: row dense; gap: 2px 20px; align-items: baseline; }
  body.desk-fit .wrap[data-desk=round] .rd-row .body > .n, body.desk-fit .wrap[data-desk=round] .rd-row .body > .rd-flag { grid-column: 1; justify-self: start; }
  body.desk-fit .wrap[data-desk=round] .rd-row .body > .m { grid-column: 2; }
}
body.desk-fit .wrap[data-desk=round] .rd-row .crew-pill { font-size: 16px; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) .dpane .card > .row > b, body.desk-fit .wrap[data-desk=round] .rd-acts b { font-size: 18px; }
/* the actions live in the side pane: no need to float over the list */
body.desk-fit .wrap[data-desk=round] .rd-side > .rd-acts { position: static; margin-top: 0; box-shadow: none; }
body.desk-fit .wrap[data-desk=round] .rd-side > .rd-acts .btn { flex-basis: 150px; }
/* text 16px+ on a computer */
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) :is(.m, .badge, .hint, .link, .small-btn, .rd-stat span, .rd-st, .rd-flag, .pill, .rd-row .n, .rd-call, label, input, select, textarea) { font-size: 16px; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) .pill { text-transform: none; letter-spacing: 0; }
body.desk-fit .wrap[data-desk=round] .rd-stat b { font-size: 22px; }
body.desk-fit .wrap:is([data-desk=rounds], [data-desk=round]) .dfill .dpane label:not(.swatch) { font-size: 16px; }   /* beats the small capital field labels */
/* Desktop: Settings (web/settings.js) — like Shopify / Jobber settings. The hub: the section cards fill the window in a grid
   that scrolls on its own. A section in this file (Business info, Custom fields, Tags, Announcements, Shortcut bar, Fixing
   visits): the settings menu on the left, the section on the right, each scrolling on its own; every section keeps its own
   address. Sections in other files keep the pinned header (body.desk-page). Phones: unchanged (the menu is hidden there). */
.set-nav { display: none; }
body.desk-fit .wrap[data-desk=settings] > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=settings] .set-hub .menu { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); align-items: stretch; }
body.desk-fit .wrap[data-desk=settings] .set-hub .menu-card .d { font-size: 16px; }
body.desk-fit .wrap[data-desk=settings] .set-hub details.more-set > .more-in { margin-top: 14px; }
body.desk-fit .wrap[data-desk=settings] > .dfill:has(> .set-nav) { grid-template-columns: minmax(250px, 290px) minmax(0, 1fr); }
body.desk-fit .wrap[data-desk=settings] .set-nav { display: block; position: relative; padding-right: 10px; border-right: 1px solid var(--border); }
body.desk-fit .set-nav .set-link { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; margin: 0 0 2px; padding: 6px 10px; border: 0; border-radius: 10px; background: none; color: var(--text); font: inherit; font-size: 16px; font-weight: 600; text-align: left; cursor: pointer; }
body.desk-fit .set-nav .set-link:hover { background: color-mix(in srgb, var(--link) 8%, transparent); }
body.desk-fit .set-nav .set-link.on { background: color-mix(in srgb, var(--primary) 12%, var(--card)); box-shadow: inset 4px 0 0 var(--primary); color: var(--primary); }
body.desk-fit .set-nav .set-link .menu-ic { grid-row: auto; flex: none; width: 32px; height: 32px; border-radius: 9px; }
body.desk-fit .set-nav .set-link .menu-ic svg { width: 19px; height: 19px; }
body.desk-fit .set-nav details.more-set { margin-top: 10px; }
body.desk-fit .set-nav details.more-set > summary { font-size: 16px; }
body.desk-fit .wrap[data-desk=settings] .set-body { padding-left: 16px; }
body.desk-fit .wrap[data-desk=settings] .set-body > * { max-width: 820px; }
body.desk-fit .wrap[data-desk=settings] .set-body :is(.m, .hint, .small-btn, .badge, .msg) { font-size: 16px; }
body.desk-fit .wrap[data-desk=settings] .dfill .dpane.set-body label:not(.swatch) { font-size: 16px; }   /* beats the small capital field labels */
/* Desktop: Log a visit (web/visits.js) — like Jobber's visit form: who / where / what (client, property, date, services,
   amounts, products, spreader) scroll on the left with Save pinned under them; heads-up notes, visit notes, photos, the
   state record and this lawn's recent visits on the right. The route-stop review: what you did on the left, notes /
   heads-up / photos on the right, its two buttons pinned at the bottom. Phones: unchanged (.lv-foot, the panes and the
   review's columns are display: contents or plain blocks; the recent visits card only shows on a computer). */
.lv-foot { display: contents; }
.lv-hist { display: none; }
body.desk-fit .wrap[data-desk=logvisit] > h1 { margin: 0 0 10px; }
body.desk-fit .wrap[data-desk=logvisit] > .sub { margin: -4px 0 12px; font-size: 16px; }
body.desk-fit .wrap[data-desk=logvisit] > .msg { margin: 0 0 12px; font-size: 16px; }
body.desk-fit .wrap[data-desk=logvisit] > form { display: contents; }
body.desk-fit .wrap[data-desk=logvisit] > form > .dfill { flex: 1 1 auto; min-height: 0; display: grid; gap: 0 20px; margin: 0 -8px;
  grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); grid-template-rows: minmax(0, 1fr) auto; }
body.desk-fit .wrap[data-desk=logvisit] .lv-main { grid-column: 1; grid-row: 1; }
body.desk-fit .wrap[data-desk=logvisit] .lv-side { grid-column: 2; grid-row: 1 / span 2; }
body.desk-fit .wrap[data-desk=logvisit] .lv-main > #addl { margin-bottom: 14px; }
/* Save: always in sight under the left side */
body.desk-fit .wrap[data-desk=logvisit] .lv-foot { grid-column: 1; grid-row: 2; display: block; padding: 12px 8px 18px; border-top: 1px solid var(--border); }
body.desk-fit .wrap[data-desk=logvisit] .lv-foot > #go { margin: 0; }
body.desk-fit .wrap[data-desk=logvisit] .lv-foot > .msg { margin: 10px 0 0; max-height: 22vh; overflow-y: auto; }
body.desk-fit .wrap[data-desk=logvisit] .lv-side > #cnotes:empty { display: none; }
body.desk-fit .wrap[data-desk=logvisit] .lv-side > #cnotes .headsup { margin-top: 0; }
/* this lawn's recent visits */
body.desk-fit .wrap[data-desk=logvisit] .lv-hist:not([hidden]) { display: block; }
body.desk-fit .wrap[data-desk=logvisit] .lv-hv { padding: 10px 0; border-top: 1px solid var(--border); }
body.desk-fit .wrap[data-desk=logvisit] .lv-hv:first-of-type { border-top: 0; padding-top: 6px; }
body.desk-fit .wrap[data-desk=logvisit] .lv-hd { font-weight: 700; font-size: 16px; }
body.desk-fit .wrap[data-desk=logvisit] .lv-hn { white-space: pre-wrap; font-style: italic; }
/* the review from a route stop */
body.desk-fit .wrap[data-desk=logvisit] > #vreview { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
body.desk-fit .wrap[data-desk=logvisit] #vreview > .vr-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); gap: 0 20px; margin: 0 -8px; }
body.desk-fit .wrap[data-desk=logvisit] #vreview > .vr-body > div { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 8px 12px; }
body.desk-fit .wrap[data-desk=logvisit] #vreview > .vr-body > div > .card:last-child { margin-bottom: 0; }
body.desk-fit .wrap[data-desk=logvisit] #vreview > .msg { margin: 10px 0 0; }
body.desk-fit .wrap[data-desk=logvisit] #vreview > .vr-acts { margin: 0; padding: 12px 0 18px; border-top: 1px solid var(--border); }
/* more room on a computer: 16px text */
body.desk-fit .wrap[data-desk=logvisit] :is(label, .hint, .m, .badge, .rate-hint, .msg, .headsup, .note, .ll-note, .ll-status, .ll-labelwarn, .row, .small-btn,
  .comp-label, .comp-h, .up-chip, .pill, .swatch, .results .n, .vr-line .n, .card > .n, .card.line > .row > b) { font-size: 16px; }
body.desk-fit .wrap[data-desk=logvisit] .card.line > .row > b { letter-spacing: .04em; }
/* Desktop: the tip is one slim line above the panes (text, then "Turn off tips", then ×) so the panes keep the room */
body.desk-fit .wrap[data-desk] > .tip { align-items: center; padding: 4px 6px 4px 12px; margin-bottom: 10px; }
body.desk-fit .wrap[data-desk] > .tip .tip-txt { display: flex; align-items: baseline; gap: 6px 16px; flex-wrap: wrap; }
body.desk-fit .wrap[data-desk] > .tip .tip-txt p { font-size: 16px; }
body.desk-fit .wrap[data-desk] > .tip .tip-off { margin-top: 0; font-size: 14px; white-space: nowrap; }
body.desk-fit .wrap[data-desk] > .tip .tip-x { margin: 0; }

/* Quote live preview (web/quotes.js) — like Jobber's quote preview: on a computer the right side of one quote switches
   between Preview (the customer's quote sheet from quotedoc.js, shrunk to the pane, redrawn as you edit) and
   Totals & actions. Save and Send stay in both. Phones: unchanged (the switch and preview never show). */
.q-pvtabs, .q-pv { display: none; }
body.desk-fit .wrap[data-desk=quote] > .dfill:has(> .q-side.pv-on) { grid-template-columns: minmax(0, 5fr) minmax(360px, 4fr); }
body.desk-fit .wrap[data-desk=quote] .q-side > .q-pvtabs { display: flex; flex-wrap: nowrap; margin: 0 0 10px; }
body.desk-fit .wrap[data-desk=quote] .q-side > .q-pvtabs button { font-size: 16px; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on { display: flex; flex-direction: column; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > :not(.q-pvtabs, .q-pv, .q-bar, #q-confirm, #q-acts) { display: none; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > #q-acts > :not(#qa-send) { display: none; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > #q-acts:empty { display: none; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > .q-bar { flex: none; margin: 10px 0 0; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > #q-acts { flex: none; margin-top: 10px; }
body.desk-fit .wrap[data-desk=quote] .q-side.pv-on > .q-pv { display: block; flex: 1 1 0; min-height: 180px; overflow-y: auto; overscroll-behavior: contain;
  border: 1px solid var(--border); border-radius: 12px; background: #e8e8e2; }
body.desk-fit .wrap[data-desk=quote] .q-pv-in { overflow: hidden; height: 400px; }
body.desk-fit .wrap[data-desk=quote] .q-pv iframe { display: block; width: 860px; height: 1100px; border: 0; transform-origin: top left; transform: scale(.4); pointer-events: none; }

/* ---------- Quick search (web/quick-search.js): Ctrl+K / Cmd+K, "/" or the header box on a computer opens one popup
   that finds clients and screens (like Linear's, Jobber's and Shopify admin's). Phones never get the box or the popup. */
.qs-open { display: none; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero > .qs-open { order: 8; display: inline-flex; align-items: center; gap: 8px; flex: none; margin-left: auto;
  min-width: 200px; height: 38px; box-sizing: border-box; margin-block: -10px; padding: 0 10px 0 12px;   /* never makes the header row taller (it's drawn a moment after the screen) */
  border: 1px solid var(--border); border-radius: 10px; background: var(--card); color: var(--text-soft); font: inherit; font-size: 16px; cursor: pointer; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero > .qs-open:hover { border-color: var(--text-soft); }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero:has(> .qs-open) .who { margin-left: 0; }
.qs-open .qs-ph { flex: 1; text-align: left; }
.qs-open .qs-mag { font-size: 18px; line-height: 1; }
.qs-open kbd, .qs-foot kbd { font: inherit; font-size: 13px; padding: 1px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--text-soft); }
.qs-bg { position: fixed; inset: 0; z-index: 95; background: rgba(0,0,0,.4); display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.qs { width: min(640px, calc(100vw - 48px)); max-height: 70vh; display: flex; flex-direction: column; background: var(--bg); color: var(--text); border-radius: 14px; box-shadow: 0 18px 50px rgba(0,0,0,.3); overflow: hidden; }
.qs .qs-in { margin: 0; width: 100%; box-sizing: border-box; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; padding: 16px 18px; font-size: 18px; background: transparent; color: var(--text); outline: none; }
.qs-list { overflow-y: auto; overscroll-behavior: contain; padding: 6px 0; }
.qs-h { padding: 8px 18px 4px; font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--text-soft); }
.qs-row { display: flex; align-items: center; gap: 12px; padding: 8px 18px; cursor: pointer; }
.qs-row[aria-selected="true"] { background: var(--card); box-shadow: inset 3px 0 0 var(--link); }
.qs-ic { flex: none; width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; background: var(--card); font-weight: 700; font-size: 15px; color: var(--text-soft); }
.qs-ic svg, .qs-ic img { width: 20px; height: 20px; }
.qs-t { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.qs-n { font-size: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qs-s { font-size: 14px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qs-k { flex: none; font-size: 13px; color: var(--text-soft); }
.qs-none { padding: 10px 18px; font-size: 15px; color: var(--text-soft); }
.qs-foot { display: flex; gap: 16px; padding: 8px 18px; border-top: 1px solid var(--border); font-size: 13px; color: var(--text-soft); }
@media (max-width: 1023px), (max-height: 639px) { .qs-bg { display: none; } }
/* QA sweep 1: small layout fixes found on phones and computers (web-tests/qa-sweep.test.mjs) */
/* phones: a message or button at the end of one pane keeps its space before the card that starts the next pane
   (the panes are display: contents on phones, so `.msg + .card` / `.btn + .card` can't see across them) */
body:not(.desk-fit) :is(.dpane, .dfill):has(> :is(.msg:not(.hidden), .btn):last-child, > .btn + .msg.hidden:last-child)
  + :is(.dpane, .dfill) > :is(.card, form.card):first-child,
body:not(.desk-fit) :is(.msg:not(.hidden), .btn) + .dfill > :is(.card, form.card):first-child,
body:not(.desk-fit) :is(.msg:not(.hidden), .btn) + .dfill > .dpane:first-child > :is(.card, form.card):first-child { margin-top: 14px; }
/* a conversation (a flex column): Back sits on the left like every other screen, not centered */
.wrap.convo > .back { align-self: flex-start; }
/* Route: the Add stops card doesn't get an extra gap over its button */
#addcard > #addopen:first-child { margin-top: 0; }
/* computer, Weather: the 12 hours split into even rows (12, 6 + 6 or 4 + 4 + 4), never 11 + 1 */
body.desk-fit #wx-page .dpane:has(.wx-strip) { container-type: inline-size; }
body.desk-fit #wx-page .wx-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@container (min-width: 380px) { body.desk-fit #wx-page .wx-strip { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@container (min-width: 720px) { body.desk-fit #wx-page .wx-strip { grid-template-columns: repeat(12, minmax(0, 1fr)); } }
/* ===== Printing (QA: printouts) =====
   The browser's own Print / Save as PDF on any app screen (route sheet, call-ahead list, Labels & SDS, day recap, records…),
   like Jobber / Shopify admin pages print: only the screen's content goes on paper, all of it, top to bottom.
   On a computer the screens fit the window (body.desk-fit / desk-page / desk-home: 100vh, panes that scroll on their own,
   a pinned header). On paper that would cut the printout to one page, so it flows as one column instead.
   The printouts made for customers (bills, quotes, letters, reports) are their own pages (printdocs.js) and aren't affected.
   Screens are unchanged: everything here is inside @media print. */
@media print {
  html, body { background: #fff !important; }
  .tabbar, .update-bar, #update-bar, .tip, .back, #navload, .savebar, .done-pop, .hero .who, .set-nav, .q-pvtabs, .q-pv,
    .sb-sheet, .sheet-bg, .lightbox, .iv-prev { display: none !important; }
  body.has-tabs { padding-left: 0 !important; }
  body.has-tabs .wrap { padding-bottom: 0 !important; }
  body.has-tabs .hero { margin-left: 0 !important; margin-right: 0 !important; padding-left: 0 !important; padding-right: 0 !important; }
  /* the computer layouts: no window-high screens or panes that scroll on their own, no pinned rows (they'd repeat or cut) */
  body:is(.desk-home, .desk-fit, .desk-page) { height: auto !important; overflow-x: clip !important; overflow-y: visible !important; }
  body:is(.desk-home, .desk-fit, .desk-page) .wrap, .wrap.convo { height: auto !important; min-height: 0 !important; overflow: visible !important; }
  body:is(.desk-home, .desk-fit, .desk-page) .wrap { display: block !important; max-width: none !important; padding: 0 !important; }
  body.desk-fit .wrap[data-desk] > form { display: block !important; }
  :is(.dfill, .hcols) { display: block !important; margin: 0 !important; height: auto !important; min-height: 0 !important; }
  :is(.dpane, .hcol, .dp-board, .dp-w) { display: block !important; height: auto !important; min-height: 0 !important; max-height: none !important; overflow: visible !important; padding: 0 !important; }
  .sticky, .convo-top, .composer, body.desk-page .wrap > .hero, .wrap .dp-h, .rd-filters, .bl-tots, .ar-head, .te-preview { position: static !important; box-shadow: none !important; }
  :is(body.desk-home, body.desk-fit, body.desk-page) .hero .sub { white-space: normal !important; overflow: visible !important; }
  /* keep a row together on a page */
  .card, .stop, .person, .rd-call, .ar-item, .menu-card { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
}

/* QA follow-ups 1 (web-tests/qa-followups.test.mjs) */
/* "More below" (web/desk.js edgeHints): a pane with more to scroll fades softly at that edge, so a card or button cut
   off at the bottom of a short laptop window reads as "scroll for more". A mask, so it works on any background and
   theme. Phones: never (the classes only go on while the window fits). */
body.desk-fit .dpane:is(.more-up, .more-down) {
  --fade-t: 0px; --fade-b: 0px;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, .25) 0, #000 var(--fade-t), #000 calc(100% - var(--fade-b)), rgba(0, 0, 0, .25) 100%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, .25) 0, #000 var(--fade-t), #000 calc(100% - var(--fade-b)), rgba(0, 0, 0, .25) 100%);
}
body.desk-fit .dpane.more-up { --fade-t: 22px; }
body.desk-fit .dpane.more-down { --fade-b: 36px; }
/* First-run QA 2: route to-do note, service checkbox rows, "Shows as" name line, feature-off screen */
/* Route: stops still to log, before the day is over: a plain note (red only once the day has passed) */
.msg.rt-todo { background: var(--card); color: var(--text); border: 1px solid var(--border); border-left: 4px solid var(--border); }
/* a checkbox row with a long hint (Charge sales tax): the words wrap beside the box instead of squeezing into a column */
.swatch.sw-two { align-items: flex-start; }
.swatch.sw-two > input { flex: none; margin-top: 3px; }
.swatch.sw-two > .sw-txt { flex: 1; min-width: 0; font-size: 16px; line-height: 1.35; }
.swatch.sw-two > .sw-txt .hint { display: block; font-size: 14px; }
/* Add a client: the name in the app fills itself in; a quiet line, tap it to change it */
.dn-row { margin-top: 12px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.dn-row[hidden] { display: none; }
.dn-row .m { font-size: 14px; }
.dn-show { background: none; border: 0; padding: 4px 0; margin: 0; min-height: 32px; font: inherit; font-size: 16px; color: var(--link); text-align: left;
  cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; overflow-wrap: anywhere; min-width: 0; }
/* a screen whose feature is off */
#ft-off .btn { width: 100%; }

/* Desktop: Ask the helper (web/helper.js, data-desk="helper"; web-tests/desk-helper.test.mjs) — like the Messages screen
   and Shopify Sidekick / Intercom on a computer: the conversation on the left (only it scrolls, it opens at the newest
   message) with the composer pinned at the bottom, and a side pane on the right with the setup checklist and the
   changes waiting for review. Opened from Settings on a wide window (1400px+) the Settings menu is the first column;
   narrower, the chat keeps the room. Phones: unchanged (.dfill/.dpane are display: contents; side-only parts hidden). */
body:not(.desk-fit) .hp-side-only, body.desk-fit .hp-phone-only { display: none !important; }
body.desk-fit .wrap[data-desk=helper] .set-nav { display: none; }
body.desk-fit .wrap[data-desk=helper] { padding-top: 16px; }
body.desk-fit .wrap[data-desk=helper] > .top { margin-bottom: 4px; }
body.desk-fit .wrap[data-desk=helper] > .back { margin: 0 0 4px; }
body.desk-fit .wrap[data-desk=helper] > .hp-head { margin-bottom: 12px; }
body.desk-fit .wrap[data-desk=helper] > .hp-head .hp-links { font-size: 16px; }
body.desk-fit .wrap[data-desk=helper] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr) minmax(280px, 340px); }
body.desk-fit .wrap[data-desk=helper] > .dfill > .hp-main { order: 1; display: flex; flex-direction: column; overflow: hidden; padding-bottom: 0; }
body.desk-fit .wrap[data-desk=helper] > .dfill > .hp-side { order: 2; border-left: 1px solid var(--border); padding-left: 16px; }
@media (min-width: 1400px) {
  body.desk-fit .wrap[data-desk=helper] > .dfill:has(> .set-nav) { grid-template-columns: minmax(230px, 260px) minmax(0, 1fr) minmax(270px, 310px); }
  body.desk-fit .wrap[data-desk=helper] .set-nav { display: block; order: 0; padding-right: 10px; border-right: 1px solid var(--border); }
}
/* the conversation: header-less thread that scrolls, then chips, review bar and the composer */
body.desk-fit .wrap[data-desk=helper] .hp-main > * { flex-shrink: 0; }
body.desk-fit .wrap[data-desk=helper] .hp-main > .msg { margin: 0 0 8px; font-size: 16px; }
body.desk-fit .wrap[data-desk=helper] .hp-log { flex: 1 1 auto; min-height: 0; margin: 0; padding: 4px 6px 12px; }
body.desk-fit .wrap[data-desk=helper] .hp-bottom { padding: 10px 0 14px; }
body.desk-fit .wrap[data-desk=helper] .hp-b { max-width: 78%; font-size: 16px; }
body.desk-fit .wrap[data-desk=helper] :is(.hp-hint, .hp-intro .m, .hp-work, .hp-review .m, .credit-line, .hp-chip, .hp-file) { font-size: 16px; }
body.desk-fit .wrap[data-desk=helper] .hp-compose textarea { max-height: 24vh; }
/* the side pane: the checklist as a list (done ✓, the one we're on in bold), next steps, changes to review */
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-prog { position: static; box-shadow: none; background: none; padding: 0; margin: 0 0 14px; }
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-prog-top { flex-direction: column; gap: 2px; font-size: 16px; color: var(--text); }
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-prog-top > :first-child { font-weight: 700; }
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-secs { flex-direction: column; flex-wrap: nowrap; gap: 0; overflow: visible; white-space: normal; font-size: 16px; margin-top: 6px; }
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-secs li { padding: 7px 10px; border-radius: 8px; }
body.desk-fit .wrap[data-desk=helper] .hp-side .hp-secs li.cur { background: color-mix(in srgb, var(--primary) 12%, var(--card)); box-shadow: inset 4px 0 0 var(--primary); }
body.desk-fit .wrap[data-desk=helper] .hp-side .card { padding: 14px; margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=helper] .hp-side .card .m, body.desk-fit .wrap[data-desk=helper] .hp-side-tip, body.desk-fit .wrap[data-desk=helper] .hp-side .hp-ul { font-size: 16px; }
body.desk-fit .wrap[data-desk=helper] .hp-side .card .m { margin: 4px 0 0; }
body.desk-fit .wrap[data-desk=helper] .hp-side .card .btn { margin: 12px 0 0; }
body.desk-fit .wrap[data-desk=helper] .hp-side-tip { color: var(--text-soft); margin: 0; }
/* ---------------------------------------------------------------- Download CSV (web/csv.js)
   Owners/admins get a "⬇ Download CSV" button on the lists (like Jobber / Housecall Pro / Shopify "Export"). It sits in
   the screen's own button row; on a computer it stays in the fixed part of the fit-the-window screens. */
.csv-btn.small-btn { font-size: 16px; min-height: 44px; }
.csv-row { display: flex; justify-content: flex-end; margin: 8px 0 4px; }
.cal-foot .csv-btn { margin-left: 10px; vertical-align: middle; }
.ql-acts { display: contents; }
.ql-acts > .csv-btn { margin-top: 10px; }
body.desk-fit .wrap[data-desk=quotes] > .ql-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 16px; }
body.desk-fit .wrap[data-desk=quotes] > .ql-acts > .btn { width: auto; margin: 0; padding-left: 22px; padding-right: 22px; }
body.desk-fit .wrap[data-desk=timesheets] > .csv-row { max-width: 520px; justify-content: flex-start; margin: -6px 0 12px; }
#sc-page > #sc-csv, #eq-home > #eq-csv { margin-top: 10px; }
body.desk-fit .wrap[data-desk=calendar] .cal-dayp[hidden] { display: none; }   /* the picked day put away: "Last time we did each service" moves up */
/* ---------------------------------------------------------------- Accessibility (keyboard focus ring) — qa/a11y
   Every control shows a clear ring when reached with the keyboard (only then: :focus-visible, so taps and clicks look
   the same as before). The theme's link color is picked to be readable on every look (Midnight too); the 2px gap keeps
   it apart from a button of the same color. A screen's title gets focus after moving to it, without a ring. */
a[href]:focus-visible, button:focus-visible, summary:focus-visible, [role=button]:focus-visible, [role=link]:focus-visible,
[role=tab]:focus-visible, [role=switch]:focus-visible, [role=checkbox]:focus-visible, [role=menuitem]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible, input[type=checkbox]:focus-visible, input[type=radio]:focus-visible,
input[type=range]:focus-visible, input[type=color]:focus-visible, input[type=file]:focus-visible, select:focus-visible {
  outline: 3px solid var(--link); outline-offset: 2px; }
.tabbar button:focus-visible, .set-nav .set-link:focus-visible, .qs-open:focus-visible { outline-offset: -3px; }
h1[tabindex="-1"]:focus, #app[tabindex="-1"]:focus, [role=dialog][tabindex="-1"]:focus, .dpane[tabindex="-1"]:focus { outline: none; }
.te-lock, .pe-lock, div.announce-mini { cursor: default; }
/* text boxes and pick lists: the same ring, a bit stronger than before so it shows on every look */
input:focus, select:focus, textarea:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 38%, transparent); }
/* a date box's calendar button (its last Tab stop) doesn't count as :focus in Chrome: ring it too */
input[type=date]:focus-within, input[type=time]:focus-within, input[type=month]:focus-within, input[type=datetime-local]:focus-within {
  outline: none; border-color: var(--link); box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 38%, transparent); }
/* inside a computer's scrolling pane the ring sits just inside the edge, so the pane never cuts it off */
:is(.dpane, .hcol) :is(button:not(.link), [role=button], a[href]:not(.link), summary):focus-visible { outline-offset: -3px; }

/* ---- clean QR codes (0173): Settings → Billing → Other ways to pay, the Venmo / Zelle code drawn from what it says ---- */
.bl-op .bl-qrrow { align-items: flex-start; flex-wrap: wrap; }
.bl-qrrow .bl-qrhint { overflow-wrap: anywhere; margin: 2px 0 6px; }
.bl-qrbox, .bl-qrprev { display: inline-block; line-height: 0; }
svg.bl-qr { width: 112px; height: 112px; padding: 4px; box-sizing: content-box; border-radius: 10px; }
.bl-qrrow .bl-qrbtns { flex: 0 1 auto; }
.bl-qrrow .bl-qrbtns .small-btn { min-height: 44px; font-size: 15px; display: inline-flex; align-items: center; justify-content: center; }
.bl-qrread { margin: 4px 0 10px; overflow-wrap: anywhere; }
.bl-qrread.msg.warn { background: color-mix(in srgb, var(--error) 8%, var(--card)); color: var(--text); border-left: 4px solid #b7791f; }
.bl-qrread .bl-qrq { margin: 0 0 8px; font-weight: 600; font-size: 15px; }
.bl-qracts { display: flex; flex-wrap: wrap; gap: 8px; }
.bl-qracts .btn { width: auto; flex: 1 1 140px; margin-top: 8px; }
@media (max-width: 520px) { .bl-qrrow .bl-qrbtns { flex: 1 1 100%; flex-direction: row; flex-wrap: wrap; } .bl-qrrow .bl-qrbtns .small-btn { flex: 1 1 auto; } }

/* ---- arrival pop-up (0175): "You're at <place> — Start?" on today's route (web/arrival.js) ---- */
.arr-bar { position: fixed; left: 12px; right: 12px; bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 45; max-width: 520px; margin: 0 auto;
  padding: 12px 14px; border-radius: 14px; background: var(--card); color: var(--text); border: 1px solid var(--border);
  border-left: 5px solid var(--link); box-shadow: 0 6px 24px rgba(20, 48, 28, .18); animation: arr-in .25s ease-out; }
.arr-bar .arr-t { font-size: 16px; line-height: 1.35; overflow-wrap: anywhere; }
.arr-bar .arr-w { display: block; font-size: 14px; color: var(--text-soft); }
.arr-bar .arr-q { font-size: 15px; font-weight: 600; margin-top: 4px; }
.arr-bar .arr-acts { display: flex; gap: 8px; margin-top: 10px; }
.arr-bar .arr-acts .small-btn { flex: 1 1 0; min-height: 44px; font-size: 16px; margin: 0; }
.arr-bar.arr-big { padding: 16px; }
.arr-bar.arr-big .arr-t { font-size: 18px; }
.arr-bar.arr-big .arr-q { font-size: 17px; }
.arr-bar.arr-big .arr-acts { gap: 10px; }
.arr-bar.arr-big .arr-acts .small-btn { min-height: 56px; font-size: 18px; font-weight: 700; }
@keyframes arr-in { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .arr-bar { animation: none; } }
@media (min-width: 900px) { .arr-bar { bottom: 20px; left: 100px; } }
@media print { .arr-bar { display: none !important; } }
.rt-view:has(> .arr-bar) { padding-bottom: 200px; }
/* ---- QA sweep 3 (web-tests/qa-sweep-3.test.mjs) ---- */
/* a row's grey second line breaks between words (it broke anywhere: "10,0 / 00 sq ft", "Apa / rtment"); a long email still wraps */
.person .m { word-break: normal; overflow-wrap: anywhere; }
/* a row with buttons (Team: Stats, Edit, Set password): on a narrow phone the buttons go under the name instead of
   squeezing it to a word a line ("Screens: Ful / l") */
.person:has(> .person-acts) { flex-wrap: wrap; }
.person:has(> .person-acts) > div:first-child { flex: 1 1 9em; min-width: 0; }
/* computer header row: a long title (a client's long name) shrinks with "…" instead of pushing Search off the window;
   the grey line under the title gives way first */
:is(body.desk-home, body.desk-fit, body.desk-page) .hero h1 { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .sub { flex: 0 1000 auto; }
/* focus rings: inside a pane's edge only where a pane scrolls (a computer); on a phone the panes are just the page, so
   the ring sits outside the button like everywhere else. A tap-to-change value always rings outside its text (the
   ring inside covered it: "$3.959/ga") */
body:not(.desk-fit):not(.desk-home) :is(.dpane, .hcol) :is(button:not(.link), [role=button], a[href]:not(.link), summary):focus-visible { outline-offset: 2px; }
body .ie[role=button]:focus-visible { outline-offset: 2px; }
/* phones, a client's property with its Lawn sections: the sections get the card's full width and Directions goes
   under them (beside them, "10,000 sq ft" broke over two lines in a 190px column) */
@media (max-width: 699px) {
  .person:has(> div > [data-psec]) { flex-wrap: wrap; }
  .person:has(> div > [data-psec]) > div:first-child { flex: 1 1 100%; min-width: 0; }
}
/* a conversation's buttons (Client page, Notes, Mark unread, Close): on a small phone they wrap to a second line
   instead of Close sliding out of sight in a strip that doesn't look scrollable */
.convo-top .convo-actions { flex-wrap: wrap; overflow-x: visible; }
/* Billing's To review / Open / Overdue / Paid / All: on a small phone they wrap instead of "All" hiding past the edge */
#app .bl-tabs { flex-wrap: wrap; overflow-x: visible; }
/* ---------------------------------------------------------------- 0174 billing dry run */
/* Billing lists: a long name wraps instead of hiding the "Practice — not sent" / "Approved" pill on a phone */
.bl-list .bl-row .bl-main .n { white-space: normal; overflow-wrap: anywhere; }
/* "Their October bill is still a practice bill … Start with October" on the customer's Billing card */
.cb-prev { margin-top: 8px; }
.cb-prev .small-btn { display: block; margin-top: 8px; }
/* "Test mode is on" in Billing → To review, above Send all approved */
.bl-testmode { margin-top: 10px; text-align: left; }
/* ---------------------------------------------------------------- Possible duplicates (0176, web/duplicates.js)
   Phone: one column (the list; a pair opens on its own screen). Computer (desk-fit): the list on the left, the pair
   being compared on the right, each scrolling on its own. */
.du-pair { display: block; width: 100%; text-align: left; font: inherit; color: var(--text); cursor: pointer; padding: 14px 16px; }
.du-pair:hover, .du-pair.on { border-color: var(--link); }
.du-pair.on { box-shadow: 0 0 0 2px color-mix(in srgb, var(--link) 30%, transparent); }
.du-ph { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 8px; }
.du-ph .pill { margin-left: 0; }
.du-two { display: grid; gap: 8px; }
.du-two > div + div { border-top: 1px dashed var(--border); padding-top: 8px; }
.du-two .n, .du-side .n { font-weight: 600; font-size: 16px; overflow-wrap: anywhere; }
.du-two .m, .du-side .m { display: block; color: var(--text-soft); font-size: 14px; margin-top: 2px; overflow-wrap: anywhere; }
.du-h { margin: 22px 0 6px; }
.du-h .m { font-size: 16px; font-weight: 400; color: var(--text-soft); }
.du-junk { flex-wrap: wrap; }
.du-junk > div:first-child { min-width: 0; flex: 1 1 200px; }
.du-junk.done { opacity: .55; }
.du-junk .du-acts { margin: 0 0 0 auto; }
.du-merge > div:first-child { min-width: 0; }
.du-acts { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; margin-top: 10px; }
.du-acts .small-btn, .du-merge .small-btn { min-height: 44px; font-size: 16px; }
.du-acts .link { min-height: 44px; font-size: 16px; text-align: left; }
.du-main .btn { width: auto; flex: 1 1 200px; margin-top: 0; }
.du-sides { display: grid; gap: 12px; }
.du-side { display: flex; flex-direction: column; gap: 2px; margin: 0; cursor: pointer; font-weight: 400; min-width: 0; }
.du-side.on { border-color: var(--primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent); }
.du-pick { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; color: var(--primary); margin: 0 0 4px; min-height: 44px; cursor: pointer; }
.du-pick input { width: 20px; height: 20px; margin: 0; flex-shrink: 0; }
.du-what { margin-top: 12px; }
.du-what .m { color: var(--text-soft); font-size: 16px; margin: 10px 0 4px; }
.du-list { margin: 4px 0 0; padding-left: 20px; font-size: 16px; }
.du-list li { margin: 2px 0; overflow-wrap: anywhere; }
.du-warn { border-left: 4px solid #b7791f; }
.du-warn .check-row { padding: 12px 0 0; border-top: 0; font-size: 16px; }
.du-card .du-acts { margin-top: 8px; }
@media (min-width: 700px) {
  .du-two, .du-sides { grid-template-columns: 1fr 1fr; }
  .du-two > div + div { border-top: 0; padding-top: 0; border-left: 1px dashed var(--border); padding-left: 12px; }
}
body:not(.desk-fit) #du-page .du-rpane { display: none; }
body.desk-fit .wrap[data-desk=dups] > h1 { margin: 0 0 2px; }
body.desk-fit .wrap[data-desk=dups] > .sub { margin: 0 0 12px; font-size: 16px; }
body.desk-fit .wrap[data-desk=dups] > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=dups] > .dfill { grid-template-columns: minmax(320px, 2fr) minmax(0, 3fr); grid-auto-flow: row; }
body.desk-fit .wrap[data-desk=dups] .du-two { grid-template-columns: 1fr; }
body.desk-fit .wrap[data-desk=dups] .du-two > div + div { border-left: 0; padding-left: 0; border-top: 1px dashed var(--border); padding-top: 8px; }
/* ---- QA sweep 4 (web-tests/qa-sweep-4.test.mjs) ---- */
/* computer header row: the grey line takes only the room that's left (basis 0), so a title that fits is never cut by
   a fraction of a pixel ("Possible duplicat…" next to a long grey line); a too-long title still ends with "…" */
:is(body.desk-home, body.desk-fit, body.desk-page) .hero .sub { flex: 1 1 0; }
/* looks with flat / lifted / bordered cards (Midnight…) set every card's border: keep the picked pair, the picked
   customer and the "Check first" stripe on Possible duplicates visible there too */
html[data-cards] .du-pair.on { border-color: var(--link); }
@media (hover: hover) { html[data-cards] .du-pair:hover { border-color: var(--link); } }
html[data-cards] .du-pair.on { box-shadow: 0 0 0 2px color-mix(in srgb, var(--link) 30%, transparent); }
html[data-cards] .du-side.on { border-color: var(--primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent); }
html[data-cards] .du-warn { border-left-color: #b7791f; }
/* the floating shortcut bar (Midnight…) is taller off the bottom: the arrival pop-up and the update bar sit above it */
@media (max-width: 899px) {
  html[data-tabbar=floating] .arr-bar, html[data-tabbar=floating] .update-bar { bottom: calc(96px + env(safe-area-inset-bottom)); }
}

/* ---------------------------------------------------------------- Previous balance on bills (0178) */
.bl-acct > div { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-variant-numeric: tabular-nums; }
.bl-acct > div span { color: var(--text-soft); }
.bl-acct > div.big { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 8px; font-size: 17px; }
.bl-acct > div.big span { color: var(--text); font-weight: 600; }
.bl-acct > div.m { display: block; margin-top: 6px; }
.bl-acct-h { display: block; margin-bottom: 4px; }
.bl-acct-list { margin: 0 0 4px; padding-left: 20px; font-size: 16px; }
.bl-acct-list li { padding: 2px 0; overflow-wrap: anywhere; }
/* ---------------------------------------------------------------- Record payments (0179, web/batch-payments.js)
   Billing → Record payments: a stack of checks / cash / Venmo typed in one after another, saved as one deposit.
   Phones: one column, big tap targets (the form, then the list and Save all). A computer: the form (and customers'
   "I sent it" reports) in a left pane, the list + Save all + past deposits in a wider right pane. */
.bl-stats > .bl-batchpay { grid-column: 1 / -1; margin: 0; }
.bl-wrap > .bl-batchpay { margin: 14px 0 4px; }
body.desk-fit .wrap[data-desk=billing] .bl-stats:has(> .bl-batchpay) { grid-template-columns: 1fr 1fr auto; }
body.desk-fit .wrap[data-desk=billing] .bl-stats > .bl-batchpay { grid-column: auto; width: auto; align-self: stretch; padding: 10px 22px; }
.bp-wrap .msg.info { background: color-mix(in srgb, var(--link) 10%, var(--card)); color: var(--text); border-left: 4px solid var(--link); }
.bp-wrap .card .m { font-size: 14px; }
.bp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.bp-total { font-family: var(--font-heading); font-size: 24px; font-weight: 700; color: var(--primary); }
.bp-total.bp-undone, .bp-amt.bp-undone { text-decoration: line-through; color: var(--text-soft); }
.bp-entry > b { display: block; margin-bottom: 2px; }
.bp-hits { margin-top: 6px; }
.bp-hit { display: flex; align-items: center; gap: 10px; padding: 12px 4px; min-height: 56px; }
.bp-hit-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bp-hit .m, .bp-who .m { overflow-wrap: anywhere; word-break: normal; }
.bp-owes { flex: none; font-weight: 600; font-size: 14px; color: var(--text-soft); }
.bp-who { display: flex; align-items: center; gap: 10px; margin: 8px 0 2px; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--link); background: color-mix(in srgb, var(--link) 7%, var(--card)); }
.bp-who-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bp-who-t .n { font-weight: 700; font-size: 17px; overflow-wrap: anywhere; }
.bp-who .small-btn { flex: none; min-height: 44px; font-size: 15px; }
.bp-meth button { min-height: 48px; font-size: 15px; }
.bp-bills .check-row { min-height: 48px; align-items: center; }
.bp-bills .check-row input { margin-top: 0; }
.bp-plan:not(:empty) { margin-top: 10px; padding: 8px 10px; border-radius: 8px; background: var(--bg); color: var(--text); font-size: 15px; }
.bp-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.bp-acts .btn { flex: 1 1 140px; min-height: 52px; font-size: 17px; margin: 0; }
.bp-count:not(:empty) { margin-top: 10px; }
.bp-reports .bp-rep { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--border); flex-wrap: wrap; }
.bp-reports .bp-rep:first-of-type { margin-top: 8px; }
.bp-rep-t { flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
.bp-confirm { flex: none; width: auto; min-height: 48px; padding: 10px 20px; margin: 0; }
.bp-in { flex: none; font-weight: 600; color: var(--link); }
.bp-rows { margin-top: 8px; }
.bp-row { display: flex; align-items: stretch; border-top: 1px solid var(--border); }
.bp-row.on { background: color-mix(in srgb, var(--link) 8%, var(--card)); }
.bp-rowbtn { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px; padding: 10px 4px; border-top: 0; min-height: 60px; }
.bp-row-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; overflow-wrap: anywhere; }
.bp-row-t .n { font-weight: 600; }
.bp-row-t .m { font-size: 14px; color: var(--text-soft); }
.bp-eff { color: var(--text) !important; }
.bp-amt { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
.bp-x { flex: none; width: 48px; min-height: 48px; border: 0; background: none; color: var(--text-soft); font-size: 18px; cursor: pointer; border-radius: 8px; }
.bp-x:hover { color: var(--error); background: color-mix(in srgb, var(--error) 8%, transparent); }
.bp-x[disabled], .bp-rowbtn[disabled] { opacity: .55; cursor: default; }
.bp-dep { margin-top: 6px; border-top: 1px solid var(--border); }
.bp-save { min-height: 56px; font-size: 18px; margin-top: 14px; }
.bp-clear { display: block; margin: 14px auto 2px; min-height: 44px; }
.bp-clear.danger { color: var(--error); }
.bp-past-rows { margin-top: 6px; }
.bp-dep-row { display: flex; align-items: center; gap: 10px; padding: 10px 4px; min-height: 56px; }
.bp-dep-row > span:first-child { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bp-dep-row .n { font-weight: 600; }
.bp-drow { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--border); }
.bp-drow:first-child { border-top: 0; }
.bp-drow.voided .bp-amt { text-decoration: line-through; color: var(--text-soft); }
.bp-dep-acts { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.bp-dep-acts > .btn { margin: 0; min-height: 52px; }
.bp-undo-box { margin: 0; }
body.desk-fit .wrap[data-desk=batchpay] > h1 { margin: 0 0 2px; }
body.desk-fit .wrap[data-desk=batchpay] > .sub { margin: 0 0 12px; font-size: 16px; }
body.desk-fit .wrap[data-desk=batchpay] > .msg { margin: 0 0 12px; }
body.desk-fit .wrap[data-desk=batchpay] > .dfill { grid-auto-flow: row; grid-template-columns: minmax(340px, 2fr) minmax(0, 3fr); }
body.desk-fit .wrap[data-desk=batchpay] .dpane > .card:first-child, body.desk-fit .wrap[data-desk=batchpay] .dpane > .hidden:first-child + .card { margin-top: 0; }
body.desk-fit .wrap[data-desk=batchpay] .bp-listcard .bp-save { position: sticky; bottom: 0; }
@media (min-width: 700px) { .bp-dep-acts { flex-direction: row; flex-wrap: wrap; } .bp-dep-acts > .btn { flex: 1 1 200px; width: auto; } .bp-undo-box { flex: 1 1 100%; } }

/* ---- Address autocomplete (0180, web/address-entry.js): Google suggestions under an address box, PO Box note ---- */
.ac-list { display: block; flex: 1 1 100%; width: 100%; margin: 4px 0 8px; background: var(--card); border: 1.5px solid var(--border); border-radius: 10px; overflow: hidden; box-shadow: 0 6px 18px rgba(0, 0, 0, .08); }
.ac-list[hidden] { display: none; }
.ac-opt { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; min-height: 52px; padding: 10px 14px; border: 0; border-top: 1px solid var(--border); background: none; color: var(--text); text-align: left; font: inherit; cursor: pointer; }
.ac-opt:first-child { border-top: 0; }
.ac-opt:hover, .ac-opt.on { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.ac-main { font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }
.ac-sub { font-size: 14px; color: var(--text-soft); overflow-wrap: anywhere; }
.ac-by { padding: 4px 14px 6px; font-size: 12px; color: var(--text-soft); text-align: right; border-top: 1px solid var(--border); }
.ac-wait { padding: 14px; font-size: 15px; color: var(--text-soft); }
.ac-po { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 6px 0 8px; padding: 10px 12px; border-radius: 10px; background: color-mix(in srgb, var(--primary) 8%, var(--card)); border: 1px solid var(--border); font-size: 15px; color: var(--text); }
.ac-po[hidden] { display: none; }
.ac-po > span { flex: 1 1 220px; min-width: 0; }
.ac-po .small-btn { min-height: 44px; font-size: 15px; }
.ie-ed .ac-list { margin: 2px 0 4px; }
/* ===== Clients → Map (0181, web/client-map.js): List | Map switch, the map, the side panel ===== */
.cl-view { display: inline-flex; gap: 0; margin: 4px 0 8px; border-radius: 10px; overflow: hidden; border: 1.5px solid var(--border); }
.cl-view .small-btn { border: 0; border-radius: 0; min-height: 44px; min-width: 76px; font-size: 16px; }
.cl-mappick { margin: 8px 0 0; }
.cm-mapbox { position: relative; height: 62vh; height: 62dvh; min-height: 320px; border-radius: var(--radius); overflow: hidden; background: #dfe6dc; margin: 4px 0 12px; }
.cm-map { position: absolute; inset: 0; }
.cm-cover { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; text-align: center; font-size: 16px; background: #dfe6dc; color: #1b1b1b; }
.cm-cover .btn { width: auto; padding: 12px 22px; }
.cm-tools { position: absolute; left: 10px; top: 10px; right: 60px; z-index: 3; display: flex; flex-wrap: wrap; gap: 8px; pointer-events: none; }
.cm-tools .small-btn { pointer-events: auto; min-height: 44px; font-size: 16px; box-shadow: 0 2px 8px rgba(0,0,0,.18); }
.cm-drag { position: absolute; inset: 0; z-index: 2; cursor: crosshair; touch-action: none; background: rgba(0,0,0,.06); }
.cm-band { position: absolute; border: 2px dashed #111; background: rgba(255,212,59,.22); pointer-events: none; }
.cm-count { position: absolute; left: 10px; bottom: 10px; z-index: 3; background: rgba(255,255,255,.92); color: #1b1b1b; border-radius: 8px; padding: 6px 10px; font-size: 14px; font-weight: 600; pointer-events: none; }
.cm-key label { display: block; font-size: 16px; font-weight: 600; margin: 0 0 8px; }
.cm-key select { display: block; width: 100%; font-size: 16px; margin-top: 4px; }
.cm-legend { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.cm-li { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.cm-sw { width: 16px; height: 16px; border-radius: 50%; flex: none; border: 2px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
.cm-ll { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.cm-ln { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.cm-fix { display: block; width: 100%; text-align: left; min-height: 48px; padding: 10px 14px; margin: 0 0 12px; border-radius: var(--radius); border: 1.5px solid var(--border); background: var(--card); color: var(--link); font-weight: 600; font-size: 16px; }
.cm-card-h { display: flex; gap: 10px; align-items: flex-start; justify-content: space-between; }
.cm-card-h .n { font-weight: 700; font-size: 18px; }
.cm-card .m { font-size: 16px; }
.cm-x { flex: none; width: 44px; height: 44px; border-radius: 10px; border: 1.5px solid var(--border); background: var(--card); color: var(--text-soft); font-size: 16px; }
.cm-row { display: flex; gap: 12px; justify-content: space-between; align-items: baseline; border-top: 1px solid var(--border); padding: 8px 0; font-size: 16px; }
.cm-row > span { color: var(--text-soft); flex: none; }
.cm-row > b { text-align: right; font-weight: 600; overflow-wrap: anywhere; }
.cm-late { color: var(--error); }
.cm-card-acts, .cm-pick-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.cm-card-acts .btn, .cm-pick-acts .btn { margin: 0; width: 100%; min-height: 48px; text-align: center; text-decoration: none; display: flex; align-items: center; justify-content: center; }
.cm-pick-acts #cm-clear { grid-column: 1 / -1; }
.cm-picked .n { font-weight: 700; font-size: 18px; }
.cm-rt { display: grid; gap: 10px; margin-top: 12px; }
.cm-rt label { font-size: 16px; font-weight: 600; }
.cm-rt input, .cm-rt select { display: block; width: 100%; font-size: 16px; margin-top: 4px; }
.cm-rt .btn { margin: 0; }
#cm-open-route { margin-top: 10px; }
body.desk-fit .wrap.cm-wrap > .cl-view { align-self: flex-start; margin: 0 0 12px; }
body.desk-fit .wrap.cm-wrap > .dfill.cm-fill { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); }
body.desk-fit .wrap.cm-wrap .cm-main { overflow: hidden; padding: 2px 8px 20px; }
body.desk-fit .wrap.cm-wrap .cm-mapbox { height: 100%; min-height: 0; margin: 0; }
body.desk-fit .wrap.cm-wrap .cm-side > .card:first-child, body.desk-fit .wrap.cm-wrap .cm-side > :empty + .card { margin-top: 0; }
body.desk-fit .wrap[data-desk=clients]:not(.cm-wrap) > .cl-view { align-self: flex-start; margin: 0 0 10px; }

/* ---- Route clock (0182): the clock bar on top of your own route, and its two questions (web/routes.js) ---- */
.rt-clock { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 8px 8px 8px 14px; min-height: 56px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); }
.rt-clock .rtc-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--text-soft); }
.rt-clock.on .rtc-dot { background: var(--link); }
.rt-clock.brk .rtc-dot { background: var(--accent); }
.rt-clock .rtc-t { flex: 1 1 auto; min-width: 0; font-size: 16px; line-height: 1.3; overflow-wrap: anywhere; }
.rt-clock .rtc-time { font-weight: 700; font-variant-numeric: tabular-nums; }
.rt-clock .rtc-wait { font-size: 14px; color: var(--text-soft); }
.rt-clock .small-btn { flex: none; margin: 0; min-height: 44px; font-size: 16px; white-space: nowrap; }
.rt-clock .small-btn[data-sure] { white-space: normal; max-width: 50%; }
body.simple-view .rt-clock { padding: 10px 10px 10px 16px; }
body.simple-view .rt-clock .rtc-t { font-size: 18px; }
body.simple-view .rt-clock .small-btn { min-height: 56px; padding: 12px 20px; font-size: 18px; }
.rt-ask .rt-ask-q { margin: 6px 0 12px; font-size: 16px; }
.rt-ask .sb-sheet-acts .small-btn { flex: 1 1 auto; font-size: 16px; }
.rt-ask.rt-ask-big .sb-sheet-acts .small-btn { min-height: 56px; font-size: 18px; }

/* ---- Popup wording: a pop-up with no heading shows its message on its own, a little bigger ---- */
.done-card h2:empty { display: none; }
.done-card h2:empty + p { font-size: 18px; color: var(--text); }
