/* ============================================================
   Artemis TMS — THEME (CONSOLIDATED + DENSE STAFF TABLE LAYOUT)
   - Removes conflicting “boxed-in” gutters
   - Staff pages default wide/dense (tables-first)
   - Portals remain scoped + mobile-safe
   ============================================================ */

/* ============================================================
   TOKENS
   ============================================================ */
:root {
    /* Phase 0.2 (DECISIONS 2026-05-28): ALL legacy --tms-* vars retired.
       Rules consume modern tokens.css. Button rules live below; class names
       unchanged (alias-not-rename per lock #1). */
}

/* ============================================================
   APP FRAME
   ============================================================ */
/* Header (remove inline styles; keep dense enterprise bar) */
.tms-header {
    padding: 10px 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-weight: 600;
    background: #f3f3f3;
    border-bottom: 1px solid #c2c2c2;
}

.tms-header-left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.tms-header-user {
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tms-header-logout {
    margin: 0;
}

.tms-header-logout-btn {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 12px;
}
   body {
    color: var(--text-primary);
    font-size: 14px;
    font-family: var(--font-sans);
}

.tms-brand-link {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    text-decoration: none;
}

.tms-brand-logo {
    display: block;
    width: 120px;
    height: auto;
}

.tms-header-left {
    display: flex;
    align-items: center;
    gap: 12px;
}

.tms-header {
    height: 52px;
}

/* STAFF DEFAULT: wide/dense container (tables-first) */
.content-wrapper {
    max-width: none;
    margin: 12px 12px;
    /* tighter side gutters */
    padding: 16px 16px;
    /* tighter inner padding */
    background-color: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    box-sizing: border-box;
}

/* Desktop: even denser */
@media (min-width: 1100px) {
    .content-wrapper {
        margin: 10px 8px;
        padding: 14px 14px;
    }
}

/* Large desktop: max density (use the screen) */
@media (min-width: 1400px) {
    .content-wrapper {
        margin: 8px 6px;
        padding: 12px 12px;
    }
}

.tms-breadcrumb-row {
    margin-top: 4px;
    margin-bottom: var(--space-2);
}

.muted {
    color: #666;
}

/* ============================================================
   PAGE HEADER
   ============================================================ */
.tms-page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-3);
}

.tms-page-title {
    font-size: 1rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    /* Neutralize browser-default <h1> margins now that the page title is a
       semantic <h1> (SEMANTIC-PAGE-HEADINGS). Visual output unchanged. */
    margin: 0;
}

/* Non-canonical reuse of the page-title look (panel sub-headings that are NOT
   the page's main <h1> — e.g. dispatch topbar, lane-quote panel). Visually
   identical to .tms-page-title; split out so those sites don't become a second
   <h1> on the page (SEMANTIC-PAGE-HEADINGS double-h1 guard). */
.tms-panel-title {
    font-size: 1rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.tms-page-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* Form-page action rows: isolate the destructive Delete at the right edge,
   separated from Cancel so it can't be fat-fingered (locked button order).
   Scoped to .tms-load-form-page so the shared list-toolbar actions are untouched;
   the only .tms-btn-danger in a form action row is the Delete button. */
.tms-load-form-page .tms-page-actions .tms-btn-danger {
    margin-left: var(--space-5);
}

/* ============================================================
   TABLES (ENTERPRISE GRID)
   ============================================================ */
.tms-table {
    width: 100%;
    border-collapse: collapse;
}

.tms-table thead th {
    background-color: #d6d6d6;
    border-bottom: 1px solid var(--border-strong);
    padding: 6px 8px;
    text-align: left;

    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.tms-table thead th a,
.tms-table thead th a:visited {
    color: var(--text-primary);
    text-decoration: none;
}

.tms-table thead th a:hover {
    text-decoration: underline;
}

.tms-table tbody td {
    padding: 6px 8px;
    border-bottom: 1px solid #e1e1e1;
    font-size: 0.85rem;
}

.tms-table tbody tr:nth-child(odd) {
    background-color: var(--surface-card);
}

.tms-table tbody tr:nth-child(even) {
    background-color: #f7f7f7;
}

.tms-table tbody tr:hover {
    background-color: #ececec;
}

.tms-table-row-clickable {
    cursor: pointer;
}

/* ============================================================
   SORTABLE TABLE HEADERS
   ============================================================ */
.tms-sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.tms-sortable::after {
    content: "";
    margin-left: 4px;
    font-size: 0.7em;
}

.tms-sortable.tms-sort-asc::after {
    content: "▲";
}

.tms-sortable.tms-sort-desc::after {
    content: "▼";
}

/* ============================================================
   DISPATCH BOARD — DATE GROUP SEPARATORS
   ============================================================ */
.tms-table tr.dispatch-date-row th {
    background-color: #d9d9d9;
    border-top: 2px solid #8f8f8f;
    border-bottom: 2px solid #8f8f8f;

    padding: 7px 10px;
    text-align: left;

    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.8rem;
}

.tms-table tr.dispatch-date-row th span {
    font-weight: 800;
}

.tms-table tr.dispatch-date-row+tr td {
    border-top: 6px solid #f0f0f0;
}

/* Sticky group headers */
.tms-table tr.dispatch-date-row th {
    position: sticky;
    top: 0;
    z-index: 5;
}

/* ============================================================
   FORMS — ENTERPRISE LAYOUT
   ============================================================ */
.tms-form-shell {
    margin-top: var(--space-2);
}

.tms-form-panel {
    border: 1px solid var(--border-default);
    background-color: var(--surface-panel);
    padding: var(--space-4) 20px;
}

.tms-form-panel--spaced {
    margin-top: 12px;
}

.tms-form-grid {
    display: grid;
    grid-template-columns: 140px minmax(0, 1fr);
    column-gap: var(--space-3);
    row-gap: var(--space-2);
    align-items: center;
}

.tms-form-row-label {
    font-size: 0.85rem;
    color: #333;
    text-align: left;
    padding-right: var(--space-2);
    /* WRAP, do not clip. The label column is a fixed 140px (above); with
       `white-space: nowrap` any label wider than that overflowed and ran behind
       its input rather than wrapping — it clipped on the part form and on all
       three work-order-numbering fields before this was fixed globally. Wrapping
       keeps the 140px column (so every existing form's alignment is unchanged)
       and only makes the affected ROW taller; align-items: center on the grid
       keeps the label centred against a taller field row. */
    white-space: normal;
}

.tms-form-row-field {
    width: 100%;
}

.tms-form-row-field input[type="text"],
.tms-form-row-field input[type="number"],
.tms-form-row-field input[type="date"],
.tms-form-row-field input[type="time"],
.tms-form-row-field input[type="tel"],
.tms-form-row-field input[type="email"],
.tms-form-row-field select,
.tms-form-row-field textarea {
    box-sizing: border-box;
    padding: 4px 6px;
    border: 1px solid #b8b8b8;
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
}

.tms-form-row-field input[type="text"],
.tms-form-row-field input[type="number"],
.tms-form-row-field input[type="tel"],
.tms-form-row-field input[type="email"],
.tms-form-row-field select {
    width: 380px;
    max-width: 100%;
}

.tms-form-row-field input[type="date"],
.tms-form-row-field input[type="time"],
.tms-time-select {
    width: 200px;
    max-width: 100%;
}

.tms-form-row-field textarea {
    width: 600px;
    max-width: 100%;
    min-height: 70px;
    resize: vertical;
}

.tms-form-section-title {
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: var(--space-2);
}

.tms-form-actions,
.form-actions.action-bar {
    margin: var(--space-4) 0;
    display: flex;
    justify-content: flex-start;
    gap: var(--space-2);
}

/* Keep load form panels from stretching too wide (intentional) */
.tms-load-form-page .tms-form-shell {
    max-width: 1100px;
}

/* ============================================================
   MODULE WRAP (SUB-PANELS INSIDE A FORM PANEL)
   ============================================================ */
.tms-module-wrap {
    border: 1px solid #c4c4c4;
    background: #ffffff;
}

.tms-module-header {
    padding: 8px 10px;
    background: #f3f3f3;
    border-bottom: 1px solid #c4c4c4;
}

.tms-module-title {
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #222;
}

.tms-module-body {
    padding: 10px;
}

.tms-panel-footer {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid #e1e1e1;
    display: flex;
    justify-content: flex-start;
    gap: 8px;
}

.tms-docs-table thead th {
    background-color: #d6d6d6;
}

.tms-docs-table tbody td {
    vertical-align: middle;
}

/* ============================================================
   BUTTONS — Phase 0.2 (DECISIONS 2026-05-28 "Phase 0.2 button standard locked")
   One global system. tms-btn vocabulary preserved (alias-not-rename per lock #1);
   modern tokens drive colors / spacing / radius / font. The two legacy vars
   deferred from 0.1 (--tms-btn-bg / --tms-btn-border) are fully retired.

   Variants:
     .tms-btn          outline neutral default (--surface-card bg, --border-default)
     .tms-btn-primary  filled --brand-accent, --text-inverse text, weight 600
     .tms-btn-danger   filled --text-danger, --text-inverse text
     .tms-btn-icon     square 28x28 transparent (login password toggle)
     .tms-btn-secondary / .tms-btn-link → aliases of .tms-btn (markup-intent)
   Sizes: default md (8/12, 12px) · .tms-btn-sm (4/8, 12px) · .tms-btn-xs (2/6, 11px)
   Disabled: global rule applies to every variant.
   #content a.tms-btn selectors preserve Django-admin specificity.
   ============================================================ */

.tms-btn,
.tms-btn:link,
.tms-btn:visited,
#content a.tms-btn,
#content a.tms-btn:link,
#content a.tms-btn:visited {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    font-family: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    line-height: 1;
    color: var(--text-primary);
    background-color: var(--surface-card);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    transition: background 0.1s, border-color 0.1s;
}

.tms-btn:hover,
.tms-btn:active,
#content a.tms-btn:hover,
#content a.tms-btn:active {
    background-color: var(--surface-sunken);
    border-color: var(--border-strong);
    color: var(--text-primary);
    text-decoration: none;
}

/* Disabled — single global rule. Applies to every variant via cascade. */
.tms-btn:disabled,
.tms-btn[disabled],
.tms-btn:disabled:hover,
.tms-btn[disabled]:hover {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Sizes */
.tms-btn-sm {
    padding: 4px var(--space-2);
    font-size: var(--text-sm);
}

.tms-btn-xs {
    padding: 2px 6px;
    font-size: var(--text-xs);
    line-height: 1.1;
}

/* Icon-only (used by login password toggle). */
.tms-btn-icon,
.tms-btn-icon:link,
.tms-btn-icon:visited {
    width: 28px;
    height: 28px;
    padding: 0;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-tertiary);
}

.tms-btn-icon:hover,
.tms-btn-icon:active {
    background: var(--surface-sunken);
    border: none;
    color: var(--text-primary);
    text-decoration: none;
}

/* Primary — filled --brand-accent. */
.tms-btn-primary,
.tms-btn-primary:link,
.tms-btn-primary:visited,
#content a.tms-btn-primary,
#content a.tms-btn-primary:link,
#content a.tms-btn-primary:visited {
    background-color: var(--brand-accent);
    border-color: var(--brand-accent);
    color: var(--text-inverse);
    font-weight: 600;
}

.tms-btn-primary:hover,
#content a.tms-btn-primary:hover {
    background-color: var(--brand-navy-600);
    border-color: var(--brand-navy-600);
    color: var(--text-inverse);
}

.tms-btn-primary:active,
#content a.tms-btn-primary:active {
    background-color: var(--brand-navy);
    border-color: var(--brand-navy);
    color: var(--text-inverse);
}

/* Confirm / success — filled colorblind-safe green. MATCHES the dispatch board's
   Confirm-Delivery control (.dispatch-confirm-btn, dispatch.css); both draw the green
   from the shared --btn-confirm-* tokens (tokens.css) so the two can't drift. */
.tms-btn-confirm,
#content a.tms-btn-confirm {
    background-color: var(--btn-confirm-bg);
    border-color: var(--btn-confirm-border);
    color: var(--text-inverse);
    font-weight: 600;
}

.tms-btn-confirm:hover,
#content a.tms-btn-confirm:hover {
    background-color: var(--btn-confirm-bg-hover);
    border-color: var(--btn-confirm-bg-hover);
    color: var(--text-inverse);
}

/* Danger — filled --text-danger. */
.tms-btn-danger,
.tms-btn-danger:link,
.tms-btn-danger:visited,
#content a.tms-btn-danger,
#content a.tms-btn-danger:link,
#content a.tms-btn-danger:visited {
    background-color: var(--text-danger);
    border-color: var(--text-danger);
    color: var(--text-inverse);
}

.tms-btn-danger:hover,
#content a.tms-btn-danger:hover {
    background-color: #b91c1c;
    border-color: #b91c1c;
    color: var(--text-inverse);
}

/* Secondary / link → aliases of .tms-btn (markup intent; no separate rule). */


/* ============================================================
   FILTER / INPUT / BUTTON SPACING
   ============================================================ */
.content-wrapper input[type="text"],
.content-wrapper input[type="number"],
.content-wrapper input[type="date"],
.content-wrapper select {
    margin-right: var(--space-2);
}

.tms-actions,
.tms-filter-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.tms-filter-actions {
    display: flex;
    gap: var(--space-2);
    margin-top: 10px;
    padding-top: 4px;
    width: 100%;
    clear: both;
}

/* ============================================================
   INPUT PREFIX (CURRENCY, ETC.)
   ============================================================ */
.tms-input-with-prefix {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.tms-prefix {
    font-weight: 600;
    font-size: 14px;
    color: #333;
}

/* ============================================================
   NAVIGATION BAR (ENTERPRISE)
   - Tight, dense layout
   - Built-in separators between items
   - Internal Tools gets a stronger divider without double pipes
   ============================================================ */
/* Dropdown behavior */
.tms-nav-item.has-menu {
    position: relative;
}

.tms-nav-menu {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 180px;
    background: #f3f3f3;
    border: 1px solid #c2c2c2;
    padding: 6px 0;
    z-index: 1000;
}

.tms-nav-item.has-menu:hover .tms-nav-menu,
.tms-nav-item.has-menu:focus-within .tms-nav-menu {
    display: block;
}

.tms-nav-menu-link {
    display: block;
    padding: 6px 12px;
    color: #222;
    text-decoration: none;
    white-space: nowrap;
}

.tms-nav-menu-link:hover {
    background: #e9e9e9;
}

.tms-nav {
    background-color: #f3f3f3;
    border-bottom: 1px solid #c2c2c2;
    padding: 6px 16px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

@media (min-width: 1100px) {
    .tms-nav {
        padding: 6px 12px;
    }
}

@media (min-width: 1400px) {
    .tms-nav {
        padding: 6px 10px;
    }
}

.tms-nav-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.tms-nav-left,
.tms-nav-right {
    display: flex;
    align-items: center;
}

/* default spacing + default thin separator between adjacent nav items */
.tms-nav-left>*+*,
.tms-nav-right>*+* {
    margin-left: 24px;
    position: relative;
}

.tms-nav-left>*+*::before,
.tms-nav-right>*+*::before {
    content: "";
    position: absolute;
    left: -12px;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 14px;
    background-color: #c2c2c2;
}

.tms-nav-link,
.tms-nav-link:visited {
    color: #222;
    text-decoration: none;
    font-weight: inherit;
}

.tms-nav-link:hover {
    text-decoration: underline;
}

.tms-logo {
    font-weight: 700;
}

/* ============================================================
   Internal Tools – stronger boundary (no duplicate divider)
   Requires: the Internal Tools wrapper has class "tms-nav-internal"
   ============================================================ */

/* remove the default thin separator immediately before Internal Tools */
.tms-nav-left>.tms-nav-internal::before {
    content: none !important;
}

/* add a stronger divider before Internal Tools */
.tms-nav-left>.tms-nav-internal {
    position: relative;
    margin-left: 28px;
    /* replaces the normal 24px gap */
}

.tms-nav-left>.tms-nav-internal::after {
    content: "";
    position: absolute;
    left: -14px;
    top: 50%;
    transform: translateY(-50%);
    width: 2px;
    height: 18px;
    background-color: #c2c2c2;
}

/* optional: subtle de-emphasis */
.tms-nav-left>.tms-nav-internal .tms-nav-link {
    opacity: 0.9;
}
/* ============================================================
   DROPDOWN MENUS (MATCH NAVBAR TYPOGRAPHY)
   ============================================================ */
.tms-nav-has-menu {
    position: relative;
}

.tms-nav-menu,
.tms-nav-user-menu {
    position: absolute;
    top: 100%;
    right: 0;
    background-color: #ffffff;
    border: 1px solid #c2c2c2;
    min-width: 180px;
    padding: 4px 0;
    display: none;
    z-index: 1000;

    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.tms-nav-has-menu:hover .tms-nav-menu,
.tms-nav-user:hover .tms-nav-user-menu {
    display: block;
}

.tms-nav-menu-link,
.tms-nav-user-menu .tms-nav-link {
    display: block;
    padding: 6px 12px;
    color: #222;
    text-decoration: none;
    font-weight: inherit;
}

.tms-nav-menu-link:hover,
.tms-nav-user-menu .tms-nav-link:hover {
    background-color: #f1f1f1;
}

/* Dropdown: make form/button items match menu links (Logout typography) */
.tms-nav-user-menu form {
    margin: 0;
    padding: 0;
}

.tms-nav-user-menu button {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    border: 0;
    width: 100%;
    text-align: left;

    display: block;
    padding: 6px 12px;

    color: #222;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;

    cursor: pointer;
}

.tms-nav-user-menu button:hover {
    background-color: #f1f1f1;
    text-decoration: none;
}

/* ============================================================
   PORTAL HEADER (DRIVER/EXTERNAL): MOBILE-SAFE LOGOUT BUTTON
   ============================================================ */
.portal-header {
    padding: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
}

.portal-logout-form {
    margin: 0;
}

/* Default: link-style */
.portal-logout-btn {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    cursor: pointer;
    font: inherit;
    color: inherit;
    text-decoration: underline;
}

/* Mobile: button-style (prevents iOS white button) */
@media (max-width: 767.98px) {
    .portal-logout-btn {
        background: var(--surface-card);
        border: 1px solid var(--border-default);
        color: var(--text-primary);
        padding: 3px 10px;
        line-height: 1.4;
        border-radius: var(--radius-sm);
        text-decoration: none;
        font-weight: 600;
    }

    .portal-logout-btn:hover,
    .portal-logout-btn:focus,
    .portal-logout-btn:active {
        background-color: #e6e6e6;
        color: var(--text-primary);
        outline: none;
    }
}

/* ============================================================
   AUTH / LOGIN (FLAT TMS)
   ============================================================ */
html,
body.auth-body {
    height: 100%;
}

body.auth-body {
    margin: 0;
    padding: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0b1120;
    color: #111827;
    font-family: var(--font-sans);
}

body.auth-body .auth-wrapper {
    width: 100%;
    max-width: 440px;
    padding: 24px 16px;
    box-sizing: border-box;
}

body.auth-body .auth-card {
    background: #f3f4f6;
    border: 1px solid #1f2937;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.45);
    padding: 24px 24px 20px 24px;
}

body.auth-body .auth-header {
    text-align: center;
    margin-bottom: 28px;
    margin-top: 6px;
}

body.auth-body .auth-logo {
    display: block;
    margin: 0 auto 12px auto;
    max-width: 180px;
    height: auto;
}

body.auth-body .auth-logo-artemis {
    max-width: 190px;
    margin-bottom: 24px;
}

body.auth-body .auth-title {
    font-size: 1.1rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    margin: 0 0 4px 0;
    color: #4b5563;
}

body.auth-body .auth-subtitle {
    margin: 0;
    font-size: 0.95rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #374151;
    font-weight: 600;
}

body.auth-body .auth-messages {
    margin-bottom: 16px;
}

body.auth-body .auth-message {
    font-size: 0.9rem;
    padding: 6px 8px;
    border-radius: 4px;
    border: 1px solid transparent;
    margin-bottom: 6px;
}

body.auth-body .auth-message-error,
body.auth-body .auth-message-danger {
    background: #fef2f2;
    border-color: #fecaca;
    color: #b91c1c;
}

body.auth-body .auth-message-success {
    background: #ecfdf3;
    border-color: #bbf7d0;
    color: #166534;
}

body.auth-body .auth-message-info {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #1d4ed8;
}

body.auth-body .auth-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

body.auth-body .auth-form-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.9rem;
}

body.auth-body .auth-label {
    font-weight: 500;
    color: #1f2937;
}

body.auth-body .auth-form-field input,
body.auth-body .auth-form-field select,
body.auth-body .auth-form-field textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 6px 8px;
    border-radius: 4px;
    border: 1px solid #9ca3af;
    background: #ffffff;
    color: #111827;
    font-size: 0.9rem;
}

body.auth-body .auth-form-field input:focus,
body.auth-body .auth-form-field select:focus,
body.auth-body .auth-form-field textarea:focus {
    outline: none;
    border-color: #2563eb;
    box-shadow: none;
}

body.auth-body .auth-nonfield-errors {
    margin-bottom: 8px;
    padding: 8px 10px;
    border-radius: 4px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #b91c1c;
    font-size: 0.9rem;
}

body.auth-body .auth-error {
    margin: 0;
    font-size: 0.8rem;
    color: #b91c1c;
}

body.auth-body .auth-form-field.has-error input,
body.auth-body .auth-form-field.has-error select,
body.auth-body .auth-form-field.has-error textarea {
    border-color: #dc2626;
}

body.auth-body .auth-submit {
    margin-top: 10px;
    width: 100%;
    padding: 8px 10px;
    font-size: 0.95rem;
    font-weight: 500;
    border-radius: 4px;
    border: 1px solid #111827;
    background: #111827;
    color: #f9fafb;
    cursor: pointer;
}

body.auth-body .auth-submit:hover {
    background: #020617;
    border-color: #020617;
}

body.auth-body .auth-footer-text {
    margin-top: 12px;
    text-align: center;
    font-size: 0.8rem;
    color: #9ca3af;
}

@media (min-width: 768px) {
    body.auth-body .auth-wrapper {
        max-width: 480px;
        padding: 32px 0;
    }

    body.auth-body .auth-card {
        padding: 28px 28px 22px 28px;
    }
}

/* ============================================================
   DRIVER PORTAL (SCOPED)
   ============================================================ */
.driver-facts {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.driver-fact {
    line-height: 1.45;
    font-size: 14px;
    color: #444;
}

/* ============================================================
   MOBILE (GLOBAL)
   ============================================================ */
@media (max-width: 640px) {
    .content-wrapper {
        margin: 10px 8px !important;
        padding: 12px !important;
        border-radius: 0;
    }

    .tms-nav {
        padding: 6px 8px;
        font-size: 0.75rem;
    }

    .tms-nav-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
    }

    .tms-nav-left,
    .tms-nav-right {
        flex-wrap: wrap;
        gap: 8px;
        width: 100%;
    }

    .tms-nav-left>*::before,
    .tms-nav-right>*::before {
        content: none;
    }

    .tms-nav-link {
        padding: 0 2px;
    }

    .tms-breadcrumb-row {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
    }

    .tms-form-actions,
    .form-actions.action-bar {
        margin: 12px 0;
        display: flex;
        justify-content: flex-start;
        gap: 8px;
    }

    .tms-filter-row {
        display: grid;
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .tms-filter-actions {
        flex-wrap: wrap;
        justify-content: flex-start;
    }

    .tms-table-wrapper {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .tms-table {
        min-width: 700px;
    }

    .tms-table thead th,
    .tms-table tbody td {
        padding: 4px 6px;
        font-size: 0.75rem;
        white-space: nowrap;
    }

    .tms-form-grid {
        grid-template-columns: 1fr;
    }

    .tms-form-row-label {
        text-align: left;
        margin-bottom: 2px;
    }
}

/* ============================================================
   DISPATCH: EDGE-TO-EDGE / TABLE-FIRST (STAFF)
   ============================================================ */
.scope-staff.page-dispatch .content-wrapper {
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
}

/* tighten vertical chrome above the grid */
.scope-staff.page-dispatch .tms-page-header {
    margin: 10px 12px 6px 12px;
}

.scope-staff.page-dispatch .tms-page-subtitle {
    margin-top: 2px;
}

/* keep tabs close to the table */
.scope-staff.page-dispatch .tms-tab-row,
.scope-staff.page-dispatch .tms-subtab-row {
    margin-left: 12px;
    margin-right: 12px;
}

.scope-staff.page-dispatch .tms-divider {
    margin: 6px 12px 10px 12px;
}

/* the actual grid surface */
.scope-staff.page-dispatch .tms-table-wrapper {
    margin: 0 8px 10px 8px;
    background: var(--surface-card);
    border-top: 1px solid var(--border-default);
    border-bottom: 1px solid var(--border-default);
}

/* sticky column headers (below top bars) */
.scope-staff.page-dispatch .tms-table thead th {
    position: sticky;
    top: 76px;
    /* adjust if needed */
    z-index: 6;
}

/* date group headers should stick below thead */
.scope-staff.page-dispatch .tms-table tr.dispatch-date-row th {
    position: sticky;
    top: 104px;
    /* adjust if needed */
    z-index: 5;
}

/* The dispatch row left-rail stripe lives in ONE place — the scoped
   ".scope-staff.page-dispatch" block lower in this file (search
   "Left status rail — SINGLE SOURCE"). The old unscoped base block that
   duplicated it here was deleted 2026-08-06 when the stripe was re-keyed onto
   the derived display status. */
/* ============================================================
   DISPATCH — STATUS BADGE + ACTION BUTTONS (CLEAN / NON-DUPED)
   Goal: badge + buttons INLINE, strong active state, colorblind-safe
   ============================================================ */

/* Status cell: badge + buttons inline and vertically centered */
.dispatch-status-cell {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    vertical-align: middle;
}

/* Action buttons row */
.dispatch-actions {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin: 0;
}

/* Neutral buttons by default */
.dispatch-status-btn {
    border: 1px solid var(--border-default);
    background: #ffffff;
    color: #111;
}

/* Normalize vertical alignment across dispatch rows */
.dispatch-table td {
    vertical-align: middle;
}

.dispatch-driver-cell select {
    vertical-align: middle;
}
/* ============================================================
   DISPATCH: DENSITY PASS (REMOVE WASTED VERTICAL SPACE)
   ============================================================ */

/* kill the giant “card” feeling on dispatch */
.scope-staff.page-dispatch .content-wrapper {
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
}

/* pull content up tight under navbar */
.scope-staff.page-dispatch .tms-page-header {
    margin: 8px 12px 6px 12px !important;
    padding: 0 !important;
}

/* header: make right meta a single row */
.scope-staff.page-dispatch .dispatch-header-meta {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    font-size: 12px;
}

/* remove extra margins on bucket rows */
.scope-staff.page-dispatch .tms-tab-row {
    margin: 6px 12px 4px 12px !important;
}

.scope-staff.page-dispatch .tms-subtab-row {
    margin: 4px 12px 6px 12px !important;
}

/* thinner divider */
.scope-staff.page-dispatch .tms-divider {
    margin: 4px 12px 8px 12px !important;
}

/* grid surface: minimal borders, minimal padding */
.scope-staff.page-dispatch .tms-table-wrapper {
    margin: 0 8px 10px 8px;
    background: var(--surface-card);
    border-top: 1px solid var(--border-default);
    border-bottom: 1px solid var(--border-default);
}

/* section bars: reduce height */
.scope-staff.page-dispatch .dispatch-section-header {
    padding: 4px 10px !important;
    margin-top: 10px !important;
    border-top-width: 1px !important;
}

/* table cells slightly tighter */
.scope-staff.page-dispatch .tms-table thead th,
.scope-staff.page-dispatch .tms-table tbody td {
    padding-top: 5px;
    padding-bottom: 5px;
}
/* DISPATCH HOTFIX: disable sticky header rows (they're causing blank bands) */
.scope-staff.page-dispatch .tms-table thead th,
.scope-staff.page-dispatch .tms-table tr.dispatch-date-row th {
    position: static !important;
    top: auto !important;
}
/* DISPATCH: sticky headers (correct offsets, no blank band) */
.scope-staff.page-dispatch .tms-table thead th {
    position: sticky;
    top: 0;
    z-index: 20;
}

.scope-staff.page-dispatch .tms-table tr.dispatch-date-row th {
    position: sticky;
    top: 32px;
    /* approx one header row height */
    z-index: 19;
}

/* DISPATCH: remove white band above section headers */
.scope-staff.page-dispatch .tms-table-wrapper {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

.scope-staff.page-dispatch .dispatch-table-scroll {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

.scope-staff.page-dispatch .dispatch-section-header {
    margin-top: 0 !important;
}
/* Dispatch date group rows — condensed */
.dispatch-date-row th {
    padding: 4px 8px !important;
    /* was ~8–10px */
    font-size: 0.75rem !important;
    /* smaller than data rows */
    font-weight: 600;
    background-color: #e1e1e1;
    /* lighter than header */
    color: #222;
    border-top: 1px solid #bcbcbc;
    border-bottom: 1px solid #bcbcbc;
}

/* Dispatch date group rows — tight, Excel-like */
.scope-staff.page-dispatch .dispatch-date-row th {
    background: #e0e0e0;
    border-top: 1px solid #9c9c9c;
    border-bottom: 1px solid #9c9c9c;
    padding: 1px 8px !important;
    /* tighter than before */
    font-size: 10.5px !important;
    font-weight: 700;
    text-transform: none !important;
    /* prevent uppercase */
    letter-spacing: 0 !important;
    line-height: 1.2;
}

.scope-staff.page-dispatch .dispatch-date-row th .date-label {
    font-weight: 600;
    color: #444;
    margin-right: 4px;
    text-transform: none !important;
}

.scope-staff.page-dispatch .dispatch-date-row th .date-value {
    font-weight: 600;
    color: #111;
    text-transform: none !important;
}

/* Dispatch: remove the spacer under date group rows */
.scope-staff.page-dispatch .dispatch-date-row+tr td {
    border-top: 0 !important;
}

/* ============================================================
   DISPATCH — ALIGNMENT: BH / PAID / RATE (LEFT, CONSISTENT)
   ============================================================ */

/* Ensure these columns don’t look “detached” on the right */
.dispatch-bh-cell,
.dispatch-paid-cell,
.dispatch-rate-cell {
    text-align: left !important;
    padding-left: 8px;
}

/* Make checkboxes line up visually with text rows */
.dispatch-bh-cell input[type="checkbox"],
.dispatch-paid-cell input[type="checkbox"] {
    margin: 0;
    transform: translateY(1px);
}

/* If you had rate right-aligned anywhere, force left */
.dispatch-rate-cell {
    white-space: nowrap;
}
/* DISPATCH: delivered rows — remove the extra thin rule look */
.dispatch-delivered-table tbody td {
    border-bottom: 0 !important;
}

/* Add a single, calmer separator between delivered rows */
.dispatch-delivered-table tbody tr {
    border-bottom: 1px solid #e6e6e6;
}
/* ============================================================
   DISPATCH — ROW DENSITY + VERTICAL ALIGNMENT (DRIVER/STATUS/BH)
   ============================================================ */

/* Make dispatch rows feel like a tight grid */
.dispatch-table tbody td {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    vertical-align: middle !important;
}

/* Driver select: consistent height and vertical centering */
.dispatch-driver-cell select {
    height: 30px !important;
    line-height: 30px !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Status cell: badge + buttons on one line */
.dispatch-status-cell {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
}

/* Buttons: match row control height */
.dispatch-status-cell .dispatch-actions {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    margin: 0 !important;
    padding: 0 !important;
}

.dispatch-status-cell .dispatch-status-btn {
    box-sizing: border-box !important;
    height: 30px !important;
    line-height: 28px !important;
    /* inside border */
    padding: 0 10px !important;
}
/* Removed 2026-08-06: dead .dispatch-status-badge + .dispatch-status-select
   blocks (badge outline colors, pending-badge fill, pill dropdown). No dispatch
   template or JS renders/writes them — verified repo-wide. */

/* ============================================================
   DISPATCH — kill the “top row” underline under status buttons
   (only affects the first load row in Active)
   ============================================================ */

/* First actual load row (not the date separator row) */
.dispatch-active+.dispatch-table-scroll .dispatch-table tbody tr.dispatch-row:first-of-type .dispatch-status-btn,
.dispatch-active+.dispatch-table-scroll .dispatch-table tbody tr.dispatch-row:first-of-type .dispatch-actions {
    box-shadow: none !important;
    background-image: none !important;
}

/* Also remove any accidental underline decoration on the first row buttons */
.dispatch-active+.dispatch-table-scroll .dispatch-table tbody tr.dispatch-row:first-of-type .dispatch-status-btn {
    text-decoration: none !important;
}
/* ============================================================
   DISPATCH — remove “double line” under first load after date header
   (fixes the phantom thin border you only see on the first row)
   ============================================================ */

/* The date separator row already has its own border; kill the next row's top border */
.dispatch-table tbody tr.dispatch-date-row+tr>td,
.dispatch-table tbody tr.dispatch-date-row+tr>th {
    border-top: 0 !important;
}

/* If any control adds an inset/shadow line, force it off on that first row */
.dispatch-table tbody tr.dispatch-date-row+tr td.dispatch-status-cell *,
.dispatch-table tbody tr.dispatch-date-row+tr td.dispatch-driver-cell *,
.dispatch-table tbody tr.dispatch-date-row+tr td.dispatch-bh-cell * {
    box-shadow: none !important;
}
/* Dispatch: remove the ghost divider line under the FIRST data row after each date row */
.dispatch-table .dispatch-date-row+tr td {
    border-top: 0 !important;
    border-bottom: 0 !important;
    box-shadow: none !important;
}
/* Force logout button visibility on mobile */
.logout-btn {
    color: #dc3545 !important;
    border-color: #dc3545 !important;
}

.logout-btn:hover,
.logout-btn:focus {
    background-color: #dc3545 !important;
    color: #fff !important;
}

@media (max-width: 768px) {
    .navbar .logout-btn {
        color: #dc3545 !important;
    }
}
/* Logout button – consistent across desktop and mobile */
.logout-btn {
    background: transparent;
    color: #dc3545 !important;
    border: 1px solid #dc3545 !important;
    box-shadow: none !important;
}

/* Hover (desktop) */
.logout-btn:hover {
    background-color: #dc3545 !important;
    color: #fff !important;
}

/* Kill bootstrap + mobile focus/active states */
.logout-btn:focus,
.logout-btn:active,
.logout-btn:focus-visible {
    background: transparent !important;
    color: #dc3545 !important;
    outline: none !important;
    box-shadow: none !important;
}

/* Mobile tap highlight (iOS/Android) */
.logout-btn {
    -webkit-tap-highlight-color: transparent;
}

/* Logout should look like other header links (e.g., ADMIN) but be red and consistent on mobile */
.tms-logout-link {
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    cursor: pointer;

    color: #dc3545 !important;
    box-shadow: none !important;
    outline: none !important;
}

/* Kill browser/Bootstrap focus/active artifacts (blue/purple box) */
.tms-logout-link:focus,
.tms-logout-link:active,
.tms-logout-link:focus-visible {
    outline: none !important;
    box-shadow: none !important;
}

/* Prevent mobile navbar link color rules from overriding logout */
@media (max-width: 768px) {
    .navbar .tms-logout-link {
        color: #dc3545 !important;
    }
}
/* === Normalize dispatch row borders (eliminate double lines) === */

/* The row owns the border */
.dispatch-row,
.dispatch-board-row,
tr.dispatch-row td {
    border-top: 1px solid #d0d0d0 !important;
    border-bottom: 1px solid #d0d0d0 !important;
}
/* Ensure adjacent rows don't double up */
.dispatch-row+.dispatch-row,
.dispatch-board-row+.dispatch-board-row {
    border-top: none !important;
}

/* Prevent sub-pixel blur */
.dispatch-row,
.dispatch-board-row {
    box-sizing: border-box;
    background-clip: padding-box;
}
/* === Dispatch row border normalization (does not touch pills/buttons) === */

/* Give rows a single, crisp divider */
.dispatch-row,
.dispatch-board-row {
    border-top: 1px solid #d0d0d0 !important;
    border-bottom: 1px solid #d0d0d0 !important;
    background-clip: padding-box;
}

/* Prevent double-thickness between adjacent rows */
.dispatch-row+.dispatch-row,
.dispatch-board-row+.dispatch-board-row {
    border-top: 0 !important;
}

/* If the table itself is drawing competing rules, disable only table cell bottom rules */
.dispatch-board-table tbody td,
.dispatch-board-table tbody th {
    border-bottom: 0 !important;
}

/* ============================================================
   DISPATCH BOARD OVERRIDES (BOTTOM-OF-FILE WINS)
   Fix: phantom borders under status controls + restore left rail
   ============================================================ */

/* 1) Left status rail — SINGLE SOURCE (the old unscoped .dispatch-row.status-*
      base block was deleted; this is the only stripe rule now).
      Keyed on the DERIVED display status class (dispatch-display-status-<value>,
      emitted from load.display_status_value), the SAME value the status cell
      renders, so stripe and cell cannot drift. Okabe-Ito colorblind-safe; row
      position is the primary scan cue, color is secondary.
      No !important on box-shadow: with the base block gone this scoped selector
      (specificity 0,4,1) is the only box-shadow rule targeting the row and wins
      unaided — every "box-shadow: none !important" in this file targets td / cells
      / buttons, never tr.dispatch-row. The ddp background KEEPS !important to
      preserve its green highlight exactly as-is. */
.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-dispatched {
    box-shadow: inset 4px 0 0 #0072B2;
}

.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-in_transit {
    box-shadow: inset 4px 0 0 #E69F00;
}

.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-delivered {
    box-shadow: inset 4px 0 0 #009E73;
}

.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-assigned {
    box-shadow: inset 4px 0 0 #56B4E9;
}

/* unassigned + pending_assignment deliberately SHARE neutral gray: both mean
   "no driver assigned yet". pending_assignment inherits unassigned's color
   (decided 2026-08-06) rather than getting a new one; unscheduled keeps its own
   magenta so dated-vs-undated no-driver loads still read differently. */
.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-unassigned,
.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-pending_assignment {
    box-shadow: inset 4px 0 0 #666666;
}

.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-unscheduled {
    box-shadow: inset 4px 0 0 #CC79A7;
}

.scope-staff.page-dispatch tr.dispatch-row.dispatch-display-status-driver_delivered_pending {
    box-shadow: inset 4px 0 0 #009E73;
    background: #e6f6f0 !important;
}

/* 2) The “line under buttons” is almost always the TD border showing through.
      Remove the bottom border ONLY for the status cell, and re-apply it on the row. */
.scope-staff.page-dispatch .dispatch-table tbody td.dispatch-status-cell {
    border-bottom: 0 !important;
    background-clip: padding-box;
}

/* Recreate a single clean divider across the row (not through the controls) */
.scope-staff.page-dispatch .dispatch-table tbody tr.dispatch-row {
    border-bottom: 1px solid #d0d0d0;
}

/* 3) Ensure controls don’t contribute shadows/underlines */
.scope-staff.page-dispatch .dispatch-status-btn,
.scope-staff.page-dispatch .dispatch-actions,
.scope-staff.page-dispatch .dispatch-status-inline {
    box-shadow: none !important;
    text-decoration: none !important;
    background-image: none !important;
}

/* ============================================================
   DISPATCH — "SEND DISPATCH" BUTTON FILL (scan weight via the attention token)
   Fills the "Send Dispatch" action (.dispatch-status-btn — the only one rendered
   on the board post fire-once) so an action row is faster to spot in a long
   scan. Its PRESENCE is the signal (fire-once, mutually exclusive with the
   position label); the fill only adds scan weight.
   Amber IS this app's attention language: every attention/warning/pending token
   is the same amber (--status-warning-*, --status-dsp-*,
   --dispatch-pill-pending-assignment-*). The button speaks it via
   --status-warning-* instead of inventing a hue — and via TOKENS, not raw hex,
   so it adds nothing to this file's hardcoded-color drift. The saturated
   in_transit RAIL (#E69F00) is the outlier here, not the button.
   Border uses --status-warning-border (amber-200): the fill (--status-warning-bg
   is a very pale amber) reads faintly borderless on the white board, so the edge
   is what makes it register as a deliberate filled control at scan distance —
   still in the attention family, no new value.
   Text (--status-warning-fg) on fill (--status-warning-bg) = 6.4:1 (clears WCAG
   AA 4.5:1). "Confirm Delivery" is deliberately NOT filled here — it keeps its
   own green (.dispatch-confirm-btn, dispatch.css), which this rule previously
   shadowed. Scoped .scope-staff.page-dispatch (0,3,0) wins over the base
   .dispatch-status-btn / .tms-btn without !important.
   ============================================================ */
.scope-staff.page-dispatch .dispatch-status-btn {
    background: var(--status-warning-bg);
    color: var(--status-warning-fg);
    border: 1px solid var(--status-warning-border);
    font-weight: 700;
}

.scope-staff.page-dispatch .dispatch-status-btn:hover,
.scope-staff.page-dispatch .dispatch-status-btn:active {
    background: var(--status-warning-border);
    color: var(--status-warning-fg);
    border-color: var(--status-warning-border);
}

/* 4) Date group row: avoid double-rule under the date header */
.scope-staff.page-dispatch .dispatch-date-row th {
    border-bottom: 0 !important;
}

.scope-staff.page-dispatch .dispatch-date-row+tr td {
    border-top: 0 !important;
}
/* DISPATCH: row owns separators (prevents lines cutting through pills/buttons) */
.scope-staff.page-dispatch .dispatch-table tbody td {
    border-bottom: 0 !important;
}

.scope-staff.page-dispatch .dispatch-table tbody tr.dispatch-row {
    border-bottom: 1px solid #e1e1e1;
}
/* ============================================================
   DISPATCH — SINGLE ROW BORDER OWNER (fixes line under pills)
   Put at VERY bottom of tms_theme.css
   ============================================================ */

/* 1) Dispatch cells never draw borders (prevents lines through pills/buttons) */
.scope-staff.page-dispatch .dispatch-table tbody td {
    border-top: 0 !important;
    border-bottom: 0 !important;
}

/* 2) Row draws the divider (single crisp separator) */
.scope-staff.page-dispatch .dispatch-table tbody tr.dispatch-row {
    border-bottom: 1px solid #d0d0d0;
}

/* 3) Prevent any “double” border stacking */
.scope-staff.page-dispatch .dispatch-table tbody tr.dispatch-row+tr.dispatch-row {
    border-top: 0 !important;
}

/* 4) Date header → first row: no border above */
.scope-staff.page-dispatch .dispatch-date-row+tr.dispatch-row {
    border-top: 0 !important;
}

/* ================================
   State modifiers (rows, badges)
   Keep small and global.
   ================================ */

.tms-row-inactive {
    opacity: 0.65;
}

.tms-badge-muted {
    border: 1px solid var(--border-color);
    padding: 1px 6px;
    border-radius: 10px;
    font-size: 12px;
    opacity: 0.85;
}

/* Aging badge — RELOCATED from billing_dashboard.css so the token is global /
   reusable (customer_form AR panel; re-adoptable on the dashboard). Visual
   vocabulary mirrors .billing-status-pill; overdue palette matches the
   .billing-aging-icon / .billing-doc-missing warning hue. Pure lift-and-shift —
   same selectors, same values. */
.billing-aging-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
    line-height: 1.4;
}

.billing-aging-badge--current {
    background: #e5e7eb;
    color: #374151;
}

.billing-aging-badge--overdue {
    background: #fef3c7;
    color: #92400e;
}

/* Canonical list toolbar (Loads baseline) */
.tms-list-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
}

/* ── Filter vocabulary (Phase 1 item 6, R-FILTER two-tier canonical) ───────
   tms-filter-field is the single canonical field atom: one label + its control
   grouped on a line. LAYOUT (row spacing, wrap, alignment, control widths) is
   owned by the container vocabularies below, NOT re-scoped per surface:
     .tms-filter-inline  in-toolbar, short fields (customers / drivers / equipment)
     .tms-filter-panel   below-header rich filter (Load History; the accounting
                         queues adopt it in the item-6 per-surface sweep)
   Renamed .tms-loads-filter-panel -> .tms-filter-panel and pulled the page-local
   loads_list.html <style> filter rules in here so all three surfaces share one
   definition (resolves the tms-filter-field cross-surface collision). */
.tms-filter-field {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
}

.tms-filter-field > span {
    white-space: nowrap;
}

/* Container 1 — compact in-toolbar inline filter */
.tms-list-toolbar .tms-filter-inline {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    flex: 1 1 auto;
    justify-content: center;
    /* keeps filters in the middle */
}

.tms-list-toolbar .tms-filter-inline .tms-filter-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}

/* Container 2 — below-header rich filter panel (free-text + date-range) */
.tms-filter-panel {
    margin-bottom: 10px;
    padding: 8px;
    border: 1px solid var(--filter-panel-border);
    background: var(--filter-panel-bg);
}

.tms-filter-panel .tms-filter-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: end;
    gap: 8px;
}

.tms-filter-panel .tms-filter-field input,
.tms-filter-panel .tms-filter-field select {
    height: 28px;
}

.tms-filter-panel .tms-filter-field-search input {
    width: 200px;
}

.tms-filter-panel .tms-date-range-field {
    flex: 0 0 auto;
}

.tms-filter-panel .tms-date-range-field input[type="text"] {
    width: 180px;
}

.tms-filter-panel .tms-filter-actions {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    /* Neutralize the legacy bare .tms-filter-actions full-width bar rule
       (used by bulk_actions_bar / driver_detail) so the panel's actions size
       to content and margin-left:auto can push them to the right edge. */
    width: auto;
    margin-top: 0;
    padding-top: 0;
}

/* Right-side actions stay right and tight */
.tms-list-toolbar .tms-page-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

/* Pill tab group (Phase 1 item 4 — server-rendered tabs, e.g. Equipment trucks/
   trailers, rendered inline beside a toolbar title). Generic .tms-pill-tab* so the
   visual pattern can be reused; active = filled brand-accent, inactive = outlined,
   connected group (rounded outer edges, square inner). */
.tms-pill-tabs {
    display: inline-flex;
    vertical-align: middle;
    margin-left: 12px;
}

.tms-pill-tab {
    padding: 3px 14px;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--text-secondary);
    background: var(--surface-card);
    border: 1px solid var(--border-default);
    border-right-width: 0;
    text-decoration: none;
}

.tms-pill-tab:first-child {
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
}

.tms-pill-tab:last-child {
    border-right-width: 1px;
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
}

.tms-pill-tab:hover {
    background: var(--surface-panel);
    color: var(--text-primary);
}

.tms-pill-tab.is-active {
    background: var(--brand-accent);
    border-color: var(--brand-accent);
    color: var(--text-inverse);
}

.tms-alert {
    border: 1px solid;
    padding: 10px 12px;
    margin-bottom: 12px;
    font-size: 13px;
}

.tms-alert-error {
    background: #fbeaea;
    border-color: #d9534f;
    color: #7a1f1f;
}

.tms-alert-info {
    background: #eef4ff;
    border-color: #9db7e8;
    color: #1f3f73;
}

body.auth-body .auth-password-wrap {
    position: relative;
}

body.auth-body .auth-password-wrap input {
    width: 100%;
    padding-right: 64px;
}

body.auth-body .auth-password-toggle {
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 24px;
    padding: 0 6px;
    margin: 0;
    border: 0;
    background: transparent;
    color: #6b7280;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    border-radius: 4px;
}

body.auth-body .auth-password-toggle:hover {
    background: #e5e7eb;
    color: #111827;
}

body.auth-body .auth-password-toggle:focus-visible {
    outline: 2px solid #2563eb;
    outline-offset: 1px;
}

body.auth-body .auth-password-toggle[aria-pressed="true"] {
    color: #111827;
}

/* ================================
    Pagination (global, small, compact)
   ================================ */

.tms-pagination {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    font-size: 13px;
}

.tms-pagination__controls {
    display: flex;
    align-items: center;
    gap: 6px;
}

.tms-pagination__summary,
.tms-pagination__current {
    color: #555;
    white-space: nowrap;
}

/* ── Modal overlay ── */
.tms-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 900;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Closed state for the reusable data-attribute modal helper (modal.js toggles
   [hidden]). Attribute selector out-specificities the base rule above, so
   server-rendered modals (which never set [hidden]) stay visible. */
.tms-modal-backdrop[hidden] {
    display: none;
}

.tms-modal-dialog {
    background: #fff;
    border: 1px solid #c4c4c4;
    border-radius: 4px;
    padding: 24px 28px;
    max-width: 480px;
    width: 90%;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
}

.tms-modal-title {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 10px;
    color: #1a1a1a;
}

.tms-modal-body {
    font-size: 14px;
    color: #333;
    margin: 0 0 20px;
    line-height: 1.5;
}

.tms-modal-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

/* ============================================================
   EMPTY STATE — Phase 0.3 (DECISIONS 2026-05-28 "Phase 0.3 empty-state standard locked")
   .tms-empty-state           bordered centered block for list-page empty states
   .tms-empty-state--inline   bare / compact modifier for inline sub-table contexts
   .tms-empty-state__message  required headline ("No X yet." / "No X match your filters.")
   .tms-empty-state__detail   optional longer explanatory line
   .tms-empty-state__cta      optional inline-CTA wrapper
   Promoted from billing_dashboard.css .billing-empty-state. Markup contract is
   the core/templates/core/partials/_empty_state.html include.
   ============================================================ */

.tms-empty-state {
    text-align: center;
    padding: var(--space-8) var(--space-6);
    background: var(--surface-panel);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: var(--text-base);
}

.tms-empty-state__message {
    margin: 0;
    font-weight: 600;
    color: var(--text-primary);
    font-size: var(--text-base);
}

.tms-empty-state__detail {
    margin: var(--space-2) 0 0;
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    line-height: 1.5;
}

.tms-empty-state__cta {
    margin-top: var(--space-4);
}

.tms-empty-state a {
    color: var(--text-link);
}

/* Inline modifier: compact, no border / no bg, left-aligned by default.
   For load_detail docs / load_form sub-tables / any colspan row context. */
.tms-empty-state--inline {
    text-align: left;
    padding: var(--space-3) var(--space-4);
    background: transparent;
    border: none;
    color: var(--text-tertiary);
    font-size: var(--text-sm);
}

.tms-empty-state--inline .tms-empty-state__message {
    font-weight: 400;
    color: var(--text-tertiary);
    font-size: var(--text-sm);
}

/* ============================================================
   DISPATCH STATUS PILLS (outline) — central rule
   Sub-phase 1.1 extraction (DECISIONS 2026-05-28 "Sub-phase 1.1
   rulings", Rulings 2 + 3). Canonical home for the pill that was
   inline-duplicated across loads_list / customer_form / driver_detail
   / lane_history and referenced-but-undefined on loads_trash. Tokens
   in tokens.css (--dispatch-pill-*). loads_list adopts in this sweep;
   the other four surfaces adopt at their own Phase 1 sweeps (the
   loads_trash unstyled pill resolves the moment this rule lands).
   ============================================================ */
.dispatch-status-pill {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    line-height: 1.4;
    white-space: nowrap;
    border: 1px solid var(--dispatch-pill-base-border);
    background: var(--dispatch-pill-base-bg);
}

.dispatch-status-pill--unscheduled {
    background: var(--dispatch-pill-unscheduled-bg);
    border-color: var(--dispatch-pill-unscheduled-border);
}

.dispatch-status-pill--pending-assignment {
    background: var(--dispatch-pill-pending-assignment-bg);
    border-color: var(--dispatch-pill-pending-assignment-border);
}

.dispatch-status-pill--dispatched {
    background: var(--dispatch-pill-dispatched-bg);
    border-color: var(--dispatch-pill-dispatched-border);
}

.dispatch-status-pill--in-transit {
    background: var(--dispatch-pill-in-transit-bg);
    border-color: var(--dispatch-pill-in-transit-border);
}

.dispatch-status-pill--active {
    background: var(--dispatch-pill-active-bg);
    border-color: var(--dispatch-pill-active-border);
}

.dispatch-status-pill--assigned {
    background: var(--dispatch-pill-assigned-bg);
    border-color: var(--dispatch-pill-assigned-border);
}

.dispatch-status-pill--delivered {
    background: var(--dispatch-pill-delivered-bg);
    border-color: var(--dispatch-pill-delivered-border);
}

/* ============================================================
   TYPEAHEAD MENU — central rule
   Sub-phase 1.1 extraction (DECISIONS 2026-05-28 "Sub-phase 1.1 —
   Ruling 4 amendment (typeahead cohabitation)"). loads_list adopts
   the central rule here; load_form.css keeps its own copy (cohabits,
   later-load wins on the load form) until its Workstream 4 sweep.
   Central values are the loads_list copy: display:none initial-hide
   and explicit font sizing, both correct for the body-hoisted menu
   (typeahead.js hoists to document.body). Tokens in tokens.css.
   ============================================================ */
.tms-typeahead-menu {
    background: var(--typeahead-menu-bg);
    border: 1px solid var(--typeahead-menu-border);
    border-radius: 3px;
    box-shadow: var(--typeahead-menu-shadow);
    overflow-y: auto;
    max-height: 220px;
    display: none;
}

.tms-typeahead-item {
    display: block;
    width: 100%;
    padding: 6px 10px;
    text-align: left;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 13px;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tms-typeahead-item:hover,
.tms-typeahead-item--highlighted {
    background: var(--typeahead-item-hover-bg);
}

/* Optional two-line item (tmsTypeahead sublabelKey): primary name + a muted
   second line (e.g. QB "Bill to" for the qb_list_name type-ahead). Single-line
   items are unaffected — they keep the bare .tms-typeahead-item text node. */
.tms-typeahead-item--has-sub {
    white-space: normal;
}
.tms-typeahead-item__name {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tms-typeahead-item__sub {
    display: block;
    font-size: 11px;
    color: var(--text-tertiary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================
   SELECTION SUMMARY — shared batch-bar readout
   The live "N selected · $X" line above a multi-select action
   row. Two adopters: the driver-pay owed screen's .settle-action-bar
   (driver_detail.html) and the invoice archive's
   .billing-export-actions (accounting/invoice_list.html). The
   classes shipped as bare hooks on both; this promotes them to
   real shared rules HERE — loaded globally by base.html — rather
   than duplicating in billing_dashboard.css, which only the
   archive pulls. Same precedent as the aging badge above.

   The summary must sit on its OWN line above the buttons on both
   surfaces. .billing-export-actions is display:flex, so a bare
   block child rendered inline and crowded the action cluster
   (colliding on narrow viewports); flex:0 0 100% breaks it to a
   full line and wraps the buttons beneath. .settle-action-bar
   picks up matching flex/gap/margin so the two bars are
   dimensionally identical.

   Emphasis is weight + tabular figures only — no color-coded
   state, nothing distinguished by hue.
   ============================================================ */
.settle-action-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.settle-selection-summary {
    flex: 0 0 100%;
    font-size: 13px;
    color: var(--text-secondary);
}

.settle-num {
    font-weight: 600;
    color: var(--text-primary);
    /* Tabular figures so the amount does not jitter as it recomputes. */
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   FLATPICKR — accent override (Sub-phase 1.1 UX 1c)
   Vendored flatpickr 4.6.13 ships hardcoded colors (no CSS var
   hook), so the brand-accent recolor lives here as selector
   overrides rather than a token mapping. Endpoints only; the
   in-range middle keeps flatpickr's neutral default.
   ============================================================ */
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover {
    background: var(--brand-accent);
    border-color: var(--brand-accent);
}
