/* ==========================================================================
   Tank Tracker
   The Jobtracker house style applied to MudBlazor: a dense, keyboard-friendly
   business UI. The density is deliberate — this replaces a WinForms MDI
   application whose users work in long grids all day.

   Colours are NOT declared here. They come from Infrastructure/AppTheme.cs as
   --mud-palette-* variables, so light and dark are one palette and nothing
   below needs a dark-mode variant of its own. The few house tokens that
   MudBlazor has no slot for are aliased at the top.
   ========================================================================== */

:root {
    /* Aliases onto the theme, so the rules below read like the Jobtracker sheet. */
    --surface: var(--mud-palette-surface);
    --surface-2: var(--mud-palette-background-gray);
    --surface-3: var(--mud-palette-divider-light);
    --page: var(--mud-palette-background);

    --ink-900: var(--mud-palette-text-primary);
    --ink-700: var(--mud-palette-text-secondary);
    --ink-500: var(--mud-palette-text-secondary);
    --ink-300: var(--mud-palette-text-disabled);

    --line: var(--mud-palette-lines-default);
    --line-strong: var(--mud-palette-lines-inputs);
    --accent: var(--mud-palette-primary);
    --accent-dark: var(--mud-palette-primary-darken);
    --accent-soft: var(--mud-palette-primary-lighten);

    /* House values with no MudBlazor equivalent. The rail keeps its dark
       treatment in both themes, so these need no light/dark pair. */
    --brand: #98c060;
    --nav-ink: #cfdbe8;
    --nav-ink-dim: #6d859e;
    --nav-hover: rgba(255, 255, 255, .06);
    --nav-line: rgba(255, 255, 255, .08);

    --shadow-sm: 0 1px 2px rgba(18, 37, 58, .08);

    --radius: 6px;
    --radius-lg: 10px;

    --mono: "Cascadia Mono", Consolas, "SF Mono", monospace;
}

/* -------------------------------------------------------------- base type -- */

html, body {
    font-size: 13.5px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
}

/* Headings carry the page, not the Material scale. */
.mud-typography-h1, .mud-typography-h2, .mud-typography-h3,
.mud-typography-h4, .mud-typography-h5, .mud-typography-h6 {
    margin: 0;
}

.mono { font-family: var(--mono); font-size: 12px; }
.muted { color: var(--ink-500); }
.small { font-size: 11.5px; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.neg { color: var(--mud-palette-error); }
.pos { color: var(--mud-palette-success); }

/* ------------------------------------------------------------------ shell -- */

/* A rule under the bar rather than a coloured band, as in Jobtracker. */
.mud-appbar {
    border-bottom: 1px solid var(--line);
    box-shadow: none !important;
}

.mud-appbar .mud-toolbar {
    min-height: 52px;
    height: 52px;
    padding-inline: 12px;
}

.mud-drawer {
    border-right: none;
    overflow-y: hidden;
}

.mud-drawer .mud-navmenu {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.mud-drawer .mud-navmenu::-webkit-scrollbar { width: 8px; }
.mud-drawer .mud-navmenu::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .12);
    border-radius: 4px;
}

/* The brand block at the head of the rail, level with the top bar. */
.nav-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 52px;
    padding: 0 16px;
    border-bottom: 1px solid var(--nav-line);
    flex: 0 0 auto;
}

.nav-brand .mark {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    overflow: hidden;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
}

.nav-brand .mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
.nav-brand .name { color: #fff; font-weight: 600; font-size: 14px; line-height: 1.1; }
.nav-brand .tenant { color: var(--nav-ink-dim); font-size: 11px; }

.nav-section {
    padding: 12px 16px 4px;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--nav-ink-dim);
    font-weight: 600;
}

/* Navigation links: flat, dense, with the brand marking the current page. */
.mud-nav-link.mud-ripple {
    padding: 7px 16px;
    font-size: 13px;
    color: var(--nav-ink);
    border-left: 3px solid transparent;
    min-height: 0;
}

.mud-nav-link.mud-ripple:hover {
    background: var(--nav-hover);
    color: #fff;
}

.mud-nav-link.active {
    background: rgba(152, 192, 96, .18) !important;
    border-left-color: var(--brand);
    color: #fff !important;
    font-weight: 600;
}

.mud-nav-link .mud-nav-link-icon { min-width: 26px; }
.mud-nav-link .mud-icon-root { font-size: 17px; opacity: .85; }

.mud-nav-group .mud-nav-link { padding-left: 26px; }

.nav-footer {
    margin-top: auto;
    flex: 0 0 auto;
    border-top: 1px solid var(--nav-line);
    padding: 10px 16px;
    font-size: 11px;
    color: var(--nav-ink-dim);
    display: grid;
    gap: 2px;
}

/* The icon rail (Feedback #293): the sidebar collapsed on a desktop. MudBlazor's mini
   drawer keeps the icons and hides each link's label; what is ours to hide is the rest
   of the brand block, the section headings and the version line, none of which fits in
   56px. Each icon is centred in the rail, and carries the page's name as a tooltip. */
.mud-drawer--closed.mud-drawer-mini .nav-brand {
    padding: 0;
    justify-content: center;
}

.mud-drawer--closed.mud-drawer-mini .nav-brand > :not(.mark),
.mud-drawer--closed.mud-drawer-mini .nav-section,
.mud-drawer--closed.mud-drawer-mini .nav-footer { display: none; }

.mud-drawer--closed.mud-drawer-mini .mud-nav-link.mud-ripple {
    padding: 9px 0;
    justify-content: center;
}

.mud-drawer--closed.mud-drawer-mini .mud-nav-link .mud-nav-link-icon {
    min-width: 0;
    margin: 0;
}

/* The tooltip's wrapper is a block, so a link inside it fills the sidebar's width. */
.nav-tip { display: block; }

/* Search from anywhere, as in Jobtracker's top bar. */
.global-search {
    position: relative;
    width: min(420px, 34vw);
}

.global-search input {
    width: 100%;
    height: 32px;
    padding: 0 10px 0 32px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--ink-900);
    font-family: inherit;
    font-size: 13px;
}

.global-search input::placeholder { color: var(--ink-300); }

.global-search input:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    background: var(--surface);
}

.global-search .mud-icon-root {
    position: absolute;
    left: 9px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 16px;
    color: var(--ink-300);
    pointer-events: none;
}

@media (max-width: 900px) { .global-search { display: none; } }

/* The signed-in user, as a chip rather than a bare icon button. */
.user-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 8px 3px 3px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface-2);
    cursor: pointer;
    color: var(--ink-900);
    text-transform: none;
}

.user-chip .avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--brand);
    color: #22350f;
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 700;
}

.user-chip .who { line-height: 1.15; text-align: left; }
.user-chip .who strong { display: block; font-size: 12.5px; font-weight: 600; }
.user-chip .who span { font-size: 11px; color: var(--ink-500); }

@media (max-width: 700px) {
    .user-chip .who { display: none; }
}

/* The automated-job lights beside the user chip (Feedback #540): an icon per job, with a
   dot for its state. Prefixed so no MudBlazor palette class can collide with them. */
.automation-status { display: flex; align-items: center; gap: 4px; }

.automation-status-light {
    position: relative;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    color: var(--ink-700);
    text-decoration: none;
}

a.automation-status-light:hover { background: var(--surface-2); }

.automation-status-dot {
    position: absolute;
    right: 3px;
    bottom: 4px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    border: 1.5px solid var(--surface);
}

.automation-status-dot.is-ok { background: #2e9e4f; }
.automation-status-dot.is-running { background: #1e88e5; animation: automation-status-pulse 1.4s ease-in-out infinite; }
.automation-status-dot.is-overdue { background: #f0a020; }
.automation-status-dot.is-failed { background: #d93636; }
.automation-status-dot.is-off { background: #9aa4ae; }

@keyframes automation-status-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .automation-status-dot.is-running { animation: none; }
}

.automation-status-tip { text-align: left; line-height: 1.4; max-width: 340px; }

/* The page banner's buttons: the record's own, a rule, then Back and Save. */
.page-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-left: auto;
}

.page-actions-group {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.page-actions-sep {
    width: 1px;
    align-self: stretch;
    min-height: 24px;
    background: var(--line-strong);
}

/* A new record has no actions of its own, so there is nothing to separate. */
.page-actions-group:empty + .page-actions-sep,
.page-actions-group:not(:has(*)) + .page-actions-sep { display: none; }

/* Nothing to separate on a narrow screen where the groups have wrapped apart. */
@media (max-width: 700px) {
    .page-actions-sep { display: none; }
}

/* ---------------------------------------------------------------- cards --- */

.mud-main-content,
.mud-appbar-dense ~ .mud-main-content {
    padding: calc(var(--mud-appbar-height) + 16px) 16px 24px;
}

/* Outlined panels rather than floating cards: a rule and a hairline shadow. */
.mud-paper {
    border-radius: var(--radius-lg);
}

.mud-paper-outlined {
    border-color: var(--line);
    box-shadow: var(--shadow-sm);
}

/* -------------------------------------------------------------- buttons -- */

.mud-button-root {
    min-height: 30px;
    min-width: 0;
    padding: 0 11px;
    border-radius: var(--radius);
    text-transform: none;
    letter-spacing: 0;
}

.mud-button-root.mud-button-filled { box-shadow: none; }
.mud-button-root.mud-button-filled:hover { box-shadow: none; }

.mud-button-root.mud-button-outlined { border-color: var(--line-strong); }

.mud-icon-button { padding: 5px; }
.mud-button-root.mud-button-text.mud-button-text-size-small,
.mud-button-root.mud-button-outlined-size-small,
.mud-button-root.mud-button-filled-size-small { min-height: 25px; padding: 0 8px; font-size: 12px; }

/* A toolbar strip above a grid. */
.nds-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 9px 12px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
}

.nds-toolbar .sep { width: 1px; height: 20px; background: var(--line-strong); margin: 0 2px; }

/* ---------------------------------------------------------------- forms --- */

/* Inputs at 30px with a 6px radius, matching the buttons beside them. */
.mud-input-control { margin-top: 0; }

.mud-input.mud-input-outlined > input.mud-input-root,
.mud-input.mud-input-outlined > div.mud-input-slot {
    padding: 7px 9px;
    font-size: 13px;
}

.mud-input.mud-input-outlined { min-height: 34px; }

.mud-input.mud-input-outlined .mud-input-outlined-border { border-radius: var(--radius); }

.mud-input-root.mud-input-root-margin-dense {
    padding-top: 6px;
    padding-bottom: 6px;
}

/* Numbers line up under one another wherever they appear. */
.numeric,
.numeric input,
td.numeric input {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* A narrow date field. The width goes on the input rather than the picker root,
   which would take the calendar popover down with it and slice it off. */
.date-narrow .mud-input-control { max-width: 170px; }

/* --------------------------------------------------------------- tables -- */

.mud-table-root { font-size: 12.5px; }

.mud-table-head .mud-table-cell {
    background: var(--surface-3);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-700);
    padding: 7px 9px;
    white-space: nowrap;
    border-bottom: 1px solid var(--line-strong);
}

.mud-table-body .mud-table-cell {
    padding: 8px 10px;
    border-bottom: 1px solid var(--line);
}

.mud-table-dense .mud-table-body .mud-table-cell { padding: 6px 9px; }

.mud-table-foot .mud-table-cell {
    padding: 7px 9px;
    background: var(--surface-2);
    border-top: 2px solid var(--line-strong);
    font-weight: 600;
}

.mud-table-container { overflow: visible; }

.mud-table-head tr:first-child th:first-child { border-top-left-radius: var(--radius-lg); }
.mud-table-head tr:first-child th:last-child { border-top-right-radius: var(--radius-lg); }

.mud-table-head .mud-table-cell {
    position: sticky;
    top: var(--mud-appbar-height);
    z-index: 2;
}

/* Inside a dialog or a fixed-height table there is no app bar to clear. */
.mud-dialog .mud-table-head .mud-table-cell,
.mud-table-container[style*="height"] .mud-table-head .mud-table-cell { top: 0; }

/* Column menus (Feedback #285, second round): a small ☰ beside a heading opens the
   column's filter and sort, as on a DataTables grid, in place of a box under every
   heading. The ☰ is quiet until the heading is hovered and turns into a filter mark in
   the accent colour while the column is filtered, so a filtered list says so. */
.col-head {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    max-width: 100%;
}

/* A heading with a menu may wrap onto two lines rather than widen its column: kept on one
   line, the ☰ and the sort arrow's reserved space pushed the Jobs list ~500px past its
   card. The body cells wrap already, so the columns now size to the data. */
.nds-grid .mud-table-head .mud-table-cell {
    white-space: normal;
    vertical-align: bottom;
}

/* MudBlazor's 16px / 24px cell sides, taken in: across thirteen columns they alone were
   wider than a laptop's card. */
.mud-table.nds-grid .mud-table-row .mud-table-cell { padding-left: 8px; padding-right: 8px; }

.col-head .mud-table-sort-label { white-space: normal; }

/* The unsorted arrow is invisible but kept its width on every heading; only the sorted
   column shows one now, and the menu offers the sort on the rest. */
.col-head .mud-table-sort-label-icon.mud-direction-none { display: none; }

.col-head .mud-table-sort-label-icon {
    font-size: 15px;
    width: 15px;
    height: 15px;
    margin-left: 2px;
}

.col-head-anchor { position: relative; display: inline-flex; }

.col-head-menu {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink-300);
    cursor: pointer;
    opacity: .7;
}

.col-head-menu .mud-icon-root { font-size: 15px; }

.mud-table-cell:hover .col-head-menu,
.col-head-menu:focus-visible,
.col-head-menu.open { opacity: 1; color: var(--ink-700); }

.col-head-menu:hover { background: var(--surface-2); }
.col-head-menu:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.col-head-menu.active { opacity: 1; color: var(--accent); }

.col-menu { min-width: 240px; max-width: 320px; }

.col-menu-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
    font-size: 13px;
    font-weight: 400;
    color: var(--ink-900);
}

.col-menu-row {
    display: grid;
    grid-template-columns: 20px 1fr;
    align-items: center;
    gap: 8px;
    color: var(--ink-700);
}

.col-menu-row.labelled { grid-template-columns: 36px 1fr; font-size: 12px; }

.col-menu-select {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink-900);
    font: inherit;
}

.col-menu-select:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.col-menu-input { margin: 0; }
.col-menu-input .mud-input > input.mud-input-root-outlined { padding: 6px 8px !important; font-size: 13px; }

.col-menu-hint { font-size: 12px; color: var(--ink-500); }

.col-menu-options {
    display: flex;
    flex-direction: column;
    max-height: 260px;
    overflow-y: auto;
}

.col-menu-divider {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 2px -10px;
}

.col-menu-item {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    width: 100%;
    padding: 6px 8px;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink-900);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.col-menu-item .mud-icon-root { color: var(--ink-500); }
.col-menu-item:hover:not(:disabled), .col-menu-item:focus-visible { background: var(--surface-2); outline: 0; }
.col-menu-item.selected { color: var(--accent); font-weight: 600; }
.col-menu-item.selected .mud-icon-root { color: var(--accent); }
.col-menu-item:disabled { color: var(--ink-300); cursor: default; }
.col-menu-item:disabled .mud-icon-root { color: var(--ink-300); }

/* On a phone or tablet a table that is wider than its panel scrolls sideways inside the
   panel (Feedback #292, #294): with the container's overflow visible, as above, it ran off
   the side of the page instead. A box that scrolls is also what a sticky header sticks
   to, so the header's offset for the app bar goes: left in, it would push the header
   down over the first rows. 960px is where MudBlazor's own small-screen tables begin.
   This sheet is shared with the driver portal, so the rule applies there as well. */
@media (max-width: 960px) {
    .mud-table-container { overflow-x: auto; }
    .mud-table-head .mud-table-cell { top: 0; }
}

/* The grids Tank Tracker edits in place, drawn as a plain table so the footer can
   span columns — MudTable would not carry a colspan, which left the grand total
   stranded on the left rather than under the column it totals. */

.table-wrap { overflow-x: auto; max-width: 100%; }

table.data {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 12.5px;
}

table.data thead th {
    background: var(--surface-3);
    text-align: left;
    font-weight: 600;
    font-size: 11.5px;
    color: var(--ink-700);
    padding: 7px 9px;
    border-bottom: 1px solid var(--line-strong);
    white-space: nowrap;
    user-select: none;
}

table.data thead th:first-child { border-top-left-radius: var(--radius-lg); }
table.data thead th:last-child { border-top-right-radius: var(--radius-lg); }

table.data tbody td {
    padding: 5px 9px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

table.data td.numeric,
table.data th.numeric { text-align: right; font-variant-numeric: tabular-nums; }

table.data tfoot td {
    padding: 7px 9px;
    background: var(--surface-2);
    border-top: 2px solid var(--line-strong);
    font-weight: 600;
}

/* Fields that show their edges only when reached for, so a wall of boxes does not
   drown the numbers. */
table.editable td { padding: 2px 3px; }

.nds-edit-grid .mud-input.mud-input-outlined .mud-input-outlined-border {
    border-color: transparent;
}

.nds-edit-grid .mud-input:hover .mud-input-outlined-border { border-color: var(--line-strong); }
.nds-edit-grid .mud-input.mud-focused .mud-input-outlined-border { border-color: var(--accent); }

/* ---------------------------------------------------------------- tabs --- */

.mud-tabs { border-radius: var(--radius-lg); overflow: hidden; }

.mud-tabs-header {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    min-height: 0;
}

/* A tab whose content is a full-width list has nothing to round off at the bottom. */
.mud-tabs .mud-tabs-panels { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }

.mud-tab {
    min-height: 0;
    padding: 9px 13px;
    font-size: 12.5px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    min-width: 0;
}

.mud-tab.mud-tab-active { font-weight: 600; }

/* --------------------------------------------------------------- pills --- */

/* Chips read as status pills: small, round, quiet until they mean something. */
.mud-chip.mud-chip-size-small {
    height: 19px;
    font-size: 11px;
    font-weight: 600;
    padding: 0 8px;
}

.mud-chip { border-radius: 999px; }

.legend-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: 3px;
    margin-right: 6px;
    vertical-align: -2px;
}

/* --------------------------------------------------------------- alerts -- */

.mud-alert {
    border-radius: var(--radius);
    padding: 7px 12px;
}

.mud-alert .mud-alert-message { font-size: 12.5px; padding: 3px 0; }

/* --------------------------------------------------------------- dialog -- */

.mud-dialog {
    border-radius: var(--radius-lg);
}

.mud-dialog-title {
    padding: 12px 16px;
    border-bottom: 1px solid var(--line);
}

.mud-dialog-title .mud-typography { font-size: 15px; font-weight: 600; }
.mud-dialog-content { padding: 16px; }

.mud-dialog-actions {
    padding: 11px 16px;
    border-top: 1px solid var(--line);
    background: var(--surface-2);
    margin: 0;
}

/* ------------------------------------------------------------------ sign in */

.sign-in-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(140deg, #12253a 0%, #1f3b57 55%, #2a4f72 100%);
}

.sign-in-card {
    width: 100%;
    max-width: 400px;
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.field-label {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-700);
    margin-bottom: 4px;
}

.field-input {
    width: 100%;
    box-sizing: border-box;
    min-height: 32px;
    padding: 6px 9px;
    font-size: 13px;
    font-family: inherit;
    color: var(--ink-900);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
}

.field-input:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.remember-device {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--ink-700);
    cursor: pointer;
    user-select: none;
}

.remember-device input {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 0;
    border: 1px solid var(--line-strong);
    border-radius: 4px;
    background: var(--surface);
    cursor: pointer;
    display: grid;
    place-content: center;
}

.remember-device input::before {
    content: "";
    width: 9px;
    height: 9px;
    transform: scale(0);
    transition: transform 90ms ease-in-out;
    box-shadow: inset 9px 9px var(--mud-palette-primary-text);
    clip-path: polygon(14% 44%, 0 65%, 40% 100%, 100% 16%, 80% 0%, 39% 62%);
}

.remember-device input:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.remember-device input:checked::before { transform: scale(1); }

.remember-device input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .remember-device input::before { transition: none; }
}

.sign-in-button {
    width: 100%;
    min-height: 34px;
    font-size: 13px;
    font-family: inherit;
    font-weight: 600;
    color: var(--mud-palette-primary-text);
    background: var(--accent);
    border: 1px solid var(--accent-dark);
    border-radius: var(--radius);
    cursor: pointer;
}

.sign-in-button:hover { background: var(--accent-dark); }
.sign-in-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --------------------------------------------------------- login (web app) */

/* Feedback #283: the office app's /sign-in in Jobtracker's login layout - a navy
   hero beside a plain panel. The hero keeps its dark treatment in both themes,
   like the navigation rail; the panel reads the palette aliases above. The
   .sign-in-* rules stay: the driver portal's pages still use them. */

.login-page {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1fr 460px;
    background: #12253a;
}

@media (max-width: 900px) {
    .login-page { grid-template-columns: 1fr; }
    .login-hero { display: none !important; }
}

.login-hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 56px;
    color: var(--nav-ink);
    background:
        radial-gradient(900px 480px at 20% 10%, rgba(47, 128, 237, .28), transparent 60%),
        radial-gradient(700px 500px at 80% 90%, rgba(111, 177, 255, .16), transparent 60%),
        #12253a;
}

.login-hero .hero-mark { display: block; width: 64px; height: 64px; margin-bottom: 18px; color: #6fb1ff; }
.login-hero h1 { margin: 0; color: #fff; font-size: 34px; font-weight: 600; letter-spacing: -.02em; }
.login-hero p { max-width: 460px; margin: 12px 0 0; font-size: 14.5px; line-height: 1.6; }
.login-hero ul { margin: 22px 0 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.login-hero li { display: flex; gap: 9px; align-items: flex-start; font-size: 13.5px; }
.login-hero li .tick { color: #6fb1ff; flex: 0 0 auto; }

.login-panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 40px 44px;
    background: var(--surface);
    color: var(--ink-900);
}

.login-panel .brand { display: flex; align-items: center; gap: 10px; margin-bottom: 26px; }
.login-panel .login-muted { font-size: 12px; color: var(--ink-500); }
.login-panel h2 { margin: 0; font-size: 20px; font-weight: 600; }
.login-panel .sub { margin: 4px 0 22px; font-size: 13px; color: var(--ink-500); }
.login-panel .sign-in-button { min-height: 38px; font-size: 14px; }
.login-panel .foot { margin-top: 22px; font-size: 11.5px; color: var(--ink-500); }

/* ------------------------------------------------ schedule / status boards */

.board-grid {
    display: grid;
    grid-template-columns: 170px repeat(7, minmax(150px, 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: auto;
}

.board-cell {
    background: var(--surface);
    min-height: 84px;
    padding: 6px;
}

.board-head {
    background: var(--surface-3);
    font-weight: 600;
    font-size: 11.5px;
    padding: 8px 6px;
    position: sticky;
    top: 0;
    z-index: 2;
}

.board-lane {
    background: var(--surface-3);
    font-weight: 600;
    font-size: 12px;
    padding: 8px 6px;
    position: sticky;
    left: 0;
    z-index: 1;
}

.board-entry {
    display: block;
    width: 100%;
    text-align: left;
    border: 1px solid rgba(0, 0, 0, 0.18);
    border-radius: 4px;
    padding: 5px 7px;
    margin-bottom: 5px;
    font-size: 11.5px;
    line-height: 1.3;
    color: #14181d;
    cursor: pointer;
    transition: filter 120ms ease, transform 120ms ease;
}

.board-entry:hover {
    filter: brightness(0.95);
    transform: translateY(-1px);
}

.board-entry.dragging { opacity: 0.45; }

.board-cell.drop-target {
    outline: 2px dashed var(--accent);
    outline-offset: -3px;
}

/* The colour bands the desktop schedule used, kept so staff recognise them. */
.state-new       { background: #ffffff; }
.state-complete  { background: #b0c4de; }
.state-invoiced  { background: #98fb98; }
/* Not a desktop band: a cancelled job that is still to invoice (Feedback #299). */
.state-cancelled { background: #f4c7c3; }

.state-notstarted         { background: #ffffff; }
.state-awaitingcollection { background: #eee8aa; }
.state-awaitingdisposal   { background: #b0c4de; }
.state-jobcomplete        { background: #98fb98; }

.unallocated-item { cursor: grab; }
.unallocated-item:active { cursor: grabbing; }

/* The time printed ahead of a job, as the desktop timeline subject had it. */
.board-entry-time {
    font-family: var(--mono);
    font-size: 10.5px;
    margin-right: 4px;
    opacity: 0.75;
}

/* Day view: rows are 30-minute slots, columns are vehicles (the desktop DayView). */
.board-day {
    max-height: calc(100vh - 250px);
}

.board-head-sub {
    font-weight: 400;
    color: var(--ink-500);
}

.board-time {
    background: var(--surface-3);
    font-family: var(--mono);
    font-size: 11px;
    padding: 4px 6px;
    position: sticky;
    left: 0;
    z-index: 1;
}

.board-head.board-time { z-index: 3; }

.board-slot {
    background: var(--surface);
    min-height: 34px;
    padding: 3px 4px;
}

.board-slot .board-entry { margin-bottom: 3px; padding: 3px 6px; }
.board-slot .board-entry:last-child { margin-bottom: 0; }

.board-time.on-hour, .board-slot.on-hour { box-shadow: inset 0 1px 0 var(--line-strong); }
.board-time.out-of-hours, .board-slot.out-of-hours { background: var(--surface-2); }

.board-slot.drop-target {
    outline: 2px dashed var(--accent);
    outline-offset: -3px;
}

/* The week grid's "Vehicle" corner is both a head and a lane: keep it above both once the
   grid scrolls on both axes (the day view's corner has the same rule above). */
.board-head.board-lane { z-index: 3; }

/* Schedule and Job Status (Feedback #345): on a desktop-width screen the page fills the space
   under the app bar as a column, and the grid takes whatever height is left and scrolls
   inside itself, so the header actions and the sticky date headers stay in view. 40px is the
   main content's 16px top and 24px bottom padding. Narrower screens keep the page scroll. */
@media (min-width: 960px) {
    .board-page {
        display: flex;
        flex-direction: column;
        height: calc(100vh - var(--mud-appbar-height) - 40px);
        height: calc(100dvh - var(--mud-appbar-height) - 40px);
    }

    .board-page > .board-paper {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    /* The rows stay as tall as their busiest cell however little height the grid is given
       (Feedback #363): a squeezed grid scrolls, it never shortens a day. Covers the week and
       day grids of both boards. */
    .board-page .board-grid {
        flex: 1 1 auto;
        min-height: 0;
        align-content: start;
        grid-auto-rows: max-content;
    }

    .board-page .board-day { max-height: none; }
}

/* A date and a time picker edited as one value. */
.date-time-picker {
    display: flex;
    gap: 8px;
}

.date-time-picker .date-time-picker-date { flex: 3 1 0; min-width: 0; }
.date-time-picker .date-time-picker-time { flex: 2 1 0; min-width: 0; }

/* Choosing which photographs go into a PDF. */
.photo-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 10px;
    max-height: 52vh;
    overflow-y: auto;
}

.photo-picker-tile {
    position: relative;
    border: 2px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    cursor: pointer;
    background: var(--surface-2);
}

.photo-picker-tile img {
    display: block;
    width: 100%;
    height: 110px;
    object-fit: cover;
    opacity: .55;
    transition: opacity 120ms ease;
}

.photo-picker-tile.chosen { border-color: var(--accent); }
.photo-picker-tile.chosen img { opacity: 1; }

.photo-picker-tile .tick {
    position: absolute;
    top: 5px;
    right: 5px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    color: transparent;
}

.photo-picker-tile.chosen .tick {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--mud-palette-primary-text);
}

.photo-picker-tile .caption {
    display: block;
    padding: 3px 6px;
    font-size: 11px;
    color: var(--ink-500);
}

.photo-picker-tile:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .photo-picker-tile img { transition: none; }
}

/* -------------------------------------------------------------- job photos */

.photo-tile {
    width: 132px;
    height: 132px;
    object-fit: cover;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    cursor: pointer;
    transition: transform 120ms ease;
}

.photo-tile:hover { transform: scale(1.03); }

/* The job Verify page: larger photographs and a note frame tall enough to read a page. */
.photo-tile.verify-photo {
    width: 200px;
    height: 200px;
}

.verify-note {
    position: relative;
    display: block;
    width: 100%;
    height: 75vh;
    min-height: 480px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: #fff;
    overflow: hidden;
    cursor: zoom-in;
}

.verify-note iframe,
.verify-note img {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    object-fit: contain;
}

/* Sits over the frame, which would otherwise keep the click for itself. */
.verify-note-catch {
    position: absolute;
    inset: 0;
}

.verify-note:focus-visible,
.verify-photo-button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.verify-photo-button {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
}

/* Full-screen view of a note or photo; above MudBlazor's app bar and drawer. */
.verify-viewer {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    background: #0f1218;
    outline: none;
}

.verify-viewer-bar {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px 16px;
}

.verify-viewer-title {
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.verify-viewer-body {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px 16px;
}

.verify-viewer-body iframe {
    width: 100%;
    height: 100%;
    border: 0;
    background: #fff;
    border-radius: 4px;
}

/* Sized to the viewport: a percentage height does not resolve inside the flex body. */
.verify-viewer-body img {
    max-width: 100%;
    max-height: calc(100vh - 76px);
    object-fit: contain;
}

.signature-image {
    max-height: 90px;
    max-width: 100%;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 4px;
}

/* ----------------------------------------------------------- document viewer */

/* A stored note shown over the job (Feedback #300): the browser's own PDF viewer in a
   frame, or a picture. Tall enough to read a page, short enough to keep the buttons. */
.document-viewer-frame {
    display: block;
    width: 100%;
    height: 72vh;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: #fff;
}

.document-viewer-image {
    display: block;
    max-width: 100%;
    max-height: 72vh;
    margin: 0 auto;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 4px;
}

/* --------------------------------------------------------------- vehicle map */

.vehicle-map {
    width: 100%;
    height: calc(100vh - 230px);
    min-height: 420px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
}

/* ------------------------------------------------------------------ errors */

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2000;
    padding: 12px 20px;
    background: #ffeaa7;
    color: #16202b;
    box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.2);
}

#blazor-error-ui .dismiss {
    position: absolute;
    right: 12px;
    top: 10px;
    cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
    .board-entry, .photo-tile { transition: none; }
    .board-entry:hover, .photo-tile:hover { transform: none; }
}

@media print {
    .mud-appbar, .mud-drawer, .no-print {
        display: none !important;
    }

    .mud-main-content {
        padding: 0 !important;
        margin: 0 !important;
    }

    /* A printed board is not clipped to one screen (Feedback #345). */
    .board-page { height: auto !important; }
    .board-page .board-grid { overflow: visible; max-height: none; }
}

/* Schedule: unallocated jobs in a collapsible tab on the right edge of the screen. */
.side-tab {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 8px;
    border: 0;
    border-radius: 8px 0 0 8px;
    background: var(--accent);
    color: var(--mud-palette-primary-text);
    font: inherit;
    font-weight: 600;
    font-size: 13px;
    writing-mode: vertical-rl;
    cursor: pointer;
    box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2);
}

.side-tab:hover { background: var(--accent-dark); }
.side-tab .mud-icon-root { transform: rotate(90deg); }

.side-panel {
    position: fixed;
    right: 0;
    top: var(--mud-appbar-height, 64px);
    bottom: 0;
    width: min(360px, 100vw);
    z-index: 1200;
    display: flex;
    flex-direction: column;
    border-radius: 0 !important;
    transition: opacity 0.15s;
}

.side-panel-list { flex: 1; overflow: auto; }

/* While a job from the panel is being dragged, the calendar underneath takes the drop. */
.side-panel-dragging {
    opacity: 0.25;
    pointer-events: none;
}

/* ---------------------------------------------------------- send by email --- */

/* The document beside the message in the Send by email dialog: shorter than the viewer's
   frame, because the compose side needs the height on a laptop screen. */
.send-document-frame {
    height: 62vh;
}

/* The message as the mail client will show it. */
.email-preview-body {
    font-size: .875rem;
    line-height: 1.45;
}
