:root {
  /* ---- Modernist reskin (design handoff, Aug 2026) ----
     Two token layers live here on purpose:
       1. --aj-*  : the design system's names. Use these for any NEW work.
       2. legacy  : --bg/--surface/--accent/… the ~300 names the existing
                    component CSS already references. Re-pointed at the new
                    palette so the whole app reskins without touching those
                    rules. Both layers are declared in BOTH themes (a custom
                    property that references var() resolves on the element
                    where it's DECLARED, so the light block must restate them
                    rather than relying on inheritance).
     Dark stays the default — the crew's app shouldn't flip on them mid-shift.
     Light lives in body.light-theme further down. */

  /* -- design tokens (dark) -- */
  --aj-bg: #0E1822;
  --aj-surface: #16222E;
  --aj-surface-2: #1E2C3A;
  --aj-chrome: #0A121B;
  --aj-text: #F2F5F8;
  --aj-text-soft: #A7B7C6;
  --aj-muted: #6E8090;
  --aj-text-on-chrome: #F2F5F8;
  --aj-text-on-chrome-soft: #96A9BB;
  --aj-line: rgba(255,255,255,.14);
  --aj-line-strong: #F2F5F8;
  --aj-accent: #4FA8DE;
  --aj-accent-hover: #6FB9E6;
  --aj-accent-strong: #7FC0E8;   /* accent as TEXT */
  --aj-accent-tint: #14344A;     /* chips, row hovers */
  --aj-accent-ink: #0A121B;      /* text on accent fills */
  --aj-ok: #46C47F;       --aj-ok-tint: #12301F;
  --aj-warn: #F0B93D;     --aj-warn-tint: #33270C;
  --aj-danger: #F0645A;   --aj-danger-tint: #3A1512;
  --aj-info: #7FC0E8;     --aj-info-tint: #14344A;
  --aj-purple: #B79AE8;   --aj-purple-tint: #241C3A;
  --aj-shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --aj-shadow-md: 0 6px 16px rgba(0,0,0,.5);
  --aj-shadow-lg: 0 16px 40px rgba(0,0,0,.6);

  /* -- legacy names, re-pointed (dark) -- */
  --bg: #0E1822;
  --surface: #16222E;
  --surface-2: #1E2C3A;
  --chrome: #0A121B;
  --text: #F2F5F8;
  --text-soft: #A7B7C6;
  --accent: #4FA8DE;
  --accent-hover: #6FB9E6;
  --muted: #6E8090;
  --muted-hover: #24384A;
  --line: rgba(255,255,255,0.14);
  --ok: #46C47F;
  --ok-bg: #12301F;
  --warn: #F0B93D;
  --warn-bg: #33270C;
  --danger: #F0645A;
  --danger-bg: #3A1512;
  --info: #7FC0E8;
  --info-bg: #14344A;
  --purple: #B79AE8;
  --purple-bg: #241C3A;
  --amber2: #F0A050;
  --amber2-bg: rgba(240,150,60,0.18);
  --radius: 8px;
  --aj-font: 'Manrope', system-ui, -apple-system, sans-serif;
  --font-display: var(--aj-font);
  --font-body: var(--aj-font);
  /* Was IBM Plex Mono — genuinely used everywhere as the small-label/
     metadata typeface (ticket IDs, section labels, timestamps, badges),
     which gave the whole app a "spreadsheet/terminal" feel rather than a
     warm one. Same font as everything else now; uppercase + letter-
     spacing + weight still creates the label/value visual distinction,
     just without a literal coding typeface doing it. Kept the variable
     name as-is rather than touch 20 individual CSS rules that reference it. */
  --font-mono: var(--aj-font);

  /* Formal 8pt spacing scale — for new/updated work going forward. Existing
     rules across ~250 CSS declarations weren't retroactively rewritten to
     use these (too much risk of regressions for too little practical gain,
     since most already land close to these values already) — but any new
     component should pull from this scale rather than picking an arbitrary
     number. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;

  /* Formal type scale, same rationale as spacing above. */
  --text-page-title: 30px;
  --text-card-title: 19px;
  --text-primary-data: 17px;
  --text-body: 15px;
  --text-label: 11px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
}

button { font-family: inherit; cursor: pointer; touch-action: manipulation; }
input, select, textarea { font-family: inherit; }

/* ---------- Top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 16px 24px;
  padding-top: 20px;
  background: var(--chrome);
  /* Deliberately NOT var(--text) — the topbar's dark chrome background
     never changes between light/dark mode, but --text does. Using the
     theme variable here meant button/tab text went dark-on-dark and
     disappeared the moment light mode was turned on. Fixed color, always
     matches what dark mode already correctly looked like. */
  color: #FFFFFF;
  border-bottom: 4px solid var(--accent);
  position: sticky;
  top: 0;
  z-index: 90;
}
/* Buttons have their own explicit color rule (needed so they adapt
   correctly everywhere else in the app), which normally overrides
   whatever they'd inherit from a parent — so fixing .topbar's own color
   above isn't enough on its own; this needs its own equally-specific
   override to actually reach button text specifically. Only .btn-secondary
   needed this — .btn-primary already correctly used --chrome for its text,
   which is identical in both themes, so it was never actually broken. */
.topbar .btn-secondary { color: #FFFFFF; }
/* Same bug, same fix, two more spots that had their own explicit color
   rule overriding the topbar's general fix above — tabs used --text-soft
   and the wordmark used --text, both theme-dependent, against a topbar
   background that never changes regardless of theme. Deliberately NOT
   touching .tab.active's color — that's a different, already-correct
   rule pairing dark text with the bright accent background specifically. */
.topbar .tab { color: rgba(255,255,255,0.75); }
.topbar .brand-name { color: #FFFFFF; }

/* Was previously flattened into one single row via display:contents,
   which is exactly why everything felt crowded — too many buttons and
   tabs competing for the same line. Now genuinely two rows: brand/refresh
   on top, tabs and actions below with space between them, giving each
   its own room instead of fighting for the same line. */
.topbar { flex-direction: column; align-items: stretch; gap: 12px; }
.topbar-row { display: flex; align-items: center; justify-content: center; gap: 16px; }
.topbar-menu {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.topbar-right { display: flex; align-items: center; gap: 20px; }
.topbar-actions { display: flex; align-items: center; gap: 10px; }

.burger-btn { display: none; }

/* ---------- Desktop-only single-row topbar ---------- */
/* Same detection approach as the job modal — min-width alone isn't
   reliable (an iPad Pro landscape is 1366px, genuinely close to some
   laptops), but touch devices always report pointer:coarse regardless of
   screen size, so combining both reliably means "real desktop." iPad and
   mobile keep the two-row layout untouched — it was deliberately split
   into two rows to avoid crowding on narrower screens, which still
   applies there. */
@media (min-width: 1400px) and (hover: hover) and (pointer: fine) {
  .topbar { flex-direction: row; }
  .topbar-row { flex-shrink: 0; }
  /* nowrap keeps the actions on the SAME line as the tabs instead of dropping
     to a crowded second row; tabs fill the middle and can wrap internally if
     space gets tight, and the actions stay pinned right — so the bar uses the
     full width edge to edge. */
  .topbar-menu { flex: 1; flex-wrap: nowrap; min-width: 0; }
  .tabs { min-width: 0; flex-wrap: wrap; }
  .topbar-actions { flex-wrap: wrap; justify-content: flex-end; }
}

.brand {
  display: flex; align-items: center; gap: 12px;
  background: none; border: none; padding: 4px; margin: -4px; border-radius: var(--radius); cursor: pointer;
}
.brand:hover { background: rgba(255,255,255,0.08); }

.brand-mark {
  font-family: var(--font-display);
  font-weight: 800;
  background: var(--accent);
  color: var(--chrome);
  padding: 9px 14px;
  border-radius: var(--radius);
  letter-spacing: .5px;
  font-size: 19px;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name { font-family: var(--font-display); font-weight: 800; letter-spacing: 1px; font-size: 20px; color: var(--text); }
.brand-sub { font-family: var(--font-mono); font-size: 12px; letter-spacing: 3px; color: var(--accent); }

.tabs { display: flex; gap: 4px; flex: 1; margin-left: 12px; }
.tab {
  background: transparent;
  border: none;
  color: var(--text-soft);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: .5px;
  padding: 10px 16px;
  border-radius: var(--radius);
}
.tab:hover { background: rgba(255,255,255,0.08); color: #fff; }
.tab.active { background: var(--accent); color: var(--chrome); }

.btn-primary {
  background: var(--accent);
  color: var(--chrome);
  border: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .3px;
  padding: 10px 16px;
  border-radius: var(--radius);
}
.btn-primary:hover { background: var(--accent-hover); }

.btn-secondary {
  background: transparent;
  border: 1.5px solid var(--muted);
  color: var(--text);
  font-weight: 600;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: var(--radius);
}
.btn-secondary:hover { background: var(--muted-hover); border-color: var(--accent); }

.btn-danger {
  background: transparent;
  border: 1.5px solid var(--danger);
  color: var(--danger);
  font-weight: 600;
  font-size: 12px;
  padding: 6px 10px;
  border-radius: var(--radius);
}
.btn-danger:hover { background: var(--danger-bg); }

.user-area { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-left: 10px; }
.user-badge {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-soft);
  letter-spacing: .5px; text-transform: uppercase;
}

.login-wrap {
  min-height: calc(100vh - 200px);
  display: flex; align-items: center; justify-content: center;
}
.login-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 32px 30px; width: 100%; max-width: 340px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.login-card .field { margin-bottom: 14px; }
.login-error { color: var(--danger); font-size: 12.5px; margin-bottom: 10px; min-height: 16px; }

/* ---------- Main / views ---------- */
main { padding: 22px 24px 60px; }

.view-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 18px;
  flex-wrap: wrap;
  gap: 10px;
}
.view-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 23px;
  letter-spacing: .3px;
  color: var(--text);
}
.view-sub { font-family: var(--font-mono); font-size: 12px; color: var(--text-soft); }

.board-header {
  align-items: center;
}
.board-header-title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}
.board-header-status {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  row-gap: 4px;
}
.board-header-status span:empty { display: none; }
.maps-link-compact {
  background: none; border: none; padding: 0 0 0 2px; font-size: 12px; font-weight: 600;
}
.maps-link-compact:hover { text-decoration: underline; }

.filters { display: flex; gap: 8px; flex-wrap: wrap; }
.filters select, .filters input {
  border: 1.5px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  border-radius: var(--radius);
  padding: 7px 10px;
  font-size: 13px;
}

/* ---------- Board (kanban) ---------- */
.board {
  display: grid;
  zoom: 0.95;
  /* Widened from 220px so cards get real breathing room on desktop instead
     of being narrow and tall — now roughly 3-4 columns fit comfortably at
     once on a typical monitor, with the existing horizontal scroll (below)
     handling the rest, rather than cramming all 6 narrow columns into view
     simultaneously. */
  grid-template-columns: repeat(5, minmax(360px, 1fr));
  gap: 14px;
  overflow-x: auto;
}
.board-col {
  background: var(--surface-2);
  border: 1px dashed var(--line);
  border-radius: 10px;
  padding: 10px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
}
/* Caps how tall a single column can grow before it scrolls internally,
   rather than letting the whole page grow endlessly. Matters most on
   iPad portrait, where columns stack vertically — without this, a column
   with many jobs (increasingly likely now that "Call for Estimate" adds
   entries to New quickly) would force scrolling past all of them just to
   reach the next column underneath. Nothing is hidden — every job is
   still there, just reachable with a small scroll inside its own column
   instead of blocking access to the rest of the board. */
.col-cards {
  max-height: calc(100vh - 240px);
  overflow-y: auto;
  padding-right: 2px;
}
.board-col-header {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-soft);
  display: flex;
  justify-content: space-between;
  padding: 4px 4px 10px;
  border-bottom: 2px solid var(--accent);
  margin-bottom: 10px;
}
.board-col-count {
  background: var(--chrome);
  color: #FFFFFF; /* same bug as topbar/ticket-head — --chrome never changes with theme, var(--text) did */
  border-radius: 20px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
}

.ticket-card { cursor: grab; }
.ticket-card.dragging { opacity: 0.4; cursor: grabbing; }
.board-col.drag-over { border-color: var(--accent); border-style: solid; background: rgba(79, 168, 222, 0.08); }

/* ---------- Reference tab — bumped up from the base sizes, per feedback
   that pricing/disposal guide/SOPs read too small at the default scale ---------- */
.ref-large-text .section-label { font-size: 13px; }
.ref-large-text table.data-table th { font-size: 12px; }
.ref-large-text table.data-table td { font-size: 15px; padding: 12px 14px; }
.ref-large-text .checklist-card { font-size: 15px; }
.ref-large-text .team-card { font-size: 15px; padding: 16px 18px; }
.ref-large-text .repeat-banner { font-size: 14px; }
.ref-large-text .view-sub { font-size: 13px; }
.customers-large-text table.data-table th { font-size: 12px; }
.customers-large-text table.data-table td { font-size: 15px; padding: 12px 14px; }

/* ---------- My Day — significantly larger text throughout, per explicit
   feedback that the field crew reads this quickly on mobile devices,
   often outdoors, and the default scale was too small to read easily. ---------- */
.myday-large-text .section-label { font-size: 22px; font-weight: 800; letter-spacing: 0.5px; margin: 26px 0 12px; color: var(--text); }
.myday-large-text .view-sub { font-size: 16px; }
.myday-large-text .checklist-item { font-size: 18px; padding: 12px 0; }
.myday-large-text .ticket-name { font-size: 22px; }
.myday-large-text .ticket-meta { font-size: 17px; }
.myday-large-text .ticket-id { font-size: 15px; }
.myday-large-text .btn-primary, .myday-large-text .btn-secondary { font-size: 16px; padding: 12px 18px; }
.myday-large-text .cost-row { font-size: 15px; }
.myday-large-text .myday-notes-field { font-size: 16px; }
.myday-large-text .message-bubble-text { font-size: 16px; }
.myday-large-text label { font-size: 16px; }
.myday-large-text input, .myday-large-text textarea, .myday-large-text select { font-size: 16px; }

/* ---------- Calendar ---------- */
.calendar-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; font-size: 12.5px; color: var(--text-soft); }
.calendar-legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.shift-chip {
  display: inline-block; background: var(--info-bg); color: var(--info); border-radius: 6px;
  padding: 4px 8px; font-size: 12.5px; font-weight: 600;
}
.calendar-week { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; }
.calendar-day {
  flex: 1 1 0; min-width: 190px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px; min-height: 200px;
}
.calendar-day.calendar-today { border-color: var(--accent); border-width: 2px; }
.calendar-day-header {
  display: flex; justify-content: space-between; align-items: baseline;
  font-family: var(--font-mono); font-size: 13px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-soft); border-bottom: 1px solid var(--line);
  padding-bottom: 7px; margin-bottom: 9px;
}
.calendar-day.calendar-today .calendar-day-header { color: var(--accent); }
.calendar-day-date { font-weight: 600; }
.calendar-day-jobs { display: flex; flex-direction: column; gap: 8px; }
.calendar-job {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 6px; padding: 9px 11px; cursor: pointer; font-size: 14px;
}
.calendar-job:hover { border-color: var(--accent); }
.calendar-job-name { font-weight: 800; font-size: 15px; color: var(--text); }
.calendar-job-meta { color: var(--text-soft); font-size: 12.5px; margin-top: 3px; }
.calendar-job.status-new { border-left-color: var(--info); }
.calendar-job.status-scheduled { border-left-color: var(--warn); }
.calendar-job.status-in_progress { border-left-color: var(--purple); }
.calendar-job.status-paid { border-left-color: var(--ok); }
.calendar-job.status-invoiced { border-left-color: var(--amber2); }
.calendar-job.status-cancelled { border-left-color: var(--danger); opacity: 0.6; }

/* ---------- Estimator — shown directly to customers, so noticeably
   bolder/larger than the rest of the app on purpose ---------- */
.modal-large-text .field label { font-size: 13px; font-weight: 700; color: var(--text); }
.modal-large-text .field input,
.modal-large-text .field select,
.modal-large-text .field textarea { font-size: 17px; font-weight: 600; padding: 12px 13px; }
.modal-large-text .checklist-item { font-size: 15px; font-weight: 600; }
.modal-large-text .fs-label { font-size: 13px; font-weight: 700; }
.modal-large-text .fs-value { font-size: 22px; }
.modal-large-text .section-label { font-size: 13px; }
.modal-large-text .cost-row,
.modal-large-text .repeat-banner,
.modal-large-text .view-sub { font-size: 14px; }
/* The estimator specifically faces customers, so its labels/headers switch
   from the app's usual monospace "dispatch ticket" font to the normal
   friendly body font — mono reads like a receipt printer, not a quote. */
.estimator-body .field label,
.estimator-body .section-label { font-family: var(--font-body) !important; }
.estimate-line {
  display: flex; justify-content: space-between; gap: 12px;
  font-size: 17px; font-weight: 600; color: var(--text);
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.estimate-line:last-child { border-bottom: none; }
.estimate-line strong { font-family: var(--font-display); font-weight: 800; }
@media (min-width: 700px) {
  .estimator-body .form-grid { grid-template-columns: 1fr 1fr 1fr; }
}

/* ---------- Estimator load-size slider — adapted from the website's own
   pricing-page slider, same interaction pattern, our color scheme ---------- */
.load-card {
  background: var(--surface-2);
  border-radius: 12px;
  padding: 12px 16px 18px;
  margin-bottom: 4px;
}
.load-img-wrap {
  height: 280px; border-radius: 10px; overflow: hidden; margin-bottom: 12px; background: var(--chrome);
  display: flex; align-items: center; justify-content: center;
}
.load-img-wrap img { width: 100%; height: 100%; object-fit: contain; display: block; transition: opacity .2s; }
@media (max-width: 700px) { .load-img-wrap { height: 220px; } }
.load-name { color: var(--text); font-size: 22px; font-weight: 800; text-align: center; margin-bottom: 4px; }
.load-price { color: var(--accent); font-size: 26px; font-weight: 900; margin: 4px 0; font-family: var(--font-display); }
.load-desc { color: var(--text-soft); font-size: 13px; text-align: center; margin-bottom: 10px; line-height: 1.4; }
.load-tags { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.load-tag {
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 10px; font-size: 12px; color: var(--text-soft); font-weight: 600;
}

/* Add-on cards — replaced a grid of near-identical number boxes with a
   scannable list: plain-language label, the rate spelled out, a stepper
   instead of typing a number, and a highlighted border once it's active
   so it's obvious at a glance what's actually applying to this quote. */
.addon-grid { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; }
.addon-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--surface-2); border: 1.5px solid var(--line); border-radius: 10px;
  padding: 12px 14px; transition: border-color .15s, background .15s;
}
.addon-card.addon-active { border-color: var(--accent); background: rgba(79,168,222,.1); }
.addon-label { font-weight: 700; font-size: 15px; color: var(--text); }
.addon-rate { font-size: 12.5px; color: var(--text-soft); margin-top: 2px; }
.addon-stepper { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.addon-step {
  width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid var(--muted);
  background: var(--surface); color: var(--text); font-size: 20px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; cursor: pointer; line-height: 1;
}
.addon-step:hover { border-color: var(--accent); color: var(--accent); }
.addon-count { font-family: var(--font-display); font-weight: 800; font-size: 18px; min-width: 24px; text-align: center; }
.addon-toggle-btn {
  padding: 10px 18px; border-radius: 8px; border: 1.5px solid var(--muted);
  background: var(--surface); color: var(--text); font-weight: 700; font-size: 14px; cursor: pointer; flex-shrink: 0;
}
.addon-toggle-btn.active { background: var(--accent); border-color: var(--accent); color: var(--chrome); }

.range-wrap { padding: 14px 4px 18px; }
.range-wrap input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
  border-radius: 3px; outline: none; cursor: pointer;
  background: linear-gradient(to right, var(--accent) 0%, var(--surface-2) 0%);
}
.range-wrap input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--surface);
  box-shadow: 0 2px 8px rgba(79,168,222,.5); cursor: pointer; transition: transform .15s;
}
.range-wrap input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.15); }
.range-wrap input[type=range]::-moz-range-thumb {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--surface); cursor: pointer;
}
.range-marks { position: relative; height: 18px; margin-top: 8px; }
.range-mark {
  position: absolute; top: 0;
  font-size: 11px; font-weight: 600; color: var(--text-soft); text-align: center;
  white-space: nowrap; transition: color .2s;
}
.range-mark.active { color: var(--accent); font-weight: 800; }

/* ---------- Job detail modal redesign — badges, info card, accordions ---------- */
.job-badge-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.job-badge {
  font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 20px;
  border: 1.5px solid var(--muted); color: var(--text); background: var(--surface-2);
}
.info-card {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 16px;
}
.job-modal-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }

.customer-search-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 20; margin-top: 4px;
  background: var(--surface); border: 1.5px solid var(--accent); border-radius: var(--radius);
  max-height: 260px; overflow-y: auto; box-shadow: 0 10px 30px rgba(0,0,0,0.4);
}
.customer-search-result {
  display: flex; justify-content: space-between; align-items: center; width: 100%;
  padding: 10px 14px; background: none; border: none; border-bottom: 1px solid var(--line);
  text-align: left; cursor: pointer; color: var(--text);
}
.customer-search-result:last-child { border-bottom: none; }
.customer-search-result:hover { background: var(--muted-hover); }
.customer-search-name { font-weight: 700; font-size: 14px; }
.customer-search-meta { font-size: 12px; color: var(--text-soft); }
.customer-search-empty { padding: 14px; text-align: center; color: var(--text-soft); font-size: 13px; }
.progress-bar-track { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.progress-bar-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width .2s; }
.accordion-summary-row { display: flex; justify-content: space-between; align-items: center; }

.accordion-section { border: 1px solid var(--line); border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.accordion-header {
  width: 100%; display: flex; justify-content: space-between; align-items: center;
  background: var(--surface-2); border: none; padding: 14px 16px; cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 700; color: var(--text); text-align: left;
}
.accordion-header:hover { background: var(--muted-hover); }
.accordion-header-right { display: flex; align-items: center; gap: 10px; font-weight: 500; }
.accordion-chevron { display: inline-block; transition: transform .2s; color: var(--text-soft); }
.accordion-header.accordion-open .accordion-chevron { transform: rotate(180deg); }
.accordion-body { padding: 16px; background: var(--surface); }

/* Message thread — chat-bubble convention: outbound (sent) right-aligned
   and accented, inbound (received) left-aligned and neutral, matching any
   texting app so direction reads instantly without a legend. */
.message-thread { max-height: 320px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.message-bubble-row { display: flex; }
.message-bubble-row.outbound { justify-content: flex-end; }
.message-bubble-row.inbound { justify-content: flex-start; }
.message-bubble { max-width: 75%; padding: 8px 12px; border-radius: 14px; }
.message-bubble.outbound { background: var(--accent); color: var(--chrome); border-bottom-right-radius: 4px; }
.message-bubble.inbound { background: var(--surface-2); color: var(--text); border-bottom-left-radius: 4px; }
.message-bubble-text { font-size: 14px; line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
.message-bubble-time { font-size: 10.5px; opacity: 0.7; margin-top: 3px; }
.quick-reply-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.quick-reply-chip {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 12px; font-size: 12px; font-weight: 600; color: var(--text); cursor: pointer;
}
.quick-reply-chip:hover { border-color: var(--accent); color: var(--accent); }
/* Only used on the photo-request chip, and only when this specific job has
   no customer photo yet — a visual nudge, not a permanent style. */
.quick-reply-chip-highlight {
  background: var(--warn-bg); border-color: var(--warn); color: var(--warn);
}
.quick-reply-chip-highlight:hover { border-color: var(--warn); color: var(--warn); filter: brightness(1.1); }
.all-day-toggle {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 12px 14px; border: 1.5px solid var(--accent); border-radius: var(--radius);
  background: rgba(79, 168, 222, 0.08); font-size: 14px;
}
.all-day-toggle input { width: 18px; height: 18px; flex-shrink: 0; }
.message-reply-row { display: flex; gap: 8px; align-items: flex-end; }
.message-reply-row textarea {
  flex: 1; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text); font-size: 16px;
  font-family: inherit; resize: none;
}

/* Checklist sub-sections (At the Jobsite, Morning Start, etc.) — a lighter,
   more compact accordion style than the main sections above, since these
   live nested inside an already-styled checklist card and default open
   (the checklist itself stays the primary content, just collapsible per
   phase once that part's done). */
.checklist-subsection {
  margin-bottom: 4px;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}
.checklist-subsection-header {
  background: transparent; border: none; padding: 10px 2px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: 1.5px;
  text-transform: uppercase; color: var(--accent); border-bottom: 1px solid var(--line);
}
.checklist-subsection-header:hover { background: transparent; }
.checklist-subsection-header .accordion-header-right .view-sub { font-family: var(--font-mono); font-size: 11px; }
.checklist-subsection-body { padding: 4px 2px 8px; background: transparent; }

/* ---------- Job ticket card ---------- */
.ticket-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 12px;
  position: relative;
}
.ticket-card:hover { border-color: var(--accent); }
.ticket-card::before {
  content: '';
  position: absolute;
  left: -1px; top: 8px; bottom: 8px;
  width: 3px;
  background: var(--accent);
  border-radius: 2px;
}
.ticket-id {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  letter-spacing: .5px;
}
.ticket-name { font-weight: 800; font-size: 19px; margin: 5px 0 4px; color: var(--text); }
.ticket-meta { font-size: 15px; color: var(--text-soft); margin-bottom: 9px; }
.ticket-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.myday-notes-field {
  width: 100%; min-height: 44px; max-height: 90px; margin-top: 8px;
  padding: 8px 10px; font-size: 13px; font-family: inherit; resize: vertical;
  border: 1.5px solid var(--line); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text);
}
.myday-notes-field:focus { outline: none; border-color: var(--accent); }
.ticket-status-select {
  margin-top: 10px;
  width: 100%;
  padding: 9px 10px;
  border-radius: var(--radius);
  border: 1.5px solid var(--muted);
  background: var(--surface-2);
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.tag {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 5px;
  background: var(--surface-2);
  color: var(--text-soft);
}
.tag.source { background: var(--info-bg); color: var(--info); }
.tag.employee { background: var(--warn-bg); color: var(--warn); }

/* ---------- Modal (ticket detail) ---------- */
.modal-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(5,10,18,0.72);
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow-y: auto;
  z-index: 100;
}
.modal-backdrop.open { display: flex; }
.modal.ticket {
  background: var(--surface);
  width: 100%;
  max-width: 640px;
  border-radius: 14px;
  border: 1px solid var(--line);
  padding: 0;
  position: relative;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
/* The estimator and job detail modal are both shown/used directly on iPad —
   give them real presence on that screen size instead of a small popup
   with wasted space on both sides. ID beats the .modal.ticket class rule
   above regardless of source order. */
#estimateModal { max-width: 820px; }
#jobModal { max-width: 1280px; }

/* Booking-link phone script — sits beside the send modal on desktop/wide
   screens so the caller doesn't have to hold the script in their head
   while also filling in the phone number. Hidden below the breakpoint —
   there's no room next to the modal on tablet/phone, and the call is
   probably already over by the time this is used on mobile anyway. */
.booking-script-panel { display: none; }
@media (min-width: 1000px) {
  #bookingLinkModalBackdrop.open { justify-content: center; gap: 18px; }
  .booking-script-panel {
    display: block;
    max-width: 420px;
    max-height: calc(100vh - 80px);
    overflow-y: auto;
  }
}
.ticket-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px 20px;
  border-bottom: 2px solid var(--line);
  background: var(--chrome);
  /* Same bug, same fix as the topbar — var(--text) changes with the page
     theme, but --chrome (this header's background) never does, so in
     light mode this went dark-navy text on a dark-navy background. */
  color: #FFFFFF;
  border-radius: 14px 14px 0 0;
}
.ticket-head .ticket-id { color: var(--accent); font-size: 12px; font-weight: 700; }
.ticket-body { padding: 20px; }
.close-x {
  background: none; border: none; font-size: 22px; line-height: 1;
  color: #FFFFFF; /* all 3 usages sit within .ticket-head's dark chrome, which never changes with theme */
}
/* The 📝 Notes / 💬 Messages buttons live in .ticket-head's always-dark
   --chrome header, so like .close-x and .ticket-id they need fixed white text.
   The base .btn-secondary uses var(--text), which flips to dark navy in
   light-theme — rendering dark-on-dark and hiding the message count until
   hover. Keep the hover fill dark too (a translucent white wash, not the light
   --muted-hover) so the white text stays readable in BOTH themes. */
.ticket-head .btn-secondary { color: #FFFFFF; }
.ticket-head .btn-secondary:hover { background: rgba(255,255,255,0.14); border-color: var(--accent); color: #FFFFFF; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; }
.form-grid .full { grid-column: 1 / -1; }
.field label {
  display: block; font-size: 11px; font-family: var(--font-mono); font-weight: 600;
  letter-spacing: .5px; color: var(--text-soft); margin-bottom: 4px; text-transform: uppercase;
}
.field input, .field select, .field textarea {
  width: 100%; border: 1.5px solid var(--line); border-radius: var(--radius);
  padding: 9px 10px; font-size: 13.5px; background: var(--surface-2); color: var(--text);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent);
}
.field textarea { resize: vertical; min-height: 50px; }

.status-pill {
  font-family: var(--font-mono); font-size: 11px; padding: 3px 10px; font-weight: 700;
  border-radius: 20px; text-transform: uppercase; letter-spacing: .5px;
}
.status-new { background: var(--info-bg); color: var(--info); }
.status-scheduled { background: var(--warn-bg); color: var(--warn); }
.status-in_progress { background: var(--purple-bg); color: var(--purple); }
.status-invoiced { background: var(--amber2-bg); color: var(--amber2); }
.status-paid { background: var(--ok-bg); color: var(--ok); }
.status-cancelled { background: var(--danger-bg); color: var(--danger); }

.section-label {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: 1.5px;
  text-transform: uppercase; color: var(--text-soft); margin: 18px 0 8px;
  border-bottom: 1px solid var(--line); padding-bottom: 4px;
}

.cost-row {
  display: flex; align-items: center; gap: 8px; font-size: 13px;
  padding: 6px 0; border-bottom: 1px solid var(--line);
}
.cost-row .amt { font-family: var(--font-mono); font-weight: 700; margin-left: auto; }
.cost-add-row { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; align-items: center; }
.cost-add-row select, .cost-add-row input {
  border: 1.5px solid var(--line); border-radius: var(--radius); padding: 7px 8px;
  font-size: 13px; background: var(--surface-2); color: var(--text);
}
.cost-add-row input[type=number] { width: 90px; }

.financial-summary {
  display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; margin-top: 12px;
}
.fs-box { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; text-align: center; }
.fs-label { font-family: var(--font-mono); font-size: 10px; color: var(--text-soft); text-transform: uppercase; font-weight: 600; }
.fs-value { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin-top: 2px; color: var(--text); }
.fs-value.profit-pos { color: var(--ok); }
.fs-value.profit-neg { color: var(--danger); }

.photo-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 8px; }
.photo-grid { display: flex; flex-wrap: wrap; gap: 8px; min-height: 40px; }
/* ---------- My Day light theme — scoped override for outdoor/field use.
   Toggled per-person via localStorage; rest of the app (indoor/desk use)
   stays on the dark theme. Colors deepened vs. the dark palette's exact
   hues where needed for contrast against white/light backgrounds. ---------- */
body.light-theme {
  /* Modernist light palette (design handoff). Same two layers as :root. */
  --aj-bg: #F3F2F2;
  --aj-surface: #FFFFFF;
  --aj-surface-2: #E9E7E6;
  --aj-chrome: #10202F;
  --aj-text: #1B242E;
  --aj-text-soft: #5B6B7A;
  --aj-muted: #8595A5;
  --aj-line: #DAD7D5;
  --aj-line-strong: #1B242E;
  --aj-accent-hover: #2F8CC7;
  --aj-accent-strong: #1D6CA3;
  --aj-accent-tint: #E3F1FA;
  --aj-ok: #1E7D4F;       --aj-ok-tint: #E0F2E8;
  --aj-warn: #A86A00;     --aj-warn-tint: #FBF0DB;
  --aj-danger: #C2372A;   --aj-danger-tint: #FBE5E2;
  --aj-info: #1D6CA3;     --aj-info-tint: #E3F1FA;
  --aj-purple: #6D55B0;   --aj-purple-tint: #EDE8F9;
  --aj-shadow-sm: 0 1px 2px rgba(16,32,47,.08);
  --aj-shadow-md: 0 4px 12px rgba(16,32,47,.12);
  --aj-shadow-lg: 0 12px 32px rgba(16,32,47,.18);

  --bg: #F3F2F2;
  --surface: #FFFFFF;
  --surface-2: #E9E7E6;
  --chrome: #10202F;
  --text: #1B242E;
  --text-soft: #5B6B7A;
  /* --accent stays the bright brand blue — it's a button BACKGROUND with dark
     text on top; only colors used as text-on-light get the deepened variants. */
  --accent-hover: #2F8CC7;
  --muted: #8595A5;
  --muted-hover: #E3F1FA;
  --line: #DAD7D5;
  --ok: #1E7D4F;
  --ok-bg: #E0F2E8;
  --warn: #A86A00;
  --warn-bg: #FBF0DB;
  --danger: #C2372A;
  --danger-bg: #FBE5E2;
  --info: #1D6CA3;
  --info-bg: #E3F1FA;
  --purple: #6D55B0;
  --purple-bg: #EDE8F9;
  --amber2: #C87F1E;
  --amber2-bg: rgba(200,127,30,0.12);
  background: var(--bg);
  /* Same fix as before, now applied at the source instead of a nested
     wrapper: `color` is inherited as an ALREADY-COMPUTED value, not a live
     binding to the variable — redefining --text alone wouldn't be enough
     without also re-declaring color itself. Doing this directly on body
     now, rather than a descendant of it, actually sidesteps the whole bug
     class this used to require a workaround for. */
  color: var(--text);
}
body.light-theme .maps-link:hover { color: var(--info); border-color: var(--info); }
body.light-theme .checklist-item.checked { color: var(--text-soft); }
body.light-theme .checklist-time { color: var(--text-soft); }

.maps-links { display: flex; gap: 8px; flex-wrap: wrap; }
.myday-btn-large { font-size: 15px !important; padding: 13px 20px !important; font-weight: 700; }
.maps-link {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface-2); border: 1.5px solid var(--muted); border-radius: var(--radius);
  padding: 9px 14px; font-size: 13.5px; font-weight: 700; color: var(--text);
  text-decoration: none; white-space: nowrap;
}
.maps-link:hover { border-color: var(--accent); color: var(--accent); }

.photo-thumb { position: relative; width: 72px; height: 72px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-source-badge {
  position: absolute; bottom: 0; left: 0; right: 0;
  background: rgba(0,0,0,0.65); color: #fff; font-size: 8.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px; text-align: center; padding: 2px 0;
}
.photo-del {
  position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; line-height: 18px;
  text-align: center; padding: 0; font-size: 11px; border-radius: 50%;
  background: rgba(0,0,0,0.65); color: #fff; border: none;
}
.photo-upload-btn {
  display: inline-block; margin-top: 8px; cursor: pointer; text-align: center;
}
.photo-upload-btn input[type=file] { display: none; }

.modal-actions { display: flex; justify-content: space-between; padding: 14px 20px; border-top: 1px solid var(--line); }
.modal-actions .right { display: flex; gap: 8px; }

.repeat-banner {
  background: var(--warn-bg); color: var(--warn); border: 1px solid var(--warn);
  border-radius: var(--radius); padding: 8px 10px; font-size: 12.5px; font-weight: 700;
}
.customer-row { cursor: pointer; }

/* ---------- Accounting ---------- */
.stat-row { display: grid; grid-template-columns: repeat(4,1fr); gap: 14px; margin-bottom: 24px; }
.stat-row-5 { grid-template-columns: repeat(5,1fr); }
.stat-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 18px;
}
.stat-label { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-soft); font-weight: 600; }
.stat-value { font-family: var(--font-display); font-weight: 800; font-size: 27px; margin-top: 4px; color: var(--text); }

table.data-table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: 12px; overflow: hidden; }
table.data-table th {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  text-align: left; padding: 10px 12px; background: var(--chrome); color: #FFFFFF; /* same bug/fix as topbar/ticket-head */
}
table.data-table td { padding: 9px 12px; font-size: 13px; border-bottom: 1px solid var(--line); color: var(--text); }
table.data-table tr:last-child td { border-bottom: none; }
table.data-table tr:hover td { background: var(--surface-2); }

/* ---------- Checklists ---------- */
.checklist-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.checklist-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; }
.checklist-item { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--line); font-size: 14px; font-weight: 500; touch-action: manipulation; }
.checklist-time { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-soft); white-space: nowrap; }
.checklist-item input {
  width: 26px; height: 26px; accent-color: var(--accent); flex-shrink: 0;
  border: 1.5px solid var(--muted); border-radius: 5px; background: var(--surface);
}
.checklist-item.checked { color: var(--text-soft); text-decoration: line-through; }
.checklist-progress { font-family: var(--font-mono); font-size: 12px; color: var(--text-soft); margin-top: 14px; }
/* My Day is single-column card content (checklists, job cards) — unlike
   Board/Calendar, which genuinely benefit from the full window width,
   stretching a stacked card list to a wide monitor's full width would
   just leave cards looking sparse and oddly spread out. Capped and
   centered, independent of the main content area's own width. */
#mydayThemeScope { max-width: 820px; margin: 0 auto; }

/* Web/desktop: flow the 6 sections into 3 columns so it's not one long
   scroll. Each section stays intact as a block, never split mid-section. */
.checklist-columns {
  column-count: 3;
  column-gap: 28px;
}
/* .checklist-subsection base styling consolidated above, near the other
   accordion rules — this used to be a separate near-duplicate definition. */

/* Tablet/mobile: single column, unchanged from before — these are the
   devices actually used out in the field. */
@media (max-width: 900px) {
  .checklist-columns { column-count: 1; }
}

/* ---------- Team ---------- */
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.team-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
.team-field-row {
  margin-top: 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13px; color: var(--text-soft);
}
.team-field-row .edit-rate-btn, .team-field-row .edit-partner-btn { font-size: 11px; padding: 4px 10px; }
.team-inline-input {
  flex: 1; min-width: 100px; padding: 6px 8px; font-size: 13px;
  border: 1.5px solid var(--accent); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text);
}
.team-field-row .save-rate-btn, .team-field-row .save-partner-btn { font-size: 11px; padding: 4px 10px; }
.team-field-row .cancel-rate-btn, .team-field-row .cancel-partner-btn { font-size: 11px; padding: 4px 10px; }
.team-name { font-weight: 800; font-size: 15.5px; color: var(--text); }
.team-role { font-family: var(--font-mono); font-size: 11px; color: var(--text-soft); text-transform: uppercase; font-weight: 600; }

.empty-state {
  text-align: center; padding: 50px 20px; color: var(--text-soft);
  font-family: var(--font-mono); font-size: 13px;
}

/* ---------- Desktop-only job modal layout ---------- */
/* Combines a generous min-width with hover/pointer checks specifically to
   exclude iPad — an iPad Pro landscape (1366px) is wide enough that a
   width check alone isn't reliable, but touch devices always report
   pointer:coarse regardless of screen size, so this genuinely only
   matches mouse/trackpad devices. iPad and iPhone keep the existing
   layout completely untouched. */
@media (min-width: 1400px) and (hover: hover) and (pointer: fine) {
  #jobModal { max-width: 1600px; }
  .job-modal-columns { grid-template-columns: 1fr 1.6fr; }
  .job-modal-col-right { columns: 2; column-gap: 20px; }
  .job-modal-col-right .accordion-section, .job-modal-col-right .checklist-progress, .job-modal-col-right .checklist-card {
    break-inside: avoid;
  }
}


@media (max-width: 1100px) {
  .board { grid-template-columns: repeat(3, minmax(240px,1fr)); }
}
@media (max-width: 860px) {
  .job-modal-columns { grid-template-columns: 1fr; }

  .topbar { flex-wrap: wrap; padding: 10px 16px; padding-top: calc(10px + env(safe-area-inset-top)); gap: 0; }

  .topbar-row {
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; width: 100%;
  }
  .topbar-row .burger-btn { justify-self: start; }
  .topbar-row .brand { justify-self: center; }
  .topbar-row #refreshBtn { justify-self: end; }
  .burger-btn {
    display: flex; flex-direction: column; justify-content: center; gap: 6px;
    width: 48px; height: 48px; background: none; border: none; cursor: pointer; padding: 10px;
    border-radius: var(--radius);
  }
  .burger-btn:hover { background: rgba(255,255,255,0.08); }
  .burger-btn span { display: block; height: 3px; width: 100%; background: #fff; border-radius: 2px; }

  .topbar-menu {
    display: none; width: 100%; flex-direction: column; gap: 4px;
    padding-top: 14px; margin-top: 12px; border-top: 1px solid rgba(255,255,255,0.15);
  }
  .topbar-menu.open { display: flex; }
  .topbar-right { display: contents; } /* wrapper disappears on mobile — its children stack directly in topbar-menu's column flow, same as before this wrapper existed */

  .tabs { flex-direction: column; width: 100%; margin-left: 0; gap: 2px; }
  .tab { width: 100%; text-align: left; padding: 12px 14px; }

  .topbar-actions { display: flex; flex-direction: column; gap: 8px; width: 100%; margin: 10px 0; }
  .topbar-actions button { width: 100%; }

  .user-area { width: 100%; flex-direction: row; justify-content: space-between; margin-left: 0; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.1); }

  .board { grid-template-columns: 1fr; overflow-x: visible; }
  .form-grid { grid-template-columns: 1fr; }
  /* The info card's fields are short (a phone number, a date, a price) —
     iPad portrait (768-820px) has plenty of room for 2 columns of these.
     The blanket 1-column rule above was written for longer/more complex
     forms and was silently collapsing this too, which is why the "2-column
     info card" never actually showed as 2 columns on the actual device. */
  .info-card .form-grid { grid-template-columns: 1fr 1fr; }
  .stat-row { grid-template-columns: 1fr 1fr; }
  .checklist-grid { grid-template-columns: 1fr; }

  /* Calendar had no mobile handling at all — 7 day-columns just overflowed
     sideways with no way to know you could scroll. Stack vertically instead,
     same pattern as Board. */
  .calendar-week { flex-direction: column; overflow-x: visible; }
  .calendar-day { min-width: 0; width: 100%; min-height: auto; }
}

/* Genuinely narrow phone-width screens — the info card's 2 columns get too
   cramped below this, unlike on iPad where there's comfortably enough room. */
@media (max-width: 480px) {
  .info-card .form-grid { grid-template-columns: 1fr; }
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* iOS/iPadOS focus-zoom backstop. Safari auto-zooms into any focused form
   control smaller than 16px and — after you press home and return — leaves
   the app stuck zoomed in. The viewport lock in index.html covers standalone
   (home-screen) use, but iPadOS Safari can ignore that, so this forces every
   form control to 16px on iOS WebKit specifically, which Safari always honors.
   !important is required because many inputs set their font-size inline.
   The @supports (-webkit-touch-callout) query matches only iOS/iPadOS, so
   desktop/laptop layouts are untouched. Tested target: iPad mini 5. */
@supports (-webkit-touch-callout: none) {
  input, textarea, select { font-size: 16px !important; }
}

/* Compact item picker for the estimator — small icon tiles instead of full-
   width rows, so the whole catalogue fits without endless scrolling. Tap a
   tile to add one; the − badge (top-left, only when count>0) removes one. */
.item-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(94px, 1fr));
  gap: 9px;
  margin-bottom: 4px;
}
.item-tile {
  position: relative;
  background: var(--surface-2);
  border: 1.5px solid transparent;
  border-radius: 12px;
  padding: 12px 5px 9px;
  min-height: 92px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  cursor: pointer;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  transition: border-color .12s, background .12s, transform .08s;
}
.item-tile:hover { background: var(--muted-hover); }
.item-tile:active { transform: scale(.96); }
.item-tile.on { border-color: var(--accent); background: rgba(79,168,222,.14); }
.item-tile .ic { width: 44px; height: 44px; color: var(--text-soft); flex-shrink: 0; }
.item-tile.on .ic { color: var(--accent); }
.item-tile .lbl { font-size: 10.5px; line-height: 1.15; color: var(--text-soft); font-weight: 600; }
.item-tile.on .lbl { color: var(--text); }
.item-tile .cnt {
  position: absolute; top: -7px; right: -7px;
  min-width: 21px; height: 21px; padding: 0 5px;
  border-radius: 11px; background: var(--accent); color: #06263b;
  font-size: 12px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.item-tile .dec {
  position: absolute; top: -7px; left: -7px;
  width: 21px; height: 21px; border-radius: 11px;
  background: var(--danger); color: #fff; border: none;
  font-size: 16px; font-weight: 800; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}

/* Bigger slider for the estimator's bottom "Load Size & Total" card. */
.est-slider-big input[type=range] { height: 12px; border-radius: 6px; }
.est-slider-big input[type=range]::-webkit-slider-thumb { width: 36px; height: 36px; border-width: 4px; }
.est-slider-big input[type=range]::-moz-range-thumb { width: 36px; height: 36px; border-width: 4px; }
.est-slider-big .range-marks { height: 22px; margin-top: 12px; }
.est-slider-big .range-mark { font-size: 14px; }

/* Styled inputs for the estimator's free fields (custom discount + custom item
   price) so they match the app instead of looking like native browser inputs. */
.est-input {
  border: 1.5px solid var(--line); border-radius: var(--radius);
  padding: 9px 11px; font-size: 14px; background: var(--surface-2);
  color: var(--text); font-family: inherit;
}
.est-input::placeholder { color: var(--muted); }
.est-input:focus { outline: none; border-color: var(--accent); }

/* ---------- Modernist reskin refinements (design handoff, Aug 2026) ----------
   Phase 1.5 — CSS-only polish on top of the token swap. Appended as an
   override layer rather than edited into ~250 existing rules, so it's one
   block to review (or remove) as a unit. */

/* Elevation: cards float on shadows instead of relying on borders alone. */
.ticket-card, .stat-card, .checklist-card, .team-card, .load-card, .info-card {
  box-shadow: var(--aj-shadow-sm);
}
.modal { box-shadow: var(--aj-shadow-lg); }

/* Pill chips — badges/tags/chips go fully rounded per the design. */
.tag, .job-badge, .status-pill, .shift-chip, .quick-reply-chip, .user-badge {
  border-radius: 999px;
}

/* Field-use tap targets: 44px minimum everywhere, 52px for the primary
   action on crew screens (dev-notes item — CSS sizing only). */
.btn-primary, .btn-secondary, .btn-danger { min-height: 44px; }
.myday-btn-large { min-height: 52px !important; }
.tab { min-height: 40px; }
input, select, textarea { min-height: 40px; }
textarea { min-height: 72px; }

/* Uppercase labels: Manrope tracks a touch wider than Poppins did. */
.section-label, .stat-label, .view-sub, .ticket-id { letter-spacing: 0.08em; }

/* ---------- Crew bottom tab bar (design handoff) ---------- */
/* Only rendered meaningfully for field users on touch devices — the body
   class is set at login by role, the media query keeps it off real desktops. */
.crew-tabbar { display: none; }
/* Role-based, not device-based: a field login gets the crew UI everywhere —
   including a desktop browser — so what the owner previews on a Mac matches
   what the crew sees on the iPad. */
body.crew-tabs-on .crew-tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
    background: var(--chrome);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom); /* iPhone/iPad home bar */
    box-shadow: var(--aj-shadow-md);
  }
body.crew-tabs-on { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
.crew-tab {
    flex: 1; min-height: 64px; border: none; background: none;
    color: #FFFFFF; opacity: .65; font-family: inherit;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; font-size: 20px; position: relative;
  }
  .crew-tab span { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
  .crew-tab.active { opacity: 1; color: var(--accent); }
.crew-tab.active::after {
  content: ''; position: absolute; top: 0; left: 25%; right: 25%;
  height: 3px; border-radius: 0 0 3px 3px; background: var(--accent);
}

/* ---------- Top-bar icon cluster (design handoff) ---------- */
.action-cluster {
  display: flex; align-items: center; gap: 4px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px;
}
.action-cluster .icon-btn {
  width: 44px; min-width: 44px; padding: 0;
  border: none; background: transparent;
  font-size: 18px; line-height: 1; border-radius: 999px;
}
.action-cluster .icon-btn:hover { background: rgba(255,255,255,0.12); }
/* On the crew's stacked mobile menu the cluster spreads full-width so each
   icon keeps a generous glove-sized target. */
@media (pointer: coarse) {
  .topbar-actions .action-cluster { width: 100%; justify-content: space-around; }
}

/* ---------- Inbox two-pane (design handoff) ---------- */
.inbox-layout {
  display: grid; grid-template-columns: 400px 1fr;
  background: var(--bg);
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  min-height: calc(100vh - 220px);
}
.inbox-list { border-right: 1px solid var(--line); background: var(--surface); overflow-y: auto; }
.inbox-thread-row {
  display: flex; align-items: center; gap: 12px;
  padding: 16px; border-top: 1px solid var(--line); cursor: pointer;
}
.inbox-thread-row:hover { background: var(--aj-accent-tint); }
.inbox-thread-row.selected { background: var(--aj-accent-tint); box-shadow: inset 3px 0 0 var(--accent); }
.inbox-convo { display: flex; flex-direction: column; min-width: 0; }
.inbox-convo-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid var(--line); background: var(--surface);
}
.inbox-convo-scroll { flex: 1; overflow-y: auto; padding: 18px; max-height: 55vh; }
.inbox-composer {
  border-top: 1px solid var(--line); background: var(--surface);
  padding: 12px 16px 14px; display: flex; flex-direction: column; gap: 10px;
}
/* Design's bubble language: 14px radius with a 4px corner toward the sender,
   accent-filled outbound. Scoped to the inbox conversation pane. */
.inbox-convo .message-bubble { border-radius: 14px; font-size: 15px; max-width: 68%; }
.inbox-convo .message-bubble.inbound { border-bottom-left-radius: 4px; background: var(--surface); border: 1px solid var(--line); }
.inbox-convo .message-bubble.outbound { border-bottom-right-radius: 4px; background: var(--accent); color: var(--aj-accent-ink); }
.inbox-convo .message-bubble.outbound .message-bubble-time { color: var(--aj-accent-ink); opacity: .75; }
/* Back button only exists for the mobile stacked flow. */
.inbox-back { display: none; }
@media (max-width: 900px) {
  .inbox-layout { display: block; border: none; background: transparent; }
  .inbox-list { border-right: none; border: 1px solid var(--line); border-radius: 12px; }
  .inbox-layout.sel-open .inbox-list { display: none; }
  .inbox-layout:not(.sel-open) .inbox-convo { display: none; }
  .inbox-layout.sel-open .inbox-convo { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
  .inbox-back { display: inline-flex; }
  .inbox-convo-scroll { max-height: 46vh; }
}

/* ---------- Crew chrome header (design handoff) ---------- */
.crew-header { display: none; }
body.crew-tabs-on .crew-header {
    display: flex; align-items: center; gap: 12px;
    position: sticky; top: 0; z-index: 92;
    min-height: 56px; padding: 8px 16px;
    padding-top: calc(8px + env(safe-area-inset-top));
    background: var(--chrome); color: #FFFFFF;
    border-bottom: 2px solid var(--accent);
  }
/* The crew header REPLACES the desktop top bar — the ⋯ button brings the
   full bar back when theme/logout/extra actions are needed. */
body.crew-tabs-on .topbar { display: none; }
body.crew-tabs-on.show-full-topbar .topbar { display: flex; }
/* Pills render in the chrome header — hide the in-page fallback. */
body.crew-tabs-on #mydayClockPills { display: none; }
.crew-clock-pill {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 40px; padding: 0 14px; border-radius: 999px;
  font-family: inherit; font-size: 12px; letter-spacing: .04em; font-weight: 800;
  cursor: pointer;
}
.crew-clock-pill.in { background: var(--ok-bg); border: 1px solid var(--ok); color: var(--ok); }
/* Default (in-page) styling uses theme tokens so the text is readable on the
   page background in BOTH themes; the white-on-chrome variant below applies
   only inside the dark crew header. */
.crew-clock-pill.out { background: var(--surface-2); border: 1px dashed var(--muted); color: var(--text); }
.crew-header .crew-clock-pill.out { background: rgba(255,255,255,.1); border: 1px dashed rgba(255,255,255,.35); color: rgba(255,255,255,.8); }
.crew-clock-pill .dot { width: 8px; height: 8px; border-radius: 50%; }

/* ---------- Crew job page (design handoff: Job Detail iPad) ---------- */
/* The crew's job view is a full-screen page, not a floating dialog. */
body.crew-tabs-on .modal.crew-job {
    width: 100vw; max-width: 100vw;
    height: 100dvh; max-height: 100dvh;
    margin: 0; border-radius: 0; padding: 0;
    overflow-y: auto;
    background: var(--bg);
    padding-bottom: calc(76px + env(safe-area-inset-bottom)); /* clear the tab bar */
  }
.modal.crew-job { padding: 0; }

/* ---------- Login (design handoff) ---------- */
.login-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.login-field span { font-size: 12px; letter-spacing: .05em; font-weight: 800; }
.login-field input {
  min-height: 44px; border: 1px solid var(--muted); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: 15px; padding: 0 12px;
}
.login-field input:focus { outline: none; border-color: var(--accent); }
/* Crew variant: glove-sized fields on touch devices. */
@media (pointer: coarse) {
  .login-field input { min-height: 56px; font-size: 17px; }
  .login-card .btn-primary { min-height: 56px; font-size: 16px; }
}

/* ---------- Calendar (design handoff) ---------- */
.calendar-day {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; min-height: 440px;
  display: flex; flex-direction: column; box-shadow: var(--aj-shadow-sm);
}
.calendar-today { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--aj-shadow-sm); }
.calendar-day-header {
  display: flex; flex-direction: column; gap: 1px;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.calendar-day-header > span:first-child { font-size: 11px; letter-spacing: .06em; font-weight: 800; color: var(--text-soft); text-transform: uppercase; }
.calendar-day-date { font-size: 14px; font-weight: 800; }
.calendar-day-jobs { display: flex; flex-direction: column; gap: 6px; padding: 8px; }
/* Job chips: status tint background + 3px status-colored left border. */
.calendar-job {
  border-radius: 6px; padding: 7px 9px; cursor: pointer;
  border-left: 3px solid var(--muted); background: var(--surface-2);
}
.calendar-job-status { font-size: 9px; letter-spacing: .06em; font-weight: 800; margin-bottom: 1px; color: var(--text-soft); }
.calendar-job-name { font-size: 12px; font-weight: 700; }
.calendar-job.status-new        { background: var(--info-bg);   border-left-color: var(--info); }
.calendar-job.status-new .calendar-job-status { color: var(--info); }
/* Status colours are FIXED and owner-defined — the same six everywhere in the
   app (chips, board, calendar): new=blue, scheduled=dark brown, in progress=
   purple, invoiced=light brown, paid=green, cancelled=red. The redesign had
   swapped scheduled and in_progress here; do not "improve" this mapping. */
.calendar-job.status-scheduled  { background: var(--warn-bg);   border-left-color: var(--warn); }
.calendar-job.status-scheduled .calendar-job-status { color: var(--warn); }
.calendar-job.status-in_progress{ background: var(--purple-bg); border-left-color: var(--purple); }
.calendar-job.status-in_progress .calendar-job-status { color: var(--purple); }
.calendar-job.status-invoiced   { background: var(--amber2-bg); border-left-color: var(--amber2); }
.calendar-job.status-invoiced .calendar-job-status { color: var(--amber2); }
.calendar-job.status-paid       { background: var(--ok-bg);     border-left-color: var(--ok); }
.calendar-job.status-paid .calendar-job-status { color: var(--ok); }
.calendar-job.status-cancelled  { background: var(--danger-bg); border-left-color: var(--danger); opacity: .7; }
.calendar-job.status-cancelled .calendar-job-status { color: var(--danger); }

/* ---------- Day map (Leaflet) ---------- */
/* Leaflet hands its own panes z-index values from 400 up to 1000 — higher than
   the job modal's backdrop (100). Because this box is position:relative with
   z-index:auto it is NOT a stacking context, so those panes were competing at
   the top level and the map painted straight over any modal opened from it:
   tapping "Open job" left the tiles pasted across the form. Making this box a
   stacking context traps every Leaflet z-index inside it, so the whole map
   stacks as one element at z-index 0 and sits under the app's chrome. */
.aj-map-canvas {
  height: 460px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-2);
  position: relative;
  z-index: 0;
  isolation: isolate;
}
@media (max-width: 700px) { .aj-map-canvas { height: 340px; } }

/* Phone/tablet: the week stacks into a single column (see the max-width:860px
   block above). Two desktop rules had to be re-stated HERE because they are
   declared later in this file than that media query and were winning on
   specificity ties:
     - flex: 1 1 0  — harmless across a row, but down a column it lets a busy
       day SHRINK below its own content, which clipped the last job card off
       the bottom of the box (a 5-job day measured 441px squeezed into 440px).
     - min-height: 440px — a full-height column on a desktop grid, just dead
       space under every light day on a phone.
   Sizing to content fixes both. */
@media (max-width: 860px) {
  .calendar-day { flex: 0 0 auto; min-height: 0; }
}

/* ---------- Board chrome (design handoff) ---------- */
/* Nav tabs: flat chrome segments, active = accent text + inset top bar
   (replaces the pill highlight). */
.topbar .tab { border-radius: 0; min-height: 44px; letter-spacing: .05em; font-weight: 600; }
.topbar .tab.active {
  background: transparent;
  color: var(--accent);
  box-shadow: inset 0 3px 0 var(--accent);
}
/* Status strip: ruled segments instead of a loose text row. */
.board-header-status {
  display: flex; align-items: stretch; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; overflow: hidden;
}
.board-header-status > span {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-left: 1px solid var(--line);
  font-size: 12.5px; letter-spacing: .02em;
}
.board-header-status > span:first-child { border-left: none; }
.board-header-status > span:empty { display: none; }
#todaySnapshotWidget::before, #truckStatusWidget::before {
  font-size: 10px; letter-spacing: .08em; font-weight: 800;
  color: var(--text-soft); margin-right: 2px;
}
#todaySnapshotWidget::before { content: "TODAY"; }
#truckStatusWidget::before { content: "TRUCK"; }
#todaySnapshotWidget:empty::before, #truckStatusWidget:empty::before { content: none; }
#outstandingInvoicesWidget { color: var(--warn); font-weight: 700; }

/* ---------- Estimator two-column rail (design handoff) ---------- */
#estimateModal { max-width: 1280px; width: min(96vw, 1280px); }
.estimator-grid { display: grid; grid-template-columns: 1fr 340px; gap: 24px; align-items: start; }
.estimator-rail { display: flex; flex-direction: column; gap: 12px; position: sticky; top: 8px; }
.rail-card { background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; }
.rail-card .estimate-line, .rail-card .estimate-line span, .rail-card .estimate-line strong { color: #FFFFFF; }
.rail-card .estimate-line span { opacity: .75; }
@media (max-width: 980px) {
  .estimator-grid { grid-template-columns: 1fr; }
  .estimator-rail { position: static; }
}

/* ---------- Job modal body (design handoff) ---------- */
/* Right column: flat uppercase section rows with right-aligned values. */
.job-modal-col-right .accordion-header {
  text-transform: uppercase; letter-spacing: .06em;
  font-size: 12.5px; font-weight: 800;
}
.job-modal-col-right .accordion-header-right .view-sub {
  font-weight: 800; letter-spacing: .04em; text-transform: uppercase; font-size: 11px;
}
/* Photo buttons become the design's dashed tiles. */
.photo-upload-btn {
  border: 2px dashed var(--muted) !important;
  background: transparent !important;
  color: var(--text-soft) !important;
  font-weight: 800; letter-spacing: .05em; text-transform: uppercase; font-size: 12px;
  min-height: 56px; border-radius: var(--radius);
}
.photo-upload-btn:hover { border-color: var(--accent) !important; color: var(--aj-accent-strong) !important; }
/* Wide screens: the form breathes in three columns like the mock. */
@media (min-width: 1200px) {
  .job-modal-columns .form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .job-modal-columns .form-grid .field.full { grid-column: 1 / -1; }
}

/* ---------- Crew option picker (bottom sheet) ---------- */
.crew-picker { display: block; }
.crew-picker-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 48px; padding: 0 12px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); font-family: inherit; font-size: 15px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.crew-picker-btn.empty { color: var(--muted); font-weight: 500; }
.crew-picker-btn .cp-chev { color: var(--muted); font-size: 12px; flex-shrink: 0; }
.crew-picker-btn:active { border-color: var(--accent); }

.crew-sheet-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(0,0,0,.45);
  display: flex; align-items: flex-end; justify-content: center;
}
.crew-sheet {
  width: 100%; max-width: 560px;
  background: var(--surface);
  border-radius: 16px 16px 0 0;
  padding: 14px 14px calc(14px + env(safe-area-inset-bottom));
  box-shadow: var(--aj-shadow-lg);
  max-height: 70vh; overflow-y: auto;
}
.crew-sheet-title {
  font-size: 12px; letter-spacing: .08em; font-weight: 800; text-transform: uppercase;
  color: var(--text-soft); padding: 4px 6px 12px;
}
.crew-sheet-opt {
  display: block; width: 100%; min-height: 52px; padding: 0 16px;
  background: transparent; border: none; border-top: 1px solid var(--line);
  color: var(--text); font-family: inherit; font-size: 16px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.crew-sheet-opt:active, .crew-sheet-opt:hover { background: var(--aj-accent-tint); }
.crew-sheet-opt.selected { color: var(--aj-accent-strong); }
.crew-sheet-cancel {
  display: block; width: 100%; min-height: 48px; margin-top: 10px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text-soft); font-family: inherit; font-size: 14px; font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase; cursor: pointer;
}

/* ---------- Crew header reconciliation ---------- */
/* When the ⋯ menu reveals the full top bar for a crew login, it must act as a
   dropdown PANEL, not a second sticky header: static position (scrolls away),
   no competing blue border, and it can never sit on top of the crew header
   intercepting its taps. */
body.crew-tabs-on.show-full-topbar .topbar {
  position: static;
  border-bottom: 1px solid var(--line);
  z-index: 1;
}
/* Keep the crew header one tidy line — pills scroll sideways if tight instead
   of stacking the whole bar into a tall column. */
.crew-header { flex-wrap: nowrap; }
.crew-header #crewHeaderPills { flex-shrink: 1; overflow-x: auto; scrollbar-width: none; }
.crew-header #crewHeaderPills::-webkit-scrollbar { display: none; }
.crew-header .crew-clock-pill { white-space: nowrap; flex-shrink: 0; }
.crew-header #crewHeaderTitle, .crew-header #crewHeaderDate { white-space: nowrap; }

/* ---------- Crew menu: 2-up tab grid (owner request) ---------- */
/* The revealed menu lists views two per row — Board+My Day / Calendar+
   Customers / Reference+Team — as tappable boxes. Inbox is hidden here since
   the crew tab bar already carries it. */
body.crew-tabs-on .topbar .tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  width: 100%;
  margin-left: 0;
}
body.crew-tabs-on .topbar .tab {
  width: 100%;
  min-height: 52px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--radius);
  font-weight: 700;
}
body.crew-tabs-on .topbar .tab.active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
body.crew-tabs-on .topbar .tab[data-view="inbox"] { display: none; }

/* Crew menu: the icon cluster and + New Job share one row, split 50/50 so
   the action row lines up exactly with the Board/My Day tab grid above it. */
body.crew-tabs-on .topbar-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  width: 100%;
}
body.crew-tabs-on .topbar-actions .action-cluster {
  width: 100%; min-height: 52px;
  justify-content: space-around;
}
body.crew-tabs-on .topbar-actions #newJobBtn { width: 100%; min-height: 52px; font-weight: 800; }

/* ---------- Phone-width fixes (owner checking the admin app on iPhone) ---------- */
@media (max-width: 700px) {
  /* Status strip: stack segments as full-width rows so the truck line reads
     horizontally instead of squeezing into a one-word-wide column. */
  .board-header-status { flex-direction: column; align-items: stretch; }
  .board-header-status > span {
    border-left: none; border-top: 1px solid var(--line);
    flex-wrap: wrap; row-gap: 6px; padding: 10px 14px;
  }
  .board-header-status > span:first-child { border-top: none; }
  .board-header-status .maps-link,
  .board-header-status .maps-link-compact { margin: 2px 0; white-space: nowrap; }

  /* Job modal: no sideways scrolling, ever. Long unbroken values (emails,
     addresses) were forcing grid columns wider than the screen — minmax(0)
     plus min-width:0 on the fields lets them shrink and ellipsize instead. */
  .modal.ticket { max-width: 100vw; overflow-x: hidden; }
  .ticket-head { flex-wrap: wrap; }
  .job-modal-columns { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid .field { min-width: 0; }
  .form-grid .field input,
  .form-grid .field select,
  .form-grid .field textarea { min-width: 0; max-width: 100%; }
  .modal-actions { flex-wrap: wrap; gap: 8px; }
  .modal-actions .right { flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
  .financial-summary { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .accordion-body { overflow-x: hidden; }

  /* Dump Receipts & Gas: the add-cost controls stack full-width instead of a
     fixed-width desktop row bursting the card; logged-cost rows wrap so the
     delete ✕ never gets pushed off-screen. */
  .cost-add-row { flex-direction: column; align-items: stretch; }
  .cost-add-row > * { width: 100% !important; min-width: 0; max-width: 100%; }
  .cost-row { flex-wrap: wrap; row-gap: 4px; min-width: 0; }
  .cost-row .amt { margin-left: auto; }

  /* Modal footer: stack cleanly — SAVE first and full-width, then the
     secondary actions, DELETE JOB last (destructive at the bottom). */
  .modal-actions { flex-direction: column; align-items: stretch; gap: 10px; }
  .modal-actions .right { order: -1; display: flex; flex-direction: column; gap: 8px; }
  .modal-actions .right #saveJobBtn { order: -1; }
  .modal-actions > div:first-child { display: flex; flex-direction: column; gap: 8px; }
  .modal-actions button, .modal-actions a.btn-secondary {
    width: 100%; min-height: 48px;
    display: inline-flex; align-items: center; justify-content: center;
  }
}
