﻿/* SodMasters admin theme - inspired by (not copied from) a Rhino-style admin dashboard look:
   dark sidebar + light content, card-based stat tiles, soft shadows, rounded corners. */

:root {
    --sm-font-body: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;

    /* The house green. Started as the Order page's button colour and is now the app's: checkboxes,
       radios and report buttons all take it, so one control doesn't look like two across pages. */
    --sm-brand-green: #1c5336;

    /* The same green, for when it is painted ON the page as type or as a border rather than used as
       a fill behind white type. The two part company in dark mode - see the dark block below. */
    --sm-brand-green-on: #1c5336;

    --sm-primary: #3a5fdd;
    --sm-primary-dark: #2c49b0;
    --sm-accent: #22c3a6;
    --sm-danger: #e5533d;
    --sm-warning: #f2a93b;
    --sm-success: #2fb380;

    --sm-sidebar-bg: #1b2438;
    --sm-sidebar-bg-active: #263252;
    --sm-sidebar-text: #aab4d1;
    --sm-sidebar-text-active: #ffffff;
    --sm-sidebar-width: 260px;

    --sm-topnav-height: 64px;
    --sm-topnav-bg: #ffffff;

    --sm-body-bg: #f4f6fb;
    --sm-card-bg: #ffffff;
    --sm-border: #e6e9f2;
    --sm-text: #2b2f3a;
    --sm-text-muted: #6b7280;

    --sm-radius: 0.6rem;
    --sm-shadow: 0 2px 10px rgba(20, 25, 45, 0.06);
}

/* ---------- Dark mode ----------
   Opt-in only: switched on from the account menu and remembered in a cookie (wwwroot/js/theme.js),
   never inferred from prefers-color-scheme.

   Following the OS setting is what the app used to do, and it was worse than having no dark mode at
   all. It darkened the shell and this file's own tokens, but every hard-coded light surface
   underneath stayed light - Bootstrap's .table above all, which paints an explicit --bs-body-bg that
   stayed white because data-bs-theme was never set. Pale type on a pale ground, on the pages drivers
   actually use. One switch that we own, driving Bootstrap and this file together, is what keeps the
   two halves in step. */
:root[data-sm-theme="dark"] {
    --sm-body-bg: #12151f;
    --sm-card-bg: #1a1e2b;
    --sm-border: #2a2f40;
    --sm-text: #e7e9f0;
    --sm-text-muted: #9aa1b5;
    --sm-topnav-bg: #171b28;
    --sm-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);

    /* Green as a FILL is unchanged - white on #1c5336 reads at 8.9:1 in either mode, so buttons,
       section tabs and ticked checkboxes keep it. Green as TYPE is a different problem: #1c5336 on
       #12151f is 1.6:1, i.e. gone. Everything that paints green onto the page - links, outline
       buttons, the Excel glyph - uses this instead. */
    --sm-brand-green-on: #7CC79B;
}

html, body {
    font-family: var(--sm-font-body);
    background-color: var(--sm-body-bg);
    color: var(--sm-text);
}

/* Disabled/readonly form fields read as non-editable at a glance, matching the light-gray fill
   the rest of the app uses for "derived elsewhere, view-only" fields (e.g. the Order page's
   BOL #, Entered By, Driver). */
.form-control:disabled,
.form-control[readonly],
.form-select:disabled,
.form-check-input:disabled {
    background-color: var(--sm-border);
    opacity: 1;
}

/* ---------- Layout shell ---------- */

.sm-app-shell {
    display: flex;
    min-height: 100vh;
}

.sm-sidebar {
    width: var(--sm-sidebar-width);
    flex-shrink: 0;
    background-color: var(--sm-sidebar-bg);
    color: var(--sm-sidebar-text);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 1030;
    transition: transform 0.2s ease, width 0.2s ease;
}

.sm-sidebar-brand-row {
    position: relative;
    display: flex;
    align-items: center;
    padding: 1.1rem 1.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.sm-sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: #fff;
    text-decoration: none;
    min-width: 0;
}

.sm-sidebar-collapse-btn {
    position: absolute;
    top: 0.01rem;
    right: 0.25rem;
    background: none;
    border: none;
    color: var(--sm-sidebar-text);
    cursor: pointer;
    padding: 0.01rem 0.01rem;
    flex-shrink: 0;
}

.sm-sidebar-collapse-btn:hover {
    color: var(--sm-sidebar-text-active);
}

.sm-sidebar-logo {
    height: 38px;
    width: auto;
    object-fit: contain;
    flex-shrink: 0;
}

.sm-sidebar-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.sm-sidebar-brand-name {
    font-weight: 800;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.sm-sidebar-brand-sub {
    font-style: italic;
    font-size: 0.75rem;
    color: var(--sm-accent);
}

.sm-sidebar-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0.75rem 0.5rem;
}

.sm-sidebar-heading {
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    font-weight: 800;
    color: #ffffff;
    padding: 0.9rem 0.9rem 0.35rem;
}

.sm-sidebar-heading-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
}

.sm-sidebar-heading-chevron {
    font-size: 0.65rem;
    transition: transform 0.15s ease;
}

.sm-sidebar-heading-toggle.collapsed .sm-sidebar-heading-chevron {
    transform: rotate(-90deg);
}

/* max-height transition instead of display:none, so the open/close animates smoothly. The bound
   only needs to comfortably clear the tallest section's real content height (Admin, ~490px with
   13 items today) - a transition on a property with a huge unrelated ceiling (e.g. 999px) would
   look front-loaded/abrupt instead of smooth, since the visible motion would only cover a
   fraction of the animated time. Bump this whenever a nav item is added to the Admin section -
   items added past this ceiling render in the DOM but are silently clipped by overflow:hidden,
   with no visual indication anything is missing. */
/* ----- Nested nav groups (Admin > Orders, Admin > Super Admin) ----- */

/* The toggle reuses .sm-sidebar-link so it sits at exactly the same rhythm as the entries around
   it - a nested group is one of the list, not a band across it. */
.sm-sidebar-subheading {
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    font: inherit;
}

.sm-sidebar-subheading .sm-sidebar-heading-chevron {
    margin-left: auto;
    opacity: 0.7;
}

.sm-sidebar-subheading.collapsed .sm-sidebar-heading-chevron {
    transform: rotate(-90deg);
}

/* Indented, and given a hairline down the left so the eye can see where the group starts and
   stops without counting pixels of padding. */
.sm-sidebar-subcollapse {
    margin-left: 1.15rem;
    border-left: 1px solid rgba(255, 255, 255, 0.16);
}

.sm-sidebar-subcollapse > .sm-sidebar-link {
    padding-left: 0.95rem;
}

/* Generous on purpose. This is a max-height transition, so the value only has to EXCEED the
   tallest section - Admin, with both its nested groups open, runs past the 560px this used to
   carry and the last entries were simply cut off. Overshooting costs nothing but a slightly
   quicker finish to the open animation. */
.sm-sidebar-collapse {
    max-height: 1400px;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.sm-sidebar-collapse.sm-collapsed {
    max-height: 0;
}

/* ---------- "Processing" indicator (Components/Shared/ProcessingIndicator.razor) - used both as
   a full-content overlay on nav clicks (NavMenu.razor) and inline in place of a page's own content
   while it reloads (e.g. Delivery Schedules after a date change) ---------- */

.sm-processing-overlay {
    position: fixed;
    top: var(--sm-topnav-height);
    left: var(--sm-sidebar-width);
    right: 0;
    bottom: 0;
    z-index: 1090;
    background-color: rgba(244, 246, 251, 0.75);
    display: flex;
    align-items: center;
    justify-content: center;
}

[data-sm-theme="dark"] .sm-processing-overlay {
    background-color: rgba(18, 21, 31, 0.75);
}

.sm-processing-inline {
    display: flex;
    justify-content: center;
    padding: 3rem 0;
}

.sm-processing-spinner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    color: var(--sm-text-muted);
    font-size: 0.9rem;
    font-weight: 600;
}

.sm-processing-spinner i {
    font-size: 2rem;
    color: var(--sm-primary);
}

@media (max-width: 991.98px) {
    .sm-processing-overlay {
        left: 0;
    }
}

.sm-sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.55rem 0.9rem;
    border-radius: 0.45rem;
    color: var(--sm-sidebar-text);
    text-decoration: none;
    font-size: 0.828rem;
    font-weight: 600;
}

.sm-sidebar-link:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--sm-sidebar-text-active);
}

.sm-sidebar-link.active {
    background-color: var(--sm-sidebar-bg-active);
    color: var(--sm-sidebar-text-active);
}

.sm-sidebar-link i {
    width: 1.1rem;
    text-align: center;
}

.sm-main {
    flex: 1 1 auto;
    margin-left: var(--sm-sidebar-width);
    display: flex;
    flex-direction: column;
    min-width: 0;
    transition: margin-left 0.2s ease;
}

.sm-topnav {
    height: var(--sm-topnav-height);
    background-color: var(--sm-topnav-bg);
    border-bottom: 1px solid var(--sm-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1.25rem;
    position: sticky;
    top: 0;
    z-index: 1020;
}

.sm-topnav-toggle {
    display: none;
    background: none;
    border: none;
    font-size: 1.25rem;
    color: var(--sm-text);
}

.sm-env-banner {
    font-size: 0.8rem;
    font-weight: 700;
    text-align: center;
    padding: 0.35rem;
    color: #fff;
    background-color: var(--sm-warning);
}

.sm-env-banner-sep {
    display: inline-block;
    padding-left: 25px;
    padding-right: 25px;
}

.sm-content {
    padding: 1.5rem;
    flex: 1 1 auto;
}

.sm-nav-toggle-checkbox {
    display: none;
}

@media (max-width: 991.98px) {
    .sm-sidebar {
        transform: translateX(-100%);
    }

    .sm-nav-toggle-checkbox:checked ~ .sm-app-shell .sm-sidebar {
        transform: translateX(0);
    }

    .sm-main {
        margin-left: 0;
    }

    .sm-topnav-toggle {
        display: inline-block;
        cursor: pointer;
    }

    .sm-sidebar-collapse-btn {
        display: none;
    }
}

/* ---------- Desktop sidebar collapse (separate checkbox from the mobile off-canvas toggle
   above, gated to desktop widths only so it can't fight with the mobile transform behavior) ---------- */

.sm-nav-collapse-checkbox {
    display: none;
}

.sm-sidebar-expand-tab {
    display: none;
    position: fixed;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    z-index: 1040;
    width: 22px;
    height: 56px;
    align-items: center;
    justify-content: center;
    background-color: var(--sm-sidebar-bg);
    color: var(--sm-sidebar-text);
    border: none;
    border-radius: 0 0.5rem 0.5rem 0;
    cursor: pointer;
}

.sm-sidebar-expand-tab:hover {
    color: var(--sm-sidebar-text-active);
}

@media (min-width: 992px) {
    .sm-nav-collapse-checkbox:checked ~ .sm-app-shell .sm-sidebar {
        width: 0;
        overflow: hidden;
    }

    .sm-nav-collapse-checkbox:checked ~ .sm-app-shell .sm-main {
        margin-left: 0;
    }

    .sm-nav-collapse-checkbox:checked ~ .sm-sidebar-expand-tab {
        display: flex;
    }
}

/* ---------- Card / stat-tile system ---------- */

.sm-card {
    background-color: var(--sm-card-bg);
    border: 1px solid var(--sm-border);
    border-radius: var(--sm-radius);
    box-shadow: var(--sm-shadow);
}

.sm-card-header {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--sm-border);
    font-weight: 700;
}

.sm-card-body {
    padding: 1.25rem;
}

.sm-card-header-tight {
    padding: 0.5rem 0.9rem;
}

/* ---------- Delivery Schedule cards ---------- */
/* The default --sm-border (#e6e9f2) is nearly invisible against the page background, so a run
   of stacked cards reads as one continuous sheet. These get a genuinely dark-gray border
   instead, purely to give each card definition - scoped to .sm-bordered-card so every other
   card in the app keeps the softer default. */

.sm-bordered-card {
    border-color: #6b7280;
    /* A full-bleed table in .sm-card-body.p-0 paints its own square corners right over the card's
       rounded ones, which chewed visible notches out of the border at the bottom-left and
       bottom-right. Clipping children to the card's radius is what actually fixes that - the
       border-radius alone doesn't constrain descendants. */
    overflow: hidden;
}

/* A dark gray would vanish against the dark card background - go lighter instead, so the border
   still reads as "definition" rather than disappearing. */
[data-sm-theme="dark"] .sm-bordered-card {
    border-color: #5b6478;
}

.sm-block-card-header {
    /* Half the usual 1rem top padding - the driver/pay controls sat in a band of whitespace. */
    padding-top: 0.5rem;
    /* Matches .sm-report-table below. 85% OF the controls' current 0.875rem would land at ~0.74rem,
       smaller than the table it sits above, so it's pinned to the table's size instead. */
    font-size: 85%;
}

/* Bootstrap's -sm form controls hardcode their own font-size, so they don't inherit the 85%
   above without this. */
.sm-block-card-header .form-select-sm,
.sm-block-card-header .form-control-sm,
.sm-block-card-header .form-label {
    font-size: inherit;
}

.sm-card-body-tight {
    padding: 0.65rem 0.9rem;
}

.sm-pto-calendar-header {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--sm-text-muted);
    margin-bottom: 0.35rem;
}

.sm-pto-calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background-color: var(--sm-border);
    border: 1px solid var(--sm-border);
    border-radius: var(--sm-radius);
    overflow: hidden;
}

.sm-pto-calendar-cell {
    background-color: var(--sm-card-bg);
    min-height: 110px;
    padding: 0.4rem;
    cursor: pointer;
}

/* A day highlights on hover because clicking it books PTO - the whole grid is a button. The tint
   is fixed rather than themed so the cue is the same in both modes. */
.sm-pto-calendar-cell:hover {
    background-color: #B7D1B9;
}

.sm-pto-calendar-cell-empty {
    background-color: var(--sm-border);
    cursor: default;
}

.sm-pto-calendar-daynum {
    font-size: 0.8rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.sm-pto-calendar-today {
    color: var(--sm-primary);
}

/* A booked day wears the same yellow as the Georgia / South Carolina badge in the header. Literal
   colours for the same reason that badge uses them: it has to read identically in light and dark,
   and against the hover tint behind it. */
.sm-pto-entry {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.7rem;
    background-color: #e9f135;
    border: 1px solid #c4cb1b;
    color: #1f2400;
    border-radius: 0.25rem;
    padding: 0.15rem 0.35rem;
    margin-bottom: 0.2rem;
    cursor: default;
}

.sm-pto-entry .btn-close {
    width: 0.5rem;
    height: 0.5rem;
    flex-shrink: 0;
}

.sm-stat-card {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.1rem 1.25rem;
    height: 120px;
}

.sm-stat-icon {
    width: 3rem;
    height: 3rem;
    border-radius: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: #fff;
    flex-shrink: 0;
    background: var(--sm-primary);
}

.sm-stat-label {
    font-size: 0.8rem;
    color: var(--sm-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Driver home tiles. These labels sit inside a link, so without a colour they would take Bootstrap's
   link blue - and Bootstrap's own .text-body is no good either: this app themes itself through its
   own tokens and never sets data-bs-theme, so .text-body stayed the LIGHT body colour and the labels
   were near-invisible dark-on-dark for anyone whose phone is in dark mode. */
.sm-tile-label {
    color: var(--sm-text);
}

.sm-stat-value {
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1.2;
}

.sm-stat-card-link {
    cursor: pointer;
    text-decoration: none;
    color: inherit;
    transition: box-shadow 0.15s ease, transform 0.1s ease;
}

.sm-stat-card-link:hover, .sm-stat-card-link:focus-visible {
    box-shadow: 0 4px 16px rgba(20, 25, 45, 0.14);
    transform: translateY(-1px);
    color: inherit;
}

/* ---------- Homepage bar charts (dependency-free: plain divs + CSS, no chart library) ---------- */

.sm-barchart {
    display: flex;
    align-items: flex-end;
    gap: 0.35rem;
    height: 180px;
    padding-top: 1.75rem;
}

.sm-barchart-col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
}

.sm-barchart-bar-track {
    flex: 1;
    display: flex;
    align-items: flex-end;
    width: 100%;
}

.sm-barchart-bar {
    width: 100%;
    min-height: 2px;
    border-radius: 3px 3px 0 0;
    position: relative;
    transition: opacity 0.15s ease;
}

.sm-barchart-bar:hover {
    opacity: 0.75;
}

.sm-barchart-bar-clickable {
    cursor: pointer;
}

.sm-barchart-bar:hover .sm-barchart-tooltip {
    display: block;
}

.sm-barchart-tooltip {
    display: none;
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    background: var(--sm-text);
    color: var(--sm-card-bg);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.15rem 0.45rem;
    border-radius: 4px;
    white-space: nowrap;
    margin-bottom: 4px;
    pointer-events: none;
    z-index: 5;
    text-align: center;
}

.sm-barchart-tooltip-date {
    display: block;
    font-weight: 600;
    opacity: 0.8;
    font-size: 0.65rem;
}

.sm-barchart-label {
    font-size: 0.65rem;
    color: var(--sm-text-muted);
    margin-top: 0.35rem;
    white-space: nowrap;
    overflow: hidden;
    /* The height is reserved whether or not this column actually shows a label. The 28-day view
       labels every fourth column, and an unlabelled div collapsed to nothing - which handed that
       column's bar the extra height, so its bar hung lower than its labelled neighbours and the
       dates ended up looking like they sat inside the chart rather than under it. Every column now
       gives up the same strip, so all the bars share one baseline. */
    line-height: 1.2;
    min-height: 1.2em;
}

/* ---------- Year-over-Year grouped bar chart + legend ---------- */

.sm-legend {
    display: flex;
    gap: 1rem;
    font-size: 0.75rem;
    color: var(--sm-text-muted);
}

.sm-legend-item {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 600;
}

.sm-legend-swatch {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 2px;
    display: inline-block;
}

.sm-groupedbarchart {
    display: flex;
    align-items: flex-end;
    gap: 0.3rem;
    height: 180px;
    padding-top: 1.75rem;
}

.sm-groupedbarchart-group {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
}

.sm-groupedbarchart-bars {
    flex: 1;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
    width: 100%;
}

.sm-groupedbarchart-bar {
    flex: 1 1 0;
    min-width: 3px;
    max-width: 14px;
    min-height: 2px;
    border-radius: 2px 2px 0 0;
    position: relative;
    transition: opacity 0.15s ease;
}

.sm-groupedbarchart-bar:hover {
    opacity: 0.75;
}

.sm-groupedbarchart-bar:hover .sm-barchart-tooltip {
    display: block;
}

.sm-groupedbarchart-label {
    font-size: 0.65rem;
    color: var(--sm-text-muted);
    margin-top: 0.35rem;
    white-space: nowrap;
}

/* ---------- Buttons/links tuned to the theme ---------- */

.btn-primary {
    background-color: var(--sm-primary);
    border-color: var(--sm-primary);
}

.btn-primary:hover, .btn-primary:focus {
    background-color: var(--sm-primary-dark);
    border-color: var(--sm-primary-dark);
}

.sm-auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--sm-body-bg);
}

.sm-auth-card {
    width: 100%;
    max-width: 380px;
}

.sm-auth-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.sm-auth-logo {
    width: 40px;
    height: 40px;
    object-fit: contain;
    flex-shrink: 0;
}

.sm-auth-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.sm-auth-brand-name {
    font-weight: 800;
    font-size: 1.3rem;
    letter-spacing: 0.02em;
    color: var(--sm-text);
}

.sm-auth-brand-sub {
    font-style: italic;
    font-size: 0.85rem;
    color: var(--sm-accent);
}

/* ---------- Public (no-auth) pages ---------- */

.sm-public-topnav {
    height: var(--sm-topnav-height);
    background-color: var(--sm-sidebar-bg);
    color: #fff;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0 1.25rem;
}

.sm-public-logo {
    width: 32px;
    height: 32px;
    object-fit: contain;
    flex-shrink: 0;
}

.sm-public-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.sm-public-brand-name {
    font-weight: 800;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
}

.sm-public-brand-sub {
    font-style: italic;
    font-size: 0.75rem;
    color: var(--sm-accent);
}

.sm-public-content {
    max-width: 720px;
    margin: 0 auto;
    padding: 1.5rem 1rem 3rem;
}

.sm-sig-canvas {
    border: 1px solid var(--sm-border);
    border-radius: var(--sm-radius);
    background-color: #fff;
    touch-action: none;
    max-width: 100%;
}

.sm-signature-image {
    border: 1px solid var(--sm-border);
    border-radius: var(--sm-radius);
    background-color: #fff;
    max-width: 298px;
    width: 100%;
}

/* ---------- Lightweight modal (no Bootstrap JS bundle loaded) ---------- */

.sm-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 8vh;
    z-index: 1050;
}

.sm-modal-panel {
    background-color: var(--sm-card-bg);
    color: var(--sm-text);
    border-radius: var(--sm-radius);
    box-shadow: var(--sm-shadow);
    padding: 1.25rem;
    width: 100%;
    max-width: 560px;
    max-height: 80vh;
    overflow-y: auto;
}

.sm-modal-panel h2 {
    font-weight: 700;
    font-size: 1.25rem;
}

/* ---------- Customer/contact name autocomplete dropdown ---------- */

.sm-autocomplete-list {
    top: 100%;
    left: 0;
    z-index: 1040;
    max-height: 220px;
    overflow-y: auto;
}

.sm-autocomplete-list .list-group-item {
    cursor: pointer;
    padding: 0.35rem 0.75rem;
    font-size: 0.875rem;
}

/* Row picked with the arrow keys. Brand green rather than Bootstrap's blue "active", matching the
   table stripe color, with dark text so it stays readable. */
.sm-autocomplete-list .list-group-item.active {
    background-color: #94B59D;
    border-color: #94B59D;
    color: #000;
}

/* ---------- Bootstrap colour classes, taught about dark mode ---------- */

/* This app themes itself with its own tokens and never sets data-bs-theme, so Bootstrap's colour
   helpers stay on their LIGHT values whatever the viewer's phone is set to. In dark mode that left
   .text-muted as dark grey on a dark background - the legal disclaimer on the customer approval page
   was very nearly invisible, and it is used in 40-odd other places besides. Bootstrap sets these
   with !important, so overriding them needs it too. */
.text-muted {
    color: var(--sm-text-muted) !important;
}

/* Same story: a "light" panel keeps its light background while the text inside it turns light in
   dark mode, leaving light-on-light. Used by the code blocks on Admin > System Errors. */
.bg-light {
    background-color: var(--sm-card-bg) !important;
}

/* ---------- Which site you are on: Georgia or South Carolina ---------- */

/* Shown in the top bar and on the login card. Staff who work for both companies need to tell the
   two sites apart at a glance - especially on test, where both run against the same restored data.
   Deliberately plain for now; the per-instance colour schemes below are where that will change. */
.sm-instance-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.15rem 0.7rem;
    border: 1px solid #c4cb1b;
    border-radius: 999px;
    /* Literal colours, not theme tokens: this badge has to look the same in light and dark, since
       its whole job is to be the one thing on screen that says which company's site you are in. */
    background-color: #e9f135;
    color: #1f2400;
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

/* The login-page badge is a button (it opens the location switcher) - strip the button chrome so it
   still reads as the same badge. */
button.sm-instance-badge {
    cursor: pointer;
}

button.sm-instance-badge:hover {
    background-color: #dfe72b;
}

.sm-instance-badge-lg {
    font-size: 0.95rem;
    padding: 0.25rem 0.9rem;
}

/* Hooks for the per-instance colour schemes. The class sits on the app shell and the login card,
   so anything inside either one can be themed from here without touching markup again. */
.sm-instance-ga .sm-instance-badge {
    /* Georgia - brand default for now. */
}

.sm-instance-sc .sm-instance-badge {
    /* South Carolina - to be given its own scheme. */
}

/* ---------- Excel export links (icon + text colored to the brand's Excel green) ---------- */

.sm-excel-link {
    color: var(--sm-brand-green-on);
}

.sm-excel-link:hover, .sm-excel-link:focus {
    color: var(--sm-brand-green-on);
}

/* ---------- App-wide green controls ----------
   Checkboxes and radios take the brand green instead of Bootstrap's blue, everywhere - the order
   page and the schedule pages already did this in their own skins, and a blue radio next to a green
   one on an admin report is just the same control looking like two different things. */

.form-check-input:checked {
    background-color: var(--sm-brand-green);
    border-color: var(--sm-brand-green);
}

.form-check-input:focus {
    border-color: var(--sm-brand-green-on);
    box-shadow: 0 0 0 0.15rem rgba(28, 83, 54, 0.25);
}

/* The fill stays deep green so the white tick still reads, but on a dark page a deep-green box on a
   dark ground has no visible edge - the border is what says "this is a control". */
[data-sm-theme="dark"] .form-check-input:checked {
    border-color: var(--sm-brand-green-on);
}

/* Report buttons - "Get Report", "Excel", "PDF". Green outline at rest; green fill with white type
   on hover, and the Excel glyph inside goes white with it rather than staying green on green. */
.btn-outline-secondary.sm-excel-link,
.sm-report-btn {
    border-color: var(--sm-brand-green-on);
    color: var(--sm-brand-green-on);
}

.btn-outline-secondary.sm-excel-link:hover,
.btn-outline-secondary.sm-excel-link:focus,
.sm-report-btn:hover,
.sm-report-btn:focus {
    background-color: var(--sm-brand-green);
    border-color: var(--sm-brand-green);
    color: #fff;
}

.btn-outline-secondary.sm-excel-link:hover .sm-excel-icon,
.btn-outline-secondary.sm-excel-link:focus .sm-excel-icon,
.btn-outline-secondary.sm-excel-link:hover i,
.btn-outline-secondary.sm-excel-link:focus i,
.sm-report-btn:hover .sm-excel-icon,
.sm-report-btn:focus .sm-excel-icon,
.sm-report-btn:hover i,
.sm-report-btn:focus i {
    color: #fff;
}


.sm-excel-icon {
    color: var(--sm-brand-green-on);
    margin-right: 20px;
}

/* ---------- Dense report tables (Active/Pending/Incomplete/Brokered/Flat Rate Orders, Cut Sheet) ---------- */

.sm-report-table {
    font-size: 85%;
}

/* Admin > Customers carries more columns than the other report tables (Credit Limit pushed it to
   13), so it runs a little tighter to stay on screen without horizontal scrolling.
   Set in rem rather than a percentage: this element also carries .sm-report-table (85%), and two
   percentages on the same element resolve against the same inherited size instead of compounding -
   see the .sm-cutsheet-table note below. */
.sm-customers-table {
    font-size: 0.78rem;
}

/* The Business Central customer number sitting beside a customer's name on Admin > Customers.
   Set a size down and in tabular figures so a column of them lines up when the eye runs down the
   name column, without competing with the name it follows. */
.sm-customer-bcid {
    margin-left: 0.45rem;
    font-size: 0.85em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ---------- Cut Sheet ---------- */

/* The sheet is a dense grid read at a glance across many columns - tighter than the standard
   report table so more of it fits on screen (and on a printed page) at once.
   NOTE: this element also carries .sm-report-table (85%), and both percentages resolve against
   the same inherited size rather than compounding - so this value must be BELOW 85% to actually
   shrink anything. 78% lands a little under the report tables it sits alongside. */
.sm-cutsheet-table {
    font-size: 78%;
}

.sm-cutsheet-table > thead > tr > th,
.sm-cutsheet-table > tbody > tr > td {
    padding: 0.2rem 0.35rem;
}

/* Dark header band with white text - the sheet is scanned by column, and a solid dark block gives
   the eye a hard stop between "what the columns are" and the rows of data underneath. Set on the
   cells rather than the row so it wins over the table's own striping/border rules. */
.sm-cutsheet-table > thead > tr > th {
    background: #24403a;
    color: #fff;
    border-color: #3a5a52;
    vertical-align: middle;
}

/* Callout lists (Unpaid / Non-Approved / Brokered / Partial Pallets). The browser default
   indent on a <ul> is ~2.5rem, which reintroduced the bulk the tight card padding just removed. */
.sm-callout-list {
    padding-left: 1.1rem;
}

.sm-callout-list > li {
    line-height: 1.35;
}

/* Cut-field row: still subordinate to the sod name and size above it, but dimmed white rather
   than grey so it stays legible on the dark header. */
.sm-cutsheet-table > thead > tr > th.sm-cutsheet-field-th {
    color: rgba(255, 255, 255, 0.75);
}

/* The running per-column totals row, sitting at the bottom of the header block - a shade lighter
   so it reads as a summary of the header rather than another label row. */
.sm-cutsheet-total-row > th {
    background: #35564e !important;
}

/* The totals strip occupies the header too, but is a light band - it's page-level context, not a
   column label, so it deliberately doesn't take the dark treatment. */
.sm-cutsheet-summary-row > td {
    background: var(--sm-card-bg);
    padding: 0.5rem 0.75rem !important;
    border-bottom: 2px solid #24403a;
}

.sm-cutsheet-stat-icon {
    font-size: 1.35rem;
    margin-right: 0.55rem;
}

/* PICKUP / PARTIAL row markers.
   inline-FLEX with an explicit line-height, not inline-block: an inline-block sits on the text
   baseline and inherits the row's line-height, which leaves dead space below the glyphs that
   symmetric padding can't cancel out - the label ends up riding high in the pill. Taking the text
   out of baseline flow and centring it makes the padding actually symmetric. */
.sm-cutsheet-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.2rem 0.45rem;
    margin-left: 0.25rem;
    border-radius: 0.25rem;
    font-size: 80%;
    line-height: 1;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: #fff;
    vertical-align: middle;
}

/* The two badges are tappable on a phone, where they read PCK/PRT until expanded. A <button>
   brings its own border and font-family, neither of which the span version had. */
button.sm-cutsheet-badge {
    border: 0;
    font-family: inherit;
}

.sm-cutsheet-badge-pickup {
    background: #7048b6;
}

.sm-cutsheet-badge-partial {
    background: #2f6fed;
}

/* Icon beside a stacked label/value pair, repeated across the strip. Each reading is closed off
   by a rule on its right - including the last one - so they read as four discrete figures rather
   than one run-on line.
   Uses --sm-text rather than a literal black: the token is near-black in light mode and light in
   dark mode, so the divider stays visible either way instead of disappearing on a dark ground. */
.sm-cutsheet-stat {
    display: flex;
    align-items: center;
    padding-right: 1.1rem;
    margin-right: 1.1rem;
    border-right: 1px solid var(--sm-text);
}

/* Total Loads is the far-right item with nothing after it, so it closes the strip on its own. */
.sm-cutsheet-stat-loads {
    padding-right: 0;
    margin-right: 0;
    border-right: none;
}

.sm-cutsheet-stat-label {
    color: var(--sm-text-muted);
    font-size: 85%;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.sm-cutsheet-stat-value {
    font-size: 1.15rem;
    font-weight: 700;
}

/* ---------- Cut Sheet date-group separator row (same-day PM vs next-day AM orders) ---------- */

/* Noticeably darker than the row stripes either side of it - at a glance the day boundary should
   be unmistakable, since reading a row under the wrong date sends sod out on the wrong truck. */
.sm-cutsheet-date-group td {
    background: #ccd7d3;
    border-top: 2px solid #24403a;
    border-bottom: 2px solid #24403a;
    padding: 0.35rem 0.5rem !important;
    box-shadow: none !important; /* opt out of the zebra-striping shadow above */
}

[data-sm-theme="dark"] .sm-cutsheet-date-group td {
    background: #2b3a36;
    border-top-color: #4a6b62;
    border-bottom-color: #4a6b62;
}

.sm-cutsheet-date-badge {
    display: inline-block;
    padding: 0.2rem 0.9rem;
    border: 1px solid var(--sm-border);
    border-radius: 0.375rem;
    font-weight: 600;
    background: var(--sm-card-bg);
}

/* ============================================================================================
   Cut Sheet on a phone.

   Deliberately the LAST word on .sm-cutsheet-*: several rules below override base rules of
   identical specificity (.sm-cutsheet-stat-icon and friends), and at equal specificity the later
   declaration wins. Move this block back above them and the sizing silently stops applying while
   the markup still looks correct - which is exactly how it was first got wrong.
   ============================================================================================ */

/* ----- Cut Sheet on a phone -----

   The sheet is a wide grid: on a 400px screen the customer names and full sod names set the
   column widths and squeeze the numbers - which are the only part anyone is actually reading -
   off the right-hand edge. So the narrow layout trades the names for taps.

   Both variants are in the markup and CSS picks one, rather than the server sniffing the client:
   the desktop sheet is what the yard prints and it must not move, and a rotated tablet should get
   the right layout without a round trip. Below the md breakpoint, matching the rest of the app. */

.sm-cutsheet-narrow,
.sm-cutsheet-row-narrow {
    display: none;
}

/* Tap targets that read as text, not buttons - a row of grey pills across the header would fight
   the grid harder than the names they replaced. */
.sm-cutsheet-reveal {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 2px;
}

.sm-cutsheet-reveal:hover,
.sm-cutsheet-reveal:focus-visible {
    text-decoration-style: solid;
}

@media (max-width: 767.98px) {
    .sm-cutsheet-wide {
        display: none;
    }

    .sm-cutsheet-narrow {
        display: inline;
    }

    /* Whole-row variants need table-row, not inline - a <tr> forced inline collapses the row and
       its cells out of the table's layout entirely. */
    .sm-cutsheet-row-wide {
        display: none;
    }

    .sm-cutsheet-row-narrow {
        display: table-row;
    }

    /* Clear of the shift label rather than butted against it - at this size the banner is three
       short phrases in a row and the count is the one worth picking out. */
    .sm-cutsheet-loads {
        margin-left: 20px;
    }

    /* ----- Totals strip on one line -----

       At full size the five stats wrap, dropping TOTAL LOADS onto a second row and costing a whole
       line of screen to say one number. Everything shrinks together - icon, label, value and the
       gaps between - so the strip keeps its shape rather than turning into cramped text.

       The two overrides are load-bearing. flex-wrap is what was pushing TOTAL LOADS down. And
       justify-content has to come off with it: the cell spans the WHOLE table, so space-between
       against a 600px-wide row would fling the loads count off the right-hand edge of the screen
       - the same trap the date banner above just came out of. Both carry !important because the
       Bootstrap utility classes in the markup set them that way. */
    .sm-cutsheet-summary-row .d-flex {
        flex-wrap: nowrap !important;
        justify-content: flex-start !important;
    }

    .sm-cutsheet-summary-row > td {
        padding: 0.35rem 0.4rem !important;
    }

    .sm-cutsheet-stat-icon {
        font-size: 0.9rem;
        margin-right: 0.2rem;
    }

    /* Tighter than it looks like it needs to be: the four sod stats give up a couple of pixels
       each so Loads can have its 15px below, and still clear a 320px phone. */
    .sm-cutsheet-stat {
        padding-right: 0.28rem;
        margin-right: 0.28rem;
    }

    .sm-cutsheet-stat-label {
        font-size: 0.52rem;
        letter-spacing: 0;
        /* Five labels in a row - any one of them wrapping takes the strip's height straight back
           up to the two rows this was meant to collapse. */
        white-space: nowrap;
    }

    .sm-cutsheet-stat-value {
        font-size: 0.78rem;
    }

    /* Loads sits clear of the divider rather than tight against it - it is the one figure here
       that describes the day rather than the sod, so a wider gap than the four stats share
       between themselves sets it apart without needing a rule or a colour. */
    .sm-cutsheet-stat-loads {
        padding-left: 15px;
    }

    /* BOL numbers come from BolLink, which renders a Bootstrap .btn-sm - and that sets its
       font-size in absolute rem, so it sails straight past the table's own 78% and lands BIGGER
       than the quantities beside it. Forced back to inherit so the BOL reads at exactly the size
       of the numbers it sits next to, which is both smaller than it was and consistent. */
    .sm-cutsheet-table > tbody > tr > td.sm-cutsheet-bol .btn {
        font-size: inherit;
    }

    /* The customer column is a single icon at this width, so centring it stops it hugging the
       left border and reads as a control rather than a truncated name. An expanded name centres
       too, which keeps the column from jumping sideways as it opens. */
    .sm-cutsheet-table > thead > tr > th.sm-cutsheet-cust,
    .sm-cutsheet-table > tbody > tr > td.sm-cutsheet-cust {
        text-align: center;
    }

    /* A shade tighter still than the desktop sheet's already-tight cells. With the names gone
       there is little left to separate, and the horizontal padding across a dozen sod columns adds
       up to more width than the numbers themselves. */
    .sm-cutsheet-table > tbody > tr > td,
    .sm-cutsheet-table > thead > tr > th {
        padding: 0.2rem 0.25rem;
    }
}

/* ---------- Driver Schedule delivery notes ---------- */
/* Black on a light yellow wash - these are act-on-them instructions sitting among reference
   detail, so they are deliberately the one highlighted thing in a drop card. Colors are literal
   rather than tokenised: the highlight has to read as a highlight in both themes, and inverting
   it for dark mode would lose exactly the emphasis it exists to create. */
.sm-driver-note {
    display: inline-block;
    color: #000;
    background: #FDF3C7;
    border: 1px solid #E9D68A;
    border-radius: 4px;
    padding: 0.15rem 0.45rem;
}

/* ---------- Checkbox / radio outlines ---------- */
/* Bootstrap's default unchecked border is rgba(0,0,0,.25) - against the app's near-white card
   background an empty radio nearly disappears, which matters most where a radio is the thing
   being chosen between (e.g. the report pages' Monthly vs Date Range). Darkened to a solid mid
   gray so the empty state reads as a real control. Only the UNCHECKED state is restyled; once
   checked, Bootstrap fills it with the accent color and paints its own matching border. */
.form-check-input:not(:checked):not(:disabled) {
    border-color: #6b7280;
}

[data-sm-theme="dark"] .form-check-input:not(:checked):not(:disabled) {
    border-color: #8b93a7;
}

/* ---------- Global table zebra striping (every other row tinted brand green) ---------- */
/* Uses an inset box-shadow rather than background-color, matching how Bootstrap's own
   .table-striped works, so it composes correctly with hover states and cell backgrounds
   and applies whether or not a table also carries the .table-striped class.

   Light mode paints BOTH halves: #94B59D on odd rows, #D7EADC on even ones, so the alternation
   is green-on-green rather than green-on-white. These started as the Order page's own pair and
   were promoted here, so every table in the app stripes the same way. Dark mode needs its own pair
   for the same reason in reverse - a fill this light behind light text is unreadable.

   Dark mode MUST override both halves. It used to restate only the odd row, which left every even
   row painted #D7EADC - pale mint - under type that had turned near-white. That is what made the
   driver schedule's line items (sod type, size, qty) all but invisible to anyone whose phone was
   in dark mode, and it is the whole reason the theme is now an explicit switch.

   The :not() guards matter. Bootstrap paints its contextual row/cell states (.table-danger,
   .table-warning, .table-secondary) with an inset box-shadow too, and this selector is more
   specific - without the guards the stripe silently covers every one of them on odd rows, so
   alerting highlights vanish on half the table. Excluding cells that carry a table-* class, and
   cells inside a row that does, hands those cells back to Bootstrap. */

.table > tbody > tr:nth-of-type(odd):not([class*="table-"]) > *:not([class*="table-"]) {
    box-shadow: inset 0 0 0 9999px #94B59D;
}

.table > tbody > tr:nth-of-type(even):not([class*="table-"]) > *:not([class*="table-"]) {
    box-shadow: inset 0 0 0 9999px #D7EADC;
}

[data-sm-theme="dark"] .table > tbody > tr:nth-of-type(odd):not([class*="table-"]) > *:not([class*="table-"]) {
    box-shadow: inset 0 0 0 9999px rgba(32, 110, 86, 0.30);
}

/* Barely there on purpose. The alternation only has to be findable when the eye tracks along a row;
   any heavier and it competes with the type it is supposed to be carrying. */
[data-sm-theme="dark"] .table > tbody > tr:nth-of-type(even):not([class*="table-"]) > *:not([class*="table-"]) {
    box-shadow: inset 0 0 0 9999px rgba(148, 181, 157, 0.07);
}

/* ---------- "Coming soon" placeholder (Driver Scheduling > Weekend Schedules) ---------- */
/* Centred in a generous amount of space rather than tucked under the tabs: the point is to read
   instantly as "nothing here yet", not as a page that failed to load its content. */
.sm-coming-soon {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 3rem 1rem 3.5rem;
}

.sm-coming-soon svg {
    width: 220px;
    max-width: 60vw;
    height: auto;
    margin-bottom: 1.25rem;
}

/* ---------- Bootstrap contextual rows in dark mode ---------- */
/* .table-secondary and friends are NOT theme-aware: Bootstrap defines them once, with a fixed
   light background and black text, and leaves them that way under data-bs-theme="dark". The rows
   they mark are usually also .text-muted, whose dark-mode colour is a light grey - so an inactive
   row came out as pale grey type on a pale grey band, which is illegible. Reported on Admin > Sod
   > Sod Pricing, where every inactive sod row was unreadable.

   Fixed here rather than on that one page because the same pairing marks inactive records on
   Admin > Customers too, and anywhere else that reaches for the Bootstrap convention.

   Redefining the variables rather than the colours directly is what keeps hover and striping
   coherent - Bootstrap composes all of them from these. */
/* Same story for the amber one, reported on Active Orders: the unassigned block and driver cells
   came out as pale grey type on a pale yellow band. Kept unmistakably AMBER rather than neutered
   to grey - an order this close to delivery with no block and no driver is the thing that column
   exists to shout about - but deep enough to carry light text. */
[data-sm-theme="dark"] .table > :not(caption) > tr.table-warning,
[data-sm-theme="dark"] .table > :not(caption) > tr > td.table-warning,
[data-sm-theme="dark"] .table-warning {
    --bs-table-color: #ffd970;
    --bs-table-bg: #4a3a0e;
    --bs-table-border-color: #6b5518;
    --bs-table-striped-bg: #53410f;
    --bs-table-striped-color: #ffd970;
    --bs-table-hover-bg: #5b4712;
    --bs-table-hover-color: #ffe49a;
    --bs-table-active-bg: #5b4712;
    --bs-table-active-color: #ffe49a;
    color: var(--bs-table-color);
}

[data-sm-theme="dark"] .table > :not(caption) > tr.table-secondary,
[data-sm-theme="dark"] .table > :not(caption) > tr > td.table-secondary,
[data-sm-theme="dark"] .table-secondary {
    --bs-table-color: #ced4da;
    --bs-table-bg: #32383e;
    --bs-table-border-color: #444b52;
    --bs-table-striped-bg: #373d43;
    --bs-table-striped-color: #ced4da;
    --bs-table-hover-bg: #3c4248;
    --bs-table-hover-color: #e9ecef;
    --bs-table-active-bg: #3c4248;
    --bs-table-active-color: #e9ecef;
    color: var(--bs-table-color);
}

/* The strikethrough and the INACTIVE chip sit inside that row - both inherit, but .text-muted on
   the row itself resolves to a colour chosen against the page background, not against this band.
   Nudged brighter so the sod name stays readable while still reading as subdued. */
[data-sm-theme="dark"] tr.table-secondary.text-muted,
[data-sm-theme="dark"] tr.table-secondary .text-muted {
    color: #adb5bd !important;
}

/* Bootstrap's default .text-danger (#dc3545) is nowhere near readable on the stripe above - and
   "Unpaid"/"Unassigned" are exactly the cells an operator needs to catch at a glance. It was
   #96101F when the stripe was the lighter #A6CAB3; against today's #94B59D that only reaches
   3.9:1, so it is deepened again to #7E0D18 - 4.8:1 on the stripe and 8.5:1 on the #D7EADC rows
   between them, i.e. AA on both halves of the alternation rather than just the pale one.
   !important is needed because Bootstrap's own .text-danger utility is itself !important. */
.table .text-danger {
    color: #7E0D18 !important;
}

/* Alerting that used to be a background highlight and is now type instead - see the Invoiced /
   Paid columns on Active Orders. A background could be covered by a row stripe or a contextual
   row class; bold type on the value itself cannot be. */
.sm-alert-text {
    color: #7E0D18;
    font-weight: 700;
}

[data-sm-theme="dark"] .sm-alert-text {
    color: #ff8087;
}

/* Dark mode's stripes are low-alpha tints over a dark ground, so red type needs to go lighter
   rather than deeper - the opposite of the adjustment above. */
[data-sm-theme="dark"] .table .text-danger {
    color: #ff8087 !important;
}

/* ---------- Brand-colored success buttons (e.g. Drop Proof) ---------- */

.btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: #54C5A4;
    --bs-btn-border-color: #54C5A4;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #47A78B;
    --bs-btn-hover-border-color: #47A78B;
    --bs-btn-focus-shadow-rgb: 84, 197, 164;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #429A80;
    --bs-btn-active-border-color: #429A80;
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: #54C5A4;
    --bs-btn-disabled-border-color: #54C5A4;
}

.sm-search-result-row {
    cursor: pointer;
}

/* ---------- Sticky "unsaved changes" footer (Order page) ---------- */

.sm-save-footer {
    position: fixed;
    left: var(--sm-sidebar-width);
    right: 0;
    bottom: 0;
    z-index: 1020;
    /* Same light yellow as the Driver Schedule delivery notes - this bar exists to say "you have
       unsaved work", so it should read as a warning rather than as more page chrome. Literal
       colors for the same reason as .sm-driver-note: inverting the wash for dark mode would lose
       the very emphasis it exists to create. */
    background-color: #FDF3C7;
    border-top: 1px solid #E9D68A;
    box-shadow: 0 -2px 10px rgba(20, 25, 45, 0.12);
    padding: 0.75rem 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    animation: sm-save-footer-in 0.25s ease-out;
}

.sm-save-footer-msg {
    font-size: 0.9rem;
    /* Black rather than the muted token - the token is near-white in dark mode and would vanish
       against the fixed yellow ground above. */
    color: #000;
}

@keyframes sm-save-footer-in {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

@media (max-width: 991.98px) {
    .sm-save-footer {
        left: 0;
    }
}

/* ---------- Transient "Saved" toast (auto-save actions with no explicit Save button) ---------- */

.sm-toast-saved {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1080;
    background-color: var(--sm-success);
    color: #fff;
    padding: 0.6rem 1rem;
    border-radius: var(--sm-radius);
    box-shadow: var(--sm-shadow);
    font-size: 0.9rem;
    font-weight: 600;
    animation: sm-toast-in 0.2s ease-out;
}

@keyframes sm-toast-in {
    from { transform: translate(-50%, -50%) scale(0.95); opacity: 0; }
    to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

/* ---------- Stackable toast host (ToastHost.razor) - same look as sm-toast-saved above, but
   multiple can be visible at once (e.g. "Order saved" + "Saved to Business Central" together) ---------- */

.sm-toast-stack {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1080;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
}

.sm-toast-item {
    background-color: var(--sm-success);
    color: #fff;
    padding: 0.6rem 1rem;
    border-radius: var(--sm-radius);
    box-shadow: var(--sm-shadow);
    font-size: 0.9rem;
    font-weight: 600;
    animation: sm-toast-stack-in 0.2s ease-out;
}

.sm-toast-item.sm-toast-warning {
    background-color: var(--sm-warning);
    color: #1a1a1a;
}

.sm-toast-item.sm-toast-danger {
    background-color: var(--sm-danger);
    color: #fff;
}

/* Catches a click anywhere off a dismissible toast. Transparent and unpainted - it exists only
   to be clicked. Sits just under the toast stack (1080) so the toast itself stays clickable, and
   above the modal backdrop (1050) so it still works over an open modal, which is exactly where
   the change-note toast appears. */
.sm-toast-dismiss-layer {
    position: fixed;
    inset: 0;
    z-index: 1079;
}

.sm-toast-item.sm-toast-dismissible {
    cursor: pointer;
}

/* Punctuation, not iconography: smaller than the words they enclose and set back from them, so
   the pair reads as quotation marks rather than as two glyphs bolted either end. The closing
   mark lifts to the top of the line the way a real closing quote does. */
.sm-toast-quote {
    font-size: 0.75em;
    opacity: 0.75;
    vertical-align: top;
}

.sm-toast-quote.fa-quote-left {
    margin-right: 0.3em;
}

.sm-toast-quote.fa-quote-right {
    margin-left: 0.3em;
}

/* Neutral variant, for a toast that is showing somebody CONTENT rather than reporting how an
   action went - a green tick beside a change note would read as "saved". */
.sm-toast-item.sm-toast-info {
    background-color: var(--sm-primary);
    color: #fff;
    font-weight: 500;
    text-align: left;
}

/* Toasts normally carry a short sentence, but a change note can run to a paragraph and would
   otherwise stretch the toast from one edge of the screen to the other.

   Line breaking is split deliberately between the two rules below. pre-wrap belongs on the
   MESSAGE, not on the toast: on the toast it also preserved the newlines in the component's own
   markup, so the opening quote, the text and the closing quote each landed on a line of their
   own and "QB INV" came out three lines tall. The message keeps pre-wrap so a note somebody
   typed with line breaks still shows them. */
.sm-toast-item {
    max-width: min(90vw, 34rem);
    overflow-wrap: break-word;
}

.sm-toast-message {
    white-space: pre-wrap;
}

/* Separate from sm-toast-in above - a stack item is already centered by its sm-toast-stack parent,
   so its own entrance animation only needs to scale in place, not re-apply the -50%/-50% translate. */
@keyframes sm-toast-stack-in {
    from { transform: scale(0.95); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

/* ---------- Weekly Dispatch: BOL hover popover (anchored near the cursor, not a full-screen
   modal - shows on mouseenter, hides on mouseleave unless the pointer moves onto the popover
   itself, per WeeklyDispatchPage's hover-tolerance close logic) ---------- */

.sm-bol-popover {
    position: fixed;
    z-index: 1095;
    width: 280px;
    max-width: calc(100vw - 20px);
    background-color: var(--sm-card-bg);
    color: var(--sm-text);
    border: 1px solid var(--sm-border);
    border-radius: var(--sm-radius);
    box-shadow: var(--sm-shadow);
    padding: 0.9rem;
}

.sm-bol-popover-body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.sm-bol-popover-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}

.sm-bol-popover-row i {
    width: 1rem;
    text-align: center;
    color: var(--sm-primary);
    flex-shrink: 0;
}

.sm-bol-popover-label {
    color: var(--sm-text-muted);
    flex-shrink: 0;
}

/* The drops row's address list can wrap to multiple lines - align the icon to the top of the
   list instead of the default baseline alignment used by every other (single-line) row. */
.sm-bol-popover-row-top {
    align-items: flex-start;
}

.sm-bol-popover-drops {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* ---------- Contacts expand/collapse toggle (Admin > Customers) ---------- */

.sm-contacts-toggle {
    width: 1.75rem;
    height: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ================= Order page look and feel =================================================
   Scoped to .sm-order-page on purpose. This is the designer's treatment for the order page only;
   every other page keeps the existing card styling until we choose to port it across. Nothing in
   here changes behaviour - it is all presentation.
   ========================================================================================== */

.sm-order-page {
    /* The page opens straight onto the first card, with no heading above it. .sm-content already
       pads 1.5rem, so this trims it to the 20px gap we want below the top bar. */
    margin-top: -0.25rem;

    --sm-order-green: #1c5336;
    --sm-order-green-dark: #14402a;
    /* Green painted ON the page (outline buttons, the drop title, tile icons) as opposed to behind
       white type. Identical in light mode; lifted in dark. See the dark block at the foot of this
       file. */
    --sm-order-green-on: #1c5336;
    --sm-order-tint: #eef5f0;
    --sm-order-border: #d7e3da;
}

/* Cards get a definite edge, since the page is a stack of them. */
.sm-order-page .sm-card {
    border: 1px solid var(--sm-order-border);
    border-radius: 0.75rem;
    overflow: visible;
}

/* The header row itself is plain - the green tab inside it carries the look. No vertical padding:
   the tab sets the row's height, so every section header is the same height whether or not it
   carries tickboxes or buttons. */
.sm-order-page .sm-card-header {
    background: transparent;
    border-bottom: 1px solid var(--sm-order-border);
    padding: 0 1rem 0 0;
    display: flex;
    align-items: center;
    /* Tight: the tab's slanted edge already leaves a wedge of space, so a wide gap on top of it
       pushed the first control (Complete) well away from the heading. */
    gap: 0.35rem;
    min-height: 0;
}

/* Controls that ride in a section header - tickboxes and buttons - add no height of their own. */
.sm-order-page .sm-card-header .form-check {
    margin: 0;
    padding-top: 0;
    padding-bottom: 0;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.sm-order-page .sm-card-header .form-check .form-check-input {
    margin: 0;
    float: none;
}

.sm-order-page .sm-card-header .form-check-label {
    margin: 0;
    font-size: 0.765em;
}

/* Matching the label: 90% of Bootstrap's 1em box. */
.sm-order-page .sm-card-header .form-check .form-check-input {
    width: 0.9em;
    height: 0.9em;
}

/* A label with chips beside it (the unpaid and credit-limit alerts next to Customer). The row is
   held to the label's line height and bottom-aligned, so a chip taller than the label overhangs
   upward into the gap above rather than making the row taller and shoving the field down. */
.sm-order-page .sm-label-with-badges {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    height: 1rem;
    margin-bottom: 3px;
}

.sm-order-page .sm-label-badge {
    font-size: 0.65rem;
    line-height: 1.1;
    padding: 1px 5px;
    white-space: nowrap;
}

/* A small button sitting beside a label or heading - the "edit" buttons next to Customer Name and
   Contact Name. Same type size and shape as the buttons in the section headers, so the page has one
   small-button look rather than several. */
.sm-order-page .sm-chip-btn {
    font-size: 0.75rem;
    line-height: 1.4;
    /* Same padding as the section-header buttons, so "edit" and "Use Customer Contact" are the
       same size wherever they appear. */
    padding: 0 0.7rem;
}

/* Buttons riding in a section header use exactly the same styling as the chip buttons in the card
   bodies - one small-button look across the whole page. (An earlier stretch-to-row-height rule lived
   here; it never took effect, and matching the chips is what was wanted anyway.)

   The 1px margin is the point of the rule as much as the padding: the button is the tallest thing
   in the header row, so it sets the row's height and would otherwise sit flush against the card's
   top border and the header's bottom rule. The margin buys exactly 1px of air on each side. */
.sm-order-page .sm-card-header .btn {
    font-size: 0.75rem;
    line-height: 1.4;
    padding: 0 0.7rem;
    margin: 1px 0;
}

/* The created note sits on the dark tab, so it reads in a light yellow rather than the link blue. */
.sm-order-page .sm-created-note {
    color: #ffe9a3;
    font-size: 74%;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    margin-left: 0.5rem;
    /* Nudged down so its smaller text sits on the heading's baseline rather than riding high. */
    position: relative;
    top: 2px;
}

/* Vertical gaps between field rows. Bootstrap's g-3/g-2 set 1rem/0.5rem; this page is dense enough
   that the space between a field and the next row's label only needs to separate them, not frame
   them. Horizontal gutters are left alone. */
.sm-order-page .row.g-3,
.sm-order-page .row.g-2 {
    --bs-gutter-y: 5px;
}

/* Blocks of fields are separate .row elements, each with mb-3 (1rem). Zeroed here so the space
   between the last field of one block and the next block's label is the row gutter alone - the same
   5px as between rows inside a block - instead of the gutter stacked on top of a margin. */
.sm-order-page .sm-card-body .row.mb-3 {
    /* !important is needed: Bootstrap's spacing utilities declare their own !important, so a plain
       override here is ignored no matter how specific it is. */
    margin-bottom: 5px !important;
}

.sm-order-page .sm-card-body {
    padding: 0.85rem 1rem;
}

/* Buttons pick up the section-tab green instead of Bootstrap's blue. The sticky save footer is
   styled alongside them: it belongs to the order page but renders outside the .sm-order-page
   wrapper (it is pinned to the window), so it would otherwise keep the blue button. */
.sm-order-page .btn-primary,
.sm-save-footer .btn-primary {
    background: linear-gradient(180deg, var(--sm-order-green) 0%, var(--sm-order-green-dark) 100%);
    border-color: var(--sm-order-green-dark);
    color: #fff;
}

.sm-order-page .btn-primary:hover:not(:disabled),
.sm-order-page .btn-primary:focus:not(:disabled),
.sm-save-footer .btn-primary:hover:not(:disabled),
.sm-save-footer .btn-primary:focus:not(:disabled) {
    background: var(--sm-order-green-dark);
    border-color: var(--sm-order-green-dark);
    box-shadow: 0 0 0 0.15rem rgba(28, 83, 54, 0.25);
}

/* The footer is outside .sm-order-page, so it needs the colours spelled out rather than inherited. */
.sm-save-footer .btn-primary {
    --sm-order-green: #1c5336;
    --sm-order-green-dark: #14402a;
}

/* The row/drop remove buttons. Green like the rest of the page - note these are the destructive
   controls (remove a sod line, remove a drop), so they no longer read as a warning; the unpaid and
   credit-limit chips keep their red, since that red carries meaning. */
.sm-order-page .btn-outline-danger:not(.sm-label-badge) {
    color: var(--sm-order-green-on);
    border-color: var(--sm-order-green-on);
}

.sm-order-page .btn-outline-danger:not(.sm-label-badge):hover:not(:disabled) {
    background-color: var(--sm-order-green);
    border-color: var(--sm-order-green);
    color: #fff;
}

.sm-order-page .btn-outline-primary {
    color: var(--sm-order-green-on);
    border-color: var(--sm-order-green-on);
}

.sm-order-page .btn-outline-primary:hover:not(:disabled) {
    background-color: var(--sm-order-green);
    border-color: var(--sm-order-green);
    color: #fff;
}

/* The tab: green, notched on its right edge, sitting flush with the card's top-left corner. */
.sm-order-page .sm-section-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: linear-gradient(180deg, var(--sm-order-green) 0%, var(--sm-order-green-dark) 100%);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.5rem 1.6rem 0.5rem 1.1rem;
    margin: -0.55rem 0 -0.55rem 0;
    border-top-left-radius: 0.7rem;
    /* Slants the trailing edge, which is what gives it the tab shape rather than a plain bar. */
    clip-path: polygon(0 0, calc(100% - 0.9rem) 0, 100% 100%, 0 100%);
}

/* 120% of the old 0.85rem. line-height 1 keeps the taller glyph from growing the tab: at its
   natural line height it would sit in a box taller than the heading text's and push the band open. */
.sm-order-page .sm-section-tab i {
    font-size: 1.02rem;
    line-height: 1;
    color: #f2efc2;
}

/* Fields: quieter labels, softly tinted inputs, green focus instead of Bootstrap blue. */
/* display:block matters: as Bootstrap's inline-block, the label sat in a line box whose descender
   added ~3px under it that no margin could remove, so the spacing below could not be set exactly. */
.sm-order-page .form-label {
    font-size: 0.78rem;
    font-weight: 700;
    color: #3d4753;
    display: block;
    line-height: 1.25;
    margin-bottom: 3px;
}

.sm-order-page .form-control,
.sm-order-page .form-select {
    border-color: var(--sm-order-border);
    border-radius: 0.5rem;
    background-color: #fbfdfc;
}

.sm-order-page .form-control:focus,
.sm-order-page .form-select:focus {
    border-color: var(--sm-order-green);
    box-shadow: 0 0 0 0.15rem rgba(28, 83, 54, 0.15);
}

.sm-order-page .form-control:disabled,
.sm-order-page .form-control[readonly],
.sm-order-page .form-select:disabled {
    background-color: #eef1ef;
}

/* The order page's zebra stripes used to be overridden here. Those greens are the app-wide
   stripes now (see the global rule earlier in this file), so this page just inherits them. */

/* Ticked checkboxes and the Flat Rate switch take the page's green rather than Bootstrap's blue. */
.sm-order-page .form-check-input:checked {
    background-color: var(--sm-order-green);
    border-color: var(--sm-order-green);
}

.sm-order-page .form-check-input:focus {
    border-color: var(--sm-order-green);
    box-shadow: 0 0 0 0.15rem rgba(28, 83, 54, 0.15);
}

/* Leading icon inside a field (calendar, phone, address and so on). */
.sm-order-page .input-group-text {
    background-color: #f3f7f4;
    border-color: var(--sm-order-border);
    border-right: 0;
    color: var(--sm-order-green);
    padding-right: 0.4rem;
}

.sm-order-page .input-group .form-control,
.sm-order-page .input-group .form-select {
    border-left: 0;
    padding-left: 0.25rem;
}

/* Drop heading inside Order Info - a label beside the tab, not a second heading, so it is lighter
   and slightly smaller than the surrounding header text and carries no divider. */
.sm-order-page .sm-drop-title {
    font-weight: 400;
    font-size: 0.9em;
    color: var(--sm-order-green-on);
    padding-left: 0.5rem;
}

/* Order total tiles. */
.sm-order-page .sm-total-tile {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--sm-order-tint);
    border: 1px solid var(--sm-order-border);
    border-radius: 0.6rem;
    padding: 0.75rem 1rem;
    height: 100%;
}

.sm-order-page .sm-total-tile i {
    font-size: 1.15rem;
    color: var(--sm-order-green-on);
}

.sm-order-page .sm-total-tile-label {
    font-size: 0.75rem;
    color: #55606d;
    font-weight: 600;
}

.sm-order-page .sm-total-tile-value {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--sm-text);
}

/* The grand total reads as the answer to the page, so it inverts. */
.sm-order-page .sm-total-tile-primary {
    background: linear-gradient(180deg, var(--sm-order-green) 0%, var(--sm-order-green-dark) 100%);
    border-color: var(--sm-order-green-dark);
}

.sm-order-page .sm-total-tile-primary i,
.sm-order-page .sm-total-tile-primary .sm-total-tile-label,
.sm-order-page .sm-total-tile-primary .sm-total-tile-value {
    color: #fff;
}

.sm-order-page .sm-total-tile-primary .sm-total-tile-value {
    font-size: 1.35rem;
}

[data-sm-theme="dark"] .sm-order-page {
    --sm-order-tint: #1b2a22;
    --sm-order-border: #2c4436;
    /* Outline buttons, the drop title and the tile icons all paint green onto the page rather than
       behind white type, so they lift clear of the dark ground. The filled controls above keep the
       deep green. */
    --sm-order-green-on: #7CC79B;
}

[data-sm-theme="dark"] .sm-order-page .form-control,
[data-sm-theme="dark"] .sm-order-page .form-select {
    background-color: #151a24;
}

[data-sm-theme="dark"] .sm-order-page .form-control:disabled,
[data-sm-theme="dark"] .sm-order-page .form-control[readonly],
[data-sm-theme="dark"] .sm-order-page .form-select:disabled {
    background-color: #1b2029;
}

[data-sm-theme="dark"] .sm-order-page .input-group-text {
    background-color: #1b2029;
    color: var(--sm-order-green-on);
}

[data-sm-theme="dark"] .sm-order-page .sm-total-tile-value {
    color: var(--sm-text);
}

/* Both of these are fixed mid-greys chosen against a white card. On a dark card they are barely
   above the background, and the field labels are the page's main orientation cue. */
[data-sm-theme="dark"] .sm-order-page .form-label {
    color: #b8c2cc;
}

[data-sm-theme="dark"] .sm-order-page .sm-total-tile-label {
    color: #a9b4bf;
}

/* ================= Dark mode: the rest =====================================================
   Everything above this point either uses the themed tokens (and so follows the switch for free)
   or is a fixed colour that was chosen to work in both modes. What is left here is the surfaces
   that were hard-coded light because, until now, light was the only mode the app really had.
   ========================================================================================== */

/* ---------- the account-menu toggle's own label ----------
   Both wordings ship in the markup; this is what picks one. It has to work without a server
   round-trip, because flipping the theme never touches the server. */

.sm-when-dark { display: none; }

[data-sm-theme="dark"] .sm-when-dark { display: inline; }
[data-sm-theme="dark"] .sm-when-light { display: none; }

/* ---------- links ----------
   app.css pins every link to #006bb7, which is 3.2:1 on the dark body background - under the 4.5:1
   a link needs, and links are the app's main means of getting anywhere.

   The exclusions are wrapped in :where() so they add NO specificity: this rule has to out-rank
   app.css's bare `a` and nothing else. Written as plain :not() it scored (0,5,1) and quietly beat
   the page skins, turning the schedule pages' deliberately green BOL links Bootstrap blue. At
   (0,1,1) any skin that sets its own link colour still wins, which is the point. */
[data-sm-theme="dark"] a:where(:not(.btn):not(.sm-sidebar-link):not(.nav-link):not(.dropdown-item):not(.sm-excel-link)),
[data-sm-theme="dark"] .btn-link:where(:not(.sm-excel-link)) {
    color: #6cb6ff;
}

[data-sm-theme="dark"] a:where(:not(.btn):not(.sm-sidebar-link):not(.nav-link):not(.dropdown-item):not(.sm-excel-link)):hover,
[data-sm-theme="dark"] .btn-link:where(:not(.sm-excel-link)):hover {
    color: #9ccdff;
}

/* ---------- Driver PTO calendar ----------
   The hover tint was deliberately fixed in both modes, on the reasoning that the cue should not
   move. It can't stay: the day's number and its PTO entries take --sm-text, which is near-white in
   dark mode, so hovering a day turned its own contents invisible. Same cue, dark enough to carry
   light type. */
[data-sm-theme="dark"] .sm-pto-calendar-cell:hover {
    background-color: #2F4A36;
}

/* ---------- surfaces that stay white on purpose ----------
   A signature is ink on paper - it is captured, printed and filed as a white-background image, so
   the pad keeps its white ground in both modes. It only needs a border that reads against a dark
   page, and black ink that cannot inherit the light body colour. */
[data-sm-theme="dark"] .sm-sig-canvas,
[data-sm-theme="dark"] .sm-signature-image {
    border-color: #5b6478;
    color: #000;
}

/* ---------- Bootstrap helpers that hard-code a light ground ---------- */

/* .bg-white has the same problem .bg-light had: the panel stays white while the type inside it
   turns light, leaving light-on-light. */
[data-sm-theme="dark"] .bg-white {
    background-color: var(--sm-card-bg) !important;
}

/* .sm-driver-note and .sm-save-footer keep their light yellow in both modes on purpose - they exist
   to be the one highlighted thing on screen, and inverting them would lose exactly that. Both
   already pin their own type to black, so neither needs anything here. */

/* ---------- a disabled dropdown on the Order page ----------
   The Pallet Cap select switches off for Rolls and Pieces, which don't sit on a pallet. It was
   taking a near-white fill (#eef1ef) barely distinguishable from an editable field, so it read as an
   empty dropdown someone had forgotten to fill in rather than one that doesn't apply - which is
   exactly the confusion that let a genuinely missing capacity go unnoticed on order 40161.

   Grayed properly: a flat gray fill, muted type, and a cursor that says so on hover. Applies to any
   disabled select on the page, not just this one - they all mean the same thing. These sit after the
   .sm-order-page block above deliberately; they share its specificity, so source order is what
   decides. */

.sm-order-page .form-select:disabled {
    background-color: #dfe3e0;
    color: var(--sm-text-muted);
    cursor: not-allowed;
}

[data-sm-theme="dark"] .sm-order-page .form-select:disabled {
    background-color: #222731;
    color: var(--sm-text-muted);
}

/* ---------- Order approval status (Components/Orders/OrderApprovalContactPanel.razor) ----------
   Reports where an order stands: approved, waiting on the customer, or never texted. Shaped like
   the buttons it sits beside so the row reads as one strip, but it is a span and not a control -
   default cursor, no hover, so nobody tries to click it.

   Sized off the same values as .sm-order-page .btn (0.75rem / 1.4 / 0 0.7rem) so it lines up with
   Resend Text and Log rather than sitting a pixel proud of them. The border carries the meaning and
   the fill stays transparent: these sit on a card whose background differs between the two themes,
   and an outline reads the same on both. */

.sm-approval-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.4;
    padding: 0.25rem 0.7rem;
    border: 2px solid currentColor;
    border-radius: 0.375rem;
    background: transparent;
    white-space: nowrap;
    cursor: default;
    user-select: none;
}

/* currentColor on the border above means each state only has to set one value. */
.sm-approval-approved { color: #1c5336; }
.sm-approval-awaiting { color: #8a6100; }
.sm-approval-none     { color: #6b7280; }

/* The amber needs to stay legibly amber rather than drifting brown, and the deep green would be
   1.6:1 on a dark card - both lift, the grey along with them. */
[data-sm-theme="dark"] .sm-approval-approved { color: #7CC79B; }
[data-sm-theme="dark"] .sm-approval-awaiting { color: #FBBF24; }
[data-sm-theme="dark"] .sm-approval-none     { color: #9aa1b5; }

/* The "Approved 9/21/26 at 11:15 AM" line under the strip - supporting detail for the badge above,
   so it is quieter than the field labels around it. */
.sm-approval-when {
    font-size: 0.7rem;
    color: var(--sm-text-muted);
    margin-top: 4px;
}

/* ---------- sod / invoice basis picker (Components/Shared/SalesBasisPicker.razor) ----------
   Sits in a card header between the title and the view buttons, so it is held to the same small
   type as those buttons and kept on one line - wrapping mid-header would push the chart down. */

.sm-basis-picker {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

.sm-basis-picker .form-check {
    margin-bottom: 0;
}

.sm-basis-picker .form-check-label {
    font-size: 0.8rem;
    font-weight: 600;
}

/* A caveat sitting under a chart - quieter than the axis labels above it, since it is read once
   and then ignored, but it has to stay legible in both themes. */
.sm-chart-footnote {
    font-size: 0.68rem;
    line-height: 1.35;
    color: var(--sm-text-muted);
    margin-top: 0.5rem;
}

/* A quiet aside next to a card title - e.g. which date a chart is grouped by. Deliberately lighter
   and smaller than the title it follows: it answers a question people have once and then stop
   asking, so it should not compete with the heading. */
.sm-card-subnote {
    font-size: 0.72rem;
    font-weight: 400;
    color: var(--sm-text-muted);
    margin-left: 0.35rem;
}

/* The legend's year chips show that series' total on hover (see GroupedBarChart) - they need to be
   a positioning context for the tooltip, and to not look clickable. */
.sm-legend-item {
    position: relative;
    cursor: default;
}

.sm-legend-item:hover .sm-barchart-tooltip {
    display: block;
}

/* A caveat under a single bar's label - e.g. that the current year includes bookings dated after
   today. Wraps on purpose: it is a sentence, not an axis label, and it only ever appears on one
   bar so the extra height costs the chart nothing. */
.sm-barchart-sublabel {
    /* Absolutely positioned, and that is the whole point. In flow it added its own height to the one
       column that carries it, which shortened that column's bar track - so the annotated bar sat
       visibly above the baseline every other bar shared. Anchored to the column rather than to the
       label, because the label sets overflow:hidden and would clip it. */
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 11rem;
    font-size: 0.6rem;
    line-height: 1.15;
    color: var(--sm-text-muted);
    text-align: center;
    margin-top: 2px;
}

.sm-barchart-col {
    position: relative;
}

/* Room for the out-of-flow caveat above, only on a chart that actually has one. */
.sm-barchart-has-sublabels {
    margin-bottom: 1.9rem;
}

/* ---------- inline help popover, outside the schedule pages ----------
   HelpPopover was built for the schedule skin and its styling lived under .sm-schedule-page, so it
   rendered unstyled anywhere else. These are the same rules against the app's own tokens; the
   schedule-scoped versions are more specific and still win on those pages, so nothing there moves. */

.sm-sched-help-wrap {
    position: relative;
    display: inline-flex;
}

.sm-sched-help-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--sm-text-muted);
    font-size: 0.9rem;
    line-height: 1;
}

.sm-sched-help-btn:hover {
    color: var(--sm-text);
}

.sm-sched-help-bubble {
    position: absolute;
    top: calc(100% + 8px);
    left: -8px;
    z-index: 20;
    outline: none;
    width: 320px;
    max-width: 80vw;
    padding: 0.7rem 2rem 0.7rem 0.9rem;
    background: var(--sm-card-bg);
    border: 1px solid var(--sm-border);
    border-radius: 10px;
    box-shadow: var(--sm-shadow);
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.45;
    color: var(--sm-text);
    text-align: left;
    white-space: normal;
}

.sm-help-close {
    position: absolute;
    top: 0.5rem;
    right: 0.6rem;
    font-size: 0.65rem;
}

/* ---------------------------------------------------------------------------
   Audit Trail modal.

   The old/new columns are the whole point of the table, so they are tinted -
   but through colour-mix against the card's own background rather than fixed
   pastels, so the tint survives the dark theme instead of turning into a pale
   block with near-white text on it, which is how every other table on this site
   first broke.
   --------------------------------------------------------------------------- */
.sm-audit-old,
.sm-audit-new {
    font-variant-numeric: tabular-nums;
}

.sm-audit-old {
    color: color-mix(in srgb, var(--bs-body-color) 72%, transparent);
    text-decoration: line-through;
    text-decoration-color: color-mix(in srgb, var(--bs-body-color) 35%, transparent);
}

.sm-audit-new {
    font-weight: 600;
}

/* The chip always sits on its own line under the description, so the What column reads the same
   whether the wording is "Edited" or "Taken off the schedule". */
.sm-audit-chip-line {
    margin-top: 0.2rem;
}

/* The same chip as below, but interactive - the note chip opens the full text, the drop proof
   chip opens the photo. Given a pointer and a hover lift so neither looks like the inert badges
   beside it. */
button.badge.sm-audit-source,
a.badge.sm-audit-source {
    cursor: pointer;
    text-decoration: none;
}

button.badge.sm-audit-source:hover,
button.badge.sm-audit-source:focus-visible,
a.badge.sm-audit-source:hover,
a.badge.sm-audit-source:focus-visible {
    color: var(--bs-body-color);
    border-color: color-mix(in srgb, var(--bs-body-color) 55%, transparent);
}

.badge.sm-audit-source {
    /* Marks a row the audit trail did not capture itself but read back out of an older table -
       worth distinguishing, not worth shouting about, hence a muted outline rather than a colour. */
    font-weight: 500;
    color: var(--bs-secondary-color);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--bs-body-color) 25%, transparent);
}
