/* ==========================================================================
   DefectDash manager portal — additions layered on ../../assets/style.css.
   Reuses that file's tokens (--bg/--ink/--accent/etc.) and components
   (.btn/.field/.panel/.chip/.stat-box/.tabular) as-is — do not redefine them.
   ========================================================================== */

/* ---------- auth pages (login.html) ---------- */
.auth-page{ min-height:100vh; display:flex; align-items:center; justify-content:center; padding:32px 20px; }
.auth-card{ width:100%; max-width:400px; padding:32px; }
.auth-h1{ font-size:22px; margin-bottom:8px; }
.auth-lede{ font-size:14px; margin-bottom:22px; }
.auth-back{ margin-top:12px; }

/* ---------- inline status banner (shared .field/.form-status idiom) ---------- */
.banner{
  font-size:13.5px; margin-top:14px; padding:11px 14px; border-radius:var(--radius-s);
  display:none;
}
.banner.show{ display:block; }
.banner-error{ background:color-mix(in srgb, var(--fail) 12%, transparent); color:var(--fail); border:1px solid color-mix(in srgb, var(--fail) 35%, var(--line)); }

/* ---------- portal shell ---------- */
.portal-shell{ display:flex; min-height:100vh; }
.portal-sidebar{
  width:236px; flex-shrink:0; background:var(--bg-raised); border-right:1px solid var(--line);
  display:flex; flex-direction:column; padding:20px 14px; position:sticky; top:0; height:100vh;
}
.portal-sidebar .wordmark{ padding:6px 10px 22px; }
.nav-section{ font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); margin:16px 10px 6px; }
.nav-section:first-of-type{ margin-top:0; }
.nav-item{
  display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:var(--radius-s);
  color:var(--ink-dim); text-decoration:none; font-size:14px; font-weight:500;
}
.nav-item svg{ width:17px; height:17px; flex-shrink:0; }
.nav-item:hover{ background:var(--bg-elevated); color:var(--ink); }
.nav-item.is-active{ background:color-mix(in srgb, var(--accent) 16%, transparent); color:var(--accent); }
.nav-item.is-secondary{ font-size:13px; padding-left:20px; }
.sidebar-footer{ margin-top:auto; padding-top:14px; border-top:1px solid var(--line); }
.sidebar-company{ padding:8px 10px; font-size:12.5px; color:var(--ink-faint); }
.sidebar-company b{ display:block; color:var(--ink); font-size:13.5px; font-weight:600; }

.portal-main{ flex:1; min-width:0; padding:32px 36px 80px; }
.portal-topbar{ display:none; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--bg); z-index:30; }

@media (max-width:900px){
  .portal-sidebar{ position:fixed; left:-260px; top:0; z-index:50; width:240px; transition:left .2s ease; box-shadow:var(--shadow); }
  body.portal-nav-open .portal-sidebar{ left:0; }
  .portal-topbar{ display:flex; }
  .portal-main{ padding:20px 16px 60px; }
}

.page-head{ display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:24px; flex-wrap:wrap; }
.page-head h1{ font-size:24px; }
.page-actions{ display:flex; gap:10px; flex-wrap:wrap; }

/* ---------- data table ---------- */
.dd-table-wrap{ overflow-x:auto; border:1px solid var(--line); border-radius:var(--radius-m); background:var(--bg-raised); }
.dd-table{ width:100%; border-collapse:collapse; font-size:14px; white-space:nowrap; }
.dd-table th{
  text-align:left; font-family:var(--font-mono); font-size:11px; letter-spacing:.05em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600; padding:12px 16px; border-bottom:1px solid var(--line);
}
.dd-table td{ padding:12px 16px; border-bottom:1px solid var(--line); color:var(--ink); }
.dd-table tr:last-child td{ border-bottom:none; }
.dd-table tbody tr:hover{ background:var(--bg-elevated); }
.dd-table tr.is-clickable{ cursor:pointer; }

/* ---------- modal / sheet ---------- */
.modal-backdrop{
  position:fixed; inset:0; background:rgba(0,0,0,.55); backdrop-filter:blur(2px);
  display:flex; align-items:center; justify-content:center; padding:20px; z-index:100;
}
.modal-backdrop[hidden]{ display:none; }
.modal{
  background:var(--bg-raised); border:1px solid var(--line); border-radius:var(--radius-m);
  width:100%; max-width:560px; max-height:88vh; display:flex; flex-direction:column; box-shadow:var(--shadow);
}
.modal-header{ display:flex; align-items:center; justify-content:space-between; padding:18px 22px; border-bottom:1px solid var(--line); }
.modal-header h2{ font-size:17px; font-family:var(--font-display); font-weight:800; }
/* The close X was invisible until 2026-09-03: the icon had no intrinsic size
   and this button gave it no rule, so it laid out at 0x0. icon() now carries a
   default, and these give it a real 32px target instead of the 8px box the
   padding alone produced, which was under any sane touch minimum. */
.modal-close{
  background:none; border:none; color:var(--ink-dim); cursor:pointer; padding:4px;
  display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; border-radius:var(--radius-s); flex-shrink:0;
}
.modal-close svg{ width:18px; height:18px; }
.modal-close:hover{ color:var(--ink); background:color-mix(in srgb, var(--ink) 8%, transparent); }
.modal-close:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.modal-body{ padding:20px 22px; overflow-y:auto; }
.modal-footer{ display:flex; justify-content:flex-end; gap:10px; padding:16px 22px; border-top:1px solid var(--line); }

@media (max-width:640px){
  .modal-backdrop{ padding:0; align-items:flex-end; }
  .modal{ max-width:none; max-height:92vh; border-radius:var(--radius-m) var(--radius-m) 0 0; border-bottom:none; }
}

/* ---------- stepper ---------- */
.stepper{ display:flex; align-items:center; gap:12px; }
.stepper button{
  width:32px; height:32px; border-radius:99px; border:1px solid var(--line-strong); background:transparent;
  color:var(--ink); font-size:16px; cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.stepper button:hover{ border-color:var(--accent); color:var(--accent); }
.stepper .stepper-value{ font-family:var(--font-mono); font-size:14.5px; min-width:8ch; text-align:center; }

/* ---------- segmented control ---------- */
.segmented{ display:inline-flex; border:1px solid var(--line-strong); border-radius:99px; padding:3px; gap:2px; }
.segmented button{
  border:none; background:transparent; padding:7px 16px; border-radius:99px; font-size:13.5px; font-weight:600;
  color:var(--ink-dim); cursor:pointer;
}
.segmented button.is-active{ background:var(--accent); color:var(--accent-ink); }

/* ---------- multi-select rows ---------- */
.select-row{
  display:flex; align-items:center; gap:12px; padding:10px 12px; border:1px solid var(--line); border-radius:var(--radius-s);
  margin-bottom:8px; cursor:pointer; background:var(--bg-raised);
}
.select-row:hover{ border-color:var(--ink-dim); }
.select-row.is-selected{ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 8%, var(--bg-raised)); }
.select-row .check{ width:18px; height:18px; flex-shrink:0; color:var(--ink-faint); }
/* Sizes the icon, not just its span. The span rule alone used to stretch the
   unsized svg to 18px; now that icon() supplies a 16px default this keeps the
   tick at the size it has always rendered. */
.select-row .check svg{ width:18px; height:18px; }
.select-row.is-selected .check{ color:var(--accent); }
.select-row .row-main{ flex:1; min-width:0; }
.select-row .row-sub{ font-size:12px; color:var(--ink-faint); }

/* ---------- compact defect table (WEB ROUND 2 item 13) ----------
   Hides the Severity and Status columns. Neither is lost information: the
   severity is already the row's left border colour and the status is already
   the group header the row sits under. Column positions are fixed by the one
   place the header row is written, in page-dashboard.js renderDefectList. */
.table-toolbar{ display:flex; justify-content:flex-end; margin-bottom:8px; }
.dd-table-wrap.is-compact .dd-table th:nth-child(4),
.dd-table-wrap.is-compact .dd-table td:nth-child(4),
.dd-table-wrap.is-compact .dd-table th:nth-child(5),
.dd-table-wrap.is-compact .dd-table td:nth-child(5){ display:none; }
/* The group header keeps colspan="7". A colspan larger than the visible
   column count is clamped by the browser, so it still spans the full width. */

/* ---------- carry-forward defect confirmation (WEB ROUND 2 item 4) ----------
   The technician side. This is a QUESTION the DVIR cannot be submitted past,
   so it has to read as one: two equal-weight answers, neither preselected,
   because a default here would be a default answer about whether a truck is
   safe. */
.tv-carry-row{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  padding:12px 0; border-bottom:1px solid var(--line);
}
.tv-carry-row:last-child{ border-bottom:none; }
.tv-carry-desc{ flex:1; min-width:190px; font-size:14px; line-height:1.45; }
.tv-carry-actions{ display:flex; gap:8px; flex-shrink:0; }
.tv-carry-actions .btn{ padding:8px 14px; font-size:13.5px; }
/* The chosen answer is filled, not merely outlined. On a bright cab-mounted
   iPad a border alone is not a reliable signal. */
.tv-carry-actions .btn.is-active{
  background:var(--accent); color:var(--accent-ink); border-color:var(--accent);
}
.tv-carry-row.is-answered .tv-carry-desc{ color:var(--ink-dim); }

/* The manager side. "Says fixed" is deliberately not green and not a tick:
   it is an unreviewed claim, and it must not read as a resolution. */
.claim-chip{
  display:inline-block; padding:2px 8px; border-radius:99px; font-size:11.5px; font-weight:600;
  background:color-mix(in srgb, #E2A93B 18%, transparent); color:#B07A12;
  border:1px solid color-mix(in srgb, #E2A93B 45%, transparent); white-space:nowrap;
}
.claim-note{
  margin:12px 0; padding:11px 14px; border-radius:var(--radius-s);
  background:color-mix(in srgb, #E2A93B 10%, transparent);
  border:1px solid color-mix(in srgb, #E2A93B 35%, var(--line));
}
.claim-note b{ display:block; font-size:13.5px; margin-bottom:3px; color:#B07A12; }
.claim-note span{ display:block; font-size:12.5px; color:var(--ink-dim); line-height:1.5; }

@media (prefers-color-scheme: dark){
  .claim-chip{ color:#E2A93B; }
  .claim-note b{ color:#E2A93B; }
}

/* ---------- dashboard hero, rebuilt (WEB ROUND 2 items 13 and 14) ----------
   Hierarchy is the whole point of item 13. Exactly one number on this page is
   allowed to be huge, and it is the ready percentage. Everything else steps
   down deliberately: the health headline is a sentence, the alert counts are
   medium, the secondary row is small and folded away. Before this, almost
   every number was large and coloured, which is why none of them stood out. */
/* -- the circle, item 14 -- */
.hero-health-row{ display:flex; align-items:center; gap:16px; margin-top:8px; }
.hero-donut-svg{ width:104px; height:104px; flex-shrink:0; display:block; }
/* ROUND 3. The breakdown swatch shares these COLOURS but is not an arc.
   It briefly carried the .donut-arc class itself, which made
   querySelectorAll('.donut-arc') return swatches as well as arcs and
   broke a real-browser test that counts the donut's segments. One
   declaration per colour, reached by two selectors, keeps the single
   source of truth without overloading what .donut-arc means. */
.donut-arc{ transition:none; }
.donut-arc.is-oos, .health-swatch.is-oos{ stroke:#7a0c0c; }
.donut-arc.is-red, .health-swatch.is-red{ stroke:var(--fail); }
.donut-arc.is-amber, .health-swatch.is-amber{ stroke:#E2A93B; }
.donut-arc.is-green, .health-swatch.is-green{ stroke:var(--pass); }

.hero-health-summary{ min-width:0; }
.hero-health-lead{ display:block; font-size:15px; font-weight:700; line-height:1.3; }
.hero-health-lead.is-oos{ color:#7a0c0c; }
.hero-health-lead.is-major{ color:var(--fail); }
.hero-health-lead.is-minor{ color:#B07A12; }
.hero-health-lead.is-clear{ color:var(--pass); }
.hero-health-sub{ display:block; font-size:12.5px; color:var(--ink-faint); margin-top:3px; }
.hero-zero{ font-size:15px; font-weight:600; margin-bottom:4px; }

/* The breakdown is folded away by default: item 13 asked for the detailed
   legend to come off the main view. */
.health-legend{ margin-top:10px; }
.health-legend > summary{
  cursor:pointer; font-size:12px; color:var(--ink-faint); list-style:none;
  padding:2px 0; width:fit-content;
}
.health-legend > summary::-webkit-details-marker{ display:none; }
.health-legend > summary::before{ content:"+ "; font-family:var(--font-mono); }
.health-legend[open] > summary::before{ content:"- "; }
.health-legend > summary:hover{ color:var(--ink); }
.health-legend > summary:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }
.health-legend-rows{ margin-top:8px; display:flex; flex-direction:column; gap:4px; }
.health-legend-row{ display:flex; align-items:center; font-size:13px; }
.health-legend-row.is-zero{ opacity:.5; }
.health-legend-n{ font-weight:700; min-width:2.5ch; font-variant-numeric:tabular-nums; }
.health-legend-label{ color:var(--ink-dim); margin-left:6px; }
.health-legend-note{ font-size:11.5px; color:var(--ink-faint); margin-top:8px; }

/* -- the one big number -- */
.hero-primary{ display:flex; justify-content:center; }
.hero-primary-btn{
  background:none; border:none; cursor:pointer; padding:8px 4px; text-align:center;
  display:flex; flex-direction:column; align-items:center; gap:2px; color:inherit;
  border-radius:var(--radius-s);
}
.hero-primary-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.hero-primary-num{
  font-size:60px; font-weight:800; line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.hero-primary-btn.is-green .hero-primary-num{ color:var(--pass); }
.hero-primary-btn.is-amber .hero-primary-num{ color:#B07A12; }
.hero-primary-btn.is-red .hero-primary-num{ color:var(--fail); }
.hero-primary-cap{ font-size:13px; font-weight:600; color:var(--ink-dim); margin-top:6px; }
.hero-delta{ font-size:12.5px; color:var(--ink-faint); }
.hero-delta.is-up{ color:var(--pass); }
.hero-delta.is-down{ color:var(--fail); }

@media (prefers-color-scheme: dark){
  .hero-primary-btn.is-amber .hero-primary-num{ color:#E2A93B; }
  .hero-health-lead.is-minor{ color:#E2A93B; }
  .hero-health-lead.is-oos{ color:#E06A60; }
  .donut-arc.is-oos, .health-swatch.is-oos{ stroke:#B3261E; }
}

/* -- needs attention: the ONE place these four numbers live -- */
.attn-chip.is-zero{
  display:inline-flex; align-items:center; gap:8px; padding:8px 14px;
  border-radius:var(--radius-s); background:transparent; border:1px dashed var(--line);
  color:var(--ink-faint); font-size:13px;
}
.attn-chip.is-zero .count{ font-weight:700; font-size:15px; }
/* Remove from service dominates whenever it is not zero. Size and weight, not
   just colour: the owner asked for one thing to be unmistakably first. */
.attn-chip.is-lead{ padding:12px 18px; }
.attn-chip.is-lead .count{ font-size:30px; }
.attn-chip.is-lead .attn-chip-label{ font-weight:700; }

/* -- progressive disclosure for the quiet numbers -- */
.secondary-disclosure{ margin-bottom:18px; }
.secondary-disclosure > summary{
  cursor:pointer; font-size:13px; color:var(--ink-faint); list-style:none;
  padding:8px 0; width:fit-content;
}
.secondary-disclosure > summary::-webkit-details-marker{ display:none; }
.secondary-disclosure > summary::before{ content:"+ "; font-family:var(--font-mono); }
.secondary-disclosure[open] > summary::before{ content:"- "; }
.secondary-disclosure > summary:hover{ color:var(--ink); }
.secondary-disclosure > summary:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }

.filters-more{ margin:-6px 0 18px; }
.filters-more > summary{
  cursor:pointer; font-size:13px; color:var(--ink-faint); list-style:none;
  padding:6px 0; width:fit-content;
}
.filters-more > summary::-webkit-details-marker{ display:none; }
.filters-more > summary::before{ content:"+ "; font-family:var(--font-mono); }
.filters-more[open] > summary::before{ content:"- "; }
.filters-more > summary:hover{ color:var(--ink); }
.filters-more > summary:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }

/* -- defect group headers now carry count and oldest age -- */
.group-row .group-label{ font-weight:700; }
.group-row .group-count{
  display:inline-block; margin-left:10px; font-variant-numeric:tabular-nums; font-weight:700;
}
.group-row .group-age{
  display:inline-block; margin-left:12px; font-size:12px; font-weight:500;
  color:var(--ink-faint); text-transform:none; letter-spacing:0;
}

/* ---------- status pill, red / amber / green (WEB ROUND 2 items 11, 12) ----------
   ONE pill, used by the compliance report, the maintenance report and the
   reminders list, so the same state cannot look different on two pages. The
   band itself is decided in models.js STATUS_THRESHOLDS, never here: CSS
   picks the colour, it does not pick the meaning.

   Colour is never the only signal. Every pill carries its own text ("92%",
   "Overdue"), so a red/green colour blind reader loses nothing, and the guide
   table below spells each band out in words. */
.status-pill{
  display:inline-block; padding:3px 9px; border-radius:99px;
  font-size:12.5px; font-weight:600; font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.status-none{ color:var(--ink-faint); }
.status-pill.is-green{ background:color-mix(in srgb, var(--pass) 16%, transparent); color:var(--pass); }
.status-pill.is-amber{ background:color-mix(in srgb, #E2A93B 18%, transparent); color:#B07A12; }
.status-pill.is-red{ background:color-mix(in srgb, var(--fail) 15%, transparent); color:var(--fail); }

@media (prefers-color-scheme: dark){
  /* The amber text darkened for contrast on light needs to go the other way
     on a dark ground. */
  .status-pill.is-amber{ color:#E2A93B; }
}

/* ---------- report guide (WEB ROUND 2 item 11) ----------
   The "so what" the owner asked for: the formula, then what each colour means
   and what to do about it. Sits UNDER the table on purpose. A manager who
   already knows how to read the report should meet the data first. */
.report-guide{ margin-bottom:20px; padding:18px 20px; }
.report-guide .guide-title{ font-size:15px; margin-bottom:10px; }
.report-guide .guide-formula{
  font-size:13.5px; color:var(--ink-dim); line-height:1.55; margin-bottom:14px;
  max-width:70ch;
}
.report-guide .guide-table{ width:100%; border-collapse:collapse; font-size:13.5px; }
.report-guide .guide-table th{
  text-align:left; font-family:var(--font-mono); font-size:10.5px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-faint); font-weight:600;
  padding:0 14px 8px 0; border-bottom:1px solid var(--line);
}
.report-guide .guide-table td{
  padding:10px 14px 10px 0; border-bottom:1px solid var(--line);
  color:var(--ink-dim); vertical-align:top; line-height:1.5;
}
.report-guide .guide-table tr:last-child td{ border-bottom:none; }
.report-guide .guide-table td:first-child{ white-space:nowrap; }

@media (max-width:640px){
  /* Three columns of prose do not fit a phone. Stack them, keeping the pill
     as the row's heading. */
  .report-guide .guide-table thead{ display:none; }
  .report-guide .guide-table tr{ display:block; padding:10px 0; border-bottom:1px solid var(--line); }
  .report-guide .guide-table td{ display:block; padding:2px 0; border-bottom:none; }
}

/* ---------- guided tour (WEB ROUND 2 items 2 and 7) ----------
   Sits ABOVE the page but BELOW the modal backdrop (z-index 100), because a
   tour annotates the page and a modal is a decision that must win.

   The spotlight is a ring, not a full screen mask, so the page underneath
   stays readable and clickable. That is the point: this teaches a live page
   rather than replacing it with a slideshow. pointer-events:none keeps the
   ring from swallowing a click on the very control it is pointing at. */
.tour-spotlight{
  position:fixed; z-index:90; pointer-events:none; border-radius:var(--radius-s);
  border:2px solid var(--accent);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
}
.tour-bubble{
  position:fixed; z-index:91; width:min(320px, calc(100vw - 24px));
  background:var(--bg-raised); border:1px solid var(--line-strong);
  border-radius:var(--radius-m); box-shadow:var(--shadow); padding:16px 18px;
}
.tour-bubble .tour-step{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-faint); margin-bottom:6px;
}
.tour-bubble .tour-title{ font-size:15px; font-weight:700; margin-bottom:6px; }
.tour-bubble .tour-body{ font-size:13.5px; color:var(--ink-dim); line-height:1.5; margin-bottom:14px; }
.tour-actions{ display:flex; align-items:center; gap:8px; }
.tour-actions .tour-spacer{ flex:1; }
.tour-actions .btn{ padding:6px 12px; font-size:13px; }
.tour-actions .btn[hidden]{ display:none; }

@media (max-width:640px){
  /* Pinned to the bottom on a phone. A bubble chasing a target on a small
     screen ends up covering the thing it is describing. */
  .tour-bubble{ left:12px !important; right:12px; width:auto; top:auto !important; bottom:12px; }
}

/* ---------- inline field suggestion (WEB ROUND 2 item 9) ----------
   A hint under an input that offers a value the system already knows, with a
   button to accept it. A button and not a link: it does not navigate. */
.odo-suggestion{ margin-top:6px; font-size:12px; color:var(--ink-faint); }
.linklike{
  font:inherit; border:none; background:none; padding:0; cursor:pointer;
  color:var(--accent); text-decoration:underline;
}
.linklike:hover{ color:var(--ink); }
.linklike:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:2px; }

/* ---------- severity / status chips ---------- */
.chip-minor{ background:color-mix(in srgb, var(--accent) 18%, transparent); color:var(--accent); }
.chip-major{ background:color-mix(in srgb, #E2A93B 20%, transparent); color:#E2A93B; }
.chip-oos{ background:color-mix(in srgb, var(--fail) 20%, transparent); color:var(--fail); }

.status-dot{ width:10px; height:10px; border-radius:99px; display:inline-block; flex-shrink:0; }
.status-dot.is-in-service{ background:var(--pass); }
.status-dot.is-out-of-service{ background:var(--fail); }
.status-dot.is-repair-scheduled{ background:#E2A93B; }

/* ---------- empty state ---------- */
.empty-state{ text-align:center; padding:60px 20px; color:var(--ink-faint); }
.empty-state svg{ width:36px; height:36px; margin:0 auto 14px; opacity:.6; }
.empty-state p{ font-size:14px; max-width:36ch; margin:0 auto; }

/* ---------- filters row ---------- */
.filters-row{ display:flex; flex-wrap:wrap; gap:14px; align-items:flex-end; margin-bottom:22px; }
.filters-row .field{ margin-bottom:0; min-width:160px; }

/* ==========================================================================
   Dashboard command center (2026-08 redesign) — additive section only.
   ========================================================================== */

/* Severity weight overrides (cascade wins over the earlier chip rules).
   House rule: out of service is ALWAYS the most prominent — filled dark red,
   white text. Major is a strong red outline. Minor is a quiet amber. */
.chip-oos{ background:#7a0c0c; color:#fff; border:1px solid #7a0c0c; }
.chip-major{ background:transparent; color:var(--fail); border:1px solid color-mix(in srgb, var(--fail) 70%, transparent); }
.chip-minor{ background:color-mix(in srgb, #E2A93B 12%, transparent); color:color-mix(in srgb, #E2A93B 80%, var(--ink-dim)); border:1px solid transparent; }
.chip-pass{ border:1px solid transparent; }
.chip-status-open{
  background:transparent; color:#E2A93B;
  border:1.5px solid color-mix(in srgb, #E2A93B 80%, var(--fail));
}

/* ---------- KPI cards ---------- */
.kpi-card{
  font:inherit; text-align:left; cursor:pointer; color:var(--ink);
  display:flex; flex-direction:column; gap:2px; min-height:92px;
  transition:border-color .12s ease, background .12s ease;
}
.kpi-card:hover{ border-color:var(--ink-dim); background:color-mix(in srgb, var(--ink) 4%, var(--bg-elevated)); }
.kpi-card:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.kpi-card.is-urgent{
  border-color:color-mix(in srgb, var(--fail) 60%, var(--line));
  background:color-mix(in srgb, var(--fail) 7%, var(--bg-elevated));
}
.kpi-top{ display:flex; align-items:center; gap:10px; }
.kpi-ring{ width:34px; height:34px; flex-shrink:0; color:var(--pass); }
.kpi-card .num.bad{ color:var(--fail); }
.kpi-ring.is-low{ color:var(--fail); }
.kpi-sub{ font-size:12px; color:var(--ink-dim); margin-top:2px; }
.kpi-sub.bad{ color:var(--fail); }

/* ---------- fleet health card (2026-08-27 redesign) — additive ---------- */
.kpi-health-top{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 14px; margin-bottom:4px; }
.kpi-donut{ width:78px; height:78px; flex-shrink:0; }
.kpi-donut text{ font-family:inherit; }
.kpi-health-counts{ display:flex; flex-direction:column; gap:3px; font-size:13px; font-weight:600; }
.kpi-health-counts > div{ white-space:nowrap; }
/* Sizing only, deliberately NO colour. ROUND 3 item 12: the breakdown
   swatch used to be a coloured div here, and its .is-red had drifted to
   #7a0c0c, the same dark red as the donut's .is-oos, so major and out of
   service rendered identically in the breakdown while the donut showed
   them apart. The swatch is now an inline SVG carrying the SAME
   .donut-arc.is-* classes the arcs carry, so those rules are the one and
   only place these four colours are defined. Do not add a colour here. */
.health-dot{ display:inline-block; width:8px; height:8px; border-radius:99px; margin-right:7px; }
.kpi-health-chips{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:6px; }
.kpi-chips-label{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint);
}
.kpi-ready-line{
  font-size:12px; color:var(--ink-dim);
  margin-top:8px; padding-top:7px; border-top:1px solid var(--line);
}

/* ---------- needs-attention strip ---------- */
.action-strip{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin-bottom:22px; }
.action-strip-label{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint);
}
.action-item{
  font:inherit; font-size:13px; font-weight:600; cursor:pointer;
  display:inline-flex; align-items:center; gap:8px; padding:8px 14px;
  border-radius:99px; border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink);
  transition:border-color .12s ease;
}
.action-item:hover{ border-color:var(--ink-dim); }
.action-item .count{ font-family:var(--font-mono); font-weight:700; }
.action-item.is-oos{ border-color:#7a0c0c; }
.action-item.is-oos .count{ color:#ff9d94; }
.action-item.is-major .count{ color:var(--fail); }
.action-item.is-maint .count{ color:#E2A93B; }
.all-clear{ font-size:13px; color:var(--pass); margin-bottom:22px; }

/* ---------- saved views + active filter chips ---------- */
.views-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
.views-label{ font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); }
.view-chip{
  font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
  display:inline-flex; align-items:center; gap:6px; padding:5px 12px;
  border-radius:99px; border:1px solid var(--line); background:transparent; color:var(--ink-dim);
}
.view-chip:hover{ border-color:var(--accent); color:var(--accent); }
.view-chip .x{ display:inline-flex; padding:0 0 0 2px; color:var(--ink-faint); }
.view-chip .x:hover{ color:var(--fail); }
.view-chip .x svg{ width:13px; height:13px; }

.chip-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
.filter-chip{
  display:inline-flex; align-items:center; gap:7px; padding:5px 8px 5px 12px;
  border-radius:99px; font-size:12.5px; font-weight:600;
  background:color-mix(in srgb, var(--accent) 14%, transparent); color:var(--accent);
}
.filter-chip button{
  font:inherit; border:none; background:none; color:inherit; cursor:pointer;
  display:inline-flex; padding:0; opacity:.75; line-height:1;
}
.filter-chip button:hover{ opacity:1; }
/* Same 0x0 icon bug as .modal-close, see components.js icon(). */
.filter-chip button svg{ width:13px; height:13px; }
.chip-row .clear-all{
  font:inherit; font-size:12.5px; border:none; background:none; color:var(--ink-faint);
  cursor:pointer; text-decoration:underline;
}
.chip-row .clear-all:hover{ color:var(--ink); }

/* ---------- defect table upgrades ---------- */
.dd-table td.cell-desc-td{ max-width:340px; }
.cell-desc{
  display:inline-block; max-width:280px; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; vertical-align:bottom;
}
.cell-icons{ display:inline-flex; align-items:center; gap:6px; margin-left:8px; vertical-align:middle; }
.cam-icon{ width:15px; height:15px; color:var(--ink-faint); flex-shrink:0; }
.wo-chip{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.04em; padding:2px 7px;
  border-radius:99px; border:1px solid var(--line-strong); color:var(--ink-dim); white-space:nowrap;
}
.vehicle-link{ color:var(--ink); text-decoration:underline; text-decoration-color:var(--line-strong); text-underline-offset:3px; }
.vehicle-link:hover{ color:var(--accent); text-decoration-color:var(--accent); }
.age-stale{ color:var(--fail); font-weight:600; }
.btn-mini{
  font:inherit; font-size:12px; font-weight:600; cursor:pointer;
  padding:4px 10px; border-radius:var(--radius-s);
  border:1px solid var(--line-strong); background:transparent; color:var(--ink-dim);
}
.btn-mini:hover{ border-color:var(--accent); color:var(--accent); }
.dd-table .col-check{ width:34px; padding-right:0; }
.dd-table input[type="checkbox"]{ accent-color:var(--accent); cursor:pointer; width:15px; height:15px; }

/* group header rows */
.dd-table tr.group-row td{
  font-family:var(--font-mono); font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); background:var(--bg); padding-top:14px; padding-bottom:8px;
}
.dd-table tr.group-row.is-danger td{ color:#ff9d94; }
.dd-table tr.group-row.is-toggle{ cursor:pointer; }
.dd-table tr.group-row.is-toggle:hover td{ color:var(--ink); }
.group-chevron{ width:13px; height:13px; vertical-align:-2px; margin-right:6px; transition:transform .12s ease; }
.group-chevron.is-open{ transform:rotate(90deg); }

/* bulk bar */
.bulk-bar{
  display:flex; align-items:center; gap:14px; margin-bottom:10px; padding:9px 14px;
  border:1px solid var(--line-strong); border-radius:var(--radius-s);
  background:var(--bg-raised); font-size:13px;
}
.bulk-bar .bulk-count{ font-family:var(--font-mono); font-weight:700; }

/* ==========================================================================
   Vendor packet builder (work-orders rebuild, 2026-08) — additive only.
   ========================================================================== */

/* success banner, sibling of .banner-error above */
.banner-ok{
  background:color-mix(in srgb, var(--pass) 12%, transparent); color:var(--pass);
  border:1px solid color-mix(in srgb, var(--pass) 35%, var(--line));
}

.packet-lede{ font-size:14px; color:var(--ink-dim); max-width:64ch; margin:-10px 0 22px; }

/* ---------- two-panel layout ---------- */
.packet-builder{
  display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:22px;
  align-items:start; margin-bottom:36px;
}
@media (max-width:1100px){
  .packet-builder{ grid-template-columns:1fr; }
}

.packet-col-head{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:14px; }
.packet-col-head h2{ font-size:15px; }
.packet-col-hint{ font-size:12px; color:var(--ink-faint); }
.packet-filters{ margin-bottom:16px; }
.packet-filters .field{ min-width:140px; }
.packet-search-field{ flex:1; min-width:180px; }

/* ---------- source list ---------- */
.source-group{ margin-bottom:18px; }
.source-group-head{
  display:flex; align-items:center; gap:10px; padding:9px 12px;
  border:1px solid var(--line-strong); border-radius:var(--radius-s);
  background:var(--bg-raised); cursor:grab; margin-bottom:8px;
}
.source-group-head:active{ cursor:grabbing; }
.source-group-head .grip{ color:var(--ink-faint); display:inline-flex; flex-shrink:0; }
.source-group-head .grip svg{ width:14px; height:14px; }
.source-group-title{ font-weight:700; font-size:14px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.source-group-status{ font-size:12px; color:var(--ink-dim); display:inline-flex; align-items:center; gap:6px; flex-shrink:0; }
.source-group-head .btn-mini{ margin-left:auto; flex-shrink:0; }

.source-row{
  display:flex; align-items:center; gap:10px; padding:8px 12px 8px 10px;
  border:1px solid var(--line); border-radius:var(--radius-s);
  background:var(--bg-raised); margin:0 0 6px 14px; cursor:grab;
}
.source-row:active{ cursor:grabbing; }
.source-row:hover{ border-color:var(--ink-dim); }
.source-row.is-dragging{ opacity:.45; }
.source-row .chip{ flex-shrink:0; }
.source-row-desc{
  min-width:0; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:13.5px;
}
.source-row-meta{ font-size:12px; color:var(--ink-faint); flex-shrink:0; display:inline-flex; align-items:center; gap:8px; }
.source-row-meta .cam-icon{ width:14px; height:14px; }
.source-row .btn-mini{ flex-shrink:0; }
.source-row.is-added{ border-style:dashed; opacity:.6; }
.source-row.is-added .btn-mini{ border-color:transparent; color:var(--ink-faint); cursor:default; }

/* reminder due-state chips (house weights: overdue red, due soon quiet amber) */
.chip-rem-hard{ background:transparent; color:var(--fail); border:1px solid color-mix(in srgb, var(--fail) 70%, transparent); }
.chip-rem-soft{ background:color-mix(in srgb, #E2A93B 12%, transparent); color:color-mix(in srgb, #E2A93B 80%, var(--ink-dim)); border:1px solid transparent; }

/* ---------- packet panel ---------- */
.packet-panel{
  border:1px solid var(--line-strong); border-radius:var(--radius-m);
  background:var(--bg-raised); padding:18px;
  position:sticky; top:24px;
}
@media (max-width:1100px){
  .packet-panel{ position:static; }
}
.packet-panel-title{ font-size:15px; margin-bottom:12px; }
.packet-panel.is-drag-over{
  border-color:var(--accent);
  background:color-mix(in srgb, var(--accent) 6%, var(--bg-raised));
}
.packet-drop-hint{
  border:1.5px dashed var(--line-strong); border-radius:var(--radius-s);
  padding:26px 16px; text-align:center; font-size:13px; color:var(--ink-faint);
  margin-bottom:14px;
}
.packet-panel.is-drag-over .packet-drop-hint{ border-color:var(--accent); color:var(--accent); }

.packet-group{ margin-bottom:12px; }
.packet-group-title{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); margin-bottom:6px;
}
.packet-item{
  display:flex; align-items:center; gap:8px; padding:6px 8px 6px 10px;
  border:1px solid var(--line); border-radius:var(--radius-s);
  background:var(--bg); margin-bottom:5px; font-size:13px;
}
.packet-item .chip{ flex-shrink:0; }
.packet-item-desc{ min-width:0; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.packet-item-remove{
  font:inherit; border:none; background:none; color:var(--ink-faint); cursor:pointer;
  display:inline-flex; padding:2px; flex-shrink:0;
}
.packet-item-remove:hover{ color:var(--fail); }
.packet-item-remove svg{ width:13px; height:13px; }
.packet-item.flash{ animation:packet-flash .8s ease; }
@keyframes packet-flash{
  0%{ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 18%, var(--bg)); }
  100%{ border-color:var(--line); background:var(--bg); }
}

.packet-summary{ font-size:13px; color:var(--ink-dim); margin:2px 0 14px; }
.packet-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:14px; }

.wo-history-title{ font-size:15px; margin-bottom:12px; }

/* ---------- packet document (paper-styled on screen AND in print) ---------- */
.packet-doc-actions{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:18px; }
.packet-doc-actions-right{ display:flex; gap:10px; flex-wrap:wrap; }

.packet-doc{
  background:#ffffff; color:#111111; border:1px solid var(--line);
  border-radius:var(--radius-m); padding:44px 48px; max-width:820px;
  font-family:var(--font-sans); line-height:1.5;
}
@media (max-width:640px){ .packet-doc{ padding:24px 18px; } }
.packet-doc .pd-company{ font-family:var(--font-display); font-weight:800; font-size:21px; margin:0; color:#111; }
.packet-doc .pd-title{ font-size:15px; font-weight:700; margin:2px 0 0; color:#111; }
.packet-doc .pd-meta{ font-size:12.5px; color:#555; margin:2px 0 0; }
.packet-doc .pd-rule{ border:none; border-top:2px solid #111; margin:16px 0 0; }
.packet-doc .pd-vehicle{ margin-top:26px; }
.packet-doc .pd-vehicle-name{ font-size:16px; font-weight:800; margin:0; color:#111; }
.packet-doc .pd-vehicle-profile{ font-size:12.5px; color:#444; margin:3px 0 0; }
.packet-doc .pd-section-label{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.07em; text-transform:uppercase;
  color:#777; margin:14px 0 6px;
}
.packet-doc .pd-entry{ border-left:3px solid #bbb; padding:3px 0 3px 12px; margin:0 0 10px; }
.packet-doc .pd-entry.pd-oos{ border-left-color:#7a0c0c; }
.packet-doc .pd-entry.pd-major{ border-left-color:#c0392b; }
.packet-doc .pd-entry p{ margin:0; font-size:13.5px; color:#111; }
.packet-doc .pd-entry .pd-entry-meta{ font-size:12px; color:#666; margin-top:2px; }
.packet-doc .pd-entry img{ max-width:340px; max-height:260px; border:1px solid #ddd; margin-top:8px; display:block; }
.packet-doc .pd-photo-note{ font-size:12px; color:#888; margin-top:4px; }
.packet-doc .pd-chip{
  display:inline-block; font-size:11px; font-weight:700; padding:1px 8px; border-radius:3px;
  margin-right:6px; vertical-align:1px;
}
.packet-doc .pd-chip-oos{ background:#7a0c0c; color:#ffffff; }
.packet-doc .pd-chip-major{ color:#c0392b; border:1px solid #c0392b; }
.packet-doc .pd-chip-minor{ color:#a07408; border:1px solid #d9b45e; }
.packet-doc .pd-chip-overdue{ color:#c0392b; border:1px solid #c0392b; }
.packet-doc .pd-chip-due{ color:#a07408; border:1px solid #d9b45e; }
.packet-doc .pd-notes{ margin-top:26px; padding:12px 14px; background:#f6f5f1; border-radius:6px; }
.packet-doc .pd-notes p{ margin:0; font-size:13.5px; white-space:pre-wrap; }
.packet-doc .pd-footer{ margin-top:34px; padding-top:12px; border-top:1px solid #ddd; font-size:11.5px; color:#888; }
.packet-doc .pd-gone{ font-size:13px; color:#777; font-style:italic; margin:0 0 10px; }

/* ==========================================================================
   Trends & analytics rebuild (2026-08-28) — additive only. Headline tiles,
   the two weekly SVG charts, and the horizontal bar list. Chip and table
   styles come from the sections above unchanged.
   ========================================================================== */

/* ---------- headline tiles ---------- */
.trend-headline{ grid-template-columns:repeat(auto-fit,minmax(215px,1fr)); margin-bottom:22px; }
.trend-tile{ display:flex; flex-direction:column; }
.trend-tile .num.bad{ color:var(--fail); }
.trend-tile-sub{ font-size:12px; color:var(--ink-dim); margin-top:6px; }
.trend-chip-row{ display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; }
.trend-spark{ display:block; width:100%; height:28px; margin-top:auto; padding-top:9px; }

/* ---------- chart panels ---------- */
.trend-panel{ margin-bottom:22px; }
.trend-panel h2{ font-size:15px; margin-bottom:14px; }
.trend-chart svg{ display:block; width:100%; height:auto; }
.trend-chart .gridline{ stroke:var(--line); stroke-width:1; }
.trend-chart .axis-label{ fill:var(--ink-faint); font-family:var(--font-mono); font-size:10px; }
.chart-legend{ display:flex; flex-wrap:wrap; gap:4px 16px; font-size:12.5px; color:var(--ink-dim); margin-bottom:10px; }
.chart-legend .swatch{ display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:6px; vertical-align:-1px; }
.chart-legend:empty{ display:none; }
.chart-takeaway{ font-size:13px; font-weight:600; color:var(--ink); margin-top:12px; }
.chart-takeaway:empty{ display:none; }
.chart-note{ font-size:12px; color:var(--ink-faint); margin-top:5px; }

/* ---------- horizontal bar list (most failed items) ---------- */
.hbar-row{ display:flex; align-items:center; gap:12px; margin-bottom:9px; }
.hbar-row:last-child{ margin-bottom:0; }
.hbar-label{ flex:0 0 250px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13.5px; }
.hbar-track{ flex:1; height:9px; border-radius:99px; background:var(--bg-elevated); overflow:hidden; }
.hbar-fill{ height:100%; border-radius:99px; background:var(--accent); }
.hbar-count{ flex:0 0 auto; min-width:3ch; text-align:right; font-family:var(--font-mono); font-size:13px; font-variant-numeric:tabular-nums; }
@media (max-width:640px){ .hbar-label{ flex-basis:130px; font-size:12.5px; } }

/* print: the packet document only, clean on paper */
@media print{
  body.packet-doc-open .portal-topbar,
  body.packet-doc-open .portal-sidebar,
  body.packet-doc-open .packet-doc-actions,
  body.packet-doc-open #doc-error,
  body.packet-doc-open #doc-notice,
  body.packet-doc-open #builder-view{ display:none !important; }
  body.packet-doc-open{ background:#ffffff; }
  body.packet-doc-open .portal-shell{ display:block; }
  body.packet-doc-open .portal-main{ padding:0; }
  body.packet-doc-open .packet-doc{
    border:none; border-radius:0; padding:0; max-width:none;
  }
  body.packet-doc-open .pd-vehicle{ break-inside:avoid; }
}

/* ==========================================================================
   Info tooltips (BL-36 item 1) — additive only. The icon is a span (it can
   sit inside KPI card buttons), the popup is one shared fixed-position box
   appended to <body> by components.js.
   ========================================================================== */
.info-tip{
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; border-radius:99px; flex-shrink:0;
  border:1px solid var(--line-strong); color:var(--ink-faint);
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  line-height:1; cursor:pointer; vertical-align:-2px; margin-left:7px;
  text-transform:none; letter-spacing:0;
  user-select:none; -webkit-user-select:none;
}
.info-tip::before{ content:"i"; }
.info-tip:hover{ color:var(--accent); border-color:var(--accent); }
.info-tip:focus-visible{
  color:var(--accent); border-color:var(--accent);
  outline:2px solid var(--accent); outline-offset:2px;
}
.info-tip-pop{
  position:fixed; z-index:200; max-width:290px;
  background:var(--bg-elevated); border:1px solid var(--line-strong);
  border-radius:var(--radius-s); padding:10px 13px;
  font-family:var(--font-sans); font-size:12.5px; font-weight:400; line-height:1.55;
  color:var(--ink); box-shadow:var(--shadow);
  white-space:normal; text-transform:none; letter-spacing:0; text-align:left;
}

/* tooltips have no place on paper */
@media print{
  .info-tip, .info-tip-pop{ display:none !important; }
}

/* ==========================================================================
   BL-36 items 7 + 8 (2026-08-29) — additive only.
   Item 8: dashboard redesign (hero fleet-health row, needs-attention chips,
   quieter secondary metrics, defect-list upgrades, contrast bumps).
   Item 7: portal-wide repair scheduler modal.
   ========================================================================== */

/* ---------- contrast bumps (owner: body text low-contrast on dark cards) -- */
.stat-box .cap{ color:var(--ink-dim); font-size:12px; }
.kpi-sub{ color:color-mix(in srgb, var(--ink) 62%, transparent); }
.dd-table tr.group-row td{ color:var(--ink-dim); }

/* ---------- hero "Fleet health at a glance" ---------- */
.hero-panel{ padding:18px 20px 16px; margin-bottom:16px; }
.hero-panel h2{ font-size:15px; margin-bottom:12px; }
/* Proportions rebuilt for WEB ROUND 2 item 13. Edited IN PLACE rather than
   overridden from the new block above, because a second .hero-grid rule at
   equal specificity earlier in the file would simply lose to this one and ship
   as dead code. align-items:center, not stretch: the three cells are a circle,
   one big number and a small chart, and stretching them made the number float
   in a tall box. */
.hero-grid{
  display:grid; grid-template-columns:minmax(240px,1fr) minmax(180px,auto) minmax(220px,1.2fr);
  gap:26px; align-items:center;
}
@media (max-width:1100px){ .hero-grid{ grid-template-columns:1fr 1fr; } }
@media (max-width:720px){ .hero-grid{ grid-template-columns:1fr; gap:20px; } }
@media (max-width:700px){ .hero-grid{ grid-template-columns:1fr; } }

.hero-left{ display:flex; align-items:center; gap:18px; flex-wrap:wrap; }
.hero-ring-btn{
  font:inherit; background:none; border:none; padding:0; cursor:pointer;
  color:inherit; display:block;
}
.hero-ring-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; border-radius:99px; }
.hero-ring-wrap{ position:relative; width:158px; height:158px; flex-shrink:0; }
.hero-ring-svg{ position:absolute; inset:0; width:100%; height:100%; }
.hero-ring-wrap.is-green{ color:var(--pass); }
.hero-ring-wrap.is-amber{ color:#E2A93B; }
.hero-ring-wrap.is-red{ color:var(--fail); }
.hero-ring-center{
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; text-align:center; gap:1px; padding:22px;
}
.hero-ring-pct{ font-family:var(--font-mono); font-size:31px; font-weight:700; font-variant-numeric:tabular-nums; line-height:1; }
.hero-ring-cap{ font-size:11.5px; font-weight:600; color:var(--ink); line-height:1.25; }
.hero-ring-delta{ font-size:11px; color:var(--ink-dim); line-height:1.3; }
.hero-ring-delta.is-down{ color:var(--fail); }
.hero-ring-delta.is-up{ color:var(--pass); }

.hero-health{ min-width:140px; flex:1; }
.hero-health-counts{ display:flex; flex-direction:column; gap:4px; font-size:13px; font-weight:600; }
.hero-health-counts > div{ white-space:nowrap; }
.hero-health-chips{ display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.hero-health .kpi-chips-label{ display:block; margin-top:10px; margin-bottom:4px; }

.hero-cards{ display:flex; flex-direction:column; gap:8px; justify-content:center; }
.hero-num-card{
  font:inherit; text-align:left; cursor:pointer; color:var(--ink);
  display:flex; align-items:center; gap:14px; padding:9px 14px 9px 16px;
  background:var(--bg-elevated); border:1px solid var(--line); border-radius:10px;
  transition:border-color .12s ease;
}
.hero-num-card:hover{ border-color:var(--ink-dim); }
.hero-num-card:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.hero-num-card .num{
  font-family:var(--font-mono); font-size:29px; font-weight:700;
  font-variant-numeric:tabular-nums; line-height:1; min-width:2ch;
}
.hero-num-card.is-oos{ box-shadow:inset 3px 0 0 #7a0c0c; }
.hero-num-card.is-oos .num{ color:#ff9d94; }
.hero-num-card.is-major{ box-shadow:inset 3px 0 0 var(--fail); }
.hero-num-card.is-major .num{ color:var(--fail); }
.hero-num-card.is-stale{ box-shadow:inset 3px 0 0 #E2A93B; }
.hero-num-card.is-stale .num{ color:#E2A93B; }
.hero-num-card.is-zero .num{ color:var(--ink-dim); }
.hero-num-label{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.hero-num-label b{ font-size:13px; font-weight:600; color:var(--ink); }
.hero-num-label span{ font-size:11.5px; color:var(--ink-dim); }

.hero-spark-card{
  display:flex; flex-direction:column; gap:6px;
  background:var(--bg-elevated); border:1px solid var(--line); border-radius:10px; padding:12px 14px;
}
.hero-spark-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.hero-spark-title{ font-size:12.5px; font-weight:600; color:var(--ink); }
.spark-toggle{ display:inline-flex; border:1px solid var(--line-strong); border-radius:99px; padding:2px; gap:2px; }
.spark-toggle button{
  font:inherit; border:none; background:transparent; padding:2px 10px; border-radius:99px;
  font-size:11px; font-weight:600; color:var(--ink-dim); cursor:pointer;
}
.spark-toggle button.is-active{ background:var(--accent); color:var(--accent-ink); }
.hero-spark-svg{ display:block; width:100%; height:56px; }
.hero-spark-now{ font-family:var(--font-mono); font-size:13px; font-weight:700; }
.spark-note{ font-size:11.5px; color:var(--ink-dim); }

/* ---------- needs-attention action bar (large clickable chips) ---------- */
.attn-bar{ display:flex; flex-wrap:wrap; align-items:stretch; gap:10px; margin-bottom:16px; }
.attn-bar .action-strip-label{ flex-basis:100%; margin-bottom:-2px; }
.attn-chip{
  font:inherit; text-align:left; cursor:pointer;
  display:flex; align-items:center; gap:12px; padding:10px 18px; min-width:150px;
  border-radius:12px; border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink);
  transition:border-color .12s ease, background .12s ease;
}
.attn-chip:hover{ border-color:var(--ink-dim); }
.attn-chip:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.attn-chip .count{
  font-family:var(--font-mono); font-size:24px; font-weight:700;
  font-variant-numeric:tabular-nums; line-height:1;
}
.attn-chip .attn-chip-label{ font-size:12.5px; font-weight:600; line-height:1.25; }
.attn-chip.is-oos{ background:#7a0c0c; border-color:#7a0c0c; color:#fff; }
.attn-chip.is-oos .count, .attn-chip.is-oos .attn-chip-label{ color:#fff; }
.attn-chip.is-oos:hover{ border-color:#a51212; background:#8c1010; }
.attn-chip.is-major{
  border-color:color-mix(in srgb, var(--fail) 55%, var(--line));
  background:color-mix(in srgb, var(--fail) 8%, var(--bg-raised));
}
.attn-chip.is-major .count{ color:var(--fail); }
.attn-chip.is-maint{
  border-color:color-mix(in srgb, #E2A93B 45%, var(--line));
  background:color-mix(in srgb, #E2A93B 7%, var(--bg-raised));
}
.attn-chip.is-maint .count{ color:#E2A93B; }
.attn-chip.is-stale .count{ color:var(--accent); }
.attn-chip.is-active{ outline:2px solid var(--accent); outline-offset:2px; }

/* ---------- secondary metrics row (quieter) ---------- */
.secondary-grid{ grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); margin-bottom:16px; }
.secondary-grid .kpi-card{ min-height:74px; padding:11px 14px; }
.secondary-grid .kpi-card .num{ font-size:19px; }
.secondary-grid .kpi-card .kpi-sub{ font-size:12px; }

/* ---------- tighter filter bar ---------- */
.filters-row.is-tight{ gap:10px; margin-bottom:12px; }
.filters-row.is-tight .field{ min-width:140px; }

/* ---------- defect list upgrades ---------- */
/* Sticky section headers need the wrap to stop being a scroll container on
   desktop (an overflow-x:auto ancestor kills vertical position:sticky).
   Scoped to the dashboard's .is-sticky wrap so wide tables on other pages
   keep their horizontal scroll untouched. */
@media (min-width:1000px){
  .dd-table-wrap.is-sticky{ overflow-x:visible; }
  /* wrapping cells keep the table inside its container at any desktop
     width, so overflow:visible never spills or forces a page scrollbar */
  .dd-table-wrap.is-sticky .dd-table{ white-space:normal; }
  .dd-table-wrap.is-sticky .dd-table .chip,
  .dd-table-wrap.is-sticky .dd-table .age-cell,
  .dd-table-wrap.is-sticky .dd-table tr.group-row td{
    position:sticky; top:0; z-index:3;
    background:var(--bg); border-bottom:1px solid var(--line);
  }
}
.dd-table tr.group-row.is-danger td{ box-shadow:inset 3px 0 0 var(--fail); }
.dd-table tr.group-row.is-majors td{ box-shadow:inset 3px 0 0 var(--accent); color:var(--ink-dim); }
.dd-table tr.row-sev-oos td:first-child{ box-shadow:inset 3px 0 0 #7a0c0c; }
.dd-table tr.row-sev-major td:first-child{ box-shadow:inset 3px 0 0 var(--fail); }
.dd-table tr.row-sev-minor td:first-child{ box-shadow:inset 3px 0 0 color-mix(in srgb, #E2A93B 55%, transparent); }

/* age intensity: quiet under 4 days, amber to 7, red past a week */
.age-cell{ display:inline-block; }
.age-tier-2{ color:#E2A93B; }
.age-tier-3{ color:var(--fail); font-weight:600; }
.age-bar{
  display:block; width:52px; height:3px; border-radius:99px;
  background:var(--bg-elevated); margin-top:4px; overflow:hidden;
}
.age-bar i{ display:block; height:100%; border-radius:99px; background:currentColor; opacity:.75; }

/* primary Repair action */
.btn-mini-primary{
  background:var(--accent); border-color:var(--accent); color:var(--accent-ink); font-weight:700;
}
.btn-mini-primary:hover{
  background:color-mix(in srgb, var(--accent) 88%, white 12%);
  border-color:var(--accent); color:var(--accent-ink);
}

/* ---------- repair scheduler modal (item 7) ---------- */
.sched-lede{ font-size:13.5px; color:var(--ink-dim); margin-bottom:14px; }
.sched-list{
  max-height:280px; overflow-y:auto; border:1px solid var(--line);
  border-radius:var(--radius-s); padding:8px; margin-bottom:8px;
}
.sched-loading{ font-size:13px; color:var(--ink-faint); padding:8px; }
.sched-row{
  display:flex; align-items:center; gap:10px; padding:8px 10px;
  border:1px solid var(--line); border-radius:var(--radius-s);
  margin-bottom:6px; cursor:pointer; background:var(--bg-raised);
}
.sched-row:last-child{ margin-bottom:0; }
.sched-row:hover{ border-color:var(--ink-dim); }
.sched-row.is-checked{ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 8%, var(--bg-raised)); }
.sched-row input[type="checkbox"]{ accent-color:var(--accent); width:15px; height:15px; flex-shrink:0; cursor:pointer; }
.sched-row-main{ flex:1; min-width:0; font-size:13.5px; font-weight:600; }
.sched-row-sub{
  display:block; font-size:11.5px; color:var(--ink-dim); font-weight:400;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sched-row-status{ font-size:11.5px; color:var(--ink-dim); flex-shrink:0; }
.sched-row-status.is-oos{ background:#7a0c0c; color:#fff; padding:2px 8px; border-radius:99px; font-weight:600; }
.sched-row-status.is-repair{ color:#E2A93B; }
.sched-count{ font-size:12.5px; color:var(--ink-dim); margin-bottom:12px; }
.sched-done{ font-size:14px; font-weight:600; }
.sched-done-list{ margin:10px 0 0 18px; font-size:13.5px; color:var(--ink-dim); }
.sched-done-list li{ margin-bottom:3px; }

/* ---------- company branding (BL-37 item 8) — additive only ---------- */
/* The img is inserted only after its signed URL resolves and stays hidden
   until it loads, so a company with no logo gets zero layout shift. */
.company-logo{ display:block; height:28px; max-width:140px; object-fit:contain; }
.company-logo[hidden]{ display:none; }
.portal-topbar .wordmark{ display:inline-flex; align-items:center; gap:10px; }
.sidebar-logo{ margin-bottom:8px; }
/* Settings preview */
.logo-preview-wrap{ margin-bottom:10px; }
.logo-preview{
  display:block; max-height:56px; max-width:240px; object-fit:contain;
  background:#fff; border:1px solid var(--line); border-radius:var(--radius-s); padding:6px;
}
/* Packet document header — sized only when the img exists, so an absent
   logo leaves the printable document exactly as before. */
.pd-logo{ display:block; height:44px; max-width:220px; object-fit:contain; margin-bottom:10px; }
.pd-logo[hidden]{ display:none; }

/* BL-37 item 11: vehicle profile photos on the vehicle modal (additive). */
.vehicle-photo-grid{ display:flex; flex-wrap:wrap; gap:12px; margin-top:4px; }
.vehicle-photo-card{ position:relative; width:132px; }
.vehicle-photo-card img{
  display:block; width:132px; height:96px; object-fit:cover; cursor:pointer;
  border:1px solid var(--line); border-radius:var(--radius-s); background:#0002;
}
.vehicle-photo-holder{
  display:flex; align-items:center; justify-content:center;
  width:132px; height:96px; font-size:11.5px; color:var(--ink-faint);
  border:1px dashed var(--line); border-radius:var(--radius-s);
}
.vehicle-photo-primary{
  position:absolute; top:5px; left:5px; padding:1px 7px;
  font-size:10.5px; font-weight:600; letter-spacing:0.02em;
  color:#fff; background:rgba(0,0,0,0.62); border-radius:999px;
  pointer-events:none;
}
.vehicle-photo-actions{ display:flex; gap:6px; margin-top:5px; }

/* ---------- BL-37 item 2/10: roles + incidents (v9) — additive only ---------- */
/* Sidebar footer role label under the technician's name. */
.sidebar-role{ display:block; font-size:11px; color:var(--ink-faint); margin-top:1px; }
/* Technician role modal: the six capability checkboxes. */
.cap-grid{ display:grid; grid-template-columns:1fr; gap:6px; margin-top:4px; }
.cap-row{ display:flex; align-items:center; gap:8px; font-size:13px; cursor:pointer; }
.cap-row input[type="checkbox"]{ accent-color:var(--accent); width:15px; height:15px; flex-shrink:0; cursor:pointer; }
/* One-time access code display. Mono, large, selectable — the plaintext
   exists exactly once, so it must be effortless to read and copy. */
.access-code-display{
  margin-top:10px; padding:12px 14px; border:1px dashed var(--ink-dim);
  border-radius:var(--radius-s); background:var(--bg-raised); text-align:center;
}
.access-code-value{
  font-family:"IBM Plex Mono", monospace; font-size:22px; font-weight:600;
  letter-spacing:0.35em; padding-left:0.35em; user-select:all;
}
/* Incident detail: the signature renders small — it is an attestation
   mark, not a photo. */
.incident-signature-img{
  display:block; max-width:220px; max-height:80px; object-fit:contain;
  background:#fff; border:1px solid var(--line); border-radius:var(--radius-s);
  padding:4px; margin-top:4px;
}

/* Odometer check on the dashboard day panel (BL-37 item 6 Phase A).
   Advisory, not an alarm: the accent tint marks it as worth a look without
   claiming a defect. Only rendered when a disagreement was actually found,
   so an empty state never needs styling. */
.day-mileage-flags{
  margin:10px 0 4px; padding:10px 12px; border-radius:var(--radius-s);
  border:1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
  background:color-mix(in srgb, var(--accent) 8%, transparent);
}
.day-mileage-title{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-faint); margin:0 0 6px;
}
.day-mileage-row{ font-size:12.5px; color:var(--ink-dim); margin:0 0 4px; }
.day-mileage-note{ font-size:11.5px; color:var(--ink-faint); margin:6px 0 0; }

/* ==========================================================================
   BL-37 item 9 Phase B (Wave 6) — web technician mode (inspect.html).
   Appended as its own block by this file's convention. Everything here is
   prefixed .tv- so it cannot collide with the manager portal's classes.

   This page has NO portal sidebar on purpose: technician view is a mode,
   and the surface it is designed for is a phone held in a yard. So the
   layout is a single centred column that stays comfortable from 360px up,
   with tap targets sized for gloves rather than a mouse.
   ========================================================================== */
.tv-shell{ min-height:100vh; display:flex; flex-direction:column; }

.tv-identity{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:12px 16px; border-bottom:1px solid var(--line);
  position:sticky; top:0; background:var(--bg); z-index:30;
}
.tv-id-left{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.tv-id-company{ font-size:13.5px; font-weight:600; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tv-id-mode{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--accent);
}
.tv-id-right{ display:flex; align-items:center; gap:10px; flex-shrink:0; }
.tv-id-who{ font-size:13px; color:var(--ink-dim); }

.tv-main{ flex:1; width:100%; max-width:680px; margin:0 auto; padding:20px 16px 80px; }
.tv-panel{ padding:18px 18px 20px; margin-bottom:16px; }
.tv-panel h2{ font-size:15px; margin:0 0 12px; }
.tv-loading{ color:var(--ink-faint); font-size:14px; padding:24px 0; text-align:center; }

.tv-form-head{ margin-bottom:16px; }
.tv-form-head h1{ font-size:22px; margin:0 0 4px; }
.tv-form-sub{ font-size:13px; color:var(--ink-faint); margin:0; }

.tv-locked-identity{
  font-size:15px; padding:12px 14px; border-radius:var(--radius-s);
  border:1px solid var(--line); background:var(--bg-elevated); color:var(--ink);
}

.tv-trip-banner{
  font-size:13.5px; color:var(--ink-dim); margin:0 0 16px;
  padding:11px 14px; border-radius:var(--radius-s);
  border:1px solid color-mix(in srgb, var(--accent) 30%, var(--line));
  background:color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Soft odometer sanity warning. Never a block, so it is amber-toned rather
   than using .banner-error's failure styling. */
.tv-warn{
  display:none; font-size:12.5px; color:#E2A93B; margin:8px 0 0;
}

.tv-carryover{ list-style:none; margin:0; padding:0; }
.tv-carryover li{
  font-size:13.5px; color:var(--ink-dim); padding:9px 0;
  border-top:1px solid var(--line); display:flex; align-items:baseline; gap:9px;
}
.tv-carryover li:first-child{ border-top:none; }

/* ---------- the walk-around accordion ---------- */
.tv-areas{ display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.tv-area{ border:1px solid var(--line); border-radius:var(--radius-s); overflow:hidden; }
.tv-area.is-open{ border-color:var(--line-strong); }
.tv-area-head{
  width:100%; display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 14px; background:var(--bg-elevated); border:none; cursor:pointer;
  font-family:var(--font-sans); font-size:14.5px; font-weight:600; color:var(--ink); text-align:left;
}
.tv-area-head:hover{ background:color-mix(in srgb, var(--accent) 6%, var(--bg-elevated)); }
.tv-area-name{ min-width:0; }
.tv-chip-unchecked{ background:var(--bg-raised); color:var(--ink-faint); border:1px solid var(--line); }
.tv-area-body{ padding:4px 14px 14px; border-top:1px solid var(--line); }

.tv-item{ padding:12px 0; border-top:1px solid var(--line); }
.tv-item:first-child{ border-top:none; }
.tv-item-label{ font-size:14px; color:var(--ink); margin-bottom:9px; }
/* Full-width three-up on a phone: Pass / Fail / N/A must be thumb targets,
   not the compact inline pill the manager pages use. */
.tv-item-seg{ display:flex; width:100%; }
.tv-item-seg button{ flex:1; padding:9px 4px; font-size:13px; }

.tv-defect{ margin-top:10px; }
.tv-defect textarea{
  font-family:var(--font-sans); font-size:14px; padding:10px 12px; width:100%;
  border-radius:var(--radius-s); border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink); resize:vertical;
}
.tv-defect textarea:focus{ outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent); }
.tv-defect-row{ display:flex; gap:10px; margin-top:9px; align-items:stretch; }
.tv-defect-row select{
  flex:1; font-family:var(--font-sans); font-size:13.5px; padding:9px 10px;
  border-radius:var(--radius-s); border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink);
}
.tv-photo-btn{
  display:inline-flex; align-items:center; justify-content:center; padding:9px 14px;
  border-radius:var(--radius-s); border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink-dim); font-size:13px; cursor:pointer; white-space:nowrap;
}
.tv-photo-btn:hover{ border-color:var(--accent); color:var(--accent); }
.tv-photo-btn input{ display:none; }

.tv-area-actions{ margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
.tv-other-issue{ display:flex; gap:8px; margin-top:10px; }
.tv-other-issue input{
  flex:1; font-family:var(--font-sans); font-size:13.5px; padding:9px 11px;
  border-radius:var(--radius-s); border:1px solid var(--line-strong);
  background:var(--bg-raised); color:var(--ink);
}

/* ---------- signature ---------- */
/* The pad is white in BOTH themes on purpose: what the person signs on has
   to be what gets stored, and the stored PNG is white paper with black ink
   because its destination is a printed DVIR. See the comment on
   captureSignature() in page-inspect.js. */
.tv-sig-wrap{ border:1px solid var(--line-strong); border-radius:var(--radius-s); overflow:hidden; background:#FFFFFF; }
.tv-sig{ display:block; width:100%; height:170px; touch-action:none; cursor:crosshair; }
@media (min-width:700px){ .tv-sig{ height:210px; } }

/* ---------- location ---------- */
.tv-loc{ font-size:14px; font-weight:600; margin:0 0 6px; }
.tv-loc-on{ color:var(--pass); }
.tv-loc-off{ color:var(--fail); }

/* ---------- submit ---------- */
.tv-block{ font-size:13px; color:var(--fail); margin:10px 0 0; text-align:center; }
.tv-abandon-row{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  margin-top:12px; font-size:12.5px; color:var(--ink-faint);
}

.tv-done h2{ font-size:18px; }
.tv-done p{ font-size:14px; color:var(--ink-dim); margin:0 0 18px; }
.tv-done-actions{ display:flex; gap:10px; flex-wrap:wrap; }

/* Entry point on the settings page. */
.tv-switch-note{ font-size:12.5px; color:var(--ink-faint); margin:10px 0 0; }

/* Phase B2: what happened to the DVIR PDF and its emailed copy. */
.tv-pdf{ font-size:13px; margin:0 0 12px; }
.tv-pdf-pending{ color:var(--ink-faint); }
.tv-pdf-ok{ color:var(--pass); }
.tv-pdf-warn{ color:#E2A93B; }

/* ==========================================================================
   BL-37 item 6 Phase B (Wave 7B) — where a vehicle went, in the vehicle modal.
   ========================================================================== */
.vm-last{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-size:13.5px; color:var(--ink); margin:2px 0 10px;
}
.vm-last-dot{
  width:8px; height:8px; border-radius:99px; background:var(--accent); flex-shrink:0;
}
.vm-last-when{ color:var(--ink-faint); font-size:12.5px; }
.vm-map{ font-size:12.5px; }

.vm-today{
  padding:10px 12px; border-radius:var(--radius-s);
  border:1px solid color-mix(in srgb, var(--accent) 28%, var(--line));
  background:color-mix(in srgb, var(--accent) 7%, transparent);
}
.vm-today-head{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-faint); margin-bottom:5px;
}
.vm-today-line{ font-size:13.5px; color:var(--ink); }

/* Compact enough that seven columns of a fortnight fit a modal without the
   table scrolling on a laptop. */
.vm-table th, .vm-table td{ padding:7px 10px; font-size:12.5px; }

.vm-note{ font-size:11.5px; color:var(--ink-faint); margin:10px 0 0; line-height:1.6; }
