/* ═══════════════════════════════════════════════════════════
   MERCURY PERMITS PORTAL — app.css
   ═══════════════════════════════════════════════════════════ */

/* ── Variables ──────────────────────────────────────────── */
:root {
  --bg-base:     #f0f4f7;
  --bg-sidebar:  #323a45;
  --bg-surface:  #ffffff;
  --bg-elevated: #f8fafc;
  --bg-hover:    #edf1f5;
  --bg-input:    #ffffff;

  --border:       rgba(0, 0, 0, 0.10);
  /* Form-field focus/active border. Deliberately a neutral slate — NOT the
     orange accent (too close to the danger red) and not any status color, so a
     focused/editable field reads as "active" without signalling a state. */
  --border-focus: #475569;
  --focus-ring:   rgba(71, 85, 105, 0.22);  /* neutral glow companion to --border-focus */

  --accent:       #f05922;
  --accent-dim:   rgba(240, 89, 34, 0.15);
  --accent-hover: #d24a17;

  --text-primary:   #2d3748;
  --text-secondary: #4a5568;
  --text-muted:     #a0aec0;

  --success:     #2f9e6a;
  --success-bg:  rgba(47, 158, 106, 0.10);
  --warning:     #c07c10;
  --warning-bg:  rgba(192, 124, 16, 0.10);
  --danger:      #c53030;
  --danger-bg:   rgba(197, 48, 48, 0.10);
  --info:        #2b6cb0;
  --info-bg:     rgba(43, 108, 176, 0.10);

  --sidebar-w:           242px;
  --sidebar-w-collapsed: 64px;
  --topbar-h:            54px;

  --r-sm: 5px;
  --r:    8px;
  --r-lg: 12px;

  --shadow:    0 2px 12px rgba(0, 0, 0, 0.10);
  --shadow-lg: 0 6px 32px rgba(0, 0, 0, 0.16);

  --font:      'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
  --transition: 140ms ease;
}

/* ── Sidebar scoped overrides (stays dark) ──────────────── */
#sidebar {
  --text-primary:   #e2e8f0;
  --text-secondary: #a0aec0;
  --text-muted:     #718096;
  --border:         rgba(255, 255, 255, 0.08);
  --bg-hover:       rgba(255, 255, 255, 0.07);
  --accent-dim:     rgba(240, 89, 34, 0.18);
}

/* ── Reset ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { height: 100%; }
body {
  height: 100%;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-primary);
  background: var(--bg-base);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }
input, select, textarea { font-family: inherit; }
svg { flex-shrink: 0; }

/* ── Login Screen ───────────────────────────────────────── */
#login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 0%, #fde4d8 0%, var(--bg-base) 65%);
}

.login-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  pointer-events: none;
}
.login-glow-1 {
  width: 500px; height: 500px;
  background: rgba(240, 89, 34, 0.12);
  top: -120px; left: -100px;
}
.login-glow-2 {
  width: 400px; height: 400px;
  background: rgba(240, 89, 34, 0.07);
  bottom: -80px; right: -80px;
}

.login-card {
  position: relative;
  z-index: 1;
  width: 380px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 40px 36px;
  box-shadow: var(--shadow-lg);
}

.login-logo {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 32px;
}
.login-title {
  display: block;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text-primary);
}
.login-subtitle {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 1px;
  letter-spacing: 0.4px;
}

.login-alt-link {
  text-align: center;
  margin-top: 14px;
  font-size: 13px;
}
.login-alt-link a {
  color: var(--accent);
  text-decoration: none;
}
.login-alt-link a:hover { text-decoration: underline; }

/* ── App Shell ──────────────────────────────────────────── */
#app {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* ── Sidebar ────────────────────────────────────────────── */
#sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  transition: width var(--transition);
}

/* ── Collapsed icon-only rail ───────────────────────────── */
#sidebar.collapsed { width: var(--sidebar-w-collapsed); }
#sidebar.collapsed .brand-chip { display: none; }
#sidebar.collapsed .sidebar-nav { padding: 12px 8px; }
#sidebar.collapsed .nav-link { justify-content: center; padding: 9px; gap: 0; }
#sidebar.collapsed .nav-label { display: none; }
#sidebar.collapsed .sidebar-footer { justify-content: center; }
#sidebar.collapsed #version-footer,
#sidebar.collapsed #auth-badge,
#sidebar.collapsed #logout-btn .btn-label { display: none; }
#sidebar.collapsed #logout-btn { justify-content: center; width: auto; padding: 8px; }

/* Toggle button in the topbar */
#sidebar-toggle svg { display: block; }

.sidebar-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px 14px;
  border-bottom: 1px solid var(--border);
}
/* The logo PNG has a baked-in white background; the chip turns that into an
   intentional rounded badge on the dark sidebar (overflow clips the corners). */
.brand-chip {
  display: inline-flex;
  background: #fff;
  padding: 5px 10px;
  border-radius: var(--r);
  overflow: hidden;
}

.sidebar-nav {
  flex: 1;
  padding: 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  font-size: 13.5px;
  font-weight: 500;
  transition: background var(--transition), color var(--transition);
}
.nav-link:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.nav-link.active {
  background: var(--accent-dim);
  color: var(--accent-hover);
}
.nav-link svg { opacity: 0.8; }
.nav-link.active svg { opacity: 1; }

/* ── Nav groups (one level) ─────────────────────────────
   .sidebar-nav's `gap: 2px` only applies to ITS OWN children, so both the
   <details> wrapper and the child list have to re-establish the column layout
   or the rows inside a group close up against each other. */
.nav-group,
.nav-group-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Rotating caret, same idiom as the order page's collapsible Route block. */
.nav-group > summary { list-style: none; cursor: pointer; user-select: none; }
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group-summary::after {
  content: '▸';
  margin-left: auto;
  font-size: 10px;
  color: var(--text-muted);
  transition: transform 0.12s ease;
}
.nav-group[open] > .nav-group-summary::after { transform: rotate(90deg); }
/* A group holding the current page stays marked while collapsed. */
.nav-group-summary.has-active { color: var(--text-primary); }
/* Line child labels up under the parent's: 10px base + 16px icon + 10px gap. */
.nav-group-items .nav-link { padding-left: 36px; }

/* Collapsed 64px rail: no room for a caret or an indent, so groups flatten —
   the heading disappears and its children render as ordinary rail icons.
   MUST come after the indent rule above; #sidebar.collapsed .nav-link sets the
   `padding` shorthand and would otherwise lose to a later padding-left. */
#sidebar.collapsed .nav-group > summary { display: none; }
#sidebar.collapsed .nav-group-items .nav-link { padding: 9px; justify-content: center; gap: 0; }

.sidebar-footer {
  padding: 14px 12px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.version-footer {
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-muted);
  opacity: 0.75;
}
.version-footer .vf-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  /* reset button chrome — this reads as a text line, not a button */
  appearance: none;
  background: none;
  border: 0;
  padding: 1px 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: 4px;
  transition: color .12s, background-color .12s;
}
.version-footer .vf-row:hover,
.version-footer .vf-row:focus-visible {
  color: var(--text);
  background: var(--surface-2, rgba(127, 127, 127, .12));
  outline: none;
}
.version-footer .vf-row:hover .vf-ver { text-decoration: underline; }
.version-footer .vf-date { font-variant-numeric: tabular-nums; }

/* Changelog modal body */
.changelog {
  max-height: 62vh;
  overflow-y: auto;
  padding-right: 6px;
}
.changelog .changelog-status { color: var(--text-muted); padding: 12px 2px; }
.changelog .cl-ver {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin: 18px 0 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border, rgba(127, 127, 127, .2));
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.changelog .cl-ver:first-child { margin-top: 2px; }
.changelog .cl-date {
  font-size: 12px;
  font-weight: 400;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.changelog .cl-desc {
  margin: 4px 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
}
.changelog .cl-desc code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--surface-2, rgba(127, 127, 127, .14));
}
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
  font-size: 13px;
  overflow: hidden;
  min-width: 0;
}
.sidebar-user #user-display-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.btn-icon-bare {
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  flex-shrink: 0;
  border-radius: 4px;
}
.btn-icon-bare:hover {
  color: var(--text);
  background: var(--surface-hover);
}

/* ── Main area ──────────────────────────────────────────── */
#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

#topbar {
  height: var(--topbar-h);
  flex-shrink: 0;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.breadcrumb {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}
/* Two-segment breadcrumb — used only by the order page, where the first crumb is the
   way back to the order list (there is no other in-page exit). */
.crumb-link { color: var(--text-secondary); }
.crumb-link:hover { color: var(--accent); text-decoration: underline; }
.crumb-sep { color: var(--text-muted); font-weight: 400; margin: 0 7px; }

.topbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

#content {
  flex: 1;
  overflow-y: auto;
  /* Exposed as a custom property because the sticky order banner has to cancel the
     top padding out to pin flush against the pane (see .ws-banner). */
  --pane-pad: 28px;
  padding: var(--pane-pad) var(--pane-pad);
}

/* ── Buttons ────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  transition: background var(--transition), color var(--transition), opacity var(--transition);
  white-space: nowrap;
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); }

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
.btn-ghost:hover:not(:disabled) {
  background: var(--bg-elevated);
  color: var(--text-primary);
}

.btn-danger {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid rgba(248, 113, 113, 0.25);
}
.btn-danger:hover:not(:disabled) {
  background: rgba(248, 113, 113, 0.22);
}

.btn-sm   { padding: 5px 11px; font-size: 12px; }
.btn-full { width: 100%; justify-content: center; padding: 11px 16px; }
.btn-icon { padding: 7px; border-radius: var(--r-sm); }

/* ── Forms ──────────────────────────────────────────────── */
.form-group { margin-bottom: 16px; }
.form-group:last-of-type { margin-bottom: 0; }

.form-label {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 6px;
  letter-spacing: 0.2px;
}

.form-input,
.form-select {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-primary);
  padding: 9px 12px;
  font-size: 13.5px;
  transition: border-color var(--transition);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.form-input:focus,
.form-select:focus {
  border-color: var(--border-focus);
}
.form-input::placeholder { color: var(--text-muted); }

/* Weight fields carry no up/down spinner arrows — the value is normalized on
   blur (e.g. "80k" → 80000), so the browser stepper adds nothing. Targeted by
   field, NOT a blanket input[type=number], so intentional steppers (tire count
   step=2, axle count, year, fees) keep their arrows. */
#f-weight::-webkit-inner-spin-button,
#f-weight::-webkit-outer-spin-button,
input[data-field="axle_weight_lbs"]::-webkit-inner-spin-button,
input[data-field="axle_weight_lbs"]::-webkit-outer-spin-button,
input[data-field="weight"]::-webkit-inner-spin-button,
input[data-field="weight"]::-webkit-outer-spin-button,
input[data-field="load_weight"]::-webkit-inner-spin-button,
input[data-field="load_weight"]::-webkit-outer-spin-button,
input[data-field="overall_weight"]::-webkit-inner-spin-button,
input[data-field="overall_weight"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
#f-weight,
input[data-field="axle_weight_lbs"],
input[data-field="weight"],
input[data-field="load_weight"],
input[data-field="overall_weight"] {
  -moz-appearance: textfield;
}

.form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a9bb8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
}
.form-select option { background: var(--bg-surface); }

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.form-error {
  font-size: 12.5px;
  color: var(--danger);
  padding: 8px 12px;
  background: var(--danger-bg);
  border-radius: var(--r-sm);
  margin-bottom: 14px;
  border: 1px solid rgba(248,113,113,0.2);
}

/* ── Cards ──────────────────────────────────────────────── */
.card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 20px 22px;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  gap: 12px;
}

.card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}

/* ── Stats Grid ─────────────────────────────────────────── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.stat-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px 20px;
}
.stat-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  margin-bottom: 8px;
}
.stat-value {
  font-size: 28px;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
}
.stat-sub {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 5px;
}

/* ── Health Info ────────────────────────────────────────── */
.health-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}
.health-item {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.health-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.health-dot.ok       { background: var(--success); box-shadow: 0 0 8px var(--success); }
.health-dot.degraded { background: var(--warning); box-shadow: 0 0 8px var(--warning); }
.health-dot.down     { background: var(--danger);  box-shadow: 0 0 8px var(--danger); }
.health-dot.disabled { background: var(--text-muted); }

.health-label { font-size: 12px; color: var(--text-secondary); }
.health-value { font-size: 13px; font-weight: 600; color: var(--text-primary); margin-top: 1px; }

/* ── System monitors (status page) ──────────────────────── */
.spark { display: block; width: 100%; height: 28px; margin-top: 8px; color: var(--accent); opacity: .85; }
.spark polyline {
  stroke: currentColor; stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke;   /* preserveAspectRatio=none must not distort the stroke */
}
.spark polyline.spark-muted { stroke: var(--text-muted); stroke-width: 1.5; }
.stat-value.sv-sm { font-size: 19px; line-height: 1.2; }
.stat-value.stat-warn   { color: var(--warning); }
.stat-value.stat-danger { color: var(--danger); }

/* ── Tables ─────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }

table {
  width: 100%;
  border-collapse: collapse;
}

thead th {
  padding: 10px 14px;
  text-align: left;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.th-sort {
  cursor: pointer;
  user-select: none;
}
.th-sort:hover { color: var(--text-secondary); }
.th-sort-active { color: var(--accent); }

tbody tr {
  border-bottom: 1px solid var(--border);
  transition: background var(--transition);
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--bg-hover); }

tbody td {
  padding: 12px 14px;
  font-size: 13.5px;
  color: var(--text-primary);
  vertical-align: middle;
}

.td-muted { color: var(--text-secondary); }
/* A confirmed selection (e.g. the chosen carrier/contact/job in the New Order
   modal) — bold + accented so it stands out from the muted helper text. */
.no-picked { font-weight: 700; color: var(--success); }
/* Clears the selection it sits beside. Small and red so it reads as a remove
   action without competing with the selection text itself. */
.no-clear {
  background: none;
  border: none;
  padding: 0 2px;
  margin-left: 6px;
  cursor: pointer;
  color: var(--danger);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  vertical-align: baseline;
}
.no-clear:hover { color: #fff; background: var(--danger); border-radius: 3px; }
.td-mono  { font-family: var(--font-mono); font-size: 12.5px; }
.td-payload-btn {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
  text-align: left;
}
.td-payload-btn:hover { color: var(--accent); text-decoration: underline; }
.td-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}

/* ── Badges ─────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 99px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
}
.badge-active     { background: var(--success-bg); color: var(--success); }
.badge-inactive   { background: var(--bg-elevated); color: var(--text-muted); }
.badge-suspended  { background: var(--danger-bg); color: var(--danger); }
.badge-user       { background: var(--info-bg); color: var(--info); }
.badge-admin      { background: var(--accent-dim); color: var(--accent-hover); }
.badge-supervisor { background: var(--warning-bg); color: var(--warning); }
.badge-default    { background: var(--bg-elevated); color: var(--text-secondary); }
.badge-ok         { background: var(--success-bg); color: var(--success); }
.badge-degraded   { background: var(--warning-bg); color: var(--warning); }
.badge-down       { background: var(--danger-bg); color: var(--danger); }
/* Submitted-but-unassigned order — attention-getting, and distinct from every
   other status hue (not the amber "warning" or red "danger"). Solid violet. */
.badge-unassigned { background: #7c3aed; color: #fff; }
/* Marks a permit row that is an amendment of a previously issued permit. */
.badge-amendment  { background: var(--warning-bg); color: var(--warning); }

/* Marks a permit row that is a route authorization (reuses the amendment
   notation layout: .permit-amend-note / .permit-amend-desc). */
.badge-route-auth { background: var(--info-bg, var(--bg-elevated)); color: var(--info, var(--text)); }

/* Amendment notation stacked under the permit-type cell. */
.permit-amend-note { margin-top: 4px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.permit-amend-desc { margin-top: 3px; }
.permit-amend-desc .ec-input { width: 100%; font-size: 12px; }

/* Amendment picker modal */
.amend-picker-controls { display: flex; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.amend-picker-controls #amend-desc { flex: 1 1 260px; }
.amend-picker-controls #amend-num-search { flex: 0 1 260px; }
.amend-row:hover { background: var(--bg-elevated); }

/* ── Notification recipient chips ───────────────────────── */
.notif-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px 3px 10px;
  background: var(--accent-dim);
  color: var(--accent-hover);
  border-radius: 99px;
  font-size: 12px;
  font-weight: 500;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.notif-chip-remove {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0;
  opacity: 0.6;
  flex-shrink: 0;
}
.notif-chip-remove:hover { opacity: 1; }

/* ── Pagination ─────────────────────────────────────────── */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 16px;
  gap: 12px;
}
.pagination-info {
  font-size: 12.5px;
  color: var(--text-muted);
}
.pagination-btns {
  display: flex;
  align-items: center;
  gap: 6px;
}
.page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  transition: background var(--transition), color var(--transition);
}
.page-btn:hover:not(:disabled) {
  background: var(--bg-elevated);
  color: var(--text-primary);
}
.page-btn.active {
  background: var(--accent-dim);
  color: var(--accent-hover);
  border-color: var(--border-focus);
}
.page-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* ── Toolbar (above table) ──────────────────────────────── */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 12px;
  flex-wrap: wrap;
}
.toolbar-left  { display: flex; align-items: center; gap: 10px; }
.toolbar-right { display: flex; align-items: center; gap: 10px; }

.filter-select {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  padding: 6px 28px 6px 10px;
  font-size: 13px;
  outline: none;
  transition: border-color var(--transition);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a9bb8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  -webkit-appearance: none;
  appearance: none;
}
.filter-select:focus { border-color: var(--border-focus); }
.filter-select option { background: var(--bg-surface); }

/* File Management record type-ahead (upload + browse). Compact text input that
   matches the toolbar filters (no select arrow) plus an absolute results list. */
.fm-ta-input {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  padding: 6px 10px;
  font-size: 13px;
  outline: none;
  transition: border-color var(--transition);
}
.fm-ta-input:focus { border-color: var(--border-focus); }
.fm-ta-input:disabled { opacity: 0.5; cursor: not-allowed; }
.fm-ta-dd {
  display: none;
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  min-width: 100%;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  z-index: 200;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.fm-ta-opt {
  padding: 6px 10px;
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fm-ta-opt:hover { background: var(--bg-hover); }

/* Two-line carrier rows in type-ahead dropdowns: name on top, a muted
   DOT · City, ST line beneath (carriers often share names — this disambiguates). */
.ta-opt-carrier { padding: 6px 10px; cursor: pointer; line-height: 1.3; }
.ta-opt-carrier:hover { background: var(--bg-hover); }
.ta-opt-name { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ta-opt-sub  { font-size: 11.5px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Empty state ────────────────────────────────────────── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 56px 24px;
  color: var(--text-muted);
  gap: 10px;
  text-align: center;
}
.empty-state svg { opacity: 0.35; }
.empty-state p { font-size: 13.5px; }

/* ── Spinner / Loading ──────────────────────────────────── */
.spinner {
  display: inline-block;
  width: 20px; height: 20px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.spinner-lg {
  width: 32px; height: 32px;
  border-width: 3px;
}
/* Inline with a line of status text (upload/scan progress). */
.spinner-sm {
  width: 12px; height: 12px;
  border-width: 2px;
  vertical-align: -1px;
  margin-right: 4px;
}
@keyframes spin { to { transform: rotate(360deg); } }

.loading-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px;
}

/* ── Modal ──────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 8, 18, 0.80);
  backdrop-filter: blur(3px);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.modal-box {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-lg);
  animation: modal-in 0.18s ease;
}
.modal-box.modal-wide { max-width: 1100px; }
@keyframes modal-in {
  from { opacity: 0; transform: scale(0.96) translateY(-8px); }
  to   { opacity: 1; transform: scale(1)    translateY(0);    }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}
.modal-close-btn {
  color: var(--text-muted);
  padding: 4px;
  border-radius: var(--r-sm);
  display: flex;
  transition: color var(--transition);
}
.modal-close-btn:hover { color: var(--text-primary); }

.modal-body {
  padding: 20px 22px;
  overflow-y: auto;
  flex: 1;
}

.modal-footer {
  padding: 14px 22px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-shrink: 0;
}

/* ── Confirm box ────────────────────────────────────────── */
.confirm-box {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 32px 28px;
  width: 100%;
  max-width: 360px;
  text-align: center;
  box-shadow: var(--shadow-lg);
  animation: modal-in 0.18s ease;
}
.confirm-icon {
  display: flex;
  justify-content: center;
  margin-bottom: 14px;
  color: var(--danger);
}
.confirm-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 8px;
}
.confirm-message {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin-bottom: 24px;
  line-height: 1.6;
}
/* Optional checkbox row in the confirm dialog (confirm(..., {checkbox})) */
.confirm-checkbox-row {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 13px; cursor: pointer; margin: -12px 0 20px;
}
/* "TEMP" chip beside a plate that's a temporary tag (display-only) */
.temp-chip {
  display: inline-block; padding: 0 5px; border-radius: 4px;
  background: var(--warning-bg, #fef3c7); color: var(--warning, #b45309);
  border: 1px solid var(--warning, #b45309);
  font-size: 10px; font-weight: 700; letter-spacing: 0.5px; vertical-align: middle;
}
/* "KIT" chip beside a glider/kit vehicle's VIN (display-only) */
.kit-chip {
  display: inline-block; padding: 0 5px; border-radius: 4px;
  background: var(--info-bg, #e0e7ff); color: var(--info, #4338ca);
  border: 1px solid var(--info, #4338ca);
  font-size: 10px; font-weight: 700; letter-spacing: 0.5px; vertical-align: middle;
}
.confirm-actions {
  display: flex;
  justify-content: center;
  gap: 10px;
}

/* ── Toasts ─────────────────────────────────────────────── */
#toasts {
  position: fixed;
  bottom: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 200;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: var(--r);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 13.5px;
  color: var(--text-primary);
  min-width: 260px;
  max-width: 380px;
  pointer-events: all;
  animation: toast-in 0.25s ease;
}
.toast.toast-out { animation: toast-out 0.22s ease forwards; }

@keyframes toast-in  {
  from { opacity: 0; transform: translateX(30px); }
  to   { opacity: 1; transform: translateX(0);    }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(30px); }
}

.toast-icon { flex-shrink: 0; }
.toast-msg { flex: 1; min-width: 0; }
.toast-clickable { cursor: pointer; }
.toast-clickable:hover { border-color: var(--info); }
/* Inline action button on a sticky toast (e.g. Acknowledge). */
.toast-btn {
  flex-shrink: 0; cursor: pointer; white-space: nowrap;
  padding: 4px 10px; border-radius: 6px; font: inherit; font-size: 12px; font-weight: 600;
  color: #fff; background: var(--accent); border: none;
}
.toast-btn:hover { filter: brightness(1.06); }
.toast-success .toast-icon { color: var(--success); }
.toast-error   .toast-icon { color: var(--danger); }
.toast-info    .toast-icon { color: var(--info); }
.toast-warning .toast-icon { color: var(--warning); }

/* ── Back to top ────────────────────────────────────────────
   Fixed, translucent jump-to-top affordance for the order page. It shares the
   bottom-right corner with the toast stack, so it sits one layer below the
   toasts (200) and is pushed up by --toast-stack-h — kept in sync with the live
   stack height by setupScrollTopBtn — instead of being buried under them. */
.scroll-top-btn {
  position: fixed;
  right: 20px;
  bottom: calc(20px + var(--toast-stack-h, 0px));
  z-index: 190;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.7);
  background: color-mix(in srgb, var(--bg-surface) 70%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--text-secondary);
  box-shadow: var(--shadow);
  /* Hidden by default — visibility (not display) so the show/hide animates, and
     so it never eats clicks aimed at whatever is underneath while hidden. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity var(--transition), transform var(--transition),
              visibility var(--transition), color var(--transition),
              border-color var(--transition), bottom 200ms ease;
}
.scroll-top-btn.visible { opacity: 0.75; visibility: visible; transform: translateY(0); }
.scroll-top-btn.visible:hover { opacity: 1; color: var(--text-primary); border-color: var(--accent); }

/* ── Helpers ────────────────────────────────────────────── */
.hidden { display: none !important; }
.text-right { text-align: right; }
.text-muted { color: var(--text-secondary); }
.mt-4 { margin-top: 16px; }

/* ── Section page header ────────────────────────────────── */
.page-header {
  margin-bottom: 22px;
}
.page-header h1 {
  font-size: 20px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.3px;
}
.page-header p {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin-top: 4px;
}

/* ── Dashboard stat card links ─────────────────────────── */
.stat-card-link {
  display: block;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.stat-card-link:hover {
  background: var(--bg-hover);
  border-color: var(--border-focus);
  transform: translateY(-1px);
}

/* ── Section header (title + action) ───────────────────── */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.section-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  margin: 0;
}

/* ── Card-wrapped table ─────────────────────────────────── */
.card-table {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  margin-bottom: 24px;
}
.card-table table { border-collapse: collapse; }
.card-table thead th { border-bottom: 1px solid var(--border); }
.card-table tbody tr:last-child td { border-bottom: none; }

/* ── Dashboard quick-links ──────────────────────────────── */
.quick-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
  margin-top: 24px;
}
.quick-link {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px 20px;
  display: flex;
  align-items: center;
  gap: 14px;
  transition: background var(--transition), border-color var(--transition);
  cursor: pointer;
}
.quick-link:hover {
  background: var(--bg-hover);
  border-color: var(--border-focus);
}
.quick-link-icon {
  width: 38px; height: 38px;
  border-radius: var(--r);
  background: var(--accent-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-hover);
  flex-shrink: 0;
}
.quick-link-label {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.quick-link-sub {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ── Assignment Panel ───────────────────────────────────── */
.assign-section { margin-bottom: 22px; }
.assign-section:last-child { margin-bottom: 0; }
.assign-section-title {
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.assign-list {
  border: 1px solid var(--border);
  border-radius: var(--r);
  overflow: hidden;
  margin-bottom: 10px;
}
.assign-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  gap: 10px;
}
.assign-item:last-child { border-bottom: none; }
.assign-item-name { font-size: 13px; color: var(--text-primary); flex: 1; }
.assign-item-meta { font-size: 11.5px; color: var(--text-muted); white-space: nowrap; }
.assign-empty {
  padding: 14px;
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
  font-style: italic;
  border: 1px solid var(--border);
  border-radius: var(--r);
  margin-bottom: 10px;
}
.assign-add-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.assign-add-row .form-select {
  flex: 1;
  padding: 7px 28px 7px 10px;
  font-size: 13px;
}
.assign-readonly-note {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  margin-top: 6px;
}

/* ── Requirement Field Builder ──────────────────────────── */
.requirements-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}
.requirement-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}
.requirement-row-fields {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.requirement-row-fields .form-row { gap: 8px; }
.requirement-required-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-secondary);
}

/* ── FMCSA SAFER Lookup ─────────────────────────────────── */
.fmcsa-lookup-box {
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  margin-bottom: 16px;
}
.fmcsa-lookup-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.fmcsa-lookup-or {
  font-size: 12px;
  color: var(--text-muted);
}
.fmcsa-snapshot {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.fmcsa-snapshot-header {
  font-size: 14px;
  margin-bottom: 8px;
}
.fmcsa-snapshot-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 16px;
}
.fmcsa-snapshot-field {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 12.5px;
}
.fmcsa-snapshot-label {
  font-size: 11px;
  color: var(--text-muted);
}
.fmcsa-snapshot-field.fmcsa-diff {
  background: var(--warning-bg);
  border-radius: 4px;
  padding: 3px 6px;
  margin: -3px -6px;
}
strong.fmcsa-diff, span.fmcsa-diff {
  background: var(--warning-bg);
  border-radius: 3px;
  padding: 0 4px;
}
.fmcsa-diff-legend {
  display: flex;
  align-items: center;
  gap: 6px;
}
.fmcsa-diff-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--warning-bg);
  border: 1px solid var(--warning);
}

/* ── Permit discrepancy modal (permit-vs-order audit) ─────── */
.pd-h { margin: 14px 0 6px; }
.pd-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.pd-table th, .pd-table td { text-align: left; padding: 5px 10px; border-bottom: 1px solid var(--border); }
.pd-table th { font-size: 11px; color: var(--text-muted); font-weight: 600; }
.pd-flag {
  background: var(--warning-bg);
  border-radius: 4px;
}
.pd-note { font-size: 12.5px; color: var(--text-muted); margin: 8px 0; }
/* Wrong issuing state = almost certainly the wrong FILE — solid-red banner at
   the top of the discrepancy modal (static cousin of .purge-warn). */
.pd-state-warn {
  background: var(--danger); color: #fff; text-align: center;
  font-size: 14.5px; font-weight: 600;
  border-radius: 8px; padding: 12px 10px; margin: 0 0 12px;
}
.pd-state-warn strong { font-weight: 800; letter-spacing: 0.5px; }
.pd-state-warn-sub { font-size: 12.5px; color: rgba(255, 255, 255, 0.85); }

/* ── Roles & Permissions Matrix ──────────────────────────── */
.pm-card { padding: 0; overflow-x: auto; }

.pm-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.pm-table thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border);
  padding: 10px 12px;
  font-weight: 600;
  white-space: nowrap;
}
.pm-label-col {
  text-align: left;
  min-width: 190px;
  position: sticky;
  left: 0;
  z-index: 10 !important;
  background: var(--bg-elevated);
  border-right: 1px solid var(--border);
}
.pm-role-col {
  text-align: center;
  min-width: 110px;
}
.pm-add-col { min-width: 48px; }
.pm-role-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-hover);
}
.pm-role-desc {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 1px;
}
.pm-role-btns {
  display: flex;
  justify-content: center;
  gap: 4px;
  margin-top: 6px;
}
.pm-btn {
  padding: 3px 6px;
  font-size: 11px;
  gap: 3px;
}

.pm-group-row .pm-group-label {
  background: var(--bg-hover);
  padding: 6px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  position: sticky;
  left: 0;
}

.pm-perm-row td {
  border-bottom: 1px solid var(--border);
  padding: 0;
}
.pm-perm-row:hover td { background: var(--bg-hover); }
.pm-action {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
  padding: 6px 12px 6px 20px;
  position: sticky;
  left: 0;
  background: inherit;
  border-right: 1px solid var(--border);
  white-space: nowrap;
}
.pm-cell {
  text-align: center;
  padding: 6px 4px;
}
.pm-cb {
  width: 15px;
  height: 15px;
  cursor: pointer;
  accent-color: var(--accent);
}
.pm-cb:disabled { opacity: 0.4; cursor: wait; }

/* ── Routing / map planner ──────────────────────────────── */
.route-editor {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 16px;
  /* Stretch so the map card tracks the form column's height (the details panel
     grew taller than the old fixed map height once the vehicle-dims fields
     landed). The embedded planner already worked this way. */
  align-items: stretch;
  /* Trap the Leaflet map's internal z-indexes (panes ~400, controls ~1000) in
     their own stacking context so they can't paint over a body-level modal
     backdrop (z 100) on the standalone Plan Route page. The embedded planner
     gets the same via .order-route-planner; fullscreen adopts the modal inside
     and bumps it to z 2000 instead. */
  isolation: isolate;
}
@media (max-width: 900px) {
  .route-editor { grid-template-columns: 1fr; }
}
.route-form { padding: 16px; }
.geo-field { position: relative; }
.geo-dd {
  display: none;
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  z-index: 1000;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.geo-opt {
  padding: 7px 10px;
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.geo-opt:hover { background: var(--bg-hover); }
.geo-msg {
  padding: 8px 10px;
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.4;
}
/* Saved-place suggestion row (name + pin + scope chip), shown above geocode hits. */
.geo-opt.place-opt {
  display: flex;
  align-items: center;
  gap: 6px;
}
.geo-opt.place-opt svg { flex: 0 0 auto; color: var(--accent); }
.geo-opt.place-opt .place-opt-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Origin/Destination field + save-to-place icon button. */
.geo-field-row { display: flex; align-items: flex-start; gap: 6px; }
.geo-field-row .geo-field { flex: 1 1 auto; }
.save-place-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  align-self: stretch;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
.save-place-btn:hover { border-color: var(--accent); color: var(--accent-hover); }
/* Visibility scope chips (Places + Routes pages + suggestions). */
.vis-badge,
.place-vis-badge {
  flex: 0 0 auto;
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: capitalize;
  border: 1px solid transparent;
}
.vis-badge.vis-public,   .place-vis-badge.vis-public   { background: rgba(16, 185, 129, 0.14); color: #059669; border-color: rgba(16, 185, 129, 0.35); }
.vis-badge.vis-internal, .place-vis-badge.vis-internal { background: rgba(59, 130, 246, 0.14); color: #2563eb; border-color: rgba(59, 130, 246, 0.35); }
.vis-badge.vis-private,  .place-vis-badge.vis-private  { background: rgba(107, 114, 128, 0.14); color: #4b5563; border-color: rgba(107, 114, 128, 0.35); }
.route-map-card { padding: 0; overflow: hidden; }
.route-map {
  width: 100%;
  /* Fill the (stretched) grid cell; the min keeps a usable map when the form
     column is short. Fullscreen and embedded selectors below override. */
  height: 100%;
  min-height: 560px;
  background: var(--bg-input);
}
/* Embedded planner (inside the Order screen's Route group) — a shorter map so
   it sits comfortably among the other order groups. */
/* Trap the embedded Leaflet map's internal z-indexes (panes ~400, controls ~1000)
   in their own stacking context so they can't paint over modals (backdrop z 100). */
.order-route-planner { width: 100%; isolation: isolate; }
.route-editor-embedded { grid-template-columns: 300px 1fr; align-items: stretch; }
/* Map fills its (stretched) grid cell so its height tracks the form beside it. */
.route-editor-embedded .route-map { height: 100%; min-height: 280px; }
/* Full-screened planner (browser Fullscreen API via the map's ⛶ control).
   Fullscreen elements default to a black backdrop — paint the app background,
   let the form column scroll, and give the map the full viewport height. */
.route-editor:fullscreen { background: var(--bg-base); padding: 14px; overflow: auto; }
/* A modal/confirm overlay is moved into the fullscreen planner (JS) so it shares
   the top layer — bump it above Leaflet's panes (~400) and controls (~1000),
   which otherwise paint over the backdrop's default z-index (100). */
.route-editor:fullscreen .modal-backdrop { z-index: 2000; }
.route-editor:fullscreen .route-map,
.route-editor-embedded:fullscreen .route-map { height: calc(100vh - 28px); min-height: 0; }
#rt-fullscreen { display: flex; align-items: center; justify-content: center; }
/* Click-to-open layer panel (custom control replacing Leaflet's hover-expand
   layers control — scales to many layers and supports groups). */
.layer-ctl { position: relative; }
#rt-layers-btn { display: flex; align-items: center; justify-content: center; }
.layer-panel {
  position: absolute; top: 0; right: 34px; width: 190px;
  max-height: 300px; overflow-y: auto;
  background: var(--bg-surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15); padding: 6px 0 8px;
}
.layer-panel-title {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--text-muted); padding: 8px 12px 3px;
}
.layer-row {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 12px; font-size: 12.5px; cursor: pointer; white-space: nowrap;
}
.layer-row:hover { background: var(--bg-hover); }
.layer-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  flex: 0 0 auto;
}
/* Collapsible sub-list inside a layer group (e.g. per-state restrictions). */
.layer-subhead {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 12px; font-size: 12.5px; font-weight: 600;
  cursor: pointer; white-space: nowrap; user-select: none;
}
.layer-subhead:hover { background: var(--bg-hover); }
.layer-caret { width: 10px; flex: 0 0 auto; font-size: 10px; color: var(--text-muted); }
#rt-states-list .layer-row { padding-left: 28px; }
.layer-count { margin-left: auto; font-size: 10.5px; color: var(--text-muted); }
/* What a restriction line's shape means — solid vs dashed vs straight. */
.layer-legend { padding: 5px 12px 1px; margin-top: 3px; border-top: 1px solid var(--border); }
.layer-legend-row {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; color: var(--text-muted); padding: 2px 0; white-space: nowrap;
}
.layer-legend-row svg { flex: 0 0 auto; }
#rt-fullscreen.active { color: var(--accent); }
@media (max-width: 900px) {
  .route-editor-embedded { grid-template-columns: 1fr; }
}
.route-summary {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13px;
}
.route-stat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.route-stat-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}
.route-stat-val { font-weight: 600; color: var(--text-primary); }
.route-actions {
  margin-top: 16px;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
/* Embedded (order screen) — the form column is narrow, so let the actions wrap:
   the save-status message gets its own full-width line above the buttons. */
.route-actions-embedded { flex-wrap: wrap; align-items: center; }
.route-actions-embedded .rt-save-status {
  flex: 1 1 100%; text-align: right; font-size: 12px; line-height: 1.3;
}
.route-actions-embedded .rt-save-status:empty { display: none; }
.route-actions-embedded .btn { white-space: nowrap; }
.state-chips { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.state-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 600;
  font-family: var(--font-mono);
  background: var(--accent-dim);
  color: var(--accent-hover);
  border: 1px solid var(--border);
}
/* Leaflet waypoint markers (divIcon — no image assets needed) */
.wp-marker {
  background: var(--accent);
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
}
.leaflet-tooltip.wp-tip {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  font-size: 11px;
  font-weight: 500;
  padding: 1px 6px;
}
.leaflet-tooltip.wp-tip::before { display: none; }
.wp-marker.wp-marker-hi {
  background: var(--accent-hover, var(--accent));
  box-shadow: 0 0 0 4px var(--accent-dim), 0 1px 5px rgba(0, 0, 0, 0.5);
}
/* Restriction the route passes THROUGH because the detour computation failed
   (enforcement_failed) — an unmissable pulsing red pin. */
.rr-viol-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #dc2626;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
  animation: rr-viol-pulse 1.6s ease-out infinite;
  cursor: pointer;
}
@keyframes rr-viol-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.55), 0 1px 5px rgba(0, 0, 0, 0.5); }
  70%  { box-shadow: 0 0 0 12px rgba(220, 38, 38, 0), 0 1px 5px rgba(0, 0, 0, 0.5); }
  100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0), 0 1px 5px rgba(0, 0, 0, 0.5); }
}
.route-map.insert-mode { cursor: crosshair; }

/* Floating "find a location" search box on the route map */
/* position + z-index so the results dropdown paints above the sibling zoom control */
.rt-find-control { width: 240px; max-width: 60vw; position: relative; z-index: 1001; }
.rt-find-control input {
  width: 100%;
  padding: 7px 10px;
  font-size: 13px;
  color: var(--text-primary);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.rt-find-control input:focus { outline: none; border-color: var(--border-focus); }
/* Distinct find pin (teardrop dot) — visually different from the blue waypoint dots */
.find-marker {
  background: #f59e0b;
  border: 2px solid #fff;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
  cursor: pointer;
}

/* Measure tool (vendored Leaflet.PolylineMeasure) — its stylesheet ships light-mode
   defaults (yellow Arial tooltips, a bright green active button) and is appended to
   <head> after this file, so these overrides are scoped through .leaflet-container
   to out-specify it rather than relying on source order. */
.leaflet-container .polyline-measure-tooltip {
  font: 500 11px/1.25 var(--font);
  background-color: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow);
  padding: 2px 6px;
}
.leaflet-container .polyline-measure-tooltip-end { background-color: var(--bg-elevated); }
.leaflet-container .polyline-measure-tooltip-total { color: var(--text-primary); font-weight: 700; }
/* Per-leg delta — the accent keeps it distinct from the bold running total. */
.leaflet-container .polyline-measure-tooltip-difference { color: var(--accent); font-style: normal; }
.leaflet-container .polyline-measure-popupTooltip { font: 11px/1.3 var(--font); }
/* Active state mirrors the fullscreen control's .active treatment. */
.leaflet-container a.polyline-measure-controlOnBgColor,
.leaflet-container a.polyline-measure-controlOnBgColor:hover {
  background-color: var(--accent);
  color: #fff;
}
/* Center the inline SVGs in both measure buttons, like #rt-fullscreen. */
#polyline-measure-control,
.leaflet-bar.measuring a.polyline-measure-clearControl {
  display: flex; align-items: center; justify-content: center;
}
/* "Clear measurements" is only offered while the tool is on (class toggled from
   the plugin's polylinemeasure:toggle event). */
.leaflet-bar:not(.measuring) a.polyline-measure-clearControl { display: none; }

/* Editor tabs (Details / Waypoints) */
.route-tabs {
  display: flex;
  gap: 4px;
  margin: -4px 0 14px;
  border-bottom: 1px solid var(--border);
}
.route-tab {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
}
.route-tab:hover { color: var(--text-primary); }
.route-tab.active {
  color: var(--text-primary);
  border-bottom-color: var(--accent);
}
.route-tab-panel[hidden] { display: none; }

/* Waypoints tab */
.wp-toolbar { margin-bottom: 8px; }
#rt-insert-toggle.active {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent-hover);
}
.wp-hint {
  margin: 0 0 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}
.wp-list { display: flex; flex-direction: column; gap: 4px; }
.wp-empty { font-size: 13px; color: var(--text-muted); margin: 4px 0; }
.wp-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elevated);
}
.wp-row:hover { border-color: var(--accent); }
.wp-row-label {
  flex: 0 0 auto;
  min-width: 40px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent-hover);
}
.wp-row-coords {
  flex: 1 1 auto;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
}
.wp-row-actions { flex: 0 0 auto; display: flex; gap: 2px; }
.wp-mustpass { flex: 0 0 auto; display: inline-flex; align-items: center; cursor: pointer; }
.wp-mustpass input { margin: 0; cursor: pointer; }
.wp-btn {
  appearance: none;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: 12px;
  line-height: 1;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg-input);
  color: var(--text-primary);
  cursor: pointer;
}
.wp-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-hover); }
.wp-btn:disabled { opacity: 0.35; cursor: default; }
.wp-btn-del:hover:not(:disabled) { border-color: var(--danger); color: var(--danger); }

/* Directions tab */
.route-stat-via {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
  text-align: right;
}
.dir-empty { font-size: 13px; color: var(--text-muted); margin: 4px 0; }
.hwy-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.hwy-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  font-family: var(--font-mono);
  background: var(--accent-dim);
  color: var(--accent-hover);
  border: 1px solid var(--border);
}
.hwy-arrow { color: var(--text-muted); font-size: 11px; }
.dir-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: dir;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dir-step {
  counter-increment: dir;
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 8px 7px 30px;
  position: relative;
  font-size: 13px;
  border-radius: 6px;
}
.dir-step::before {
  content: counter(dir);
  position: absolute;
  left: 8px;
  top: 7px;
  font-size: 10px;
  font-weight: 700;
  font-family: var(--font-mono);
  color: var(--text-muted);
}
.dir-step:nth-child(odd) { background: var(--bg-elevated); }
.dir-step-text { flex: 1 1 auto; color: var(--text-primary); line-height: 1.4; }
.dir-step-dist {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ── Maintenance mode card (dashboard, API-key sessions only) ── */
.maint-card {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 18px 20px;
  margin-bottom: 24px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
  border-radius: 10px;
}
.maint-card.maint-on {
  background: var(--warning-bg);
  border-color: rgba(251, 191, 36, 0.35);
  border-left-color: var(--warning);
}
.maint-info { flex: 1 1 auto; min-width: 0; }
.maint-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}
.maint-card.maint-on .maint-title { color: var(--warning); }
.maint-desc {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.45;
}
.maint-state {
  margin-top: 6px;
  font-size: 12px;
  color: var(--text-muted);
}
.maint-card.maint-on .maint-state { color: var(--warning); }

/* ── Login maintenance notice ───────────────────────────── */
.login-maint {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 14px 16px;
  margin-bottom: 20px;
  background: var(--warning-bg);
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-radius: 10px;
  color: var(--warning);
}
.login-maint svg { flex: 0 0 auto; margin-top: 1px; }
/* Session-timeout variant — informational blue, so it never reads as the
   amber "the system is down" notice above it. */
.login-maint.login-timeout {
  background: var(--info-bg);
  border-color: rgba(43, 108, 176, 0.35);
  color: var(--info);
}
.login-maint-title { font-size: 14px; font-weight: 600; }
.login-maint-text {
  margin-top: 3px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-secondary);
}

/* ── Toggle switch ──────────────────────────────────────── */
.switch { flex: 0 0 auto; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  display: block;
  width: 46px;
  height: 26px;
  border-radius: 13px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  transition: background 0.18s ease, border-color 0.18s ease;
}
.switch-thumb {
  display: block;
  width: 20px;
  height: 20px;
  margin: 2px;
  border-radius: 50%;
  background: var(--text-secondary);
  transition: transform 0.18s ease, background 0.18s ease;
}
.switch input:checked + .switch-track {
  background: var(--warning);
  border-color: var(--warning);
}
.switch input:checked + .switch-track .switch-thumb {
  transform: translateX(20px);
  background: #1a1205;
}
.switch input:focus-visible + .switch-track { border-color: var(--border-focus); }
.switch input:disabled + .switch-track { opacity: 0.5; cursor: progress; }

/* ── File management ─────────────────────────────────────── */
.card-section-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 14px;
}
.fm-upload-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.fm-upload-grid .form-group { margin-bottom: 0; }
.fm-queue { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.fm-queue-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  padding: 4px 8px;
  background: var(--bg-elevated);
  border-radius: var(--r-sm);
}

/* Drag-and-drop zone (page + in-form) */
.dropzone {
  margin-top: 12px;
  padding: 22px 16px;
  border: 1.5px dashed var(--border);
  border-radius: var(--r-sm);
  text-align: center;
  font-size: 13px;
  color: var(--text-secondary);
  background: var(--bg-input);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone.dropzone-sm { padding: 14px 12px; margin-top: 8px; font-size: 12.5px; }
.dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-dim);
  color: var(--text-primary);
}
/* An upload is in flight — drops are ignored, so don't invite one. */
.dropzone.dropzone-busy {
  opacity: 0.55;
  cursor: progress;
  border-style: solid;
  background: var(--bg-elevated);
}
.dropzone.dropzone-busy.dragover {
  border-color: var(--border);
  background: var(--bg-elevated);
  color: var(--text-secondary);
}

/* In-form Files section */
.rec-files {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.rec-files-title { font-size: 13px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; }
.rec-files-list { display: flex; flex-direction: column; gap: 4px; }
.rec-file-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  padding: 5px 8px;
  background: var(--bg-elevated);
  border-radius: var(--r-sm);
}
.rec-file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rec-file-meta { flex-shrink: 0; font-size: 11.5px; }

/* A displayed file name that doubles as a download link. */
.file-dl-link { color: var(--accent-hover); cursor: pointer; text-decoration: none; }
.file-dl-link:hover, .file-dl-link:focus-visible { text-decoration: underline; }
.rec-files-upload { margin-top: 10px; }
.rf-agencies-list { display: flex; flex-wrap: wrap; gap: 4px 14px; max-height: 132px; overflow-y: auto; padding: 2px 0; }
.rf-agency-opt { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text-primary); cursor: pointer; }
.rf-agency-opt input { margin: 0; }

/* ══ Orders — dashboard table + working screen ══ */

/* Vehicles grid: the Unit cell doubles as a link to the vehicle's own record. */
.veh-unit-link { color: var(--accent-hover); cursor: pointer; }
.veh-unit-link:hover, .veh-unit-link:focus-visible { text-decoration: underline; }

tr.col-filters th { padding: 4px 8px 8px; background: var(--bg-elevated); }
.col-filter {
  width: 100%; box-sizing: border-box; padding: 4px 7px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--bg-input); color: var(--text-primary);
}
.col-filter:focus { outline: none; border-color: var(--border-focus); }
/* Per-field clear. The ✕ is absolutely positioned rather than the cell being
   made a flex container: that leaves the input's width:100% box model exactly
   as it was, so no column anywhere in the 14 filterable tables changes width.
   padding-right on the input keeps long values from running under the glyph.
   Scoped to .col-filter-th (not `tr.col-filters th`) so the bare <th></th>
   cells — Annuals' unfilterable columns, and the select/delete columns on
   Orders and Order Templates — are untouched. */
.col-filter-th { position: relative; }
/* Only reserve room for the ✕ once there IS one, so an empty filter row is
   pixel-identical to before and narrow columns don't lose usable width. The
   accent tint marks a filter that's narrowing the list — filters survive
   navigation and can be pre-seeded by dashboard drill-downs, so an active one
   isn't necessarily one the user just typed. Background only: the invalid-state
   red border must stay the sole claimant of border-color. */
.col-filter:not(:placeholder-shown) { padding-right: 19px; background: var(--accent-dim); }
.col-filter-x {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; padding: 0 1px;
  color: var(--text-muted); font-size: 10px; line-height: 1;
}
.col-filter-x:hover { color: var(--text-primary); }
/* Shown only when the field has something to clear — so an empty filter row
   looks exactly as it did before, and the ✕ marks which columns are filtering.
   Pure CSS, so it toggles as you type rather than on the debounced re-render;
   pointer-events:none lets a click on a hidden one fall through to the input. */
.col-filter:placeholder-shown + .col-filter-x { opacity: 0; pointer-events: none; }
tr.order-row { cursor: pointer; }
tr.order-row:hover td { background: var(--bg-hover); }

/* Active-order banner — the wrong-carrier guard. Sticky at the top of the scrolling
   content pane so the carrier stays in view down a long order; it collapses to a
   single carrier + load line while pinned (see .ws-banner.collapsed below). z-index
   30 clears page content — modals (100/150) and toasts (200) still cover it, and the
   route planner's Leaflet z-indexes are trapped by its own `isolation: isolate`. */
.ws-banner {
  position: sticky; z-index: 30;
  /* Negative by exactly #content's top padding: with top:0 the banner pins to the
     pane's CONTENT box, i.e. 28px down, leaving a strip above it for content to
     scroll through. Cancelling the padding pins it flush with the top of the pane. */
  top: calc(-1 * var(--pane-pad, 0px));
  border: 1px solid; border-radius: 10px; padding: 14px 18px; margin-bottom: 12px;
  color: #fff;
}
/* Order page for a filled/invoiced/complete order: wash the whole content area
   a bright red so it's immediately obvious the order is done and needs no more
   work. Translucent so it reads in either theme; the white content cards stay
   light and pop against it. Toggled on #content by drawOrderWork and cleared in
   navigate(). */
#content.ord-billed { background-color: rgba(239, 51, 51, 0.30); }
.ws-banner-carrier { font-size: 22px; font-weight: 700; letter-spacing: 0.3px; margin-top: 6px; }
/* Unit # of the order's first vehicle, trailing the carrier name. Inherits the
   carrier line's size so it scales with the collapsed banner too (22px → 16px);
   lighter weight keeps the carrier name dominant, and nowrap stops it breaking
   across "- Unit#" and the number. */
.ws-banner-unit { font-weight: 400; opacity: 0.9; white-space: nowrap; }
/* Carrier trade name, its own line under the legal name. Filled in by the async
   carrier lookup in wireOrderWork (the order object carries no DBA), so it starts
   empty — :empty keeps it from contributing a line, and its margin, until then.
   Deliberately NOT a .ws-banner-meta row: it survives into the collapsed bar,
   where it sits inline beside the carrier name (see .collapsed below). */
.ws-banner-dba {
  margin-top: 2px; font-size: 14px; font-weight: 600; letter-spacing: 0.2px;
  color: rgba(255, 255, 255, 0.85);
}
.ws-banner-dba:empty { display: none; }
/* "Download PDF" pill in the banner's upper-right corner. */
.ws-banner-pdf {
  position: absolute; top: 12px; right: 14px;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 11px; border-radius: 6px; cursor: pointer;
  background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.4);
  color: #fff; font-size: 12.5px; font-weight: 600; letter-spacing: 0.2px;
  transition: background var(--transition, 140ms ease);
}
.ws-banner-pdf:hover { background: rgba(255, 255, 255, 0.28); }
.ws-banner-pdf:disabled { opacity: 0.6; cursor: default; }
/* Third-party billing flag — small, non-bold, inline right after the carrier
   name (a subtle billing cue against the dark banner). */
.ws-banner-billto {
  margin-left: 10px; font-size: 13px; font-weight: 400; letter-spacing: normal;
  color: #ffdada; opacity: 0.85;
}
/* Red DRAFT strip between the carrier banner and the action buttons */
.draft-banner {
  background: var(--danger); color: #fff; text-align: center;
  font-weight: 700; letter-spacing: 4px; font-size: 14px;
  border-radius: 8px; padding: 6px 0; margin-bottom: 12px;
}
/* Carrier-on-hold strip, directly under .draft-banner. Amber rather than red:
   the draft is fine and expected — only submitting is blocked — so this must
   not read as loudly as DRAFT itself. Sentence-cased with normal tracking
   because it carries a full explanation, not a single word. */
.hold-banner {
  background: var(--warning-bg); color: var(--warning);
  border: 1px solid var(--warning); text-align: center;
  font-size: 12.5px; line-height: 1.5;
  border-radius: 8px; padding: 7px 12px; margin-bottom: 12px;
}
.hold-banner strong { font-weight: 700; letter-spacing: 1px; margin-right: 6px; }
/* Purge-issued-permit severe confirmation (second modal of the two-step
   flow). Solid red on purpose — nothing else in the app looks like this,
   which is the point: the user is destroying an issued, paid-for permit. */
.purge-warn {
  background: var(--danger); color: #fff; text-align: center;
  font-weight: 800; letter-spacing: 2px; font-size: 15px;
  border-radius: 8px; padding: 12px 8px; margin-bottom: 14px;
  animation: purge-pulse 1.2s ease-in-out infinite alternate;
}
@keyframes purge-pulse {
  from { box-shadow: 0 0 0 0 rgba(197, 48, 48, 0.55); }
  to   { box-shadow: 0 0 0 8px rgba(197, 48, 48, 0); }
}
.purge-facts { margin-bottom: 10px; }
.btn-danger-solid, .btn-danger-solid.btn-primary {
  background: var(--danger); color: #fff;
  border: 1px solid var(--danger);
}
.btn-danger-solid:hover:not(:disabled) { background: #a52626; }
.ws-banner-meta {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  margin-top: 6px; font-size: 13.5px; color: rgba(255, 255, 255, 0.92);
}
.ws-banner-meta .td-muted { color: rgba(255, 255, 255, 0.65); }
/* Customer PO — click-to-reveal, sits just right of the order number. Reads as
   plain banner text; only swaps to an input once its display is clicked. */
.ws-banner-po { display: inline-flex; align-items: center; }
.ws-banner-po-display {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; letter-spacing: inherit;
}
.ws-banner-po-display:hover {
  text-decoration: underline dotted; text-underline-offset: 3px;
}
.ws-banner-po-display.is-empty { color: rgba(255, 255, 255, 0.5); }
.ws-banner-po .ec-input { display: none; width: 120px; }
.ws-banner-po.editing .ec-input { display: inline-block; }
.ws-banner-po.editing .ws-banner-po-display { display: none; }
/* Load description + overall dims/weight — the emphasized bottom line. */
.ws-banner-load {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin-top: 8px; font-size: 17px; font-weight: 700; letter-spacing: 0.2px;
}
/* Copy buttons sit on the dark banner — override the light-theme muted color. */
.ws-banner .copy-btn { color: rgba(255, 255, 255, 0.7); }
.ws-banner .copy-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.15); }
.ws-banner .copy-btn.copied { color: #4ade80; }

/* ── Collapse-on-scroll ──────────────────────────────────────
   The banner above is sticky at the top of the scrolling content pane. The sentinel
   sits just above it: once the sentinel scrolls out of the pane the banner has
   reached the pin point, and drawOrderWork's IntersectionObserver adds .collapsed —
   shrinking it to one carrier + load line. The spacer is then given exactly the
   height the banner gave up, so content below it never shifts. Both are zero-height
   at rest; the banner's own width tracks the content pane, so it follows sidebar
   collapse. */
.ws-banner-sentinel { height: 0; }
/* overflow-anchor: none so the browser never picks the spacer itself as its scroll
   anchor — it's the one node that deliberately changes height, and anchoring to it
   would fight the compensation it exists to provide. */
.ws-banner-spacer { height: 0; overflow-anchor: none; }
/* NB: margin-bottom stays 12px here. The spacer's height is derived from the
   banner's offsetHeight delta, which excludes margins — changing the margin between
   the two states would leave the spacer short by that difference and jump the page. */
.ws-banner.collapsed {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px;
  padding: 9px 18px;
  border-top: 0; border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.28);
}
/* Collapsed shows carrier + load only — the order-number/PO/agent, address,
   DOT/Tax-ID and contact rows hide along with the PDF pill. */
.ws-banner.collapsed .ws-banner-meta,
.ws-banner.collapsed .ws-banner-pdf { display: none; }
.ws-banner.collapsed .ws-banner-carrier { font-size: 16px; margin-top: 0; }
/* The DBA stays, as a flex item just right of the carrier name. Smaller than the
   16px name, so it doesn't grow the collapsed bar past the height probed at render
   time (before the async DBA lands) — which is what the spacer is sized against. */
.ws-banner.collapsed .ws-banner-dba { font-size: 13px; margin-top: 0; font-weight: 500; }
.ws-banner.collapsed .ws-banner-load {
  margin-top: 0; margin-left: auto; font-size: 14px; gap: 4px 12px;
}
.ws-banner.collapsed .ws-banner-load .td-mono {
  font-weight: 400; color: rgba(255, 255, 255, 0.85);
}

.ws-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
/* Receive-permit shortcut strip — a distinct accent callout so it doesn't read
   as more of the neutral action buttons above it. */
.ws-receive-strip {
  margin-top: 2px;
  align-items: center;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: var(--bg-elevated);
  border-radius: var(--r-sm);
}
.ws-receive-label { font-size: 12px; font-weight: 700; color: var(--accent-hover); margin-right: 2px; }
/* Accent chips — clearly different from the ghost buttons in the top strip. */
.ws-receive-strip .btn {
  background: var(--accent-dim);
  color: var(--accent-hover);
  border: 1px solid var(--accent);
  font-weight: 600;
}
.ws-receive-strip .btn:hover:not(:disabled) { background: var(--accent); color: #fff; }

/* Summary groups */
.ord-groups {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
}
.ord-group {
  background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px;
}
.ord-group-title {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.6px; color: var(--text-muted); margin-bottom: 8px;
}
/* Collapsible group (Route block) — reuses .ord-group styling with a clickable
   summary. The <details> marker is replaced by a rotating chevron. */
.ord-collapsible > summary { list-style: none; }
.ord-collapsible > summary::-webkit-details-marker { display: none; }
.ord-collapsible-summary {
  cursor: pointer; user-select: none; display: flex; align-items: center; gap: 6px;
  margin-bottom: 0;
}
.ord-collapsible[open] > .ord-collapsible-summary { margin-bottom: 8px; }
.ord-collapsible-summary::before {
  content: '▸'; font-size: 10px; color: var(--text-muted);
  transition: transform 0.12s ease;
}
.ord-collapsible[open] > .ord-collapsible-summary::before { transform: rotate(90deg); }
.ord-collapsible-summary:hover { color: var(--text-secondary); }
/* Copy-to-clipboard buttons next to VIN / plate / load fields. */
.copy-cell { display: inline-flex; align-items: center; gap: 3px; min-width: 0; }
.copy-cell .veh-input { flex: 1 1 auto; min-width: 0; }
.copy-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; padding: 2px; margin-right: 3px; border: none; background: none;
  color: var(--text-muted); border-radius: 4px; cursor: pointer; line-height: 0;
  vertical-align: middle;
}
.copy-btn:hover { color: var(--text-primary); background: var(--bg-hover); }
.copy-btn.copied { color: var(--success, #16a34a); }

/* Axle spacing profile diagram (side view, circles = tires) under the grid. */
.ord-axle-diagram { margin-top: 10px; color: var(--text-primary); }
.ord-axle-diagram:empty { display: none; }
.ord-axle-diagram svg { display: block; width: 100%; max-width: 50%; height: auto; max-height: 90px; margin: 0 auto; }
.ord-field {
  display: flex; align-items: baseline; gap: 10px; padding: 4px 0;
  font-size: 13.5px; border-bottom: 1px dashed var(--border);
}
.ord-field:last-child { border-bottom: none; }
.ord-field-label { flex: 0 0 130px; color: var(--text-muted); font-size: 12.5px; }
.req-dot { color: var(--warning); font-size: 9px; margin-left: 4px; vertical-align: super; cursor: help; }
.ord-flags { display: flex; flex-wrap: wrap; gap: 10px; }
.ord-flag { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; cursor: pointer; }
/* Arrangement flag that needs 2+ pieces — greyed, not hidden, so the option is
   still discoverable and an already-set flag stays visible. */
.ord-flag-off { color: var(--text-muted); cursor: not-allowed; }
.ord-flag-off input { cursor: not-allowed; }
/* Route planner "Round Trip": a checked round trip has to be impossible to
   miss while an agent fills the order, so it flips to a solid blue chip
   (--info is the palette's only blue; --accent is orange). */
.rt-roundtrip { padding: 3px 8px; border-radius: var(--r-sm); border: 1px solid var(--border); transition: var(--transition); }
.rt-roundtrip.is-on { background: var(--info); border-color: var(--info); color: #fff; font-weight: 600; }
.rt-roundtrip.is-on input { accent-color: #fff; }
.ord-group-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }

/* Inline-editable cells — always-live inputs, not click-to-reveal */
.ec-input {
  font: inherit; padding: 2px 5px; border: 1px solid var(--border-focus);
  border-radius: 5px; background: var(--bg-input); color: var(--text-primary);
  width: 140px; max-width: 100%;
}
.ec-input.invalid { border-color: var(--danger); }
.ec-input.invalid:focus { border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger-bg); }
.ec-input.saving { opacity: 0.6; }
.ec-input.saved { background: var(--success-bg); border-color: var(--success); transition: background 1s; }
.ec-input:disabled { opacity: 0.55; cursor: not-allowed; }
/* Hours-based permit start: one flatpickr datetime field (vendored flatpickr —
   calendar + time controls in a single popup). Wide enough for "Aug 12, 2026 12:30 PM". */
.ec-input.start-dt-input { width: 175px; }
/* Requested route is free text that can run long — give it more room than the
   140px default (matches the old read-only display width). */
.ec-input[data-field="requested_route"] { width: 200px; }
/* Permit list Type cell: short description on top, tag beneath in a smaller,
   muted monospace line. */
.permit-type-desc { font-size: 13px; }
.permit-type-tag { font-size: 11px; color: var(--text-muted); margin-top: 1px; }
/* One permit, several jurisdictions (mig 0167): the marker on the real row, and
   the stand-in row under each other jurisdiction it covers. Both sit visually
   below the data they qualify, and the stand-in is deliberately quiet — it is a
   pointer, not a second permit. */
.permit-also-covers { font-size: 11px; margin-top: 2px; font-style: italic; }
.permit-ref-row td { font-size: 12px; }
/* Compact flatpickr popup typography — the vendored default is 14px days/time
   with a 135% month header; the app runs denser than that. app.css loads after
   the vendored sheet, so these plain overrides win. */
.flatpickr-calendar { font-size: 12px; }
.flatpickr-time input { font-size: 12px; }
.flatpickr-current-month { font-size: 105%; }
.flatpickr-current-month .numInputWrapper input.cur-year { font-size: inherit; }
.flatpickr-weekday { font-size: 10px; }
/* "Now"/"Today" shortcut appended to date/date-time popups on the order page. */
.fp-now-btn {
  text-align: center; padding: 6px; cursor: pointer; font-size: 12px;
  font-weight: 600; color: var(--text-secondary);
  border-top: 1px solid var(--border); background: var(--bg-elevated);
  border-bottom-left-radius: 5px; border-bottom-right-radius: 5px;
}
.fp-now-btn:hover { color: var(--text-primary); background: var(--bg-input); }
/* Load Description grows to fill the rest of its row (full block width); the
   "Trip & Fuel only" toggle sits on its own row above it. */
.ord-field .ec-input[data-field="load_description"] { flex: 1 1 auto; }
/* Load H/W/L are short dimension values — keep them narrow (default is 140px) so
   the "H × W × L @ weight lbs" row doesn't overflow the half-width Load block.
   The weight field keeps the default width. */
.ord-field .ec-input[data-field="load_height"],
.ord-field .ec-input[data-field="load_width"],
.ord-field .ec-input[data-field="load_length"] { width: 72px; }
.ord-tripfuel { white-space: nowrap; }

/* Vehicle / axle editable grids */
.grid-table th { font-size: 11px; }
.grid-table td { padding: 4px 6px; }
/* Vehicles table is referenced constantly — enlarge it (only) for legibility.
   Scoped to .veh-grid so the axles grid keeps its compact sizing. Covers header,
   read-only cell text (Unit column + non-editable values) and the editable
   inputs/Make select alike. */
.grid-table.veh-grid th { font-size: 13px; }
.grid-table.veh-grid td { font-size: 15px; padding: 6px 8px; }
.grid-table.veh-grid .veh-input,
.grid-table.veh-grid .veh-make-select,
.grid-table.veh-grid .veh-make-other { font-size: 15px; }
.veh-input, .ax-input {
  width: 100%; min-width: 44px; box-sizing: border-box; padding: 3px 5px;
  font-size: 12.5px; border: 1px solid transparent; border-radius: 4px;
  background: transparent; color: var(--text-primary);
}
/* VIN / plate inputs size to their content (not stretched to fill the cell) so the
   copy button sits right beside the value instead of floating at the far edge.
   Higher specificity than `.veh-input{width:100%}` and `.copy-cell .veh-input{flex:1 1 auto}`.
   22ch (border-box, less 10px padding) still shows a full 17-char VIN with cushion. */
.grid-table .copy-cell .veh-input[data-vfield="vin"]           { flex: 0 0 auto; width: 22ch; }
.grid-table .copy-cell .veh-input[data-vfield="license_plate"] { flex: 0 0 auto; width: 11ch; }
.veh-input:hover, .ax-input:hover { border-color: var(--border); }
.veh-input:focus, .ax-input:focus { outline: none; border-color: var(--border-focus); background: var(--bg-input); }
.veh-input.invalid { border-color: var(--danger); }
.veh-input.invalid:focus { border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger-bg); }
/* Order-grid Make cell: a catalog select with an "Other…" escape hatch that
   reveals a free-text input beneath it (styled to match the veh-input cells). */
.veh-make-cell { min-width: 108px; }
.veh-make-select, .veh-make-other {
  width: 100%; min-width: 90px; box-sizing: border-box; padding: 3px 5px;
  font-size: 12.5px; border: 1px solid transparent; border-radius: 4px;
  background: transparent; color: var(--text-primary);
}
.veh-make-other { margin-top: 3px; }
.veh-make-select:hover, .veh-make-other:hover { border-color: var(--border); }
.veh-make-select:focus, .veh-make-other:focus { outline: none; border-color: var(--border-focus); background: var(--bg-input); }

/* Jurisdictions */
.jur-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.jur-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  font-size: 12.5px; border: 1px solid var(--border); border-radius: 20px;
  background: var(--bg-elevated);
}
.jur-src { color: var(--accent); font-size: 11px; }
.jur-del { border: none; background: none; cursor: pointer; color: var(--text-muted); font-size: 10px; padding: 0; }
.jur-del:hover { color: var(--danger); }

/* Permits table */
.jur-head td {
  background: var(--bg-elevated); font-weight: 600; font-size: 12.5px;
  padding: 7px 12px;
}
.jur-head-label { margin-right: 12px; }
/* Per-jurisdiction collapse toggle (caret + clickable label). */
.jur-toggle {
  background: none; border: none; cursor: pointer; color: var(--text-secondary);
  font-size: 11px; line-height: 1; padding: 0 6px 0 0; vertical-align: middle;
}
.jur-toggle:hover { color: var(--accent); }
.jur-head-label[data-jur-toggle] { cursor: pointer; user-select: none; }

/* ── Jurisdiction drag-to-reorder ────────────────────────────────────────
   The grip is the ONLY drag surface, which is what leaves the caret, the label,
   the add-permit-type box and the two buttons behaving normally. touch-action
   is scoped to the grip alone so a finger anywhere else still scrolls the
   table. */
.jur-grip {
  display: inline-block; vertical-align: middle; cursor: grab;
  color: var(--text-muted); font-size: 13px; line-height: 1;
  padding: 0 6px 0 0; user-select: none; touch-action: none;
}
.jur-grip:hover, .jur-grip:focus-visible { color: var(--accent); }
body.jur-dragging, body.jur-dragging * { cursor: grabbing !important; user-select: none; }
/* The rows being dragged, dimmed in place — the tbody is never mutated
   mid-drag, so they don't move until the drop redraws. */
tr.jur-drag-src > td { opacity: 0.45; }
/* Drop indicator. inset box-shadow rather than a border: borders on <tr> don't
   render reliably under border-collapse, and a real border would shift the row
   by 2px as it appears. */
tr.jur-drop-before > td { box-shadow: inset 0  2px 0 var(--accent); }
tr.jur-drop-after  > td { box-shadow: inset 0 -2px 0 var(--accent); }
/* In-flight save — veils the table and blocks a second drop mid-request. */
.jur-reordering { opacity: 0.6; pointer-events: none; }
/* Applied-route roads through this jurisdiction, after the add-permit-type selector. */
.jur-head-roads { color: var(--text-muted); font-weight: normal; font-size: 12.5px; letter-spacing: 0; margin-left: 10px; }
.jur-head-roads::before { content: '— '; }
/* Add-permit-type selector sits inline, just right of the state label. */
.jur-head-actions { display: inline-flex; align-items: center; vertical-align: middle; }
.permit-status-sel {
  padding: 3px 6px; font-size: 12px; border: 1px solid var(--border);
  border-radius: 5px; background: var(--bg-input); color: var(--text-primary);
}
/* Brief highlight when a cell is updated in place by a live (realtime) update. */
@keyframes rt-flash-kf {
  from { background-color: var(--accent-dim, rgba(240, 89, 34, 0.18)); }
  to   { background-color: transparent; }
}
.rt-flash { animation: rt-flash-kf 1.1s ease-out; }
.jur-type-search {
  width: 200px; padding: 3px 8px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 5px;
  background: var(--bg-input); color: var(--text-primary); font-weight: normal;
}
.jur-type-search:focus { outline: none; border-color: var(--border-focus); }
.jur-type-opt {
  padding: 6px 10px; cursor: pointer; font-size: 12.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.jur-type-opt:hover { background: var(--bg-hover); }
.jur-type-opt.jur-type-other { color: var(--text-muted); }
.jur-type-badge {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--warning); margin-left: 6px;
}
.jur-type-hint {
  padding: 6px 10px; font-size: 11.5px; color: var(--text-muted);
  border-top: 1px solid var(--border); font-style: italic;
}

/* Notes */
.notes-list { display: flex; flex-direction: column; gap: 8px; }
.note-row {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 7px;
  font-size: 13px; background: var(--bg-elevated);
}
.note-row.note-internal { border-style: dashed; }
.note-meta { font-size: 11.5px; color: var(--text-muted); margin-bottom: 3px; }
.note-body { word-break: break-word; }

/* Load + Notes side-by-side row (order screen). Load = left half, Notes = right
   half; Notes list scrolls internally, height capped to Load by JS (max-height
   below is the fallback). Wraps to stacked columns when the row is too narrow. */
.ord-load-notes-row {
  display: flex; gap: 12px; align-items: stretch;
  margin-top: 14px; flex-wrap: wrap;
}
.ord-load-notes-row > .ord-group,
.ord-load-notes-row > #order-notes-card { flex: 1 1 320px; }
/* Override the g() inline margin-top so the Load block's top aligns with Notes,
   and give Load 10px more height (deeper bottom padding, 12px → 22px). */
.ord-load-notes-row > .ord-group { margin-top: 0 !important; padding-bottom: 22px; }
.ord-load-notes-row > #order-notes-card { margin-top: 0; }
#order-notes-card { display: flex; flex-direction: column; min-height: 0; }
#order-notes-card .notes-list {
  overflow-y: auto; flex: 1 1 auto; min-height: 0; max-height: 340px;
}

/* Route section: the load's STATED origin/destination, above the planner. Two
   lines tall and half width each, the pair stacking rather than crushing once
   the row gets narrow (same reasoning as .ord-load-notes-row). Distinct from
   the planner's Map Origin/Map Destination, which are single-line geocoder
   inputs inside the Details tab. */
.ord-od-row { margin-bottom: 12px; }
@media (max-width: 700px) { .ord-od-row { grid-template-columns: 1fr; } }
.ord-od-row .form-group { margin-bottom: 0; }
/* Fill the half-column. .ec-input is a 140px inline cell by default, and a bare
   textarea falls back to its ~20-column intrinsic width — both have to be
   overridden here, and the padding loosened to the form-field standard so two
   typed lines don't sit cramped against the border. */
textarea.ord-od {
  width: 100%; resize: vertical; min-height: 52px;
  padding: 8px 12px; line-height: 1.35;
}
/* Read-only rendering on a closed order — keeps the typed line break. */
.ord-od-ro {
  white-space: pre-wrap; word-break: break-word; min-height: 54px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-elevated); font-size: 13.5px; line-height: 1.35;
}

/* Order Activity feed — capped to ~4-5 rows, scrolls internally. */
.ord-activity-list { overflow-y: auto; max-height: 270px; }

.note-row[data-note-id] { cursor: pointer; }
.note-row[data-note-id]:hover { border-color: var(--text-secondary); }
.note-row.note-unread { border-left: 3px solid var(--warning); }
.note-unread-dot { color: var(--warning); font-size: 9px; }
.note-action-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 6px; min-height: 20px;
}
.note-read-btn, .note-menu-btn {
  border: none; background: none; cursor: pointer; padding: 2px 6px;
  border-radius: 4px; line-height: 1; font-size: 12px; color: var(--text-muted);
}
.note-read-btn { border: 1px solid var(--border); color: var(--text-secondary); }
.note-read-btn:hover { color: var(--text-primary); border-color: var(--text-secondary); }
.note-menu-btn { font-size: 16px; }
.note-menu-btn:hover { color: var(--text-primary); background: var(--bg-hover); }
.note-modal-body { white-space: pre-wrap; word-break: break-word; margin-top: 8px; }

/* Waivers + blockers */
.waiver-block {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 7px;
  margin-bottom: 8px; font-size: 13px;
}
.blocker-list { margin: 8px 0 8px 18px; font-size: 13.5px; color: var(--danger); }
.blocker-list li { margin-bottom: 5px; }

/* ── VIN validity signal (used wherever a VIN is edited/displayed) ──────── */
.form-input.invalid { border-color: var(--danger); }
.form-input.invalid:focus { border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger-bg); }
.vin-invalid, .cell-invalid { border: 1px solid var(--danger); border-radius: 4px; padding: 0 4px; }

/* ── Error-outline invariant (regression guard, 2026-07-21) ──────────────────
   A field failing validation (the `.invalid` class — VIN check digit, a year
   that disagrees with the VIN, gross weight that doesn't reconcile with the axle
   weights, etc.) is ALWAYS outlined in the danger red, never the neutral
   focus/active border. The per-base-class rules above (.ec-input/.veh-input/
   .form-input) already do this; this catch-all covers every other validated
   control (axle-weight cells, selects, bare inputs) so a change to the neutral
   --border-focus can never quietly neutralise an error indicator. Keep red. */
.ax-input.invalid, .form-select.invalid, .filter-select.invalid,
.veh-make-select.invalid, .veh-make-other.invalid, .jur-type-search.invalid,
input.invalid, select.invalid, textarea.invalid { border-color: var(--danger); }
.ax-input.invalid:focus, .form-select.invalid:focus, .filter-select.invalid:focus,
input.invalid:focus, select.invalid:focus, textarea.invalid:focus {
  border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger-bg);
}

/* ── Legacy Import ─────────────────────────────────────── */
.li-banner {
  padding: 10px 12px; border-radius: 6px; font-size: 13px; margin-bottom: 10px;
  border: 1px solid var(--border);
}
.li-banner-ok   { background: var(--success-bg); border-color: var(--success); }
.li-banner-new  { background: var(--accent-dim);  border-color: var(--accent); }
.li-banner-info { background: var(--accent-dim);  border-color: var(--accent); }
.li-banner-warn { background: var(--warning-bg);  border-color: var(--warning); }
.li-src {
  display: inline-block; font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  padding: 1px 5px; border-radius: 4px; vertical-align: 1px;
  background: var(--accent-dim); color: var(--accent-hover);
}
.li-exists {
  font-size: 12px; font-weight: 600; color: var(--warning);
  background: var(--warning-bg); padding: 2px 8px; border-radius: 10px;
}
.li-vin-warn { font-size: 11.5px; color: var(--danger); font-weight: 600; margin-left: 6px; }
.li-veh-off { opacity: .5; }
/* Make picker stuck on a custom ("Other…") make — thick red border on the
   select and its free-text box until a catalog make is chosen. box-shadow
   thickens the 1px border without shifting the grid. */
.li-make-custom,
.li-make-custom:focus { border-color: var(--danger); box-shadow: 0 0 0 2px var(--danger); }
.muted { color: var(--text-muted); }

/* ── Realtime connection dot (topbar) ─────────────────────────────────── */
.rt-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-muted);
}
.rt-dot.rt-on    { background: var(--success); }
.rt-dot.rt-off   { background: var(--text-muted); }
.rt-dot.rt-retry { background: var(--warning, #d97706); animation: rt-pulse 1.2s ease-in-out infinite; }
@keyframes rt-pulse { 50% { opacity: 0.35; } }

/* ── Password reset / login-with-code (login screen) ────────────────────── */
.reset-title { font-size: 15px; font-weight: 600; margin-bottom: 12px; text-align: center; }
.login-alt-sep { color: var(--text-muted); margin: 0 6px; }
.reset-channel {
  display: inline-flex; align-items: center; gap: 6px;
  margin-right: 16px; font-size: 13.5px; cursor: pointer;
}
.reset-channel input { margin: 0; }

/* ── Announcement banners ───────────────────────────────────────────────── */
.banner-strip { display: flex; flex-direction: column; }
.banner-strip:empty { display: none; }
.banner-strip-login { margin-bottom: 14px; gap: 8px; }

.banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  font-size: 13.5px;
  border-left: 4px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text-primary);
}
.banner-strip-login .banner { border-radius: var(--r-sm, 6px); border-bottom: none; }
.banner-icon { flex-shrink: 0; display: flex; margin-top: 1px; }
.banner-content { flex: 1; min-width: 0; }
.banner-title { font-weight: 600; }
.banner-msg { font-size: 12.5px; color: var(--text-secondary); margin-top: 2px; }
.banner-link {
  flex-shrink: 0; align-self: center; white-space: nowrap;
  font-weight: 600; font-size: 12.5px; text-decoration: none; color: inherit;
  padding: 4px 10px; border: 1px solid currentColor; border-radius: 99px; opacity: 0.9;
}
.banner-link:hover { opacity: 1; }
.banner-close {
  flex-shrink: 0; align-self: flex-start; background: none; border: none; cursor: pointer;
  color: var(--text-secondary); font-size: 15px; line-height: 1; padding: 2px 4px; border-radius: 4px;
}
.banner-close:hover { color: var(--text-primary); background: rgba(127,127,127,0.12); }

/* Per-type accent (icon + left border tinted; subtle bg wash). */
.banner-announcement { border-left-color: var(--success); background: var(--success-bg); }
.banner-announcement .banner-icon { color: var(--success); }
.banner-information   { border-left-color: var(--info);    background: var(--info-bg); }
.banner-information .banner-icon { color: var(--info); }
.banner-warning       { border-left-color: var(--warning); background: var(--warning-bg); }
.banner-warning .banner-icon { color: var(--warning); }
.banner-important     { border-left-color: var(--danger);  background: var(--danger-bg); }
.banner-important .banner-icon { color: var(--danger); }

/* Admin-table type tag (icon + label pill). */
.banner-type-tag { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.banner-type-tag svg { width: 15px; height: 15px; }
.banner-type-tag.banner-announcement { color: var(--success); background: none; border: none; }
.banner-type-tag.banner-information  { color: var(--info); }
.banner-type-tag.banner-warning      { color: var(--warning); }
.banner-type-tag.banner-important    { color: var(--danger); }

/* Permit Delivery recipient list (order work screen). */
.pd-row { display: flex; align-items: center; gap: 8px; padding: 4px 2px; font-size: 13px; }
.pd-row + .pd-row { border-top: 1px solid var(--border); }
.pd-icon { flex: 0 0 auto; }
.pd-name { font-weight: 600; }
.pd-addr { color: var(--text-muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 240px; }
.pd-badge { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; padding: 1px 7px; border-radius: 9px; border: 1px solid var(--border); }
.pd-badge-email { color: var(--info); }
.pd-badge-sms   { color: var(--success); }
.pd-badge-warn  { color: var(--warning); border-color: var(--warning); }
.pd-src { font-size: 10.5px; color: var(--text-muted); font-style: italic; }
.pd-del { margin-left: auto; background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 0 6px; font-size: 13px; }
.pd-del:hover { color: var(--danger); }

/* ── Conditions (admin catalog page + send-dialog checklist) ── */
.cond-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.cond-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px;
  font-size: 11.5px; border: 1px solid var(--border); border-radius: 20px;
  background: var(--bg-elevated); white-space: nowrap;
}
.cond-chip-req {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  padding: 0 5px; border-radius: 9px; border: 1px solid var(--border);
}
.cond-chip-req-always      { color: var(--warning); border-color: var(--warning); }
.cond-chip-req-conditional { color: var(--text-muted); }
/* "required" tag on an always-included condition row in the send dialog. */
.pd-badge-req { color: var(--warning); border-color: var(--warning); }
.pd-cond-title { font-size: 12.5px; font-weight: 600; margin: 12px 0 4px; }

/* ── File chooser (openFileChooser) — explorer-style picker overlay ── */
.fc-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 8, 18, 0.80);
  backdrop-filter: blur(3px);
  z-index: 150; /* above .modal-backdrop (100) so it stacks over an open modal */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.fc-box {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 900px;
  height: min(70vh, 640px);
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-lg);
  animation: modal-in 0.18s ease;
}
.fc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.fc-header h3 { font-size: 15px; font-weight: 600; color: var(--text-primary); margin: 0; }
.fc-x {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); padding: 4px; border-radius: var(--r-sm);
  font-size: 14px; line-height: 1;
}
.fc-x:hover { color: var(--text-primary); }
.fc-toolbar {
  display: flex;
  gap: 8px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.fc-body { display: flex; flex: 1; min-height: 0; }
.fc-tree {
  width: 300px;
  flex-shrink: 0;
  overflow-y: auto;
  border-right: 1px solid var(--border);
  padding: 8px;
  position: relative;
}
.fc-files { flex: 1; overflow-y: auto; padding: 8px; position: relative; }
.fc-node-hdr, .fc-record, .fc-file {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 13px;
  color: var(--text-primary);
  user-select: none;
}
.fc-node-hdr:hover, .fc-record:hover, .fc-file:hover { background: var(--bg-elevated); }
.fc-node-hdr svg, .fc-record svg, .fc-file svg { flex-shrink: 0; color: var(--text-muted); }
.fc-caret { display: flex; transition: transform 0.12s ease; }
.fc-node.open > .fc-node-hdr .fc-caret { transform: rotate(90deg); }
.fc-children { display: none; padding-left: 22px; }
.fc-node.open > .fc-children { display: block; }
.fc-record.active { background: var(--accent-dim); }
.fc-record.active svg { color: var(--accent); }
.fc-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fc-count {
  font-size: 11px;
  color: var(--text-muted);
  background: var(--bg-elevated);
  border-radius: 8px;
  padding: 1px 7px;
  flex-shrink: 0;
}
.fc-file { padding: 8px; }
.fc-file.selected { background: var(--accent-dim); }
.fc-file.selected svg { color: var(--accent); }
.fc-file-main { display: flex; flex-direction: column; min-width: 0; }
.fc-file-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fc-file-meta { font-size: 11.5px; color: var(--text-muted); }
.fc-hint {
  padding: 24px 16px;
  text-align: center;
  font-size: 13px;
  color: var(--text-muted);
}
.fc-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-shrink: 0;
}

/* ── Notification-template editor (CodeMirror + Jinja2 + live preview) ── */
.ft-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.ft-toolbar .form-label { margin: 0; }
.ft-insertvar { width: auto; min-width: 160px; font-size: 12px; padding: 4px 8px; }
.ft-html-row { display: flex; gap: 12px; align-items: stretch; }
.ft-html-row .ft-editor-col, .ft-html-row .ft-preview-col { flex: 1 1 0; min-width: 0; }
.ft-preview-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin: 8px 0 4px; }
.ft-preview {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-elevated); padding: 10px; margin: 0;
  overflow: auto; font-size: 12px; color: var(--text-primary);
}
.ft-preview-text { white-space: pre-wrap; font-family: var(--font-mono); min-height: 60px; max-height: 160px; }
.ft-preview-frame { width: 100%; height: 240px; background: #fff; }
.ft-sample { margin-top: 6px; }
.ft-sample-summary { cursor: pointer; font-size: 13px; color: var(--text-secondary); font-weight: 600; }
.ft-sample-hint { font-size: 12px; color: var(--text-muted); margin: 6px 0; }
.ft-sample-rows { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.ft-sample-row { display: flex; flex-direction: column; gap: 3px; }
.ft-sample-row label { font-size: 12px; color: var(--text-secondary); font-family: var(--font-mono); }
.ft-sample-val { font-size: 12px; padding: 5px 8px; }
/* Notices between the bodies and the sample panel: a variable the body uses
   that the template isn't actually given (renders as literal text in the real
   message), and the "seeded but nothing sends it yet" note. Sits above the
   collapsed sample panel so the warning can't hide inside it. */
.ft-varnotice { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 2px; }
.ft-varwarn, .ft-varnote {
  font-size: 12px; line-height: 1.45; padding: 7px 10px; border-radius: var(--r-sm);
  border: 1px solid;
}
.ft-varwarn { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }
.ft-varnote { color: var(--text-secondary); border-color: var(--border); background: var(--bg-elevated); }
.ft-varwarn code { font-family: var(--font-mono); font-size: 11.5px; }

/* CodeMirror surface themed to the app's light/orange tokens */
.CodeMirror {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  font-family: var(--font-mono); font-size: 12px; height: auto;
  background: var(--bg-input); color: var(--text-primary);
}
.CodeMirror-focused { border-color: var(--border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
.CodeMirror-cursor { border-left-color: var(--accent); }
.CodeMirror-selected { background: var(--accent-dim); }
/* Jinja delimiters, highlighted over the base HTML/plain-text mode */
.cm-jinja-var     { color: var(--accent); font-weight: 600; }
.cm-jinja-tag     { color: #7c3aed; font-weight: 600; }   /* {% logic %} */
.cm-jinja-comment { color: var(--text-muted); font-style: italic; }
