/* ============================================================
   Load Board — stylesheet
   Design intent: this is an operations tool people stare at all
   shift, not a marketing page. Density, legibility, and fast
   visual scanning (status color) matter more than decoration.
   ============================================================ */
:root {
  --navy-950: #0b1220;
  --navy-900: #101a2e;
  --navy-800: #172542;
  --slate-700: #33415c;
  --slate-500: #5c6b85;
  --slate-300: #aab4c6;
  --slate-100: #eef1f6;
  --paper: #f7f8fb;
  --line: #dbe1eb;
  --amber-bg: #fdf3d0;
  --amber-line: #e8cf7e;
  --green-bg: #dcf3e4;
  --green-line: #8fd1a8;
  --blue-bg: #e2ecfb;
  --blue-line: #a9c4ea;
  --red-600: #c0362c;
  --red-bg: #f8d6d3;
  --good-surf: #92A2A6;
  --pea-flower: #6777B6;
  --butter-yellow: #EFCE7B;
  --pistachio: #CBD183;
  --focus: #2f6fed;
  --radius-sm: 4px;
  --radius-md: 8px;
  --font-ui: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
}
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--paper);
  color: var(--navy-950);
  font-family: var(--font-ui);
  font-size: 13px;
}
/* Belt-and-suspenders on top of #board-view's own overflow:hidden — this
   guarantees the body itself can never scroll on pages using the
   #board-view pattern (every board page, Location/Driver Analytics),
   even if some minor height discrepancy would otherwise let it. Scoped
   with :has() so driverlist.html, which has no internal scroll
   container of its own and genuinely needs the whole page to scroll,
   is completely unaffected. */
body:has(#board-view) {
  overflow: hidden;
}
button {
  font-family: inherit;
  cursor: pointer;
}
/* ---------------- Top bar / brand + nav ---------------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 28px;
  background: var(--good-surf);
  padding: 0 20px;
  height: 52px;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #000;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.brand-mark {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  background: linear-gradient(135deg, #2f6fed, #17b06b);
  flex: none;
}
.tabs {
  display: flex;
  gap: 2px;
  height: 100%;
  overflow-x: auto;
  flex: 1;
}
/* Bottom-right notification widget — chat-window style, always visible
   (even with zero alerts), collapsed by default, blinks when a genuinely
   new alert arrives while collapsed. Draggable by its header; position
   and open/closed/expanded state all persist across page loads. */
#alert-widget {
  position: fixed; bottom: 16px; right: 16px; width: 320px; z-index: 200;
  background: #fff; border: 1px solid var(--slate-500, #cbd5e1); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.16); font-size: 13px; overflow: hidden;
}
#alert-widget.hidden { display: none; }
.alert-widget-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px; cursor: grab; font-weight: 700; background: var(--navy-950, #0f172a); color: #fff;
  user-select: none;
}
.alert-widget-header:active { cursor: grabbing; }
.alert-widget-controls { display: flex; gap: 4px; }
.alert-widget-btn {
  background: rgba(255,255,255,0.15); border: none; color: #fff; width: 22px; height: 22px;
  border-radius: 4px; cursor: pointer; font-size: 14px; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.alert-widget-btn:hover { background: rgba(255,255,255,0.3); }
.alert-widget-body { max-height: 0; overflow-y: auto; transition: max-height 0.2s ease; }
#alert-widget.expanded .alert-widget-body { max-height: 360px; }
.alert-empty { padding: 16px; color: var(--slate-500, #64748b); }
.alert-chat-item {
  display: flex; gap: 8px; align-items: flex-start; padding: 10px 12px; text-decoration: none; color: inherit;
  border-bottom: 1px solid var(--slate-100, #f1f5f9); cursor: pointer;
}
.alert-chat-item:last-child { border-bottom: none; }
.alert-chat-item:hover { background: var(--slate-100, #f1f5f9); }
.alert-chat-icon { flex-shrink: 0; }
.alert-chat-text { flex: 1; }
.alert-chat-time { flex-shrink: 0; color: var(--slate-500, #64748b); font-size: 11px; white-space: nowrap; }
.alert-chat-item { flex-wrap: wrap; }
.alert-action-btn {
  flex-shrink: 0; margin-left: 26px; margin-top: 4px; padding: 3px 10px; font-size: 11px; font-weight: 700;
  border: none; border-radius: var(--radius-sm, 4px); background: var(--navy-900, #1e293b); color: #fff; cursor: pointer;
}
.alert-action-btn:hover { background: var(--navy-800, #334155); }
#alert-widget.blinking .alert-widget-header,
#alert-widget-reopen.blinking { animation: alertBlink 1s ease-in-out infinite; }
.alert-widget-new { font-size:11px; color:#fde68a; }
#alert-widget-reopen-count:not(:empty) {
  position:absolute; top:-5px; right:-5px; min-width:22px; padding:3px 5px;
  border-radius:999px; background:#dc2626; color:white; font-size:11px; font-weight:700;
}
@media (prefers-reduced-motion: reduce) {
  #alert-widget.blinking .alert-widget-header, #alert-widget-reopen.blinking {
    animation:none; background:#b91c1c;
  }
}
@keyframes alertBlink {
  0%, 100% { background: var(--navy-950, #0f172a); }
  50% { background: #dc2626; }
}
#alert-widget-reopen {
  position: fixed; bottom: 16px; right: 16px; z-index: 200; width: 44px; height: 44px;
  border-radius: 999px; border: none; background: var(--navy-950, #0f172a); color: #fff;
  font-size: 18px; cursor: pointer; box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}
#alert-widget-reopen.hidden { display: none; }
#alert-widget-reopen:hover { background: #1e293b; }
.tab-btn {
  border: none;
  background: transparent;
  color: #000;
  padding: 0 16px;
  height: 100%;
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
  white-space: nowrap;
}
.tab-btn:hover { background: rgba(0,0,0,0.08); }
.tab-btn.active {
  color: #000;
  border-bottom-color: #000;
  background: rgba(0,0,0,0.12);
  font-weight: 800;
}
/* ---------------- Toolbar (title / date nav / actions) ---------------- */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 20px;
  border-bottom: 1px solid var(--line);
  background: #fff;
  flex-wrap: wrap;
}
.toolbar-left h1 {
  margin: 0;
  font-size: 17px;
  font-weight: 800;
  color: var(--navy-950);
}
.toolbar-left .subtext {
  margin-top: 2px;
  font-size: 12px;
  color: var(--slate-500);
}
.date-nav {
  display: flex;
  align-items: center;
  gap: 6px;
}
.date-nav button:not(.today-pill) {
  border: 1px solid var(--line);
  background: #fff;
  border-radius: var(--radius-sm);
  width: 28px;
  height: 28px;
  font-size: 14px;
  color: var(--navy-950);
}
.date-nav button:not(.today-pill):hover { background: var(--slate-100); }
.date-nav button:disabled { opacity: 0.35; cursor: not-allowed; }
.date-nav input[type="date"] {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  height: 28px;
  padding: 0 8px;
  font-size: 12.5px;
  font-family: var(--font-ui);
}
.today-pill {
  border: 1px solid var(--line);
  background: var(--slate-100);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 700;
  color: var(--slate-700);
  white-space: nowrap;
  flex-shrink: 0;
}
.toolbar-actions { display: flex; gap: 8px; position: relative; }
/* Keep board dates in their own column as selection actions appear. */
#board-view > .toolbar {
  display: grid;
  grid-template-columns: minmax(500px, 35%) max-content minmax(0, 1fr);
  align-items: start;
}
#board-view > .toolbar > .date-nav {
  margin-top: 7px;
}
#board-view > .toolbar > .toolbar-actions {
  justify-content: flex-end;
  flex-wrap: wrap;
  min-width: 0;
}
@media (max-width: 1100px) {
  #board-view > .toolbar {
    grid-template-columns: minmax(0, 1fr) max-content;
  }
  #board-view > .toolbar > .toolbar-actions {
    grid-column: 1 / -1;
  }
}
@media (max-width: 700px) {
  #board-view > .toolbar {
    grid-template-columns: minmax(0, 1fr);
  }
  #board-view > .toolbar > .date-nav {
    margin-top: 0;
  }
  #board-view > .toolbar > .toolbar-actions {
    justify-content: flex-start;
  }
}
.btn {
  border: 1px solid var(--slate-700);
  background: var(--navy-900);
  color: #fff;
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn:hover { background: var(--navy-800); }
.btn-ghost {
  background: #fff;
  color: var(--navy-950);
  border: 1px solid var(--line);
}
.btn-ghost:hover { background: var(--slate-100); }
.btn-danger-outline {
  background: #fff;
  color: var(--red-600);
  border: 1px solid var(--red-600);
}
.btn-danger-outline:hover { background: var(--red-bg); }
/* Solid red, for an action that destroys something. Deliberately louder than
   the outline variant: this is the button that permanently removes a route. */
.btn-danger {
  background: var(--red-600, #dc2626);
  color: #fff;
  border: 1px solid var(--red-600, #dc2626);
}
.btn-danger:hover:not(:disabled) { background: #b91c1c; border-color: #b91c1c; }
.btn-danger:disabled {
  background: #fff;
  color: var(--slate-500, #64748b);
  border-color: var(--line);
  opacity: .7;
  cursor: not-allowed;
}
/* Columns visibility panel */
.columns-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(10,20,40,0.18);
  width: 240px;
  max-height: 420px;
  overflow-y: auto;
  z-index: 40;
  padding: 10px 0;
}
.columns-panel-group-label {
  padding: 6px 14px 4px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--slate-500);
}
.columns-panel label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  font-size: 12.5px;
  color: var(--navy-950);
  cursor: pointer;
}
.columns-panel label:hover { background: var(--slate-100); }
.columns-panel input[type="checkbox"] { width: 14px; height: 14px; }
.columns-panel-footer {
  padding: 8px 14px 2px;
  border-top: 1px solid var(--line);
  margin-top: 6px;
}
.columns-panel-footer button {
  border: none;
  background: none;
  color: var(--focus);
  font-size: 11.5px;
  font-weight: 700;
  padding: 0;
}
.columns-panel-footer button:hover { text-decoration: underline; }
/* ---------------- Grid ---------------- */
#board-view {
  display: flex;
  flex-direction: column;
  margin-top: 52px; /* topbar is now position:fixed and out of flow — this replaces the space it used to occupy */
  max-height: calc(100vh - 52px); /* 52px = .topbar height — caps a large board so it still scrolls internally instead of stretching the page, but doesn't force this height when there's little content */
  overflow: hidden; /* without this, content taller than max-height (e.g. a page with a tall toolbar section above the table) makes the page itself scroll too, on top of .grid-scroll's own internal scrollbar — two scrollbars instead of one */
}
.grid-scroll {
  flex: 1;
  min-height: 0; /* required so a flex child can actually shrink and scroll internally */
  overflow: auto;
  border-top: 1px solid var(--line);
}
/* Full live redraws replace anchor nodes; the board renderer preserves the
   viewport explicitly instead of letting the browser pick a new anchor. */
#board-view .grid-scroll { overflow-anchor: none; }
.board-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--slate-500);
  font-size: 13px;
  border-top: 1px solid var(--line);
}
table.board {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
}
table.board thead th {
  position: sticky;
  top: 0;
  background: var(--good-surf);
  color: #000;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 700;
  padding: 4px 6px;
  border-right: 1px solid #000;
  border-bottom: 2px solid #000;
  white-space: nowrap;
  z-index: 5;
}
/* Location Analytics specifically — column headers at least as large as
   the table's own body text (13px). Scoped to #la-table only; the main
   board pages keep the smaller 9.5px header size above, which is
   likely deliberate given how many more columns those tables carry. */
#la-table thead th {
  font-size: 13px;
}
table.board thead th.col-draggable { cursor: grab; }
table.board thead th.col-draggable:active { cursor: grabbing; }
table.board thead th.col-drop-target { box-shadow: inset 3px 0 0 var(--focus); }
table.board td {
  border-right: 1px solid #000;
  border-bottom: 1px solid #000;
  padding: 1.5px 5px;
  vertical-align: middle;
  white-space: nowrap;
  background: #fff;
}
table.board tbody tr:nth-child(even) td { background: #fbfcfe; }
table.board tbody tr.is-row-pinned td { background: rgba(234, 179, 8, 0.14); }
table.board tbody tr.is-row-selected td { background: rgba(59, 130, 246, 0.14); }
/* Temporary attention-flash when clicking an alert jumps to its row —
   fades out on its own after a few seconds, doesn't need manual dismissal. */
@keyframes alert-outline-pulse {
  0%, 100% { box-shadow: inset 0 0 0 3px #f59e0b; }
  50% { box-shadow: inset 0 0 0 3px rgba(245, 158, 11, 0.3); }
}
tr.alert-outline-flash td { animation: alert-outline-pulse 0.6s ease-in-out 4; }
/* "Someone's editing this row" — a real outline, not just a tint, so it
   stays clearly visible regardless of whatever background color the row
   already has (TONU red, shift-complete green, zebra striping, etc).
   box-shadow instead of border so toggling it on/off never shifts row
   height. Every cell gets a top/bottom line that joins up with its
   neighbors into one continuous line across the whole row; the leftmost
   pinned cell also gets a left edge to close the box visually. */
table.board tbody tr.is-being-edited td {
  background: rgba(37, 99, 235, 0.14);
  box-shadow: inset 0 3px 0 0 #2563eb, inset 0 -3px 0 0 #2563eb;
  transition: box-shadow 0.15s ease, background 0.15s ease;
}
table.board tbody tr.is-being-edited td.pin {
  background: rgba(37, 99, 235, 0.24);
}
table.board tbody tr.is-being-edited td.pin-select {
  box-shadow: inset 3px 0 0 0 #2563eb, inset 0 3px 0 0 #2563eb, inset 0 -3px 0 0 #2563eb;
}
/* Board hover is driven by board-row-hover-enhancements.js, not by native
   :hover. A load's shift-level cells are rowspanned out of its first row, so
   native :hover reassigns the highlight to route 1 the moment the pointer
   enters the pinned Driver/PRO# columns and reassigns it back on the way out
   -- the highlight flickering between two rows for one continuous move. The
   script decides which logical row the pointer is on and marks it. */
/* The hover tint itself lives in board-row-hover-enhancements.js, which
   owns this class. It is a background-IMAGE gradient plus inset top and
   bottom edges, so the column colours below survive under it rather than
   being repainted -- see the note there. Nothing here should set an
   opaque background for the hovered row again. */
/* Column highlights, per request: Shift Start in pea flower, Next Call
   Time in butter yellow, the whole Route ID -> Ppwk Rec'd range in
   pistachio. Full column, header through every data row. */
table.board th.col-shiftStart,
table.board td.col-shiftStart { background: var(--pea-flower) !important; }
table.board th.col-nextCallTimeCalc,
table.board td.col-nextCallTimeCalc { background: var(--butter-yellow) !important; }
table.board th.col-pistachio,
table.board td.col-pistachio { background: var(--pistachio) !important; }
/* A saved Highlight applies to the whole logical load row, including cells
   whose column/status surfaces normally use !important. Hover remains the
   strongest temporary treatment so the row under the pointer stays clear. */
table.board tbody tr.is-row-pinned > td {
  background: rgba(234, 179, 8, 0.22) !important;
}
/* The other two tables keep a native :hover fill -- neither has rowspanned
   cells, so there is nothing for the script to reconcile -- but they use the
   same tint-over-colour treatment so hover reads identically site-wide. */
table.driverlist tbody tr:hover > td,
table.available-table tbody tr:hover > td {
  background-image: linear-gradient(rgba(37, 99, 235, 0.13), rgba(37, 99, 235, 0.13));
  box-shadow: inset 0 1px 0 0 rgba(37, 99, 235, 0.55), inset 0 -1px 0 0 rgba(37, 99, 235, 0.55);
}
/* pinned/sticky left columns */
.pin {
  position: sticky;
  z-index: 3;
  background: #fff;
  will-change: transform;
  isolation: isolate;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pin-select { left: 0; width: 74px; min-width: 74px; text-align: center; }
.pin-text { left: 74px; width: 46px; min-width: 46px; }
.pin-pro { left: 120px; width: 92px; min-width: 92px; }
.pin-driver { left: 212px; width: 160px; min-width: 160px; }
.board-select-count {
  font-size: 8.5px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
  line-height: 1.25;
  white-space: normal;
  padding-bottom: 2px;
  color: #000;
}
table.board tbody tr:nth-child(even) td.pin { background: #fbfcfe; }
table.board tbody tr.is-row-pinned td.pin { background: rgba(234, 179, 8, 0.22) !important; }
table.board tbody tr.is-row-selected td.pin { background: rgba(59, 130, 246, 0.22); }
table.board thead th.pin { z-index: 6; }
/* Shift Complete — green tint specifically on the PRO# cell */
td.pin-pro.shift-complete-tint {
  background: rgba(34, 197, 94, 0.18) !important;
}
/* Fully documented — every trip clean (no red pill) AND the time sheet is
   in. A stricter, more saturated green than the basic completion tint
   above, since a shift can be "complete" while a trip is still missing
   something (paperwork, an image, etc). */
td.pin-pro.pro-fully-documented {
  background: rgba(21, 128, 61, 0.32) !important;
  border-color: #15803d !important;
}
.trip-chip.shift-complete-tint { background: rgba(34, 197, 94, 0.18) !important; }
@keyframes tripCompletedFlash {
  0% { background: rgba(34, 197, 94, 0.55); }
  100% { background: rgba(34, 197, 94, 0.18); }
}
.trip-chip.trip-just-completed-flash { animation: tripCompletedFlash 1.5s ease-out; }
tr.quick-add-row td { background: var(--slate-100) !important; padding: 0; border-top: 1px dashed var(--line); }
.quick-add-btn {
  border: none;
  background: none;
  color: var(--navy-950);
  font-size: 12px;
  font-weight: 700;
  height: 34px;
  text-align: left;
}
.quick-add-btn:hover { background: #fff; }
.quick-add-btn-label {
  position: sticky;
  left: 6px;
  display: inline-block;
  border: 1px dashed var(--slate-500);
  padding: 6px 18px;
  border-radius: var(--radius-sm);
  background: transparent;
}
/* Second button needs its own sticky offset so it doesn't land on top of
   the first one once both are pinned during a horizontal scroll. */
.quick-add-btn-secondary .quick-add-btn-label { left: 150px; }
.quick-add-btn:hover .quick-add-btn-label { border-style: solid; }
.text-btn {
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  font-size: 10.5px;
  font-weight: 700;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  width: 40px;
}
.text-btn:hover { background: var(--slate-100); }
/* Right-click context menu */
.row-context-menu {
  position: fixed;
  z-index: 200;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(10,20,40,0.22);
  padding: 6px 0;
  min-width: 180px;
}
.context-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  padding: 8px 14px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--navy-950);
}
.context-menu-item:hover { background: var(--slate-100); }
.context-menu-item-success { color: #15803d; }
.context-menu-item-success:hover { background: rgba(34, 197, 94, 0.12); }
.context-menu-item-danger { color: var(--red-600, #dc2626); border-top: 1px solid var(--line); margin-top: 4px; padding-top: 10px; }
.context-menu-item-danger:hover { background: rgba(220, 38, 38, 0.08); }
.tg-group-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.tg-group-tab {
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  font-size: 12.5px;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: 999px;
}
.tg-group-tab:hover { background: var(--slate-100); }
.tg-group-tab.is-active {
  background: var(--navy-950);
  border-color: var(--navy-950);
  color: #fff;
}
.location-tabs { display: flex; gap: 8px; padding: 0 0 14px 0; }
.location-tab {
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  font-size: 13px;
  font-weight: 700;
  padding: 8px 18px;
  border-radius: var(--radius-md);
}
.location-tab:hover { background: var(--slate-100); }
.location-tab.is-active {
  background: var(--navy-950);
  border-color: var(--navy-950);
  color: #fff;
}
#date-input[readonly] { cursor: pointer; background: #fff; }
.date-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 28px rgba(10,20,40,0.18);
  width: 264px;
  padding: 10px 12px 12px;
}
.cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.cal-month-label { font-size: 13px; font-weight: 700; color: var(--navy-950); }
.cal-nav-btn {
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  line-height: 1;
}
.cal-nav-btn:hover { background: var(--slate-100); }
.cal-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 4px;
}
.cal-weekdays span {
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--slate-500);
}
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.cal-cell {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--navy-950);
}
.cal-dot {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--red-600, #dc2626);
}
.cal-cell-blank { visibility: hidden; }
.cal-cell:not(.cal-cell-blank):not(:disabled):hover { background: var(--slate-100); }
.cal-cell-empty {
  color: var(--slate-500);
  font-weight: 500;
  background: var(--slate-100);
}
.cal-cell-disabled {
  color: #d4d9e2;
  font-weight: 500;
  cursor: default;
}
.cal-cell-selected {
  background: var(--navy-950) !important;
  color: #fff !important;
}
.cal-cell-today:not(.cal-cell-selected) {
  box-shadow: inset 0 0 0 1.5px var(--navy-950);
}
.cell-input {
  border: 1px solid transparent;
  background: transparent;
  font-family: var(--font-ui);
  font-size: 11.5px;
  width: 100%;
  padding: 2px 3px;
  border-radius: var(--radius-sm);
  color: var(--navy-950);
}
.acct-driver-sort { border: 0; padding: 0; background: transparent; color: inherit; font: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer; }
.acct-driver-sort:hover { text-decoration: underline; }
.acct-driver-sort:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.cell-input:hover { border-color: var(--line); }
.cell-input:focus {
  outline: none;
  border-color: var(--focus);
  background: #fff;
  box-shadow: 0 0 0 2px rgba(47,111,237,0.15);
}
#accounting-table select[data-action="acct-revenue-level"] {
  appearance: none;
  -webkit-appearance: none;
  padding-left: 22px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='m3 4.5 3 3 3-3' fill='none' stroke='%230b1220' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 5px center;
  background-size: 12px 12px;
}
.cell-input.calc {
  color: var(--slate-700);
  font-family: var(--font-mono);
  font-weight: 600;
}
.cell-input.small { text-align: center; width: 40px; }
td.trip-block-start {
  border-left: 3px solid var(--slate-700);
  padding-left: 10px;
}
/* Alternating trip-block tint in the body — box-shadow instead of background-color
   so it layers cleanly on top of zebra striping, row hover, TONU, and the
   30-min highlight instead of fighting them for specificity. */
td.trip-tint-b {
  box-shadow: inset 0 0 0 1000px rgba(51, 65, 92, 0.045);
}
.chk { width: 16px; height: 16px; cursor: pointer; }
/* driver name cell + autocomplete */
.driver-name-wrap { position: relative; }
.autocomplete-list {
  position: absolute;
  top: 100%; left: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 18px rgba(10,20,40,0.15);
  min-width: 220px;
  max-height: 200px;
  overflow-y: auto;
  z-index: 30;
}
.autocomplete-item { padding: 6px 10px; font-size: 12.5px; cursor: pointer; }
.autocomplete-item:hover, .autocomplete-item.is-highlighted { background: var(--slate-100, #f1f5f9); }
/* The floating driver autocomplete is appended to <body> and positioned via
   JS (position:fixed, set inline), used both on regular pages and inside
   modals (Load Details) -- needs to sit above the modal overlay (z-index
   100), not just above regular page content. */
.driver-ac-floating { z-index: 500; }
.autocomplete-item:hover { background: var(--blue-bg); }
.autocomplete-item .ac-sub { color: var(--slate-500); font-size: 11px; }
/* TONU button */
.tonu-btn {
  border: 1px solid var(--red-600);
  background: #fff;
  color: var(--red-600);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  width: 56px;
}
.tonu-btn:hover { background: var(--red-bg); }
.tonu-btn.is-active {
  background: var(--red-600);
  color: #fff;
}
/* Highlight is now a context-menu action rather than a dedicated button —
   the amber tint itself is defined above (tr.is-row-pinned). */
tr.is-tonu td:not(.pin-select):not(.pin-text) .cell-input,
tr.is-tonu td:not(.pin-select):not(.pin-text) span.static-text {
  text-decoration: line-through;
  color: var(--slate-500);
}
/* A cancelled load reads the same way a TONU does -- struck through and
   greyed -- so it's obvious at a glance the load isn't running. The driver
   name column is deliberately left alone: who it was assigned to is the
   part still worth reading. */
tr.is-load-cancelled td:not(.pin-select):not(.pin-text) .cell-input,
tr.is-load-cancelled td:not(.pin-select):not(.pin-text) span.static-text {
  text-decoration: line-through;
  color: var(--slate-500);
}
tr.is-load-cancelled { background: rgba(71, 85, 105, 0.06); }
/* Faded back the same way a released row reads on the Accounting sheet, so a
   cancellation is obvious without having to read it. Cancelled loads also
   sort to the very bottom of the board -- see sinkRank() in loadboard.js.

   Opacity goes on the whole row, pinned columns included. That looks like it
   should let the scrolling cells show through PRO#/Driver, since those are
   position:sticky and the row becomes one composited group -- but it does
   not: the sticky cells still paint above their siblings INSIDE the group on
   their own opaque background, and only the finished group is faded against
   the page. Checked by sampling pixels inside the pinned Driver cell with
   1200px of columns scrolled underneath it: no bleed-through. */
tr.is-load-cancelled { opacity: 0.55; }
/* Hover lifts it back to full strength: a dispatcher checking why something
   was cancelled should not have to fight the styling to read it. */
table.board tbody tr.is-load-cancelled.site-row-hover-current { opacity: 1; }
/* Driver call-offs are persisted separately from explicit load cancellations,
   but both mean the load is no longer running. Keep the same visual treatment
   even when the board is rebuilt from Supabase. */
tr.is-called-off td:not(.pin-select):not(.pin-text) .cell-input,
tr.is-called-off td:not(.pin-select):not(.pin-text) span.static-text {
  text-decoration: line-through;
  color: var(--slate-500);
}
tr.is-called-off { background: rgba(71, 85, 105, 0.06); }
.is-driver-history-cancelled {
  text-decoration: line-through;
  color: var(--slate-500);
  background: rgba(71, 85, 105, 0.06);
}
.is-driver-history-cancelled .cell-link-btn,
.is-driver-history-cancelled .subtext { text-decoration: line-through; }
/* status swatches for salvage / backhaul flags */
.flag-yes { background: var(--amber-bg) !important; }
.flag-backhaul { background: var(--blue-bg) !important; }
/* highlight-new-entry animation: 30 min soft red tint */
@keyframes pulseIn {
  0% { background-color: rgba(192,54,44,0.55); }
  100% { background-color: rgba(192,54,44,0.16); }
}
tr.is-new td { animation: pulseIn 1.4s ease-out 1; background-color: rgba(192,54,44,0.16) !important; }
tr.is-new td.pin { background-color: rgba(192,54,44,0.22) !important; }
.add-trip-cell { text-align: center; }
.add-trip-btn {
  border: 1px dashed var(--slate-500);
  background: #fff;
  color: var(--slate-700);
  font-size: 11px;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: var(--radius-sm);
}
.add-trip-btn:hover { background: var(--slate-100); }
.calc-note {
  padding: 5px 20px;
  background: var(--amber-bg);
  border-bottom: 1px solid var(--amber-line);
  font-size: 11px;
  color: #6b5510;
}
#driver-sync-status {
  padding: 4px 20px;
  font-size: 11.5px;
  background: var(--blue-bg);
  border-bottom: 1px solid var(--blue-line);
  color: #1c3f6e;
}
#driver-sync-status.sync-error {
  background: var(--red-bg);
  border-bottom: 1px solid var(--red-600);
  color: var(--red-600);
  font-weight: 600;
}
/* The sticky Accounting shows when a load-board push replaced what was on the
   row. Small, yellow, unmissable next to a driver name, and clickable to
   dismiss -- it is an acknowledgement, not an error. */
.acct-push-sticky {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: 6px;
  padding: 0;
  vertical-align: middle;
  border: 1px solid #d9a441;
  border-radius: 3px;
  background: var(--butter-yellow, #ffe89a);
  color: #6b4d05;
  font: 700 11px/1 system-ui, -apple-system, "Segoe UI", sans-serif;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(11, 18, 32, 0.25);
}
.acct-push-sticky:hover { background: #ffd966; }

/* A release that refused, marked on the checkbox the operator clicked --
   the status line above the table is off screen by row 900. */
.acct-release-error {
  display: inline-block;
  margin-left: 4px;
  width: 14px;
  height: 14px;
  line-height: 14px;
  border-radius: 50%;
  background: #c0392b;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  text-align: center;
  cursor: help;
  vertical-align: middle;
}

/* ---------------- Accounting: find a load ----------------
   The sheet is one location on one day; this reaches any load in the
   database by Trip ID, Route ID, Load # or PRO #. Results sit in flow under
   the field rather than in a floating dropdown -- a match list can run to 50
   rows, and an overlay that long covers the sheet it is meant to help with. */
.acct-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 0 0 12px 0;
}
.acct-search-label {
  font-size: 12.5px;
  font-weight: 700;
}
.acct-search-input {
  flex: 0 1 320px;
  min-width: 200px;
  padding: 6px 8px;
  border: 1px solid var(--slate-500);
  border-radius: var(--radius-sm);
  font: inherit;
}
.acct-search-results {
  flex-basis: 100%;
  margin-top: 4px;
  max-height: 340px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  font-size: 13px;
}
.acct-search-results:empty { display: none; }
.acct-search-results.is-error { border-color: #fecdd3; background: #fff1f2; color: #881337; }
.acct-search-results.is-empty { color: var(--slate-500); }
.acct-search-results.hidden { display: none; }
.acct-search-summary {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  color: var(--slate-500);
}
.acct-search-hit {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 14px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.acct-search-hit:last-child { border-bottom: 0; }
.acct-search-hit:hover,
.acct-search-hit:focus-visible { background: #eef2f9; }
.acct-search-hit-main { display: flex; align-items: baseline; gap: 8px; }
.acct-search-hit-driver { color: var(--slate-500); }
.acct-search-hit-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  color: var(--slate-500);
  font-size: 12px;
}
/* Which field matched is the whole reason a list has more than one row on
   it -- two loads can share a Trip ID and differ in nothing else visible. */
.acct-search-hit-match { font-weight: 700; color: var(--ink, #0b1220); }

/* ---------------- Column visibility ----------------
   Each rule hides every cell for that column — header cells in both
   header rows, and body cells in all 5 trip blocks where relevant —
   in one shot, driven by a class toggled on <table class="board">. */
table.board .col-schneider { min-width: 105px; }
table.board.hide-col-schneider .col-schneider,
table.board.hide-col-carrierRate .col-carrierRate,
table.board.hide-col-backhaulLocation .col-backhaulLocation,
table.board.hide-col-salvageBhaulRefusedBy .col-salvageBhaulRefusedBy,
table.board.hide-col-rate .col-rate,
table.board.hide-col-cell .col-cell,
table.board.hide-col-dispatcherPhone .col-dispatcherPhone,
table.board.hide-col-email .col-email,
table.board.hide-col-shiftDate .col-shiftDate,
table.board.hide-col-mc .col-mc,
table.board.hide-col-rating .col-rating,
table.board.hide-col-driverPreference .col-driverPreference,
table.board.hide-col-shiftStart .col-shiftStart,
table.board.hide-col-etaShiftReport .col-etaShiftReport,
table.board.hide-col-shiftHosLeft .col-shiftHosLeft,
table.board.hide-col-revLevel .col-revLevel,
table.board.hide-col-routeId .col-routeId,
table.board.hide-col-tripId .col-tripId,
table.board.hide-col-trailerOut .col-trailerOut,
table.board.hide-col-routeMiles .col-routeMiles,
table.board.hide-col-stopCount .col-stopCount,
table.board.hide-col-dispatchTime .col-dispatchTime,
table.board.hide-col-lastStopDepart .col-lastStopDepart,
table.board.hide-col-returnToDC .col-returnToDC,
table.board.hide-col-salvage .col-salvage,
table.board.hide-col-backhaul .col-backhaul,
table.board.hide-col-salvageBhaulRefusedBy .col-salvageBhaulRefusedBy,
table.board.hide-col-backhaulTrailerNumber .col-backhaulTrailerNumber,
table.board.hide-col-returnEtaToDc .col-returnEtaToDc,
table.board.hide-col-routeEstHours .col-routeEstHours,
table.board.hide-col-backhaulType .col-backhaulType,
table.board.hide-col-etaToFinalStop .col-etaToFinalStop,
table.board.hide-col-estRouteComplete .col-estRouteComplete,
table.board.hide-col-etaNextDispatch .col-etaNextDispatch,
table.board.hide-col-tripCallTime .col-tripCallTime,
table.board.hide-col-routeImage .col-routeImage {
  display: none;
}
/* ---------------- Driver list tab ---------------- */
.panel { padding: 20px; }
#driverlist-view {
  margin-top: 52px; /* topbar is now position:fixed and out of flow — this replaces the space it used to occupy */
}
/* Driver List toolbar stays on screen while the list scrolls — unlike the
   board pages, this page has no internal scroll container of its own, so
   the whole page scrolls and the toolbar needs position:sticky to stay put. */
#driverlist-view .toolbar {
  position: sticky;
  top: 52px; /* height of .topbar */
  z-index: 40;
  margin: -20px -20px 0;
  padding-left: 20px !important;
  padding-right: 20px !important;
}
.edit-driver-btn {
  border: 1px solid var(--line);
  background: #fff;
  color: var(--navy-950);
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
}
.edit-driver-btn:hover { background: var(--slate-100); border-color: var(--slate-500); }
.driverlist-scroll { overflow-x: auto; }
table.driverlist { width: 100%; border-collapse: collapse; background: #fff; }
table.driverlist th {
  text-align: left;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--slate-500);
  border-bottom: 2px solid var(--line);
  padding: 8px;
}
table.driverlist th.sortable {
  cursor: pointer;
  user-select: none;
}
table.driverlist th.sortable:hover {
  color: var(--navy-950);
}
table.driverlist th .sort-arrow {
  font-size: 9px;
  letter-spacing: 0;
}
table.board th.board-sortable {
  cursor: pointer;
  user-select: none;
}
table.board th.board-sortable:hover {
  background: #a9b7ba;
}
table.board th.board-sortable .sort-arrow {
  font-size: 8px;
  letter-spacing: 0;
}
table.driverlist td {
  padding: 8px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}
table.driverlist tr.is-new td { animation: pulseIn 1.4s ease-out 1; background-color: rgba(192,54,44,0.16) !important; }
.badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
}
.badge-yes { background: var(--green-bg); color: #1b6b3d; }
.badge-no { background: var(--slate-100); color: var(--slate-500); }
/* ---------------- Placeholder tabs ---------------- */
.placeholder {
  margin: 60px auto;
  max-width: 480px;
  text-align: center;
  color: var(--slate-500);
}
.placeholder h2 { color: var(--navy-950); margin-bottom: 6px; }
/* ---------------- Modals ---------------- */
.overlay {
  position: fixed; inset: 0;
  background: rgba(11,18,32,0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
}
/* Driver profile opens FROM WITHIN Load Details on every board now (the
   "↗" link next to the driver name) — it needs to render above that modal,
   not behind it. Same z-index as any other .overlay would fall back to DOM
   order, and this modal is defined earlier in the HTML than the newer Load
   Details modals, so it was losing that fight even though it's opened
   more recently and should be the one on top. */
#modal-add-driver { z-index: 150; }
/* Load Details, opened FROM WITHIN the driver profile's History tab (a
   PRO#/Load# link) — needs to render above #modal-add-driver (z-index
   150) in that specific case. Only applied via the ld-in-front class,
   added by openLoadFromDriverHistory() and removed on close, so a
   normal (non-nested) open of Load Details is unaffected. */
#modal-load-details.ld-in-front { z-index: 200; }
/* Load Details fills in piece by piece: the tabs render first, then
   attachments, change history, stop times, and the mobile-app paperwork
   section each land as their queries come back. With the card sized to its
   contents every one of those arrivals changed its height, and because the
   overlay centers the card it moved on screen each time -- which is what read
   as the modal shaking and resizing while it opened. Give the card one fixed
   envelope and let the body scroll inside it, so only the contents move. */
#modal-load-details > .modal {
  height: min(82vh, 780px);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#modal-load-details > .modal > .modal-header,
#modal-load-details > .modal > .modal-tabs,
#modal-load-details > .modal > .modal-footer { flex: 0 0 auto; }
#modal-load-details > .modal > #ld-tab-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}
.hidden { display: none !important; }
.modal {
  background: #fff;
  border-radius: var(--radius-md);
  width: 440px;
  max-width: 92vw;
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: 0 20px 50px rgba(10,20,40,0.35);
}
.modal-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
}
/* Route image thumbnail (Mondelez) — small, clickable, opens the lightbox */
.mdz-image-dropzone {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 6px;
  min-width: 40px; min-height: 26px;
  border: 1.5px dashed var(--slate-300, #cbd5e1);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.mdz-image-dropzone:hover, .mdz-image-dropzone:focus { border-color: var(--slate-500, #64748b); outline: none; }
.mdz-image-dropzone.mdz-dropzone-active { border-color: #2563eb; background: rgba(37, 99, 235, 0.08); }
.mdz-upload-hint { font-size: 9.5px; color: var(--slate-500, #64748b); text-align: center; line-height: 1.2; padding: 2px 4px; pointer-events: none; }
.mdz-hidden-file-input { display: none; }
.mdz-thumb-wrap { position: relative; display: inline-block; }
#st-image-slot .mdz-image-dropzone { width: 100%; min-height: 60px; }
#st-image-slot .mdz-route-thumb { width: 52px; height: 52px; }
.mdz-route-thumb {
  width: 26px; height: 26px;
  object-fit: cover;
  border-radius: 4px;
  cursor: pointer;
  border: 1px solid var(--line);
  transition: transform 0.12s ease;
}
.mdz-route-thumb:hover { transform: scale(1.08); }

/* A PDF sits in the same cells as the route photographs, but it cannot be an
   <img> -- that renders as a broken-image icon -- and the app's zoom/rotate
   viewer is an <img> too. So it shows as a chip that opens the file in a
   browser tab, where Chrome and Edge render it with their own viewer. Sized
   to the 26px thumbnail beside it so a row holding both stays one line. */
.mdz-pdf-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 150px;
  height: 26px;
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--navy-950);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease;
}
.mdz-pdf-chip:hover { transform: scale(1.04); border-color: var(--red-600); }
.mdz-pdf-chip-badge {
  flex: 0 0 auto;
  border-radius: 3px;
  padding: 1px 4px;
  background: var(--red-600);
  color: #fff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .03em;
}
/* The filename is the useful part, so it truncates rather than wrapping --
   a wrapped chip would double the row height, which is what made the phone
   columns unreadable in the Available list. */
.mdz-pdf-chip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The bigger slots show a roomier chip, matching their 52px thumbnails. */
#st-image-slot .mdz-pdf-chip,
.ld-image-item .mdz-pdf-chip { height: 32px; max-width: 220px; font-size: 12px; }
.mdz-thumb-delete {
  position: absolute;
  top: -6px; right: -6px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: #b91c1c;
  color: #fff;
  border: 1px solid #fff;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.mdz-thumb-delete:hover { background: #991b1b; }
/* Image lightbox — grows in from the center rather than just appearing,
   and sized to fill most of the screen so it's actually readable
   (a trip sheet photo needs to be legible, not thumbnail-sized). */
@keyframes lightbox-grow-in {
  from { transform: scale(0.85); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
.image-lightbox-overlay {
  background: rgba(11,18,32,0.8);
}
.image-lightbox-content {
  width: auto;
  max-width: 95vw;
  max-height: 95vh;
  animation: lightbox-grow-in 0.16s ease-out;
}
.image-lightbox-content img {
  display: block;
  max-width: 95vw;
  max-height: calc(95vh - 60px);
  object-fit: contain;
  border-radius: 6px;
}
.modal-header h3 { margin: 0; font-size: 15px; }
.modal-close { border: none; background: transparent; font-size: 18px; color: var(--slate-500); line-height: 1; }
.modal-body { padding: 18px 20px; }
.modal-footer {
  padding: 14px 20px;
  border-top: 1px solid var(--line);
  display: flex; justify-content: flex-end; gap: 8px;
}
.modal-large { width: 1040px; }
.modal-tabs {
  display: flex;
  gap: 2px;
  padding: 0 20px;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
.ld-tab {
  border: none;
  background: none;
  padding: 10px 14px;
  font-size: 12px;
  font-weight: 700;
  color: var(--slate-500);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.ld-tab:hover { color: var(--navy-950); }
.ld-tab.is-active { color: var(--navy-950); border-bottom-color: var(--navy-950); }
.col-routes { min-width: 150px; max-width: 220px; white-space: normal; }
.col-trip-actions { min-width: 130px; }
.trip-chip {
  display: inline-block;
  border: 1px solid var(--slate-500);
  background: var(--slate-100);
  color: var(--navy-950);
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  margin: 2px 3px 2px 0;
}
.trip-chip:hover { background: #fff; }
.trip-chip.trip-segment-done { background: rgba(34, 197, 94, 0.22); border-color: #15803d; color: #15803d; }
.trip-chip.trip-chip-undocumented { background: rgba(239, 68, 68, 0.18); border-color: #b91c1c; color: #b91c1c; font-weight: 700; }
.cell-with-link { display: flex; align-items: center; gap: 3px; }
.cell-with-link .cell-input { flex: 1; min-width: 0; }
.cell-link-btn {
  flex-shrink: 0;
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  font-size: 11px;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  line-height: 1;
}
.cell-link-btn:hover { background: var(--slate-100); }
.ld-history-row { display: grid; grid-template-columns: 130px 140px 1fr 1fr; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 12px; }
.ld-history-row-5col { grid-template-columns: 120px 90px 110px 1fr 1fr; }
.ld-history-row:first-child { font-weight: 700; color: var(--slate-500); font-size: 10.5px; text-transform: uppercase; }
/* Notes have no header row: the first note is styled exactly like the rest. */
.driver-note-row { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 12px; font-weight: 400; text-transform: none; }
.driver-note-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-bottom: 5px; color: var(--slate-500); font-size: 12px; font-weight: 400; }
.driver-note-text { color: var(--navy-950); font-weight: 400; white-space: pre-wrap; overflow-wrap: anywhere; }
.ld-history-old { color: var(--slate-500); text-decoration: line-through; }
.ld-history-new { color: var(--navy-950); font-weight: 600; }
.ld-image-gallery { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.ld-image-thumb { width: 120px; height: 120px; border-radius: var(--radius-sm); border: 1px solid var(--line); object-fit: cover; }
.ld-image-item { position: relative; }
.ld-image-remove {
  position: absolute; top: 4px; right: 4px;
  background: rgba(0,0,0,0.65); color: #fff; border: none;
  width: 20px; height: 20px; border-radius: 50%; font-size: 12px; line-height: 1;
}
.field label {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--slate-700);
  margin-bottom: 4px;
}
.field input[type="text"],
.field input[type="email"],
.field input[type="number"],
.field input[type="tel"],
.field textarea,
.field select {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 7px 9px;
  font-size: 13px;
  font-family: var(--font-ui);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--focus); box-shadow: 0 0 0 2px rgba(47,111,237,0.15);
}
.field textarea { resize: vertical; min-height: 54px; }
.radio-row { display: flex; gap: 16px; }
.radio-row label { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--navy-950); }
.inline-add-driver {
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--focus);
  background: none;
  border: none;
  font-weight: 700;
  padding: 0;
}
.inline-add-driver:hover { text-decoration: underline; }
.field-error { color: var(--red-600); font-size: 11px; margin-top: 3px; display: none; }
.field.has-error input, .field.has-error select { border-color: var(--red-600); }
.field.has-error .field-error { display: block; }
#available-section { margin-top: 12px; padding-bottom: 40px; }
#btn-night-shift { box-shadow: 0 2px 2px rgba(11,18,32,.18); }
#btn-night-shift[aria-pressed="true"] {
  color: #fff;
  background: #41464d;
  border-color: #30353b;
  box-shadow: inset 0 2px 4px rgba(0,0,0,.35);
  transform: translateY(1px);
}
.shift-start-date { display: inline-block; margin-right: 5px; font-size: 11px; font-variant-numeric: tabular-nums; }
.available-title { font-size: 16px; margin: 0 0 10px 0; }
/* Five rows, then scroll.
   The list is a working reference a dispatcher scans while on the phone, so it
   should not push the rest of the page down as it fills up. Capping the height
   keeps the page stable; the header stays put so the columns are still
   readable once you are scrolling. Fewer than five rows and the box simply
   shrinks to fit -- max-height, not height. */
.available-scroll {
  /* Measured against the real stylesheet rather than estimated: a row renders
     at 37px (12px padding + the 22px notes field + a 1px border, rounded up by
     the font metrics) and the header at 29px. Getting these wrong by 2px each
     is what showed four rows instead of five. */
  --avail-row-h: 37px;
  --avail-head-h: 29px;
  /* The box is border-box, so its 1px top and bottom borders come out of the
     same budget as the rows. Without the +2px a list of exactly five drivers
     overflows by two pixels and becomes scrollable when it should sit still. */
  max-height: calc(var(--avail-head-h) + (5 * var(--avail-row-h)) + 2px);
  /* Wide enough that the nine columns and the reserved scrollbar gutter all
     fit without a sideways scroll on a normal screen -- at 1280px the last
     column (the remove button) sat just past the edge. Narrower screens
     still get overflow-x below. */
  max-width: 1320px;
  overflow-y: auto;
  overflow-x: auto;
  /* Reserve the scrollbar's width whether or not it is showing. Without this
     every column shifts sideways the moment a fifth driver is added and the
     scrollbar appears -- a visible jolt in a list people add to all day. */
  scrollbar-gutter: stable;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
}
table.available-table {
  border-collapse: collapse;
  width: 100%;
  /* 900px could not fit nine columns, so the phone numbers wrapped onto a
     second line and every row grew to double height. */
  min-width: 1180px;
  font-family: var(--font-ui);
}
/* The header has to survive scrolling, and needs its own background or the
   rows show through it. */
table.available-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
}
/* Nothing in these columns should ever wrap: a phone number, an MC number or a
   dollar amount broken across two lines is harder to read and makes the row
   twice as tall for no gain. */
.available-table .col-cell,
.available-table .col-dispatcherPhone,
.available-table .col-mc,
.available-table .col-rating,
.available-table .col-availCarrierRate { white-space: nowrap; }
.available-table .col-cell,
.available-table .col-dispatcherPhone { min-width: 118px; }
.available-table .col-email { min-width: 210px; }
.available-table .col-mc { min-width: 84px; }
.available-table .col-rating { min-width: 86px; }
table.available-table thead th {
  background: var(--navy-950);
  color: #fff;
  text-align: left;
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
table.available-table td {
  border-bottom: 1px solid var(--line);
  padding: 6px 10px;
  font-size: 12.5px;
}
table.available-table tbody tr:nth-child(even) { background: #fbfcfe; }
.col-availText { width: 64px; min-width: 64px; text-align: center; }
.col-availDriver { min-width: 190px; }
.col-availCarrierRate { min-width: 104px; }
.col-availNotes { min-width: 240px; }
.col-availNotes textarea { display: block; box-sizing: border-box; width: 100%; min-height: 22px; line-height: 16px; resize: none; overflow: hidden; }
.col-availRemove { width: 32px; }
.available-remove-btn {
  border: none;
  background: none;
  color: var(--slate-500);
  font-size: 15px;
  line-height: 1;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
}
.available-remove-btn:hover { background: rgba(220, 38, 38, 0.1); color: var(--red-600, #dc2626); }
.tc-actions { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.tc-btn {
  border: 1px solid var(--slate-500);
  background: #fff;
  color: var(--navy-950);
  font-size: 9.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.tc-btn:hover:not(:disabled) { background: var(--slate-100); }
.tc-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.tc-btn-primary { background: var(--navy-900); border-color: var(--navy-700); color: #fff; }
.tc-btn-primary:hover:not(:disabled) { background: var(--navy-800); }
.ld-edit-bar { display: flex; justify-content: flex-end; gap: 8px; margin: 4px 0 14px 0; }
.ld-stop-row { display: flex; gap: 14px; font-size: 12px; padding: 4px 0; border-bottom: 1px solid var(--line); }
.ld-stop-edit-row { display: flex; gap: 8px; align-items: center; padding: 3px 0; }
.ld-stop-edit-row span { font-size: 11px; font-weight: 700; color: var(--slate-500); width: 48px; flex-shrink: 0; }
/* Time In / Time Out reuse .cell-input.small, which is 40px because that is
   what a board cell needs. In the Stop Times modal that clipped the value --
   "14:30" does not fit in 40px. There is room here, so take it. */
.ld-stop-edit-row .cell-input { width: 92px; min-width: 92px; text-align: center; }
.trip-add-btn {
  border: 1px dashed var(--slate-500);
  background: none;
  color: var(--navy-950);
  font-size: 16px;
  font-weight: 700;
  width: 34px;
  border-radius: var(--radius-sm);
  align-self: stretch;
}
.trip-add-btn:hover { background: var(--slate-100); border-style: solid; }
.col-rate { width: 62px; min-width: 62px; }
/* ============================================================
   Rate engine additions
   ============================================================ */
/* BIRM checkbox column on the board grid (Building C only in practice) */
.col-birm { width: 92px; min-width: 92px; }
.col-birm select.cell-input { font-size: 10.5px; padding: 3px 2px; }
/* Route ID / Trip ID need more room than the rest — widened by hand */
table.board td.col-routeId, table.board th.col-routeId,
table.board td.col-tripId, table.board th.col-tripId {
  width: 95px;
}
/* Narrower columns, per request — roughly half their previous auto width */
table.board td.col-trailerOut, table.board th.col-trailerOut,
table.board td.col-dispatchTime, table.board th.col-dispatchTime,
table.board td.col-lastStopDepart, table.board th.col-lastStopDepart,
table.board td.col-returnToDC, table.board th.col-returnToDC,
table.board td.col-salvageBhaulRefusedBy, table.board th.col-salvageBhaulRefusedBy,
table.board td.col-backhaulTrailerNumber, table.board th.col-backhaulTrailerNumber,
table.board td.col-returnEtaToDc, table.board th.col-returnEtaToDc {
  width: 55px;
}
/* Wider than the other short time-ish columns — this one sometimes shows
   "At DC since: HH:MM" instead of just a bare clock time. */
table.board td.col-nextCallTimeCalc, table.board th.col-nextCallTimeCalc {
  width: 128px;
}
/* Overview tab: existing fields on the left, Rate panel as a narrow
   column on the right, top-aligned so it starts level with PRO#. */
.ld-overview-grid {
  display: grid;
  grid-template-columns: 1fr 420px;
  gap: 24px;
  align-items: start;
}
.ld-overview-main { min-width: 0; }
.ld-overview-side { min-width: 0; }
/* Left-side fields, boxed the same way as the Rate section */
.field-box-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
fieldset.field-box {
  border: 2px solid var(--navy-950);
  border-radius: 12px;
  padding: 2px 12px 10px;
  margin: 0;
  min-width: 0;
}
fieldset.field-box legend {
  padding: 0 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--navy-950);
}
fieldset.field-box .static-text { font-size: 13.5px; }
/* Missing-field highlighting inside Load Details tabs */
fieldset.field-box.field-box-missing {
  border-color: #b91c1c;
  background: rgba(239, 68, 68, 0.06);
}
fieldset.field-box.field-box-missing legend { color: #b91c1c; }
/* Status banner at the top of a Load Details tab */
.ld-status-banner {
  padding: 8px 14px;
  border-radius: 8px;
  font-weight: 700;
  font-size: 13px;
  margin-bottom: 12px;
  text-align: center;
}
.ld-status-banner-green { background: rgba(34, 197, 94, 0.18); color: #15803d; }
.ld-status-banner-red { background: rgba(239, 68, 68, 0.14); color: #b91c1c; }
fieldset.field-box input.cell-input {
  border: 1px solid var(--line);
  padding: 6px 8px;
}
.ov-timesheet-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.ov-timesheet-row label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--slate-500);
  margin-bottom: 2px;
}
/* The big outer "Rate" box — a real <fieldset> so the title notches into
   the border on its own, matching the hand-drawn example */
fieldset.rate-section {
  border: 2px solid var(--navy-950);
  border-radius: 18px;
  padding: 4px 14px 14px;
  margin: 0;
  min-width: 0;
}
.rate-section-header {
  padding: 0 8px;
  font-size: 14px;
  font-weight: 800;
  color: var(--navy-950);
}
.rate-section-subheader {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--slate-500);
  margin-bottom: 6px;
}
/* Each individual tier/rate figure — its own small titled box, matching
   the "61-140MI / $400" boxes in the sketch. */
.rate-tier-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: 4px;
}
fieldset.rate-tier-box {
  border: 2px solid var(--navy-950);
  border-radius: 12px;
  padding: 2px 10px 7px;
  margin: 0;
  background: #fff;
  text-align: left;
  min-width: 0;
}
fieldset.rate-tier-box legend {
  padding: 0 6px;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--navy-950);
  white-space: normal;
}
fieldset.rate-tier-box input {
  width: 100%;
  border: none;
  background: transparent;
  text-align: left;
  font-size: 15px;
  font-weight: 800;
  color: var(--navy-950);
  padding: 2px 0;
}
fieldset.rate-tier-box input:focus {
  outline: none;
  background: var(--slate-100);
  border-radius: 6px;
}
/* Per-load override indicator — this figure differs from the location's
   normal default, scoped to just this one load */
fieldset.rate-tier-box.is-overridden {
  border-color: #b45309;
  background: var(--amber-bg);
}
.rate-override-dot {
  color: #b45309;
  font-size: 8px;
  vertical-align: middle;
}
.rate-total-box {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--slate-700);
  border-radius: var(--radius-md);
  background: var(--slate-100);
}
.rate-total-box label {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--slate-700);
  margin-bottom: 5px;
}
.rate-total-box input {
  width: 100%;
  border: 1px solid var(--slate-500);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: 16px;
  font-weight: 800;
  background: #fff;
}
.rate-total-box #ld-rate-reset {
  margin-top: 6px;
  font-size: 11.5px;
}
.rate-breakdown { margin-top: 14px; }
.rate-breakdown-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 0;
  border-bottom: 1px solid var(--slate-100);
  font-size: 12px;
}
.rate-breakdown-row span:first-child { font-weight: 700; }
.rate-breakdown-row span:last-child { font-weight: 700; }
.rate-breakdown-row:last-child { border-bottom: none; }
.rate-breakdown-total {
  font-weight: 800;
  border-top: 2px solid var(--slate-700);
  border-bottom: none;
  margin-top: 4px;
  padding-top: 8px;
}
/* Stack to one column on narrower viewports so the sidebar never gets crushed */
@media (max-width: 720px) {
  .ld-overview-grid { grid-template-columns: 1fr; }
}
/* ============================================================
   Mondelez board
   ============================================================ */
.col-mdz-location { min-width: 110px; }
.col-mdz-group { width: 55px; min-width: 55px; }
.col-mdz-driverapp { width: 110px; min-width: 110px; }
.col-mdz-driverapp .cell-input.small { width: 100%; }
.col-mdz-trailer { width: 80px; min-width: 80px; }
.col-mdz-miles { width: 56px; min-width: 56px; }
.col-mdz-stops { width: 46px; min-width: 46px; }
.col-mdz-carrierpay { width: 76px; min-width: 76px; }
.col-mdz-fsc { width: 56px; min-width: 56px; }
.col-mdz-additional { width: 70px; min-width: 70px; }
.col-mdz-revenue { width: 80px; min-width: 80px; }
.col-mdz-notes { min-width: 150px; }
.col-mdz-image { width: 90px; min-width: 90px; text-align: center; }
.col-routeImage { width: 90px; min-width: 90px; text-align: center; }
/* Mondelez needs a wider Text/Email button cell than the other boards —
   scoped to #mondelez-table specifically so this doesn't affect the
   shared .pin-text/.pin-pro/.pin-driver sizing used elsewhere. */
#mondelez-table .pin-text {
  width: 108px; min-width: 108px;
}
#mondelez-table td.pin-text {
  display: flex; align-items: center; justify-content: center; gap: 4px;
}
#mondelez-table .pin-pro { left: 182px; }
#mondelez-table .pin-mdz-mc { left: 274px; width: 84px; min-width: 84px; }
#mondelez-table .pin-driver { left: 358px; }
/* Add Time Slots modal */
.ats-slot-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ats-slot-row input[data-ats-time] { width: 80px; flex: none; }
.ats-slot-row input[data-ats-count] { width: 70px; flex: none; }
.ats-slot-row .ats-remove-btn {
  border: none; background: none; color: var(--slate-500); font-size: 16px; line-height: 1;
  width: 22px; height: 22px; border-radius: var(--radius-sm); flex: none;
}
.ats-slot-row .ats-remove-btn:hover { background: rgba(220, 38, 38, 0.1); color: var(--red-600); }

/* Mondelez grid/readability fixes */
#mondelez-table { table-layout: fixed; }
#mondelez-table .col-mdz-trailer { width: 118px; min-width: 118px; }
#mondelez-table td.col-mdz-trailer input { width: 100% !important; box-sizing: border-box; }
#mondelez-table .pin-text { width: 108px; min-width: 108px; white-space: nowrap; text-align: center; }
#mondelez-table td.pin-text { display: table-cell; vertical-align: middle; }
#mondelez-table td.pin-text .text-btn { display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; }
.mdz-image-dropzone { min-width: 90px; min-height: 30px; gap: 4px; flex-wrap: wrap; }
.mdz-lightbox-gallery { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.mdz-lightbox-gallery img { max-width: min(44vw, 420px); max-height: 70vh; object-fit: contain; }

.image-lightbox-overlay { z-index: 300; }

/* Mondelez route scans need a real viewing canvas, not natural-size thumbnails */
.mdz-image-lightbox-overlay .image-lightbox-content { width: min(92vw, 1200px); max-width: 92vw; }
.mdz-image-lightbox-overlay .image-lightbox-content .modal-body { min-height: min(70vh, 760px); display: flex; align-items: center; justify-content: center; }
.mdz-image-lightbox-overlay .image-lightbox-content img { width: min(86vw, 1080px); max-width: 86vw; max-height: 78vh; object-fit: contain; }

/* Full-screen original-image viewer. Thumbnails remain compact on the board,
   but every viewer loads the stored original and gives it a zoomable canvas. */
.image-lightbox-overlay {
  z-index: 300;
  padding: 0;
}
.image-viewer-modal {
  width: 100vw;
  max-width: none;
  height: 100vh;
  max-height: none;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.image-viewer-header {
  flex: 0 0 auto;
  gap: 12px;
}
.image-viewer-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
}
.image-viewer-toolbar .btn {
  min-width: 34px;
  padding: 4px 9px;
  line-height: 1.2;
}
.image-viewer-toolbar .modal-close {
  margin-left: 4px;
}
.image-viewer-zoom-level {
  min-width: 48px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  color: var(--slate-500);
}
.image-viewer-stage {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: #111827;
  touch-action: none;
  cursor: grab;
}
.image-viewer-stage.is-dragging {
  cursor: grabbing;
}
.image-viewer-stage > img {
  display: block;
  width: min(94vw, 1400px);
  max-width: 100%;
  max-height: 100%;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
  user-select: none;
}
.image-viewer-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  overflow: visible;
  transform-origin: center center;
}
.image-viewer-gallery img {
  max-width: min(44vw, 700px);
  max-height: 78vh;
  object-fit: contain;
  background: #fff;
  cursor: pointer;
}
.image-viewer-gallery img.is-selected-image {
  outline: 4px solid #2563eb;
  outline-offset: 4px;
  border-radius: 4px;
}
.image-viewer-footer {
  flex: 0 0 auto;
}

/* The skipped / shared-number / DNU notes used to stack above the send buttons
   and push them off the bottom of a long batch. They fold into one summary
   that starts closed -- worth keeping, since who was skipped and why is what
   gets asked afterwards, but not worth the height every time. */
.text-modal-details { margin-top: 8px; }
.text-modal-details > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--slate-100);
  color: var(--slate-500);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .03em;
  user-select: none;
}
.text-modal-details > summary::-webkit-details-marker { display: none; }
.text-modal-details > summary::before { content: "\25B8"; font-size: 10px; }
.text-modal-details[open] > summary::before { content: "\25BE"; }
.text-modal-details > summary:hover { border-color: var(--slate-500); }
.text-modal-details > .calc-note { margin-top: 6px; }

/* Accounting row marks stay visible across all sheet layouts. */
#accounting-table-body tr.acct-highlighted > td { background-color: #fff2b3; }
.acct-load-reference { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
#accounting-table .acct-load-text {
  border: 1px solid transparent;
  background: transparent;
  font-family: var(--font-ui);
  font-size: 11.5px;
  padding: 2px 3px;
  border-radius: var(--radius-sm);
  color: var(--navy-950);
  user-select: text;
  cursor: text;
  min-width: 2ch;
  display: inline-block;
}
#accounting-table .acct-load-text:hover { border-color: var(--line); }
#accounting-table .acct-load-text:focus {
  outline: none;
  border-color: var(--focus);
  background: #fff;
  box-shadow: 0 0 0 2px rgba(47,111,237,0.15);
}
#accounting-table .cell-input:hover,
#accounting-table .acct-load-text:hover { border-color: var(--line); }
#accounting-table .cell-input:focus,
#accounting-table .acct-load-text:focus {
  outline: none;
  border-color: var(--focus);
  background: #fff;
  box-shadow: 0 0 0 2px rgba(47,111,237,0.15);
}
.acct-load-text:empty::before { content: "—"; color: var(--slate-500); }

.acct-note-button { border: 0; background: transparent; padding: 2px 4px; color: white; cursor: pointer; vertical-align: middle; }
.acct-note-button.has-notes { color: #facc15; }
.acct-note-button svg { display: block; }

/* Enclose each week's daily rows AND its recap in one black box. */
:is(#la-table, #vol-table) .analytics-week-row > td:first-child { border-left: 3px solid #000; }
:is(#la-table, #vol-table) .analytics-week-row > td:last-child { border-right: 3px solid #000; }
:is(#la-table, #vol-table) .analytics-week-start > td { border-top: 3px solid #000; }
:is(#la-table, #vol-table) .analytics-week-end > td { border-bottom: 3px solid #000; }

/* DNU assignments require an explicit acknowledgment on every board. */
.dnu-assignment-dialog {
  width: min(420px, calc(100vw - 40px));
  box-sizing: border-box;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
  color: var(--navy-950);
  font-family: var(--font-ui);
}
.dnu-assignment-dialog::backdrop { background: rgba(0, 0, 0, 0.5); }
.dnu-assignment-dialog h3 {
  margin: 0 0 12px;
  color: #b91c1c;
  font-size: 28px;
  font-weight: 800;
}
.dnu-assignment-dialog p { margin: 0 0 20px; line-height: 1.5; }
.dnu-assignment-dialog .btn { white-space: normal; }

.dnu-assignment-notes-link {
  display: block;
  margin-bottom: 20px;
  color: #1d4ed8;
  font-weight: 600;
  text-decoration: underline;
}

.rate-rating-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 8px; }
.rate-rating-toggle { border: 2px solid var(--line); font-weight: 700; }
.rate-rating-toggle[aria-pressed="true"] { background: var(--focus); color: #fff; border-color: var(--focus); }
.rate-rating-toggle[aria-pressed="false"] { background: #fff; color: var(--navy-950); border-color: var(--slate-500); }
.rate-rating-toggle:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
/* A rating nobody at the chosen rates holds. Kept on screen so the panel does
   not change height as rates are picked -- see renderRateTextRatings(). */
.rate-rating-toggle.is-unavailable,
.rate-rating-toggle.is-unavailable[aria-pressed="false"] {
  opacity: 0.35;
  cursor: default;
  background: #fff;
  color: var(--slate-500);
  border-color: var(--line);
}
.rating-selection-mark { display: inline-block; width: 1em; font-weight: 900; }

.group-text-mode-tabs { margin-bottom: 16px; padding-left: 0; padding-right: 0; }

.shared-driver-rate-source { margin-bottom: 12px; }

/* Driver selection finishes editing while retaining a spreadsheet cell focus. */
td[data-driver-cell-selected]:focus {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.houston-sort-btn { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* ---------------- Invoice week picker ----------------
   An invoice covers one Monday-Sunday week, so the calendar's unit of
   selection is a WEEK ROW, never a day. Each row is its own element and the
   highlight is :hover on that row -- pure CSS, so the whole week lights up on
   the same frame the pointer enters it, with no mousemove handler to lag or
   to leave a stale row highlighted when the pointer exits the grid quickly.
   Days are spans inside the row, not buttons: nothing inside is separately
   clickable, which is what makes a part-week impossible to express. */
.inv-cal { border: 1px solid var(--line); border-radius: var(--radius-sm, 6px); overflow: hidden; }
.inv-cal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px; background: var(--slate-100, #f1f5f9);
  border-bottom: 1px solid var(--line); font-weight: 700; font-size: 13px;
}
.inv-cal-nav {
  border: 1px solid var(--line); background: #fff; border-radius: 4px;
  width: 24px; height: 24px; line-height: 1; cursor: pointer; font-size: 15px;
}
.inv-cal-nav:hover { background: var(--slate-100, #f1f5f9); }
.inv-cal-dow, .inv-cal-week { display: grid; grid-template-columns: repeat(7, 1fr); }
.inv-cal-dow {
  padding: 4px 0; background: var(--slate-100, #f1f5f9);
  border-bottom: 1px solid var(--line);
}
.inv-cal-dow span { text-align: center; font-size: 10px; font-weight: 700; color: var(--slate-500, #64748b); }
.inv-cal-week { cursor: pointer; border-bottom: 1px solid var(--line); }
.inv-cal-week:last-child { border-bottom: none; }
.inv-cal-week span { text-align: center; padding: 6px 0; font-size: 12px; }
.inv-cal-week .inv-cal-other { color: var(--slate-400, #94a3b8); }
.inv-cal-week:hover { background: var(--brand-50, #eff6ff); }
.inv-cal-week.is-selected { background: var(--brand, #175cd3); }
.inv-cal-week.is-selected span, .inv-cal-week.is-selected .inv-cal-other { color: #fff; font-weight: 700; }
.inv-cal-week.is-disabled { cursor: not-allowed; }
.inv-cal-week.is-disabled span { color: var(--slate-300, #cbd5e1); }
.inv-cal-week.is-disabled:hover { background: transparent; }
.inv-cal-week:focus-visible { outline: 2px solid var(--brand, #175cd3); outline-offset: -2px; }
.inv-week-label { margin-top: 8px; font-weight: 700; font-size: 13px; }
.inv-pro { font-size: 15px; font-weight: 700; letter-spacing: 0.3px; min-height: 20px; }
