/* ============================================================================
 * Trucking Books — the design system. ONE file. There is no second one.
 *
 * Every page in this product is styled from here. Do not create per-page CSS.
 *
 * Why that rule exists: the JITC Planning app grew 24 separate <page>-2030.css
 * files layered over a shared token set, and they drifted — the same control
 * ended up with different radii, different borders, and two competing token
 * systems (--s30-* and --ops-*) that later had to be reconciled by hand. A new
 * page here gets a class in this file, or it reuses one that already exists.
 *
 * Built on the JITC 2030 tokens so it reads as the same house style:
 * ink #0b1f3a, blue #155eef, page #f3f7fc, the 10/15/20 radius ladder, 44px
 * controls, soft wide shadows, and the frosted-glass panel treatment.
 *
 * GLASS PERFORMANCE RULE (carried over, and it matters):
 * backdrop-filter goes on LARGE, MOSTLY-STATIC surfaces only — the sidebar and
 * page-level cards. Never on table rows, pills, buttons, or anything that
 * repeats dozens of times or animates. Blur is per-element GPU work; a hundred
 * blurred rows will visibly stutter on a laptop.
 * ==========================================================================*/

:root {
  /* ink */
  --tb-ink:          #0b1f3a;
  --tb-ink-soft:     #243b5a;
  --tb-muted:        #64748b;
  --tb-muted-strong: #506581;

  /* ground */
  --tb-page:         #f3f7fc;
  --tb-surface:      rgba(255, 255, 255, 0.92);
  --tb-surface-solid:#ffffff;
  --tb-surface-soft: #f8fbff;
  --tb-glass-border: rgba(96, 140, 210, 0.35);
  --tb-line:         #d8e3f1;
  --tb-line-strong:  #c6d5e8;

  /* accents */
  --tb-blue:         #155eef;
  --tb-blue-dark:    #0f49c7;
  --tb-blue-soft:    #eaf1ff;
  --tb-green:        #079669;
  --tb-green-soft:   #e9f8f2;
  --tb-amber:        #d97706;
  --tb-amber-soft:   #fff5e5;
  --tb-red:          #dc3545;
  --tb-red-soft:     #fff0f1;
  --tb-violet:       #6d4aff;
  --tb-violet-soft:  #f1edff;

  --tb-shadow-sm:    0 8px 24px rgba(32, 60, 96, 0.07);
  --tb-shadow-md:    0 16px 42px rgba(32, 60, 96, 0.10);
  --tb-radius-sm:    10px;
  --tb-radius-md:    15px;
  --tb-radius-lg:    20px;
  --tb-control:      44px;

  --tb-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --tb-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* Single visual world, deliberately: this is a daylight, glass-on-blue-wash
 * product. No dark theme. Colours are therefore stated once and are safe to
 * use directly. */
html { color-scheme: light; }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--tb-ink);
  background-color: var(--tb-page);
  background-image:
    radial-gradient(circle at 82% 0%, rgba(21, 94, 239, 0.07), transparent 29rem),
    radial-gradient(circle at 4% 12%, rgba(109, 74, 255, 0.05), transparent 24rem),
    linear-gradient(180deg, #f8fafe 0%, #f3f7fc 46%, #eef4fb 100%);
  background-attachment: fixed;
  font-family: var(--tb-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--tb-blue); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--tb-blue); outline-offset: 2px; border-radius: 4px; }

h1, h2, h3 { margin: 0; letter-spacing: -.02em; line-height: 1.2; text-wrap: balance; }
h1 { font-size: 1.7rem; font-weight: 650; }
h2 { font-size: 1.1rem; font-weight: 620; }

.eyebrow {
  font-family: var(--tb-mono);
  font-size: .67rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--tb-muted);
}

.num { font-family: var(--tb-mono); font-variant-numeric: tabular-nums; }

/* ---------- glass ---------------------------------------------------------
 * .glass is the ONLY place blur is declared. Anything that wants the frosted
 * treatment adds this class; nothing else sets backdrop-filter. That keeps the
 * performance rule enforceable by reading one selector.
 * ------------------------------------------------------------------------*/

.glass {
  background: var(--tb-surface);
  border: 1px solid var(--tb-glass-border);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: var(--tb-surface-solid); }
}

/* ---------- app shell ---------- */

.shell { display: grid; grid-template-columns: 244px minmax(0, 1fr); min-height: 100vh; }
@media (max-width: 900px) { .shell { grid-template-columns: 1fr; } }

.side {
  border-right: 1px solid var(--tb-glass-border);
  background: var(--tb-surface);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  padding: 20px 14px;
  display: flex; flex-direction: column; gap: 22px;
  position: sticky; top: 0; height: 100vh;
}
@media (max-width: 900px) {
  .side { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--tb-glass-border); }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .side { background: var(--tb-surface-solid); }
}

.brand { display: flex; align-items: center; gap: 10px; padding: 0 8px; }
.brand-mark {
  width: 32px; height: 32px; border-radius: 10px; flex: none;
  background: linear-gradient(145deg, var(--tb-blue), var(--tb-violet));
  box-shadow: 0 4px 12px rgba(21, 94, 239, .25);
  display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: .78rem; letter-spacing: -.03em;
}
.brand-name { font-weight: 640; letter-spacing: -.02em; }
.brand-sub { font-size: .7rem; color: var(--tb-muted); }

.nav-sections { display: flex; flex-direction: column; gap: 2px; }
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--tb-radius-sm);
  color: var(--tb-ink-soft); font-weight: 500; font-size: .9rem;
  text-decoration: none; min-height: 40px;
  transition: background 150ms ease, color 150ms ease;
}
.nav a .ic { flex: none; opacity: .72; }
.nav a:hover { background: rgba(255, 255, 255, .7); color: var(--tb-ink); text-decoration: none; }
.nav a:hover .ic { opacity: 1; }
.nav a[aria-current="page"] {
  background: var(--tb-blue-soft); color: var(--tb-blue); font-weight: 600;
}
.nav a[aria-current="page"] .ic { opacity: 1; }
.nav-group {
  margin: 14px 0 3px; padding: 0 11px;
  font-size: .67rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--tb-muted); font-weight: 650;
}
.nav-sections > .nav-group:first-child { margin-top: 0; }
.nav-badge {
  margin-left: auto; min-width: 22px; height: 20px; padding: 0 6px;
  border-radius: 10px; background: var(--tb-amber, #d97706); color: #fff;
  font-size: .7rem; font-weight: 700; display: flex; align-items: center;
  justify-content: center;
}

.side-foot { margin-top: auto; padding: 0; font-size: .78rem; color: var(--tb-muted); }
.who {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--tb-radius-sm);
  border: 1px solid var(--tb-line); background: var(--tb-surface-solid);
}
.who-mark {
  width: 32px; height: 32px; border-radius: 9px; flex: none;
  background: linear-gradient(145deg, var(--tb-blue), var(--tb-violet));
  color: #fff; font-size: .74rem; font-weight: 700;
  display: grid; place-items: center;
}
.who-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.who-text strong {
  font-size: .82rem; color: var(--tb-ink); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.who-text span { font-size: .7rem; color: var(--tb-muted); text-transform: capitalize; }
.who-out {
  margin-left: auto; display: grid; place-items: center; flex: none;
  width: 32px; height: 32px; border-radius: 8px; color: var(--tb-muted);
}
.who-out:hover { background: var(--tb-blue-soft); color: var(--tb-blue); }

/* Below the sidebar breakpoint the navigation becomes one scrolling strip.
 * A drawer needs script to open and this app ships none, and a strip that is
 * always visible beats a menu that cannot be closed. */
@media (max-width: 900px) {
  .nav-sections {
    flex-direction: row; overflow-x: auto; gap: 4px;
    scrollbar-width: none; padding-bottom: 4px;
  }
  .nav-sections::-webkit-scrollbar { display: none; }
  .nav-group { display: none; }
  .nav { flex-direction: row; gap: 4px; }
  .nav a { white-space: nowrap; }
}

.main { padding: 26px clamp(16px, 3vw, 34px) 60px; min-width: 0; }
.head {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end;
  justify-content: space-between; margin-bottom: 20px;
}
.head h1 { font-size: 1.55rem; letter-spacing: -.02em; margin: 0; }
.head .eyebrow {
  font-size: .68rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--tb-muted); font-weight: 650;
}

/* ---------- cards ---------- */

.card {
  background: var(--tb-surface-solid);
  border: 1px solid var(--tb-line);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(11, 31, 64, .05), 0 8px 24px -14px rgba(11, 31, 64, .16);
  padding: 18px 20px;
  transition: box-shadow 160ms ease;
}
.card + .card { margin-top: 16px; }
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px; flex-wrap: wrap;
}
/* The same micro-label the dashboard panels use, so a card on Setup and a
 * panel on the Overview announce themselves the same way. */
.card-head h2 {
  margin: 0; font-size: .74rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--tb-muted); font-weight: 650;
}
.card-head h3 { margin: 0; font-size: .95rem; font-weight: 620; }
.card h3 { font-size: .82rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--tb-muted); font-weight: 650; margin: 18px 0 2px; }

.grid { display: grid; gap: 16px; }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* ---------- stat tiles ---------- */

.stat { display: flex; flex-direction: column; gap: 3px; }
.stat-label { font-size: .78rem; color: var(--tb-muted); font-weight: 500; }
.stat-value { font-family: var(--tb-mono); font-variant-numeric: tabular-nums; font-size: 1.55rem; font-weight: 600; letter-spacing: -.02em; }
.stat-note { font-size: .75rem; color: var(--tb-muted); }
.stat-value.good { color: var(--tb-green); }
.stat-value.bad  { color: var(--tb-red); }

/* ---------- pills — no blur, these repeat ---------- */

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px;
  font-size: .73rem; font-weight: 600;
  border: 1px solid transparent; white-space: nowrap;
}
.pill-ok    { background: var(--tb-green-soft);  color: var(--tb-green);  border-color: rgba(7, 150, 105, .28); }
.pill-warn  { background: var(--tb-amber-soft);  color: var(--tb-amber);  border-color: rgba(217, 119, 6, .28); }
.pill-bad   { background: var(--tb-red-soft);    color: var(--tb-red);    border-color: rgba(220, 53, 69, .28); }
.pill-info  { background: var(--tb-blue-soft);   color: var(--tb-blue);   border-color: rgba(21, 94, 239, .28); }
.pill-quiet { background: var(--tb-surface-soft); color: var(--tb-muted); border-color: var(--tb-line); }

/* ---------- tables — no blur, rows repeat ---------- */

.table-wrap {
  overflow-x: auto;
  border-radius: var(--tb-radius-sm);
  border: 1px solid var(--tb-line);
  background: var(--tb-surface-solid);
}
table {
  width: 100%; border-collapse: collapse; font-size: .86rem;
  /* Money lines up column-wise only when the digits are the same width. */
  font-variant-numeric: tabular-nums;
}
thead th {
  background: var(--tb-surface-soft);
  position: sticky; top: 0; z-index: 1;
  text-align: left; font-weight: 650; font-size: .71rem;
  letter-spacing: .07em; text-transform: uppercase; color: var(--tb-muted);
  padding: 9px 12px; white-space: nowrap;
  border-bottom: 1px solid var(--tb-line);
  position: sticky; top: 0; z-index: 1;
}
tbody td { padding: 9px 12px; border-bottom: 1px solid var(--tb-line); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--tb-surface-soft); }
td.r, th.r { text-align: right; font-family: var(--tb-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
tr.flagged { background: rgba(217, 119, 6, .07); }
tr.flagged:hover { background: rgba(217, 119, 6, .11); }

/* ---------- forms & buttons ---------- */

label { display: block; font-size: .82rem; font-weight: 550; color: var(--tb-ink-soft); margin-bottom: 5px; }
/* Matched by exclusion, not by listing every type. An <input> with no type
 * attribute behaves as text but is NOT matched by input[type=text] -- attribute
 * selectors match the attribute, not the computed type -- so the MFA code field
 * rendered completely unstyled. Excluding the few that must not be stretched is
 * the version that cannot silently miss a field again. */
input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=hidden]),
select, textarea {
  width: 100%; min-height: var(--tb-control);
  padding: 9px 12px;
  background: var(--tb-surface-solid);
  border: 1px solid var(--tb-line-strong);
  border-radius: var(--tb-radius-sm);
  color: var(--tb-ink); font: inherit;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--tb-blue); outline: none; box-shadow: 0 0 0 3px var(--tb-blue-soft);
}
.field + .field { margin-top: 14px; }
.hint { font-size: .76rem; color: var(--tb-muted); margin-top: 6px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tb-control); padding: 0 18px;
  border-radius: var(--tb-radius-sm); border: 1px solid transparent;
  font: inherit; font-weight: 600; cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, transform 80ms ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--tb-blue); color: #fff; box-shadow: 0 4px 12px rgba(21, 94, 239, .22); }
.btn-primary:hover { background: var(--tb-blue-dark); }
.btn-primary:disabled { background: #9fb0c7; box-shadow: none; cursor: not-allowed; }
.btn-quiet { background: var(--tb-surface-solid); color: var(--tb-ink); border-color: var(--tb-line-strong); }
.btn-quiet:hover { background: var(--tb-surface-soft); }
.btn-full { width: 100%; }

/* ---------- notices ---------- */

.notice { padding: 11px 14px; border-radius: var(--tb-radius-sm); border: 1px solid; font-size: .86rem; margin-bottom: 16px; }
.notice-bad  { background: var(--tb-red-soft);   border-color: rgba(220, 53, 69, .3);  }
.notice-warn { background: var(--tb-amber-soft); border-color: rgba(217, 119, 6, .3);  }
.notice-ok   { background: var(--tb-green-soft); border-color: rgba(7, 150, 105, .3);  }
.notice-info { background: var(--tb-blue-soft);  border-color: rgba(21, 94, 239, .3);  }

/* ---------- centred auth pages ---------- */

.auth { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-card {
  width: min(415px, 100%);
  background: var(--tb-surface);
  border: 1px solid var(--tb-glass-border);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border-radius: var(--tb-radius-lg);
  box-shadow: var(--tb-shadow-md);
  padding: 32px;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .auth-card { background: var(--tb-surface-solid); }
}
.auth-brand { display: flex; align-items: center; gap: 11px; margin-bottom: 22px; }
.auth-title { font-size: 1.28rem; font-weight: 640; letter-spacing: -.02em; }
.auth-sub { color: var(--tb-muted); font-size: .88rem; margin: 4px 0 22px; }
.auth-foot { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--tb-line); font-size: .78rem; color: var(--tb-muted); }

/* A six-digit code is not a sentence: a full-width field invites the wrong
 * mental model and looks broken beside the content it sits under. */
.code-input {
  width: 100%; max-width: 260px; margin: 0 auto;
  font-family: var(--tb-mono); font-size: 1.6rem; font-weight: 600;
  letter-spacing: .42em; text-indent: .42em; text-align: center;
  min-height: 58px; padding: 8px 10px;
}
.field-centre { display: flex; flex-direction: column; align-items: center; }
.field-centre label { align-self: center; }


/* ---------- setup forms ----------
 * A bare button next to a labelled field never lines up: the field is a label
 * stacked on an input and the button is one box, so any align-items setting is
 * wrong for one of them. Fields go in a grid that wraps on its own, and the
 * buttons sit on their own row underneath where nothing has to line up at all.
 */
.form-grid {
  display: grid;
  gap: 14px 16px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  align-items: start;
}
.form-grid .wide { grid-column: 1 / -1; }
.form-grid label { margin-bottom: 5px; }
.form-actions {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--tb-line);
}
.form-actions .hint { margin: 0; }

/* Search sits above a table and belongs to it, so it is quiet rather than a
 * second call to action competing with the buttons in the card. */
.search-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.search-bar input[type=search] { min-width: 220px; }
.search-bar label { margin: 0; }

/* A row of buttons inside a table cell should not stretch the row. */
td form { display: inline; }
td .btn { padding: 5px 12px; font-size: .78rem; }

/* ---------- misc ---------- */

.muted { color: var(--tb-muted); }
.small { font-size: .8rem; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.spread { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
.stack { display: flex; flex-direction: column; gap: 3px; }
hr.sep { border: 0; border-top: 1px solid var(--tb-line); margin: 18px 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- MFA enrolment ----------
 * Matches the JITC Planning enrolment layout: numbered steps, QR panel beside a
 * manual setup key. The QR is inline SVG rendered on the server rather than
 * drawn by a vendored script, so script-src can stay 'none'.
 */

.auth-card-wide { width: min(560px, 100%); }

.steps-list {
  margin: 0 0 20px;
  padding-left: 20px;
  font-size: .85rem;
  color: var(--tb-muted);
  display: flex; flex-direction: column; gap: 5px;
}

.mfa-grid {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  padding: 16px;
  background: var(--tb-surface-soft);
  border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md);
  margin-bottom: 18px;
}
@media (max-width: 520px) { .mfa-grid { grid-template-columns: 1fr; justify-items: center; text-align: center; } }

.mfa-qr { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.mfa-qr svg {
  display: block; width: 168px; height: 168px;
  background: #fff; padding: 8px;
  border: 1px solid var(--tb-line); border-radius: var(--tb-radius-sm);
}
.mfa-qr figcaption { font-size: .72rem; color: var(--tb-muted); }

.mfa-key { display: flex; flex-direction: column; }
.mfa-key-value {
  display: block;
  font-family: var(--tb-mono); font-size: .82rem; line-height: 1.5;
  word-break: break-all; user-select: all;
  padding: 10px 12px;
  background: var(--tb-surface-solid);
  border: 1px solid var(--tb-line-strong);
  border-radius: var(--tb-radius-sm);
}

/* ==========================================================================
 * Fleet Command Center
 *
 * Every rule below is scoped under .fleet-command-center. The rest of the
 * product keeps the stylesheet it had: a dashboard is not a reason to restyle
 * the ledger. Colour, radius and shadow are declared once here as tokens so
 * this page can be adjusted without hunting through selectors.
 * ========================================================================== */

.fleet-command-center {
  /* Pointed at the product's tokens rather than redeclaring them: the two sets
   * differed only in the third hex digit, and two palettes that nearly agree
   * are how a design system starts to drift. */
  --fcc-bg: var(--tb-page);
  --fcc-surface: var(--tb-surface-solid);
  --fcc-ink: var(--tb-ink);
  --fcc-ink-2: var(--tb-muted);
  --fcc-blue: var(--tb-blue);
  --fcc-blue-deep: #0F4FBF;
  --fcc-pos: var(--tb-green);
  --fcc-warn: var(--tb-amber);
  --fcc-warn-bg: var(--tb-amber-soft);
  --fcc-bad: var(--tb-red);
  --fcc-bad-bg: var(--tb-red-soft);
  --fcc-line: var(--tb-line);
  --fcc-r-lg: 18px;
  --fcc-r-sm: 11px;
  --fcc-shadow: 0 1px 2px rgba(11, 31, 64, .05), 0 8px 24px -12px rgba(11, 31, 64, .16);

  color: var(--fcc-ink);
  font-variant-numeric: tabular-nums;
  display: flex; flex-direction: column; gap: 20px;
}

.fleet-command-center .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- header ---------- */
.fcc-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 18px; flex-wrap: wrap;
}
.fcc-head h1 { font-size: 1.85rem; letter-spacing: -.02em; margin: 0; }
.fcc-sub { color: var(--fcc-ink-2); margin: 5px 0 0; font-size: .92rem; }
.fcc-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

.fleet-command-center .period {
  display: flex; align-items: center; gap: 8px;
  background: var(--fcc-surface); border: 1px solid var(--fcc-line);
  border-radius: var(--fcc-r-sm); padding: 6px 10px;
}
.fleet-command-center .period-icon { color: var(--fcc-ink-2); display: flex; }
.fleet-command-center .period select,
.fleet-command-center .period input[type=date] {
  border: 0; background: transparent; padding: 4px 2px; min-height: 32px;
  font-size: .86rem; color: var(--fcc-ink); font-weight: 550;
}
.fleet-command-center .period input[type=date] { max-width: 140px; }
.fleet-command-center .btn-quiet {
  border: 1px solid var(--fcc-line); background: var(--fcc-surface);
  color: var(--fcc-ink); border-radius: 9px; padding: 7px 13px;
  font-size: .82rem; font-weight: 600; cursor: pointer; min-height: 34px;
}
.fleet-command-center .btn-quiet:hover { border-color: var(--fcc-blue); color: var(--fcc-blue); }

/* The bell is a disclosure, not a widget: no script, and it closes on Escape
 * because that is what a <details> does. */
.fleet-command-center .bell { position: relative; }
.fleet-command-center .bell > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center;
  justify-content: center; width: 42px; height: 42px; border-radius: var(--fcc-r-sm);
  border: 1px solid var(--fcc-line); background: var(--fcc-surface); position: relative;
}
.fleet-command-center .bell > summary::-webkit-details-marker { display: none; }
.fleet-command-center .bell-count {
  position: absolute; top: -6px; right: -6px; min-width: 19px; height: 19px;
  border-radius: 10px; background: var(--fcc-bad); color: #fff;
  font-size: .68rem; font-weight: 700; display: flex; align-items: center;
  justify-content: center; padding: 0 5px;
}
.fleet-command-center .bell-panel {
  position: absolute; right: 0; top: 50px; z-index: 30; width: min(340px, 86vw);
  background: var(--fcc-surface); border: 1px solid var(--fcc-line);
  border-radius: var(--fcc-r-lg); box-shadow: var(--fcc-shadow); padding: 14px;
}
.fleet-command-center .bell-panel h3 {
  margin: 0 0 10px; font-size: .74rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fcc-ink-2);
}
.fleet-command-center .bell-item {
  display: block; padding: 9px 10px; border-radius: 9px; text-decoration: none;
  color: var(--fcc-ink);
}
.fleet-command-center .bell-item:hover { background: var(--fcc-bg); }
.fleet-command-center .bell-item strong { display: block; font-size: .86rem; }
.fleet-command-center .bell-item span { font-size: .78rem; color: var(--fcc-ink-2); }

/* ---------- summary cards ---------- */
/* The hero stands beside two rows of three. It was one row of four until the
 * fleet started reporting driver pay and what it left after them, and a fifth
 * and sixth card squeezed into a row built for four is how a dashboard starts
 * looking cramped. */
.fleet-command-center .stats {
  display: grid; gap: 14px;
  grid-template-columns: 1.65fr repeat(3, 1fr);
  align-items: stretch;
}
.fleet-command-center .stat.hero { grid-row: span 2; }
.fleet-command-center .stat {
  background: var(--fcc-surface); border: 1px solid var(--fcc-line);
  border-radius: var(--fcc-r-lg); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 6px;
  transition: box-shadow 160ms ease, transform 160ms ease;
}
.fleet-command-center .stat:hover { box-shadow: var(--fcc-shadow); }
.fleet-command-center .stat h3 {
  margin: 0; font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--fcc-ink-2); font-weight: 650;
}
.fleet-command-center .stat-value {
  margin: 0; font-size: 1.6rem; font-weight: 680; letter-spacing: -.02em;
}
.fleet-command-center .stat-note { margin: 0; font-size: .76rem; color: var(--fcc-ink-2); }
.fleet-command-center .stat-spark { margin-top: auto; color: var(--fcc-blue); opacity: .55; }

/* The one gradient on the page, on the one card that matters most. */
.fleet-command-center .stat.hero {
  grid-row: span 1;
  background: linear-gradient(135deg, var(--fcc-blue) 0%, var(--fcc-blue-deep) 100%);
  border-color: transparent; color: #fff; padding: 20px 22px; gap: 8px;
}
.fleet-command-center .stat.hero h2 {
  margin: 0; font-size: .74rem; letter-spacing: .07em; text-transform: uppercase;
  font-weight: 650; color: rgba(255,255,255,.86);
}
.fleet-command-center .stat.hero h2 span { text-transform: none; letter-spacing: 0; opacity: .8; }
.fleet-command-center .hero-value {
  margin: 0; font-size: 2.6rem; font-weight: 700; letter-spacing: -.03em; line-height: 1.05;
}
.fleet-command-center .hero-delta {
  margin: 0; display: flex; align-items: center; gap: 6px;
  font-size: .84rem; font-weight: 600; color: rgba(255,255,255,.94);
}
.fleet-command-center .hero-delta-note { font-weight: 500; opacity: .74; }
.fleet-command-center .muted-delta { opacity: .8; }
.fleet-command-center .hero-spark { margin-top: auto; color: rgba(255,255,255,.85); }
.fleet-command-center .spark { display: block; width: 100%; height: auto; }
.fleet-command-center .spark-green { color: var(--fcc-pos); }
.fleet-command-center .spark-amber { color: var(--fcc-warn); }
.fleet-command-center .spark-empty { color: var(--fcc-ink-2); font-size: .8rem; }

/* ---------- attention ---------- */
.fleet-command-center .attention h2,
.fleet-command-center .panel-head h2 {
  margin: 0 0 10px; font-size: .74rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fcc-ink-2); font-weight: 650;
}
.fleet-command-center .alert-row {
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.fleet-command-center .alert {
  display: flex; align-items: center; gap: 13px;
  background: var(--fcc-surface); border: 1px solid var(--fcc-line);
  border-radius: var(--fcc-r-lg); padding: 14px 16px;
}
.fleet-command-center .alert-icon {
  width: 40px; height: 40px; border-radius: 11px; flex: 0 0 40px;
  display: flex; align-items: center; justify-content: center;
}
.fleet-command-center .alert-warn .alert-icon { background: var(--fcc-warn-bg); color: var(--fcc-warn); }
.fleet-command-center .alert-bad .alert-icon { background: var(--fcc-bad-bg); color: var(--fcc-bad); }
.fleet-command-center .alert-ok .alert-icon { background: #DCFCE7; color: var(--fcc-pos); }
.fleet-command-center .alert-body { flex: 1 1 auto; min-width: 0; }
.fleet-command-center .alert-title { margin: 0; font-weight: 620; font-size: .94rem; }
.fleet-command-center .alert-detail {
  margin: 2px 0 0; font-size: .79rem; color: var(--fcc-ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fleet-command-center .alert-action {
  display: flex; align-items: center; gap: 5px; white-space: nowrap;
  color: var(--fcc-blue); font-weight: 620; font-size: .84rem; text-decoration: none;
  min-height: 44px; padding: 0 4px;
}
.fleet-command-center .alert-action:hover { text-decoration: underline; }

/* ---------- panels ---------- */
.fleet-command-center .fcc-grid {
  display: grid; gap: 16px; grid-template-columns: 2fr 1fr; align-items: start;
}
.fleet-command-center .panel {
  background: var(--fcc-surface); border: 1px solid var(--fcc-line);
  border-radius: var(--fcc-r-lg); padding: 16px 18px;
}
.fleet-command-center .panel-head {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.fleet-command-center .panel-link {
  display: flex; align-items: center; gap: 5px; text-decoration: none;
  color: var(--fcc-blue); font-weight: 600; font-size: .82rem;
}
.fleet-command-center .panel-foot {
  display: flex; justify-content: space-between; gap: 12px; padding-top: 12px;
  font-size: .78rem; color: var(--fcc-ink-2); border-top: 1px solid var(--fcc-line);
  margin-top: 10px;
}

.fleet-command-center .table-controls {
  display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-bottom: 12px;
}
.fleet-command-center .control-search {
  display: flex; align-items: center; gap: 7px; flex: 1 1 200px;
  border: 1px solid var(--fcc-line); border-radius: 9px; padding: 0 11px;
  color: var(--fcc-ink-2); background: var(--fcc-surface);
}
.fleet-command-center .control-search input {
  border: 0; background: transparent; padding: 8px 0; min-height: 34px;
  width: 100%; font-size: .86rem; color: var(--fcc-ink);
}
.fleet-command-center .control-select select {
  border: 1px solid var(--fcc-line); border-radius: 9px; padding: 7px 10px;
  min-height: 36px; font-size: .84rem; background: var(--fcc-surface); color: var(--fcc-ink);
}

.fleet-command-center .table-scroll { overflow-x: auto; }
.fleet-command-center table { width: 100%; border-collapse: collapse; }
.fleet-command-center thead th {
  position: sticky; top: 0; background: var(--fcc-surface); z-index: 1;
  text-align: left; font-size: .69rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--fcc-ink-2); font-weight: 650; padding: 8px 12px;
  border-bottom: 1px solid var(--fcc-line); white-space: nowrap;
}
.fleet-command-center thead th a { color: inherit; text-decoration: none; }
.fleet-command-center thead th a:hover { color: var(--fcc-blue); }
.fleet-command-center tbody td {
  padding: 11px 12px; border-bottom: 1px solid var(--fcc-line);
  font-size: .88rem; white-space: nowrap;
}
.fleet-command-center tbody tr:last-child td { border-bottom: 0; }
.fleet-command-center tbody tr:hover { background: var(--fcc-bg); }
.fleet-command-center .row-best { background: rgba(14, 159, 110, .05); }
.fleet-command-center .num { text-align: right; }
.fleet-command-center .pos { color: var(--fcc-pos); font-weight: 620; }
.fleet-command-center .neg { color: var(--fcc-bad); font-weight: 620; }
.fleet-command-center .unit { color: var(--fcc-blue); font-weight: 680; text-decoration: none; }
.fleet-command-center .unit:hover { text-decoration: underline; }
.fleet-command-center .empty { color: var(--fcc-ink-2); text-align: center; padding: 22px; }
.fleet-command-center .trend { width: 140px; }
.fleet-command-center .period { white-space: nowrap; }
.fleet-command-center td.period { display: flex; align-items: center; gap: 6px; color: var(--fcc-ink-2); }

/* Status never rests on colour alone: each tag carries its own word. */
.fleet-command-center .tag {
  display: inline-block; padding: 3px 9px; border-radius: 20px;
  font-size: .73rem; font-weight: 620; border: 1px solid transparent;
}
.fleet-command-center .tag-ok { background: #DCFCE7; color: #0A7048; border-color: #A7F3D0; }
.fleet-command-center .tag-watch { background: var(--fcc-warn-bg); color: #92400E; border-color: #FDE68A; }
.fleet-command-center .tag-inactive { background: #EEF2F8; color: #52627C; border-color: var(--fcc-line); }
.fleet-command-center .tag-info { background: #DBEAFE; color: #1E40AF; border-color: #BFDBFE; }

/* ---------- contribution chart ---------- */
.fleet-command-center .bars { display: flex; flex-direction: column; gap: 9px; margin-top: 4px; }
.fleet-command-center .bar-row {
  display: grid; grid-template-columns: 42px 1fr auto; align-items: center; gap: 10px;
  text-decoration: none; color: var(--fcc-ink); padding: 3px 4px; border-radius: 8px;
}
.fleet-command-center .bar-row:hover { background: var(--fcc-bg); }
.fleet-command-center .bar-unit { font-size: .82rem; font-weight: 620; color: var(--fcc-ink-2); }
.fleet-command-center .bar-track { height: 15px; background: #EEF3FA; border-radius: 7px; overflow: hidden; }
.fleet-command-center .bar { display: block; height: 100%; border-radius: 7px; }
.fleet-command-center .bar-pos { background: var(--fcc-pos); }
.fleet-command-center .bar-neg { background: var(--fcc-bad); }
.fleet-command-center .bar-zero { background: #C7D3E4; }
.fleet-command-center .bar-value { font-size: .8rem; font-weight: 620; }
.fleet-command-center .bar-value.zero { color: var(--fcc-ink-2); }
.fleet-command-center .insight {
  display: flex; align-items: center; gap: 10px; margin-top: 14px; padding: 12px 14px;
  background: rgba(14, 159, 110, .07); border: 1px solid rgba(14, 159, 110, .18);
  border-radius: var(--fcc-r-sm);
}
.fleet-command-center .insight-icon { color: var(--fcc-pos); display: flex; }
.fleet-command-center .insight-label { font-size: .8rem; color: var(--fcc-ink-2); font-weight: 600; }
.fleet-command-center .insight-value {
  margin-left: auto; color: var(--fcc-pos); font-weight: 680; text-decoration: none; font-size: .88rem;
}

.fleet-command-center a:focus-visible,
.fleet-command-center button:focus-visible,
.fleet-command-center select:focus-visible,
.fleet-command-center input:focus-visible,
.fleet-command-center summary:focus-visible {
  outline: 2px solid var(--fcc-blue); outline-offset: 2px; border-radius: 6px;
}

/* ---------- responsive ---------- */
@media (max-width: 1279px) {
  .fleet-command-center .stats { grid-template-columns: repeat(2, 1fr); }
  /* Full width and one row again: the two-row span only makes sense beside
   * three columns of cards. */
  .fleet-command-center .stat.hero { grid-column: 1 / -1; grid-row: auto; }
  .fleet-command-center .fcc-grid { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
  .fleet-command-center .stats { grid-template-columns: 1fr; }
  .fleet-command-center .fcc-head h1 { font-size: 1.45rem; }
  .fleet-command-center .hero-value { font-size: 2.1rem; }
  .fleet-command-center .alert-row { grid-template-columns: 1fr; }
  /* The unit stays put while the money scrolls: losing which truck a row is
   * about makes the rest of the row meaningless. */
  .fleet-command-center .col-unit,
  .fleet-command-center tbody td:first-child {
    position: sticky; left: 0; background: var(--fcc-surface); z-index: 2;
  }
  .fleet-command-center tbody tr:hover td:first-child { background: var(--fcc-bg); }
}
@media (prefers-reduced-motion: reduce) {
  .fleet-command-center * { transition: none !important; }
}

/* ==========================================================================
 * The printed statement
 *
 * A payment record rather than a page of the app: no navigation, no controls,
 * nothing that only means something on a screen. Printed from the browser --
 * a print stylesheet costs nothing and the browser's own PDF export produces
 * the file, where a rendering library would have been a dependency to redraw
 * a table that already exists.
 * ========================================================================== */

body.print-page { background: #EDEFF3; padding: 24px 16px; }

.sheet {
  max-width: 860px; margin: 0 auto; background: #fff; color: #10161F;
  padding: 40px 44px; border: 1px solid #CBD2DC; border-radius: 4px;
  box-shadow: 0 10px 30px -18px rgba(16, 22, 31, .3);
  font-variant-numeric: tabular-nums;
}
.sheet .mono { font-family: var(--tb-mono); }
.sheet .num { text-align: right; font-variant-numeric: tabular-nums; }

.sheet-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 28px; padding-bottom: 18px; border-bottom: 2px solid #1F3556;
}
.sheet-head h1 { margin: 4px 0 0; font-size: 1.5rem; letter-spacing: -.01em; color: #16263E; }
.sheet .kicker {
  margin: 0; font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
  color: #4A5666; font-weight: 600;
}
.sheet .meta { border-collapse: collapse; font-size: .8rem; }
.sheet .meta th {
  text-align: left; padding: 2px 14px 2px 0; color: #7B8797; font-weight: 500;
}
.sheet .meta td { padding: 2px 0; font-weight: 600; white-space: nowrap; }

.sheet .vendor { margin: 20px 0 24px; }
.sheet .label {
  margin: 0 0 4px; font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
  color: #7B8797; font-weight: 600;
}
.sheet .vendor-name { margin: 0; font-size: 1.02rem; font-weight: 650; }
.sheet .vendor-line { margin: 1px 0 0; font-size: .84rem; color: #4A5666; }

.sheet .loads { width: 100%; border-collapse: collapse; font-size: .82rem; }
.sheet .loads thead th {
  text-align: left; font-size: .64rem; letter-spacing: .1em; text-transform: uppercase;
  color: #7B8797; font-weight: 650; padding: 0 8px 7px;
  border-bottom: 1px solid #CBD2DC; white-space: nowrap;
}
.sheet .loads thead th.num { text-align: right; }
.sheet .loads tbody td { padding: 7px 8px; border-bottom: 1px solid #E4E8EE; }
.sheet .loads .lane { color: #4A5666; }
.sheet .loads .extra td { font-weight: 600; }
.sheet .loads .extra td:first-child { color: #4A5666; font-weight: 500; }
.sheet .loads .deduct { color: #8A6A1F; }

.sheet .totals {
  margin: 18px 0 0 auto; border-collapse: collapse; font-size: .88rem; min-width: 280px;
}
.sheet .totals th {
  text-align: left; padding: 5px 24px 5px 0; font-weight: 500; color: #4A5666;
}
.sheet .totals td { padding: 5px 0; font-weight: 600; }
.sheet .totals .grand th, .sheet .totals .grand td {
  border-top: 2px solid #1F3556; padding-top: 10px;
  font-size: 1.12rem; font-weight: 700; color: #16263E;
}

.sheet .foot { margin: 26px 0 0; font-size: .72rem; color: #7B8797; }
/* Sits with the totals it explains, not at the foot of the page where the
 * driver would read it after already wondering. */
.sheet .note-miles {
  margin: 12px 0 0 auto; max-width: 360px; text-align: right;
  font-size: .74rem; color: #4A5666; line-height: 1.45;
}
.sheet .draft-mark {
  margin: 14px 0 0; font-size: .74rem; font-weight: 700; letter-spacing: .1em;
  color: #8A6A1F;
}
.sheet .actions {
  margin-top: 28px; padding-top: 16px; border-top: 1px solid #E4E8EE;
  display: flex; gap: 14px; align-items: center; font-size: .8rem; color: #7B8797;
}

@media print {
  body.print-page { background: #fff; padding: 0; }
  .sheet { border: 0; box-shadow: none; max-width: none; padding: 0; }
  .no-print { display: none !important; }
  /* A statement that splits a load across two pages is hard to check. */
  .sheet .loads tr, .sheet .totals { break-inside: avoid; }
  .sheet .loads thead { display: table-header-group; }
}

/* Choosing a layout is not part of the statement, so it does not print. */
.layout-picker {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 26px; padding-top: 16px; border-top: 1px solid #E4E8EE;
  font-size: .78rem;
}
.layout-picker span { color: #7B8797; font-weight: 600; margin-right: 4px; }
.layout-picker a {
  padding: 5px 11px; border-radius: 8px; text-decoration: none;
  color: #4A5666; border: 1px solid #CBD2DC;
}
.layout-picker a:hover { border-color: #1F3556; color: #16263E; }
.layout-picker a[aria-current="page"] {
  background: #1F3556; border-color: #1F3556; color: #fff; font-weight: 600;
}

/* ---------- full settlement ----------
 * The shape a driver already knows how to read, because it is the shape their
 * settlement arrives in: centred masthead, a dark rule under the header row,
 * earnings and deductions as sections, then the totals and the year.
 */
.sheet.settlement { padding: 38px 44px 34px; }
.settle-head { text-align: center; padding-bottom: 16px; }
.settle-head h1 {
  margin: 0 0 14px; font-size: 1.16rem; letter-spacing: .06em;
  text-transform: uppercase; color: #1F3556; font-weight: 700;
}
.settle-head .label { margin: 0 0 2px; }
.settle-head .vendor-name { margin: 0; font-size: 1.22rem; font-weight: 700; }
.settle-head .vendor-line { margin: 4px 0 0; }

.settle-meta {
  display: flex; gap: 34px; flex-wrap: wrap;
  padding: 12px 0; border-top: 2px solid #1F3556; border-bottom: 1px solid #CBD2DC;
}
.settle-meta div { display: flex; flex-direction: column; gap: 3px; }
.settle-meta span {
  font-size: .63rem; letter-spacing: .12em; text-transform: uppercase;
  color: #7B8797; font-weight: 600;
}
.settle-meta strong { font-size: .88rem; font-weight: 650; }

.settle-table { margin-top: 22px; }
.settle-table thead th {
  background: #1F3556; color: #fff; padding: 9px 10px;
  border-bottom: 0; letter-spacing: .1em;
}
.settle-table thead th:first-child { border-radius: 3px 0 0 3px; }
.settle-table thead th:last-child { border-radius: 0 3px 3px 0; }
.settle-table .section td {
  padding-top: 18px; font-size: .63rem; letter-spacing: .12em;
  text-transform: uppercase; color: #7B8797; font-weight: 650;
  border-bottom: 1px solid #CBD2DC;
}

.ytd { margin-top: 26px; padding-top: 16px; border-top: 1px solid #CBD2DC; }
.ytd-row { display: flex; gap: 40px; flex-wrap: wrap; margin-top: 8px; }
.ytd-row div { display: flex; flex-direction: column; gap: 2px; }
.ytd-row span {
  font-size: .63rem; letter-spacing: .12em; text-transform: uppercase;
  color: #7B8797; font-weight: 600;
}
.ytd-row strong { font-size: .96rem; font-weight: 650; }
.ytd .foot { margin-top: 10px; }

/* ============================================================================
 * The operations workspace — shared by Driver pay and Fleet.
 *
 * One set of components, not two: both pages are a header, a rail of numbers,
 * a row of filters and one wide table, and building that twice is how two
 * pages start disagreeing about what a chip looks like. A page adds .ops-2030
 * for the shared parts and its own class for anything genuinely its own.
 *
 * Scoped to .ops-2030 so it cannot leak, but built entirely from the
 * tokens above: this is the same house style at a larger size, not a second
 * design system. Nothing here redefines a colour, a radius or a shadow.
 *
 * The glass rule from the top of this file is obeyed strictly. backdrop-filter
 * appears exactly twice — the summary rail and the workflow rail, both single
 * large surfaces that never repeat. The table, its rows, the chips, the pills
 * and the menus are all opaque. A hundred blurred rows stutter; five hundred
 * would crawl.
 * ==========================================================================*/

.ops-2030 { --ops-gap: 14px; }

/* Its own copy rather than a global rule: the only other one in this file is
 * scoped to the command centre, and a rule this destructive is better stated
 * twice than made global by a page that happened to need it second. */
.ops-2030 .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- header ------------------------------------------------------------ */

.ops-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; flex-wrap: wrap; margin: 0 0 var(--ops-gap);
}
.ops-eyebrow {
  margin: 0; font-size: .68rem; font-weight: 650; letter-spacing: .13em;
  text-transform: uppercase; color: var(--tb-muted);
}
.ops-head h1 { margin: 2px 0 0; font-size: 1.85rem; font-weight: 680; }
.ops-sub { margin: 4px 0 0; color: var(--tb-muted-strong); font-size: .95rem; }
.ops-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ops-head-actions .btn { display: inline-flex; align-items: center; gap: 7px; }

.ops-period {
  display: flex; align-items: center; gap: 6px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-sm); padding: 0 6px 0 10px; height: var(--tb-control);
}
.ops-period-icon { display: flex; color: var(--tb-muted); }
.ops-period select {
  border: 0; background: none; font: inherit; color: var(--tb-ink);
  height: 100%; padding: 0 2px; min-width: 8.5rem;
}
.ops-period select:focus-visible { outline: 2px solid var(--tb-blue); outline-offset: 1px; }

/* ---- the five numbers -------------------------------------------------- */

.ops-summary {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 0;
  background: var(--tb-surface); border: 1px solid var(--tb-glass-border);
  border-radius: var(--tb-radius-lg); box-shadow: var(--tb-shadow-sm);
  backdrop-filter: blur(14px); overflow: hidden; margin-bottom: 10px;
}
.ops-metric {
  display: flex; align-items: center; gap: 12px; padding: 15px 18px;
  color: inherit; text-decoration: none; position: relative;
  border-left: 1px solid var(--tb-line);
}
.ops-metric:first-child { border-left: 0; }
.ops-metric:hover { background: rgba(21, 94, 239, .045); text-decoration: none; }
.ops-metric-icon {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  background: var(--tb-blue-soft); color: var(--tb-blue);
}
.ops-ok    .ops-metric-icon { background: var(--tb-green-soft); color: var(--tb-green); }
.ops-warn  .ops-metric-icon { background: var(--tb-amber-soft); color: var(--tb-amber); }
.ops-qb    .ops-metric-icon { background: var(--tb-green-soft); color: #2ca01c; }
.ops-metric-text { display: flex; flex-direction: column; min-width: 0; }
.ops-metric-label {
  font-size: .78rem; color: var(--tb-muted-strong); font-weight: 550;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ops-metric-value {
  font-size: 1.5rem; font-weight: 680; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
/* Selection is a bar and a weight change as well as a colour, so it survives
 * being read by someone who cannot tell the blue from the grey. */
.ops-metric.is-on { background: var(--tb-blue-soft); }
.ops-metric.is-on::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--tb-blue);
}
.ops-metric.is-on .ops-metric-label { color: var(--tb-blue-dark); font-weight: 650; }

/* ---- the lifecycle ----------------------------------------------------- */

.ops-rail {
  display: flex; align-items: center; gap: 4px;
  background: var(--tb-surface); border: 1px solid var(--tb-glass-border);
  border-radius: var(--tb-radius-lg); box-shadow: var(--tb-shadow-sm);
  backdrop-filter: blur(14px); padding: 12px 20px; margin-bottom: var(--ops-gap);
}
.ops-stage {
  display: inline-flex; align-items: center; gap: 9px; flex: none;
  padding: 6px 12px; border-radius: 999px; color: var(--tb-ink-soft);
  font-size: .9rem; text-decoration: none;
}
a.ops-stage:hover { background: var(--tb-blue-soft); text-decoration: none; }
a.ops-stage.is-on { background: var(--tb-blue); color: #fff; }
a.ops-stage.is-on .ops-stage-count { background: rgba(255,255,255,.22); color: #fff; }
.ops-stage-dot {
  width: 13px; height: 13px; border-radius: 50%; flex: none;
  border: 2px solid var(--tb-line-strong); background: var(--tb-surface-solid);
}
.ops-stage-dot.is-done { border-color: var(--tb-green); background: var(--tb-green); }
a.ops-stage.is-on .ops-stage-dot { border-color: #fff; }
.ops-stage-label { white-space: nowrap; }
.ops-stage-count {
  font-variant-numeric: tabular-nums; font-weight: 650; font-size: .82rem;
  background: var(--tb-blue-soft); color: var(--tb-blue-dark);
  border-radius: 999px; padding: 1px 8px;
}
.ops-stage-line { flex: 1 1 auto; height: 2px; background: var(--tb-line); min-width: 12px; }

/* ---- the workspace ----------------------------------------------------- */

/* Not `overflow: hidden`. Every menu in these tables is positioned absolutely,
 * and an ancestor with overflow clips those -- which is why the row menu opened
 * and showed half a Paperwork button and nothing else. The rounded corners
 * survive without it; the menus do not survive with it. */
.ops-panel {
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-lg); box-shadow: var(--tb-shadow-sm);
}
.ops-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; padding: 14px 16px;
  border-bottom: 1px solid var(--tb-line);
}
.ops-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ops-chip {
  display: inline-flex; align-items: center; gap: 7px; height: 36px;
  padding: 0 13px; border-radius: var(--tb-radius-sm); font-size: .89rem;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  color: var(--tb-ink-soft); text-decoration: none; font-weight: 550;
}
.ops-chip:hover { border-color: var(--tb-line-strong); text-decoration: none; }
.ops-chip-n {
  font-variant-numeric: tabular-nums; font-size: .8rem; font-weight: 650;
  color: var(--tb-muted-strong);
}
.ops-chip.is-on { background: var(--tb-blue); border-color: var(--tb-blue); color: #fff; }
.ops-chip.is-on .ops-chip-n { color: rgba(255,255,255,.85); }

.ops-tools { display: flex; align-items: center; gap: 8px; }
.ops-search {
  display: flex; align-items: center; gap: 6px; height: 38px; padding: 0 6px 0 11px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-sm); min-width: min(320px, 60vw);
}
.ops-search:focus-within { border-color: var(--tb-blue); }
.ops-search-icon { display: flex; color: var(--tb-muted); flex: none; }
.ops-search input {
  border: 0; background: none; font: inherit; height: 100%; flex: 1 1 auto;
  min-width: 0; color: var(--tb-ink);
}
.ops-search input:focus { outline: none; }
.ops-clear { font-size: .85rem; color: var(--tb-muted-strong); white-space: nowrap; }

.ops-filter { position: relative; }
.ops-filter > summary,
.ops-menu > summary {
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  list-style: none; border-radius: var(--tb-radius-sm); color: var(--tb-muted-strong);
  border: 1px solid var(--tb-line); background: var(--tb-surface-solid);
}
.ops-filter > summary { width: 38px; height: 38px; }
.ops-filter > summary::-webkit-details-marker,
.ops-menu > summary::-webkit-details-marker { display: none; }
.ops-filter > summary:hover, .ops-menu > summary:hover { border-color: var(--tb-line-strong); }
.ops-filter[open] > summary { border-color: var(--tb-blue); color: var(--tb-blue); }
.ops-filter-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; width: 260px;
  display: flex; flex-direction: column; gap: 6px; padding: 14px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md); box-shadow: var(--tb-shadow-md);
}
.ops-filter-h { margin: 0 0 2px; font-weight: 650; font-size: .92rem; }
.ops-filter-panel label {
  font-size: .78rem; font-weight: 600; color: var(--tb-muted-strong); margin-top: 4px;
}
.ops-filter-panel select, .ops-filter-panel input {
  height: 38px; padding: 0 9px; font: inherit; color: var(--tb-ink);
  border: 1px solid var(--tb-line); border-radius: var(--tb-radius-sm);
  background: var(--tb-surface-solid);
}
.ops-filter-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 10px; }

/* ---- the table --------------------------------------------------------- */

/* No scroll box on a wide screen, for the same reason: a menu absolutely
 * positioned inside one is cut off at its edge. The page scrolls instead, and
 * the sticky header sticks to the top of the window rather than to the top of
 * a box, which is the same thing to look at.
 *
 * Narrow screens do get one back, further down, where the menus are fixed to
 * the bottom of the window and so cannot be clipped by it. */
.ops-table-wrap { overflow: visible; }
.ops-table { width: 100%; border-collapse: collapse; background: var(--tb-surface-solid); }
.ops-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--tb-surface-soft); text-align: left;
  font-size: .72rem; font-weight: 650; letter-spacing: .07em; text-transform: uppercase;
  color: var(--tb-muted-strong); padding: 11px 14px; white-space: nowrap;
  border-bottom: 1px solid var(--tb-line);
}
.ops-table thead th.r { text-align: right; }
.ops-table tbody td {
  padding: 0 14px; height: 55px; border-bottom: 1px solid #eef3fa;
  vertical-align: middle;
}
.ops-table tbody tr:last-child td { border-bottom: 0; }
.ops-table tbody tr:hover { background: #f7fafe; }
.ops-table td.r { text-align: right; }
.ops-fig { font-variant-numeric: tabular-nums; }
.ops-net { font-weight: 650; }
.ops-date { color: var(--tb-muted-strong); font-size: .89rem; white-space: nowrap; }
.ops-num { white-space: nowrap; }
.ops-num a { font-weight: 650; }
.ops-tag {
  margin-left: 7px; font-size: .68rem; font-weight: 650; text-transform: uppercase;
  letter-spacing: .05em; color: var(--tb-amber); background: var(--tb-amber-soft);
  border-radius: 5px; padding: 1px 5px; vertical-align: middle;
}
.ops-pill {
  display: inline-block; font-size: .78rem; font-weight: 600; border-radius: 999px;
  padding: 2px 10px;
}
.ops-pill-quiet { color: var(--tb-muted); background: #f1f5fa; }

.ops-actions { width: 48px; text-align: right; }
.ops-table td.ops-actions:has(.ops-links) { width: auto; white-space: nowrap; }
.ops-menu { position: relative; display: inline-block; }
.ops-menu > summary { width: 32px; height: 32px; border-color: transparent; }
.ops-menu-panel {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; width: 180px;
  display: flex; flex-direction: column; padding: 6px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md); box-shadow: var(--tb-shadow-md);
}
.ops-menu-panel a {
  padding: 8px 10px; border-radius: 8px; color: var(--tb-ink-soft); font-size: .9rem;
}
.ops-menu-panel a:hover { background: var(--tb-blue-soft); color: var(--tb-blue-dark); text-decoration: none; }

/* ---- nothing to show --------------------------------------------------- */

.ops-empty-row td { height: auto; padding: 0; }
.ops-empty { text-align: center; padding: 62px 20px; }
.ops-empty-title { margin: 0; font-size: 1.1rem; font-weight: 650; }
.ops-empty-note { margin: 6px 0 16px; color: var(--tb-muted-strong); }
.ops-empty-span { display: block; font-size: .87rem; margin-top: 4px; }
.ops-foot {
  margin: 0; padding: 12px 16px; border-top: 1px solid var(--tb-line);
  color: var(--tb-muted); font-size: .85rem; background: var(--tb-surface-soft);
}

/* ---- narrower ---------------------------------------------------------- */

@media (max-width: 1180px) {
  .ops-summary { grid-template-columns: repeat(3, 1fr); }
  .ops-metric:nth-child(4) { border-left: 0; }
  .ops-metric { border-top: 1px solid var(--tb-line); }
  .ops-summary > .ops-metric:nth-child(-n+3) { border-top: 0; }
  .ops-rail { overflow-x: auto; }
  .ops-search { min-width: 220px; }
}

@media (max-width: 780px) {
  /* Wide tables scroll sideways here. Safe now, because every menu below this
   * width is fixed to the bottom of the window rather than floated beside its
   * button, and a fixed element is not clipped by an ancestor's overflow. */
  .ops-table-wrap { overflow-x: auto; }
  .ops-head { align-items: flex-start; }
  .ops-head-actions { width: 100%; }
  .ops-head-actions .btn, .ops-period { flex: 1 1 auto; justify-content: center; }
  .ops-summary { grid-template-columns: repeat(2, 1fr); }
  .ops-metric:nth-child(odd) { border-left: 0; }
  .ops-metric:nth-child(3) { border-left: 1px solid var(--tb-line); }
  .ops-metric-value { font-size: 1.25rem; }
  .ops-tools { width: 100%; }
  .ops-search { flex: 1 1 auto; min-width: 0; }
  /* Whatever names the row -- a statement number, a unit, a person -- stays put
   * while the money scrolls past it. A row that scrolls away from its own name
   * is a row of numbers about nobody. Written once here for every ops table;
   * it lived three times over, once per page, and two of those copies were
   * scoped so tightly they only ever applied to one of them. */
  .ops-table th:first-child, .ops-table td:first-child {
    position: sticky; left: 0; background: var(--tb-surface-solid); z-index: 1;
  }
  .ops-table thead th:first-child { z-index: 3; background: var(--tb-surface-soft); }
  .ops-table tbody tr:hover td:first-child { background: #f7fafe; }
  /* The row menu joins the others at the bottom of the window. Left floating
   * beside its button it would be clipped by the sideways scroll box above. */
  .ops-menu-panel {
    position: fixed; inset: auto 12px 12px; width: auto; max-height: 70vh;
    overflow-y: auto; z-index: 60;
  }
  /* 44px minimum on anything a thumb has to find. */
  .ops-menu > summary { width: 44px; height: 44px; }
  .ops-chip { height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  .ops-2030 * { transition: none !important; animation: none !important; }
}

/* ---- shared additions: things Fleet needed that Driver pay had no use for -- */

/* A rail of figures rather than filters. Same surface, no link affordances,
 * because these five describe the fleet and do not narrow it. */
.ops-summary-plain .ops-metric { cursor: default; }
.ops-summary-plain .ops-metric:hover { background: none; }

.ops-attention {
  display: flex; align-items: stretch; gap: 0; flex-wrap: wrap;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-lg); box-shadow: var(--tb-shadow-sm);
  margin-bottom: var(--ops-gap); overflow: hidden;
}
.ops-worry {
  display: flex; align-items: center; gap: 11px; padding: 14px 20px;
  flex: 1 1 320px; min-width: 0;
}
.ops-worry-split { width: 1px; background: var(--tb-line); flex: none; }
.ops-worry-icon { display: flex; flex: none; }
.ops-worry-warn  .ops-worry-icon { color: var(--tb-amber); }
.ops-worry-quiet .ops-worry-icon { color: var(--tb-muted-strong); }
.ops-worry-ok    .ops-worry-icon { color: var(--tb-green); }
.ops-worry-text {
  flex: 1 1 auto; min-width: 0; color: var(--tb-ink-soft); font-size: .93rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ops-worry-action { font-size: .9rem; font-weight: 600; white-space: nowrap; flex: none; }

/* The drawer. <details> because the app serves no JavaScript -- it opens and
 * closes from the keyboard on its own, which a div listening for clicks would
 * not. On a failed save the server re-renders it open, holding what was typed. */
.ops-drawer { position: relative; }
.ops-drawer > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px;
}
.ops-drawer > summary::-webkit-details-marker { display: none; }
.ops-drawer-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; width: 340px;
  display: flex; flex-direction: column; gap: 5px; padding: 18px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md); box-shadow: var(--tb-shadow-md);
  text-align: left;
}
.ops-drawer-h { margin: 0 0 6px; font-size: 1.02rem; font-weight: 650; }
.ops-drawer-panel label {
  font-size: .79rem; font-weight: 600; color: var(--tb-muted-strong); margin-top: 7px;
}
.ops-opt { font-weight: 500; color: var(--tb-muted); text-transform: none; }
.ops-drawer-panel input, .ops-drawer-panel select {
  height: 40px; padding: 0 10px; font: inherit; color: var(--tb-ink);
  border: 1px solid var(--tb-line); border-radius: var(--tb-radius-sm);
  background: var(--tb-surface-solid); width: 100%;
}
.ops-drawer-panel input[aria-invalid="true"] { border-color: var(--tb-red); }
.ops-drawer-err {
  margin: 5px 0 0; font-size: .84rem; color: var(--tb-red); font-weight: 550;
}
.ops-drawer-note {
  margin: 12px 0 0; font-size: .82rem; line-height: 1.5; color: var(--tb-muted-strong);
  background: var(--tb-surface-soft); border-radius: var(--tb-radius-sm); padding: 10px 12px;
}
.ops-drawer-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }

/* A toolbar with a title in it, rather than chips alone. */
.ops-toolbar-title h2 { font-size: 1.12rem; font-weight: 650; }
.ops-toolbar-sub { margin: 2px 0 0; font-size: .86rem; color: var(--tb-muted); }
.ops-chips-row {
  padding: 0 16px 14px; border-bottom: 1px solid var(--tb-line);
}

/* Sortable headers. The whole label is the target, so the hit area matches
 * what looks clickable. */
.ops-sort {
  color: inherit; text-decoration: none; display: inline-block;
  white-space: nowrap;
}
.ops-sort:hover { color: var(--tb-blue); text-decoration: none; }
.ops-sort.is-on { color: var(--tb-blue-dark); }

/* ---- the fleet table --------------------------------------------------- */

/* Shared, not fleet-only. Three pages put a second line under the first cell
 * -- a truck's nickname, a settlement's payer, where a candidate came from --
 * and while these were scoped to .fleet-2030 the other two ran the two lines
 * together: "Michael CruzIndeed". */
.ops-2030 .ops-unit { white-space: nowrap; }
.ops-2030 .ops-nick {
  display: block; font-size: .8rem; color: var(--tb-muted); margin-top: 1px;
}
.ops-status {
  display: inline-flex; align-items: center; gap: 7px; font-size: .89rem;
  color: var(--tb-ink-soft); white-space: nowrap;
}
.ops-status-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ops-status-active   .ops-status-dot { background: var(--tb-green); }
.ops-status-inactive .ops-status-dot { background: var(--tb-amber); }
.ops-status-retired  .ops-status-dot { background: var(--tb-muted); }

.ops-own { font-size: .88rem; color: var(--tb-ink-soft); }
/* Outlined rather than filled: it is a gap to fill in, not an alarm. */
.ops-own-missing {
  display: inline-block; padding: 1px 9px; border-radius: 999px;
  border: 1px solid var(--tb-amber); color: var(--tb-amber);
  font-size: .8rem; font-weight: 600;
}

.ops-contrib { font-weight: 650; }
.ops-contrib.is-up   { color: var(--tb-green); }
.ops-contrib.is-down { color: var(--tb-red); }
.ops-contrib.is-flat { color: var(--tb-muted); }

/* Warm and very light. Enough to find the row, not enough to read as a fault. */
.ops-row-idle { background: #fffbf3; }
.ops-table tbody tr.ops-row-idle:hover { background: #fff6e8; }

@media (max-width: 1180px) {
  .ops-attention { flex-direction: column; }
  .ops-worry-split { width: auto; height: 1px; }
}

@media (max-width: 780px) {
  .ops-drawer, .ops-drawer > summary { width: 100%; justify-content: center; }
  /* Near enough full-screen on a phone, where a 340px panel floating over the
   * page would be most of the page anyway. */
  .ops-drawer-panel {
    position: fixed; inset: auto 12px 12px; width: auto; max-height: 82vh;
    overflow-y: auto; z-index: 60;
  }
  /* The sticky first cell keeps the row's own tint. Settlements dims a
   * discarded row the same way, so this is not fleet's alone either. */
  .ops-table tbody tr.ops-row-idle td:first-child { background: #fffbf3; }
}

/* ---- settlements ------------------------------------------------------- */

/* Words, not just colours: "Does not reconcile" and "Ready" have to be
 * distinguishable in a screenshot printed in black and white. */
.ops-state {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: .8rem; font-weight: 600; white-space: nowrap;
}
.ops-state-ok    { color: var(--tb-green); background: var(--tb-green-soft); }
.ops-state-info  { color: var(--tb-blue-dark); background: var(--tb-blue-soft); }
.ops-state-warn  { color: var(--tb-amber); background: var(--tb-amber-soft); }
.ops-state-bad   { color: var(--tb-red); background: var(--tb-red-soft); }
.ops-state-quiet { color: var(--tb-muted); background: #f1f5fa; }

.ops-2030 .ops-span {
  white-space: nowrap; font-size: .89rem; color: var(--tb-muted-strong);
  font-variant-numeric: tabular-nums;
}


/* ---- hiring ------------------------------------------------------------ */

.hiring-2030 .hire-reach { white-space: nowrap; }
.hire-tel {
  display: inline-flex; align-items: center; gap: 6px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.hire-mail {
  display: block; font-size: .8rem; color: var(--tb-muted-strong); margin-top: 1px;
}
.hire-note {
  color: var(--tb-muted-strong); font-size: .88rem;
  max-width: 26rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hire-update {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; width: 250px;
  display: flex; flex-direction: column; gap: 6px; padding: 14px; text-align: left;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md); box-shadow: var(--tb-shadow-md);
}
.hire-update label {
  font-size: .78rem; font-weight: 600; color: var(--tb-muted-strong);
}
.hire-update textarea {
  font: inherit; padding: 7px 9px; border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-sm); resize: vertical;
}
.hire-set {
  margin: 6px 0 0; font-size: .78rem; font-weight: 600; color: var(--tb-muted-strong);
}
.hire-states { display: flex; flex-wrap: wrap; gap: 5px; }
.hire-states .btn { padding: 0 9px; height: 30px; font-size: .82rem; }

@media (max-width: 780px) {
  /* Wide enough to hit with a thumb, and the note is the point of it. */
  .hire-update { position: fixed; inset: auto 12px 12px; width: auto; max-height: 78vh;
    overflow-y: auto; z-index: 60; }
  .hire-states .btn { height: 40px; }
  .hire-note { max-width: 12rem; }
}

/* Call it or text it, side by side. The number is the call, because that is
 * what a phone number looks like it does. */
.hire-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.hire-sms {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .82rem; font-weight: 600; color: var(--tb-muted-strong);
  white-space: nowrap;
}
.hire-sms:hover { color: var(--tb-blue); text-decoration: none; }

@media (max-width: 780px) {
  /* Both are thumb targets on a phone, which is where this list gets worked. */
  .hire-tel, .hire-sms { min-height: 44px; }
}

/* The Text button opens a short menu of what to send. <details>, like every
 * other menu here, because the app serves no JavaScript. */
.hire-texts { position: relative; }
.hire-texts > summary { list-style: none; cursor: pointer; }
.hire-texts > summary::-webkit-details-marker { display: none; }
.hire-texts[open] > summary { color: var(--tb-blue); }
.hire-texts-panel {
  position: absolute; left: 0; top: calc(100% + 5px); z-index: 30; width: 290px;
  display: flex; flex-direction: column; padding: 6px;
  background: var(--tb-surface-solid); border: 1px solid var(--tb-line);
  border-radius: var(--tb-radius-md); box-shadow: var(--tb-shadow-md);
  white-space: normal;
}
.hire-texts-panel a {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
  border-radius: 8px; color: var(--tb-ink-soft);
}
.hire-texts-panel a:hover { background: var(--tb-blue-soft); text-decoration: none; }
.hire-texts-panel strong { font-size: .88rem; font-weight: 650; }
/* Two lines of the message itself, so the label is not the only thing telling
 * you what is about to be sent to a stranger. */
.hire-texts-panel span {
  font-size: .78rem; color: var(--tb-muted); line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.hire-blank { font-size: .84rem; border-top: 1px solid var(--tb-line); margin-top: 4px; }

@media (max-width: 780px) {
  .hire-texts-panel { position: fixed; inset: auto 12px 12px; width: auto;
    max-height: 70vh; overflow-y: auto; z-index: 60; }
}

/* The address is the button that opens the email menu. */
.hire-mail-btn {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  list-style: none; font-size: .8rem; color: var(--tb-muted-strong);
  margin-top: 1px; max-width: 22rem; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
.hire-mail-btn::-webkit-details-marker { display: none; }
.hire-mail-btn:hover { color: var(--tb-blue); }
.hire-emails[open] > .hire-mail-btn { color: var(--tb-blue); }
.hire-emails .hire-texts-panel { width: 330px; }

/* An open menu sits above the rows under it, and above a menu further down the
 * table. Without the second rule a menu opened on an early row is drawn under
 * the rows that follow, which is the same overlap by a different route. */
.ops-table tbody tr:has(details[open]) { position: relative; z-index: 40; }

/* When somebody was last reached, above whatever note was written about them. */
.hire-last {
  display: block; font-size: .78rem; font-weight: 600;
  color: var(--tb-muted-strong); margin-bottom: 1px;
}

/* The camera button. A file input styled as a button, because a file input is
 * how a phone opens its camera without any JavaScript to ask it to. */
.ops-shoot { display: flex; align-items: center; gap: 8px; }
.ops-shoot label { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.ops-shoot input[type="file"] {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.ops-shoot label:focus-within { outline: 2px solid var(--tb-blue); outline-offset: 2px; }

/* What the model says it read, above the fields it filled in. Blue rather than
 * green: it is a claim to be checked, not a result. */
.ops-read {
  margin: 0 0 4px; padding: 9px 11px; font-size: .82rem; line-height: 1.5;
  color: var(--tb-blue-dark); background: var(--tb-blue-soft);
  border-radius: var(--tb-radius-sm);
}

/* Click anywhere to close a menu.
 *
 * A <details> only closes from its own summary, so an open menu sat there
 * until you went back and clicked Text a second time. Giving the open summary
 * a full-screen pseudo-element means a click anywhere else lands on the
 * summary and toggles it shut -- which is what a menu is expected to do, and
 * needs no JavaScript to do it.
 *
 * z-index 10 puts it under every panel (20 and up) and over the page, so the
 * links inside the menu still take their own clicks. */
.ops-menu[open] > summary::before,
.ops-drawer[open] > summary::before,
.ops-filter[open] > summary::before,
.hire-texts[open] > summary::before {
  content: ""; position: fixed; inset: 0; z-index: 10; cursor: default;
}

/* ---- one person -------------------------------------------------------- */
/* Shared with the People list, so it lives on .ops-2030 and not on the page
   class: a rule scoped to one page is the bug that ran "Michael CruzIndeed"
   together on another. */
.ops-2030 .person-link { color: inherit; text-decoration: none; }
.ops-2030 .person-link:hover strong { text-decoration: underline; }

.person-2030 .person-facts {
  display: grid; gap: 2px 28px; margin: 0; padding: 16px 20px;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.person-2030 .person-fact dt {
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--tb-muted); margin: 0 0 2px;
}
.person-2030 .person-fact dd { margin: 0 0 12px; font-size: 15px; }

.person-2030 .person-do {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding: 0 20px 16px;
}
.person-2030 .person-do select { min-width: 260px; max-width: 100%; }
.person-2030 .person-do form { margin: 0; }
/* Page-own class names, not scoped overrides of shared ones: a rule written as
   `.person-2030 .ops-panel` would be invisible to every other page that later
   needed the same spacing. */
.person-2030 { display: flex; flex-direction: column; gap: 18px; }
.person-2030 .person-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* ---- the one nav item that opens ---------------------------------------- */
/* Setup holds six pages. They used to be tabs across the top of a page you had
   to reach before you could see them, which meant the way to Preferences was
   to go to Drivers first. A <details> opens in place with no script, which is
   the only kind of menu this app can have. */
.nav-sub > summary {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--tb-radius-sm); cursor: pointer;
  color: var(--tb-ink-soft); font-weight: 500; font-size: .9rem;
  min-height: 40px; list-style: none;
  transition: background 150ms ease, color 150ms ease;
}
.nav-sub > summary .ic { flex: none; opacity: .72; }
.nav-sub > summary:hover .ic { opacity: 1; }
.nav-sub > summary::-webkit-details-marker { display: none; }
.nav-sub > summary::marker { content: ""; }
.nav-sub > summary:hover { background: rgba(255, 255, 255, .7); color: var(--tb-ink); }
.nav-sub > summary > span:first-of-type { flex: 1; }

.nav-caret { display: flex; transition: transform .15s ease; color: var(--tb-muted); }
.nav-sub[open] .nav-caret { transform: rotate(90deg); }

/* Indented under the parent, and hung off a hairline so the group reads as
   one thing rather than as six more top-level pages. */
.nav-under {
  margin: 2px 0 4px 19px; padding-left: 11px;
  border-left: 1px solid var(--tb-line);
}
.nav-under a { padding: 6px 10px; font-size: .86rem; }
.nav-count {
  margin-left: auto; font-size: .72rem; font-weight: 600; color: var(--tb-muted);
  background: rgba(16, 24, 40, .06); border-radius: 20px; padding: 1px 7px;
}

/* ---- a driver's own pay ------------------------------------------------- */
/* The whole app, for the person it is about. Wider than it needs to be on a
   desk and readable on the phone it will actually be opened on. */
.mine-2030 { display: flex; flex-direction: column; gap: 18px; }
.mine-2030 .mine-year {
  display: grid; gap: 2px 28px; margin: 0; padding: 4px 20px 18px;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
}
.mine-2030 .mine-fact dt {
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--tb-muted); margin: 0 0 3px;
}
.mine-2030 .mine-fact dd { margin: 0; font-size: 20px; font-weight: 650; }
.mine-2030 .mine-do { display: flex; gap: 8px; justify-content: flex-end; }

/* ---- the fleet table's total line --------------------------------------- */
/* Set apart from the rows without being another row: it is the same figures
   added up, not another truck. */
.fleet-command-center .row-total > * {
  border-top: 2px solid var(--fcc-line);
  padding-top: 11px; font-weight: 700; background: var(--fcc-surface-2, transparent);
}
.fleet-command-center .row-total th {
  text-align: left; font-size: .78rem; letter-spacing: .05em;
  text-transform: uppercase; color: var(--fcc-ink-2);
}
/* Why the total under the table is not the number in the tile above it. Left
   in plain words rather than a footnote marker nobody clicks. */
.fleet-command-center .panel-note {
  margin: 9px 0 0; font-size: .75rem; line-height: 1.5; color: var(--fcc-ink-2);
}

/* ---- the mileage question ----------------------------------------------- */
/* Read as a sentence rather than a row of figures: somebody deciding whether
   828 miles is right is answering a question, not reading a report. */
/* The sentence is allowed to wrap where the rest of the row is not: it is
   the question itself, and cutting it off would cut off the reasoning. */
.ops-2030 .high-ask { line-height: 1.5; white-space: normal; max-width: none; }
.ops-2030 .high-ask .muted { display: block; margin-top: 2px; }
.ops-2030 .empty-answer {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  justify-content: flex-end; margin: 0;
}
.ops-2030 .empty-answer input[type="text"] {
  padding: 5px 9px; border: 1px solid var(--tb-line); border-radius: 7px;
  font-size: .84rem; min-width: 90px;
}

/* ---- the run between two loads ------------------------------------------ */
/* Set back from the hauls either side: this is not a line of the statement and
   must never read as one. It is the office working out whether a deadhead has
   been counted; the driver's copy does not carry it. */
tr.lane-gap td {
  background: #fbfaf7; color: var(--tb-muted);
  border-top: 1px dashed var(--tb-line); border-bottom: 1px dashed var(--tb-line);
  padding-top: 6px; padding-bottom: 6px;
}
tr.lane-gap .muted { display: block; font-size: .96em; }

/* ---- picking several statements ----------------------------------------- */
/* The column is narrow and the box is the whole cell's worth of target: a
   tickbox you have to aim at is one somebody mis-clicks, and mis-clicking here
   adds a driver's pay to a batch of outgoing email. */
.ops-table th:first-child:has(.sr-only),
.ops-table td.ops-pick { width: 38px; }
.ops-table td.ops-pick { padding-left: 14px; }
.ops-table td.ops-pick input[type="checkbox"] {
  width: 17px; height: 17px; cursor: pointer; accent-color: var(--tb-blue);
}
.ops-bulk {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; border-top: 1px solid var(--tb-line);
  background: var(--tb-blue-soft);
}
.ops-bulk-note { flex: 1 1 260px; font-size: .78rem; color: var(--tb-ink-soft); }

/* ---- row actions, out in the open --------------------------------------- */
/* These were behind a three-dot menu, and a menu with no script cannot close
   itself when you pick something from it. Two of the three navigate, so they
   looked fine; Download PDF does not navigate -- the file arrives and the page
   never changes -- so the menu sat there open, having done its job, looking
   like it had not.
   Three short words fit where the dots were. Nothing to open, nothing to
   close, and one fewer click to reach any of them. */
.ops-actions .ops-links {
  display: inline-flex; gap: 10px; align-items: center; justify-content: flex-end;
}
.ops-actions .ops-links a {
  font-size: .78rem; font-weight: 550; color: var(--tb-blue);
  text-decoration: none; white-space: nowrap;
}
.ops-actions .ops-links a:hover { text-decoration: underline; }

/* A gap that earns nothing is still worth seeing: "no layover owed" and
   "nobody looked" are different answers, and an empty panel said both. Quieter
   than the ones that pay, and carrying its own reason. */
tr.gap-nil td { color: var(--tb-muted); background: #fcfcfd; }

/* ---- applied before ------------------------------------------------------ */
/* Nineteen arrive at once and each is a glance, so every row is one line. The
   buttons were stacking because they sat in the 48px actions column meant for
   a three-dot menu; here they get the room they need and nothing wraps. */
.again-row td { padding-top: 7px; padding-bottom: 7px; vertical-align: middle; }
.again-who strong { display: block; font-size: .9rem; line-height: 1.3; }
.again-who span { font-size: .78rem; color: var(--tb-muted); }
.again-was, .again-when { white-space: nowrap; font-size: .8rem; }
.again-was .muted { margin-left: 5px; }
.again-note {
  font-size: .82rem; color: var(--tb-ink-soft);
  max-width: 26ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.again-do { text-align: right; white-space: nowrap; width: 1%; }
.again-do form { display: inline-flex; gap: 6px; margin: 0; }
.again-do .btn { padding: 4px 10px; font-size: .78rem; white-space: nowrap; }

/* ---- rows that ask a question ------------------------------------------- */
/* Sixty of these can arrive and each is a glance, so a row is one line. The
   controls were stacking inside the 48px actions column meant for a three-dot
   menu; here they get the width they need and nothing wraps. */
.ask-row td { padding-top: 7px; padding-bottom: 7px; vertical-align: middle; }
.ask-who strong { display: block; font-size: .88rem; line-height: 1.3; }
.ask-who span { font-size: .76rem; color: var(--tb-muted); white-space: nowrap; }
.ask-run {
  font-size: .82rem; max-width: 44ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ask-run .muted { margin-left: 6px; font-size: .95em; }
.ask-miles { font-variant-numeric: tabular-nums; font-weight: 620; white-space: nowrap; }
.ask-do { text-align: right; white-space: nowrap; width: 1%; }
.ask-do form { display: inline-flex; flex-wrap: nowrap; gap: 5px; align-items: center; margin: 0; }
.ask-do .btn { padding: 4px 9px; font-size: .76rem; white-space: nowrap; }
.ask-do input[type="text"] {
  padding: 4px 7px; border: 1px solid var(--tb-line); border-radius: 6px;
  font-size: .76rem;
}

/* Miles that have run and not yet been paid for. The rate leaves them out --
   dividing by miles with no money against them describes a month that has not
   finished arriving, not a bad one -- and the dot says the two columns are
   covering different loads. */
.fleet-command-center .waiting {
  color: var(--fcc-blue); font-weight: 700; margin-left: 3px; cursor: help;
}

.again-pick { width: 34px; text-align: center; }
.again-pick input { width: 16px; height: 16px; cursor: pointer; }

/* Miles and truck typed straight into a draft's table.
   Sized to the number they hold rather than to the column: a 4-digit mileage
   box that stretches to the full width of a cell reads as a search field, and
   the row stops scanning as a row. */
.cell-num { width: 74px; text-align: right; padding: 3px 5px; }
td select[name^="truck-"] { width: 78px; padding: 3px 4px; }
