/* Northline Office, concept build (23 Oct 2026, round 11).
   Layout follows ServiceTitan's patterns; the look is Northline's own (the d-tesla site): dark, one blue, Instrument Sans.
   Rules: 4 text sizes only (32, 20, 16, 14). Weights 400, 500, 600. Every corner 4 (cards, pictures, buttons, inputs, pills);
   only true circles (the map dots and the unread dot) are round.
   Buttons 40 and 32 tall on a computer; 44 and 40 on the phone (tap targets). Spacing in steps of 8. Amber is for urgent or
   warning only, green for done only. */

@font-face { font-family: "Instrument Sans"; src: url("assets/fonts/instrument-sans-latin.woff2") format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }

:root {
  --bg: #0B1117;
  --raised: #121A22;
  --card: #18222C;
  --text: #F2F1EE;
  --text-2: #A9B3BB;
  --line: rgba(242, 241, 238, .12);
  --line-2: rgba(242, 241, 238, .26);
  --soft: rgba(242, 241, 238, .06);
  --accent: #22709F;
  --accent-hover: #1C618A;
  --on-accent: #FFFFFF;
  --accent-text: #9CC4E2;
  --accent-tint: rgba(34, 112, 159, .26);
  --warm: #E0A15E;
  --warm-tint: rgba(224, 161, 94, .14);
  --done: #8CC35C;
  --done-tint: rgba(140, 195, 92, .14);
  --stripe: repeating-linear-gradient(-45deg, rgba(34, 112, 159, .42) 0 6px, rgba(34, 112, 159, .14) 6px 12px);

  --t1: 32px; --t2: 20px; --t3: 16px; --t4: 14px;
  --r-card: 4px; --r-ctl: 4px;
  --side: 288px; --top: 64px;
  --font: "Instrument Sans", system-ui, sans-serif;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; overflow-anchor: none; }
body { margin: 0; background: var(--bg); color: var(--text); font: 400 var(--t3)/24px var(--font); -webkit-font-smoothing: antialiased; font-variant-numeric: tabular-nums; }
body::before { content: ""; position: fixed; inset: 0 0 auto 0; height: 480px; pointer-events: none; z-index: 0;
  background: radial-gradient(640px 320px at 72% -120px, rgba(34, 112, 159, .16), transparent 72%); }
h1, h2, h3, p, ul, ol, dl, dd, figure, fieldset { margin: 0; padding: 0; }
ul, ol { list-style: none; }
fieldset { border: 0; min-width: 0; }
legend { padding: 0; }
img { display: block; max-width: 100%; }
a { color: inherit; }
b, strong { font-weight: 600; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, .h1 { font-size: var(--t1); line-height: 40px; font-weight: 600; letter-spacing: -.02em; }
h2, .h2 { font-size: var(--t2); line-height: 28px; font-weight: 600; letter-spacing: -.01em; }
h3 { font-size: var(--t3); line-height: 24px; font-weight: 600; }
.meta, .sub-s { font-size: var(--t4); line-height: 20px; color: var(--text-2); }
.sub { color: var(--text-2); margin-top: 8px; }
.muted { color: var(--text-2); }
.ic { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
[tabindex="-1"]:focus { outline: none; }
.skip { position: absolute; left: 16px; top: -64px; z-index: 100; background: var(--card); padding: 8px 16px; border-radius: var(--r-ctl); }
.skip:focus { top: 16px; }
.warn { color: var(--warm); }
.warn-i { display: inline-flex; align-items: center; gap: 8px; color: var(--warm); white-space: nowrap; }
.warn-i .ic { width: 16px; height: 16px; }
.ok-t { color: var(--done); }

/* ---------- App frame: left module menu, top bar, work area ---------- */
.app { position: relative; z-index: 1; display: grid; grid-template-columns: var(--side) minmax(0, 1fr); grid-template-rows: var(--top) 1fr; min-height: 100vh; }
.side { grid-row: 1 / 3; position: sticky; top: 0; height: 100vh; overflow-y: auto; display: flex; flex-direction: column; padding: 16px 16px 24px; border-right: 1px solid var(--line); background: var(--bg); }
.brand { display: flex; align-items: center; gap: 16px; height: 48px; padding: 0 16px; margin-bottom: 8px; text-decoration: none; flex: none; }
.brand-logo { height: 24px; width: auto; }
.brand-mark { display: none; }
.brand-tag { font-size: var(--t4); line-height: 20px; color: var(--text-2); font-weight: 500; padding-left: 16px; border-left: 1px solid var(--line-2); }
.nav { display: flex; flex-direction: column; gap: 0; }
.nav a, .nav-a { display: flex; align-items: center; gap: 16px; height: 40px; padding: 0 16px; border-radius: var(--r-ctl); color: var(--text-2); text-decoration: none; font-weight: 500; white-space: nowrap; flex: none; transition: background-color .15s, color .15s; }
.nav a:hover, .nav-a:hover { color: var(--text); background: var(--soft); }
.nav a[aria-current="page"], .nav-a[aria-current="page"] { color: var(--text); background: var(--card); }
.nav a[aria-current="page"] .ic { color: var(--accent-text); }
.nl { overflow: hidden; text-overflow: ellipsis; }
.nc { margin-left: auto; font-size: var(--t4); color: var(--text-2); }
.nc.hot { color: var(--accent-text); }
.nc.warn { color: var(--warm); }
.nav-label { font-size: var(--t4); line-height: 20px; color: var(--text-2); padding: 0 16px; margin: 16px 0 8px; font-weight: 500; }
.side-foot { margin-top: auto; padding-top: 16px; display: grid; gap: 8px; }
.btn.rail-btn { justify-content: flex-start; gap: 16px; padding: 0 16px; font-size: var(--t4); }
.runs { font-size: var(--t4); line-height: 20px; color: var(--text-2); padding: 0 16px; }

.top { grid-column: 2; grid-row: 1; position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 16px; height: var(--top); padding: 0 32px; border-bottom: 1px solid var(--line); background: rgba(11, 17, 23, .9); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.m-brand { display: none; align-items: center; gap: 8px; text-decoration: none; font-weight: 600; }
.m-brand img { width: 28px; height: 28px; }
.mb-job { display: none; }
.search { position: relative; width: 400px; max-width: 40%; }
.search > .ic { position: absolute; left: 16px; top: 10px; color: var(--text-2); pointer-events: none; }
.search input[type="search"] { width: 100%; padding-left: 48px; }
.top-sp { flex: 1; }
.tag { display: inline-flex; align-items: center; height: 32px; padding: 0 16px; border: 1px solid var(--line-2); border-radius: var(--r-ctl); font-size: var(--t4); color: var(--text-2); white-space: nowrap; }
.q-results { position: absolute; top: 48px; left: 0; width: 480px; max-width: 80vw; z-index: 40; background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-card); padding: 8px; box-shadow: 0 16px 40px rgba(0, 0, 0, .35); }
.q-results a { display: block; padding: 8px 16px; border-radius: var(--r-ctl); text-decoration: none; }
.q-results a:hover, .q-results a:focus-visible { background: var(--soft); }
.q-results p { padding: 8px 16px; }

.main { grid-column: 2; grid-row: 2; min-width: 0; padding: 40px 32px 64px; }
.screen { animation: in .22s var(--ease); }
@keyframes in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------- Controls ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 40px; padding: 0 16px; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--card); color: var(--text); font: 500 var(--t3)/1 var(--font); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color .15s, border-color .15s, color .15s; }
.btn:hover { border-color: rgba(242, 241, 238, .44); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn.ghost:hover { background: var(--soft); color: var(--text); }
.btn.sm { height: 32px; font-size: var(--t4); }
.btn.sm .ic { width: 16px; height: 16px; }
.btn.wide { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn[aria-pressed="true"] { background: var(--accent-tint); border-color: var(--accent); color: var(--text); }
.btn.primary[aria-pressed="true"] { background: var(--accent); }
.icon-btn { width: 40px; padding: 0; }
.icon-btn.sm { width: 32px; }
.seg { display: inline-flex; flex-wrap: wrap; gap: 8px; }

input[type="text"], input[type="search"], input[type="email"], input[type="tel"], input[type="number"], select, textarea {
  height: 40px; padding: 0 16px; border: 1px solid var(--line-2); border-radius: var(--r-ctl); background: var(--bg); color: var(--text); font-size: var(--t3); transition: border-color .15s; }
input::placeholder, textarea::placeholder { color: var(--text-2); opacity: 1; }
input:hover, select:hover, textarea:hover { border-color: rgba(242, 241, 238, .44); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 0; border-color: transparent; }
input[aria-invalid="true"] { border-color: var(--warm); }
select { appearance: none; -webkit-appearance: none; padding-right: 40px; cursor: pointer;
  background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A9B3BB' stroke-width='1.7' stroke-linecap='round'%3E%3Cpath d='M7 10l5 5 5-5'/%3E%3C/svg%3E") no-repeat right 16px center / 16px 16px; }
select[disabled] { opacity: .6; cursor: not-allowed; }
textarea { height: auto; min-height: 96px; padding: 8px 16px; line-height: 24px; resize: vertical; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; flex: none; }
.field { display: grid; gap: 8px; align-content: start; }
.field > label, .field > .lbl { font-size: var(--t4); line-height: 20px; color: var(--text-2); font-weight: 500; }
.field input, .field select, .field textarea { width: 100%; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; }
.form-grid .full { grid-column: 1 / -1; }
.err { color: var(--warm); font-size: var(--t4); line-height: 20px; }

/* switch: a 32 px button */
.switch { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 8px 0 0; border: 0; background: none; color: var(--text-2); font-size: var(--t4); font-weight: 500; cursor: pointer; }
.switch .trk { position: relative; width: 40px; height: 24px; border-radius: var(--r-ctl); background: var(--card); border: 1px solid var(--line-2); transition: background-color .2s, border-color .2s; }
.switch .trk::after { content: ""; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; border-radius: var(--r-ctl); background: var(--text-2); transition: transform .2s var(--ease), background-color .2s; }
.switch[aria-checked="true"] { color: var(--text); }
.switch[aria-checked="true"] .trk { background: var(--accent); border-color: var(--accent); }
.switch[aria-checked="true"] .trk::after { transform: translateX(16px); background: #fff; }

/* pills: status and labels (24 tall, 4 corners) */
.pill { display: inline-flex; align-items: center; gap: 8px; height: 24px; padding: 0 8px; border-radius: var(--r-ctl); font-size: var(--t4); line-height: 20px; font-weight: 500; white-space: nowrap; background: var(--soft); color: var(--text); border: 1px solid transparent; }
.pill .ic { width: 14px; height: 14px; }
.pill.booked, .pill.draft { background: var(--soft); color: var(--text); border-color: var(--line); }
.pill.onway, .pill.sent { background: var(--accent-tint); color: var(--accent-text); }
.pill.working { background: var(--accent); color: var(--on-accent); }
.pill.done, .pill.ok, .pill.paid { background: var(--done-tint); color: var(--done); }
.pill.urgent, .pill.late, .pill.overdue { background: var(--warm-tint); color: var(--warm); }
.pill.unassigned, .pill.hold { background: transparent; color: var(--text-2); border: 1px dashed var(--line-2); }
.pill.src { background: transparent; color: var(--text-2); border-color: var(--line); }
.pill.member { background: transparent; color: var(--accent-text); border-color: rgba(156, 196, 226, .4); }
.pill.tier-good { background: var(--soft); color: var(--text); border-color: var(--line-2); }
.pill.tier-better { background: var(--accent-tint); color: var(--accent-text); }
.pill.tier-best { background: var(--accent); color: var(--on-accent); }
.pills { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* one time and status: the status as a pill, then the rest in words ("On the Way" about 10:55 AM, booked 10:30 AM) */
.st { display: inline-flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; vertical-align: middle; }
.st > span:last-child:not(.pill) { min-width: 0; }
/* the Status and Time column has one fixed width on every list (416 px), so the line is never cut; a rare long line wraps */
.tbl.one td.stc { white-space: normal; overflow: visible; }
/* key text is never cut: a title wraps to a second line, with the customer (or the job number) on the line under it */
.tbl.one td.wrap { white-space: normal; overflow: visible; }
.tbl.one td.wrap > a, .tbl.one td.wrap > .t1 { display: block; }
.tbl.one td.wrap > .meta { display: block; }
/* Care: what the plan covers, in the small size, on up to two lines */
.tbl td.covers { font-size: var(--t4); line-height: 20px; color: var(--text-2); }
/* the invoice as the customer sees it: Pay Invoice is the one full width main button, with room above it */
.pay-row { margin-top: 32px; }
.tcard-top { min-width: 0; }
.tcard-top .st { flex: 1; }
/* the Jobs list (and the jobs behind Reports): the title on one line in about 300 px, the type with the technician under it,
   the customer with the address under it, and the status pill with its time under it, in a column as wide as its text */
.tbl.one.jobs-t td, .tbl.one.jobs-t th { padding-left: 8px; padding-right: 8px; }
.tbl.one.jobs-t td:first-child, .tbl.one.jobs-t th:first-child { padding-left: 24px; }
.tbl.one.jobs-t td:last-child, .tbl.one.jobs-t th:last-child { padding-right: 24px; }
.tbl.one.jobs-t td.stc { white-space: nowrap; }
.tbl.one.jobs-t td.wrap > .meta { white-space: normal; }
.st.st2 { display: grid; justify-items: start; gap: 0; width: max-content; max-width: none; }
/* a rare long line (a leave time) wraps under the pill, so the customer keeps room for the address */
.st.st2 > .meta { display: block; max-width: 248px; white-space: normal; }
/* search: the matching text is marked */
mark { background: var(--accent-tint); color: var(--text); }
.q-results .q-more { padding-top: 8px; }

/* ---------- Building blocks ---------- */
.head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; }
.head.tight { margin-bottom: 16px; align-items: center; }
.head.tight .h-line { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.head-act { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.back { display: inline-flex; align-items: center; gap: 8px; font-size: var(--t4); line-height: 20px; color: var(--text-2); text-decoration: none; margin-bottom: 8px; }
.back:hover { color: var(--text); }
.back .ic { width: 16px; height: 16px; }
.panel { background: var(--raised); border: 1px solid var(--line); border-radius: var(--r-card); min-width: 0; }
.panel-h { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 24px 24px 16px; flex-wrap: wrap; }
.panel-h > .meta { flex: 1 1 auto; text-align: right; }
.kpi > .meta:first-child { grid-column: 1 / -1; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi > .meta + .k-v + .meta { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.min0 { min-width: 0; }
.m-only { display: none !important; }
.panel-b { padding: 0 24px 24px; }
.panel-b.pt { padding-top: 24px; }
.panel-f { display: flex; align-items: center; gap: 8px; padding: 16px 24px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.panel-f .grow { flex: 1; min-width: 0; }
/* a label with its small action on the same line (Tags, Edit Tags) */
.lbl-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.stack { display: grid; gap: 24px; align-content: start; min-width: 0; }
.g2 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.g31 { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.g2e { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.g3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.mt { margin-top: 24px; }
.mt-s { margin-top: 8px; }
.mt-m { margin-top: 16px; }
.empty { padding: 24px; color: var(--text-2); }
.link { color: var(--accent-text); text-decoration: none; font-weight: 500; }
.link:hover { text-decoration: underline; }
button.link { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-weight: 500; }
.strong { font-weight: 600; }
.chip { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 8px 0 16px; border-radius: var(--r-ctl); border: 1px solid rgba(156, 196, 226, .4); color: var(--accent-text); font-size: var(--t4); white-space: nowrap; }

.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 24px; }
.kpis.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* number tiles: about 88 tall, the label above, the number and a short line beside it */
.kpi { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; column-gap: 16px; row-gap: 4px; padding: 16px 24px; text-decoration: none; text-align: left; color: var(--text); font: inherit; transition: border-color .15s; }
button.kpi { cursor: pointer; }
a.kpi:hover, button.kpi:hover { border-color: var(--line-2); }
.kpi[aria-pressed="true"], .kpi[aria-selected="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.care-tabs .kpi:focus-visible { outline-offset: 2px; }
.kpi .k-v { display: block; font-size: var(--t2); line-height: 28px; font-weight: 600; }
.kpi .k-v.warm { color: var(--warm); }
/* Today's tiles: the short line sits under the number ("Since 7:52 AM" under the waiting time), so it is never cut */
.kpis.tall .kpi { grid-template-columns: minmax(0, 1fr); }
.kpis.tall .kpi > .meta + .k-v + .meta { white-space: normal; }

.rows > li { display: flex; align-items: center; gap: 16px; padding: 16px 0; border-top: 1px solid var(--line); }
.rows > li:first-child { border-top: 0; padding-top: 8px; }
.rows .grow { flex: 1 1 auto; min-width: 0; }
.rows .end { display: flex; align-items: center; gap: 8px; flex: none; }
.r-title { font-weight: 600; }
.r-top { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.r-acts { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
a.row-link { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 0; border-top: 1px solid var(--line); text-decoration: none; }
a.row-link:first-child { border-top: 0; padding-top: 8px; }
a.row-link:hover .r-title { color: var(--accent-text); }
.row-link .k-v { font-size: var(--t2); line-height: 28px; font-weight: 600; }

/* tables */
.tbl-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; }
.tbl th { font-size: var(--t4); line-height: 20px; font-weight: 500; color: var(--text-2); text-align: left; padding: 8px 16px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.tbl td { padding: 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl th:first-child, .tbl td:first-child { padding-left: 24px; }
.tbl th:last-child, .tbl td:last-child { padding-right: 24px; }
.tbl tbody tr { transition: background-color .15s; }
.tbl tbody tr.click { cursor: pointer; }
.tbl tbody tr.click:hover { background: var(--soft); }
.tbl a { text-decoration: none; font-weight: 600; }
.tbl a:hover { color: var(--accent-text); }
.tbl .r { text-align: right; }
.tbl .nw { white-space: nowrap; }
.tbl .meta { display: block; }
.tbl.fixed { table-layout: fixed; }
.tbl.fixed td { overflow-wrap: break-word; }
.tbl.tight td { padding-top: 8px; padding-bottom: 8px; }
.cell-2 { display: grid; }
.r-cell { justify-items: end; gap: 8px; }
/* one line rows, about 48 tall: the dense lists (Jobs, Customers, Invoices, tray) */
.tbl.one { table-layout: fixed; }
.tbl.one td { height: 48px; padding-top: 8px; padding-bottom: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tbl.one td.act { overflow: visible; }
.tbl.one .pills { flex-wrap: nowrap; }
.tbl.one th { height: 40px; padding-top: 0; padding-bottom: 0; }
.tbl.one td, .tbl.one th { padding-left: 12px; padding-right: 12px; }
.tbl.one td:first-child, .tbl.one th:first-child { padding-left: 24px; }
.tbl.one td:last-child, .tbl.one th:last-child { padding-right: 24px; }
.tbl.one .meta { display: inline; }
.tbl td.dim { color: var(--text-2); font-size: var(--t4); }
.tbl .ic.mark { width: 16px; height: 16px; color: var(--warm); vertical-align: -3px; margin-right: 8px; }
.sort { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 8px; margin-left: -8px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--text-2); font: 500 var(--t4)/20px var(--font); cursor: pointer; }
.sort:hover { color: var(--text); background: var(--soft); }
.sort .ic { width: 16px; height: 16px; opacity: .45; }
th[aria-sort="ascending"] .sort, th[aria-sort="descending"] .sort { color: var(--text); }
th[aria-sort="ascending"] .sort .ic, th[aria-sort="descending"] .sort .ic { opacity: 1; color: var(--accent-text); }
.toolbar { display: flex; align-items: center; gap: 8px; padding: 16px 24px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.toolbar input[type="search"] { width: 240px; }
.toolbar select { width: auto; }
.toolbar .tb-sp { flex: 1; }
.tb-f { display: inline-flex; align-items: center; gap: 8px; margin-right: 16px; }

/* tabs (role tablist, arrow keys move between them) */
.tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--line); margin-bottom: 24px; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab { height: 40px; padding: 0; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; background: none; color: var(--text-2); font-weight: 500; cursor: pointer; white-space: nowrap; transition: color .15s, border-color .15s; }
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent-text); }
.tab .tn { color: var(--text-2); margin-left: 8px; font-size: var(--t4); }
.panel .tabs { padding: 0 24px; margin-bottom: 0; }
[role="tabpanel"]:focus-visible { outline-offset: 4px; }

/* key facts strip (record pages) */
.facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 24px; }
.facts > div { padding: 16px 24px; border-left: 1px solid var(--line); border-top: 1px solid var(--line); min-width: 0; }
.facts > div:nth-child(4n + 1) { border-left: 0; }
.facts > div:nth-child(-n + 4) { border-top: 0; }
.facts dt { font-size: var(--t4); line-height: 20px; color: var(--text-2); }
.facts dd { overflow-wrap: anywhere; }
.facts dd a { text-decoration: none; font-weight: 600; }
.facts dd a:hover { color: var(--accent-text); }
.facts select { width: 100%; }
.facts .err { margin-top: 8px; }
.dl { display: grid; grid-template-columns: auto 1fr; gap: 8px 24px; }
.dl dt { color: var(--text-2); font-size: var(--t4); line-height: 24px; }
.dl dd { min-width: 0; overflow-wrap: anywhere; }
/* narrow side panels: the label sits above the value */
.dl.stack { grid-template-columns: minmax(0, 1fr); gap: 0; }
.dl.stack dt { line-height: 20px; }
.dl.stack dt:not(:first-child) { margin-top: 16px; }
.dl.stack dd { overflow-wrap: normal; }
/* timelines and history: the time sits above the event */
.tl > li { display: grid; gap: 0; padding: 16px 0; border-top: 1px solid var(--line); }
.tl > li:first-child { border-top: 0; padding-top: 0; }
.tl .meta { white-space: nowrap; }
.done-list { display: grid; gap: 8px; }
.done-list li { display: flex; align-items: flex-start; gap: 8px; }
.done-list .ic { width: 16px; height: 16px; margin-top: 4px; color: var(--done); stroke-width: 2; }
.up-list { display: grid; gap: 8px; }
.up-list li { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 16px; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--raised); }
.up-list li > span { min-width: 0; }
tr.hl td { background: var(--accent-tint); }
tr.hl td:first-child { box-shadow: inset 3px 0 0 var(--accent-text); }

/* photos: locked to squares */
.photos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.photos.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.photo { aspect-ratio: 1 / 1; width: 100%; object-fit: cover; border-radius: var(--r-card); background: var(--card); }

/* toasts: one at a time, one or two lines (never cut), at a fixed spot at the top centre of the work area. The toast hangs from the bottom edge of
   the top bar, over the page's top margin (40 px), so it takes no room in the page and nothing moves when it comes or goes;
   at the top of a page it sits above the heading, clear of tables, the board and buttons. While a job panel is open it is
   centred on the part of the work area the panel leaves free. Empty, the spot is 0 px. */
.toasts { position: fixed; top: var(--top); left: var(--side); right: 0; z-index: 58; display: flex; justify-content: center; padding: 0 32px; pointer-events: none; }
body.dr-open .toasts { right: 480px; }
.toast { pointer-events: auto; cursor: pointer; display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 640px; min-height: 40px; padding: 4px 4px 4px 16px; border: 1px solid var(--accent); border-top: 0; border-radius: 0 0 var(--r-card) var(--r-card); background: var(--card); box-shadow: 0 16px 32px rgba(0, 0, 0, .35); animation: drop .2s var(--ease); }
@keyframes drop { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.toast-t { flex: 1; min-width: 0; font-weight: 500; line-height: 24px; }
.toast .btn { flex: none; }

/* the app notice: what My Northline would show the customer */
.notice { display: grid; grid-template-columns: 32px 1fr; gap: 16px; align-items: start; padding: 16px; border: 1px solid var(--line-2); border-radius: var(--r-card); background: var(--bg); }
.notice img { width: 32px; height: 32px; border-radius: var(--r-ctl); background: var(--accent); padding: 4px; }
.notice b { display: block; }
.notice-wrap { display: grid; gap: 8px; margin-top: 16px; }
/* the same notice in one line (phone job screen, once it is sent) */
.notice-1 { display: flex; align-items: center; gap: 8px; margin-top: 16px; min-height: 32px; padding: 4px 8px; border: 1px solid var(--line-2); border-radius: var(--r-ctl); background: var(--bg); font-size: var(--t4); line-height: 20px; color: var(--text-2); }
.notice-1 img { width: 24px; height: 24px; flex: none; border-radius: var(--r-ctl); background: var(--accent); padding: 3px; }
.notice-1 span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* success panel (when it shows, no toast) */
.success { padding: 24px; border: 1px solid rgba(140, 195, 92, .45); border-radius: var(--r-card); background: var(--done-tint); }
.success h2, .success .h2 { color: var(--done); }
.success.slim { padding: 16px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
.note-box { padding: 16px 24px; border: 1px solid rgba(156, 196, 226, .3); border-radius: var(--r-card); background: rgba(34, 112, 159, .1); }
.warn-box { padding: 16px; border: 1px solid rgba(224, 161, 94, .5); border-radius: var(--r-card); background: var(--warm-tint); }

/* ---------- Today ---------- */
.statusbar { display: flex; gap: 2px; height: 8px; margin: 8px 0 16px; }
.statusbar span { display: block; height: 100%; }
.sb-booked { background: var(--line-2); }
.sb-onway { background: var(--accent-text); }
.sb-working { background: var(--accent); }
.sb-done { background: var(--done); }
.legend { display: flex; flex-wrap: wrap; gap: 8px 24px; font-size: var(--t4); line-height: 20px; color: var(--text-2); align-items: center; }
.legend > span { display: inline-flex; align-items: center; gap: 8px; }
.legend .sq { display: inline-block; width: 8px; height: 8px; }

/* ---------- Dispatch board ---------- */
.d-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
.date-nav { display: flex; align-items: center; gap: 8px; }
.date-nav h2 { min-width: 264px; text-align: center; }
/* a dialog's window picker: one week at a time, with Previous Week and Next Week */
.slot-nav { margin-top: 16px; }
.slot-nav p { min-width: 216px; text-align: center; }
.sec-h { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.board { overflow: hidden; }
.b-head, .b-row { display: grid; grid-template-columns: 216px minmax(0, 1fr); }
.b-head { height: 40px; border-bottom: 1px solid var(--line); }
.b-head .b-name { display: flex; align-items: center; padding: 0 24px; border-right: 1px solid var(--line); font-size: var(--t4); color: var(--text-2); font-weight: 500; }
.b-hours { position: relative; }
.b-hours span { position: absolute; top: 10px; font-size: var(--t4); line-height: 20px; color: var(--text-2); padding-left: 8px; white-space: nowrap; }
.b-body { position: relative; }
.b-lines { position: absolute; top: 0; bottom: 0; left: 216px; right: 0; pointer-events: none; }
.b-lines i { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); }
.win-band { position: absolute; top: 0; bottom: 0; background: rgba(34, 112, 159, .14); border-left: 1px dashed var(--accent-text); border-right: 1px dashed var(--accent-text); }
.now { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--accent-text); z-index: 1; }
/* every hour label is always drawn; now is a small marker on its line, under the labels */
.now-mk { position: absolute; bottom: 0; width: 0; height: 0; margin-left: -6px; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 8px solid var(--accent-text); }
.leg-now { display: inline-block; width: 2px; height: 16px; background: var(--accent-text); }
/* the booked window is shaded in the header row itself, behind the hours (no strip of its own under them); while a job with a
   window on this day is placed, the header's first cell is its key */
.b-head .win-band.hd { background: rgba(34, 112, 159, .22); }
.wb-key { display: inline-block; width: 24px; height: 16px; margin-right: 8px; flex: none; background: rgba(34, 112, 159, .22); border-left: 1px dashed var(--accent-text); border-right: 1px dashed var(--accent-text); }
.b-head .b-name:has(.wb-key) { color: var(--accent-text); font-weight: 600; }
.b-row { height: 56px; border-bottom: 1px solid var(--line); }
.b-row:last-child { border-bottom: 0; }
.b-row .b-name { display: flex; align-items: center; gap: 16px; padding: 0 24px; min-width: 0; border-right: 1px solid var(--line); }
.b-row.sugg .b-name { box-shadow: inset 3px 0 0 var(--accent-text); }
.ini { display: inline-grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: var(--r-ctl); background: var(--card); border: 1px solid var(--line-2); font-size: var(--t4); font-weight: 600; }
.b-who { display: grid; min-width: 0; line-height: 20px; }
.b-who b { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-who span { font-size: var(--t4); color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-who span.sg { color: var(--accent-text); font-weight: 500; }
.b-track { position: relative; transition: background-color .15s; }
.b-track.over, .w-cell.over { background: var(--accent-tint); }
.w-cell.over.no { background: none; outline: 1px dashed var(--warm); outline-offset: -2px; }
.blk { position: absolute; top: 8px; height: 40px; display: grid; align-content: center; gap: 0; padding: 0 8px; text-align: left; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--card); color: var(--text); font-size: var(--t4); line-height: 16px; cursor: pointer; overflow: hidden; z-index: 2; transition: border-color .15s, background-color .2s; }
.blk .l1, .blk .l2 { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; }
.blk b, .blk .l2 span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.blk .l2 { color: var(--text-2); }
.blk .ic { width: 14px; height: 14px; stroke-width: 2; }
.blk .urg { color: var(--warm); margin-left: auto; display: inline-flex; }
.blk:hover { border-color: rgba(242, 241, 238, .5); }
.blk.s-booked .l1 > .ic { color: var(--text-2); }
.blk.s-onway { background: var(--stripe), var(--bg); border: 1px solid var(--accent-text); }
.blk.s-onway .l1 > .ic { color: var(--accent-text); }
.blk.s-onway .l2 { color: var(--text); }
.blk.s-working { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.blk.s-working .l2 { color: var(--on-accent); }   /* white on the blue: 5.4 to 1 */
.blk.s-done { background: #1C2A22; border-color: rgba(140, 195, 92, .45); }
.blk.s-done .l1 > .ic { color: var(--done); }
.blk.late, .wchip.late { border-color: var(--warm); box-shadow: inset 0 0 0 1px var(--warm); }
.blk.urgent { box-shadow: inset 3px 0 0 var(--warm); }
.blk[draggable="true"] { cursor: grab; }
/* an install's helper row: the same visit, drawn with a dashed edge */
.blk.helper, .wchip.helper { border-style: dashed; }
/* the original fades while it is dragged (the ghost, or on the Week view the chip under the pointer, is the moving copy) */
.blk.drag-src, .wchip.drag-src, tr.drag-src { opacity: .35; }
/* placing a job: each technician's earliest spot carries a label, and one ghost block of the job's real length follows the
   pointer (or the keyboard: arrow keys move the focused spot by half an hour) */
.b-track.picking-row { cursor: copy; }
.spot, .pghost { position: absolute; top: 8px; height: 40px; z-index: 3; display: grid; align-content: center; padding: 0 8px; border-radius: var(--r-ctl); font: 500 var(--t4)/16px var(--font); text-align: left; overflow: hidden; white-space: nowrap; }
.spot { border: 1px dashed var(--accent-text); background: rgba(156, 196, 226, .08); color: var(--accent-text); cursor: pointer; }
.spot b { font-weight: 600; }
.spot span, .pghost span { overflow: hidden; text-overflow: ellipsis; }
.spot:hover, .spot:focus-visible { border-style: solid; background: var(--accent-tint); color: var(--text); }
.spot.out { border-color: var(--line-2); color: var(--text-2); }
.pghost { pointer-events: none; border: 1px solid var(--accent-text); background: #1A4A69; color: var(--on-accent); z-index: 4; }
.pghost.no { border: 1px dashed var(--warm); background: none; }
.pghost.out { border-style: dashed; background: #15344A; color: var(--text); }
/* while placing, a visit on the row is a busy spot: a click there says why */
.b-track.picking-row .blk { cursor: not-allowed; }
/* the hover and focus card for a block: the details a short block has no room for */
.blk-card { position: fixed; z-index: 65; width: 288px; padding: 16px; display: grid; gap: 4px; background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-card); box-shadow: 0 16px 40px rgba(0, 0, 0, .4); pointer-events: none; }
.blk-card .meta { display: block; }
/* the board's legend row: the legend, or while placing a job, the placing message in the same height (two lines of the small
   size), so the board never moves */
.b-legend { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 57px; padding: 8px 24px; border-bottom: 1px solid var(--line); }
.b-legend.picking { background: rgba(34, 112, 159, .12); box-shadow: inset 3px 0 0 var(--accent-text); }
.b-legend.picking.urgent { background: var(--warm-tint); box-shadow: inset 3px 0 0 var(--warm); }
.pick-msg { min-width: 0; }
.pick-msg p { font-size: var(--t4); line-height: 20px; }
.pick-msg .warn-i { vertical-align: top; }
.b-legend > .btn, .b-legend > .pills { flex: none; }
/* a job just booked from Calls flashes on the board, then keeps a ring for a few seconds */
.blk.flash { outline: 2px solid var(--accent-text); outline-offset: 2px; animation: flash 1s ease-in-out 3; z-index: 4; }
@keyframes flash { 50% { outline-color: transparent; } }
.no-room { position: absolute; top: 16px; left: 8px; font-size: var(--t4); color: var(--text-2); }
.tray tr.sel td { background: rgba(34, 112, 159, .12); }
.tray tr[draggable="true"] { cursor: grab; }
.leg-blk { display: inline-block; width: 24px; height: 16px; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--card); }
.leg-blk.s-onway { background: var(--stripe), var(--bg); border-color: var(--accent-text); }
.leg-blk.s-working { background: var(--accent); border-color: var(--accent); }
.leg-blk.s-done { background: #1C2A22; border-color: rgba(140, 195, 92, .45); }
.leg-blk.late { border-color: var(--warm); }
.leg-blk.urgent { box-shadow: inset 3px 0 0 var(--warm); }
.legend .ic { width: 16px; height: 16px; }

/* week view */
.w-head, .w-row { display: grid; grid-template-columns: 168px repeat(5, minmax(0, 1fr)); }
.w-head { border-bottom: 1px solid var(--line); }
.w-head .b-name { display: flex; align-items: center; padding: 0 16px; font-size: var(--t4); color: var(--text-2); font-weight: 500; }
.w-day { height: 40px; border: 0; border-left: 1px solid var(--line); background: none; color: var(--text-2); font: 500 var(--t4)/20px var(--font); text-align: left; padding: 0 16px; cursor: pointer; white-space: nowrap; }
.w-day:hover { color: var(--text); background: var(--soft); }
.w-day.today { color: var(--accent-text); }
.w-row { border-bottom: 1px solid var(--line); min-height: 56px; }
.w-row:last-child { border-bottom: 0; }
.w-row .b-name { display: flex; align-items: center; gap: 8px; padding: 4px 8px 4px 16px; min-width: 0; }
.w-cell { border-left: 1px solid var(--line); padding: 4px; display: grid; gap: 4px; align-content: start; min-width: 0; transition: background-color .15s; }
.w-cell.today { background: rgba(34, 112, 159, .06); }
/* each cell: the hours booked that day, then the visits in order, each a one line chip: the start time, the customer and the
   job type. A chip too long for its cell leaves the type out (class short), so the time and the name are never cut. */
.w-hrs { font-size: var(--t4); line-height: 20px; color: var(--text-2); padding: 0 4px; }
.w-hrs.full { color: var(--text); font-weight: 500; }
.wchip { display: flex; align-items: center; gap: 4px; height: 24px; padding: 0 4px; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--card); color: var(--text); font: 400 var(--t4)/20px var(--font); cursor: pointer; min-width: 0; text-align: left; white-space: nowrap; overflow: hidden; }
.wchip[draggable="true"] { cursor: grab; }
.wchip b { flex: none; font-weight: 600; }
.wchip .wc-n { min-width: 0; }
.wchip.short .wc-ty { display: none; }
.wchip .urg { margin-left: auto; display: inline-flex; color: var(--warm); }
.wchip .ic { width: 14px; height: 14px; stroke-width: 2; color: var(--text-2); }
.wchip .urg .ic { color: var(--warm); }
.wchip.s-onway { background: var(--stripe), var(--bg); border-color: var(--accent-text); }
.wchip.s-onway .ic { color: var(--accent-text); }
.wchip.s-working { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.wchip.s-working .ic { color: var(--on-accent); }
.wchip.s-done { background: #1C2A22; border-color: rgba(140, 195, 92, .45); }
.wchip.s-done .ic { color: var(--done); }
.wchip.urgent { box-shadow: inset 3px 0 0 var(--warm); }

/* map: Metro Vancouver drawn from real coordinates (no map service). Land is the panel colour, water a darker blue. */
/* map: fitted to the day's jobs, zoom buttons, and a side list of each technician's stops (hover or focus lights up the route) */
.map-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 304px; align-items: start; }
.map-main { min-width: 0; border-right: 1px solid var(--line); }
.map-tools { display: flex; align-items: center; gap: 8px; padding: 16px 24px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.map-tools .meta { margin-right: auto; }
.map-side { min-width: 0; overflow-y: auto; }
.map-note { padding: 16px 24px; border-top: 1px solid var(--line); }
.ml-tech { border-bottom: 1px solid var(--line); padding: 8px 16px 16px; }
.ml-tech:last-child { border-bottom: 0; }
.ml-head { display: flex; align-items: center; gap: 16px; width: 100%; min-height: 48px; padding: 8px; margin: 0 -8px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; width: calc(100% + 16px); }
.ml-head:hover, .ml-tech.hl .ml-head { background: var(--soft); }
p.ml-head { cursor: default; }
p.ml-head:hover { background: none; }
.ml-head[aria-pressed="true"] { background: var(--accent-tint); }
.ml-stops { display: grid; gap: 0; }
.ml-stop { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 16px; align-items: start; width: calc(100% + 16px); margin: 0 -8px; padding: 8px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--text); font: 400 var(--t4)/20px var(--font); text-align: left; cursor: pointer; }
.ml-stop:hover { background: var(--soft); }
.ml-stop b { font-weight: 600; display: block; }
.ml-stop .meta { display: block; }
.ml-n { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: var(--r-ctl); font-weight: 600; font-size: var(--t4); }
.ml-n.ring { background: transparent !important; border: 2px solid; }
.ml-n.ring.tc1 { border-color: var(--tc1); } .ml-n.ring.tc2 { border-color: var(--tc2); } .ml-n.ring.tc3 { border-color: var(--tc3); } .ml-n.ring.tc4 { border-color: var(--tc4); } .ml-n.ring.tc5 { border-color: var(--tc5); }
.ml-n.tray { border: 1px dashed var(--line-2); color: var(--accent-text); }
.map .route.dim, .map .m-job.dim, .map .m-dot.dim, .map .m-done.dim { opacity: .18; }
.map .route.hl { opacity: 1; stroke-width: 4.5; }
.map .m-job.now { box-shadow: 0 0 0 2px var(--raised), 0 0 0 4px var(--text); }
.map { position: relative; aspect-ratio: 5 / 3; background: #121A22; overflow: hidden; touch-action: none; cursor: grab; }
.map.dragging { cursor: grabbing; }
.map svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.map svg.map-over { pointer-events: none; z-index: 1; }
.map .mw { fill: #070D14; stroke: rgba(156, 196, 226, .3); stroke-width: 1; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.map .mr, .map .mro { fill: none; stroke: #070D14; stroke-linecap: round; stroke-linejoin: round; }
.map .mro { stroke: rgba(156, 196, 226, .3); }
/* main roads: the same 2 px line at every zoom, light enough to sit under the routes */
.map .mroad { fill: none; stroke: rgba(242, 241, 238, .17); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.map .route { fill: none; stroke-width: 2.5; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; opacity: .85; }
.map .lead { stroke-width: 1.5; vector-effect: non-scaling-stroke; stroke: var(--text-2); }
.route.tc1, .lead.tc1 { stroke: var(--tc1); } .route.tc2, .lead.tc2 { stroke: var(--tc2); } .route.tc3, .lead.tc3 { stroke: var(--tc3); } .route.tc4, .lead.tc4 { stroke: var(--tc4); } .route.tc5, .lead.tc5 { stroke: var(--tc5); }
.m-lbl { position: absolute; transform: translate(-50%, -50%); font-size: var(--t4); line-height: 20px; color: var(--text-2); pointer-events: none; white-space: nowrap; z-index: 1; }
.m-lbl.water-lbl { color: var(--accent-text); }
/* place and road names draw above the routes, each with a dark halo, so a route line never runs through the words */
.m-lbl.city, .m-lbl.nb, .m-lbl.road-lbl { z-index: 2; -webkit-text-stroke: 4px var(--bg); paint-order: stroke fill;
  text-shadow: -2px -2px 1px var(--bg), 2px -2px 1px var(--bg), -2px 2px 1px var(--bg), 2px 2px 1px var(--bg), -3px 0 1px var(--bg), 3px 0 1px var(--bg), 0 -3px 1px var(--bg), 0 3px 1px var(--bg), 0 0 8px var(--bg), 0 0 8px var(--bg); }
.m-lbl.city { color: var(--text); font-weight: 600; }
.m-lbl.road-lbl { color: #A9B3BB; }
.m-lbl.under { z-index: 1; }
/* the lit route: each stop named beside its pin, with the customer's last name and the time */
.m-rl { position: absolute; transform: translate(-50%, -50%); z-index: 4; padding: 0 8px; border: 1px solid var(--line-2); border-radius: var(--r-ctl); background: var(--card); color: var(--text); font: 500 var(--t4)/20px var(--font); white-space: nowrap; pointer-events: none; }
/* the Map's legend: the pins, as they look on the map */
.lg-pin { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--bg); color: var(--accent-text); font-style: normal; font-size: var(--t4); line-height: 1; }
.lg-pin.ring { width: 12px; height: 12px; border: 2px solid var(--text-2); background: transparent; }
.lg-pin.here { background: var(--tc2); border-color: var(--tc2); box-shadow: 0 0 0 2px var(--raised), 0 0 0 4px var(--text); }
.lg-pin.tray { border-style: dashed; }
.lg-pin.urg { border: 2px solid var(--warm); }
.lg-off { display: inline-block; width: 12px; height: 12px; background: var(--raised); border: 2px solid var(--text); }
.map-legend { gap: 8px 16px; }
.m-dot { position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: var(--text-2); box-shadow: 0 0 0 2px var(--raised); z-index: 2; }
.m-done { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; border: 2px solid; background: var(--raised) !important; z-index: 2; }
.m-office { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 0; background: var(--raised); border: 2px solid var(--text); z-index: 2; }
.m-job { position: absolute; transform: translate(-50%, -50%); min-width: 32px; height: 32px; padding: 0 8px; border-radius: var(--r-ctl); border: 1px solid var(--line-2); background: var(--bg); color: var(--text); font: 600 var(--t4)/20px var(--font); cursor: pointer; z-index: 3; box-shadow: 0 0 0 2px var(--raised); }
.m-job:hover { outline: 2px solid var(--accent-text); outline-offset: 1px; }
.m-job.s-unassigned { border-style: dashed; color: var(--accent-text); }
.m-job.s-unassigned.urgent { border-style: dashed; }
.m-job.pick { outline: 2px solid var(--accent-text); outline-offset: 1px; }
/* technician colours: one clearly different filled colour each, used only for technicians (map pins, legend, initials).
   Blue, sky and white come from the brand; violet and rose are added for the map only. Never amber (urgent) or green (done). */
:root { --tc1: #22709F; --tc2: #9CC4E2; --tc3: #F2F1EE; --tc4: #A99BE6; --tc5: #E39AC0; }
.tc1 { background: var(--tc1); border-color: var(--tc1); color: var(--on-accent); }
.tc2 { background: var(--tc2); border-color: var(--tc2); color: var(--bg); }
.tc3 { background: var(--tc3); border-color: var(--tc3); color: var(--bg); }
.tc4 { background: var(--tc4); border-color: var(--tc4); color: var(--bg); }
.tc5 { background: var(--tc5); border-color: var(--tc5); color: var(--bg); }
.m-job.urgent { border: 2px solid var(--warm); }
.sw { display: inline-block; width: 16px; height: 16px; border-radius: var(--r-card); border: 1px solid transparent; flex: none; }
.ini.tc1, .ini.tc2, .ini.tc3, .ini.tc4, .ini.tc5 { border-radius: var(--r-ctl); }

/* ---------- Drawer (job and claim panels) ---------- */
/* the panel starts under the top bar and never covers it */
.drawer { position: fixed; top: var(--top); right: 0; bottom: 0; z-index: 60; width: 480px; max-width: 100%; display: flex; flex-direction: column; background: var(--raised); border-left: 1px solid var(--line-2); box-shadow: -24px 0 48px rgba(0, 0, 0, .3); transform: translateX(24px); opacity: 0; transition: transform .22s var(--ease), opacity .22s var(--ease); }
.drawer.open { transform: none; opacity: 1; }
.dr-h { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 24px; border-bottom: 1px solid var(--line); }
.dr-b { padding: 24px; overflow-y: auto; display: grid; gap: 24px; align-content: start; flex: 1; }
.dr-f { display: flex; gap: 8px; padding: 16px 24px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.steps li { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-top: 1px solid var(--line); font-size: var(--t4); line-height: 20px; color: var(--text-2); }
.steps li:first-child { border-top: 0; }
.steps li.cur { color: var(--text); font-weight: 600; }
.steps li.cur span:first-child { color: var(--accent-text); }
.checklist { display: grid; gap: 8px; }
.checklist label { display: flex; align-items: center; gap: 16px; min-height: 32px; cursor: pointer; }

/* ---------- Modal dialogs (slot picker, new estimate, confirm) ---------- */
.modal-wrap { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 16px; background: rgba(11, 17, 23, .76); }
.modal { width: min(680px, calc(100vw - 32px)); max-width: none; max-height: calc(100vh - 32px); overflow-y: auto; background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--r-card); box-shadow: 0 24px 64px rgba(0, 0, 0, .45); animation: in .18s var(--ease); }
.modal.narrow { width: min(480px, calc(100vw - 32px)); }
.md-h { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding: 24px 24px 16px; }
.md-b { padding: 0 24px 24px; display: grid; gap: 16px; }
.md-f { display: flex; gap: 8px; justify-content: flex-end; padding: 16px 24px; border-top: 1px solid var(--line); flex-wrap: wrap; }

/* ---------- Calls (booking) ---------- */
.step-k { display: block; font-size: var(--t4); line-height: 20px; color: var(--accent-text); font-weight: 600; margin-bottom: 0; }
.choices { display: grid; gap: 8px; margin-top: 16px; }
.choices.two { grid-template-columns: 1fr 1fr; }
.choices.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.choice { position: relative; display: flex; align-items: center; gap: 16px; padding: 16px; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--bg); cursor: pointer; transition: border-color .15s, background-color .15s; }
.choice:hover { border-color: var(--line-2); }
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice:has(input:checked) { border-color: var(--accent); background: rgba(34, 112, 159, .12); }
.choice:has(input:focus-visible) { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.choice .grow { flex: 1; min-width: 0; }
.choice.sm { padding: 8px 16px; }
.glance .warn-i { white-space: normal; }
.glance .up-list li { flex-wrap: wrap; gap: 8px; }
/* a finished booking step is one line: the step, its name, what was picked, and Change */
.step-line { display: flex; align-items: center; gap: 16px; padding: 8px 24px; min-height: 56px; }
.step-lines .step-line + .step-line { border-top: 1px solid var(--line); }
.step-line .step-k { flex: none; }
.step-line h2 { flex: none; }
.step-line .sl-v { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-2); }
.step-line .btn { flex: none; }
.slots { display: grid; grid-template-columns: 120px repeat(5, minmax(0, 1fr)); gap: 8px; margin-top: 16px; align-items: center; }
.slots .sh { font-size: var(--t4); line-height: 20px; color: var(--text-2); font-weight: 500; }
.slots .dh { text-align: center; }
.slot { position: relative; display: flex; align-items: center; justify-content: center; height: 40px; border: 1px solid var(--line); border-radius: var(--r-ctl); background: var(--bg); font-size: var(--t4); cursor: pointer; transition: border-color .15s, background-color .15s; }
.slot input { position: absolute; opacity: 0; pointer-events: none; }
.slot:hover { border-color: var(--line-2); }
.slot:has(input:checked) { background: var(--accent); border-color: var(--accent); color: #fff; }
.slot:has(input:focus-visible) { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.slot.full { color: var(--text-2); cursor: not-allowed; background: transparent; border-style: dashed; }
.slot.passed { border-color: transparent; background: var(--soft); }
/* the earliest open window (urgent jobs) or the current one (reschedule) carries a small tag */
.slot.marked { border-color: var(--accent-text); }
.slot-m { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); height: 20px; padding: 0 8px; border-radius: var(--r-ctl); background: var(--raised); border: 1px solid var(--accent-text); color: var(--accent-text); font-size: var(--t4); line-height: 18px; font-weight: 600; white-space: nowrap; }
.slot.full .slot-m { position: static; transform: none; margin-right: 8px; border-color: var(--line-2); color: var(--text-2); }
.slots { row-gap: 16px; }
.call-in { border-color: var(--accent); }
.call-in .h2 { margin: 4px 0; }
.sugg-box { margin-top: 16px; padding: 16px; border: 1px solid rgba(156, 196, 226, .3); border-radius: var(--r-card); background: rgba(34, 112, 159, .1); display: grid; gap: 8px; }

/* ---------- Estimates ---------- */
.est-list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 24px; }
.est-card { display: grid; gap: 8px; padding: 16px 24px; text-decoration: none; transition: border-color .15s; }
.est-card:hover { border-color: var(--line-2); }
.est-card[aria-current="true"] { border-color: var(--accent); }
.opts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.opt { display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; transition: border-color .2s, box-shadow .2s; }
/* the recommended option stands out: a light blue ring and "Our Pick for You" on its picture */
.opt.rec { border-color: var(--accent-text); box-shadow: 0 0 0 1px var(--accent-text); }
.opt.picked { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.opt-img-wrap { position: relative; }
.rec-pill { position: absolute; left: 16px; top: 16px; background: var(--accent-text); color: var(--bg); border: 0; font-weight: 600; }
.rec-pill .ic { stroke-width: 2.4; }
/* a locked option: the system is plain text in a dashed, quiet box (no menu), and the footer names who approved and when */
.ro-val { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 16px; border: 1px dashed var(--line-2); border-radius: var(--r-ctl); color: var(--text-2); line-height: 24px; }
.ro-val .ic { width: 16px; height: 16px; color: var(--text-2); }
.ro-val .ro-why { margin-left: auto; font-size: var(--t4); }
.opt-ok { display: flex; align-items: center; gap: 8px; color: var(--done); font-size: var(--t4); line-height: 20px; font-weight: 500; }
.opt-ok .ic { width: 16px; height: 16px; }
/* the chosen option after approval: full contrast, it just no longer takes clicks */
.btn.chosen[aria-disabled="true"] { opacity: 1; cursor: default; }
.opt-head { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 16px; align-items: center; }
.opt-thumb { width: 96px; height: 96px; object-fit: cover; border-radius: var(--r-card); }
.opt-img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0; }
.opt-b { display: grid; gap: 16px; padding: 24px; flex: 1; align-content: start; }
.opt-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.opt-b select { width: 100%; }
.lines { display: grid; }
.line { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 40px; padding: 8px 0; border-top: 1px solid var(--line); font-size: var(--t4); line-height: 20px; }
.line:first-child { border-top: 0; }
.line > :first-child { display: flex; align-items: center; gap: 16px; min-width: 0; }
.line > :last-child { flex: none; color: var(--text-2); }
.line.off > :first-child { color: var(--text-2); }
.line.total { font-weight: 600; border-top: 1px solid var(--line-2); }
.line.total > :last-child { color: var(--text); }
.line label { display: flex; align-items: center; gap: 16px; cursor: pointer; }
/* a line added on a draft: its amount, then Remove */
.line-end { display: flex; align-items: center; gap: 8px; flex: none; color: var(--text-2); }
.line-end .btn { margin-right: -8px; }
/* the two option buttons stack, so the longer one never runs into the card padding */
.opt-f { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 16px 24px 24px; }
.opt-f .btn { width: 100%; }
/* invoice lines: pricebook items, Qty, Amount, then Subtotal, GST and Total */
.tbl.il td { padding-top: 8px; padding-bottom: 8px; vertical-align: middle; }
.tbl.il th.r, .tbl.il td.r { text-align: right; }
.tbl.il .il-name { display: block; font-weight: 500; }
.tbl.il td.r { white-space: nowrap; color: var(--text-2); font-size: var(--t4); }
.tbl.il td.cov { color: var(--accent-text); }
.tbl.il tfoot th, .tbl.il tfoot td { padding-top: 8px; padding-bottom: 8px; border-top: 1px solid var(--line); border-bottom: 0; font-size: var(--t4); line-height: 20px; }
.tbl.il tfoot th { text-align: left; font-weight: 500; color: var(--text-2); white-space: nowrap; }
.tbl.il tfoot tr.tot th, .tbl.il tfoot tr.tot td { color: var(--text); font-weight: 600; border-top: 1px solid var(--line-2); font-size: var(--t3); line-height: 24px; }
.tbl.il tbody tr:last-child td { border-bottom: 0; }
/* the wrap up: two line rows, the amount under the item */
.il-rows { margin-top: 8px; }
.il-rows li { display: grid; padding: 8px 0; border-top: 1px solid var(--line); }
.il-rows li:first-child { border-top: 0; }
.il-top { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }
.il-rows .il-name { font-weight: 500; }
.il-rows .cov { color: var(--accent-text); }
.il-tot { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-2); display: grid; gap: 0; }
.il-tot > div { display: flex; justify-content: space-between; gap: 16px; font-size: var(--t4); line-height: 20px; color: var(--text-2); }
.il-tot > div.tot { color: var(--text); font-weight: 600; font-size: var(--t3); line-height: 24px; margin-top: 8px; }
input.qty { width: 96px; padding: 0 8px 0 16px; text-align: right; }
input:disabled { border-style: dashed; color: var(--text-2); cursor: not-allowed; }
.il-qty.locked .qty-v { color: var(--text-2); }
.crew-h { display: flex; align-items: center; min-height: 40px; }
/* a draft invoice has fixed column widths; a quantity's error sits on its own line under the row */
.tbl.il.edit { table-layout: fixed; }
.tbl.il tr.has-err td { border-bottom: 0; }
.tbl.il tr.qerr-row td { padding-top: 0; padding-bottom: 8px; }
/* the wrap up's lines: the item and its amount, then the quantity with steppers */
.il-qty { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.stepper { display: inline-flex; align-items: center; gap: 8px; }
.qty-v { min-width: 40px; text-align: center; font-weight: 600; }
.il-qty .btn.ghost { margin-left: auto; }
/* readings: one group per unit, each field with its unit; the CO reading sits under the carbon monoxide test */
.rd-unit { display: grid; gap: 16px; padding: 16px; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--bg); }
.rd-leg { float: left; width: 100%; padding: 0; }
.rd-mode { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.ck-sub { margin: 0 0 8px 32px; max-width: 240px; }
.add-line { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.add-line .grow { flex: 1 1 240px; }
.opt-desc { min-height: 48px; }
/* Days Since Sent: the days on the left, Follow Up on the right, so the buttons line up */
.since { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.est-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 24px; border-bottom: 1px solid var(--line); }

/* customer view (full screen) */
.overlay { position: fixed; inset: 0; z-index: 70; overflow-y: auto; background: var(--bg); opacity: 0; transition: opacity .22s var(--ease); }
.overlay.open { opacity: 1; }
.ov-top { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 64px; padding: 0 32px; border-bottom: 1px solid var(--line); background: rgba(11, 17, 23, .92); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.ov-top img { height: 24px; width: auto; }
.ov-b { max-width: 1160px; margin: 0 auto; padding: 48px 32px 64px; }
.ov-b.narrow { max-width: 800px; }
.ov-b .opts { margin-top: 32px; }
.cv-list { display: grid; gap: 8px; }
.cv-list li { padding-left: 16px; border-left: 2px solid var(--line-2); }
.approve { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: end; margin-top: 32px; padding: 24px; }

/* ---------- Kanban (rebates and warranty) ---------- */
.kanban { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; padding: 0 24px 24px; }
.kcol { display: grid; gap: 8px; align-content: start; min-width: 0; }
.kcol-h { display: flex; justify-content: space-between; align-items: center; height: 40px; padding: 0 16px; border-radius: var(--r-ctl); background: var(--bg); border: 1px solid var(--line); font-size: var(--t4); font-weight: 600; }
.kcol-h span { color: var(--text-2); font-weight: 500; }
.kcard { display: grid; gap: 8px; padding: 16px; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); animation: in .2s var(--ease); }
.kcard.cur { border-color: var(--accent); }
.kc-open { display: grid; text-decoration: none; color: inherit; border-radius: var(--r-ctl); }
.kc-open:hover .r-title { color: var(--accent-text); }
.k-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.k-foot .seg { margin-left: auto; }
.kcol .empty { padding: 16px; font-size: var(--t4); }

/* ---------- Inbox: the reply box stays at the bottom of the conversation ---------- */
/* the panel takes the screen's spare height (down to the page's bottom margin), and the thread takes the panel's */
.inbox { display: grid; grid-template-columns: 360px minmax(0, 1fr); height: calc(100vh - 224px); min-height: 560px; overflow: hidden; }
.ib-list { border-right: 1px solid var(--line); overflow-y: auto; }
.ib-filter { padding: 16px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--raised); z-index: 1; }
.ib-item { display: grid; gap: 0; padding: 16px 24px; border-bottom: 1px solid var(--line); text-decoration: none; transition: background-color .15s; }
.ib-item:hover { background: var(--soft); }
.ib-item[aria-current="true"] { background: var(--card); box-shadow: inset 2px 0 0 var(--accent-text); }
.ib-top { display: flex; justify-content: space-between; gap: 8px; }
.ib-item .pills { margin-top: 8px; }
.ib-top b { font-weight: 600; }
.ib-item.unread .ib-top b::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-text); margin-right: 8px; vertical-align: 2px; }
.ib-prev { font-size: var(--t4); line-height: 20px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ib-thread { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* the job the conversation is about, at the top */
.ib-job { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--line); background: var(--bg); }
.ib-job .grow { min-width: 0; }
.ib-h .grow { flex: 1; min-width: 0; }
.ib-name { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.ib-job-m { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.ib-pick { margin: auto; text-align: center; }
.ib-h { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--line); flex-wrap: wrap; flex: none; }
.msgs { flex: 1; min-height: 0; overflow-y: auto; display: grid; gap: 16px; align-content: start; padding: 24px; }
.msg { max-width: 72%; display: grid; gap: 8px; }
.msg .bub { padding: 16px; border-radius: var(--r-card); background: var(--card); border: 1px solid var(--line); }
.msg.me { justify-self: end; }
.msg.me .bub { background: var(--accent); border-color: var(--accent); color: #fff; }
.msg.bot .bub { background: rgba(34, 112, 159, .14); border-color: rgba(156, 196, 226, .3); }
.msg.bot > .meta { color: var(--accent-text); }
.msg.me .meta { text-align: right; }
.msg .bub img { width: 240px; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--r-card); margin-top: 8px; }
.sr-row { display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; }
.handoff { justify-self: center; text-align: center; font-size: var(--t4); line-height: 20px; color: var(--accent-text); padding: 8px 16px; border: 1px solid rgba(156, 196, 226, .3); border-radius: var(--r-ctl); }
.composer { flex: none; padding: 16px 24px 24px; border-top: 1px solid var(--line); display: grid; gap: 16px; background: var(--raised); }
.composer textarea { width: 100%; min-height: 72px; }
.composer-f { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }

/* ---------- Marketing ---------- */
.casl { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px; align-items: center; justify-items: start; padding: 24px; margin-bottom: 24px; border-color: rgba(156, 196, 226, .3); }
.email { border: 1px solid var(--line-2); border-radius: var(--r-card); background: var(--bg); overflow: hidden; }
.email-top { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-bottom: 1px solid var(--line); }
.email-top img { height: 20px; width: auto; }
.email-img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0; }
.email-b { display: grid; gap: 16px; padding: 24px; }
.email-f { padding: 16px 24px; border-top: 1px solid var(--line); }
.mail-btn { justify-self: start; }

/* ---------- Reports: every bar opens the matching jobs ---------- */
.bars { display: grid; gap: 8px; }
.bar-row { display: grid; grid-template-columns: 168px minmax(0, 1fr) 80px; gap: 16px; align-items: center; width: calc(100% + 16px); height: 32px; padding: 0 8px; margin: 0 -8px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--text); font: 400 var(--t3)/24px var(--font); text-align: left; cursor: pointer; }
.bar-row:hover { background: var(--soft); }
.bar-row:hover .bar i { background: var(--accent-text); }
.bar-row > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar { height: 16px; background: var(--soft); }
.bar i { display: block; height: 100%; background: var(--accent); transition: width .4s var(--ease), background-color .15s; }
.bar-row .r { text-align: right; font-weight: 600; }
/* Reports: each technician against the period before; every number opens its jobs */
.rep-t td { padding-top: 8px; padding-bottom: 8px; }
.rep-t .lead { white-space: nowrap; }
.rep-t .ini { width: 32px; height: 32px; margin-right: 8px; vertical-align: middle; }
.cmp { display: inline-grid; justify-items: start; gap: 0; min-width: 96px; padding: 4px 8px; margin: 0 -8px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.cmp:hover { background: var(--soft); }
.cmp b { font-size: var(--t2); line-height: 28px; font-weight: 600; }
.cmp b.zero { color: var(--text-2); font-weight: 500; }
.bar-row .r.zero { color: var(--text-2); font-weight: 500; }
/* a card that fills its row (Estimate Results), so no empty half sits beside it */
.g2e > .span2 { grid-column: 1 / -1; }
.cmp .meta { white-space: nowrap; }
/* the On My Way choice: each time is a full width button with a line under it */
.ow-opts { display: grid; gap: 16px; }
.ow-opt { display: grid; gap: 8px; }

/* ---------- Technician app (Northline Tech) ---------- */
.tech-wrap { display: grid; grid-template-columns: minmax(0, 440px) minmax(0, 400px); gap: 48px; align-items: start; }
.tech { max-width: 480px; min-width: 0; }
.tech-side { position: sticky; top: calc(var(--top) + 40px); }
.m-grid, .m-time, .m-block { display: none; }
.tlist { display: grid; gap: 16px; }
.tcard { padding: 16px; }
.tcard.current { border-color: var(--accent); }
.tcard a { display: grid; gap: 0; text-decoration: none; }
.tcard-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; }
.tcard .tcard-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
/* a finished job is one row: the time, the title (it wraps to a second line rather than being cut) and Done */
.tcard.t-done { padding: 8px 16px; }
.tcard.t-done a { display: flex; align-items: center; gap: 16px; min-height: 32px; }
.t-done .t1 { flex: 1; min-width: 0; color: var(--text-2); font-weight: 500; line-height: 20px; }
.t-acts { position: sticky; bottom: 0; z-index: 5; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 16px 0; margin-top: 24px; background: var(--bg); border-top: 1px solid var(--line); }
.t-acts .meta { grid-column: 1 / -1; }
/* the phone job header: a 20 px title, one chip row, the time once, the customer's latest message, Call and Directions in one row */
.tj-title { font-size: var(--t2); line-height: 28px; letter-spacing: -.01em; }
.tj-chips { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: nowrap; overflow: hidden; }
.tj-time { margin-top: 8px; }
.tj-who { margin-top: 16px; }
.cmsg { display: grid; gap: 4px; margin-top: 16px; padding: 8px 16px; border-left: 2px solid var(--accent-text); border-radius: 0 var(--r-ctl) var(--r-ctl) 0; background: rgba(34, 112, 159, .1); }
.cmsg .meta { display: flex; justify-content: space-between; gap: 16px; }
.t-quick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 16px 0 0; }
.t-quick .btn { width: 100%; }
.sig { display: block; width: 100%; height: 160px; border: 1px dashed var(--line-2); border-radius: var(--r-card); background: var(--bg); touch-action: none; cursor: crosshair; }
.sig-wrap { position: relative; }
.sig-wrap .sig-hint { position: absolute; left: 16px; bottom: 16px; font-size: var(--t4); color: var(--text-2); pointer-events: none; }
.read-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.m-list a { display: grid; gap: 0; padding: 16px; border-bottom: 1px solid var(--line); text-decoration: none; }
.m-list li:last-child a { border-bottom: 0; }
.m-row-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; }
.m-row-top .r-title { min-width: 0; }
.m-row-top .ic.mark { width: 16px; height: 16px; color: var(--warm); vertical-align: -3px; margin-right: 8px; }
.more-list a { display: flex; align-items: center; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--line); text-decoration: none; font-weight: 500; }
.more-list a:last-child { border-bottom: 0; }
.more-list .ic { color: var(--accent-text); }
.more-list .grow { flex: 1; min-width: 0; display: grid; }
.more-list .ic:last-child { color: var(--text-2); }
/* the outdoor air: one field, as wide as a reading */
.rd-out input { max-width: calc(50% - 8px); }
/* a reading's example is its placeholder, a bare number: an empty field has a dashed edge and a fainter number, so an example
   never looks like a reading already taken */
.rd-unit input:placeholder-shown, .rd-out input:placeholder-shown, .ck-sub input:placeholder-shown { border-style: dashed; }
.rd-unit input::placeholder, .rd-out input::placeholder, .ck-sub input::placeholder { color: rgba(169, 179, 187, .6); }
.rd-unit .warn { margin-top: -8px; }
.rd-unit .field > .warn { margin-top: 0; }
/* a part under the maker's warranty: the end date, who pays, and Start Warranty Claim */
.warr-box { display: grid; gap: 8px; justify-items: start; margin-top: 8px; padding: 8px 16px; border-left: 2px solid var(--accent-text); border-radius: 0 var(--r-ctl) var(--r-ctl) 0; background: rgba(34, 112, 159, .1); }
.tbl .warr-row td { padding-top: 0; }
/* a job of another day (or a closed one): the bottom bar is one line of words */
.t-acts.one { grid-template-columns: minmax(0, 1fr); }
.tj-cust { color: var(--accent-text); text-decoration: none; }
.tj-cust:hover { text-decoration: underline; }
.tc-home { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.m-list .m-li { display: grid; gap: 0; padding: 16px; border-bottom: 1px solid var(--line); }
.m-list li:last-child .m-li { border-bottom: 0; }
.panel > .m-list + .m-list { border-top: 1px solid var(--line); }
/* Truck Stock: one line per part, the count on the right; Out in amber with the word, Low quiet */
.stock-list li { display: flex; align-items: center; gap: 16px; min-height: 48px; padding: 8px 0; border-top: 1px solid var(--line); }
.stock-list li:first-child { border-top: 0; }
.stock-list .sk-name { flex: 1; min-width: 0; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stock-list .sk-st { flex: none; }
.stock-list .sk-n { flex: none; min-width: 48px; text-align: right; font-weight: 600; }
.stock-list li.out .sk-n { color: var(--warm); }
.stock-list li.low .sk-n { color: var(--text-2); }
/* the timesheet: clocked in or out, and since when */
.ts-now { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

/* menu popover */
.menu-wrap { position: relative; }
.menu { position: absolute; right: 0; top: 48px; z-index: 20; min-width: 240px; display: grid; padding: 8px; background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-card); box-shadow: 0 16px 40px rgba(0, 0, 0, .35); animation: in .15s var(--ease); }
.menu .btn { justify-content: flex-start; border-color: transparent; background: transparent; }
.menu .btn:hover { background: var(--soft); }

/* ---------- Phone tab bar (the sidebar on a phone) ---------- */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; display: none; grid-template-columns: repeat(5, minmax(0, 1fr)); height: calc(64px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); background: rgba(18, 26, 34, .96); border-top: 1px solid var(--line); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.tabbar a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; font-size: var(--t4); line-height: 20px; color: var(--text-2); text-decoration: none; font-weight: 500; }
.tabbar a[aria-current="page"] { color: var(--accent-text); }

/* ---------- Narrower computers: the menu becomes a rail ---------- */
body.rail { --side: 80px; }
body.rail .app { grid-template-columns: 80px minmax(0, 1fr); }
body.rail .side .nl, body.rail .nav-label, body.rail .brand-tag, body.rail .brand-logo, body.rail .nc, body.rail .runs { display: none; }
body.rail .brand-mark { display: block; }
body.rail .brand { padding: 0; justify-content: center; }
body.rail .nav a, body.rail .nav-a, body.rail .rail-btn { justify-content: center; padding: 0; }
body.rail .nav-label + a { margin-top: 24px; }
@media (max-width: 1240px) {
  :root { --side: 80px; }
  .app { grid-template-columns: 80px minmax(0, 1fr); }
  .side .nl, .nav-label, .brand-tag, .brand-logo, .nc, .runs, .rail-btn { display: none; }
  .brand-mark { display: block; }
  .brand { padding: 0; justify-content: center; }
  .nav a, .nav-a { justify-content: center; padding: 0; }
  .nav-label + a { margin-top: 24px; }
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .est-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1080px) {
  .g2, .g2e, .g31 { grid-template-columns: minmax(0, 1fr); }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts > div:nth-child(n) { border-left: 1px solid var(--line); border-top: 1px solid var(--line); }
  .facts > div:nth-child(2n + 1) { border-left: 0; }
  .facts > div:nth-child(-n + 2) { border-top: 0; }
  .opts { grid-template-columns: minmax(0, 1fr); }
  .opt-desc { min-height: 0; }
  .kanban { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .search { width: 280px; }
}

/* ---------- Phone: Northline Tech, the menu becomes a bottom tab bar. Tap targets 44 tall. ---------- */
@media (max-width: 760px) {
  .app { grid-template-columns: minmax(0, 1fr); grid-template-rows: 56px 1fr; }
  .side, .search, .office, .newjob { display: none !important; }
  .top { grid-column: 1; height: 56px; padding: 0 16px; gap: 8px; }
  .m-brand { white-space: nowrap; }
  .tag { padding: 0 8px; }
  .m-brand { display: inline-flex; }
  .main { grid-column: 1; padding: 24px 16px calc(112px + env(safe-area-inset-bottom)); }
  .tabbar { display: grid; }
  .btn, .btn.sm { height: 44px; }
  .btn.sm { font-size: var(--t4); }
  .icon-btn, .icon-btn.sm { width: 44px; }
  .sort, .w-day, .bar-row { height: 40px; }
  /* tap targets 44 px: tabs, switches, fields, checklist rows, choices, back links and the Reply link */
  .tab, .switch { height: 44px; }
  input[type="text"], input[type="search"], input[type="email"], input[type="tel"], input[type="number"], select { height: 44px; }
  .checklist label { min-height: 44px; }
  .choice.sm { min-height: 44px; }
  .back { padding: 12px 0; margin: -12px 0 -4px; }
  .cmsg .link, .warr-box .link, .tc-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px; margin: -12px -8px; }
  .tj-cust { display: inline-flex; align-items: center; min-height: 44px; margin: -12px 0; }
  .m-brand { min-height: 44px; }
  .tcard.t-done a { min-height: 48px; }
  .tcard.t-done { padding: 0 16px; }
  .ro-val { min-height: 44px; }
  .m-job { display: inline-grid; place-items: center; height: 24px; min-width: 24px; padding: 0 4px; line-height: 20px; }
  .toasts { left: 0; right: 0; top: 56px; padding: 0 8px; }
  .toast { width: 100%; max-width: none; height: auto; min-height: 52px; padding: 4px 0 4px 16px; }
  .toast-t { font-size: var(--t4); line-height: 20px; white-space: normal; }
  /* a job panel fills the phone: the toast shows at the bottom instead */
  body.dr-open .toasts { right: 0; top: auto; bottom: 8px; }
  body.dr-open .toast { border-top: 1px solid var(--accent); border-radius: var(--r-card); }
  /* the job screen: once you scroll, the title moves into the top bar and the tabs stick under it */
  .mb-job { display: none; min-width: 0; flex: 1; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body.tj-compact .m-brand .mb-app { display: none; }
  body.tj-compact .mb-job { display: block; }
  body.tj-compact .top .tag, body.tj-compact .top-sp { display: none; }
  .tj-tabs { position: sticky; top: 56px; z-index: 6; background: var(--bg); }
  .tj-tabs .tabs { margin-bottom: 0; }
  .tj-tabs + [role="tabpanel"] { margin-top: 16px; }
  .head { align-items: flex-start; flex-direction: column; gap: 16px; }
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .kpi { padding: 16px; }
  .panel-h { padding: 16px 16px 8px; }
  .panel-h .meta { text-align: left; flex-basis: 100%; }
  .panel-b { padding: 0 16px 16px; }
  .panel-b.pt { padding-top: 16px; }
  .panel .tabs { padding: 0 16px; }
  .sec-h { padding: 16px; }
  .toolbar { padding: 16px; }
  .toolbar input[type="search"] { width: 100%; }
  .toolbar select { flex: 1 1 40%; }
  .tb-f { flex: 1 1 100%; margin-right: 0; }
  .tb-f label { min-width: 56px; }
  .facts > div:nth-child(n) { padding: 16px; }
  .form-grid, .choices.two, .choices.three, .read-grid { grid-template-columns: minmax(0, 1fr); }
  /* readings are short numbers: two to a row. Each label takes two lines' room, its words at the foot, so the inputs stay
     level; a check line under one field never moves the field beside it */
  .rd-unit .read-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rd-unit .read-grid .field > label { min-height: 40px; display: flex; align-items: flex-end; }
  .slots { grid-template-columns: 72px repeat(5, minmax(0, 1fr)); gap: 16px 8px; }
  .slot-m { padding: 0 4px; }
  .slot { height: 44px; }
  .kanban { grid-template-columns: minmax(0, 1fr); padding: 0 16px 16px; }
  .inbox { grid-template-columns: minmax(0, 1fr); height: auto; min-height: 0; overflow: visible; }
  /* an open conversation fills the screen down to the page's bottom margin: the thread takes the spare height and the reply
     box sits at the bottom */
  .inbox.has-thread { min-height: calc(100vh - 192px - env(safe-area-inset-bottom)); min-height: calc(100dvh - 192px - env(safe-area-inset-bottom)); }
  .ib-list { border-right: 0; border-bottom: 1px solid var(--line); overflow: visible; }
  .inbox.has-thread .ib-list { display: none; }
  .inbox:not(.has-thread) .ib-thread { display: none; }
  .msgs { overflow: visible; }
  .composer { position: sticky; bottom: calc(64px + env(safe-area-inset-bottom)); padding: 16px; border-radius: 0 0 var(--r-card) var(--r-card); }
  .msg { max-width: 88%; }
  .msg .bub img { width: 160px; }
  .casl { grid-template-columns: minmax(0, 1fr); }
  .bar-row { grid-template-columns: 112px minmax(0, 1fr) 64px; gap: 8px; }
  .photos.four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tech { max-width: none; }
  .tech-wrap { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .d-only { display: none !important; }
  .m-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  .m-block { display: block; margin-bottom: 24px; }
  .slot-w { display: none; }
  .map-wrap { grid-template-columns: minmax(0, 1fr); }
  .map-main { border-right: 0; border-bottom: 1px solid var(--line); }
  .map-tools { padding: 16px; }
  .map-note { padding: 16px; }
  .ml-stop { min-height: 44px; }
  .map { touch-action: pan-y; }
  .m-time { display: inline; }
  .rows > li { flex-direction: column; align-items: stretch; gap: 8px; }
  .rows .end { justify-content: flex-start; }
  .est-list { display: flex; overflow-x: auto; gap: 8px; scroll-snap-type: x mandatory; scrollbar-width: none; }
  .est-list::-webkit-scrollbar { display: none; }
  .est-card { flex: 0 0 240px; scroll-snap-align: start; }
  .ib-h, .msgs { padding: 16px; }
  .ib-job { padding: 16px; align-items: flex-start; }
  .ib-job-m .st { flex-wrap: wrap; row-gap: 0; }
  .ib-h { gap: 8px; }
  .composer { gap: 8px; }
  .composer-f { flex-wrap: nowrap; }
  .ib-item { padding: 16px; }
  .t-acts { bottom: calc(64px + env(safe-area-inset-bottom)); }
  /* inside a job the tab bar steps aside, so the job gets the room */
  body.in-job .tabbar { display: none; }
  body.in-job .t-acts { bottom: 0; padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
  body.in-job .main { padding-bottom: 32px; }
  .m-only { display: inline-flex !important; }
  .wide-only { display: none; }
  .ov-top { padding: 0 16px; }
  .ov-b { padding: 32px 16px 64px; }
  .approve { grid-template-columns: minmax(0, 1fr); }
  .drawer { width: 100%; top: 56px; }
  .date-nav h2 { min-width: 0; flex: 1; font-size: var(--t3); line-height: 24px; }
  .date-nav { width: 100%; }
  .slot-nav p { min-width: 0; flex: 1; }
  .modal-wrap { padding: 8px; align-items: end; }
  .modal, .modal.narrow { width: calc(100vw - 16px); max-height: calc(100vh - 16px); }
  .tabs { gap: 0 16px; flex-wrap: wrap; overflow: visible; }
  .tab .tn { display: none; }
  .facts { grid-template-columns: minmax(0, 1fr); }
  .facts > div:nth-child(n) { border-left: 0; border-top: 1px solid var(--line); }
  .facts > div:first-child { border-top: 0; }
  .md-h { padding: 16px; }
  .md-b { padding: 0 16px 16px; }
  .md-f { padding: 16px; }
  .md-f .btn { flex: 1; }
  .success.slim { padding: 16px; }

  /* tables become stacked rows */
  .tbl.stack-sm thead { display: none; }
  .tbl.stack-sm, .tbl.stack-sm tbody, .tbl.stack-sm tr, .tbl.stack-sm td { display: block; width: 100%; }
  .tbl.stack-sm tr { padding: 16px; border-bottom: 1px solid var(--line); }
  .tbl.stack-sm tbody tr:last-child { border-bottom: 0; }
  .tbl.stack-sm td, .tbl.one.stack-sm td { padding: 0; border: 0; height: auto; white-space: normal; }
  .tbl.stack-sm td + td { margin-top: 8px; }
  .tbl.stack-sm td:first-child, .tbl.stack-sm td:last-child { padding: 0; }
  .tbl.stack-sm .hide-sm { display: none; }
  .tbl.stack-sm td.r { text-align: left; }
  .tbl.stack-sm .r-cell { justify-items: start; }
  .tbl.fixed, .tbl.one { table-layout: auto; }
  .tbl.stack-sm td.act { margin-top: 16px; }
  .tbl.stack-sm td.lead { font-weight: 600; }

  /* the board becomes a list per technician */
  .b-head, .b-lines { display: none; }
  .b-legend { flex-direction: column; align-items: flex-start; padding: 16px; }
  .b-row { display: block; height: auto; padding: 16px; }
  .b-row .b-name { border-right: 0; padding: 0 0 8px; }
  .b-track { display: grid; gap: 8px; }
  .blk { position: static; width: auto !important; height: 44px; }
  .hh-list { display: flex; flex-wrap: wrap; gap: 8px; }
  .no-room { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
