/* ============================================================================
   DelPod Dashboard - visual system

   One slate neutral ramp, one teal accent, one elevation, one radius scale,
   one type scale. The slate ramp is anchored on the sidebar's existing
   #0F172A, so the dark chrome and the light content area are two ends of the
   SAME ramp rather than two unrelated greys - that shared origin is what
   makes the shell read as one product.

   Density target: data-dense SaaS (Linear / Stripe dashboard), not a
   marketing page. 44px table rows, 13px body, tight cards. Whitespace is
   spent on separating groups, not on padding out individual rows.
   ========================================================================= */

:root {
  /* ---- Brand - keep in sync with src/theme/colors.js ---- */
  --dropproof-teal: #5ed6d1;   /* BRAND_TEAL - accent/background only */
  --dropproof-black: #000000;  /* BRAND_BLACK */
  --action-blue: #2563eb;      /* ACTION_BLUE */
  --dropproof-teal-dark: #04342c;

  /* ---- Slate ramp. --slate-900 IS the sidebar colour. ---- */
  --slate-50:  #f8fafc;
  --slate-100: #f1f5f9;
  --slate-200: #e2e8f0;
  --slate-300: #cbd5e1;
  --slate-400: #94a3b8;
  --slate-500: #64748b;
  --slate-600: #475569;
  --slate-700: #334155;
  --slate-800: #1e293b;
  --slate-900: #0f172a;

  --white: #fff;
  --text: var(--slate-800);
  --text-strong: var(--slate-900);
  --muted: var(--slate-500);
  --bg: var(--slate-50);
  --border: var(--slate-200);
  --border-subtle: var(--slate-100);

  /* ---- Status. Two families only: teal = delivered, amber = not
     delivered (pending OR exception). Text is always a dark shade of the
     same family as its background, never a different hue. ---- */
  --status-teal-bg: #d9f2f0;
  --status-teal-text: #04342c;
  --status-teal-ring: rgba(4, 52, 44, 0.14);
  --status-amber-bg: #fdf0d5;
  --status-amber-text: #7c4a10;
  --status-amber-ring: rgba(124, 74, 16, 0.16);

  --green: #059669;
  --danger-text: #b91c1c;

  /* ---- Elevation. Cards are defined by their border; the shadow only
     lifts them a hair off the ground. Floating surfaces get --shadow-pop. */
  --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-pop: 0 12px 32px -8px rgba(15, 23, 42, 0.18), 0 0 0 1px rgba(15, 23, 42, 0.04);
  --ring-focus: 0 0 0 3px rgba(94, 214, 209, 0.32);

  --radius-card: 10px;
  --radius-control: 7px;

  /* ---- Sidebar ---- */
  --sidebar-bg: var(--slate-900);
  --sidebar-text: #94a3b8;
  --sidebar-text-strong: #e2e8f0;
  --sidebar-active-bg: rgba(94, 214, 209, 0.10);

  /* ---- Type. Five roles. Weight and colour carry importance beyond
     these sizes - we do not add more sizes to signal hierarchy. ---- */
  --fs-metric: 28px;
  --fs-title: 20px;   /* page heading */
  --fs-section: 14px; /* card/section heading */
  --fs-body: 13px;
  --fs-label: 12px;
  --fs-micro: 11px;   /* uppercase; sidebar dividers + table headers ONLY */

  --row-h: 44px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: Inter, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* cv11 = single-storey g, ss01 = alternate digits: Inter's dashboard
     defaults. Harmless no-ops on the fallback stack. */
  font-feature-settings: "cv11", "ss01";
  font-size: var(--fs-body);
  line-height: 1.45;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }

/* Numerals in data positions render at a fixed advance width so digits
   line up down a column - the difference between a data table and a text
   table set in a proportional face. */
.deliveries-table td,
.stat-value,
.detail-caption dd,
.toolbar-count {
  font-variant-numeric: tabular-nums;
}

/* ---- Login ------------------------------------------------------------- */
#login-view {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--bg);
}

/* An author `display` outranks the browser's [hidden] { display: none } at
   equal specificity, so without this guard `loginView.hidden = true` is
   silently ignored and the form stays on screen over the signed-in app.
   The same fix appears on .lightbox-overlay below. */
#login-view[hidden] { display: none; }

.login-card {
  width: 100%;
  max-width: 360px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 32px;
  display: flex;
  flex-direction: column;
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}

.login-brand .brand-logo { color: var(--dropproof-teal-dark); }

.login-card h1 {
  margin: 0;
  font-size: var(--fs-title);
  color: var(--text-strong);
}

.login-sub {
  color: var(--muted);
  margin: 4px 0 24px;
  font-size: var(--fs-body);
}

.login-card label {
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 6px;
}

.login-card label + input { margin-bottom: 16px; }

.login-card button {
  margin-top: 8px;
  min-height: 42px;
  padding: 10px 16px;
  border: none;
  border-radius: var(--radius-control);
  background: var(--slate-900);
  color: var(--white);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.login-card button:hover { background: var(--slate-800); }
.login-card button:focus-visible { outline: none; box-shadow: var(--ring-focus); }

.error-text {
  color: var(--danger-text);
  font-size: var(--fs-label);
  min-height: 16px;
  margin: 12px 0 0;
}

/* ---- Sidebar ----------------------------------------------------------- */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 232px;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  overflow-y: auto;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 56px;
  padding: 0 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}

.brand-logo {
  flex-shrink: 0;
  color: var(--dropproof-teal);
}

.sidebar-wordmark {
  color: var(--white);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* "Pod" in the lockup - its own span, but only so it can take a different
   colour. DelPod is one word at one size, so it inherits everything else. */
.lockup-pod {
  color: var(--dropproof-teal-dark);
}

/* Sequence order: what order a run is in, who set it, and what the learning
   has changed lately. Read-only apart from Reset to auto. */
.run-order {
  margin: 18px 0 8px;
  padding: 18px 20px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.run-order-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.run-order-mode { margin: 0; font-size: var(--fs-section); font-weight: 700; }
.run-order-sub { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-label); }
.run-order-subhead { margin: 18px 0 8px; font-size: var(--fs-label); font-weight: 700; color: var(--muted); }
.run-order-list {
  margin: 14px 0 0;
  padding-left: 22px;
  columns: 2;
  column-gap: 32px;
  font-size: var(--fs-label);
}
@media (max-width: 900px) { .run-order-list { columns: 1; } }
.run-order-list li { break-inside: avoid; padding: 3px 0; }
.run-order-pin {
  margin-left: 8px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--dropproof-teal-dark);
  background: #CFF3F0;
  border-radius: 999px;
  padding: 2px 8px;
}
.run-order-new {
  margin-left: 8px;
  font-size: 10.5px;
  font-weight: 800;
  color: #92400E;
  background: #FEF3C7;
  border-radius: 999px;
  padding: 2px 8px;
}
.run-order-history { margin: 0; padding: 0; list-style: none; }
.run-order-history li {
  padding: 8px 0;
  border-top: 1px solid var(--border);
  font-size: var(--fs-label);
}
.run-order-history .meta { color: var(--muted); }

.sidebar-wordmark .lockup-pod { color: var(--dropproof-teal); }

.sidebar-nav {
  display: flex;
  flex-direction: column;
  padding: 12px 8px;
  gap: 1px;
}

/* One of only two places uppercase micro-type is allowed (the other is the
   table header). Used sparingly it reads as structure; used on every label
   it flattens the hierarchy it is supposed to create. */
.nav-section-label {
  margin: 12px 0 4px;
  padding: 0 8px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--slate-600);
}

.sidebar-nav .nav-section-label:first-child { margin-top: 0; }

.sidebar-nav .tab-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 34px;
  padding: 0 8px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--sidebar-text);
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.tab-icon { flex-shrink: 0; opacity: 0.85; }

.sidebar-nav .tab-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  color: var(--sidebar-text-strong);
}

/* Active state is the accent's main job: teal mark + teal label on a faint
   teal wash. No left bar - the filled row is enough at this density. */
.sidebar-nav .tab-btn.active {
  background: var(--sidebar-active-bg);
  color: var(--dropproof-teal);
}

.sidebar-nav .tab-btn.active .tab-icon { opacity: 1; }

.sidebar-bottom {
  margin-top: auto;
  padding: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.sidebar-company {
  font-size: var(--fs-label);
  font-weight: 700;
  color: #e2e8f0;
}

.sidebar-bottom #user-email {
  font-size: var(--fs-label);
  color: var(--slate-400);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-signout {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  margin-left: -6px;
  padding: 0 6px;
  border-radius: 6px;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--fs-label);
  color: var(--slate-500);
  cursor: pointer;
}

.sidebar-signout:hover { color: var(--sidebar-text-strong); }

/* ---- Shell ------------------------------------------------------------- */
.content-area { margin-left: 232px; }

.content-header {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  height: 56px;
  padding: 0 24px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

main { padding: 24px; }

.page-title {
  margin: 0;
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-strong);
}

/* Controls that belong to a screen as a whole (the run picker, the driver
   it belongs to) rather than to one table. */
.page-toolbar {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.run-driver-line {
  font-size: var(--fs-body);
  color: var(--text);
}

.run-driver-line strong {
  font-weight: 500;
  color: var(--muted);
  margin-right: 6px;
}

/* ---- Stat cards -------------------------------------------------------- */
/* The Runs screen's headline. Four equal cards - the answer to "are we done
   yet" should be readable without parsing a table. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.stat-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.stat-label {
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
}

/* The run's two answers, in the app's own status families. */
#stat-delivered { color: var(--status-teal-text); }
#stat-exceptions { color: var(--status-amber-text); }

.stat-value {
  font-size: var(--fs-metric);
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}

.stat-sub {
  font-size: var(--fs-micro);
  color: var(--slate-400);
}

/* Sits where .stat-sub does on the other cards, so all four cards keep the
   same height and their numbers stay on one baseline. */
.progress-track {
  height: 5px;
  margin-top: 7px;
  border-radius: 999px;
  background: var(--slate-200);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--slate-700);
  transition: width 240ms ease;
}

/* Teal is reserved for a finished run - a partial bar stays neutral so
   "nearly done" never reads as "done". */
.progress-fill-complete { background: var(--dropproof-teal); }

/* ---- Next-stop ETA ------------------------------------------------------ */
/* One strip under the stat cards: where the driver is heading and when.
   The "last synced" note is the honest part - the ETA moves only when a
   phone's outbox drains, so a quiet strip means no signal, not a stall. */
/* Same [hidden] override as #login-view and .lightbox-overlay: the display
   below outranks the browser's [hidden] rule, so the empty ETA strip showed
   under a run with no sheet. Unreachable until the picker started listing
   runs that have not scanned today. */
.run-eta[hidden] { display: none; }
.run-eta {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "label name time"
    "label sub time"
    "label behind time"
    "label then time"
    "label updated time";
  column-gap: 16px;
  row-gap: 2px;
  align-items: center;
  padding: 12px 16px;
  margin-bottom: 20px;
  background: var(--white);
  border: 1px solid var(--border);
  border-left: 3px solid var(--dropproof-teal);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.run-eta-label {
  grid-area: label;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
}

.run-eta-name {
  grid-area: name;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-strong);
}

.run-eta-behind {
  grid-area: behind;
  margin-top: 4px;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--status-amber-text);
}

.run-eta-then {
  grid-area: then;
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  font-size: var(--fs-label);
  color: var(--muted);
}
.run-eta-then li { display: inline-flex; gap: 8px; align-items: baseline; }
.run-eta-then-name { color: var(--text); }
.run-eta-then-window { font-variant-numeric: tabular-nums; }
.run-eta-then-more { color: var(--slate-400); }
/* A stop the driver went past: amber, no time - the office picks up the phone. */
.run-eta-skipped, .roster-group {
  list-style: none;
  margin: 14px 0 4px;
  padding: 0 2px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.roster-eta-skipped, .run-eta-sub-skipped { color: var(--status-amber-text); font-weight: 600; }
.roster-eta-skipped::before { content: '\26A0  '; }

/* The projected window beside a pending stop on the sheet. */
.roster-eta {
  margin-left: auto;
  margin-right: 12px;
  font-size: var(--fs-label);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.run-eta-time {
  grid-area: time;
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.run-eta-sub {
  grid-area: sub;
  font-size: var(--fs-body);
  color: var(--muted);
}

.run-eta-updated {
  grid-area: updated;
  font-size: var(--fs-label);
  color: var(--slate-400);
}

@media (max-width: 640px) {
  .run-eta {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "label time"
      "name time"
      "sub sub"
      "behind behind"
      "then then"
      "updated updated";
  }
}

@media (prefers-reduced-motion: reduce) {
  .progress-fill { transition: none; }
}

/* ---- Roster list ------------------------------------------------------- */
/* Lives inside a .table-frame, so it inherits the table's card edges and
   needs no border of its own. */
.roster-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  overflow: hidden;
}

.roster-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  height: var(--row-h);
  padding: 0 16px;
  border-bottom: 1px solid var(--border-subtle);
}

.roster-row:last-child { border-bottom: none; }

.roster-row-clickable { cursor: pointer; }
.roster-row-clickable:hover { background: var(--slate-50); }

.roster-row:focus-visible {
  outline: none;
  background: var(--slate-50);
  box-shadow: inset 0 0 0 2px var(--dropproof-teal);
}

/* Truncates rather than wrapping - a two-line name would make one row taller
   than its neighbours and break the list's rhythm. */
.roster-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: var(--text-strong);
}

/* Off-sheet deliveries sit below the roster as a second, clearly-separate
   frame - they are real work, but not part of the plan the roster shows. */
.extra-frame { margin-top: 20px; }

.toolbar-title-muted {
  font-weight: 400;
  color: var(--muted);
}

.roster-time {
  flex-shrink: 0;
  font-size: var(--fs-label);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.roster-empty,
.table-empty {
  margin: 0;
  padding: 32px 16px;
  text-align: center;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
}

.muted-cell { color: var(--slate-300); }

/* ---- Run picker -------------------------------------------------------- */
.run-picker { position: relative; }

.run-picker-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--white);
  color: var(--text);
  font: inherit;
  box-shadow: var(--shadow-card);
  cursor: pointer;
}

.run-picker-btn:hover { background: var(--slate-50); }

.run-picker-label { font-weight: 600; }

.run-picker-selected {
  color: var(--muted);
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.run-picker-caret { color: var(--slate-400); font-size: 10px; }

.run-picker-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 280px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 8px;
  /* Floating surface - the one place real elevation is used. */
  box-shadow: var(--shadow-pop);
  z-index: 80;
}

.run-picker-dropdown .runs-list { max-height: 260px; overflow-y: auto; }

.runs-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.run-row {
  display: block;
  width: 100%;
  text-align: left;
  padding: 7px 8px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}

.run-row:hover { background: var(--slate-100); }

.run-row.active {
  background: var(--sidebar-active-bg);
  color: var(--dropproof-teal-dark);
  font-weight: 600;
}

/* ---- Cards ------------------------------------------------------------- */
/* One treatment, everywhere: white, hairline border, 10px radius, the same
   near-flat shadow. Nothing on this page is a "different kind" of card. */
.empty-panel,
.detail-caption {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.detail-caption { padding: 20px; }

/* ---- Status pill ------------------------------------------------------- */
/* The one status component - roster list, both tables, detail panel. Same
   padding, size and weight everywhere, whichever state it shows. */
.status-pill {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  height: 20px;
  padding: 0 8px;
  border-radius: 999px;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  box-shadow: inset 0 0 0 1px var(--pill-ring);
}

.status-pill-delivered {
  --pill-ring: var(--status-teal-ring);
  background: var(--status-teal-bg);
  color: var(--status-teal-text);
}

/* Pending and exception share the amber family - both are "not delivered".
   The exception carries its reason on the tooltip, not in the label, so the
   pill stays a fixed-width object instead of an unbounded string. */
/* Informational, not a state - used where a pill reports what an action will
   do ("Replaces") rather than how a delivery went. */
.status-pill-neutral {
  --pill-ring: rgba(15, 23, 42, 0.10);
  background: var(--slate-100);
  color: var(--slate-600);
}

/* GPS marking beside the coordinates on the delivery detail and the proof
   page (gpsLabel.js) - sits inline after the value, or alone when there are
   no coordinates at all. */
.gps-pill { margin-left: 8px; vertical-align: middle; }
.gps-pill:first-child { margin-left: 0; }

.status-pill-pending,
/* Damage reports: flagged, above the routine list, never in the gallery. */
.incident-block { margin-bottom: 18px; border: 1px solid #FCA5A5; border-left: 4px solid #DC2626; border-radius: 12px; background: #FEF2F2; padding: 16px 18px; }
.incident-title { margin: 0 0 10px; font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #991B1B; }
.incident-row { display: flex; align-items: flex-start; gap: 14px; padding: 12px 0; border-top: 1px solid #FCA5A5; }
.incident-row:first-child { border-top: 0; }
.incident-meta { flex: 1; min-width: 0; }
.incident-note { margin: 0; font-size: 15px; font-weight: 700; color: var(--text-strong); }
.incident-sub { margin: 4px 0 0; font-size: 13px; color: #991B1B; font-variant-numeric: tabular-nums; }
.incident-photos { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.incident-photos img { width: 72px; height: 54px; object-fit: cover; border-radius: 6px; border: 1px solid #FCA5A5; background: var(--slate-100); cursor: pointer; }

/* Fleet management: Vehicle Check */
.sub-tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.sub-tab { padding: 8px 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--white); color: var(--muted); font-weight: 600; font-size: 13px; cursor: pointer; }
.sub-tab.active { background: var(--text-strong); color: #fff; border-color: var(--text-strong); }
.toolbar-note { padding: 8px 16px; }
.plate { display: block; max-width: 100%; height: auto; }
.plate-cell { width: 128px; }
.truck-hero { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; margin-bottom: 20px; }
.truck-plate { flex: 0 0 auto; }
.truck-line { margin: 0; font-size: 16px; font-weight: 600; }
.truck-sub { margin: 4px 0 0; color: var(--muted); font-size: 13px; }
.truck-never { color: #991B1B; font-weight: 600; }
.truck-check { background: var(--white); border: 1px solid var(--border); border-radius: 12px; padding: 16px; margin-bottom: 14px; }
.truck-check-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.truck-check-head h3 { margin: 0; font-size: 15px; }
.truck-check-note { margin: 0 0 10px; color: var(--muted); font-size: 13px; }
.truck-sections { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
.truck-section h4 { margin: 0 0 6px; font-size: 12px; font-weight: 700; color: var(--muted); }
.truck-section .photos-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.truck-section .photos-grid img { aspect-ratio: 4 / 3; }
.truck-history-title { margin: 22px 0 10px; font-size: 14px; color: var(--muted); }
.truck-history-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); margin-bottom: 8px; cursor: pointer; }
.truck-history-row:hover { border-color: var(--dropproof-teal); }
.danger-btn { color: #991B1B; border-color: #FCA5A5; }
.danger-btn:hover { background: #FEF2F2; }
.status-pill-void {
  background: #FEE2E2;
  color: #991B1B;
}
.correction-note {
  margin: 10px 0 0;
  font-size: 13px;
  color: #991B1B;
}
.status-pill-exception {
  --pill-ring: var(--status-amber-ring);
  background: var(--status-amber-bg);
  color: var(--status-amber-text);
}

/* ---- Toolbar / filter bar --------------------------------------------- */
/* One bordered row of controls sitting directly on top of the table it
   filters, sharing the table's top corners - reads as part of the table's
   frame rather than as fields floating above it. */
.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 10px 12px;
  background: var(--white);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
}

.toolbar-search {
  position: relative;
  flex: 1 1 240px;
  min-width: 132px;
  max-width: 380px;
  display: flex;
  align-items: center;
}

.toolbar-search svg {
  position: absolute;
  left: 9px;
  color: var(--slate-400);
  pointer-events: none;
}

/* Higher specificity than the bare `input[type="text"]` control rule below,
   which is declared later and would otherwise reset this padding and slide
   the text back under the icon. */
.toolbar-search input[type="text"] {
  width: 100%;
  padding-left: 30px;
}

.toolbar-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.toolbar-sep { color: var(--slate-400); }

.toolbar-count {
  margin-left: auto;
  font-size: var(--fs-label);
  color: var(--muted);
  white-space: nowrap;
}

/* ---- Controls ---------------------------------------------------------- */
/* Every text input, date field and select on the page shares this - one
   control look, so a filter field and a search box are visibly the same
   kind of thing. */
input[type="text"],
input[type="date"],
input[type="email"],
input[type="password"],
select {
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--white);
  color: var(--text);
  font: inherit;
  box-shadow: var(--shadow-card);
}

select {
  padding-right: 28px;
  cursor: pointer;
  /* Custom caret; the native one differs per platform and reads as an
     unstyled browser control next to our own inputs. */
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 9px center;
}

input::placeholder { color: var(--slate-400); }

.secondary-btn {
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--white);
  color: var(--text);
  font: inherit;
  font-weight: 500;
  box-shadow: var(--shadow-card);
  cursor: pointer;
}

.secondary-btn:hover { background: var(--slate-50); }
.secondary-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.secondary-btn:disabled:hover { background: var(--white); }

/* One focus treatment for every control. :focus-visible, not :focus, so it
   serves keyboard users without ringing on every mouse click. */
input:focus-visible,
select:focus-visible,
button:focus-visible,
.delivery-row:focus-visible {
  outline: none;
  border-color: var(--dropproof-teal);
  box-shadow: var(--ring-focus);
}

.status-text {
  color: var(--muted);
  font-size: var(--fs-body);
}

/* ---- Filters (Customers panel) ---------------------------------------- */
/* ---- Deliveries table -------------------------------------------------- */
.deliveries-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

/* When the toolbar sits directly above, the table joins onto it rather
   than reading as a second, separate box. */
.toolbar + .deliveries-table {
  border-radius: 0 0 var(--radius-card) var(--radius-card);
}

/* The toolbar deliberately stays visible when its table is empty: an empty
   result is usually the FILTERS' doing, so hiding the controls would strand
   the user with no way to clear them. */

.deliveries-table th {
  height: 34px;
  text-align: left;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--slate-500);
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  background: var(--slate-50);
  white-space: nowrap;
}

/* Fixed row height, content vertically centred. This - not padding - is
   what gives the table its rhythm: nothing a row contains (six photos, a
   long customer name) can push it taller than its neighbours. */
.deliveries-table td {
  height: var(--row-h);
  padding: 0 16px;
  vertical-align: middle;
  border-bottom: 1px solid var(--border-subtle);
}

/* Column rules are per-table, not on the shared .deliveries-table class -
   Customers reuses the same base table but its columns mean different
   things (col 1 is a name, not a timestamp). */

/* Timestamp: muted, never wrapped mid-value. */
#deliveries-table td:nth-child(1) {
  white-space: nowrap;
  color: var(--muted);
}

/* Customer: the one column allowed to be long, so it truncates instead of
   wrapping and dragging the row height with it. */
#deliveries-table td:nth-child(2) {
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: var(--text-strong);
}

/* Run: a short identifier, never wrapped. */
#deliveries-table td:nth-child(3) { white-space: nowrap; color: var(--muted); }

/* Customers: name / last delivery / count / exceptions. */
.customers-table td:nth-child(1) {
  max-width: 380px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: var(--text-strong);
}

.customers-table td:nth-child(2) { white-space: nowrap; color: var(--muted); }

.customers-table th:nth-child(3),
.customers-table td:nth-child(3) {
  text-align: right;
  width: 120px;
}

.delivery-row { cursor: pointer; }

/* Customers in a run's order: one label row per group (learned / the rest). */
.deliveries-table .group-row td:last-child,
.group-row td {
  text-align: left;
  padding: 14px 12px 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted);
  background: transparent;
  border-bottom: 0;
}

/* One row state. A zebra stripe was previously layered under this hover at
   effectively the same value (#FAFAFB vs #F9FAFB), which made hovering an
   even row a visual no-op. Dividers carry the row rhythm instead. */
.delivery-row:hover { background: var(--slate-50); }
.delivery-row:last-child td { border-bottom: none; }

/* Status is always the trailing column in both tables - right-aligned with
   its header so the pill is anchored to the row's edge every time. */
.deliveries-table th:last-child,
.deliveries-table td:last-child {
  text-align: right;
}

.deliveries-table td:last-child .status-pill { vertical-align: middle; }

/* Single line, never wrapping. Sized to exactly four 28px thumbs plus three
   4px gaps so the strip never ends on a half-sliced image. */
.thumb-row {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
  gap: 4px;
  max-width: 124px;
}

.thumb-img {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: 5px;
  /* Inset ring, not a border - it sits inside the 28px box so thumbnails
     keep an exact 28px pitch instead of each growing 2px. */
  border: none;
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.10);
  background: var(--slate-100);
}

.thumb-img.thumb-error { opacity: 0.4; }

/* No signature is the normal case (~90% of deliveries), so absence is
   rendered as a quiet dash rather than an alarming blank. */
.sig-cell { color: var(--slate-300); text-align: center; }
.sig-cell:empty::after { content: "–"; }
.sig-present { color: var(--green); font-weight: 600; }

/* Signature column, deliveries only - Customers' second-from-last column is
   a numeric count, which stays right-aligned with the other numbers. */
#deliveries-table th:nth-last-child(2),
#deliveries-table td:nth-last-child(2) { text-align: center; }

.customers-table th:last-child,
.customers-table td:last-child { width: 110px; }

/* ---- Detail view ------------------------------------------------------- */
.detail-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.detail-layout {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: stretch;
}

.detail-caption-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-subtle);
}

.detail-caption-header h2 {
  font-size: var(--fs-section);
  color: var(--text-strong);
}

/* Metadata as a horizontal run of label/value pairs rather than a stacked
   list - at two or three fields a vertical <dl> leaves most of a full-width
   card empty. */
/* Metadata as a row of label-over-value pairs, not a stacked list - at two
   or three fields a vertical <dl> leaves most of a full-width card empty.
   grid-auto-flow: column puts each dt/dd pair in its own column, with the
   two explicit rows keeping every label on the top line. */
.detail-caption dl {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: auto auto;
  justify-content: start;
  gap: 4px 48px;
  margin: 16px 0 0;
}

.detail-caption dt {
  margin: 0;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
}

.detail-caption dd {
  margin: 0;
  font-weight: 500;
  color: var(--text-strong);
}

.signature-img {
  max-width: 100%;
  max-height: 96px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--white);
}

.photos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}

.photos-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  cursor: pointer;
  background: var(--slate-100);
}

.photos-grid img:hover { border-color: var(--dropproof-teal); }

.photo-error {
  aspect-ratio: 1;
  border-radius: 8px;
  border: 1px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: var(--fs-label);
  text-align: center;
  padding: 8px;
}

/* ---- Customers panel --------------------------------------------------- */

/* ---- Run sheet import -------------------------------------------------- */
.import-launch {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.import-launch .status-text { flex-basis: 100%; margin: 0; }

/* The one line the office reads after an import. Quiet by default; marked
   only when the sheet went in under a day that is not today, which is the
   one outcome worth a second look. */
.import-result {
  margin: 20px 0 24px;
  font-size: var(--fs-section);
  font-weight: 600;
  color: var(--text-strong);
  white-space: pre-line;
}

.import-result-other-day {
  padding: 10px 14px;
  border-radius: var(--radius-control);
  background: var(--status-amber-bg);
  color: var(--status-amber-text);
  box-shadow: inset 0 0 0 1px var(--status-amber-ring);
}

/* Collapsed by default - only opens when the header row was not
   recognised, so the common case is just "pick a file". */
.import-mapping {
  margin-bottom: 20px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 12px 16px;
}

.import-mapping > summary {
  cursor: pointer;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
}

.import-mapping[open] > summary { margin-bottom: 16px; }

.import-row {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.import-row + .import-row {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--border-subtle);
}

.import-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 220px;
}

.import-field label {
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
}

/* The native file button is the one control that cannot be restyled from
   the outside, so it is given the same height and border as every other
   control and its button half is targeted directly. */
input[type="file"] {
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--white);
  font: inherit;
  color: var(--muted);
  box-shadow: var(--shadow-card);
}

input[type="file"]::file-selector-button {
  height: 30px;
  margin-right: 10px;
  padding: 0 12px;
  border: none;
  border-right: 1px solid var(--border);
  border-radius: var(--radius-control) 0 0 var(--radius-control);
  background: var(--slate-50);
  font: inherit;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
}

input[type="file"]::file-selector-button:hover { background: var(--slate-100); }

.toolbar-title {
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--text-strong);
}

.runsheets-table td:nth-child(1) { font-weight: 500; color: var(--text-strong); }
.runsheets-table th:nth-child(3),
.runsheets-table td:nth-child(3) { text-align: right; width: 120px; }
/* Advisory notes above the preview - one per line, so three separate
   problems read as three problems, not one paragraph. */
#import-message { white-space: pre-line; }
.runsheets-table th:last-child,
.runsheets-table td:last-child { width: 140px; }

.import-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 20px;
}

/* The only filled button in the app besides sign-in - this is the one
   action here that writes something irreversible. */
.primary-btn {
  height: 34px;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-control);
  background: var(--slate-900);
  color: var(--white);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.primary-btn:hover { background: var(--slate-800); }
.primary-btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---- Empty states ------------------------------------------------------ */
/* Fleet / Drivers / Credits / Run sheets. A real screen: a defined block
   with a marked icon and one line of copy, not a blank card. */

/* The same [hidden] override as #login-view, .run-eta and .lightbox-overlay.
   An author display rule outranks the browser's [hidden] { display: none },
   so without these two the empty states and the confirm button showed
   whether or not anything had asked for them. */
.empty-state[hidden] { display: none; }
.import-actions[hidden] { display: none; }

/* An empty state standing in for a table has to bring the card the table
   would have provided: a .table-frame is only a wrapper, and the toolbar
   above it is the only thing with a background of its own. */
.table-frame > .empty-state {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.toolbar ~ .empty-state {
  border-top: none;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 14px;
  min-height: 320px;
  padding: 40px 24px;
}

.empty-state-icon {
  box-sizing: content-box;
  width: 24px;
  height: 24px;
  padding: 14px;
  border-radius: 12px;
  background: var(--slate-50);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--slate-400);
}

.empty-state-title {
  margin: 0;
  font-size: var(--fs-section);
  font-weight: 600;
  color: var(--text-strong);
}

.empty-state-text {
  color: var(--muted);
  margin: 0;
  max-width: 340px;
}

/* ---- Lightbox ---------------------------------------------------------- */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  cursor: zoom-out;
  z-index: 100;
}

/* Same [hidden] override fix as #login-view - without it the overlay
   renders full-screen on every page load. */
.lightbox-overlay[hidden] { display: none; }

.lightbox-overlay img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
}

/* ---- Public proof page (proof.html) ----------------------------------- */
.proof-main {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 24px;
}

.proof-header {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.table-show-more { display: block; margin: 12px auto 16px; }

/* ---- Credit notes ------------------------------------------------------ */
/* Foodlink's paper credit note is pale pink; the customer copy page and the
   printed note are too (src/theme/credit.js on the phone: same values).
   Black text; the pink is the paper, not a status. */
:root { --credit-pink: #FBE9EE; --credit-pink-deep: #F5D0DA; --credit-pink-line: #E9B8C6; }
/* ---- Shared record treatment (dt-*): credits now, vehicle checks later.
   Section headers, label-over-value rows with hairline dividers, chips
   with a dot, tabular numerals. Scoped to .dt-record so the delivery
   detail's own dl layout is untouched. ---------------------------------- */
.dt-record { padding: 0; }
.dt-record > .dt-section,
.dt-record > dl.dt-fields,
.dt-record > .credit-items,
.dt-record > .credit-processing,
.dt-record > .photos-grid { margin-left: 24px; margin-right: 24px; }
.dt-record > dl.dt-fields { margin-top: 0; margin-bottom: 0; }
.dt-record > .credit-items { width: calc(100% - 48px); table-layout: auto; }
.dt-record > .photos-grid { margin-bottom: 24px; }
.dt-head { padding: 22px 24px 18px; border-bottom: 1px solid var(--border); }
.dt-head-credit { background: var(--credit-pink); border-left: 4px solid var(--credit-pink-line); }
.dt-head .detail-caption-header { margin: 0; }
.dt-head .credit-ref-line { margin: 6px 0 0; font-size: 13px; font-weight: 700; letter-spacing: 0.02em; color: var(--muted); }
.dt-num { font-variant-numeric: tabular-nums; }
.dt-section {
  margin: 32px 0 6px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.dt-record .dt-fields { display: block; margin: 0; }
.dt-record .dt-fields-inline { display: flex; flex-wrap: wrap; gap: 0 40px; margin-top: 14px; }
.dt-record .dt-fields-inline .dt-field { border-bottom: 0; padding: 6px 0 0; }
.dt-field { padding: 12px 0; border-bottom: 1px solid var(--border-subtle); }
.dt-field:last-child { border-bottom: 0; }
.dt-field[hidden] { display: none; }
.dt-record .dt-field dt {
  margin: 0 0 3px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.dt-record .dt-field dd { margin: 0; font-size: 15px; font-weight: 700; color: var(--text-strong); }
.dt-record .credit-items { margin-top: 4px; max-width: none; }
.dt-record .credit-items th { font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.dt-record .credit-items td { padding: 10px 12px 10px 0; font-weight: 600; }
.dt-record .credit-items .credit-qty { font-variant-numeric: tabular-nums; font-weight: 700; }
.dt-record .credit-processing { margin-top: 32px; }

/* The item line is the hero of a credit note: code and product name large,
   quantity large beside them. The decision column is unchanged. */
.credit-items-hero td { padding-top: 14px; padding-bottom: 14px; }
.credit-items-hero td:nth-child(1) { font-size: 15px; font-weight: 700; color: var(--muted); letter-spacing: 0.04em; }
.credit-items-hero td:nth-child(2) { font-size: 20px; font-weight: 800; color: var(--text-strong); line-height: 1.3; }
.credit-items-hero td.credit-qty { font-size: 24px; font-weight: 800; color: var(--text-strong); }
.credit-items-hero td.credit-unit { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }

/* Chips: a dot before the label; Open is amber, Processed / Sent green. */
.status-pill.chip::before { content: ''; width: 6px; height: 6px; border-radius: 50%; margin-right: 6px; background: currentColor; opacity: 0.85; }
.status-pill-open { background: var(--status-amber-bg); color: var(--status-amber-text); --pill-ring: var(--status-amber-ring); }

/* Dense queue: uppercase headers (base), tabular numbers, hover + selected. */
.credits-table td { font-variant-numeric: tabular-nums; }
/* Raised and Driver / run never wrap to three lines in a dense queue. */
#credits-table td:nth-child(7), #credits-table td:nth-child(8) { white-space: nowrap; }
.credits-table tr.row-selected td { background: var(--status-teal-bg); }
.credits-table tr.row-selected:hover td { background: var(--status-teal-bg); }
.credits-table .delivery-row:hover td { background: var(--slate-50); }

.credit-paper { background: var(--credit-pink); border-radius: var(--radius-card); padding: 24px 28px; }
.credit-paper .credit-items th, .credit-paper .credit-items td { border-bottom-color: var(--credit-pink-line); }
.credit-items .credit-code { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.credit-kicker { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-body); }
.credit-items { border-collapse: collapse; width: 100%; max-width: 480px; margin: 4px 0 0; }
.credit-items th, .credit-items td { text-align: left; padding: 6px 8px 6px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-body); }
.credit-items th { color: var(--muted); font-weight: 500; }
.credit-items .credit-qty { text-align: right; width: 56px; padding-right: 12px; }
.credit-items .credit-unit { width: 56px; color: var(--muted); }
.credit-foot { margin-top: 24px; color: var(--muted); font-size: var(--fs-label); }
.credit-ref-line { margin: 2px 0 12px; color: var(--muted); font-size: var(--fs-body); }
.credits-table .credit-no-cell { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.credits-table .credit-thumb { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; background: var(--slate-100); display: block; }
.credits-table .credit-thumb-empty { width: 44px; height: 44px; border-radius: 6px; background: var(--slate-100); }
.credits-table td.credit-items-cell { max-width: 260px; white-space: normal; }
.credit-raised-sub { display: block; color: var(--muted); font-size: var(--fs-label); }
.credit-processing { margin-top: 20px; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--slate-50); }
.credit-processing label { display: block; font-size: var(--fs-label); font-weight: 500; color: var(--muted); margin-bottom: 6px; }
.credit-process-row { display: flex; gap: 8px; flex-wrap: wrap; }
.credit-process-row input { flex: 1 1 160px; min-height: 36px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px; font: inherit; }
.credit-process-hint { margin: 8px 0 0; color: var(--muted); font-size: var(--fs-label); }
.credit-processed-line { margin: 0 0 10px; font-weight: 500; }
.credit-history { margin: 10px 0 0; padding: 0; list-style: none; color: var(--muted); font-size: var(--fs-label); }
.credit-history li { padding: 2px 0; }
.credit-items-decide { max-width: 640px; }
.credit-decision-col { width: 300px; }
.credit-decide { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.credit-decide .decide-btn { min-height: 28px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--white); font: inherit; font-size: var(--fs-label); cursor: pointer; }
.credit-decide .decide-btn.on-approved { background: var(--status-teal-bg); border-color: var(--status-teal-ring); color: var(--status-teal-text); font-weight: 600; }
.credit-decide .decide-btn.on-denied { background: #fee2e2; border-color: rgba(185, 28, 28, 0.25); color: var(--danger-text); font-weight: 600; }
.credit-decide input { flex: 1 1 140px; min-height: 28px; padding: 0 8px; border: 1px solid var(--border); border-radius: 6px; font: inherit; font-size: var(--fs-label); }
.credit-outcome-line { margin: 0 0 10px; font-weight: 500; }
.credit-outcome-mark { display: inline-block; margin-right: 4px; font-weight: 700; }
.credit-outcome-mark.ok { color: var(--status-teal-text); }
.credit-outcome-mark.no { color: var(--danger-text); }
.credit-items .credit-outcome-cell { color: var(--muted); font-size: var(--fs-label); }
.status-pill-partial { --pill-ring: var(--status-amber-ring); background: var(--status-amber-bg); color: var(--status-amber-text); }
.status-pill-denied { --pill-ring: rgba(185, 28, 28, 0.2); background: #fee2e2; color: var(--danger-text); }

/* Print one credit as the paper note: the detail panel only, in the
   paper's field order, no chrome. */
@media print {
  body * { visibility: hidden; }
  #tab-panel-credit, #tab-panel-credit * { visibility: visible; }
  #tab-panel-credit { position: absolute; left: 0; top: 0; width: 100%; padding: 24px; background: var(--credit-pink); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  #tab-panel-credit .detail-actions, #tab-panel-credit .credit-processing button, #tab-panel-credit input { display: none !important; }
  #tab-panel-credit .detail-layout { display: block; }
  #tab-panel-credit .photos-grid img { max-width: 320px; page-break-inside: avoid; }
}

.proof-meta { margin: 16px 0 24px; }

.proof-meta dt {
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--muted);
  margin-top: 12px;
}

.proof-meta dd {
  margin: 2px 0 0;
  font-weight: 500;
  color: var(--text-strong);
}

.proof-signature-wrap { margin-bottom: 24px; }

.proof-photos {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Full size, not cropped - unlike the dashboard's square thumbnails, this
   page's whole purpose is showing the actual photo. */
.proof-full-photo {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--slate-100);
}

/* Customer copy: same item-hero treatment as the phone and the dashboard,
   and the same label-over-value rhythm - the copy page had its own
   proof-meta styling, so its labels read at the value's weight and its
   item table stopped short of the block below it. */
.credit-items-copy.credit-items-hero { max-width: none; }
.credit-items-copy.credit-items-hero td:nth-child(2) { font-size: 19px; }
.credit-items-copy.credit-items-hero td.credit-qty { font-size: 22px; }
.credit-paper .proof-meta dt,
.proof-meta-inline dt {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.credit-paper .proof-meta dd,
.proof-meta-inline dd { font-weight: 700; color: var(--text-strong); }
.proof-meta-inline { display: block; margin: 10px 0 26px; }
.proof-meta-inline dt { margin-bottom: 3px; }
.proof-meta-inline dd { margin: 0 0 12px; }

/* ---- Credit note detail ----------------------------------------------------
   Pink panel carrying the identity and the reference fields, then the
   credited product, its reason, and the driver's photo. The item table is
   laid out as flex rows by CSS so renderDecisionRows keeps emitting the
   same five cells. */
.credit-sheet { --cr-pink: #FBE3E7; --cr-pink-line: #EFC9D0; --cr-pink-deep: #9E4457; --cr-ink: #17211F; --cr-muted: #647774; --cr-line: #E4EAE8; --cr-teal: #2C8A82; --cr-green: #2E9E6B; --cr-deny: #b23b3b; --cr-amber: #C77E1E; display: block; }

.credit-panel {
  background: var(--cr-pink);
  border: 1px solid var(--cr-pink-line);
  border-radius: 14px;
  padding: 18px 20px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.credit-panel-label { margin: 0; font-size: 10.5px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cr-pink-deep); }
.credit-number { margin: 2px 0 0; font-size: 30px; font-weight: 800; letter-spacing: -0.02em; color: var(--cr-ink); font-variant-numeric: tabular-nums; }
.credit-customer { margin: 10px 0 0; font-size: 16px; font-weight: 800; color: var(--cr-ink); }
.credit-panel-left .status-pill { margin-top: 10px; }

.credit-panel-right { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; margin: 0; align-content: start; }
.credit-ref-field { margin: 0; min-width: 0; }
.credit-ref-field.is-wide { grid-column: 1 / -1; }
.credit-panel-right dt { margin: 0 0 2px; font-size: 10px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cr-pink-deep); }
.credit-panel-right dd { margin: 0; font-size: 15px; font-weight: 800; color: var(--cr-ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.credit-ref-field.is-date dd { font-size: 13.5px; font-weight: 700; }

.credit-body { padding: 0 2px; }
.credit-section { margin: 26px 0 2px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.13em; text-transform: uppercase; color: var(--cr-muted); }

/* the item rows */
.credit-rows, .credit-rows tbody { display: block; width: 100%; max-width: none; border-collapse: collapse; }
.credit-rows thead { display: none; }
.credit-rows tr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid var(--cr-line);
  border-bottom: 1px solid var(--cr-line);
}
.credit-rows tr + tr { border-top: 0; }
.credit-rows td { display: block; padding: 0; border: 0; }
.credit-rows td.credit-code { flex: 0 0 auto; font-size: 15px; font-weight: 700; color: var(--cr-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.credit-rows td:nth-child(2) { flex: 1 1 auto; min-width: 0; font-size: 22px; font-weight: 800; line-height: 1.25; color: var(--cr-ink); }
.credit-rows td.credit-qty { flex: 0 0 auto; width: auto; text-align: right; font-size: 26px; font-weight: 800; color: var(--cr-ink); font-variant-numeric: tabular-nums; }
.credit-rows td.credit-unit { flex: 0 0 auto; width: auto; font-size: 10.5px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cr-muted); }
.credit-rows td.credit-decision-col { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.credit-rows td.credit-decision-col button { font-size: 12px; font-weight: 800; padding: 7px 14px; }
.credit-rows td.credit-decision-col button:first-of-type { color: var(--cr-green); border-color: var(--cr-green); }
.credit-rows td.credit-decision-col button:last-of-type { color: var(--cr-deny); border-color: var(--cr-deny); }

/* reason + detail */
.credit-why { display: grid; gap: 14px; margin: 22px 0 0; }
.credit-why-field { margin: 0; }
.credit-why-field[hidden] { display: none; }
.credit-why dt { margin: 0 0 3px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cr-muted); }
.credit-why dd { margin: 0; font-size: 15px; font-weight: 700; color: var(--cr-ink); }

.credit-body .credit-processing { margin-top: 26px; }
.credit-body .photos-grid { margin-top: 8px; }

@media (max-width: 660px) {
  .credit-panel { grid-template-columns: 1fr; }
  .credit-rows tr { flex-wrap: wrap; }
  .credit-rows td.credit-decision-col { width: 100%; }
}


/* ---- Narrow widths ------------------------------------------------------ */
/* The shell was desktop-only: a fixed 232px sidebar with the content pushed
   past it, so at 390px the page ran 88px wider than the screen and customer
   names truncated to their first letter. Below 900px the sidebar stops being
   a column and becomes the page's header: brand and sign-out on one line,
   the tabs scrolling sideways under them as one row. */
@media (max-width: 900px) {
  .sidebar {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    width: 100%;
    height: auto;
    overflow: visible;
  }

  .sidebar-brand {
    flex: 1 1 auto;
    width: auto;
    height: 52px;
    border-bottom: none;
  }

  /* Beside the brand, not stranded under a bar that is no longer tall. The
     signed-in address is the one thing there is no room for; the company
     name is what tells the office whose data this is. */
  .sidebar-bottom {
    flex: 0 0 auto;
    flex-direction: row;
    align-items: center;
    gap: 14px;
    margin: 0;
    padding: 0 16px;
    border-top: none;
  }
  .sidebar-bottom #user-email { display: none; }

  /* One scrolling row. Without width:auto the first tab inherits the
     column layout's full width and the other five sit off-screen. */
  .sidebar-nav {
    flex: 1 0 100%;
    display: flex;
    flex-direction: row;
    gap: 4px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 6px 12px 10px;
    scrollbar-width: none;
  }
  .sidebar-nav::-webkit-scrollbar { display: none; }
  .sidebar-nav .nav-section-label { display: none; }
  .sidebar-nav .tab-btn {
    flex: 0 0 auto;
    width: auto;
    white-space: nowrap;
  }

  .content-area { margin-left: 0; }
  .content-header { padding: 0 16px; }
  main { padding: 16px; }

  /* A table is the one thing allowed to scroll sideways, and only inside
     its own card. */
  .table-frame {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .table-frame .deliveries-table { min-width: 560px; }

  .toolbar { flex-wrap: wrap; }
  .page-toolbar { flex-wrap: wrap; gap: 12px; }

  /* Roster rows hold a name and a time. The name takes what is left and
     ellipsizes rather than collapsing to one letter. */
  .roster-row { gap: 12px; }
  .roster-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .empty-state { min-height: 220px; }
}

/* The ETA panel is five rows in one line at desktop width. Below 720px the
   time cannot sit in its own column beside a wrapping customer name without
   the two colliding, so it goes under the name. */
@media (max-width: 720px) {
  .run-eta {
    grid-template-columns: 1fr;
    grid-template-areas:
      "label"
      "name"
      "time"
      "sub"
      "behind"
      "then"
      "updated";
    row-gap: 3px;
  }
  .run-eta-name { font-size: 15px; line-height: 1.25; }
  .run-eta-time { font-size: var(--fs-title); white-space: nowrap; }
  .run-eta-then { gap: 4px 14px; }
  .run-eta-then li { min-width: 0; }
  .run-eta-then-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 58vw;
  }
}

@media (max-width: 480px) {
  .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .import-launch { gap: 12px; }
  .import-launch .primary-btn { width: 100%; }
}

/* A pending stop's row carries three things: the customer, its ETA window
   and a status pill. Below 560px the two on the right leave the name 46px,
   which is not a name. The row wraps instead: the customer takes its own
   line in full, the window and the pill sit under it. */
@media (max-width: 560px) {
  .roster-row {
    flex-wrap: wrap;
    row-gap: 4px;
    height: auto;
    min-height: var(--row-h);
    padding-top: 8px;
    padding-bottom: 8px;
  }
  .roster-name {
    flex: 1 0 100%;
    white-space: normal;
    overflow: visible;
  }
  .roster-eta { margin-left: 0; }
}


/* ---- Public pages: the proof link and the customer's credit copy -------- */
/* Neither sits inside the dashboard shell - they are what a customer opens
   from a text message - so they need their own header. It had none at all:
   the lockup was jammed into the corner of an otherwise empty page. */
.topbar {
  display: flex;
  align-items: center;
  height: 64px;
  padding: 0 24px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
}

.topbar-brand .brand-logo {
  width: 30px;
  height: 30px;
  color: var(--dropproof-teal-dark);
}

.topbar-brand h1 {
  margin: 0;
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-strong);
}

/* The proof page is one delivery on an otherwise empty page. Give the
   content a card so it reads as a document rather than text on a wall. */
.proof-content {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 24px;
}

.proof-content > .proof-header h2 {
  margin: 0;
  font-size: var(--fs-title);
  color: var(--text-strong);
}

.proof-main > .status-text { text-align: center; padding: 48px 0; }

/* The heading has nothing under it until the photos load, and on an
   exception there may be none at all. */
.run-subheading:has(+ .proof-photos:empty) { display: none; }

@media (max-width: 640px) {
  .topbar { height: 56px; padding: 0 16px; }
  .topbar-brand .brand-logo { width: 26px; height: 26px; }
  .proof-main { padding: 20px 16px; }
  .proof-content { padding: 18px; }
}
