/* ═══════════════════════════════════════════════════════════════════════
   SHOPNC · Service Manual Design System Override · Phase 1
   LIGHT MODE ONLY.

   This file loads AFTER shopnc.css. It overrides the foundation to
   deliver the Service Manual aesthetic for light mode only.

   Dark mode intentionally unchanged — we'll tackle that in Phase 2
   once light mode is validated with beta users.

   To disable and revert: comment out the <link> in index.html.
   One line. Fully reversible.

   Philosophy:
     - Don't rename existing CSS variables — 542+ JS references use
       var(--cyan), var(--green), etc. by name. We override VALUES.
     - Remap fonts globally via selectors so the 499 Rajdhani refs
       in JS pick up Archivo without touching a single JS file.
     - Neutralise gradients, glows, rounded corners in light mode.
     - New utility classes use .ds- prefix to avoid collisions.
   ═══════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════
   01 · FONT IMPORTS
   ═══════════════════════════════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800;900&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700;800&display=swap');


/* ═══════════════════════════════════════════════════════════════════════
   02 · LIGHT MODE PALETTE OVERRIDE
   Remaps existing variable names to Service Manual palette.
   Applied to both default light-mode and theme-orange.light-mode.

   Mapping rationale:
     --cyan          → signal amber #e85520
     --green         → forest ok #3a8a47
     --gold          → caution amber #c98612
     --red           → danger red #c93a1f
     --orange        → signal amber (unified with cyan)
     --purple        → info slate #3d6da3
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode,
body.theme-orange.light-mode {
  /* Paper tones */
  --bg: #f1ece3;
  --bg2: #e6dfd1;
  --surface: #faf6ed;
  --surface2: #f1ece3;
  --surface3: #e6dfd1;

  /* Rules */
  --border: #c5bda9;
  --border2: #9f967f;

  /* Signal (amber) */
  --cyan: #e85520;
  --cyan-dim: rgba(232,85,32,0.1);
  --cyan-glow: rgba(232,85,32,0.22);
  --orange: #e85520;

  /* Semantic states — brightened for better on-paper legibility
     while staying within the Service Manual muted-but-readable band. */
  --green: #3a8a47;
  --green-dim: rgba(58,138,71,0.13);
  --gold: #c98612;
  --gold-dim: rgba(201,134,18,0.13);
  --red: #c93a1f;
  --red-dim: rgba(201,58,31,0.11);
  --purple: #3d6da3;

  /* Ink */
  --text: #1a1611;
  /* May 2026 (round 2): pushed darker after first pass still read as
     "too light" — the workshop screen is in a well-lit bay and the
     cream paper background absorbs subtle greys. Now:
       --text-muted: contrast ≈10:1 (was ≈3.9:1)
       --text-dim:   contrast ≈6.2:1 (was ≈1.9:1)
     Still preserves a visible three-tier hierarchy (full text → muted
     → dim) but all tiers are now in the "easily read at arm's length"
     band. KPI labels above the Profit Intel cards use --text-dim via
     .kpi-lbl; section meta-text and audit log timestamps use
     --text-muted. Both groups were the original complaint. */
  --text-muted: #3a2f24;
  --text-dim: #6a5b48;

  /* Timeline */
  --tl-green: #3a8a47;
  --tl-amber: #c98612;
  --tl-red: #c93a1f;

  /* ── Service Manual DS Tokens (canonical names used by new/redesigned
     screens). These alias the legacy palette so JS that reads
     var(--cyan) / var(--text) etc. and new code that reads var(--amber)
     / var(--ink) etc. resolve to the same values. Single source of truth. */
  --ink:        var(--text);          /* primary text  */
  --ink-soft:   #3a3328;              /* slightly softer ink for body copy */
  --ink-mute:   var(--text-muted);    /* muted text */
  --ink-dim:    var(--text-dim);      /* dimmed text */
  --bg-deep:    var(--bg2);           /* deeper paper */
  --bg-panel:   var(--surface);       /* panel paper */
  --bg-raised:  #ffffff;              /* white card */
  --rule:       var(--border);        /* default rule */
  --rule-bright:var(--border2);       /* brighter rule */
  --amber:      var(--cyan);          /* signal amber */
  --amber-soft: var(--cyan-dim);
  --amber-deep: #b33a0f;
  --warn:       var(--gold);
  --warn-soft:  var(--gold-dim);
  --ok:         var(--green);
  --ok-soft:    var(--green-dim);
  --danger:     var(--red);
  --danger-soft:var(--red-dim);
  --info:       var(--purple);
  --info-soft:  rgba(61,109,163,0.10);
}


/* ═══════════════════════════════════════════════════════════════════════
   03 · FONT REMAPPING
   Remap legacy fonts without touching JS. Inline styles in JS that
   write font-family:'Rajdhani' still work; we override at selector level.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode,
body.light-mode button,
body.light-mode input,
body.light-mode select,
body.light-mode textarea {
  font-family: 'IBM Plex Sans', 'Exo 2', sans-serif !important;
}

/* Display surfaces → Archivo */
body.light-mode .logo-text,
body.light-mode .page-title,
body.light-mode .card-title,
body.light-mode .pw-val,
body.light-mode .jd-section-title,
body.light-mode .jd-job-title,
body.light-mode .jd-plate-text,
body.light-mode .tv-job-title,
body.light-mode #tv-job-title,
body.light-mode .modal-title,
body.light-mode h1,
body.light-mode h2,
body.light-mode h3,
body.light-mode h4,
body.light-mode [style*="Rajdhani"] {
  font-family: 'Archivo', sans-serif !important;
  letter-spacing: 0.03em;
}

/* Data surfaces → JetBrains Mono */
body.light-mode .plate,
body.light-mode .jd-plate,
body.light-mode .badge,
body.light-mode .b-service,
body.light-mode .b-repair,
body.light-mode .b-diag,
body.light-mode .b-major,
body.light-mode .b-wait,
body.light-mode .b-approval,
body.light-mode .b-quote-needed,
body.light-mode .b-advisor,
body.light-mode .b-parts,
body.light-mode .b-prog,
body.light-mode .b-done,
body.light-mode .b-comeback,
body.light-mode .nav-section,
body.light-mode .pw-lbl,
body.light-mode th,
body.light-mode .jd-line-code,
body.light-mode .jd-line-num,
body.light-mode .jd-stat-lbl,
body.light-mode .jd-stat-val,
body.light-mode .pw-sub,
body.light-mode .sb-footer,
body.light-mode .line-total,
body.light-mode .tot-val {
  font-family: 'JetBrains Mono', monospace !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   04 · NEUTRALISE GRADIENTS
   Every gradient stripe becomes a flat amber bar or surface.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .sidebar::before {
  background: var(--cyan) !important;
  opacity: 0.6;
}
body.light-mode .pw::before {
  background: var(--cyan) !important;
}
body.light-mode .topbar::after {
  background: var(--border) !important;
}
body.light-mode .btn-cyan {
  background: var(--cyan) !important;
  color: #fff !important;
  box-shadow: none !important;
  border-radius: 0 !important;
}
body.light-mode .btn-cyan:hover {
  background: #d14914 !important;
  box-shadow: none !important;
  transform: none !important;
}
body.light-mode .pw-bar {
  background: var(--green) !important;
  border-radius: 0 !important;
}
body.light-mode .pw-bar.neg {
  background: var(--red) !important;
}
body.light-mode .modal::before {
  background: var(--cyan) !important;
  opacity: 0.7;
}


/* ═══════════════════════════════════════════════════════════════════════
   05 · KILL GLOWS
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .pw-val,
body.light-mode .pw-val.neg,
body.light-mode .card-title.glow,
body.light-mode .btn-cyan:hover,
body.light-mode [style*="text-shadow"],
body.light-mode [style*="box-shadow:0 0"],
body.light-mode [style*="box-shadow: 0 0"] {
  text-shadow: none !important;
  box-shadow: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   06 · SHARPEN CORNERS
   Flatten everything except known-circular shapes.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .card,
body.light-mode .pw,
body.light-mode .btn,
body.light-mode .btn-sm,
body.light-mode .btn-xs,
body.light-mode .badge,
body.light-mode .nav-badge,
body.light-mode input,
body.light-mode textarea,
body.light-mode select,
body.light-mode .modal,
body.light-mode .modal-header,
body.light-mode .modal-body,
body.light-mode .modal-footer,
body.light-mode .plate,
body.light-mode .line-row,
body.light-mode .line-input,
body.light-mode .job-totals,
body.light-mode .insp-cat-header,
body.light-mode .insp-items,
body.light-mode .insp-notes-input,
body.light-mode .search-bar,
body.light-mode .filter-btn,
body.light-mode .tv-job-card {
  border-radius: 0 !important;
}

/* Keep circular shapes */
body.light-mode [style*="border-radius:50%"],
body.light-mode [style*="border-radius: 50%"],
body.light-mode .tl-btn {
  border-radius: 50% !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   07 · PAPER SURFACE REFINEMENTS
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .card {
  border-color: var(--border);
}
body.light-mode .card-header {
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
}
body.light-mode .card-title {
  color: var(--text);
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
body.light-mode .card-title.glow {
  color: var(--cyan);
}
body.light-mode th {
  background: var(--bg2);
  border-bottom: 2px solid var(--text);
  color: var(--text-muted);
  letter-spacing: 0.15em;
  font-weight: 700;
}

/* Sidebar — ink-dark logo header with amber underline */
body.light-mode .sidebar {
  background: var(--surface);
}
body.light-mode .logo {
  background: var(--text);
  color: var(--bg);
  border-bottom: 3px solid var(--cyan);
}
body.light-mode .logo-text {
  color: var(--bg) !important;
}
body.light-mode .logo-text span {
  color: var(--cyan) !important;
}
body.light-mode .logo-sub {
  color: rgba(255,255,255,0.5);
}


/* ═══════════════════════════════════════════════════════════════════════
   08 · BUTTONS
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .btn {
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 700;
  letter-spacing: 0.1em;
  border-radius: 0 !important;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
body.light-mode .btn-ghost {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border2);
}
body.light-mode .btn-ghost:hover {
  border-color: var(--cyan);
  color: var(--cyan);
  background: var(--surface);
}
body.light-mode .btn-green {
  background: var(--surface);
  color: var(--green);
  border: 1px solid var(--green);
}
body.light-mode .btn-green:hover {
  background: var(--green);
  color: #fff;
}
body.light-mode .btn-red {
  background: var(--surface);
  color: var(--red);
  border: 1px solid var(--red);
}
body.light-mode .btn-red:hover {
  background: var(--red);
  color: #fff;
}
body.light-mode .btn-gold {
  background: var(--surface);
  color: var(--gold);
  border: 1px solid var(--gold);
}
body.light-mode .btn-gold:hover {
  background: var(--gold);
  color: #fff;
}


/* ═══════════════════════════════════════════════════════════════════════
   09 · NAV
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .nav-item.active {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-left-color: var(--cyan);
}
body.light-mode .nav-section {
  color: var(--cyan);
  font-weight: 800;
  letter-spacing: 0.18em;
}


/* ═══════════════════════════════════════════════════════════════════════
   10 · TABLES
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode td {
  border-bottom-color: var(--border);
}
body.light-mode tbody tr:hover td {
  background: var(--bg2);
}


/* ═══════════════════════════════════════════════════════════════════════
   11 · BADGES — outlined monospace pills
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .badge {
  background: transparent !important;
  border: 1px solid currentColor !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 700;
  letter-spacing: 0.12em;
  border-radius: 0 !important;
}
body.light-mode .b-service { color: var(--text-muted); }
body.light-mode .b-repair { color: var(--purple); }
body.light-mode .b-diag { color: var(--purple); }
body.light-mode .b-major { color: var(--red); }
body.light-mode .b-wait { color: var(--gold); }
body.light-mode .b-approval { color: var(--cyan); }
body.light-mode .b-quote-needed { color: var(--gold); }
body.light-mode .b-advisor { color: var(--green); }
body.light-mode .b-parts { color: var(--purple); }
body.light-mode .b-prog { color: var(--cyan); }
body.light-mode .b-done { color: var(--green); }
body.light-mode .b-comeback { color: var(--red); }

body.light-mode .nav-badge {
  background: var(--cyan) !important;
  color: #fff !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   12 · PROFIT WIDGET
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .pw {
  border-radius: 0 !important;
  background: var(--surface);
}
body.light-mode .pw-lbl {
  letter-spacing: 0.18em;
  font-weight: 700;
  font-size: 9px;
}
body.light-mode .pw-val {
  font-family: 'Archivo', sans-serif !important;
  color: var(--green);
  font-weight: 800;
}
body.light-mode .pw-val.neg {
  color: var(--red);
}


/* ═══════════════════════════════════════════════════════════════════════
   13 · TOPBAR
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .topbar {
  background: var(--surface);
}
body.light-mode .page-title {
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--text);
}


/* ═══════════════════════════════════════════════════════════════════════
   14 · MODALS — inverse ink header with amber underline
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .modal {
  background: var(--surface);
  border: 1px solid var(--border2);
}
body.light-mode .modal-header {
  background: var(--text);
  color: var(--bg);
  border-bottom: 3px solid var(--cyan);
  padding: 12px 18px;
}
body.light-mode .modal-title {
  color: var(--bg);
  font-family: 'Archivo', sans-serif !important;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 13px;
}
body.light-mode .modal-close {
  color: rgba(255,255,255,0.5);
  background: transparent;
}
body.light-mode .modal-close:hover { color: #fff; }
body.light-mode .modal-body {
  background: var(--surface);
  color: var(--text);
  padding: 20px 22px;
}
body.light-mode .modal-footer {
  background: var(--bg2);
  border-top: 1px solid var(--border);
  padding: 12px 22px;
}


/* ═══════════════════════════════════════════════════════════════════════
   15 · INPUTS
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
body.light-mode textarea,
body.light-mode select {
  background: var(--surface);
  border: 1px solid var(--border2);
  color: var(--text);
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
}
body.light-mode input:focus,
body.light-mode textarea:focus,
body.light-mode select:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: inset 0 0 0 1px var(--cyan);
}
body.light-mode input::placeholder,
body.light-mode textarea::placeholder {
  color: var(--text-dim);
}

body.light-mode .jd-input {
  background: var(--surface) !important;
  border: 1px solid var(--border2) !important;
  color: var(--text) !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
}

/* ─── Section action buttons (+ ADD, CREATE PO, VIEW POS) ─────────────────
   Used in Labour / Parts / Consumables section headers and equivalent
   inline-action spots across the job card and AQ builder. JetBrains Mono
   caps, ink hairline default, amber on hover. Bigger than the old
   `btn btn-sm` (which was 11px) so the eye finds them at a glance. */
body.light-mode .jd-action-btn {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  padding: 9px 16px !important;
  border-radius: 0 !important;
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  color: var(--ink) !important;
  cursor: pointer;
  transition: all .12s;
  line-height: 1;
  white-space: nowrap;
}
body.light-mode .jd-action-btn:hover {
  border-color: var(--amber) !important;
  color: var(--amber) !important;
}
body.light-mode .jd-action-btn.is-primary {
  background: var(--amber) !important;
  border-color: var(--amber) !important;
  color: #fff !important;
}
body.light-mode .jd-action-btn.is-primary:hover {
  background: var(--amber-deep) !important;
  border-color: var(--amber-deep) !important;
  color: #fff !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   16 · PLATE — boarding-pass badge treatment
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .plate {
  background: var(--ink) !important;
  color: var(--bg) !important;
  border: none !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 800;
  letter-spacing: 0.05em;
  padding: 4px 12px 6px !important;
  display: inline-block !important;
  position: relative !important;
  line-height: 1 !important;
}

/* State-of-registration strip. Markup is .plate > .locale (single
   element, nested child). The .locale renders as a small amber strip
   on TOP of the plate, bleeding to the plate's edges via negative
   margins. Matches the design-system spec at
   shopnc-design-system.html § 08 (PLATE BADGE).
   Previously this CSS targeted `.plate-wrap > .plate-state` from an
   older 2-piece markup; that emitter shape is gone — the function
   now produces the spec-compliant nested-child shape. */
body.light-mode .plate .locale {
  display: block !important;
  font-size: 8px !important;
  letter-spacing: 0.2em !important;
  text-align: center !important;
  background: var(--amber) !important;
  color: #fff !important;
  margin: -4px -12px 3px -12px !important;
  padding: 1px 0 !important;
  font-weight: 700 !important;
  font-family: 'JetBrains Mono', monospace !important;
  text-transform: uppercase !important;
}

/* Size variants from the design system. plate-lg used on doc headers;
   plate-sm in tight inline contexts. */
body.light-mode .plate-lg { padding: 6px 16px 9px !important; font-size: 22px !important; }
body.light-mode .plate-lg .locale { font-size: 9px !important; margin: -6px -16px 3px -16px !important; }
body.light-mode .plate-sm { padding: 2px 8px 4px !important; font-size: 11px !important; }
body.light-mode .plate-sm .locale { font-size: 7px !important; margin: -2px -8px 2px -8px !important; }


/* ═══════════════════════════════════════════════════════════════════════
   17 · HARDCODED HEX NEUTRALISATION
   Catch the common inline hex values that bypass var().
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode [style*="color:#00d4ff"],
body.light-mode [style*="color: #00d4ff"] { color: var(--cyan) !important; }
body.light-mode [style*="color:#00ff88"],
body.light-mode [style*="color: #00ff88"] { color: var(--green) !important; }
body.light-mode [style*="color:#ffd700"],
body.light-mode [style*="color: #ffd700"] { color: var(--gold) !important; }
body.light-mode [style*="color:#ff3d5a"],
body.light-mode [style*="color: #ff3d5a"] { color: var(--red) !important; }
body.light-mode [style*="color:#e8eef8"],
body.light-mode [style*="color: #e8eef8"] { color: var(--text) !important; }
body.light-mode [style*="color:#7d92ba"],
body.light-mode [style*="color: #7d92ba"] { color: var(--text-muted) !important; }
body.light-mode [style*="color:#c8d4e8"],
body.light-mode [style*="color: #c8d4e8"] { color: var(--text) !important; }

body.light-mode [style*="background:#00d4ff"],
body.light-mode [style*="background: #00d4ff"] { background: var(--cyan) !important; }
body.light-mode [style*="background:#0088ff"],
body.light-mode [style*="background: #0088ff"] { background: var(--cyan) !important; }
body.light-mode [style*="background:#00ff88"],
body.light-mode [style*="background: #00ff88"] { background: var(--green) !important; }
body.light-mode [style*="background:#161b27"] { background: var(--surface) !important; }
body.light-mode [style*="background: #161b27"] { background: var(--surface) !important; }

body.light-mode [style*="border:1px solid #2a3550"],
body.light-mode [style*="border: 1px solid #2a3550"] { border-color: var(--border) !important; }
body.light-mode [style*="border:2px solid #2a3550"],
body.light-mode [style*="border: 2px solid #2a3550"] { border-color: var(--border2) !important; }


/* ═══════════════════════════════════════════════════════════════════════
   18 · EMOJI HYGIENE
   Kill decorative emoji in well-defined selectors. The nav icons, mobile
   nav icons, and sidebar logo gear are handled purely in CSS.

   Applies to BOTH light and dark mode (no body.light-mode prefix needed
   for these structural rules).

   Kept on purpose (information-bearing):
     ⚠  offline banner, error toasts
     ✕  close / delete / clear buttons
     ✓  inspection OK states
     ❌ missing parts
   ═══════════════════════════════════════════════════════════════════════ */

/* Kill all 12 sidebar nav icons (<span class="ni">) at once */
.sidebar .nav-item .ni {
  display: none !important;
}
.sidebar .nav-item {
  gap: 0 !important;
  padding-left: 20px !important;
}

/* Kill 6 mobile bottom-nav icons — keep labels */
#mobile-nav .mn-item .mn-icon {
  display: none !important;
}

/* Kill sidebar logo gear — replace box with a solid amber square */
.logo-icon {
  font-size: 0 !important;
  width: 10px !important;
  height: 10px !important;
  background: var(--cyan) !important;
  box-shadow: none !important;
  border-radius: 0 !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   19 · NEW UTILITY CLASSES (ds- prefix)
   For use in new code going forward.
   ═══════════════════════════════════════════════════════════════════════ */

/* Numbered section header ("01 / LABOUR") */
.ds-section-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.15em;
  color: var(--cyan);
  font-weight: 700;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
}
.ds-section-label .ds-num {
  background: var(--cyan);
  color: #fff;
  padding: 1px 6px 2px;
  margin-right: 8px;
  font-weight: 800;
}

/* Stencilled panel (label floats on top-left corner) */
.ds-stencil {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border2);
  padding: 14px 18px;
}
.ds-stencil::before {
  content: attr(data-label);
  position: absolute;
  top: -7px;
  left: 10px;
  background: var(--bg);
  padding: 0 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.2em;
  color: var(--cyan);
  font-weight: 700;
  text-transform: uppercase;
}

/* LED status indicators */
.ds-led {
  width: 8px;
  height: 8px;
  border-radius: 50% !important;
  flex-shrink: 0;
  display: inline-block;
  background: var(--text-muted);
}
.ds-led.ok { background: var(--green); }
.ds-led.warn { background: var(--gold); }
.ds-led.alert { background: var(--cyan); }
.ds-led.danger { background: var(--red); }
.ds-led.live {
  background: var(--cyan);
  position: relative;
}
.ds-led.live::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 1px solid var(--cyan);
  opacity: 0;
  animation: dsLivePulse 2.4s ease-out infinite;
}
@keyframes dsLivePulse {
  0% { opacity: 0.6; transform: scale(1); }
  100% { opacity: 0; transform: scale(2); }
}

/* Outlined monospace pill */
.ds-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
  color: var(--text-muted);
}
.ds-pill.ok { color: var(--ok); }
.ds-pill.warn { color: var(--warn); }
.ds-pill.alert { color: var(--info); }
.ds-pill.danger { color: var(--danger); }

/* Left-edge striped accent for critical items */
.ds-hazard-strip {
  position: relative;
  padding-left: 18px;
}
.ds-hazard-strip::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 6px;
  background: repeating-linear-gradient(
    135deg,
    var(--red) 0,
    var(--red) 4px,
    transparent 4px,
    transparent 8px
  );
}

/* Boarding-pass plate badge (for new code) */
.ds-plate-tag {
  background: var(--text);
  color: var(--bg);
  padding: 4px 12px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 800;
  font-size: 16px;
  letter-spacing: 0.05em;
  line-height: 1;
  display: inline-block;
  position: relative;
}
.ds-plate-tag .ds-plate-locale {
  display: block;
  font-size: 8px;
  letter-spacing: 0.2em;
  text-align: center;
  background: var(--cyan);
  color: #fff;
  margin: -4px -12px 3px -12px;
  padding: 1px 0;
  font-weight: 700;
}


/* ═══════════════════════════════════════════════════════════════════════
   20 · GLITCH FIXES — targeted patches for v1 deploy
   Each rule addresses a specific visual bug spotted in the live build.
   Organised by screen / surface so future maintainers can grep by
   symptom.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── Today's Activity widget — progress bar gradient still renders
       because the gradient is in an inline style on #sw-bar ─── */
body.light-mode #sw-bar[style*="linear-gradient"],
body.light-mode .pw-bar[style*="linear-gradient"] {
  background: var(--green) !important;
}

/* ─── Topbar sun-emoji light/dark toggle — box looks weird as bordered
       cell. Tighten to match the topbar button rhythm. ─── */
body.light-mode button[onclick="toggleLightMode()"] {
  border: 1px solid var(--border2) !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 13px !important;
  color: var(--cyan) !important;
  padding: 6px 10px !important;
  min-width: 36px;
}
body.light-mode button[onclick="toggleLightMode()"]:hover {
  border-color: var(--cyan) !important;
  background: var(--cyan-dim) !important;
}

/* ─── Sidebar "Switch to Tech View" button — still has a cyan gradient
       background and rounded corners. Reshape to match the aesthetic. ─── */
body.light-mode button[onclick="enterTechView()"] {
  background: transparent !important;
  border: 1px solid var(--cyan) !important;
  border-radius: 0 !important;
  color: var(--cyan) !important;
  font-family: 'JetBrains Mono', monospace !important;
  letter-spacing: 0.1em !important;
}
body.light-mode button[onclick="enterTechView()"]:hover {
  background: var(--cyan) !important;
  color: #fff !important;
}

/* ─── Online-pending button in topbar — hardcoded cyan gradient bg ─── */
body.light-mode #online-pending-btn {
  background: var(--cyan-dim) !important;
  border: 1px solid var(--cyan) !important;
  border-radius: 0 !important;
  color: var(--cyan) !important;
  font-family: 'JetBrains Mono', monospace !important;
  letter-spacing: 0.1em !important;
}

/* ─── Diary week view — "booked" block slim rows use inline color-hex
       from TECH_COLORS palette (#00d4ff/#a855f7/#00ff88/#f59e0b/#ef4444/
       #3b82f6/#ec4899) as background tints plus left borders. In light
       mode these read as harsh coloured slabs against cream paper.
       Neutralise: keep the left-border colour (it signals the tech), but
       flatten the background to paper tone. ─── */
body.light-mode .diary-block-slim {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-left-width: 3px !important;
  color: var(--text) !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  border-radius: 0 !important;
  letter-spacing: 0.02em;
  padding: 4px 6px !important;
  margin-bottom: 3px;
}

/* ─── Diary week-view day header — the `style="color:var(--cyan)"` on
       today-column highlights. That's correct (now amber) but the
       `rgba(0,212,255,0.08)` background tint doesn't update via --cyan.
       Replace with amber-dim. ─── */
body.light-mode .diary-day-header[style*="rgba(0,212,255"] {
  background: var(--cyan-dim) !important;
  border-bottom: 2px solid var(--cyan) !important;
}

/* ─── Diary day capacity bar — gradient fills ─── */
body.light-mode .diary-day-col .diary-day-header > div[style*="background:var(--surface3)"] > div {
  /* This is the capacity fill bar — the inner one inherits the --green
     variable which has been remapped to forest-ok. That's fine. No-op. */
}

/* ─── Diary list section headers — "Today", "Completed Today",
       "Cancelled" section strips. These use hardcoded rgba tints
       for backgrounds:
         Today:          rgba(0,212,255,0.08) / 0.04
         Completed:      rgba(0,255,136,0.06) / border 0.2
         Cancelled:      (no explicit bg — plain)
         Carry Over:     rgba(245,158,11,0.08) / 0.25
         No Show:        rgba(255,61,90,0.1) / 0.4
         Online Pending: rgba(0,212,255,0.08) / 0.35
       Neutralise these tints via attribute selectors. Keep the border
       colour to preserve state affordance. ─── */
body.light-mode .dl-section-header[style*="rgba(0,212,255"] {
  background: var(--cyan-dim) !important;
  border-color: var(--cyan) !important;
}
body.light-mode .dl-section-header[style*="rgba(0,255,136"] {
  background: var(--green-dim) !important;
  border-color: var(--green) !important;
}
body.light-mode .dl-section-header[style*="rgba(245,158,11"],
body.light-mode .dl-section-header[style*="rgba(255,215,0"] {
  background: var(--gold-dim) !important;
  border-color: var(--gold) !important;
}
body.light-mode .dl-section-header[style*="rgba(255,61,90"] {
  background: var(--red-dim) !important;
  border-color: var(--red) !important;
}

/* ─── Diary booking rows — inline border-left:3px solid var(--cyan) +
       bg rgba(0,212,255,0.04). The var(--cyan) is now amber (correct).
       The hardcoded rgba is the stray cyan bleed. ─── */
body.light-mode .diary-bk-row[style*="rgba(0,212,255"] {
  background: var(--cyan-dim) !important;
}
body.light-mode .diary-bk-row .dl-time[style*="color:var(--cyan)"] {
  color: var(--cyan) !important;
}

/* ─── Hardcoded rgba tints that bypass --cyan-dim/--green-dim/etc
       throughout JS-rendered content. These are catch-alls for inline
       bg colours commonly used for status strips and alert bars. ─── */
body.light-mode [style*="background:rgba(0,212,255"],
body.light-mode [style*="background: rgba(0,212,255"],
body.light-mode [style*="background:rgba(0, 212, 255"] {
  background: var(--cyan-dim) !important;
}
body.light-mode [style*="background:rgba(0,255,136"],
body.light-mode [style*="background: rgba(0,255,136"] {
  background: var(--green-dim) !important;
}
body.light-mode [style*="background:rgba(255,61,90"],
body.light-mode [style*="background: rgba(255,61,90"] {
  background: var(--red-dim) !important;
}
body.light-mode [style*="background:rgba(255,215,0"],
body.light-mode [style*="background: rgba(255,215,0"],
body.light-mode [style*="background:rgba(245,158,11"],
body.light-mode [style*="background: rgba(245,158,11"] {
  background: var(--gold-dim) !important;
}
body.light-mode [style*="background:rgba(168,85,247"] {
  /* purple → info */
  background: var(--info-soft, rgba(61,109,163,0.08)) !important;
}

/* Hardcoded border-color rgba variants (same colours, different prop) */
body.light-mode [style*="border-color:rgba(0,212,255"],
body.light-mode [style*="border-color: rgba(0,212,255"] {
  border-color: var(--cyan) !important;
}
body.light-mode [style*="border-color:rgba(0,255,136"] {
  border-color: var(--green) !important;
}
body.light-mode [style*="border-color:rgba(255,61,90"] {
  border-color: var(--red) !important;
}
body.light-mode [style*="border-color:rgba(255,215,0"],
body.light-mode [style*="border-color:rgba(245,158,11"] {
  border-color: var(--gold) !important;
}

/* Gradient backgrounds that survive because they're inline */
body.light-mode [style*="linear-gradient(135deg,#00d4ff"],
body.light-mode [style*="linear-gradient(135deg,var(--cyan)"] {
  background: var(--cyan) !important;
}
body.light-mode [style*="linear-gradient(90deg,var(--cyan)"],
body.light-mode [style*="linear-gradient(90deg,transparent,var(--cyan)"] {
  background: var(--cyan) !important;
}

/* ─── "CXL BKNG" badge on cancelled bookings — grey column with
       stacked text. It's rendering as a narrow block of monospace text.
       Tighten spacing and make it read as a proper label. ─── */
body.light-mode .dl-row .dl-time {
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--cyan);
}

/* ─── Completed jobs total strip "Total: $2103.17 inc GST · 2 unpaid"
       in the "Completed Today" section header — needs to use amber for
       the "2 unpaid" count. It currently renders red inline. ─── */
body.light-mode .dl-section-meta [style*="color:var(--red)"] {
  color: var(--red) !important;
  font-weight: 700;
}

/* ─── Sidebar "Today's Activity" widget — pw-val shows the big number
       (currently "4"). It's huge because of inline font-size:28px AND
       my CSS uses Archivo 800. That's intentionally big but the cyan
       inline colour was "var(--cyan)" — which we want, it's now amber. ─── */

/* ─── Overall layout: the "Today" and "Completed Today" section
       headers sit directly above the section body. They need a
       clear paper boundary below so content doesn't look like it's
       bleeding out of the coloured strip. ─── */
body.light-mode .dl-section {
  margin-bottom: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
}
body.light-mode .dl-section-header {
  border-bottom: 1px solid var(--border) !important;
  padding: 10px 14px !important;
}
body.light-mode .dl-section-date {
  font-family: 'Archivo', sans-serif !important;
  font-weight: 800 !important;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 13px;
}
body.light-mode .dl-section-meta {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}


/* ═══════════════════════════════════════════════════════════════════════
   21 · SAFETY NET — catch any legacy neon literals that slip through
   Post-v2 sweep of the JS codebase removed 3,000+ legacy colour / font
   literals. These catch-all selectors neutralise anything that might
   return in future (dev regressions, dynamically-built style strings,
   third-party embeds).
   ═══════════════════════════════════════════════════════════════════════ */

/* Legacy cyan (#00d4ff and variants) in inline styles — remap to amber */
body.light-mode [style*="#00d4ff"],
body.light-mode [style*="#00b8e6"],
body.light-mode [style*="#00a8d8"],
body.light-mode [style*="#0891b2"],
body.light-mode [style*="#06b6d4"],
body.light-mode [style*="#0ea5e9"],
body.light-mode [style*="#0284c7"],
body.light-mode [style*="#00b4d8"],
body.light-mode [style*="#38bdf8"],
body.light-mode [style*="#0088ff"],
body.light-mode [style*="#0088cc"] {
  /* The attribute selector matches; the actual colour comes from our
     base palette via the `style` inline value being overridden by rules
     on `color` / `background` wherever possible. This primarily catches
     background attribute tints. */
  border-color: var(--cyan) !important;
}

/* Legacy neon-green — remap to forest-ok */
body.light-mode [style*="#00ff88"],
body.light-mode [style*="#00e87a"],
body.light-mode [style*="#00c060"],
body.light-mode [style*="#34d399"],
body.light-mode [style*="#22c55e"],
body.light-mode [style*="#10b981"],
body.light-mode [style*="#16a34a"] {
  border-color: var(--green) !important;
}

/* Legacy purple / violet — remap to info */
body.light-mode [style*="#a855f7"],
body.light-mode [style*="#c084fc"],
body.light-mode [style*="#a78bfa"],
body.light-mode [style*="#8b5cf6"],
body.light-mode [style*="#7c3aed"],
body.light-mode [style*="#9333ea"],
body.light-mode [style*="#e9d5ff"] {
  border-color: var(--purple) !important;
}

/* Legacy amber-warning / yellow — remap to gold */
body.light-mode [style*="#f59e0b"],
body.light-mode [style*="#fbbf24"],
body.light-mode [style*="#ffd700"],
body.light-mode [style*="#d97706"],
body.light-mode [style*="#fcd34d"] {
  border-color: var(--gold) !important;
}

/* Legacy pink / hot-red — remap to danger */
body.light-mode [style*="#ff3d5a"],
body.light-mode [style*="#ef4444"],
body.light-mode [style*="#f87171"],
body.light-mode [style*="#ec4899"],
body.light-mode [style*="#f43f5e"] {
  border-color: var(--red) !important;
}

/* Legacy generic blue — remap to info */
body.light-mode [style*="#3b82f6"],
body.light-mode [style*="#60a5fa"],
body.light-mode [style*="#2563eb"],
body.light-mode [style*="#1d4ed8"],
body.light-mode [style*="#635bff"] {
  border-color: var(--purple) !important;
}

/* ─── Flatten any remaining border-radius in inline styles ─────────
   Aggressive: any element with an explicit border-radius inside its
   style attribute gets it zeroed. Circles are preserved via
   `border-radius:50%` matching and the `!important` only applying when
   the attr substring is a px/em/rem value — matching on the containing
   style string as a whole. We list the common offenders. ─── */
body.light-mode [style*="border-radius:3px"],
body.light-mode [style*="border-radius:4px"],
body.light-mode [style*="border-radius:5px"],
body.light-mode [style*="border-radius:6px"],
body.light-mode [style*="border-radius:7px"],
body.light-mode [style*="border-radius:8px"],
body.light-mode [style*="border-radius:10px"],
body.light-mode [style*="border-radius:12px"],
body.light-mode [style*="border-radius:14px"],
body.light-mode [style*="border-radius:16px"],
body.light-mode [style*="border-radius:20px"],
body.light-mode [style*="border-radius: 3px"],
body.light-mode [style*="border-radius: 4px"],
body.light-mode [style*="border-radius: 5px"],
body.light-mode [style*="border-radius: 6px"],
body.light-mode [style*="border-radius: 8px"] {
  border-radius: 0 !important;
}

/* Exceptions: elements that must keep their roundness */
body.light-mode .avatar,
body.light-mode .tech-dot,
body.light-mode .led,
body.light-mode .ds-led,
body.light-mode [style*="border-radius:50%"],
body.light-mode [style*="border-radius: 50%"] {
  border-radius: 50% !important;
}

/* ─── Kill any leftover neon font declarations on inline styles ─────
   Most inline 'Rajdhani' / 'Exo 2' were swept, but this catches any
   late additions. Attribute-match the style substring and force our
   fonts. ─── */
body.light-mode [style*="Rajdhani"],
body.light-mode [style*="Exo 2"],
body.light-mode [style*="'Exo 2'"] {
  font-family: 'IBM Plex Sans', sans-serif !important;
}

/* Monospace surfaces keep JetBrains Mono */
body.light-mode [style*="monospace"] {
  font-family: 'JetBrains Mono', monospace !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   22 · INSPECTION SURFACES — readability in light mode
   The inspection item rows were originally styled for dark mode with
   hardcoded colours (#e6dfd1 for text, #1a1611 for inputs). The JS
   render path was rewritten to use var() references, but these
   selectors pin down the surface so future dev additions can't
   accidentally regress.
   ═══════════════════════════════════════════════════════════════════════ */

body.light-mode .insp-item {
  background: var(--surface) !important;
  border-color: var(--border) !important;
}

body.light-mode .insp-name {
  color: var(--text) !important;
}

/* Traffic-light indicators — square per Service Manual aesthetic.
   The button is a square with an inner filled square; colour shows state.
   iPad fixes mirrored from the base shopnc.css rule — 44px touch target,
   hover gated to hover-capable pointers (so iOS doesn't double-tap), and
   touch-action: manipulation for instant taps. See shopnc.css comment for
   the full rationale. */
body.light-mode .insp-tl-btn {
  border-radius: 0 !important;
  background: var(--surface3) !important;
  border: 2px solid var(--border) !important;
  width: 44px;
  height: 44px;
  font-size: 0 !important;  /* kill any emoji characters inside */
  position: relative;
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(232,85,32,0.25);
  user-select: none;
  -webkit-user-select: none;
}
body.light-mode .insp-tl-btn::before {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: 0;
  background: var(--text-dim);
  opacity: 0.35;
  transition: opacity .15s, transform .15s, background .15s;
}
/* Hover effect only for hover-capable pointers (mouse/trackpad) — gating
   prevents the iOS Safari "first tap = hover, second tap = click" issue
   that made every traffic light require a double-tap on the iPad. */
@media (hover: hover) and (pointer: fine) {
  body.light-mode .insp-tl-btn:hover::before {
    opacity: 0.55;
    transform: scale(1.05);
  }
}
/* Pressed state — fires on every device, instant visual confirmation. */
body.light-mode .insp-tl-btn:active::before {
  opacity: 0.7;
  transform: scale(0.95);
}
body.light-mode .insp-tl-btn.active-red {
  background: var(--red-dim) !important;
  border-color: var(--red) !important;
}
body.light-mode .insp-tl-btn.active-red::before {
  background: var(--red);
  opacity: 1;
}
body.light-mode .insp-tl-btn.active-amber {
  background: var(--gold-dim) !important;
  border-color: var(--gold) !important;
}
body.light-mode .insp-tl-btn.active-amber::before {
  background: var(--gold);
  opacity: 1;
}
body.light-mode .insp-tl-btn.active-green {
  background: var(--green-dim) !important;
  border-color: var(--green) !important;
}
body.light-mode .insp-tl-btn.active-green::before {
  background: var(--green);
  opacity: 1;
}
body.light-mode .insp-tl-btn.active-blue {
  background: rgba(61,109,163,0.12) !important;
  border-color: var(--purple) !important;
}
body.light-mode .insp-tl-btn.active-blue::before {
  background: var(--purple);
  opacity: 1;
}

/* N/A pill — light-mode override. Needs:
   - font-size restored (the base light-mode .insp-tl-btn rule sets
     font-size:0 to kill emoji content inside circles)
   - the ::before coloured-dot pseudo suppressed (no dot for a label
     pill)
   - width unpinned so the "N/A" label can fit horizontally */
body.light-mode .insp-tl-btn-na {
  width: auto !important;
  min-width: 48px;
  padding: 0 10px;
  font-size: 11px !important;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--text-muted) !important;
  background: var(--surface3) !important;
  border: 2px solid var(--border) !important;
}
body.light-mode .insp-tl-btn-na::before {
  display: none !important;
}
body.light-mode .insp-tl-btn-na.active-na {
  background: var(--surface2) !important;
  border-color: var(--text-muted) !important;
  color: var(--ink) !important;
}

/* Buttons in the inspection header strip — ALL OK, ADD ITEM — square edges */
body.light-mode .insp-stage-head .btn,
body.light-mode .insp-stage-head button,
body.light-mode button[onclick*="inspAllOk"],
body.light-mode button[onclick*="inspAddItem"],
body.light-mode button[onclick*="insp"] {
  border-radius: 0 !important;
}

/* Stage progress strip icons (kill leftover emoji in stage tabs) */
body.light-mode .insp-stage-nav .stage-icon,
body.light-mode .stage-nav-item .stage-icon {
  display: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   25 · DIARY · REDESIGNED (Phase 2 — DS-compliant)
   ───────────────────────────────────────────────────────────────────────
   New scoped class set: .d2-* on the diary view. Replaces the legacy
   .diary-day-col / .diary-day-header / .diary-cap / .booking-block /
   .diary-block-slim / .dl-* rules. Renders only when the new structure
   is in place — old rules above remain harmless if any other view still
   references them.
   ═══════════════════════════════════════════════════════════════════════ */

/* Toolbar */
body.light-mode .d2-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
body.light-mode .d2-range {
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  min-width: 240px;
  text-align: center;
  color: var(--ink);
}
body.light-mode .d2-shop-cap {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
body.light-mode .d2-shop-cap .v {
  color: var(--ink);
  font-size: 12px;
}
body.light-mode .d2-shop-cap .bar {
  width: 90px; height: 4px; background: var(--bg-deep);
  position: relative; overflow: hidden;
}
body.light-mode .d2-shop-cap .bar > span {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--ok);
}
body.light-mode .d2-shop-cap .bar > span.warn   { background: var(--warn); }
body.light-mode .d2-shop-cap .bar > span.danger { background: var(--danger); }

/* Segmented (Week/Day) — uses DS .segmented from shopnc-design-system.html
   Add the rules here so they render in production (the DS doc only
   defines them as reference). */
body.light-mode .segmented {
  display: inline-flex;
  border: 1px solid var(--rule-bright);
}
body.light-mode .segmented button {
  background: transparent;
  border: none;
  border-right: 1px solid var(--rule-bright);
  padding: 7px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  cursor: pointer;
  transition: all 0.12s;
  border-radius: 0;
}
body.light-mode .segmented button:last-child { border-right: none; }
body.light-mode .segmented button:hover {
  color: var(--ink);
  background: var(--bg-deep);
}
body.light-mode .segmented button.active {
  background: var(--amber);
  color: #fff;
}

/* Week strip */
body.light-mode .d2-week {
  display: grid;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  margin-bottom: 22px;
}
body.light-mode .d2-week.cols-5 { grid-template-columns: repeat(5, 1fr); }
body.light-mode .d2-week.cols-7 { grid-template-columns: repeat(7, 1fr); }
body.light-mode .d2-day {
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: background 0.12s;
  min-height: 160px;
}
body.light-mode .d2-day:last-child { border-right: none; }
body.light-mode .d2-day:hover { background: var(--bg-panel); }
body.light-mode .d2-day.selected { background: var(--amber-soft); }

/* Day header */
body.light-mode .d2-day-head {
  padding: 10px 12px;
  background: var(--bg-deep);
  border-bottom: 1px solid var(--rule);
  position: relative;
}
body.light-mode .d2-day.selected .d2-day-head {
  background: var(--ink);
  border-bottom-color: var(--amber);
}
body.light-mode .d2-day.selected .d2-day-head .d2-dow,
body.light-mode .d2-day.selected .d2-day-head .d2-dom,
body.light-mode .d2-day.selected .d2-day-head .d2-meta {
  color: var(--bg);
}
body.light-mode .d2-day.today .d2-day-head::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--amber);
}
body.light-mode .d2-dow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
body.light-mode .d2-dom {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 30px;
  line-height: 1;
  margin-top: 3px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
body.light-mode .d2-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 7px;
  display: flex;
  align-items: center;
  gap: 6px;
}
body.light-mode .d2-meta .v { color: var(--ink); }
body.light-mode .d2-day.selected .d2-meta .v {
  color: #fff;
  font-weight: 800;
}
body.light-mode .d2-cap-bar {
  height: 3px;
  margin-top: 6px;
  background: var(--bg-panel);
  position: relative;
  overflow: hidden;
}
body.light-mode .d2-day.selected .d2-cap-bar {
  background: rgba(255,255,255,0.15);
}
body.light-mode .d2-cap-bar > span {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--ok);
}
body.light-mode .d2-cap-bar > span.warn   { background: var(--warn); }
body.light-mode .d2-cap-bar > span.danger { background: var(--danger); }

/* Carryover sub-line — appears under the cap-bar on today's tile when
   there's unfinished work brought forward from past days. Compact
   numeric monoline, gold accent, breakdown in muted tone. */
body.light-mode .d2-day-carry {
  margin-top: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
  line-height: 1.3;
  color: var(--ink-mute);
}
body.light-mode .d2-day.selected .d2-day-carry {
  color: rgba(255,255,255,0.85);
}
body.light-mode .d2-day.selected .d2-day-carry > span:first-child {
  color: var(--amber) !important;
}

/* Day body — booking strip */
body.light-mode .d2-day-body {
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}
body.light-mode .d2-bk {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  background: var(--bg-panel);
  border-left: 3px solid var(--ink-mute);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  cursor: pointer;
  transition: all 0.12s;
}
body.light-mode .d2-bk:hover {
  background: var(--bg-raised);
  border-left-color: var(--amber);
}
body.light-mode .d2-day.selected .d2-bk {
  background: rgba(255,255,255,0.6);
}
body.light-mode .d2-bk .t {
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
}
body.light-mode .d2-bk .ty {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 11px;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.light-mode .d2-bk .h {
  font-size: 10px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
/* Booking strip semantic borders */
body.light-mode .d2-bk.diag    { border-left-color: var(--info); }
body.light-mode .d2-bk.rwc     { border-left-color: var(--warn); }
body.light-mode .d2-bk.started { border-left-color: var(--ok); }
body.light-mode .d2-bk.missed  { border-left-color: var(--danger); }
body.light-mode .d2-bk.missed .t { color: var(--danger); }

/* DONE state — booking's linked job is finalised/completed. Kept on the
   diary so the day reads as "here's what happened" rather than vanishing
   into thin air, but visually de-emphasised so it doesn't compete with
   active work for attention. Capacity totals still exclude these
   (computed separately in the day-header math). */
body.light-mode .d2-bk.invoiced {
  border-left-color: var(--ok);
  background: var(--bg-deep);
  opacity: 0.7;
}
body.light-mode .d2-bk.invoiced .ty,
body.light-mode .d2-bk.invoiced .t,
body.light-mode .d2-bk.invoiced .h { color: var(--ink-mute); }
body.light-mode .d2-bk-done-tag {
  display: inline-block;
  padding: 1px 5px;
  margin-left: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ok);
  border: 1px solid var(--ok);
  background: rgba(46,107,60,0.08);
  vertical-align: middle;
}

/* TOW IN state — booking is for a tow-in arrival, time uncertain. The
   booking still has a slot time so it has somewhere to live in the
   calendar grid, but the visual makes clear it's not a scheduled arrival. */
body.light-mode .d2-bk.towin {
  border-left-color: var(--warn);
  background: rgba(160,106,16,0.06);
}
body.light-mode .d2-bk-towin-tag {
  display: inline-block;
  padding: 1px 5px;
  margin-left: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--warn);
  border: 1px solid var(--warn);
  background: rgba(160,106,16,0.1);
  vertical-align: middle;
}

/* Free / empty day */
body.light-mode .d2-free {
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  padding: 18px 0;
  font-weight: 700;
}

/* Detail-list section heads */
body.light-mode .d2-section { margin-bottom: 22px; }
body.light-mode .d2-section-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  position: relative;
}
body.light-mode .d2-section-head::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 60px;
  height: 2px;
  background: var(--amber);
}
body.light-mode .d2-section.warn   .d2-section-head::after { background: var(--warn); }
body.light-mode .d2-section.danger .d2-section-head::after { background: var(--danger); }
body.light-mode .d2-section.ok     .d2-section-head::after { background: var(--ok); }
body.light-mode .d2-section.info   .d2-section-head::after { background: var(--info); }

body.light-mode .d2-section-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #fff;
  background: var(--amber);
  padding: 2px 8px 3px;
}
body.light-mode .d2-section.warn   .d2-section-num { background: var(--warn); }
body.light-mode .d2-section.danger .d2-section-num { background: var(--danger); }
body.light-mode .d2-section.ok     .d2-section-num { background: var(--ok); }
body.light-mode .d2-section.info   .d2-section-num { background: var(--info); }

body.light-mode .d2-section-title {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}
body.light-mode .d2-section-meta {
  margin-left: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
body.light-mode .d2-section-meta .v { color: var(--ink); font-weight: 700; }
body.light-mode .d2-section-meta .danger { color: var(--danger); font-weight: 700; }

/* Row container */
body.light-mode .d2-rows {
  border: 1px solid var(--rule);
  border-top: none;
  background: var(--bg-raised);
}
body.light-mode .d2-row {
  display: grid;
  grid-template-columns: 64px 4px auto minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
  transition: background 0.1s;
}
body.light-mode .d2-row:last-child { border-bottom: none; }
body.light-mode .d2-row:hover { background: var(--bg-panel); }
body.light-mode .d2-row.warn   { border-left: 3px solid var(--warn);   padding-left: 13px; }
body.light-mode .d2-row.danger { border-left: 3px solid var(--danger); padding-left: 13px; }
body.light-mode .d2-row.ok     { border-left: 3px solid var(--ok);     padding-left: 13px; }
body.light-mode .d2-row.alert  { border-left: 3px solid var(--amber);  padding-left: 13px; }
body.light-mode .d2-row.info   { border-left: 3px solid var(--info);   padding-left: 13px; }
/* Done — booking's linked job has finalised/completed/cancelled. Keeps
   the row visible so the day's history isn't erased, but muted so the
   eye skips it when scanning for actionable work. */
body.light-mode .d2-row.done {
  background: var(--bg-deep);
  opacity: 0.7;
}
body.light-mode .d2-row.done:hover {
  background: var(--bg-panel);
  opacity: 1;
}
/* Tow-in — arrival time uncertain, additional context likely in notes. */
body.light-mode .d2-row.towin {
  background: rgba(160,106,16,0.05);
}

/* Legacy booking-detail-row used by viewBooking() modal. Without these
   light-mode overrides the modal falls through to the original dark
   TV-mode styling and looks misplaced against the rest of the app.
   Same visual language as .d2-row: cream tone, dark ink, mono labels. */
body.light-mode .booking-detail-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 13px;
  color: var(--ink);
}
body.light-mode .booking-detail-row:last-child { border-bottom: none; }
body.light-mode .bdr-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-mute);
  width: 110px;
  flex-shrink: 0;
  margin-top: 2px;
}

/* Row pieces */
body.light-mode .d2-time {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-align: center;
  line-height: 1.2;
}
body.light-mode .d2-time .sub {
  display: block;
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-mute);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 3px;
}
body.light-mode .d2-row.danger .d2-time { color: var(--danger); }
body.light-mode .d2-row.danger .d2-time .sub { color: var(--danger); }
body.light-mode .d2-row.warn   .d2-time .sub { color: var(--warn); }

body.light-mode .d2-tech-stripe {
  width: 4px;
  height: 40px;
  background: var(--ink-dim);
}

body.light-mode .d2-body { min-width: 0; }
body.light-mode .d2-cust {
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--ink);
  margin-bottom: 3px;
  letter-spacing: 0.01em;
}
body.light-mode .d2-sub {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  color: var(--ink-soft);
  font-weight: 500;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
body.light-mode .d2-sub .sep { color: var(--ink-dim); }
body.light-mode .d2-aux {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--warn);
  letter-spacing: 0.04em;
  margin-top: 5px;
}
body.light-mode .d2-aux.info { color: var(--info); }
body.light-mode .d2-aux.norm { color: var(--ink-mute); }

body.light-mode .d2-money {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 18px;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  text-align: right;
  min-width: 76px;
}
body.light-mode .d2-money.ok { color: var(--ok); }

body.light-mode .d2-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}

/* "Days in shop" tile */
body.light-mode .d2-days {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 26px;
  line-height: 1;
  color: var(--warn);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
body.light-mode .d2-days.danger { color: var(--danger); }
body.light-mode .d2-days .lbl {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 5px;
}

/* State column (replaces emoji) */
body.light-mode .d2-state {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.4;
  width: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  color: var(--ink-mute);
}
body.light-mode .d2-state.warn   { color: var(--warn); }
body.light-mode .d2-state.ok     { color: var(--ok); }
body.light-mode .d2-state.danger { color: var(--danger); }

/* Type pill */
body.light-mode .d2-type {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 3px 8px;
  border: 1px solid var(--rule-bright);
  color: var(--ink-mute);
  white-space: nowrap;
}
body.light-mode .d2-type.diag { color: var(--info); border-color: var(--info); }
body.light-mode .d2-type.svc  { color: var(--ink); }
body.light-mode .d2-type.rwc  { color: var(--warn); border-color: var(--warn); }
body.light-mode .d2-type.major{ color: var(--danger); border-color: var(--danger); }
body.light-mode .d2-type.repair{ color: var(--ink); }

/* Job number chip */
body.light-mode .d2-jobnum {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
}

/* Return pill — outlined mono, ↩ icon prefix, colour by urgency.
   Mirrors dueOutBadge() output but renders via class so the diary
   can swap colour with row state without inline-style soup. */
body.light-mode .d2-return {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
  white-space: nowrap;
}
body.light-mode .d2-return::before {
  content: '↩';
  font-size: 11px;
  opacity: 0.85;
}
body.light-mode .d2-return.waiting   { color: var(--danger); }
body.light-mode .d2-return.same-day  { color: var(--info); }
body.light-mode .d2-return.eod       { color: var(--ink-mute); }
body.light-mode .d2-return.next-am   { color: var(--info); }
body.light-mode .d2-return.next-pm   { color: var(--warn); }
body.light-mode .d2-return.norush    { color: var(--ok); }
body.light-mode .d2-return.call      { color: var(--amber); }
body.light-mode .d2-return.timed     { color: var(--info); }
body.light-mode .d2-return.nextday   { color: var(--info); }

/* DS pill (mono outlined) — used for status next to row */
body.light-mode .d2-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
  color: var(--ink-mute);
}
body.light-mode .d2-pill.ok     { color: var(--ok); }
body.light-mode .d2-pill.warn   { color: var(--warn); }
body.light-mode .d2-pill.alert  { color: var(--amber); }
body.light-mode .d2-pill.danger { color: var(--danger); }
body.light-mode .d2-pill.info   { color: var(--info); }

body.light-mode .d2-pill-solid {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: var(--ink-mute);
  color: var(--bg);
}
body.light-mode .d2-pill-solid.ok     { background: var(--ok);     color: #fff; }
body.light-mode .d2-pill-solid.warn   { background: var(--warn);   color: #fff; }
body.light-mode .d2-pill-solid.alert  { background: var(--amber);  color: #fff; }
body.light-mode .d2-pill-solid.danger { background: var(--danger); color: #fff; }

/* LEDs */
body.light-mode .d2-led {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
  background: var(--ink-mute);
}
body.light-mode .d2-led.ok     { background: var(--ok); }
body.light-mode .d2-led.warn   { background: var(--warn); }
body.light-mode .d2-led.alert  { background: var(--amber); }
body.light-mode .d2-led.danger { background: var(--danger); }


/* ═══════════════════════════════════════════════════════════════════════
   26 · JOB CARD — DOCUMENT FORM (.jc-* prefix)
   Replaces the legacy .jd-* / .doc-* job-card markup with a Service-
   Manual aesthetic. Approved mockup: jobcard-conditional.html scenario A.
   Pass 1 ships clean + locked + AQ + rework states. Pass 2 ships the
   four banner types (advisor flag, parts mismatch, approval pending,
   AQ approved) plus the service-history rail.
   ═══════════════════════════════════════════════════════════════════════ */

/* DOC HEAD — ink band + 2-col customer/vehicle pair */
body.light-mode .jc-doc-head {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  margin-bottom: 0;
}
body.light-mode .jc-doc-head-band {
  background: var(--ink);
  color: var(--bg);
  padding: 14px 22px;
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  align-items: center;
  gap: 22px;
  border-bottom: 3px solid var(--amber);
}
body.light-mode .jc-doc-head-band .jc-meta-block {
  display: flex; flex-direction: column; gap: 4px;
}
body.light-mode .jc-doc-head-band .jc-meta-lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255,255,255,0.55);
}
body.light-mode .jc-doc-head-band .jc-meta-val {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 16px;
  color: #fff;
}
body.light-mode .jc-doc-head-band .jc-meta-val.amber { color: var(--amber); }

/* Status pill that sits on the right edge of the band — surfaces high
   priority job state (Action Required, Awaiting Customer, Paid·Locked) */
body.light-mode .jc-doc-state {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid;
}
body.light-mode .jc-doc-state.danger { color: var(--danger); border-color: var(--danger); background: rgba(168,48,26,0.18); }
body.light-mode .jc-doc-state.warn   { color: var(--warn); border-color: var(--warn); background: rgba(160,106,16,0.18); }
body.light-mode .jc-doc-state.alert  { color: var(--amber); border-color: var(--amber); background: rgba(217,72,21,0.18); }
body.light-mode .jc-doc-state.ok     { color: var(--ok); border-color: var(--ok); background: rgba(46,107,60,0.20); }
body.light-mode .jc-doc-state.info   { color: #99c2ee; border-color: #99c2ee; background: rgba(58,90,122,0.30); }

/* 2-col customer + vehicle pair */
body.light-mode .jc-doc-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
body.light-mode .jc-doc-cell {
  padding: 18px 22px;
  border-right: 1px solid var(--rule);
  position: relative;
}
body.light-mode .jc-doc-cell:last-child { border-right: none; }
body.light-mode .jc-doc-cell-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--amber);
  text-transform: uppercase;
  margin-bottom: 8px;
}
body.light-mode .jc-doc-cell-name {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 20px;
  color: var(--ink);
  letter-spacing: 0.01em;
  margin-bottom: 8px;
}
body.light-mode .jc-doc-cell-name .muted {
  font-weight: 500; color: var(--ink-mute);
  font-size: 14px; margin-left: 8px;
}
body.light-mode .jc-doc-cell-row {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 6px 12px;
  font-size: 13px;
  margin-bottom: 4px;
}
body.light-mode .jc-doc-cell-row .k {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--ink-mute);
  text-transform: uppercase;
  align-self: center;
}
body.light-mode .jc-doc-cell-row .v {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px; color: var(--ink); font-weight: 500;
}
body.light-mode .jc-doc-cell-row .v .mono {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
}
body.light-mode .jc-doc-cell-edit {
  position: absolute; top: 12px; right: 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-mute);
  border: 1px solid var(--rule);
  padding: 4px 8px;
  cursor: pointer;
  background: var(--bg-panel);
}
body.light-mode .jc-doc-cell-edit:hover { color: var(--amber); border-color: var(--amber); }


/* CONTROL PANEL — Save | Status | Tech | Type | Due | Internal | Total */
body.light-mode .jc-ctrl-panel {
  background: var(--bg-deep);
  border: 1px solid var(--rule);
  border-top: none;
  display: flex;
  align-items: stretch;
  flex-wrap: nowrap;
}
body.light-mode .jc-ctrl-panel .jc-ctrl-cell {
  flex: 1 1 0;
  min-width: 0;
}
body.light-mode .jc-ctrl-panel .jc-ctrl-cell.jc-save,
body.light-mode .jc-ctrl-panel .jc-ctrl-cell.jc-total {
  flex: 0 0 auto;
}
body.light-mode .jc-ctrl-cell {
  padding: 12px 18px 14px;
  border-right: 1px solid var(--rule);
  display: flex; flex-direction: column;
  gap: 6px; justify-content: center;
  min-width: 0;
  min-height: 80px;
  position: relative;
}
body.light-mode .jc-ctrl-cell:last-child { border-right: none; }
body.light-mode .jc-ctrl-cell .lbl,
body.light-mode .jc-ctrl-cell label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
  white-space: nowrap;
  /* Constrain to the cell width — without these, labels with longer
     strings ("Assigned Technician", "Internal Job Type") spilled over
     into adjacent cells because nowrap + 0.18em letter-spacing made
     them wider than the cell. Tightened letter-spacing too (0.18→0.14)
     to give a little more headroom before truncation kicks in. */
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
body.light-mode .jc-ctrl-cell select,
body.light-mode .jc-ctrl-cell input {
  font-family: 'JetBrains Mono', monospace;
  font-size: 17px; font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: transparent;
  border: none; outline: none;
  padding: 6px 0; cursor: pointer;
  text-transform: uppercase;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-mute) 50%), linear-gradient(135deg, var(--ink-mute) 50%, transparent 50%);
  background-position: calc(100% - 10px) 60%, calc(100% - 5px) 60%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 24px;
  width: 100%;
  text-overflow: ellipsis;
  line-height: 1.2;
}
body.light-mode .jc-ctrl-cell select:focus { color: var(--amber); }
/* Hover the whole cell to telegraph that clicking ANYWHERE in the cell
   opens the dropdown — wider click target than just the select arrow */
body.light-mode .jc-ctrl-cell:hover:not(.jc-save):not(.jc-total) {
  background: rgba(0,0,0,0.025);
}

/* Read-only display value (used for due-out pill, internal-job-type pill) */
body.light-mode .jc-ctrl-cell .jc-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  color: var(--ink-mute);
  align-self: flex-start;
  cursor: pointer;
  background: transparent;
  line-height: 1.1;
}
body.light-mode .jc-ctrl-cell .jc-pill:hover { background: rgba(0,0,0,0.04); }
body.light-mode .jc-ctrl-cell .jc-pill.ok    { color: var(--ok); }
body.light-mode .jc-ctrl-cell .jc-pill.warn  { color: var(--warn); }
body.light-mode .jc-ctrl-cell .jc-pill.alert { color: var(--amber); }
body.light-mode .jc-ctrl-cell .jc-pill.danger{ color: var(--danger); }
body.light-mode .jc-ctrl-cell .jc-pill.info  { color: var(--info); }

/* Solid pill — used for rectification chip */
body.light-mode .jc-ctrl-cell .jc-pill.solid {
  background: var(--ink-mute); color: #fff;
  border-color: transparent;
  font-weight: 800;
}
body.light-mode .jc-ctrl-cell .jc-pill.solid.warranty { background: var(--info); }
body.light-mode .jc-ctrl-cell .jc-pill.solid.rework   { background: var(--warn); }
body.light-mode .jc-ctrl-cell .jc-pill.solid.comeback { background: var(--danger); }
body.light-mode .jc-ctrl-cell .jc-pill.solid.since    { background: var(--ok); }

/* Save cell — full amber tile */
body.light-mode .jc-ctrl-cell.jc-save {
  background: var(--amber);
  border-right: 1px solid var(--amber-deep);
  display: flex; align-items: center; justify-content: center;
  padding: 0 36px;
  cursor: pointer; transition: background 0.12s;
  min-height: 80px;
}
body.light-mode .jc-ctrl-cell.jc-save:hover { background: var(--amber-deep); }
body.light-mode .jc-ctrl-cell.jc-save .jc-save-text {
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px; font-weight: 800;
  letter-spacing: 0.2em;
  color: #fff; text-transform: uppercase;
}

/* Total cell — inverted ink */
body.light-mode .jc-ctrl-cell.jc-total {
  background: var(--ink);
  padding: 12px 26px 14px;
  min-height: 80px;
}
body.light-mode .jc-ctrl-cell.jc-total .lbl {
  color: rgba(255,255,255,0.6);
  font-size: 12px;
}
body.light-mode .jc-ctrl-cell.jc-total .v {
  font-family: 'Archivo', sans-serif;
  font-size: 30px; font-weight: 800;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
body.light-mode .jc-ctrl-cell.jc-total .v.ok { color: #5fb96e; }
body.light-mode .jc-ctrl-cell.jc-total .ex {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: rgba(255,255,255,0.5);
  letter-spacing: 0.1em; text-transform: uppercase;
}

/* When locked, the controls panel becomes read-only (greyed out, no hover) */
body.light-mode .jc-ctrl-panel.locked {
  opacity: 0.78;
  pointer-events: none;
}
body.light-mode .jc-ctrl-panel.locked .jc-save { display: none; }


/* STAT STRIP — Tech Time / Margin / Parts Status / Workflow */
body.light-mode .jc-stat-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-top: none;
  margin-bottom: 16px;
}
body.light-mode .jc-stat-cell {
  padding: 14px 20px;
  border-right: 1px solid var(--rule);
  border-left: 3px solid transparent;
  min-height: 88px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
body.light-mode .jc-stat-cell:last-child { border-right: none; }
body.light-mode .jc-stat-cell.ok    { border-left-color: var(--ok); }
body.light-mode .jc-stat-cell.warn  { border-left-color: var(--warn); }
body.light-mode .jc-stat-cell.alert { border-left-color: var(--amber); }
body.light-mode .jc-stat-cell.info  { border-left-color: var(--info); }
body.light-mode .jc-stat-cell.danger{ border-left-color: var(--danger); }
body.light-mode .jc-stat-cell .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 7px;
}
body.light-mode .jc-stat-cell .val {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 26px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  display: flex; align-items: baseline; gap: 10px;
}
body.light-mode .jc-stat-cell .val.ok     { color: var(--ok); }
body.light-mode .jc-stat-cell .val.amber  { color: var(--amber); }
body.light-mode .jc-stat-cell .val.warn   { color: var(--warn); }
body.light-mode .jc-stat-cell .val.danger { color: var(--danger); }
body.light-mode .jc-stat-cell .val .sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; color: var(--ink-mute);
  font-weight: 700; letter-spacing: 0.04em;
}
body.light-mode .jc-stat-cell .actions { display: flex; gap: 6px; margin-top: 10px; }
body.light-mode .jc-stat-cell .actions .btn,
body.light-mode .jc-stat-cell .actions button {
  padding: 7px 12px;
  font-size: 11px;
  letter-spacing: 0.12em;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  text-transform: uppercase;
  border: 1px solid var(--rule-bright);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
}
body.light-mode .jc-stat-cell .actions .btn.primary {
  background: var(--amber); color: #fff; border-color: var(--amber);
}
body.light-mode .jc-stat-cell .actions .btn.primary:hover { background: var(--amber-deep); }
body.light-mode .jc-stat-cell .actions .btn:hover { border-color: var(--amber); color: var(--amber); }


/* NOTES BLOCK — Repair Request / Notes */
body.light-mode .jc-notes-block {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  padding: 20px 24px;
  margin-bottom: 16px;
}
body.light-mode .jc-notes-block .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 12px;
}
body.light-mode .jc-notes-block textarea {
  width: 100%;
  border: 1px solid var(--rule);
  background: var(--bg-panel);
  padding: 14px 16px;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 16px; color: var(--ink); font-weight: 500;
  resize: vertical; min-height: 96px;
  outline: none;
  line-height: 1.55;
  letter-spacing: 0.01em;
}
body.light-mode .jc-notes-block textarea:focus { border-color: var(--amber); }


/* CUSTOMER ACTIONS strip */
body.light-mode .jc-cust-actions {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
  background: var(--bg-deep);
  border: 1px solid var(--rule);
  padding: 14px 20px;
  margin-bottom: 16px;
}
body.light-mode .jc-cust-actions .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute);
  margin-right: 8px;
  white-space: nowrap;
}
body.light-mode .jc-cust-actions button {
  padding: 9px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  border: 1px solid var(--rule);
  background: var(--bg-raised);
  color: var(--ink-mute);
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.12s;
}
body.light-mode .jc-cust-actions button:hover {
  color: var(--ink);
  border-color: var(--rule-bright);
  background: var(--bg-panel);
}
body.light-mode .jc-cust-actions button.ok    { color: var(--ok); border-color: var(--ok); }
body.light-mode .jc-cust-actions button.ok:hover { background: var(--ok); color: #fff; }
body.light-mode .jc-cust-actions button.info  { color: var(--info); border-color: var(--info); }
body.light-mode .jc-cust-actions button.info:hover { background: var(--info); color: #fff; }
body.light-mode .jc-cust-actions button.alert { color: var(--amber); border-color: var(--amber); }
body.light-mode .jc-cust-actions button.alert:hover { background: var(--amber); color: #fff; }


/* AQ BUTTON — dashed when no AQ exists */
body.light-mode .jc-add-quote-btn {
  display: block; width: 100%;
  padding: 14px;
  background: transparent;
  border: 1px dashed var(--info);
  color: var(--info);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer;
  margin-bottom: 16px;
}
body.light-mode .jc-add-quote-btn:hover { background: var(--info-soft, rgba(58,90,122,0.08)); }


/* INSPECTION BLOCK */
body.light-mode .jc-inspect-block {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  margin-bottom: 16px;
}
body.light-mode .jc-inspect-head {
  background: var(--bg-deep);
  padding: 10px 18px;
  display: flex; align-items: center; gap: 14px;
  border-bottom: 1px solid var(--rule);
}
body.light-mode .jc-inspect-head .title {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 13px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink);
}
body.light-mode .jc-inspect-head .meta {
  margin-left: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-mute);
}
body.light-mode .jc-inspect-body {
  padding: 14px 18px;
}


/* SECTION CARD — numbered ink head, amber tag */
body.light-mode .jc-sec-card {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  margin-bottom: 16px;
}
body.light-mode .jc-sec-card.locked {
  opacity: 0.92;
}
body.light-mode .jc-sec-head {
  background: var(--ink);
  color: var(--bg);
  padding: 12px 18px;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 16px;
}
body.light-mode .jc-sec-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.2em;
  background: var(--amber);
  color: #fff;
  padding: 3px 8px 4px;
}
body.light-mode .jc-sec-num.warn { background: var(--warn); }
body.light-mode .jc-sec-num.info { background: var(--info); }
body.light-mode .jc-sec-num.danger { background: var(--danger); }
body.light-mode .jc-sec-num.ok { background: var(--ok); }
body.light-mode .jc-sec-title {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 14px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: #fff;
}
body.light-mode .jc-sec-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: rgba(255,255,255,0.55);
}
body.light-mode .jc-sec-meta .v { color: #fff; font-weight: 700; margin-left: 4px; }
body.light-mode .jc-sec-total {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 18px;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
}
body.light-mode .jc-sec-total.warn { color: var(--warn); }
body.light-mode .jc-sec-actions { display: flex; gap: 6px; }
body.light-mode .jc-sec-actions .jc-btn-add {
  background: var(--amber);
  color: #fff; border: none;
  padding: 5px 11px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer;
}
body.light-mode .jc-sec-actions .jc-btn-add:hover { background: var(--amber-deep); }
body.light-mode .jc-sec-actions .jc-btn-add.info { background: var(--info); }
body.light-mode .jc-sec-actions .jc-btn-add.info:hover { background: #2a4560; }


/* TABLES — used inside section cards for labour / parts / consumables / cost recovery */
body.light-mode .jc-tbl {
  width: 100%; border-collapse: collapse;
  font-size: 13px;
  background: var(--bg-raised);
}
body.light-mode .jc-tbl thead th {
  background: var(--bg-deep);
  border-bottom: 2px solid var(--ink);
  padding: 9px 14px;
  text-align: left;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute);
  white-space: nowrap;
}
body.light-mode .jc-tbl thead th.num { text-align: right; }
body.light-mode .jc-tbl thead th.cen { text-align: center; }
body.light-mode .jc-tbl tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--rule);
  vertical-align: middle;
}
body.light-mode .jc-tbl tbody tr:last-child td { border-bottom: none; }
body.light-mode .jc-tbl tbody tr:hover { background: var(--bg-panel); }
body.light-mode .jc-tbl tbody tr.locked:hover { background: transparent; }
body.light-mode .jc-tbl td.code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  color: var(--info);
}
body.light-mode .jc-tbl td.num {
  font-family: 'JetBrains Mono', monospace;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
body.light-mode .jc-tbl td.cen { text-align: center; }
body.light-mode .jc-tbl td.num.total {
  font-weight: 700; color: var(--ink);
}

/* In-table inputs (only when unlocked) */
body.light-mode .jc-row-input {
  background: var(--bg-panel);
  border: 1px solid var(--rule);
  padding: 7px 10px;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 13px;
  color: var(--ink);
  width: 100%;
  outline: none;
}
body.light-mode .jc-row-input.mono { font-family: 'JetBrains Mono', monospace; }
body.light-mode .jc-row-input:focus { border-color: var(--amber); }

body.light-mode .jc-row-x {
  background: transparent;
  border: 1px solid var(--rule);
  width: 26px; height: 26px;
  font-family: 'JetBrains Mono', monospace;
  color: var(--ink-mute);
  cursor: pointer; font-weight: 700;
  line-height: 1;
}
body.light-mode .jc-row-x:hover { color: var(--danger); border-color: var(--danger); }


/* STOCK CHIP — green/amber/red indicator on parts row */
body.light-mode .jc-stock-chip {
  display: inline-flex; align-items: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ok);
  padding: 2px 7px;
  border: 1px solid var(--ok);
  background: rgba(46,107,60,0.08);
}
body.light-mode .jc-stock-chip.warn   { color: var(--warn); border-color: var(--warn); background: rgba(160,106,16,0.10); }
body.light-mode .jc-stock-chip.danger { color: var(--danger); border-color: var(--danger); background: rgba(168,48,26,0.08); }


/* FOOT BLOCKS — audit trail / arrival report (collapsed) */
body.light-mode .jc-foot-block {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  margin-bottom: 12px;
}
body.light-mode .jc-foot-block.ok { border-left: 3px solid var(--ok); }
body.light-mode .jc-foot-block .head {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 18px;
  cursor: pointer;
}
body.light-mode .jc-foot-block .head .title {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 13px;
  letter-spacing: 0.06em; text-transform: uppercase;
}
body.light-mode .jc-foot-block.ok .head .title { color: var(--ok); }
body.light-mode .jc-foot-block .head .meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-mute);
  display: flex;
  align-items: center;
  gap: 8px;
}
body.light-mode .jc-foot-block .head .arr {
  margin-left: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--ink-mute);
  letter-spacing: 0.12em;
}
body.light-mode .jc-foot-block .body {
  border-top: 1px solid var(--rule);
  padding: 14px 18px;
  background: var(--bg-panel);
}


/* LOCK BANNER — replaces nothing, sits ABOVE the doc head when finalised */
body.light-mode .jc-lock-banner {
  background: var(--ink);
  color: var(--bg);
  border: none;
  border-left: 3px solid var(--ok);
  margin-bottom: 10px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 18px;
  padding: 14px 22px;
}
body.light-mode .jc-lock-banner.unlocked { border-left-color: var(--warn); }
body.light-mode .jc-lock-banner .tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.2em; text-transform: uppercase;
  background: var(--ok);
  color: #fff;
  padding: 3px 9px 4px;
}
body.light-mode .jc-lock-banner.unlocked .tag { background: var(--warn); }
body.light-mode .jc-lock-banner .body strong {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  letter-spacing: 0.04em;
  font-size: 14px;
  text-transform: uppercase;
  margin-right: 8px;
}
body.light-mode .jc-lock-banner .body .sub {
  display: block;
  margin-top: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.04em;
}
body.light-mode .jc-lock-banner .body .pay {
  color: var(--bg);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
}
body.light-mode .jc-lock-banner .body .pay .ok { color: #5fb96e; }
body.light-mode .jc-lock-banner .body .pay .warn { color: #e0aa3a; }
body.light-mode .jc-lock-banner button {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.25);
  color: var(--bg);
  padding: 7px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  cursor: pointer;
}
body.light-mode .jc-lock-banner button:hover {
  background: rgba(255,255,255,0.15);
  border-color: rgba(255,255,255,0.45);
}


/* RECTIFICATION BANNER — danger-toned, sits above doc head when j.rectificationType is set */
body.light-mode .jc-rect-banner {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--danger);
  margin-bottom: 10px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 11px 16px;
}
body.light-mode .jc-rect-banner.warranty { border-left-color: var(--info); }
body.light-mode .jc-rect-banner.rework   { border-left-color: var(--warn); }
body.light-mode .jc-rect-banner.since    { border-left-color: var(--ok); }

body.light-mode .jc-rect-banner .tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.2em; text-transform: uppercase;
  background: var(--danger);
  color: #fff;
  padding: 3px 9px 4px;
}
body.light-mode .jc-rect-banner.warranty .tag { background: var(--info); }
body.light-mode .jc-rect-banner.rework   .tag { background: var(--warn); }
body.light-mode .jc-rect-banner.since    .tag { background: var(--ok); }

body.light-mode .jc-rect-banner .msg {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  color: var(--ink);
}
body.light-mode .jc-rect-banner .msg strong {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 13px;
  margin-right: 8px;
  color: var(--danger);
}
body.light-mode .jc-rect-banner.warranty .msg strong { color: var(--info); }
body.light-mode .jc-rect-banner.rework   .msg strong { color: var(--warn); }
body.light-mode .jc-rect-banner.since    .msg strong { color: var(--ok); }
body.light-mode .jc-rect-banner .msg .sub {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--ink-mute);
  letter-spacing: 0.04em;
  margin-top: 3px;
}
body.light-mode .jc-rect-banner .actions { display: flex; gap: 6px; }
body.light-mode .jc-rect-banner .actions button {
  padding: 6px 11px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  border: 1px solid var(--rule);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
}
body.light-mode .jc-rect-banner .actions button:hover { border-color: var(--amber); color: var(--amber); }


/* AQ PANEL — Additional Work Quote (slate-blue toned) */
body.light-mode .jc-aq-panel {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--info);
  margin-bottom: 16px;
}
body.light-mode .jc-aq-head {
  background: rgba(58,90,122,0.08);
  border-bottom: 1px solid var(--rule);
  padding: 11px 18px;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 14px;
  cursor: pointer;
}
body.light-mode .jc-aq-head:hover { background: rgba(58,90,122,0.14); }
body.light-mode .jc-aq-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.18em;
  background: var(--info);
  color: #fff;
  padding: 2px 8px 3px;
}
body.light-mode .jc-aq-title {
  font-family: 'Archivo', sans-serif;
  font-weight: 800; font-size: 14px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--info);
}
body.light-mode .jc-aq-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 3px 9px 4px;
  border: 1px solid currentColor;
}
body.light-mode .jc-aq-status.warn   { color: var(--warn); }
body.light-mode .jc-aq-status.ok     { color: var(--ok); }
body.light-mode .jc-aq-status.danger { color: var(--danger); }
body.light-mode .jc-aq-item-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--rule);
}
body.light-mode .jc-aq-item-row:last-child { border-bottom: none; }
body.light-mode .jc-aq-item-status {
  width: 28px; height: 28px;
  display: inline-flex;
  align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px; font-weight: 800;
  border: 1px solid currentColor;
  color: var(--warn);
  letter-spacing: 0;
}
body.light-mode .jc-aq-item-status.r  { color: var(--danger); border-color: var(--danger); }
body.light-mode .jc-aq-item-status.a  { color: var(--warn); border-color: var(--warn); }
body.light-mode .jc-aq-item-status.i  { color: var(--info); border-color: var(--info); }
body.light-mode .jc-aq-item-status.ok { background: var(--ok); color: #fff; border-color: var(--ok); }
body.light-mode .jc-aq-item-status.dx { background: var(--ink-mute); color: #fff; border-color: var(--ink-mute); }
body.light-mode .jc-aq-item-name {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px; font-weight: 600;
  color: var(--ink);
}
body.light-mode .jc-aq-item-name.declined {
  text-decoration: line-through;
  color: var(--ink-dim);
  font-weight: 500;
}
body.light-mode .jc-aq-item-name.approved { color: var(--ok); }
body.light-mode .jc-aq-item-name .note {
  display: block;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 12px;
  color: var(--ink-mute);
  font-weight: 400;
  margin-top: 3px;
  text-decoration: none;
}
body.light-mode .jc-aq-item-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  text-align: right;
}
body.light-mode .jc-aq-item-total {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 16px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 90px;
}
body.light-mode .jc-aq-item-total.declined {
  color: var(--ink-dim);
  text-decoration: line-through;
}
body.light-mode .jc-aq-item-total.ok { color: var(--ok); }
body.light-mode .jc-aq-foot {
  background: var(--bg-deep);
  border-top: 2px solid var(--ink);
  padding: 12px 18px;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
body.light-mode .jc-aq-foot-totals {
  display: flex;
  gap: 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  flex-wrap: wrap;
}
body.light-mode .jc-aq-foot-totals .v {
  font-family: 'Archivo', sans-serif;
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
body.light-mode .jc-aq-foot-totals .v.ok { color: var(--ok); }
body.light-mode .jc-aq-foot-totals .v.info { color: var(--info); }
body.light-mode .jc-aq-foot-totals .v.dim { color: var(--ink-dim); }
body.light-mode .jc-aq-foot .actions { display: flex; gap: 6px; }
body.light-mode .jc-aq-foot .actions button {
  padding: 6px 11px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  border: 1px solid var(--rule);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
}
body.light-mode .jc-aq-foot .actions button:hover { border-color: var(--amber); color: var(--amber); }
body.light-mode .jc-aq-foot .actions button.info {
  background: var(--info); color: #fff; border-color: var(--info);
}
body.light-mode .jc-aq-foot .actions button.info:hover {
  background: #2a4560;
}


/* ═══════════════════════════════════════════════════════════════════════
   27 · LEGACY .doc-* RESKIN — JOB CARD HEADER
   The doc-header markup (used by job, invoice, standalone quote, booking
   quote) is shared. Rather than fork four templates to use new .jc-doc-*
   classes, override the legacy .doc-* classes with the Service-Manual
   aesthetic. New sections (control panel, stat strip, lock banner)
   that don't exist in the legacy markup are emitted with .jc-* classes
   directly from renderJobDetailPage and friends.
   ═══════════════════════════════════════════════════════════════════════ */

/* Wrapper — kill rounded corners, kill the cyan/purple stripe, use ink rule */
body.light-mode .doc-header {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: 0;
  margin-bottom: 0;
  overflow: visible;
  position: relative;
}
body.light-mode .doc-header::before { display: none; }
body.light-mode .doc-header.locked { /* nothing extra; lock banner above carries it */ }

/* ID row — becomes the inverted ink band with amber bottom rule */
body.light-mode .doc-header-id-row {
  background: var(--ink);
  color: var(--bg);
  padding: 14px 22px;
  border-bottom: 3px solid var(--amber);
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
body.light-mode .doc-header-id-row .doc-id {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.72);
  font-weight: 700;
}

/* Plate already handled by the .plate / .plate .locale rules above.
   Force the doc-plate (rendered as <span class="doc-plate">…) to
   inherit the same boarding-pass treatment. */
body.light-mode .doc-header-id-row .doc-plate {
  background: var(--bg);
  color: var(--ink);
  border: none;
  border-radius: 0;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 800;
  font-size: 22px;
  letter-spacing: 0.05em;
  padding: 7px 14px 9px;
  line-height: 1;
}

/* Status badges in the ID row stay solid — but use ink-mute as the muted tone */
body.light-mode .doc-header-id-row .badge {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.2);
  color: rgba(255,255,255,0.85);
}
body.light-mode .doc-header-id-row .badge.b-done {
  background: rgba(46,107,60,0.25);
  border-color: var(--ok);
  color: #5fb96e;
}

/* Spacer pushes ACTIONS_PLACEHOLDER (jdActions) to the right */
body.light-mode .doc-header-id-row .doc-id-row-spacer { flex: 1; min-width: 0; }


/* Doc blocks (customer + vehicle pair) — become the 2-col grid */
body.light-mode .doc-blocks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: none;
  background: var(--bg-raised);
}
body.light-mode .doc-block {
  display: block;
  position: relative;
  /* Right padding reserves space for the absolutely-positioned Edit
     button (84px wide + 16px right offset = ~100px total). Without
     this reservation, fact values flow underneath the button and get
     wrapped mid-word — e.g. "Automatic" rendering as "Automat / ic".
     The 110px gives a comfortable gutter between the longest value
     and the button edge. */
  padding: 18px 110px 18px 22px;
  border-bottom: none;
  border-right: 1px solid var(--rule);
  min-height: 0;
}
body.light-mode .doc-block:last-child { border-right: none; }

body.light-mode .doc-block-label {
  flex: none;
  display: block;
  position: static;
  background: transparent;
  border-right: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--amber);
  text-transform: uppercase;
  margin-bottom: 8px;
  padding: 0;
  text-align: left;
}

body.light-mode .doc-block-body {
  flex: none;
  display: block;
  padding: 0;
}

body.light-mode .doc-block-name {
  font-family: 'Archivo', sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: 0.01em;
  line-height: 1.25;
  margin-bottom: 8px;
}
body.light-mode .doc-block-name:hover { color: var(--amber); }
body.light-mode .doc-block-sub {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-mute);
}

/* Fact row — switch from horizontal flex to a clean key-value list */
body.light-mode .doc-fact-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}
body.light-mode .doc-fact {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 6px 12px;
  font-size: 13px;
  align-items: baseline;
}
body.light-mode .doc-fact-key {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--ink-mute);
  text-transform: uppercase;
}
body.light-mode .doc-fact-val {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  color: var(--ink);
  font-weight: 500;
}
body.light-mode .doc-fact-val a,
body.light-mode a.doc-fact-val {
  color: var(--ink);
  border-bottom: 1px dotted var(--ink-mute);
}
body.light-mode .doc-fact-val a:hover,
body.light-mode a.doc-fact-val:hover {
  color: var(--amber);
  border-bottom-color: var(--amber);
}
body.light-mode .doc-fact-missing {
  font-size: 13px;
  color: var(--ink-dim);
  font-style: italic;
}

/* Edit button — chip in the top-right of each cell.
   Icon stacked over a 2-line "Edit / Customer" or "Edit / Vehicle" label.
   Width was 64px but that's too narrow for "CUSTOMER" at 10px with the
   0.12em letter-spacing — the word wrapped weirdly mid-letter. Bumping
   to 84px gives both labels a comfortable single-line render. */
body.light-mode .doc-block-edit {
  position: absolute;
  top: 14px;
  right: 16px;
  flex: none;
  width: 84px;
  height: 64px;
  min-width: 0;
  align-self: auto;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  background: var(--bg-panel);
  border: 1px solid var(--rule);
  color: var(--ink-mute);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 4px;
  line-height: 1.2;
  text-align: center;
}
body.light-mode .doc-block-edit:hover {
  background: var(--bg-deep);
  border-color: var(--amber);
  color: var(--amber);
}
body.light-mode .doc-block-edit-icon { font-size: 18px; line-height: 1; }
/* Restore the <br> linebreak so "Edit / Customer" stacks vertically */
body.light-mode .doc-block-edit br { display: inline; }
body.light-mode .doc-block-edit > span:not(.doc-block-edit-icon) {
  display: block;
  white-space: nowrap;
  letter-spacing: 0.06em;
}


/* The legacy doc-controls is the OLD inline status/tech/type strip.
   When renderJobDetailPage emits the new .jc-ctrl-panel + .jc-stat-strip,
   the legacy .doc-controls block is gone. Keep these overrides ONLY for
   the standalone-quote / booking-quote paths that still use it. */
body.light-mode .doc-controls {
  background: var(--bg-deep);
  border-top: 1px solid var(--rule);
  border-radius: 0;
  padding: 12px 22px;
}
body.light-mode .doc-controls label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--ink-mute);
  font-weight: 700;
}
body.light-mode .doc-controls select,
body.light-mode .doc-controls input[type=date] {
  background: var(--bg-panel);
  border: 1px solid var(--rule);
  border-radius: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
}
body.light-mode .doc-controls select:focus,
body.light-mode .doc-controls input[type=date]:focus {
  border-color: var(--amber);
  outline: none;
}

/* Doc-control-chip already used by Internal Job Type pill — neutralise legacy
   colours so it inherits ink-mute / amber instead of cyan. */
body.light-mode .doc-control-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
  border-width: 1px;
  padding: 4px 10px;
  background: transparent;
  color: var(--ink-mute);
  border-color: var(--rule);
}
body.light-mode .doc-control-chip:hover { color: var(--amber); border-color: var(--amber); filter: none; }
body.light-mode .doc-control-chip-empty {
  color: var(--ink-mute);
  border-color: var(--rule);
  background: transparent;
}
body.light-mode .doc-control-chip-empty:hover { color: var(--ink); border-color: var(--rule-bright); }


/* ═══════════════════════════════════════════════════════════════════════
   28 · LEGACY .jd-section RESKIN — LABOUR / PARTS / CONSUMABLES / AUDIT
   The labour/parts/consumables/cost-recovery/audit sections all use
   .jd-section / .jd-section-header / .jd-section-title / .jd-section-total
   markup. Restyle them to the new .jc-sec-card aesthetic without
   touching the JS templates.
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
   28 · LEGACY .jd-section RESKIN — LABOUR / PARTS / CONSUMABLES / AUDIT
   ───────────────────────────────────────────────────────────────────────
   The labour/parts/consumables/cost-recovery/audit sections all use
   .jd-section / .jd-section-header / .jd-section-title / .jd-section-total
   markup. Restyle them to align with the design-system numbered-section
   pattern (01 LABOUR / 02 PARTS / 03 CONSUMABLES) — cream raised
   background, JetBrains Mono section labels, amber numbered chip,
   thick amber underline rule, NEVER ink-on-black.
   No JS template changes — we restyle entirely via CSS.
   ═══════════════════════════════════════════════════════════════════════ */

body.light-mode .jd-section {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: 0;
  margin-bottom: 16px;
  overflow: hidden;
}

/* HEADER — cream-on-cream with thick amber underline. Counter-based
   numbering: each consecutive .jd-section inside the doc page gets
   01, 02, 03 etc. Reset at the page-level container so the count
   resets when you switch documents. */
body.light-mode #view-job-detail #job-detail-content,
body.light-mode #view-sq-detail  #sq-detail-content,
body.light-mode #view-quote      #quote-detail-content {
  counter-reset: jdsec;
}
body.light-mode .jd-section-header {
  background: #d4cab3;
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 14px 22px 12px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  position: relative;
  counter-increment: jdsec;
}
/* Amber underline rule — 80px stub, sits flush with the bottom border */
body.light-mode .jd-section-header::after {
  content: '';
  position: absolute;
  left: 22px;
  bottom: -2px;
  width: 80px;
  height: 2px;
  background: var(--amber);
}

/* TITLE — numbered amber chip + uppercase JetBrains Mono label.
   Replaces the inline emoji+colour scheme. */
body.light-mode .jd-section-title {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
/* Numbered chip — uses the page-level counter (01, 02, 03…). The
   pseudo-element renders before the title text. White-on-amber. */
body.light-mode .jd-section-title::before {
  content: counter(jdsec, decimal-leading-zero);
  background: var(--amber);
  color: #fff;
  padding: 3px 8px 4px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.1em;
  line-height: 1;
}
/* Suppress the chip when the title is inside an arrival panel — that's
   an info banner, not a numbered section, and inherited the title
   styling for typography only. Without this it shows whatever counter
   value happened last (typically a duplicate of the audit trail). */
body.light-mode .arrival-panel .jd-section-title::before,
body.light-mode .arrival-locked .jd-section-title::before {
  content: none;
}
/* Hide any inline emoji prefixes the legacy JS still emits inside
   the title (🛢/🔩/⏱/etc). They were an early-prototype affordance
   and clash with the numbered chip. The actual label text after the
   emoji is preserved by the title rule above.
   Achieved by setting font-size on emoji unicode ranges to 0 — but
   that's brittle. Cleaner: trust the JS and just visually quiet
   them via opacity. Better still: the inline `style="color:var(--cyan)"`
   etc. is already overridden below. Emoji noise will be tackled in
   a JS pass once the CSS reskin is approved. */
body.light-mode .jd-section-title[style*="color:var(--cyan)"],
body.light-mode .jd-section-title[style*="color:var(--purple)"],
body.light-mode .jd-section-title[style*="color:var(--orange)"],
body.light-mode .jd-section-title[style*="color:var(--green)"],
body.light-mode .jd-section-title[style*="color:var(--gold)"] {
  color: var(--ink) !important;
}

/* SECTION TOTAL — Archivo numerals, amber, prominent.
   Right-aligned with tabular-nums so dollar amounts stack cleanly
   when sections are scanned vertically. */
body.light-mode .jd-section-total {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 22px;
  font-variant-numeric: tabular-nums;
  color: var(--amber);
  letter-spacing: 0.01em;
}
body.light-mode .jd-section-header .jd-section-total[style*="color:var(--cyan)"],
body.light-mode .jd-section-header .jd-section-total[style*="color:var(--purple)"],
body.light-mode .jd-section-header .jd-section-total[style*="color:var(--orange)"],
body.light-mode .jd-section-header .jd-section-total[style*="color:var(--gold)"] {
  color: var(--amber) !important;
}

/* Header buttons — + Add / Create PO / View POs etc. JetBrains Mono
   uppercase, amber by default for primary (+ Add), ghost for secondary. */
body.light-mode .jd-section-header button {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
  padding: 7px 13px;
  cursor: pointer;
  border: 1px solid var(--rule-bright);
  background: var(--bg-deep);
  color: var(--ink);
  transition: all 0.12s;
}
body.light-mode .jd-section-header button:hover {
  border-color: var(--amber);
  color: var(--amber);
}
/* Primary + Add button — amber-filled. Detected by onclick containing
   "Add" or by the legacy .btn-amber/.btn-add class. */
body.light-mode .jd-section-header button.btn-amber,
body.light-mode .jd-section-header button.btn-add,
body.light-mode .jd-section-header button[onclick*="openLabourPopup"],
body.light-mode .jd-section-header button[onclick*="openPartsPopup"],
body.light-mode .jd-section-header button[onclick*="openConsPopup"],
body.light-mode .jd-section-header button[onclick*="jdAddLabourLine"],
body.light-mode .jd-section-header button[onclick*="jdAddPartsLine"],
body.light-mode .jd-section-header button[onclick*="jdAddConsLine"] {
  background: var(--amber);
  color: #fff;
  border-color: var(--amber);
}
body.light-mode .jd-section-header button.btn-amber:hover,
body.light-mode .jd-section-header button.btn-add:hover,
body.light-mode .jd-section-header button[onclick*="openLabourPopup"]:hover,
body.light-mode .jd-section-header button[onclick*="openPartsPopup"]:hover,
body.light-mode .jd-section-header button[onclick*="openConsPopup"]:hover {
  background: var(--amber-deep);
  border-color: var(--amber-deep);
  color: #fff;
}

/* ─── CUSTOMER & VEHICLE DETAIL — numbered section pattern ──────────────
   Mirrors the job-card pattern above but scoped to .cd-section* classes
   used on the customer detail and vehicle detail screens. Single source
   of truth: same numbered amber chip, same 80px amber rule, same Archivo
   total, same JetBrains Mono caps title. The counter resets per page so
   sections always begin at 01.

   Containers covered:
     #view-customer-detail #customer-detail-content
     #view-vehicle-detail  #vehicle-detail-content

   Suppression rules: the customer detail's first .cd-section is the
   header card with the avatar/name/KPIs, NOT a numbered work section.
   We'd usually suppress its chip, but the customer header doesn't use
   .cd-section anymore (it's a .cd-header div). So nothing to suppress
   here today — every .cd-section IS a real numbered section. */
body.light-mode #view-customer-detail #customer-detail-content,
body.light-mode #view-vehicle-detail  #vehicle-detail-content {
  counter-reset: cdsec;
}
body.light-mode #customer-detail-content .cd-section,
body.light-mode #vehicle-detail-content  .cd-section {
  background: var(--bg-panel) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  overflow: visible !important; /* let amber rule overhang the bottom border */
  margin-bottom: 14px !important;
}
body.light-mode #customer-detail-content .cd-section-header,
body.light-mode #vehicle-detail-content  .cd-section-header {
  background: #d4cab3 !important;
  color: var(--ink) !important;
  border-bottom: 1px solid var(--ink) !important;
  padding: 14px 22px 12px !important;
  display: flex !important;
  align-items: flex-end !important;
  justify-content: space-between !important;
  gap: 16px !important;
  position: relative !important;
  counter-increment: cdsec !important;
}
/* Opt-out: sections with .cd-section-no-num don't increment the counter
   and don't render a number chip. Used for conditional sections (POs,
   Bookings, Quotes) where the count would otherwise jump around as
   data appears and disappears. The "spine" of evergreen sections stays
   01/02/03/... regardless of which conditional blocks are present. */
body.light-mode #customer-detail-content .cd-section.cd-section-no-num .cd-section-header,
body.light-mode #vehicle-detail-content  .cd-section.cd-section-no-num .cd-section-header {
  counter-increment: none !important;
}
body.light-mode #customer-detail-content .cd-section.cd-section-no-num .cd-section-title::before,
body.light-mode #vehicle-detail-content  .cd-section.cd-section-no-num .cd-section-title::before {
  content: none !important;
}
body.light-mode #customer-detail-content .cd-section-header::after,
body.light-mode #vehicle-detail-content  .cd-section-header::after {
  content: '';
  position: absolute;
  left: 22px;
  bottom: -2px;
  width: 80px;
  height: 2px;
  background: var(--amber);
}
body.light-mode #customer-detail-content .cd-section-title,
body.light-mode #vehicle-detail-content  .cd-section-title {
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 800 !important;
  font-size: 12px !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: var(--ink) !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 10px !important;
}
body.light-mode #customer-detail-content .cd-section-title::before,
body.light-mode #vehicle-detail-content  .cd-section-title::before {
  content: counter(cdsec, decimal-leading-zero);
  background: var(--amber);
  color: #fff;
  padding: 3px 8px 4px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.1em;
  line-height: 1;
}

/* ─── FIELD ROWS — one ink-bordered cell per field ──────────────────────
   The legacy .cd-field-row used a continuous bottom-hairline pattern,
   producing rows that visually flowed together with no boundaries
   between values. The Service Manual aesthetic wants each field to
   read as its own discrete data cell — ink hairline box, value sits
   inside it, hover/focus tinge to amber. Mirrors the `.jd-input` look
   used for editable inputs across the rest of the app. */
body.light-mode #customer-detail-content .cd-field-row,
body.light-mode #vehicle-detail-content  .cd-field-row {
  display: flex !important;
  align-items: center !important;
  gap: 14px !important;
  padding: 8px 18px !important;
  border-bottom: none !important;
}
body.light-mode #customer-detail-content .cd-field-label,
body.light-mode #vehicle-detail-content  .cd-field-label {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  color: var(--ink-mute) !important;
  width: 170px !important;
  flex-shrink: 0 !important;
}
body.light-mode #customer-detail-content .cd-field-val,
body.light-mode #vehicle-detail-content  .cd-field-val {
  flex: 1 !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  color: var(--ink) !important;
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  padding: 9px 12px !important;
  cursor: pointer !important;
  transition: border-color .12s !important;
  min-height: 34px !important;
  display: flex !important;
  align-items: center !important;
}
body.light-mode #customer-detail-content .cd-field-val:hover,
body.light-mode #vehicle-detail-content  .cd-field-val:hover {
  border-color: var(--ink) !important;
}
body.light-mode #customer-detail-content .cd-field-val.editing,
body.light-mode #vehicle-detail-content  .cd-field-val.editing,
body.light-mode #customer-detail-content .cd-field-val:focus,
body.light-mode #vehicle-detail-content  .cd-field-val:focus {
  border-color: var(--amber) !important;
  outline: none !important;
  cursor: text !important;
}
body.light-mode #customer-detail-content .cd-field-empty,
body.light-mode #vehicle-detail-content  .cd-field-empty {
  color: var(--ink-mute) !important;
  font-style: normal !important;
}
/* Inputs, selects, textareas inside field rows match the same boxed
   look. Many of the vehicle screen's fields are <input> / <select>
   elements rather than contenteditable divs (Make, Model, State,
   Transmission, Body Type, etc.) — bring them into the same visual
   language. */
body.light-mode #customer-detail-content .cd-field-row input[type="text"],
body.light-mode #customer-detail-content .cd-field-row input[type="number"],
body.light-mode #customer-detail-content .cd-field-row input[type="date"],
body.light-mode #customer-detail-content .cd-field-row input[type="email"],
body.light-mode #customer-detail-content .cd-field-row input[type="tel"],
body.light-mode #customer-detail-content .cd-field-row select,
body.light-mode #customer-detail-content .cd-field-row textarea,
body.light-mode #vehicle-detail-content  .cd-field-row input[type="text"],
body.light-mode #vehicle-detail-content  .cd-field-row input[type="number"],
body.light-mode #vehicle-detail-content  .cd-field-row input[type="date"],
body.light-mode #vehicle-detail-content  .cd-field-row input[type="email"],
body.light-mode #vehicle-detail-content  .cd-field-row input[type="tel"],
body.light-mode #vehicle-detail-content  .cd-field-row select,
body.light-mode #vehicle-detail-content  .cd-field-row textarea {
  flex: 1 !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  color: var(--ink) !important;
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  padding: 9px 12px !important;
  outline: none !important;
  min-height: 34px !important;
  transition: border-color .12s !important;
}
body.light-mode #customer-detail-content .cd-field-row input:hover,
body.light-mode #customer-detail-content .cd-field-row select:hover,
body.light-mode #customer-detail-content .cd-field-row textarea:hover,
body.light-mode #vehicle-detail-content  .cd-field-row input:hover,
body.light-mode #vehicle-detail-content  .cd-field-row select:hover,
body.light-mode #vehicle-detail-content  .cd-field-row textarea:hover {
  border-color: var(--ink) !important;
}
body.light-mode #customer-detail-content .cd-field-row input:focus,
body.light-mode #customer-detail-content .cd-field-row select:focus,
body.light-mode #customer-detail-content .cd-field-row textarea:focus,
body.light-mode #vehicle-detail-content  .cd-field-row input:focus,
body.light-mode #vehicle-detail-content  .cd-field-row select:focus,
body.light-mode #vehicle-detail-content  .cd-field-row textarea:focus {
  border-color: var(--amber) !important;
}

/* Column header strip — JetBrains Mono uppercase, sits below the
   amber rule. The 2px ink under-rule from the legacy CSS clashed
   visually; demote to a 1px subtle rule so the amber stub above
   reads as the dominant boundary. */
body.light-mode .jd-line-cols {
  background: var(--bg-raised);
  border-bottom: 1px solid var(--rule);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding: 8px 14px 7px;
}
body.light-mode .jd-col-lbl {
  color: var(--ink-mute);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Per-line total — keep prominent (per user pref), but in amber +
   Archivo + tabular-nums for the design-system aesthetic. The legacy
   inline color values (red/gold) were overpowering. */
body.light-mode .jd-line-total {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--amber);
  text-align: right;
  letter-spacing: 0.01em;
}
/* Beat inline color="var(--orange)" / "var(--cyan)" / "var(--purple)"
   set by legacy line-add functions. The inline colour is amber-equivalent
   in the new aesthetic regardless of section. */
body.light-mode .jd-line-total[style*="color:var(--orange)"],
body.light-mode .jd-line-total[style*="color:var(--cyan)"],
body.light-mode .jd-line-total[style*="color:var(--purple)"],
body.light-mode .jd-line-total[style*="color:var(--gold)"] {
  color: var(--amber) !important;
}


/* Audit trail — keep collapsed by default; restyle entries when expanded */
body.light-mode .jd-audit-entry {
  border-color: var(--rule);
  font-family: 'IBM Plex Sans', sans-serif;
}
body.light-mode .jd-audit-time { font-family: 'JetBrains Mono', monospace; color: var(--ink-mute); }
body.light-mode .jd-audit-who  { font-family: 'JetBrains Mono', monospace; font-weight: 700; }
body.light-mode .jd-audit-msg  { color: var(--ink-soft); }


/* Locked banner (legacy) — overridden by the new .jc-lock-banner emitted
   by renderJobDetailPage. Hide the legacy ::before stripe, kill rounded. */
body.light-mode .jd-locked-banner {
  display: none !important;  /* superseded by .jc-lock-banner */
}


/* Approval banner — temporarily kept on legacy classes; pass 2 will
   replace with the .jc-banner pattern. Just neutralise the rounded
   corners and recolour. */
body.light-mode .jd-approval-banner {
  border-radius: 0;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--amber);
  background: var(--bg-raised);
  padding: 11px 16px;
}
body.light-mode .jd-approval-banner.jd-approval-pending {
  border-left-color: var(--amber);
}
body.light-mode .jd-approval-banner.jd-approval-approved {
  border-left-color: var(--ok);
}


/* ═══════════════════════════════════════════════════════════════════════
   29 · AQ PANEL RESKIN — info-toned, slate blue
   The Additional Work Quote panel uses inline-styled markup with
   rgba(61,109,163,...) info colours. Override the inline header so the
   AQ panel reads as info-toned section in the new aesthetic. The AQ
   item rows themselves use inline styles too — restyle by attribute
   selector.
   ═══════════════════════════════════════════════════════════════════════ */

/* AQ panel outer — pick out the .jd-section with the info-toned border */
body.light-mode .jd-section[style*="rgba(61,109,163"] {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule) !important;
  border-left: 3px solid var(--info) !important;
  border-radius: 0 !important;
}

/* AQ header band — the inner div with info-toned background */
body.light-mode .jd-section[style*="rgba(61,109,163"] > div[style*="rgba(61,109,163,0.08)"] {
  background: rgba(58,90,122,0.08) !important;
  border-bottom: 1px solid var(--rule) !important;
}

/* AQ title text — was using #3d6da3 colour */
body.light-mode .jd-section[style*="rgba(61,109,163"] [style*="color:#3d6da3"] {
  color: var(--info) !important;
  font-family: 'Archivo', sans-serif !important;
  letter-spacing: 0.06em !important;
}

/* AQ status pill — translates to .jc-aq-status look */
body.light-mode .jd-section[style*="rgba(61,109,163"] span[style*="background:rgba(61,109,163,0.15)"] {
  background: transparent !important;
  border: 1px solid currentColor !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  padding: 3px 9px 4px !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   30 · INSPECTION BLOCK RESKIN
   The inspection assignment block also uses .jd-section. The header is
   already styled by section 28. Just neutralise inner colours so the
   "Vehicle Inspection" title doesn't fight the new ink head.
   ═══════════════════════════════════════════════════════════════════════ */

/* Status badges inside inspection — kill the rgba glows, use semantic tones */
body.light-mode .jd-section span[style*="background:rgba(58,138,71"] {
  background: rgba(46,107,60,0.12) !important;
  border: 1px solid var(--ok) !important;
  color: var(--ok) !important;
  border-radius: 0 !important;
}
body.light-mode .jd-section span[style*="background:rgba(201,134,18"] {
  background: rgba(160,106,16,0.12) !important;
  border: 1px solid var(--warn) !important;
  color: var(--warn) !important;
  border-radius: 0 !important;
}
body.light-mode .jd-section span[style*="background:rgba(201,58,31"] {
  background: rgba(168,48,26,0.12) !important;
  border: 1px solid var(--danger) !important;
  color: var(--danger) !important;
  border-radius: 0 !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   31 · ADD-QUOTE BUTTON RESKIN
   The "+ Additional Work Quote Builder" dashed button was previously
   styled inline with cyan/info colours and rgba border. Override to use
   the new .jc-add-quote-btn aesthetic when no AQ exists yet.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode button[onclick*="openAdditionalQuote"][style*="border-style:dashed"] {
  display: block !important;
  width: 100% !important;
  padding: 18px !important;
  background: transparent !important;
  border: 1px dashed var(--info) !important;
  color: var(--info) !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  border-radius: 0 !important;
  margin-bottom: 16px !important;
}
body.light-mode button[onclick*="openAdditionalQuote"][style*="border-style:dashed"]:hover {
  background: rgba(58,90,122,0.08) !important;
}


/* ═══════════════════════════════════════════════════════════════════════
   32 · TECH TIME ROWS — per-tech breakdown inside the stat tile
   When multiple techs have logged time on a job, the Tech Time tile
   swaps from a single-line value to a stacked list of "TechName · hours"
   rows. Live row gets an amber dot + accent. Total row at the bottom
   when more than one tech.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-tt-rows {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
body.light-mode .jc-tt-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.2;
}
body.light-mode .jc-tt-row .who {
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.light-mode .jc-tt-row .hrs {
  font-family: 'Archivo', sans-serif;
  font-size: 17px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: 0;
  flex-shrink: 0;
}
body.light-mode .jc-tt-row.live .who { color: var(--amber); font-weight: 700; }
body.light-mode .jc-tt-row.live .hrs { color: var(--amber); }
body.light-mode .jc-tt-row.total {
  border-top: 1px solid var(--rule);
  padding-top: 4px;
  margin-top: 2px;
}
body.light-mode .jc-tt-row.total .who {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 10px;
  color: var(--ink-mute);
  font-weight: 700;
}
body.light-mode .jc-tt-row.total .hrs { font-size: 19px; }

/* When the tech-time cell hosts the rows (instead of .val), let it
   align top-justify so multi-tech stacks read top-down. */
body.light-mode .jc-stat-cell:has(.jc-tt-rows) { justify-content: flex-start; }
body.light-mode .jc-stat-cell:has(.jc-tt-rows) .lbl { margin-bottom: 8px; }


/* ═══════════════════════════════════════════════════════════════════════
   33 · PARTS STATUS — PO PENDING INDICATOR
   When a job has parts on an unreceived PO, the Parts Status stat tile
   shows a sub-line "1 PO pending" in warn tone. Already wired by JS;
   this just gives the chip its tone styling.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-po-pending {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--warn);
}
body.light-mode .jc-po-pending::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--warn);
}


/* ═══════════════════════════════════════════════════════════════════════
   34 · SERVICE HISTORY BANNER — info-toned, restyled
   The legacy buildSvcHistoryBanner() now emits .jc-svc-history-* classes.
   Slate-blue info head, key-value rows underneath. Dismiss button is a
   proper visible chip not a thin × icon.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-svc-history {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--info);
  overflow: hidden;
}
body.light-mode .jc-svc-history-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  background: rgba(58,90,122,0.08);
  border-bottom: 1px solid var(--rule);
}
body.light-mode .jc-svc-history-tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  background: var(--info);
  color: #fff;
  padding: 3px 9px 4px;
}
body.light-mode .jc-svc-history-plate {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--info);
  text-transform: uppercase;
}
body.light-mode .jc-svc-history-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--ink-mute);
  text-transform: uppercase;
}
body.light-mode .jc-svc-history-dismiss {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  color: var(--ink-mute);
  padding: 6px 12px;
  cursor: pointer;
  flex-shrink: 0;
}
body.light-mode .jc-svc-history-dismiss:hover {
  background: var(--bg-deep);
  border-color: var(--ink-mute);
  color: var(--ink);
}

body.light-mode .jc-svc-history-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 16px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--rule);
  align-items: start;
}
body.light-mode .jc-svc-history-row:last-child { border-bottom: none; }
body.light-mode .jc-svc-history-row-lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding-top: 2px;
}
body.light-mode .jc-svc-history-row-body {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.45;
}
/* Section 1 — Unresolved findings from last visit. Slate-blue toned
   because it's reference data, not an action item. */
body.light-mode .jc-svc-history-row.findings .jc-svc-history-row-lbl { color: var(--info); }

/* Section 2 — Service items due now. Amber-toned because this is the
   upsell action — advisor should ACT on it (raise with customer). */
body.light-mode .jc-svc-history-row.intervals {
  background: rgba(217,72,21,0.04);
}
body.light-mode .jc-svc-history-row.intervals .jc-svc-history-row-lbl { color: var(--amber); }


/* ═══════════════════════════════════════════════════════════════════════
   35 · INVOICE NOTES BLOCK (.jc-invoice-notes)
   Surfaces below Repair Request when status is Completed*. Info-toned
   left rail to distinguish from the amber-toned Repair Request block
   above. Two-line label so the advisor knows this content is
   customer-facing (it ends up on the invoice).
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-notes-block.jc-invoice-notes {
  border-left: 3px solid var(--info);
}
body.light-mode .jc-notes-block.jc-invoice-notes .lbl {
  color: var(--info);
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
}
body.light-mode .jc-notes-block.jc-invoice-notes .lbl .lbl-main {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--info);
}
body.light-mode .jc-notes-block.jc-invoice-notes .lbl .lbl-sub {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mute);
  font-style: italic;
}
body.light-mode .jc-notes-block.jc-invoice-notes textarea:focus {
  border-color: var(--info);
}


/* ═══════════════════════════════════════════════════════════════════════
   36 · STAT-CELL ACTION BUTTONS (.jc-action-btn / .jc-action-primary)
   Big, deliberate buttons for the booking estimate stat strip.
   Replaces the smaller .actions buttons inside the stat-cell when
   the cell IS the action (Print Estimate / Mark Not Proceeding /
   Start Job) rather than an auxiliary action under a number.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-stat-cell .actions .jc-action-btn,
body.light-mode .jc-stat-cell .actions button.jc-action-btn {
  width: 100%;
  padding: 14px 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid var(--rule-bright);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
  transition: all 0.12s;
}
body.light-mode .jc-stat-cell .actions .jc-action-btn:hover {
  border-color: var(--amber);
  color: var(--amber);
  background: var(--bg-deep);
}

/* Primary action — amber-filled, the dominant CTA of the stat strip.
   Used for Start Job. Bigger feel via heavier weight + amber fill. */
body.light-mode .jc-stat-cell .actions .jc-action-btn.jc-action-primary,
body.light-mode .jc-stat-cell .actions button.jc-action-primary {
  background: var(--amber);
  color: #fff;
  border-color: var(--amber);
  font-size: 16px;
  letter-spacing: 0.18em;
  padding: 16px 20px;
  font-weight: 800;
}
body.light-mode .jc-stat-cell .actions .jc-action-btn.jc-action-primary:hover {
  background: var(--amber-deep);
  border-color: var(--amber-deep);
  color: #fff;
}

/* The Start Job cell gets a slightly heavier left rail to draw
   attention as the primary forward action of the booking estimate. */
body.light-mode .jc-stat-cell.jc-start-job-cell {
  border-left-width: 4px;
}


/* ═══════════════════════════════════════════════════════════════════════
   37 · ARRIVAL REPORT BANNER — info-toned info banner aesthetic
   The legacy .arrival-locked used a rgba(0,255,136,0.06) green-wash
   with green-on-green badges that read as muddy. Restyle to match the
   service-history banner aesthetic: cream raised bg, info-toned head
   with ok-green left rail to signal "completed/confirmed".
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .arrival-panel,
body.light-mode .arrival-panel.arrival-locked {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ok);
  border-radius: 0;
  overflow: hidden;
}
body.light-mode .arrival-panel .arrival-header,
body.light-mode .arrival-locked .arrival-header {
  background: rgba(46,107,60,0.06);
  border-bottom: 1px solid var(--rule);
  padding: 14px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
/* Title inside arrival header — already styled by .jd-section-title
   reskin. Force ok-green to signal confirmed state. The legacy
   inline color="var(--green)" gets overridden by the section-title
   rule, so re-tone here. */
body.light-mode .arrival-panel .jd-section-title,
body.light-mode .arrival-locked .jd-section-title {
  color: var(--ok) !important;
}
/* Badges inside the arrival header — retone green pills to match the
   design system. The legacy markup uses .badge.b-done (green) and
   .badge.b-comeback (red). */
body.light-mode .arrival-panel .badge.b-done,
body.light-mode .arrival-locked .badge.b-done {
  background: transparent;
  color: var(--ok);
  border: 1px solid var(--ok);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 3px 9px 4px;
  border-radius: 0;
}
body.light-mode .arrival-panel .badge.b-comeback,
body.light-mode .arrival-locked .badge.b-comeback {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 3px 9px 4px;
  border-radius: 0;
}
/* Inline ODO km readout in the header — retone to amber to highlight
   it as the most actionable piece of info on the row. */
body.light-mode .arrival-panel .arrival-header span[style*="color:var(--cyan)"] {
  color: var(--amber) !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 800 !important;
  letter-spacing: 0.04em;
}

/* ═══════════════════════════════════════════════════════════════════════
   38 · ADDITIONAL WORK QUOTE BUILDER CTA (.jc-aq-add-btn)
   Full-width amber-dashed entry point. Replaces the legacy info-blue
   dashed ghost button which read as muted/disabled.
   ═══════════════════════════════════════════════════════════════════════ */
body.light-mode .jc-aq-add-btn {
  width: 100%;
  display: block;
  padding: 14px 24px;
  background: var(--bg-deep);
  border: 1px solid var(--ink);
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  border-radius: 0;
  transition: all 0.12s;
}
body.light-mode .jc-aq-add-btn:hover {
  background: var(--amber);
  border-color: var(--amber);
  color: #fff;
}

/* Flagged variant — applied when the inspection has red or amber findings
   that haven't been pulled into a quote yet. The button switches to filled
   amber to signal "there's something here to action." A small inline pill
   counts the flagged items so the workshop knows what they're walking into
   before they click. Subtle pulse animation draws the eye on first render
   without being annoying long-term. */
body.light-mode .jc-aq-add-btn.flagged {
  background: var(--amber);
  border-color: var(--amber);
  color: #fff;
  animation: jcAqFlagPulse 2.2s ease-in-out infinite;
}
body.light-mode .jc-aq-add-btn.flagged:hover {
  background: var(--amber-deep, #b33a0f);
  border-color: var(--amber-deep, #b33a0f);
  color: #fff;
  animation: none;
}
body.light-mode .jc-aq-add-btn.flagged .jc-aq-flag-count {
  display: inline-block;
  margin-left: 10px;
  padding: 2px 9px;
  background: rgba(255,255,255,0.22);
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  vertical-align: 1px;
}
@keyframes jcAqFlagPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232,85,32,0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(232,85,32,0); }
}

/* ═══════════════════════════════════════════════════════════════════════
   39 · LABOUR MODAL RESKIN — light-mode override of #lp-popup
   ───────────────────────────────────────────────────────────────────────
   The legacy popup styling (shopnc.css) targets a dark theme — surface
   panel, cyan-accent gradient bar, drop shadow glow. In light mode the
   modal needs to read as a clean cream sheet with amber accents, in
   keeping with the rest of the doc.

   Backdrop: #lp-overlay sits behind the popup. Click-to-cancel.
   ═══════════════════════════════════════════════════════════════════════ */

/* Backdrop overlay — dim + blur the job card behind */
#lp-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 1100;
  opacity: 0;
  transition: opacity 0.18s ease;
}
#lp-overlay.lp-overlay-open {
  display: block;
  opacity: 1;
}

/* Popup panel — light theme override */
body.light-mode #lp-popup {
  background: var(--bg-raised);
  border: 1px solid var(--ink);
  border-radius: 0;
  box-shadow: 0 24px 60px rgba(0,0,0,0.18);
  width: 560px;
  max-width: 96vw;
  max-height: 90vh;
  overflow-y: auto;
}
/* Top accent bar — solid amber, not the cyan→purple gradient */
body.light-mode #lp-popup::before {
  background: var(--amber);
  height: 3px;
  border-radius: 0;
}

/* Header */
body.light-mode #lp-popup .np-popup-header {
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--rule);
  background: var(--bg-raised);
  border-radius: 0;
}
body.light-mode #lp-popup .np-popup-body {
  padding: 22px;
  background: var(--bg-raised);
}
body.light-mode #lp-popup .np-popup-footer {
  padding: 14px 22px;
  border-top: 1px solid var(--rule);
  background: var(--bg-deep);
  border-radius: 0;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

/* Field labels — JetBrains Mono uppercase ink-mute */
body.light-mode #lp-popup .np-lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 6px;
}

/* Inputs — ink hairlines, amber on focus */
body.light-mode #lp-popup .np-input,
body.light-mode #lp-popup #lp-search,
body.light-mode #lp-popup #lp-desc,
body.light-mode #lp-popup #lp-hours,
body.light-mode #lp-popup #lp-rate,
body.light-mode #lp-popup #lp-fixed,
body.light-mode #lp-popup #lp-technote {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  padding: 10px 12px;
  outline: none;
  transition: border-color 0.12s;
}
body.light-mode #lp-popup .np-input:focus,
body.light-mode #lp-popup #lp-search:focus,
body.light-mode #lp-popup #lp-desc:focus,
body.light-mode #lp-popup #lp-hours:focus,
body.light-mode #lp-popup #lp-rate:focus,
body.light-mode #lp-popup #lp-fixed:focus,
body.light-mode #lp-popup #lp-technote:focus {
  border-color: var(--amber) !important;
}

/* Hours / Rate / Fixed numeric inputs — Archivo tabular-nums ink.
   Force-override the inline cyan/purple set by openLabourPopup. */
body.light-mode #lp-popup #lp-hours,
body.light-mode #lp-popup #lp-rate,
body.light-mode #lp-popup #lp-fixed {
  font-family: 'Archivo', sans-serif !important;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink) !important;
  text-align: center;
}

/* Preview total block — cream + amber Archivo */
body.light-mode #lp-popup #lp-preview {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  padding: 16px !important;
}
body.light-mode #lp-popup #lp-preview > div:first-child {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: var(--ink-mute) !important;
}
body.light-mode #lp-popup #lp-preview-total {
  font-family: 'Archivo', sans-serif !important;
  font-size: 32px !important;
  font-weight: 800 !important;
  font-variant-numeric: tabular-nums;
  color: var(--amber) !important;
}

/* Footer buttons — amber-fill primary, ghost cancel */
body.light-mode #lp-popup .np-popup-footer .btn-cyan,
body.light-mode #lp-popup .np-popup-footer .btn-primary {
  background: var(--amber) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 22px !important;
  cursor: pointer;
  transition: background 0.12s;
}
body.light-mode #lp-popup .np-popup-footer .btn-cyan:hover,
body.light-mode #lp-popup .np-popup-footer .btn-primary:hover {
  background: var(--amber-deep) !important;
}
body.light-mode #lp-popup .np-popup-footer .btn-ghost {
  background: transparent !important;
  border: 1px solid var(--rule-bright) !important;
  color: var(--ink) !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 18px !important;
  cursor: pointer;
}
body.light-mode #lp-popup .np-popup-footer .btn-ghost:hover {
  border-color: var(--ink) !important;
}

/* Category grid buttons — visual retone only (per user spec, layout
   stays). Amber-on-hover, ink hairlines. */
body.light-mode #lp-popup #lp-cat-grid > button {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  font-size: 12px !important;
  font-weight: 700 !important;
  border-radius: 0 !important;
  transition: all 0.12s;
}
body.light-mode #lp-popup #lp-cat-grid > button:hover {
  border-color: var(--amber) !important;
  color: var(--amber) !important;
  background: var(--bg-raised) !important;
}

/* Preset list (after picking a category) */
body.light-mode #lp-popup #lp-preset-list {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   40 · PARTS MODAL RESKIN — light-mode override of #pp-popup
   ───────────────────────────────────────────────────────────────────────
   Mirrors section 39 (labour modal) for the parts popup. Same backdrop,
   same panel aesthetic, same input styling. Distinct CSS block so
   regressions in one modal don't bleed into the other.
   ═══════════════════════════════════════════════════════════════════════ */

#pp-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 1100;
  opacity: 0;
  transition: opacity 0.18s ease;
}
#pp-overlay.pp-overlay-open {
  display: block;
  opacity: 1;
}

body.light-mode #pp-popup {
  background: var(--bg-raised);
  border: 1px solid var(--ink);
  border-radius: 0;
  box-shadow: 0 24px 60px rgba(0,0,0,0.18);
  width: 600px;
  max-width: 96vw;
  max-height: 90vh;
  overflow-y: auto;
}
body.light-mode #pp-popup::before {
  background: var(--amber);
  height: 3px;
  border-radius: 0;
}

body.light-mode #pp-popup .np-popup-header {
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--rule);
  background: var(--bg-raised);
  border-radius: 0;
}
body.light-mode #pp-popup .np-popup-body {
  padding: 22px;
  background: var(--bg-raised);
}
body.light-mode #pp-popup .np-popup-footer {
  padding: 14px 22px;
  border-top: 1px solid var(--rule);
  background: var(--bg-deep);
  border-radius: 0;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

body.light-mode #pp-popup .np-lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 6px;
}

/* Inputs — ink hairlines, amber on focus. Beats inline styles set
   by openPartsPopup. */
body.light-mode #pp-popup .np-input,
body.light-mode #pp-popup #pp-partnum,
body.light-mode #pp-popup #pp-name,
body.light-mode #pp-popup #pp-supplier,
body.light-mode #pp-popup #pp-qty,
body.light-mode #pp-popup #pp-cost,
body.light-mode #pp-popup #pp-markup,
body.light-mode #pp-popup #pp-sell,
body.light-mode #pp-popup #pp-init-stock,
body.light-mode #pp-popup #pp-low-alert,
body.light-mode #pp-popup #pp-drum-cap,
body.light-mode #pp-popup #pp-cat {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  padding: 10px 12px;
  outline: none;
  transition: border-color 0.12s;
}
body.light-mode #pp-popup .np-input:focus,
body.light-mode #pp-popup #pp-partnum:focus,
body.light-mode #pp-popup #pp-name:focus,
body.light-mode #pp-popup #pp-supplier:focus,
body.light-mode #pp-popup #pp-qty:focus,
body.light-mode #pp-popup #pp-cost:focus,
body.light-mode #pp-popup #pp-markup:focus,
body.light-mode #pp-popup #pp-sell:focus,
body.light-mode #pp-popup #pp-init-stock:focus,
body.light-mode #pp-popup #pp-low-alert:focus,
body.light-mode #pp-popup #pp-drum-cap:focus {
  border-color: var(--amber) !important;
}

/* Numeric inputs — Archivo tabular-nums ink. Force-override the inline
   cyan/blue/gold colours from openPartsPopup. */
body.light-mode #pp-popup #pp-partnum {
  font-family: 'JetBrains Mono', monospace !important;
  font-weight: 800 !important;
  letter-spacing: 0.06em;
  font-size: 18px !important;
  color: var(--ink) !important;
  text-transform: uppercase;
}
body.light-mode #pp-popup #pp-qty,
body.light-mode #pp-popup #pp-markup {
  font-family: 'Archivo', sans-serif !important;
  font-weight: 800 !important;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--ink) !important;
  font-size: 18px !important;
}
body.light-mode #pp-popup #pp-cost,
body.light-mode #pp-popup #pp-sell {
  font-family: 'Archivo', sans-serif !important;
  font-weight: 700 !important;
  font-variant-numeric: tabular-nums;
  color: var(--ink) !important;
  font-size: 15px !important;
}

/* Pricing block — cream raised, ink hairline. Replaces the legacy
   surface2/border block. */
body.light-mode #pp-popup .np-popup-body > div[style*="background:var(--surface2)"] {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
}

/* Line total preview — amber Archivo */
body.light-mode #pp-popup #pp-preview-total {
  font-family: 'Archivo', sans-serif !important;
  font-size: 32px !important;
  font-weight: 800 !important;
  font-variant-numeric: tabular-nums;
  color: var(--amber) !important;
}
body.light-mode #pp-popup div[style*="background:rgba(61,109,163,0.06)"]:has(#pp-preview-total) {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  padding: 16px !important;
}

/* Tracked/Untracked tile selector — ink hairlines on inactive,
   amber on active (active state set inline by openPartModalUnified +
   ppSelectTile). The CSS rule must NOT use !important on properties
   that the inline-amber state sets, or the selection won't show. */
body.light-mode #pp-popup #pp-tile-untracked,
body.light-mode #pp-popup #pp-tile-tracked {
  border-radius: 0 !important;
  transition: all 0.12s;
  cursor: pointer;
}
body.light-mode #pp-popup #pp-tile-untracked:hover,
body.light-mode #pp-popup #pp-tile-tracked:hover {
  border-color: var(--amber) !important;
}
/* Strong active state — amber border + tinted background + amber label.
   Class `.pp-tile-active` is set/removed by ppSelectTile. */
body.light-mode #pp-popup #pp-tile-untracked.pp-tile-active,
body.light-mode #pp-popup #pp-tile-tracked.pp-tile-active {
  border-color: var(--amber) !important;
  background: rgba(217,72,21,0.08) !important;
  box-shadow: inset 0 0 0 1px var(--amber);
}
body.light-mode #pp-popup #pp-tile-untracked.pp-tile-active .pp-tile-label,
body.light-mode #pp-popup #pp-tile-tracked.pp-tile-active .pp-tile-label {
  color: var(--amber) !important;
}
/* Legacy selection state (cyan inline) → retone to amber. */
body.light-mode #pp-popup [id^="pp-tile-"][style*="border:2px solid var(--cyan)"],
body.light-mode #pp-popup [id^="pp-tile-"][style*="border:2px solid #3d6da3"] {
  border: 2px solid var(--amber) !important;
  background: rgba(217,72,21,0.08) !important;
}
body.light-mode #pp-popup [id^="pp-tile-"][style*="border:2px solid var(--cyan)"] .pp-tile-label,
body.light-mode #pp-popup [id^="pp-tile-"][style*="border:2px solid #3d6da3"] .pp-tile-label {
  color: var(--amber) !important;
}

/* Stock fields wrapper */
body.light-mode #pp-popup #pp-stock-fields {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
}

/* Footer buttons — same as labour modal */
body.light-mode #pp-popup .np-popup-footer .btn[onclick*="ppConfirm"],
body.light-mode #pp-popup .np-popup-footer .btn-cyan,
body.light-mode #pp-popup .np-popup-footer .btn-primary {
  background: var(--amber) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 22px !important;
  cursor: pointer;
  transition: background 0.12s;
}
body.light-mode #pp-popup .np-popup-footer .btn[onclick*="ppConfirm"]:hover,
body.light-mode #pp-popup .np-popup-footer .btn-cyan:hover,
body.light-mode #pp-popup .np-popup-footer .btn-primary:hover {
  background: var(--amber-deep) !important;
}
body.light-mode #pp-popup .np-popup-footer .btn-ghost {
  background: transparent !important;
  border: 1px solid var(--rule-bright) !important;
  color: var(--ink) !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 18px !important;
  cursor: pointer;
}
body.light-mode #pp-popup .np-popup-footer .btn-ghost:hover {
  border-color: var(--ink) !important;
}

/* Found-in-catalogue / new-part badges in the part-number row */
body.light-mode #pp-popup #pp-found-badge {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 800 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--ok) !important;
  border: 1px solid var(--ok);
  padding: 2px 8px;
  background: transparent;
}
body.light-mode #pp-popup #pp-new-badge {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 800 !important;
  letter-spacing: 0.14em !important;
  text-transform: uppercase !important;
  color: var(--warn) !important;
  border: 1px solid var(--warn);
  padding: 2px 8px;
  background: transparent;
}

/* Autocomplete dropdowns — partnum + supplier */
body.light-mode #pp-popup #pp-partnum-dd,
body.light-mode #pp-popup #pp-sup-dd {
  background: var(--bg-raised) !important;
  border: 1px solid var(--ink) !important;
  border-radius: 0 !important;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15) !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   41 · CONSUMABLES MODAL RESKIN — light-mode override of #cp-popup
   Mirrors sections 39 (labour) and 40 (parts).
   ═══════════════════════════════════════════════════════════════════════ */

#cp-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 1100;
  opacity: 0;
  transition: opacity 0.18s ease;
}
#cp-overlay.cp-overlay-open {
  display: block;
  opacity: 1;
}

body.light-mode #cp-popup {
  background: var(--bg-raised);
  border: 1px solid var(--ink);
  border-radius: 0;
  box-shadow: 0 24px 60px rgba(0,0,0,0.18);
  width: 560px;
  max-width: 96vw;
  max-height: 90vh;
  overflow-y: auto;
}
body.light-mode #cp-popup::before {
  background: var(--amber);
  height: 3px;
  border-radius: 0;
}

body.light-mode #cp-popup .np-popup-header {
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--rule);
  background: var(--bg-raised);
  border-radius: 0;
}
body.light-mode #cp-popup .np-popup-body {
  padding: 22px;
  background: var(--bg-raised);
}
body.light-mode #cp-popup .np-popup-footer {
  padding: 14px 22px;
  border-top: 1px solid var(--rule);
  background: var(--bg-deep);
  border-radius: 0;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

body.light-mode #cp-popup .np-lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 6px;
}

body.light-mode #cp-popup .np-input,
body.light-mode #cp-popup #cp-desc,
body.light-mode #cp-popup #cp-qty,
body.light-mode #cp-popup #cp-price {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  padding: 10px 12px;
  outline: none;
  transition: border-color 0.12s;
}
body.light-mode #cp-popup .np-input:focus,
body.light-mode #cp-popup #cp-desc:focus,
body.light-mode #cp-popup #cp-qty:focus,
body.light-mode #cp-popup #cp-price:focus {
  border-color: var(--amber) !important;
}

/* Numeric inputs — Archivo tabular-nums ink. Override the inline
   orange colour set by openConsPopup. */
body.light-mode #cp-popup #cp-qty,
body.light-mode #cp-popup #cp-price {
  font-family: 'Archivo', sans-serif !important;
  font-weight: 700 !important;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--ink) !important;
}
body.light-mode #cp-popup #cp-qty {
  font-size: 18px !important;
}
body.light-mode #cp-popup #cp-price {
  font-size: 16px !important;
}

/* Preset grid buttons — ink hairline default, amber-active. The inline
   styles in cpPickPreset() use var(--orange) — capture and retone. */
body.light-mode #cp-popup .cp-preset-btn {
  background: var(--bg-raised) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  transition: all 0.12s;
}
body.light-mode #cp-popup .cp-preset-btn:hover {
  border-color: var(--amber) !important;
  color: var(--amber) !important;
  background: var(--bg-raised) !important;
}
/* Active preset (cpPickPreset adds .cp-active and inline orange styles) */
body.light-mode #cp-popup .cp-preset-btn.cp-active,
body.light-mode #cp-popup .cp-preset-btn[style*="border-color: var(--orange)"],
body.light-mode #cp-popup .cp-preset-btn[style*="border-color:var(--orange)"] {
  border-color: var(--amber) !important;
  background: var(--bg-deep) !important;
  color: var(--amber) !important;
}

/* Levy banner at top — retone from peach-rgb to a clean cream notice */
body.light-mode #cp-popup .np-popup-body > div[style*="background:rgba(232,85,32,0.05)"] {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  color: var(--ink) !important;
  font-family: 'IBM Plex Sans', sans-serif !important;
}
body.light-mode #cp-popup .np-popup-body > div[style*="background:rgba(232,85,32,0.05)"] strong {
  color: var(--amber) !important;
}

/* Preview total — amber Archivo */
body.light-mode #cp-popup #cp-preview-wrap {
  background: var(--bg-deep) !important;
  border: 1px solid var(--rule-bright) !important;
  border-radius: 0 !important;
  padding: 16px !important;
}
body.light-mode #cp-popup #cp-preview-wrap > div:first-child {
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: var(--ink-mute) !important;
}
body.light-mode #cp-popup #cp-preview-total {
  font-family: 'Archivo', sans-serif !important;
  font-size: 32px !important;
  font-weight: 800 !important;
  font-variant-numeric: tabular-nums;
  color: var(--amber) !important;
}
body.light-mode #cp-popup #cp-levy-note {
  font-family: 'IBM Plex Sans', sans-serif !important;
  font-size: 11px !important;
  color: var(--ink-mute) !important;
  margin-top: 6px !important;
}

/* Footer buttons */
body.light-mode #cp-popup .np-popup-footer button[onclick*="cpConfirm"],
body.light-mode #cp-popup .np-popup-footer .btn-cyan,
body.light-mode #cp-popup .np-popup-footer .btn-primary {
  background: var(--amber) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 22px !important;
  cursor: pointer;
  transition: background 0.12s;
}
body.light-mode #cp-popup .np-popup-footer button[onclick*="cpConfirm"]:hover {
  background: var(--amber-deep) !important;
}
body.light-mode #cp-popup .np-popup-footer .btn-ghost {
  background: transparent !important;
  border: 1px solid var(--rule-bright) !important;
  color: var(--ink) !important;
  border-radius: 0 !important;
  font-family: 'JetBrains Mono', monospace !important;
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  padding: 10px 18px !important;
  cursor: pointer;
}
body.light-mode #cp-popup .np-popup-footer .btn-ghost:hover {
  border-color: var(--ink) !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   50 · MOBILE BREAKPOINT — Targeted (Diary + Job Card only)
   ───────────────────────────────────────────────────────────────────────
   Scope: just the two most-used screens for a workshop owner on phone:
     1. Diary (day-rows that show today's bookings, plate + customer +
        action buttons). The desktop 7-column grid collapses into a
        stacked card layout where the time + plate are a top row, the
        customer/vehicle fills the next, and any action buttons get
        their own dedicated row at the bottom (full-width, tappable).
     2. Job card (header customer/vehicle blocks side-by-side, control
        panel with 5+ columns, stat strip with 4 columns). All collapse
        to single-column or 2x2 grids so nothing overlaps and nothing
        is cut off the edge.
   Other screens (customers list, vehicles, settings, etc.) are not
   adjusted here. They still render as desktop layout on mobile, which
   is "ugly but readable" — acceptable for pre-launch when workshops
   primarily use the app from a counter PC anyway.

   Breakpoint: 700px. iPhones max out around 430px portrait; larger
   phones in landscape and small tablets up to ~700px get the same
   treatment. Above 700px, desktop layout returns.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 700px) {

  /* ── DIARY DAY-ROWS ─────────────────────────────────────────────
     The desktop 7-column grid is a mess on mobile. Rebuild as a
     vertical card: time + plate on row 1, customer name + vehicle on
     row 2, action buttons (job card, mark paid, send link) as their
     own full-width row at the bottom. No more overlapping UNPAID
     badges or cut-off plates. */
  body.light-mode .d2-row {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 12px 14px;
  }
  /* Time cell — move to its own line at the top, inline with the plate */
  body.light-mode .d2-row .d2-time {
    text-align: left;
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
  }
  body.light-mode .d2-row .d2-time .sub {
    display: inline;
    margin-top: 0;
    margin-left: 6px;
  }
  /* Hide the thin tech-stripe column on mobile — visual signal not
     critical enough to deserve a row of its own, and the row's left
     border (.warn/.danger/.ok) already conveys status colour */
  body.light-mode .d2-row .d2-tech-stripe { display: none; }
  /* Customer/vehicle body — takes full width, breaks line normally */
  body.light-mode .d2-row .d2-body { padding: 4px 0; }
  body.light-mode .d2-row .d2-cust { font-size: 17px; margin-bottom: 4px; }
  body.light-mode .d2-row .d2-sub { font-size: 14px; }
  /* Money — right-align inline with status pill on its own row */
  body.light-mode .d2-row .d2-money {
    text-align: right;
    min-width: 0;
    align-self: end;
    font-size: 17px;
  }
  /* Days-in-shop tile — right-align on its own row */
  body.light-mode .d2-row .d2-days {
    text-align: right;
    align-self: end;
    font-size: 18px;
  }
  /* Action buttons — give them a full-width container so they stack
     in a clean row and don't overlap the price or the badge. Each
     button stretches to fill so they're tap-friendly (44px+ tall). */
  body.light-mode .d2-row .d2-actions {
    flex-wrap: wrap;
    gap: 8px;
    width: 100%;
    margin-top: 4px;
  }
  body.light-mode .d2-row .d2-actions > * {
    flex: 1 1 auto;
    min-width: 100px;
    min-height: 38px;
    text-align: center;
    justify-content: center;
    display: inline-flex;
    align-items: center;
  }

  /* ── JOB CARD CUSTOMER / VEHICLE BLOCKS ─────────────────────────
     Desktop has them side-by-side (1fr 1fr). On mobile that forces
     horizontal scroll, hiding half the data. Stack them vertically. */
  body.light-mode .doc-blocks {
    grid-template-columns: 1fr;
  }
  body.light-mode .doc-block {
    border-right: none;
    border-bottom: 1px solid var(--rule);
    /* Right padding reduced — Edit button is positioned absolutely,
       so we still need to reserve space for it, but with no second
       column eating horizontal room the button has more breathing
       space already. Keep 100px to clear the 84px button + 16px gap */
    padding: 16px 100px 16px 18px;
  }
  body.light-mode .doc-block:last-child { border-bottom: none; }

  /* ── JOB CARD CONTROL PANEL (Save / Status / Tech / Type / Due / Internal / Total) ─
     Desktop has 7 cells in a single row. Mobile crams them into ~375px
     and the text overlaps into unreadable soup. Rebuild as a vertical
     stack — Save tile + Total tile keep prominent placement at top
     and bottom, the four status dropdowns become a 2x2 grid in the
     middle. Each cell gets full width with adequate tap targets. */
  body.light-mode .jc-ctrl-panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    flex-wrap: wrap;
  }
  body.light-mode .jc-ctrl-cell {
    border-right: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    min-height: 64px;
    padding: 10px 14px 12px;
  }
  /* Save and Total each span the full width — they're the most
     important controls and deserve dedicated rows */
  body.light-mode .jc-ctrl-panel .jc-ctrl-cell.jc-save,
  body.light-mode .jc-ctrl-panel .jc-ctrl-cell.jc-total {
    grid-column: span 2;
    flex: none;
  }
  body.light-mode .jc-ctrl-cell.jc-save { padding: 14px; }
  body.light-mode .jc-ctrl-cell.jc-total { padding: 14px 18px 16px; }
  body.light-mode .jc-ctrl-cell.jc-total .v { font-size: 26px; }
  /* Reduce select font size so dropdown labels fit on mobile.
     17px desktop value was overflowing the now-narrower cell. */
  body.light-mode .jc-ctrl-cell select,
  body.light-mode .jc-ctrl-cell input { font-size: 14px; }
  body.light-mode .jc-ctrl-cell .lbl,
  body.light-mode .jc-ctrl-cell label {
    font-size: 10px;
    letter-spacing: 0.12em;
  }
  body.light-mode .jc-ctrl-cell .jc-pill {
    padding: 6px 10px;
    font-size: 11px;
  }

  /* ── JOB CARD STAT STRIP (Tech Time / Margin / Parts / Workflow) ─
     Desktop 4-column grid. Mobile drops to 2x2 so each cell has
     enough horizontal room to read clearly. */
  body.light-mode .jc-stat-strip {
    grid-template-columns: 1fr 1fr;
  }
  body.light-mode .jc-stat-cell {
    border-right: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
  }
  /* Right-column cells should not have a right border (would extend
     past the panel edge) — same for bottom-row cells */
  body.light-mode .jc-stat-cell:nth-child(2n) { border-right: none; }
  body.light-mode .jc-stat-cell:nth-last-child(-n+2) { border-bottom: none; }

  /* ── JOB CARD TOPBAR ACTIONS ────────────────────────────────────
     "CANCEL JOB" and "DELETE JOB" buttons are at the top-right on
     desktop. On mobile they're forced to a new line below "BACK /
     JOB CARD" which is fine — but make sure they wrap rather than
     overflow the screen edge. */
  body.light-mode .topbar,
  body.light-mode .topbar-actions,
  body.light-mode #topbar-actions {
    flex-wrap: wrap;
    gap: 6px;
  }

  /* ── EDIT BUTTON STAYS RESPONSIVE ───────────────────────────────
     On very narrow screens, the 84px Edit button can dominate the
     doc-block. Slightly trim its width on mobile but keep the
     text legible. The padding-right reservation on .doc-block above
     is already updated to match. */
  body.light-mode .doc-block-edit {
    width: 78px;
    height: 58px;
    top: 12px;
    right: 12px;
  }

  /* ── LABOUR / PARTS LINE GRID ───────────────────────────────────
     Root cause of the "C / o / n / n / e / c / t / e / d" character-
     stack bug: shopnc.css sets `labour-cols` to grid-template-columns
     `2.5fr 80px 90px 90px 30px` — total ~290px of fixed columns
     before the description even gets space. On a 375px iPhone the
     description column ends up ~30-50px wide which forces text to
     wrap per-character. In tech-view mode the Rate and Total columns
     are hidden via display:none but their grid slots still allocated
     space, making it worse.

     Fix: redefine the labour grid for mobile to put Description on
     its own full-width row, then Hours/Rate/Total/delete on a second
     compact row underneath. Same for parts (which uses a similar
     5-column grid). The .jd-line.labour-cols selector targets both
     the header label row and each individual line, so they stay
     visually consistent. */
  body.light-mode .jd-line-cols.labour-cols,
  body.light-mode .jd-line.labour-cols {
    grid-template-columns: 1fr auto auto auto auto !important;
    grid-template-areas:
      "desc desc desc desc desc"
      "hours rate total dot del";
    column-gap: 8px;
    row-gap: 4px;
  }
  body.light-mode .jd-line-cols.labour-cols > div:nth-child(1),
  body.light-mode .jd-line.labour-cols > *:nth-child(1) {
    grid-area: desc;
    min-width: 0;
  }
  body.light-mode .jd-line-cols.labour-cols > div:nth-child(2),
  body.light-mode .jd-line.labour-cols > *:nth-child(2) { grid-area: hours; }
  body.light-mode .jd-line-cols.labour-cols > div:nth-child(3),
  body.light-mode .jd-line.labour-cols > *:nth-child(3) { grid-area: rate; }
  body.light-mode .jd-line-cols.labour-cols > div:nth-child(4),
  body.light-mode .jd-line.labour-cols > *:nth-child(4) { grid-area: total; }
  body.light-mode .jd-line-cols.labour-cols > div:nth-child(5),
  body.light-mode .jd-line.labour-cols > *:nth-child(5) { grid-area: del; }

  /* Tech-view mode — Rate and Total are hidden, so collapse them
     entirely and let Hours sit beside the delete button on its row.
     This needs explicit override because shopnc.css uses display:none
     on the cells which still leaves their grid slot allocation. */
  body.tv-mode .jd-line-cols.labour-cols,
  body.tv-mode .jd-line.labour-cols {
    grid-template-areas:
      "desc desc desc desc desc"
      "hours hours hours del del" !important;
  }

  /* Parts line — same problem, similar fix. The parts grid is
     5-column too: Part# / Description / Qty / UnitPrice / Total
     plus a delete chevron. On mobile we stack: part# + description
     on row 1, qty / price / total / del on row 2. */
  body.light-mode .jd-line.parts-cols,
  body.light-mode .jd-line-cols.parts-cols {
    grid-template-columns: 1fr auto auto auto !important;
    grid-template-areas:
      "part part part part"
      "desc desc desc desc"
      "qty price total del";
    column-gap: 8px;
    row-gap: 4px;
  }
  body.light-mode .jd-line.parts-cols > *:nth-child(1),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(1) { grid-area: part; }
  body.light-mode .jd-line.parts-cols > *:nth-child(2),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(2) { grid-area: desc; min-width: 0; }
  body.light-mode .jd-line.parts-cols > *:nth-child(3),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(3) { grid-area: qty; }
  body.light-mode .jd-line.parts-cols > *:nth-child(4),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(4) { grid-area: price; }
  body.light-mode .jd-line.parts-cols > *:nth-child(5),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(5) { grid-area: total; }
  body.light-mode .jd-line.parts-cols > *:nth-child(6),
  body.light-mode .jd-line-cols.parts-cols > *:nth-child(6) { grid-area: del; }

  /* Consumables — same problem as parts/labour, was missed in the
     original mobile-stack fix. Grid template is 2.5fr 80px 90px 90px
     30px = ~290px of fixed cols, leaving the description ~30-50px on
     a 390px iPhone (the "D / E / S / C / R / I / P / T / I / O / N"
     vertical character-stack reported May 2026). Stack the same way:
     description full-width on row 1, qty/price/total/del compact on
     row 2. Header row and data row use the same grid template so
     they stay aligned. */
  body.light-mode .jd-line-cols.consumable-cols,
  body.light-mode .jd-line.consumable-cols {
    grid-template-columns: 1fr auto auto auto !important;
    grid-template-areas:
      "desc desc desc desc"
      "qty price total del";
    column-gap: 8px;
    row-gap: 4px;
  }
  body.light-mode .jd-line-cols.consumable-cols > *:nth-child(1),
  body.light-mode .jd-line.consumable-cols > *:nth-child(1) { grid-area: desc; min-width: 0; }
  body.light-mode .jd-line-cols.consumable-cols > *:nth-child(2),
  body.light-mode .jd-line.consumable-cols > *:nth-child(2) { grid-area: qty; }
  body.light-mode .jd-line-cols.consumable-cols > *:nth-child(3),
  body.light-mode .jd-line.consumable-cols > *:nth-child(3) { grid-area: price; }
  body.light-mode .jd-line-cols.consumable-cols > *:nth-child(4),
  body.light-mode .jd-line.consumable-cols > *:nth-child(4) { grid-area: total; }
  body.light-mode .jd-line-cols.consumable-cols > *:nth-child(5),
  body.light-mode .jd-line.consumable-cols > *:nth-child(5) { grid-area: del; }

  /* Tech-view mode — qty/price/total/del are already hidden by existing
     rules (shopnc.css ~line 417-423). Drop row 2 entirely so we don't
     leave an empty 4-track strip below the description. */
  body.tv-mode .jd-line-cols.consumable-cols,
  body.tv-mode .jd-line.consumable-cols {
    grid-template-columns: 1fr !important;
    grid-template-areas: "desc" !important;
  }

  /* Parts collapsed row — built imperatively in buildPartsRow with
     inline grid-template-columns: 110px 1fr 70px 90px auto 84px 32px
     32px = ~480px of fixed columns plus the 1fr description. On a
     390px iPhone after section padding (~360px usable) the description
     column gets squeezed to near-zero width — its content (the part
     name span + "X on shelf" stock badge) overflows out of its cell
     and visually overlaps the next-door qty input. Reported May 2026:
     "1" qty rendering on top of "3 ON SHELF" badge, description
     column appearing empty.
     Mobile fix: stack into 2 rows. Row 1 = Part# + Description spans
     the full width (Description's stock badge wraps neatly inside).
     Row 2 = qty / sell / total / PO / pencil / delete laid out
     left-to-right with explicit column positions so they don't
     overlap. Hidden tv-mode children (display:none) collapse their
     tracks naturally. */
  /* Advisor-mode 2-row layout. Scoped to :not(.tv-mode) so tech mode
     keeps the single-row layout owned by shopnc.css (~line 1559).
     Without this exclusion both selectors match on phone in tech mode
     (the body carries both light-mode and tv-mode classes), and the
     light-mode block — being loaded later, with the same specificity
     and explicit per-child grid-row/grid-column !important — was
     winning and dragging the tech-mode parts row back to a broken
     2-row stack. Reported May 2026 with screenshot. */
  body.light-mode:not(.tv-mode) .part-collapsed {
    grid-template-columns: auto auto 1fr auto auto auto !important;
    grid-template-rows: auto auto !important;
    column-gap: 6px !important;
    row-gap: 6px !important;
    padding: 8px 10px !important;
  }
  /* Row 1: Part# left ~110px, Description right (rest). Both stretch
     vertically with their content. The cells use line-clamp / ellipsis
     internally so they don't blow out heights. */
  body.light-mode:not(.tv-mode) .part-collapsed > .part-coll-pnum {
    grid-row: 1 !important;
    grid-column: 1 / span 2 !important;
  }
  body.light-mode:not(.tv-mode) .part-collapsed > .part-coll-name {
    grid-row: 1 !important;
    grid-column: 3 / -1 !important;
    min-width: 0 !important;
  }
  /* Row 2: 6 action items in source order — qty(3) / sell(4) /
     total(5) / PO(6) / pencil(7) / delete(8). Each gets explicit
     column placement so they line up cleanly and don't auto-flow back
     into row 1. */
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(3) { grid-row: 2 !important; grid-column: 1 !important; }
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(4) { grid-row: 2 !important; grid-column: 2 !important; }
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(5) { grid-row: 2 !important; grid-column: 3 !important; justify-self: end; }
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(6) { grid-row: 2 !important; grid-column: 4 !important; }
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(7) { grid-row: 2 !important; grid-column: 5 !important; }
  body.light-mode:not(.tv-mode) .part-collapsed > *:nth-child(8) { grid-row: 2 !important; grid-column: 6 !important; }

  /* Tech-view mode parts row — owned by shopnc.css ~line 1559, which
     defines a single dense row: [Part# | Description | Qty | PO].
     Previously this file also touched `body.tv-mode .part-collapsed`
     to override the column template — but only `grid-template-columns`,
     not `grid-template-areas`. Because shopnc-ds.css loads after
     shopnc.css and both rules carry equal specificity, the columns
     here (6 tracks) were winning while the areas template from
     shopnc.css (4 tracks: "pnum name qty po") stayed in effect. The
     mismatched grid produced a broken auto-flow layout on phone: the
     qty input was getting punted onto its own implicit row and the
     orphaned pencil button followed it down. Reported May 2026 with
     screenshot ("parts on phone screen still look mangled").
     Fix: stop touching the template here. Let shopnc.css's tech-mode
     block be the single source of truth for the row. The advisor-mode
     two-row block above (body.light-mode .part-collapsed) still owns
     its own layout. */

  /* ── BUSINESS HOURS TABLE ───────────────────────────────────────
     Each row is a 5-column grid: 120px day label + 3 time pickers
     + 50px checkbox. On 375px the day label is wider than the
     viewport allows, so the row scrolls and the day label gets cut
     off. Fix: stack the day label above the time pickers as a
     header, and make the time pickers fill row 2 in a 3-col grid. */
  body.light-mode [id^="biz-row-"] {
    grid-template-columns: 1fr 1fr 1fr 50px !important;
    grid-template-areas:
      "day day day check"
      "opens dueout drop check" !important;
    row-gap: 6px;
  }
  body.light-mode [id^="biz-row-"] > *:nth-child(1) {
    grid-area: day;
    font-size: 13px;
  }
  body.light-mode [id^="biz-row-"] > *:nth-child(2) { grid-area: opens; }
  body.light-mode [id^="biz-row-"] > *:nth-child(3) { grid-area: dueout; }
  body.light-mode [id^="biz-row-"] > *:nth-child(4) { grid-area: drop; }
  body.light-mode [id^="biz-row-"] > *:nth-child(5) { grid-area: check; align-self: start; }
  body.light-mode [id^="biz-row-"] select {
    width: 100%;
    font-size: 12px;
    padding: 6px 4px;
  }

  /* ── INSPECTION TEMPLATE EDITOR ─────────────────────────────────
     The editor is a 2-column grid (220px templates list + 1fr editor
     pane) that's wider than mobile viewports. Stack vertically: the
     templates list becomes a horizontal-scrolling strip of chips at
     the top, then the editor pane gets full width below.
     Selector targets the editor container's child grid div. */
  body.light-mode #insp-preset-editor-container > div[style*="grid-template-columns:220px"] {
    grid-template-columns: 1fr !important;
    min-height: 0 !important;
  }
  /* Templates list pane — give it a max-height so it doesn't dominate
     the screen. User can scroll within it to find their template. */
  body.light-mode #insp-preset-editor-container > div > div:first-child {
    border-right: none !important;
    border-bottom: 1px solid var(--rule);
    max-height: 260px;
    overflow-y: auto;
  }

  /* ── INSPECTION STAGE EDITOR ROWS ───────────────────────────────
     Each stage row has many controls — type toggle, traffic-light
     state, measurement input, notes, etc. On mobile let them wrap
     freely. Already has flex-wrap on row 2 in the markup; just need
     to ensure the inputs don't force horizontal scroll. */
  body.light-mode #insp-template-editor input[type="text"],
  body.light-mode #insp-template-editor input[type="number"] {
    min-width: 0;
    max-width: 100%;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   51 · MOBILE COMPLIANCE PASS — Comprehensive sweep
   ───────────────────────────────────────────────────────────────────────
   Catches the broad classes of layout issues found across the codebase:
   2-col / 3-col / 4-col inline grids stacking, form inputs at proper
   touch-target sizes, text overflow protection, bottom-nav clearance,
   button wrapping. These are blanket rules that target patterns by
   shape rather than specific selectors — caught a lot of the small
   "noticed it" bugs in one pass.

   Layered AFTER the targeted breakpoint above so these rules win when
   they overlap. !important is used liberally because many of the
   targeted layouts are inline-styled (style="display:grid;...") which
   has higher specificity than any class selector.

   Breakpoint: 700px (matches the previous breakpoint).
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 700px) {

  /* ── INLINE GRID RELAXATION ─────────────────────────────────────
     Most settings sections, form layouts and audience cards use
     inline `style="display:grid;grid-template-columns:1fr 1fr"` or
     `1fr 1fr 1fr` patterns. On mobile these compress to half/third
     widths that break form inputs and labels. Force them to a single
     column. Attribute selectors target inline-style patterns. */
  body.light-mode [style*="grid-template-columns:1fr 1fr"]:not([style*="1fr 1fr 1fr"]),
  body.light-mode [style*="grid-template-columns: 1fr 1fr"]:not([style*="1fr 1fr 1fr"]) {
    grid-template-columns: 1fr !important;
  }
  /* 3-col grids stay as 2-col on mobile — better than collapsing to
     1-col which would be too tall. Exception: 1fr 110px 70px style
     grids (used in some settings rows) keep their fixed columns. */
  body.light-mode [style*="grid-template-columns:1fr 1fr 1fr"],
  body.light-mode [style*="grid-template-columns: 1fr 1fr 1fr"] {
    grid-template-columns: 1fr 1fr !important;
  }
  /* repeat(3,1fr), repeat(4,1fr), repeat(5,1fr) — common in KPI strips,
     category pickers, payment-method grids. Drop to 2 columns on
     mobile so each cell has enough room. */
  body.light-mode [style*="repeat(3,1fr)"],
  body.light-mode [style*="repeat(3, 1fr)"],
  body.light-mode [style*="repeat(3,minmax"],
  body.light-mode [style*="repeat(4,1fr)"],
  body.light-mode [style*="repeat(4, 1fr)"],
  body.light-mode [style*="repeat(4,minmax"],
  body.light-mode [style*="repeat(5,1fr)"],
  body.light-mode [style*="repeat(5, 1fr)"] {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  /* Dashboard KPI strip — the class-based version */
  body.light-mode .dash-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  /* Form-grid (.form-grid / .fg3) — used in setting forms */
  body.light-mode .form-grid,
  body.light-mode .fg3 {
    grid-template-columns: 1fr !important;
  }
  /* Dashboard 3-pane layout (1fr 1fr 280px) — stack vertically. The
     280px right rail goes BELOW the main panes on mobile. */
  body.light-mode .dash-grid {
    grid-template-columns: 1fr !important;
  }

  /* ── FIXED-WIDTH SIDE PANES ─────────────────────────────────────
     Anywhere a grid has a literal "Npx 1fr" pattern (templates list +
     content, SMS thread list + conversation, etc) — stack vertically.
     The fixed-px side pane becomes a horizontal-scrolling or full-
     width strip above the main pane. We already handled the
     inspection template editor (220px 1fr) in the previous block;
     this catches the SMS layout (300px 1fr) and any others. */
  body.light-mode .sms-layout {
    /* Already has @media (max-width:700px) in shopnc.css — leave it */
  }

  /* ── INVOICE TOTALS BOX ─────────────────────────────────────────
     Fixed 280px width "totals" box on invoices/quotes. On mobile it
     would either overflow or get stuck. Switch to full width. */
  body.light-mode .inv-totals {
    width: 100% !important;
    max-width: 100% !important;
    margin-left: 0 !important;
  }

  /* ── FORM INPUTS: TOUCH TARGETS ─────────────────────────────────
     iOS auto-zooms when an input has font-size < 16px on focus.
     We bump all inputs to 16px to prevent the zoom jump. Buttons
     get a minimum tappable height of 40px. */
  body.light-mode input[type="text"],
  body.light-mode input[type="number"],
  body.light-mode input[type="tel"],
  body.light-mode input[type="email"],
  body.light-mode input[type="search"],
  body.light-mode input[type="password"],
  body.light-mode input[type="date"],
  body.light-mode input[type="time"],
  body.light-mode input:not([type]),
  body.light-mode select,
  body.light-mode textarea {
    font-size: 16px !important;
    /* Ensure inputs don't overflow narrow containers */
    max-width: 100%;
  }
  /* Buttons — minimum 38px tall for comfortable tap. Don't override
     the labour/action buttons that already have explicit sizes. */
  body.light-mode button:not(.jc-save):not(.tier-cta):not([style*="height"]) {
    min-height: 38px;
  }
  /* Topbar nav buttons — slightly tighter to fit more on the strip */
  body.light-mode #topbar-actions button {
    min-height: 36px !important;
  }

  /* ── TEXT OVERFLOW PROTECTION ───────────────────────────────────
     The "Connected vehicle to dia..." per-character wrap bug taught
     us that any cell with tiny available width forces extreme wrap.
     A blanket overflow-wrap rule on common content selectors
     prevents the worst cases. break-word > break-all because we
     prefer to keep whole words together where possible. */
  body.light-mode .jd-line,
  body.light-mode .jd-line-cols,
  body.light-mode .doc-fact-val,
  body.light-mode .d2-sub,
  body.light-mode .d2-cust {
    overflow-wrap: break-word;
    word-break: normal;
  }
  /* But ensure none of these collapse to widths so small that even
     individual words can't fit (which is when break-all kicks in
     and creates the per-character stack). */
  body.light-mode .jd-line > *,
  body.light-mode .jd-line-cols > * {
    min-width: 0;
  }

  /* ── BOTTOM-NAV CLEARANCE ───────────────────────────────────────
     Bottom mobile nav is fixed-position and ~56px tall. Anything
     fixed at the bottom (toasts, floating action buttons) overlaps
     unless given bottom clearance. Already handled in base CSS for
     some elements; add for any we might have missed. */
  body.light-mode .toast {
    bottom: 76px !important;
  }
  /* Generic floating "below-the-fold" containers — anything with
     position:fixed bottom-anchored should clear the nav */
  body.light-mode [style*="position:fixed"][style*="bottom:"] {
    /* Don't apply blanket transform — too risky to break working
       fixed elements. Just push the safety margin via padding on
       .content above. */
  }
  body.light-mode .content {
    padding-bottom: 80px !important;
  }

  /* ── BUTTON GROUPS: WRAP INSTEAD OF OVERFLOW ────────────────────
     Action-button rows (cancel/save/print) commonly have
     `display:flex;justify-content:end` with no flex-wrap. On mobile
     they overflow off-screen. Force flex-wrap on common patterns. */
  body.light-mode .doc-actions,
  body.light-mode .modal-foot,
  body.light-mode .np-popup-footer,
  body.light-mode .jd-section-header,
  body.light-mode .modal-actions {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }

  /* ── TABLES: HORIZONTAL SCROLL CONTAINERS ───────────────────────
     Tables (invoice tables, settings tables, customer lists, etc)
     should be wrapped in horizontal scroll on mobile rather than
     forced to fit. The user can swipe horizontally to see all
     columns. Apply to all .card-wrapping and known table contexts. */
  body.light-mode .card > table,
  body.light-mode table {
    display: block;
    width: 100% !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  /* Table content cells get their normal whitespace back so wraps
     happen inside cells where appropriate */
  body.light-mode table td,
  body.light-mode table th {
    white-space: normal;
  }

  /* ── MODALS FROM BOTTOM ─────────────────────────────────────────
     Base CSS already does this for .modal-content / .modal-content-wide
     under @media (max-width:768px). Light-mode-specific modals
     (#lp-popup, #pp-popup, #cp-popup, #fin-popup) need their own
     mobile treatment. They already have max-width:96vw so they fit;
     just adjust positioning to slide up from bottom for thumb reach. */
  body.light-mode #lp-popup,
  body.light-mode #pp-popup,
  body.light-mode #cp-popup,
  body.light-mode #fin-popup {
    width: 100vw !important;
    max-width: 100vw !important;
    max-height: 92vh !important;
    border-radius: 16px 16px 0 0 !important;
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    transform: none !important;
    margin: 0 !important;
  }
  body.light-mode #lp-overlay,
  body.light-mode #pp-overlay {
    align-items: flex-end !important;
  }

  /* ── INSPECTION REPORT (PORTAL & PRINT) ─────────────────────────
     The inspection report header has a 4-col status band. On mobile
     it gets crammed. Drop to 2x2 grid via the inline pattern catcher
     above. The CSS class `.mn-statusband` already targeted by the
     inline-style attribute selectors. */

  /* ── TECHVIEW JOB SECTIONS ──────────────────────────────────────
     The "+ Tech note" placeholder, the Parts / Consumables / Money
     sections have fairly compact layouts already. Just ensure the
     tech-note textarea doesn't squeeze too narrow. */
  body.light-mode #jd-notes,
  body.light-mode textarea[id*="notes"] {
    min-height: 60px;
    font-size: 16px !important; /* prevent iOS zoom */
  }

  /* ── DIARY: SHOP CAPACITY STRIP ─────────────────────────────────
     The capacity bar with "1.8 H / 15.2 H" sometimes gets too wide
     and the bar gets clipped. Ensure it fills the row cleanly. */
  body.light-mode .d2-cap-strip {
    flex-wrap: wrap;
    gap: 8px;
  }
  body.light-mode .d2-cap-bar {
    flex: 1 1 100%;
    min-width: 0;
  }

  /* ── VEHICLE DETAIL HERO ────────────────────────────────────────
     Plate badge + title + actions on one row → wrap on mobile */
  body.light-mode .vd-hero {
    flex-wrap: wrap;
  }
  body.light-mode .vd-hero-plate-row {
    flex-wrap: wrap;
  }

  /* ── SETTINGS TABS ──────────────────────────────────────────────
     The settings sub-tab strip (Job Types / Service Intervals /
     Inspection Templates / Labour Presets / etc) can overflow on
     narrow screens. Allow horizontal scroll instead of wrap so the
     active tab stays visible. */
  body.light-mode .settings-tabs,
  body.light-mode .stab-strip,
  body.light-mode [class*="settings-tab"] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    flex-wrap: nowrap !important;
  }

  /* ── REDUCE EXCESSIVE PADDING ───────────────────────────────────
     Sections built for desktop have 22-30px padding which eats
     half the screen on mobile. Tighten the most common patterns. */
  body.light-mode .cd-section,
  body.light-mode .jd-section {
    padding: 12px 14px !important;
  }
  body.light-mode .cd-section-header,
  body.light-mode .jd-section-header {
    padding: 10px 14px !important;
  }
}

/* ── EXTRA-NARROW (iPhone SE class) ──────────────────────────────────
   Below 400px, drop even further. The earlier @media (max-width: 400px)
   block handles doc-fact specifically; here we cover broader patterns. */
@media (max-width: 400px) {
  /* Tighter doc-fact key column for the customer/vehicle blocks */
  body.light-mode .doc-fact {
    grid-template-columns: 72px 1fr;
    gap: 4px 10px;
    font-size: 13px;
  }
  body.light-mode .doc-block {
    padding: 14px 92px 14px 16px;
  }
  body.light-mode .doc-block-name { font-size: 18px; }
  body.light-mode .doc-block-edit {
    width: 72px;
    height: 56px;
  }

  /* Drop 3-col / 4-col grids further to single-column on very narrow
     screens — 2-col cells were getting too cramped (especially when
     each contained an input + label) */
  body.light-mode [style*="grid-template-columns:1fr 1fr 1fr"],
  body.light-mode [style*="grid-template-columns: 1fr 1fr 1fr"],
  body.light-mode [style*="repeat(3,1fr)"],
  body.light-mode [style*="repeat(3, 1fr)"],
  body.light-mode [style*="repeat(4,1fr)"],
  body.light-mode [style*="repeat(4, 1fr)"] {
    grid-template-columns: 1fr !important;
  }
  body.light-mode .dash-kpis {
    grid-template-columns: 1fr !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   40 · MODAL TEXT CRISPNESS — fix subpixel blur on transform-centered popups
   ───────────────────────────────────────────────────────────────────────
   All modal popups in the app (lp-popup, np-popup, pp-popup, cp-popup,
   st-modal) use the same centering technique:
     position: fixed;
     top: 50%; left: 50%;
     transform: translate(-50%, -50%) scale(1);
   
   This is standard practice, but it has a well-known side effect: the
   `transform` property promotes the element onto a separate GPU compositing
   layer. Browsers default to subpixel-antialiasing for text (the LCD-style
   trick that improves apparent sharpness on integer-pixel positions), but
   when text sits on a transformed composite layer and the layer's final
   pixel position is non-integer (which happens any time the viewport
   height is odd-numbered, the body has unexpected scrollbar widths, etc.),
   subpixel-AA goes wrong — the text looks slightly soft / blurry.
   
   Reported May 2026: the Labour Line modal's preset rows looked soft.
   Comparison against a non-transformed text element confirmed: the
   modal text was a hair off pixel grid.
   
   Fix: switch text inside modal popups to GRAYSCALE antialiasing
   (-webkit-font-smoothing: antialiased). Grayscale AA is slightly less
   sharp on perfectly-aligned integer-pixel text than subpixel-AA, but it
   doesn't degrade on composite layers. Net effect: consistently crisp
   modal text regardless of viewport dimensions.
   
   We DON'T apply this globally to <body> because the rest of the app
   benefits from subpixel-AA's slightly heavier glyph weight on the cream
   document surface. The rule is scoped to modals only.
   ═══════════════════════════════════════════════════════════════════════ */

#lp-popup,
#np-popup,
#pp-popup,
#cp-popup,
#st-modal {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Force a clean integer-pixel compositing layer via translate3d.
     The .0 in the z-axis is what makes the browser commit to a
     consistent GPU layer; without it, some browsers shuffle the
     element between 2D and 3D compositing paths and re-rasterise
     the text on each transition. */
  transform: translate3d(-50%, -46%, 0) scale(.97);
}

#lp-popup.lp-popup-open,
#np-popup.np-popup-open,
#pp-popup.pp-open,
#cp-popup.cp-open,
#st-modal.st-open {
  /* Match the opened state's transform with translate3d too, otherwise
     the opening transition would flip the element between 2D and 3D
     transform contexts mid-animation. */
  transform: translate3d(-50%, -50%, 0) scale(1);
}
