html, body {
    margin: 0;
    padding: 0;
    font-family: 'Roboto', 'Helvetica Neue', Arial, sans-serif;
}

.loading-splash {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    height: 100vh;
    font-size: 1.25rem;
    color: #555;
}

#blazor-error-ui {
    background: #b71c1c;
    color: #fff;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* Short form dialogs that opt in via a marker element shouldn't show a phantom vertical scrollbar. */
.mud-dialog-content:has(.alhs-no-scroll) {
    overflow-y: visible;
}
/* ---- Precleaner tank display ----
   The tank graphic is a fixed 44.75mm wide; the per-tank column pitch is 40.25mm
   (= 44.75mm * canvas 80.5 / viewBox 89.5). The 4.5mm difference is the precleaner continuation that
   overlaps the next tank, giving the single continuous bar across the tops. These three numbers are
   linked — change one and re-derive the others. (Kept in the shared stylesheet rather than scoped CSS:
   the standalone /cloud WASM app's {Assembly}.styles.css bundle isn't reliably served by the host.) */
.tank-scroll {
    overflow-x: auto;
    overflow-y: hidden;
    width: 100%;
}

/* Sized to its content so every row shares the same width and scrolls together. */
.tank-rows {
    width: max-content;
}

.tank-flex-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
}

.tank-label-spacer {
    flex: 0 0 150px;
    width: 150px;
}

.tank-row-label {
    flex: 0 0 150px;
    width: 150px;
    background: #64994B;
    color: #fff;
    font-weight: 600;
    padding: 4px 8px;
    border: 1px solid #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The svg is a fixed 44.75mm; the overlap is created by pulling each subsequent tank left by exactly
   the continuation width so the precleaner bars join. */
.tank-graphic-cell {
    flex: 0 0 44.75mm;
    width: 44.75mm;
}

.tank-graphic-cell.overlap {
    margin-left: -4.5mm;
}

.tank-name {
    flex: 0 0 40.25mm;
    width: 40.25mm;
    background: #64994B;
    color: #fff;
    font-weight: 700;
    text-align: center;
    padding: 4px;
    border: 1px solid #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tank-add {
    flex: 0 0 40.25mm;
    width: 40.25mm;
    padding: 3px;
}

.tank-cell {
    flex: 0 0 40.25mm;
    width: 40.25mm;
    padding: 4px 8px;
    border: 1px solid #e0e0e0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Run Manager: bin-filling output boxes. Two columns across the wide desktop layout, collapsing to
   one-per-row on small screens. Lives in app.css because scoped CSS isn't reliably served for the /cloud
   SPA (see README). */
.run-output-grid {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
}

@media (min-width: 960px) {
    .run-output-grid {
        grid-template-columns: 1fr 1fr;
    }
}

/* Reports: inline PDF viewer host. (Scoped CSS doesn't reliably serve for the /cloud SPA, so this lives
   in the shared app.css — see README.) The host div is populated by pdf-viewer.js with a blob-url iframe. */
.report-pdf-host-wrap {
    position: relative;
    width: 100%;
    height: calc(100% - 48px);
    min-height: 60vh;
}

.report-pdf-host {
    width: 100%;
    height: 100%;
}

.report-pdf-empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
}

/* Run restructure dialog: conflict list inside the warning alert (scoped CSS isn't served for the
   /cloud SPA, so this lives here — see README). Keeps bullets tidy and indented within the alert. */
.mud-list-conflicts {
    margin: 4px 0 0;
    padding-left: 20px;
}

.mud-list-conflicts li {
    margin: 2px 0;
}

/* USDA certificate editor: the quality-sample table (percent + weight per kernel category). Lives in the
   shared app.css because scoped CSS isn't reliably served for the /cloud SPA (see README). */
.usda-quality {
    width: 100%;
    border-collapse: collapse;
}

.usda-quality th,
.usda-quality td {
    padding: 2px 6px;
    vertical-align: middle;
}

.usda-quality th.num,
.usda-quality td.num {
    text-align: right;
    width: 110px;
}

.usda-quality thead th {
    border-bottom: 1px solid rgba(0, 0, 0, 0.2);
    font-weight: 600;
}

.usda-quality tr.total-row td {
    border-top: 1px solid rgba(0, 0, 0, 0.2);
    font-weight: 600;
}

/* Right-align the numeric input fields (quality-sample weights, chipped & scratched, and the per-bin
   meat-weight editor) so the digits line up on the right like the desktop's numeric-up-down controls. */
.usda-quality input,
.usda-num-right input {
    text-align: right;
}

/* Crop Year Transition: the unvisited-tab red "X" badge sits at the tab's top-right corner and was being
   clipped by the tab strip. Give the toolbar a little headroom and let the badges overflow. */
.cyt-tabs .mud-tabs-toolbar {
    overflow: visible;
    padding-top: 8px;
}

.cyt-tabs .mud-tabs-tabbar,
.cyt-tabs .mud-tab {
    overflow: visible;
}

/* ---- In-app user documentation viewer (rendered markdown) ----
   Scoped CSS isn't served for the standalone /cloud SPA, so the doc styles live here. Colors track the
   MudBlazor theme via --mud-palette-* vars. The .markdown-alert* rules + :root alert colors are ported
   from ALHS.Server/wwwroot/html/chat.html so the GitHub-style [!NOTE]/[!TIP]/... blocks render the same. */
.almond-docs {
    line-height: 1.6;
    color: var(--mud-palette-text-primary);
    max-width: 80ch;
    overflow-wrap: break-word;
}

.almond-docs h1,
.almond-docs h2,
.almond-docs h3,
.almond-docs h4 {
    font-weight: 600;
    margin: 1.4em 0 0.5em;
    line-height: 1.25;
}

.almond-docs h1 {
    font-size: 2rem;
    margin-top: 0;
    border-bottom: 1px solid var(--mud-palette-divider);
    padding-bottom: 0.2em;
}

.almond-docs h2 {
    font-size: 1.5rem;
    border-bottom: 1px solid var(--mud-palette-divider);
    padding-bottom: 0.2em;
}

.almond-docs h3 { font-size: 1.2rem; }

.almond-docs p { margin: 0.75em 0; }

.almond-docs a {
    color: var(--mud-palette-primary);
    text-decoration: none;
}

.almond-docs a:hover { text-decoration: underline; }

.almond-docs ul,
.almond-docs ol { padding-left: 1.5em; }

.almond-docs li { margin: 0.25em 0; }

.almond-docs code {
    background: var(--mud-palette-background-grey);
    padding: 0.15em 0.35em;
    border-radius: 4px;
    font-size: 0.9em;
    font-family: 'Roboto Mono', Consolas, monospace;
}

.almond-docs pre {
    background: var(--mud-palette-background-grey);
    padding: 1em;
    border-radius: 6px;
    overflow: auto;
}

.almond-docs pre code {
    background: none;
    padding: 0;
}

.almond-docs img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    border: 1px solid var(--mud-palette-divider);
}

.almond-docs table {
    border-collapse: collapse;
    width: 100%;
    margin: 1em 0;
}

.almond-docs th,
.almond-docs td {
    border: 1px solid var(--mud-palette-divider);
    padding: 6px 10px;
    text-align: left;
}

.almond-docs th { background: var(--mud-palette-background-grey); }

.almond-docs blockquote {
    border-left: 4px solid var(--mud-palette-divider);
    margin: 1em 0;
    padding: 0.25em 1em;
    color: var(--mud-palette-text-secondary);
}

.almond-docs hr {
    border: none;
    border-top: 1px solid var(--mud-palette-divider);
    margin: 1.5em 0;
}

/* GitHub-style alert boxes (ported from chat.html) */
:root {
    --color-note: #0969da;
    --color-tip: #1a7f37;
    --color-warning: #9a6700;
    --color-severe: #bc4c00;
    --color-caution: #d1242f;
    --color-important: #8250df;
}

.markdown-alert {
    padding: 0.5rem 1rem;
    margin-bottom: 16px;
    color: inherit;
    border-left: 0.25em solid #888;
}

.markdown-alert > :first-child { margin-top: 0; }
.markdown-alert > :last-child { margin-bottom: 0; }

.markdown-alert .markdown-alert-title {
    display: flex;
    font-weight: 500;
    align-items: center;
    line-height: 1;
}

.markdown-alert .markdown-alert-title .octicon {
    margin-right: 0.5rem;
    display: inline-block;
    overflow: visible !important;
    vertical-align: text-bottom;
    fill: currentColor;
}

.markdown-alert.markdown-alert-note { border-left-color: var(--color-note); }
.markdown-alert.markdown-alert-note .markdown-alert-title { color: var(--color-note); }
.markdown-alert.markdown-alert-important { border-left-color: var(--color-important); }
.markdown-alert.markdown-alert-important .markdown-alert-title { color: var(--color-important); }
.markdown-alert.markdown-alert-warning { border-left-color: var(--color-warning); }
.markdown-alert.markdown-alert-warning .markdown-alert-title { color: var(--color-warning); }
.markdown-alert.markdown-alert-tip { border-left-color: var(--color-tip); }
.markdown-alert.markdown-alert-tip .markdown-alert-title { color: var(--color-tip); }
.markdown-alert.markdown-alert-caution { border-left-color: var(--color-caution); }
.markdown-alert.markdown-alert-caution .markdown-alert-title { color: var(--color-caution); }

/* ---- Run Validation grid: freeze the first two columns (select checkbox + Run) during horizontal scroll ----
   MudBlazor 9.4 has no native frozen columns, so we pin the first two cells with position:sticky inside the
   MudTable HorizontalScrollbar container. Tinted rows expose their colour via the --rv-row-bg custom property
   (set by RowStyleFunc on the <tr>, inherited by the <td>s) so the frozen cells match the row. */
.rv-grid td:first-child,
.rv-grid th:first-child {
    position: sticky;
    left: 0;
    width: 48px;
    min-width: 48px;
    z-index: 2;
    background-color: var(--rv-row-bg, var(--mud-palette-surface));
}

.rv-grid td:nth-child(2),
.rv-grid th:nth-child(2) {
    position: sticky;
    left: 48px;
    z-index: 2;
    background-color: var(--rv-row-bg, var(--mud-palette-surface));
}

/* Header frozen cells sit above the body frozen cells and never carry a row tint. */
.rv-grid th:first-child,
.rv-grid th:nth-child(2) {
    z-index: 3;
    background-color: var(--mud-palette-surface);
}

/* Full-page loading overlay */
.loading-overlay {
    background: rgba(0, 0, 0, 0.5);
    width: 100%;
    height: 100%;
    z-index: 10;
    top: 0;
    left: 0;
    position: fixed;
}

.loading-spinner-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
}

.loading-spinner {
    border: 8px solid #f3f3f3;
    border-top: 8px solid #507B3D;
    border-radius: 50%;
    width: 64px;
    height: 64px;
    margin-bottom: 8px;
    animation: spin 2s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* ---- Camera barcode scan viewfinder (BarcodeScanDialog / CameraScanOverlay) ---- */
.alhs-camera-scan {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    max-height: 60vh;
    background-color: #000;
    border-radius: 8px;
    overflow: hidden;
}

.alhs-camera-scan-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Purely decorative scan-target guide; must not intercept taps meant for the video/controls. */
.alhs-camera-scan-frame {
    position: absolute;
    inset: 12% 18%;
    border: 3px solid rgba(255, 255, 255, 0.85);
    border-radius: 12px;
    pointer-events: none;
}

.alhs-camera-scan-controls {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 4px;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.45);
    border-radius: 24px;
    padding: 2px;
}

.alhs-camera-scan-error {
    position: absolute;
    left: 8px;
    right: 8px;
    bottom: 8px;
}

/* =====================================================================
   TANK LOG PAGE  (Pages/Plant/TankLog.razor)
   Self-contained block. Colors ported from desktop LightTheme.xaml:
     Deleted  AL_AccentBackgroundColor4  #F6D5CA  (text AL_NegativeForegroundColor #C61F08)
     Closed   PrimaryBackgroundColor     #FFFFFF
     Open     AL_AccentBackgroundColor3  #DEE9D7
     Filled   AL_AccentBackgroundColor1  #D5DCE7
     Filling  AL_AccentBackgroundColor5  #FAF8DE
   ===================================================================== */

/* Issue 2 - responsive toolbar: wrap instead of squishing on small screens */
.tank-log-page .mud-table-toolbar {
    height: auto;
    min-height: unset;
}

.tank-log-page .mud-table-toolbar .mud-toolbar-content {
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 12px;
    padding-top: 6px;
    padding-bottom: 6px;
}

.tank-log-page .tanklog-toolbar-title {
    margin-right: 4px;
}

.tank-log-page .tanklog-toolbar-item {
    margin-top: 0;
    flex: 0 1 auto;
}

/* Issue 1 - color key / legend at the top of the page */
.tank-log-page .tanklog-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 18px;
    padding: 6px 8px 10px 8px;
    font-size: 0.8125rem;
    color: rgba(0, 0, 0, 0.75);
}

.tank-log-page .tanklog-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.tank-log-page .tanklog-swatch {
    display: inline-block;
    width: 18px;
    height: 18px;
    border: 1px solid rgba(0, 0, 0, 0.55);
    border-radius: 2px;
}

/* Issue 1 - per-status ROW background (matches desktop RadGridView row triggers) */
.tank-log-page .tanklog-row.tanklog-status-deleted td {
    background-color: #F6D5CA !important;
    color: #C61F08;
}
.tank-log-page .tanklog-row.tanklog-status-closed td {
    background-color: #FFFFFF !important;
}
.tank-log-page .tanklog-row.tanklog-status-open td {
    background-color: #DEE9D7 !important;
}
.tank-log-page .tanklog-row.tanklog-status-filled td {
    background-color: #D5DCE7 !important;
}
.tank-log-page .tanklog-row.tanklog-status-filling td {
    background-color: #FAF8DE !important;
}

/* Issue 1 - Status chip uses the SAME color as its row background */
.tank-log-page .tanklog-chip.mud-chip {
    color: rgba(0, 0, 0, 0.82);
    border: 1px solid rgba(0, 0, 0, 0.35);
    font-weight: 500;
}
.tanklog-swatch.tanklog-status-deleted,
.tank-log-page .tanklog-chip.tanklog-status-deleted {
    background-color: #F6D5CA !important;
}
.tank-log-page .tanklog-chip.tanklog-status-deleted {
    color: #C61F08;
}
.tanklog-swatch.tanklog-status-closed,
.tank-log-page .tanklog-chip.tanklog-status-closed {
    background-color: #FFFFFF !important;
}
.tanklog-swatch.tanklog-status-open,
.tank-log-page .tanklog-chip.tanklog-status-open {
    background-color: #DEE9D7 !important;
}
.tanklog-swatch.tanklog-status-filled,
.tank-log-page .tanklog-chip.tanklog-status-filled {
    background-color: #D5DCE7 !important;
}
.tanklog-swatch.tanklog-status-filling,
.tank-log-page .tanklog-chip.tanklog-status-filling {
    background-color: #FAF8DE !important;
}
.tanklog-swatch.tanklog-status-na,
.tank-log-page .tanklog-chip.tanklog-status-na {
    background-color: #EEEEEE !important;
}

/* Issue 3 - trim abnormally tall rows to a normal compact height */
.tank-log-page .mud-table-dense td,
.tank-log-page .mud-table-dense th {
    padding-top: 3px;
    padding-bottom: 3px;
    line-height: 1.2;
}
.tank-log-page .tanklog-chip.mud-chip.mud-chip-size-small {
    height: 20px;
    margin: 0;
}

/* Follow-up: keep every cell on a single line and let the grid scroll
   horizontally (MudTable HorizontalScrollbar) instead of word-wrapping the
   content — internal wrapping was what made the rows abnormally tall. */
.tank-log-page td,
.tank-log-page th {
    white-space: nowrap;
}

/* ============================================================
   RUN SCHEDULER PAGE  (touch-friendly reorder — issue 1)
   Reordering is restricted to the MudDragHandle inside each queued-run card
   (see RunScheduler.razor). Because a handle is registered, MudBlazor leaves
   the card body non-draggable, so a touch/swipe on the body scrolls normally.
   ============================================================ */

/* The drag handle is the ONLY affordance that begins a reorder. It must claim
   the touch gesture (touch-action:none) so dragging from the handle doesn't
   also pan the page — MudDragHandle's touchmove handler doesn't preventDefault. */
.run-scheduler-queue .run-scheduler-drag-handle {
    touch-action: none;
    cursor: grab;
    flex: 0 0 auto;
    align-self: center;
    display: inline-flex;
}
.run-scheduler-queue .run-scheduler-drag-handle:active {
    cursor: grabbing;
}

/* Available Lots dialog: keep the column headers pinned while the grid body
   scrolls vertically. Reliable CSS sticky within the scroll wrapper (used
   instead of MudDataGrid FixedHeader, which collapsed the grid body height). */
.alots-grid-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: #ffffff;
}

/* Stockpile Area edit: pinned Bulk Add box + touch-friendly row/pile drag handle. */
.stockpile-bulk-add {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    background-color: var(--mud-palette-background-grey);
}
.stockpile-drag-handle {
    touch-action: none;
    cursor: grab;
    flex: 0 0 auto;
    align-self: center;
    display: inline-flex;
}
.stockpile-drag-handle:active {
    cursor: grabbing;
}

/* ---- Load/Run/Inventory Search explorers (ExplorerSearchView) ----
   Desktop-style two-pane layout: fixed-width filter panel + results grid. On narrow screens the panes
   stack (filters above, grid below) so the grid is usable instead of being crushed beside the panel. */
.explorer-view {
    display: flex;
    gap: 8px;
    height: calc(100vh - 130px);
}

.explorer-filters {
    flex: 0 0 400px;
    min-width: 340px;
}

.explorer-results {
    min-width: 0;
}

@media (max-width: 960px) {
    .explorer-view {
        flex-direction: column;
        height: auto;
    }

    .explorer-filters {
        flex: 0 0 auto;
        width: 100%;
        min-width: 0;
        max-height: 60vh;
    }

    .explorer-results {
        min-height: 70vh;
    }

    .explorer-toolbar {
        flex-wrap: wrap;
        height: auto;
        min-height: 48px;
        row-gap: 4px;
    }
}

/* QC attribute filter: fixed-width min/max cells so the numeric inputs never get squished by long
   attribute labels (desktop QCFilter's uniform-grid layout). */
.qc-filter-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 84px 84px;
    gap: 2px 8px;
    align-items: center;
}

.qc-filter-grid .mud-input-control {
    margin-top: 0;
}

/* Checked checkboxes always render in the brand green so a checked box can't be mistaken for a
   disabled (grey) one. !important is needed to outrank MudBlazor's color-text utility classes;
   disabled boxes keep their grey via :not(:disabled). */
.mud-checkbox .mud-checkbox-input:checked:not(:disabled) ~ .mud-icon-root {
    color: var(--mud-palette-primary) !important;
}
