/* Boxes brand: Satoshi-style grotesque, Azeret Mono labels, green #22c55e,
   sharp corners, 1px black borders, off-white canvas. */
:root {
  --green: #22c55e;
  --green-dark: #16a34a;
  --ink: #000;
  --bg: #f2f2ef;
  --card: #fff;
  --muted: #6b6b66;
  --line: #000;
  --soft-line: #d9d9d2;
  --danger: #dc2626;
  --amber: #d97706;
  --hover: #fafaf7;
  --dim: #e9e9e4;
  --faint: #a9a9a1;
  --tint-green: #dcfce7;
  --tint-amber: #fef3c7;
  --tint-yellow: #fde68a;
  --tint-yellow-hi: #fcd34d;
  --tint-gray: #e5e7eb;
  --tint-red: #fee2e2;
  --tint-blue: #dbeafe;
  --mark: #111827;
  --overlay: rgba(242, 242, 239, 0.94);
  --font: "Satoshi", "Inter", Arial, "Helvetica Neue", sans-serif;
  --mono: "Azeret Mono", ui-monospace, "SF Mono", Menlo, monospace;
}
/* Dark mode: the <head> script sets data-theme before first paint (stored
   choice, else the OS preference), so receiver pages follow it too. */
html[data-theme="dark"] {
  --ink: #e8e8e2;
  --bg: #141412;
  --card: #1d1d1a;
  --muted: #9a9a90;
  --line: #50504a;
  --soft-line: #2b2b27;
  --hover: #232320;
  --dim: #262622;
  --faint: #64645d;
  --tint-green: #173a25;
  --tint-amber: #3a3012;
  --tint-yellow: #4a3d12;
  --tint-yellow-hi: #5c4c17;
  --tint-gray: #333330;
  --tint-red: #431d1c;
  --tint-blue: #1b3a5c;
  --mark: #e5e7eb;
  --overlay: rgba(20, 20, 18, 0.94);
  color-scheme: dark;
}
/* The wordmark SVG is a static near-black file; invert it in the dark topbar. */
html[data-theme="dark"] .brand img { filter: invert(1); }
* { box-sizing: border-box; }
html { background: var(--bg); }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font); font-size: 15px; line-height: 1.45;
}
a { color: inherit; }

/* Top bar */
.topbar {
  background: var(--card); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 28px; padding: 0 24px; height: 56px;
  position: sticky; top: 0; z-index: 10;
}
.brand { display: flex; align-items: flex-end; gap: 10px; font-weight: 800;
  font-size: 22px; letter-spacing: -0.5px; text-decoration: none; }
.brand svg { display: block; }
.brand .sub { font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: 1px; text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--line); padding: 2px 6px; margin-left: 2px;
  margin-bottom: 1px; /* optically level with the wordmark baseline */ }
nav.main { display: flex; gap: 2px; height: 100%; }
nav.main a {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.8px;
  text-transform: uppercase; text-decoration: none; color: var(--ink);
  display: flex; align-items: center; padding: 0 14px; border-bottom: 3px solid transparent;
}
nav.main a:hover { background: var(--bg); }
nav.main a.active { border-bottom-color: var(--green); font-weight: 600; }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
/* Mid widths (narrow desktop windows): the full topbar no longer fits on one
   line, so wrap to the same two-row layout mobile uses — brand + action
   buttons on top, nav strip below — instead of pushing the buttons
   off-screen. The <=720px block below adds the rest of the mobile tuning. */
@media (max-width: 1230px) {
  .topbar { flex-wrap: wrap; height: auto; padding: 10px 12px 0; gap: 10px; row-gap: 4px; }
  nav.main { order: 10; flex-basis: 100%; height: 42px; overflow-x: auto;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  nav.main::-webkit-scrollbar { display: none; }
  nav.main a { padding: 0 10px; white-space: nowrap; }
}

.mode-chip { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; padding: 4px 10px; border: 1px solid var(--line); }
.mode-chip.mock { background: var(--tint-amber); }
.mode-chip.live { background: var(--green); color: #000; }

/* Layout */
.wrap { max-width: 1180px; margin: 0 auto; padding: 28px 24px 80px; }
.page-head { display: flex; align-items: baseline; gap: 16px; margin: 8px 0 20px; flex-wrap: wrap; }
h1 { font-size: 34px; font-weight: 800; letter-spacing: -1px; margin: 0; }
h2 { font-size: 20px; font-weight: 700; letter-spacing: -0.3px; margin: 0 0 12px; }
.kicker { font-family: var(--mono); font-size: 11px; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--ink); margin-bottom: 4px; }
.page-head .spacer { flex: 1; }

/* Cards / tables */
.card { background: var(--card); border: 1px solid var(--line); margin-bottom: 20px; }
.card .card-title { font-family: var(--mono); font-size: 11px; letter-spacing: 1px;
  text-transform: uppercase; border-bottom: 1px solid var(--line); padding: 10px 16px;
  display: flex; align-items: center; gap: 10px; }
.card .card-title .spacer { flex: 1; }
.card .pad { padding: 16px; }
.grid { display: grid; gap: 20px; }
.grid.cols-2 { grid-template-columns: 1fr 1fr; }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .grid.cols-2, .grid.cols-4 { grid-template-columns: 1fr; } }

.stat { border: 1px solid var(--line); background: var(--card); padding: 14px 16px; }
.stat .n { font-size: 30px; font-weight: 800; letter-spacing: -1px; }
.stat .l { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--muted); }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th { font-family: var(--mono); font-size: 10px; letter-spacing: 1px; text-transform: uppercase;
  text-align: left; color: var(--muted); font-weight: 500;
  padding: 10px 12px; border-bottom: 1px solid var(--line); }
td { padding: 10px 12px; border-bottom: 1px solid var(--soft-line); vertical-align: top; }
tr:last-child td { border-bottom: 0; }
tr:hover td { background: var(--hover); }

/* Badges */
.badge { font-family: var(--mono); font-size: 10px; letter-spacing: 0.6px;
  text-transform: uppercase; padding: 2px 8px; border: 1px solid var(--line);
  white-space: nowrap; display: inline-block; }
.badge.pending { background: var(--card); }
.badge.scheduled { background: var(--tint-green); }
.badge.rescheduled { background: var(--tint-amber); }
.badge.dispatched { background: var(--green); color: #000; }
.badge.delivered { background: var(--tint-gray); }
.badge.voided { background: var(--tint-red); }
.badge.overflow { background: var(--tint-yellow); }
.badge.pickup { background: var(--tint-blue); }
.badge.mock { background: var(--tint-amber); }
.badge.sent { background: var(--green); color: #000; }
.badge.failed { background: var(--danger); color: #fff; border-color: var(--danger); }
.badge.planned { background: var(--tint-green); }
.badge.removed { background: var(--tint-gray); color: var(--muted); }
.badge.full { background: var(--tint-yellow); }
/* Needs-attention severity: red = a person must fix data before ANY run can
   place it; amber (badge.rescheduled) = waiting on a decision or just aging. */
.badge.attn-red { background: var(--tint-red); border-color: var(--danger); color: var(--danger); }
.badge.overtime { background: var(--tint-yellow); }
.badge.window-missed { background: var(--tint-red); }
.badge.pulled-off { background: var(--tint-amber); }
.badge.eta-shift { background: var(--tint-blue); }
.btn.warn { background: var(--tint-yellow); }
.btn.warn:hover { background: var(--tint-yellow-hi); }
.btn.icon { padding: 4px 8px; line-height: 1; background: var(--card); color: var(--ink);
  border-color: var(--line); }
.btn.icon:hover { background: var(--danger); color: #fff; border-color: var(--danger); }
/* Plan page: the order list is stacked dropdown sections in one card. */
.acc-head { cursor: pointer; user-select: none; }
.acc-head .acc-caret { display: inline-block; transition: transform .15s ease; }
.acc-head.open .acc-caret { transform: rotate(90deg); }
/* Each section's select-all only shows while that section is open. */
.acc-head .sel-all { display: none; }
.acc-head.open .sel-all { display: flex; }
/* Pickup-site "must go on" pin row (below the site's checkbox row). */
.site-pin { display: flex; gap: 8px; align-items: center; padding: 6px 12px 10px 38px;
  border-bottom: 1px solid var(--soft-line); font-size: 12px; }
.site-pin input[type=date] { padding: 5px 8px; font-size: 12px; }
/* Reclassify toggle (⇄): neutral hover, unlike the destructive ✕. */
.btn.icon.flip:hover { background: var(--green); color: #000; border-color: var(--line); }
.scroll-table { max-height: 320px; overflow-y: auto; }
.scroll-table table th { position: sticky; top: 0; background: var(--card); z-index: 1; }

/* Dashboard busyness calendar */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr);
  border-top: 1px solid var(--line); border-left: 1px solid var(--line);
  margin: -1px; }
.cal-head { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; padding: 6px 8px; background: var(--card);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.cal-cell { min-height: 60px; padding: 6px 8px; position: relative; background: var(--card);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.cal-cell.weekend { background: var(--dim); }
.cal-cell.today { box-shadow: inset 0 0 0 2px var(--ink); }
.cal-cell.blocked { background: var(--ink); color: var(--bg); }
.cal-num { font-weight: 600; font-size: 12px; }
.cal-sub { font-family: var(--mono); font-size: 10px; margin-top: 3px; }
.cal-dot { position: absolute; top: 6px; right: 6px; width: 9px; height: 9px;
  background: var(--tint-yellow); border: 1px solid var(--line); }
/* Pickup trips that day: one blue dot each, capped at 4 in the template.
   Solid = scheduled on a route; hollow = pinned to the day, still pending. */
.cal-pickups { position: absolute; bottom: 3px; right: 5px; display: flex; gap: 2px; }
.cal-resched { position: absolute; bottom: 2px; left: 5px; font-family: var(--mono);
  font-size: 9px; line-height: 1; padding: 2px 4px; background: var(--tint-amber);
  border: 1px solid var(--ink); border-radius: 2px; }
.cal-mini .cal-resched { bottom: 1px; left: 3px; font-size: 8px; padding: 1px 3px; }
.cal-pickups .pdot, .pdot { width: 7px; height: 7px; border-radius: 50%;
  background: #3b82f6; border: 1px solid var(--line); display: inline-block; }
.pdot.pending { background: transparent; border: 2px solid #3b82f6; }
.pdot.direct { background: #a855f7; }
.cal-mini .cal-pickups { bottom: 2px; right: 3px; }
.cal-mini .cal-pickups .pdot { width: 5px; height: 5px; }
.cal-legend { display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 1px; }
.cal-total { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--muted); margin-left: 12px; }
.cal-swatch { width: 14px; height: 14px; border: 1px solid var(--line); display: inline-block; }
.badge.blocked { background: var(--ink); color: var(--bg); border-color: var(--ink); }
/* Route detail: consecutive manifests dropped at one door are one physical
   visit — the rider rows tuck under the visit above (no separating rule). */
tr:has(+ tr.same-visit) td { border-bottom: 0; }
tr.same-visit td { padding-top: 2px; }
.badge.samevisit { background: var(--tint-blue); }
.badge.dropoff { background: var(--tint-green); }

/* /routes page-head tools: one flat segmented strip in the topbar idiom —
   mono uppercase segments split by hairlines, sharp corners; Plan routes
   stays the page's lone green primary beside it. */
.tool-strip { display: inline-flex; align-items: stretch; align-self: center;
  border: 1px solid var(--line); background: var(--card); }
.tool-strip form { display: inline-flex; align-items: stretch; }
.tool-strip > * + *, .tool-strip form > .tool { border-left: 1px solid var(--line); }
.tool-strip .tool { font-family: var(--mono); font-size: 10px; letter-spacing: 0.8px;
  text-transform: uppercase; background: none; border: 0 solid var(--line);
  color: var(--ink); padding: 9px 14px; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 7px; }
.tool-strip .tool:hover { background: var(--bg); }
.tool-strip .tool.warn { background: var(--tint-yellow); }
.tool-strip .tool.warn:hover { background: var(--tint-yellow-hi); }
.tool-strip .tool.primary { background: var(--green); color: #000; font-weight: 600; }
.tool-strip .tool.primary:hover { background: var(--green-dark); }
.tool-strip .tool .acc-caret { display: inline-block; color: var(--muted);
  transition: transform .15s ease; }
.tool-strip .tool.open .acc-caret { transform: rotate(90deg); }
.tool-strip .tool-seg { display: inline-flex; align-items: center; gap: 8px;
  padding: 0 4px 0 12px; }
.tool-strip .tool-lbl { font-family: var(--mono); font-size: 10px;
  letter-spacing: 1px; text-transform: uppercase; color: var(--muted); }
.tool-strip input[type=date] { border: 0; background: none; width: auto;
  padding: 6px 4px; font-family: var(--mono); font-size: 12px; }

/* /routes: route rows unfold in place to their stop list. The row keeps its
   normal look — only a small muted caret before the name hints at it. */
tr.route-row, tr.visit-lead { cursor: pointer; }
tr.route-row .acc-caret, tr.visit-lead .acc-caret { display: inline-block;
  margin-right: 4px; color: var(--muted); font-size: 10px;
  transition: transform .15s ease; }
tr.route-row.open .acc-caret, tr.visit-lead.open .acc-caret {
  transform: rotate(90deg); }
tr.route-row.open td { border-bottom: 0; }
tr.route-stops > td { padding: 0 12px 12px 30px; }
.stops-inline { font-size: 13px; }
.stops-inline td { padding: 4px 10px 4px 0; border-bottom: 0; }
.stops-inline tr.same-visit td { padding-top: 1px; }

/* /routes day maps: a simple SVG sketch of the day's geography — colored
   polyline per route, blob dots labeled with their destination count. */
.route-map { border-top: 1px solid var(--soft-line); }
.route-map svg { display: block; width: 100%; max-width: 560px; height: auto;
  margin: 0 auto; cursor: grab; touch-action: none; }
.route-map svg.grabbing { cursor: grabbing; }
.route-map .map-state { fill: var(--bg); stroke: var(--line); stroke-width: 1; }
.route-map .map-line { fill: none; stroke-width: 2; opacity: 0.8; }
.route-map .map-hit { fill: none; stroke: #000; stroke-opacity: 0;
  stroke-width: 14; pointer-events: stroke; }
.route-map .map-dot { stroke: var(--card); stroke-width: 2; }
.route-map svg { user-select: none; -webkit-user-select: none; }
.route-map .map-stop-label { fill: var(--ink); stroke: var(--bg);
  paint-order: stroke; stroke-linejoin: round; pointer-events: none;
  text-anchor: middle; font-weight: 600; font-family: var(--mono); }
.route-map .map-stop-leader { stroke: var(--muted); opacity: 0.65;
  pointer-events: none; }
.route-map .map-count { fill: #000; font-family: var(--mono); font-size: 9px;
  font-weight: 700; text-anchor: middle; pointer-events: none; }
.route-map .map-hub { fill: var(--ink); stroke: var(--green); stroke-width: 2; }
.route-map .map-legend { display: flex; flex-wrap: wrap; gap: 6px 18px;
  padding: 4px 12px 12px; font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.8px; text-transform: uppercase; color: var(--ink); }
.map-key { width: 10px; height: 10px; display: inline-block; margin-right: 6px;
  vertical-align: -1px; }

/* Topbar sync chip: steady "up to date" normally, pulsing "syncing" while
   a METRC ingest is actively running (.on). */
.poll-blip { display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--muted); }
.pb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green);
  opacity: 0.6; }
.poll-blip.on .pb-dot { opacity: 1;
  animation: pollblip 1.1s ease-in-out infinite; }
@keyframes pollblip {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(34,197,94,0.55); }
  50% { opacity: 0.55; box-shadow: 0 0 0 5px rgba(34,197,94,0); }
}

/* Bulk-run progress: fills by stops accounted for (placed or set aside). */
.run-progress { border: 1px solid var(--line); height: 16px; background: var(--card); }
.run-progress .fill { height: 100%; width: 0;
  background: repeating-linear-gradient(135deg, var(--green) 0 12px, #4ade80 12px 24px);
  background-size: 34px 34px; transition: width .6s ease;
  animation: run-stripes .6s linear infinite; }
@keyframes run-stripes { to { background-position: 34px 0; } }

/* Receiver reschedule calendar: unavailable days are visibly dead. */
.rcal-grid { display: grid; grid-template-columns: repeat(7, 1fr); margin-top: 6px;
  border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.rcal-head { font-family: var(--mono); font-size: 9px; letter-spacing: 1px;
  text-transform: uppercase; text-align: center; padding: 5px 0; background: var(--card);
  color: var(--muted); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.rcal-cell { font-family: var(--mono); font-size: 12px; padding: 10px 0; text-align: center;
  background: var(--card); border: 0; border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line); border-radius: 0; cursor: pointer; }
.rcal-cell:disabled { background: var(--dim); color: var(--faint); cursor: not-allowed;
  text-decoration: line-through; }
.rcal-cell[data-date]:hover { background: var(--tint-green); }
.rcal-cell.selected, .rcal-cell.selected:hover { background: var(--green); color: #000; font-weight: 700; }
.rcal-cell.today { box-shadow: inset 0 0 0 2px var(--ink); }
.badge.staged { background: var(--tint-green); }
.badge.draft { background: var(--card); border-style: dashed; }

/* drag-to-reorder on /routes stop rows */
.drag-handle { cursor: grab; padding: 0 6px; color: var(--muted);
  font-size: 14px; user-select: none; -webkit-user-select: none; }
.drag-handle:active { cursor: grabbing; }
tr.dragging { opacity: 0.45; }
tr.drop-above td { box-shadow: inset 0 3px 0 var(--green); }
tr.drop-below td { box-shadow: inset 0 -3px 0 var(--green); }
.badge.done { background: var(--tint-gray); }

/* Forms */
label.field { display: block; margin-bottom: 14px; }
label.field .lbl, .lbl { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; display: block; margin-bottom: 4px; color: var(--ink); }
/* Every text-ish field wears the same flat box. Miss one off this list and
   it silently falls back to the browser's default control — which is how
   the Drivers page ended up with a rounded phone box beside a square name
   box. Adding a new input type? Add it here too. */
input[type=text], input[type=password], input[type=number], input[type=date],
input[type=time], input[type=email], input[type=tel], select, textarea {
  width: 100%; padding: 9px 10px; border: 1px solid var(--line); background: var(--card);
  color: var(--ink); font-family: var(--font); font-size: 14px; border-radius: 0;
  outline-offset: 0;
}
input:focus, select:focus { outline: 2px solid var(--green); }
.row { display: flex; gap: 14px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 140px; }
.hint { font-size: 12px; color: var(--muted); margin-top: 3px; }
/* The deliberate-fallback control (force_internal). Amber so it reads as a
   cautionary choice, loud enough to be findable when the 402 error points
   at it — the old .hint styling hid it from the first person who needed it
   (2026-08-24). */
.fallback-opt {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: 8px; cursor: pointer;
  background: var(--tint-amber); border: 1px solid var(--tint-yellow-hi);
  font-size: 13px; line-height: 1.35;
}
.fallback-opt input { flex: 0 0 auto; margin: 0; }

.btn {
  display: inline-block; font-family: var(--mono); font-size: 12px; letter-spacing: 0.8px;
  text-transform: uppercase; padding: 11px 20px; border: 1px solid var(--line);
  background: var(--card); color: var(--ink); text-decoration: none; cursor: pointer;
  border-radius: 0; transition: background .1s;
}
.btn:hover { background: var(--bg); }
.btn.primary { background: var(--green); color: #000; font-weight: 600; }
.btn.primary:hover { background: var(--green-dark); }
.btn.small { padding: 6px 12px; font-size: 10px; }
.btn.danger { background: var(--danger); color: #fff; border-color: var(--danger); }

/* Flash */
.flash { border: 1px solid var(--line); background: var(--green); color: #000;
  padding: 12px 16px; margin-bottom: 20px; font-weight: 600; }

/* Login + receiver (centered pages) */
.center-page { min-height: calc(100vh - 57px); display: flex; align-items: flex-start;
  justify-content: center; padding: 60px 20px; }
.center-card { width: 100%; max-width: 520px; }
.hero-title { font-size: 42px; font-weight: 800; letter-spacing: -1.5px; line-height: 1.02;
  margin: 0 0 18px; }

.checklist { max-height: 420px; overflow-y: auto; border: 1px solid var(--line); }
.checklist label { display: flex; gap: 10px; align-items: center; padding: 8px 12px;
  border-bottom: 1px solid var(--soft-line); cursor: pointer; font-size: 14px; }
.checklist label:hover { background: var(--bg); }
.checklist input { width: 16px; height: 16px; accent-color: var(--green); }

/* Staging overlay: blocks interaction while OnFleet optimization runs. */
.busy-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: var(--overlay);
  display: flex; align-items: center; justify-content: center;
}
.busy-overlay[hidden] { display: none; }
.busy-card {
  background: var(--card); border: 1px solid var(--line); padding: 36px 44px;
  text-align: center; max-width: 420px;
}
/* The real Boxes mark: pieces pulse green in sequence while OnFleet works,
   then the box "opens" — pieces fly apart — when staging completes. */
.busy-card .boxes-mark { width: 84px; height: auto; margin-bottom: 18px; overflow: visible; }
.busy-card .boxes-mark .mp {
  animation: busy-pulse 1.4s ease-in-out infinite;
  transform-origin: center; transform-box: fill-box;
  transition: transform .7s cubic-bezier(.5, -0.2, .6, 1.4), opacity .7s ease;
}
.busy-card .boxes-mark .mp:nth-child(1) { animation-delay: 0s; }
.busy-card .boxes-mark .mp:nth-child(2) { animation-delay: .2s; }
.busy-card .boxes-mark .mp:nth-child(3) { animation-delay: .4s; }
.busy-card .boxes-mark .mp:nth-child(4) { animation-delay: .6s; }
.busy-card .boxes-mark .mp:nth-child(5) { animation-delay: .8s; }
.busy-card .boxes-mark .mp:nth-child(6) { animation-delay: 1s; }
.busy-card .boxes-mark .mp:nth-child(7) { animation-delay: 1.2s; }
@keyframes busy-pulse {
  0%, 60%, 100% { fill: var(--mark); transform: scale(1); }
  30% { fill: var(--green); transform: scale(1.3); }
}
/* The core (piece 2) stays black while loading — a scale-only pulse. It
   only goes green at the moment the box opens. */
.busy-card .boxes-mark .mp:nth-child(2) { animation-name: busy-pulse-core; }
@keyframes busy-pulse-core {
  0%, 60%, 100% { transform: scale(1); }
  30% { transform: scale(1.15); }
}
/* Box-opens finale: each piece departs outward and fades. */
/* Box-opens finale: the core turns green while the outer pieces blast
   radially out of frame; the overlay lingers 2s so the exit plays out.
   Piece order: 1 bottom, 2 center, 3 lower-right, 4 upper-right, 5 top,
   6 lower-left, 7 upper-left — each flies along its own bearing. */
.busy-card.done .boxes-mark .mp { animation: none; fill: var(--mark);
  transition: transform 2s cubic-bezier(.35, 0, .65, .3); }
.busy-card.done .boxes-mark .mp:nth-child(2) { fill: var(--green); transform: scale(1.18); }
.busy-card.done .boxes-mark .mp:nth-child(1) { transform: translate(-60px, 1300px) rotate(35deg); }
.busy-card.done .boxes-mark .mp:nth-child(3) { transform: translate(1300px, 760px) rotate(-40deg); }
.busy-card.done .boxes-mark .mp:nth-child(4) { transform: translate(1250px, -900px) rotate(30deg); }
.busy-card.done .boxes-mark .mp:nth-child(5) { transform: translate(-50px, -1300px) rotate(-30deg); }
.busy-card.done .boxes-mark .mp:nth-child(6) { transform: translate(-1350px, 680px) rotate(40deg); }
.busy-card.done .boxes-mark .mp:nth-child(7) { transform: translate(-1300px, -760px) rotate(-35deg); }
.busy-card.done .busy-bar .stripes { animation-duration: .4s; }
.busy-card h2 { margin: 0 0 6px; }
.busy-card .sub { font-family: var(--mono); font-size: 10px; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--muted); margin-bottom: 20px; }
.busy-bar {
  height: 10px; border: 1px solid var(--line); overflow: hidden; background: var(--card);
}
.busy-bar .stripes {
  height: 100%; width: 200%;
  background: repeating-linear-gradient(-45deg,
    var(--green) 0 12px, var(--card) 12px 24px);
  animation: busy-march 1s linear infinite;
}
@keyframes busy-march { from { transform: translateX(-34px); } to { transform: translateX(0); } }

.mono { font-family: var(--mono); font-size: 12px; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
footer { font-family: var(--mono); font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--muted); padding: 24px;
  border-top: 1px solid var(--soft-line); margin-top: 40px; text-align: center; }

/* ---------- Mobile (dashboard, orders, plan, routes) ----------
   Everything below is scoped to small screens; desktop is untouched. */
@media (max-width: 720px) {
  /* Topbar becomes two rows: brand + actions, then a swipeable nav strip. */
  .topbar { flex-wrap: wrap; height: auto; padding: 10px 12px 0; gap: 10px; row-gap: 4px; }
  .topbar .right { gap: 8px; }
  .mode-chip { display: none; }  /* long and staff-only; save the width */
  nav.main { order: 10; flex-basis: 100%; height: 42px; overflow-x: auto;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  nav.main::-webkit-scrollbar { display: none; }
  nav.main a { padding: 0 10px; white-space: nowrap; }

  .wrap { padding: 16px 12px 60px; }
  h1 { font-size: 26px; }

  /* Wide tables scroll inside their card instead of stretching the page. */
  .card { overflow-x: auto; }
  .card > table, .scroll-table table { min-width: 600px; }
  /* ...but the RECEIVER page is label/value pairs, not a staff data grid:
     inheriting that 600px floor pushed the manifest, status badge, and —
     worst — the arrival time off a phone screen. Let it fit. */
  .center-card .card { overflow-x: visible; }
  .center-card .card > table { min-width: 0; }
  .center-card .card > table td { word-break: break-word; }

  /* Stat tiles: 2×2 instead of one tall stack. */
  .grid.cols-4 { grid-template-columns: 1fr 1fr; }
  .stat .n { font-size: 24px; }

  /* Busyness calendar: tighter cells; the numbers live in the tap tooltip. */
  .cal-cell { min-height: 42px; padding: 4px 5px; }
  .cal-sub { display: none; }
  .cal-num { font-size: 10px; }
  .cal-head { padding: 4px 5px; font-size: 9px; }
  .cal-dot { top: 4px; right: 4px; width: 7px; height: 7px; }
}

/* Receiver page: one-reschedule warning callout */
.resched-warn { background: var(--tint-yellow); border: 1px solid var(--line);
  padding: 10px 14px; margin-bottom: 14px; font-size: 14px; }

/* Plan page: mini busyness calendar (click a day to plan it) */
.cal-mini .cal-cell { min-height: 34px; padding: 3px 5px; }
.cal-mini .cal-num { font-size: 10px; }
.cal-mini .cal-head { padding: 4px 5px; font-size: 9px; }
.cal-mini .cal-dot { top: 3px; right: 3px; width: 7px; height: 7px; }
.cal-mini .cal-cell.clickable { cursor: pointer; }
.cal-mini .cal-cell.clickable:hover { box-shadow: inset 0 0 0 2px var(--green-dark); }
/* Picked beats hover: the selected ring shows the instant the day is
   clicked, even while the pointer is still parked on the cell. */
.cal-mini .cal-cell.picked,
.cal-mini .cal-cell.picked:hover { box-shadow: inset 0 0 0 3px var(--ink); font-weight: 700; }

/* Plan page: the calendar card stretches to match its neighbor — week rows
   share the leftover height so the grid fills the pane. */
.cal-fill { display: flex; flex-direction: column; }
.cal-fill .cal-mini { flex: 1; grid-template-rows: auto repeat(4, 1fr); }
.cal-fill .cal-mini .cal-cell { min-height: 48px; }
.cal-fill .cal-mini .cal-num { font-size: 11px; }
.cal-fill .cal-mini .cal-sub { font-size: 8.5px; margin-top: 1px; letter-spacing: 0; }
.route-map .map-legend .map-tab { cursor: pointer; }
.route-map .map-hit, .route-map .map-dot { cursor: pointer; }
