/* ════════════════════════════════════════════════════════════════════════════════════════════
   R2 page chrome — the ONE copy. Every page uses these classes; a page's own .razor.css holds only
   what is unique to that page. Reference pages: Users + Tags (maintenance), Sales Recap (report).

   Before 2026-09-23 each page carried its own copy of all of this (users-, tags-, sr-, ov-, lg-,
   ci-, hy-, st-, otw-, ar-, imp-, lc-, rp-, ld- …). Don't start a new copy: add a variant here.

   Contents
     1. Page frame + scroll
     2. Filter card (the box at the top of every page)
     3. Buttons and checkboxes
     4. Panels, grid cards and SfGrid fill
     5. Summary tiles
     6. Report table
     7. Text helpers, legends, section titles
     8. Maintenance modal
     9. Messages
   ════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── 1. Page frame + scroll ─────────────────────────────────────────────────────────────────── */

/* A page fills the content area and never scrolls itself: its grid or .r2-scroll does. */
.r2-page {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
    padding: 0 16px 16px;
    gap: 12px;
}

/* A detail page whose whole body scrolls (no fixed grid). */
.r2-page--scrolls {
    overflow: hidden auto;
}

.r2-page--scrolls > * {
    flex-shrink: 0;
}

/* ⚠ ContentLoadingOverlay wraps its content in two block divs, which breaks the flex chain.
   Descendant selector, not ">": the overlay is not always a direct child. */
.r2-page .content-loading-overlay-shell,
.r2-page .content-loading-overlay-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* ⚠ "overflow: hidden auto" — x hidden, y scrolls. A bare overflow:hidden here would make this a
   scroll container with no scrollbar and swallow everything past the fold. */
.r2-scroll {
    flex: 1;
    min-height: 0;
    overflow: hidden auto;
}

/* Stacked blocks inside a scroll area (tiles, then panels, then a note). */
.r2-stack {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.r2-stack > * {
    flex-shrink: 0;
}

/* ── 2. Filter card ─────────────────────────────────────────────────────────────────────────── */

/* ── 0. Empty text ──────────────────────────────────────────────────────────────────────────── */
/* Every placeholder in the app, one colour (Seth, 2026-10-20: it kept coming out as dark as real
   text). Firefox dims placeholders by default; opacity 1 makes the colour the whole story. Syncfusion
   inputs included. */
::placeholder,
.e-input::placeholder,
.e-input-group input::placeholder {
    color: #9aa5b4;
    opacity: 1;
}

.r2-filter-card {
    flex-shrink: 0;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 8px;
    padding: 12px 14px;
}

/* Title (+ subtitle) left, counts right. */
.r2-filter-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}

.r2-filter-header > :first-child {
    min-width: 0;
}

/* A card with only a header (no filters): no rule under it. */
.r2-filter-header:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.r2-filter-title {
    margin: 0;
    font-size: 0.98rem;
    font-weight: 600;
    white-space: nowrap;
}

.r2-filter-subtitle {
    margin-top: 0.3rem;
    color: #475569;
    font-size: 0.92rem;
}

.r2-filter-subtitle--warn {
    color: #b42318;
    font-weight: 600;
}

/* One muted line between title and counts (Sales Recap's year note). */
.r2-filter-note {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.r2-filter-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Header metrics ("807 invoices | $2,120.00 open | 1 to send"): a thin rule between items, the figure bold. */
.r2-filter-meta--stats {
    gap: 6px 0;
}

    .r2-filter-meta--stats > * {
        padding: 0 12px;
        line-height: 1.25;
    }

    .r2-filter-meta--stats > * + * {
        border-left: 1px solid #d3d9e0;
    }

    .r2-filter-meta--stats > :last-child {
        padding-right: 0;
    }

    .r2-filter-meta--stats strong {
        font-weight: 600;
        color: #2f3640;
    }

    .r2-filter-meta--stats .r2-bad strong {
        color: inherit;
    }

/* A header meta item for work running in the background (Refresh from QuickBooks): spinner + text. */
.r2-syncing {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #1d5c9e;
}

/* Maintenance layout (Users/Tags): filters or a checkbox left, the action buttons right. */
.r2-filter-footer {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    padding-top: 12px;
    flex-wrap: wrap;
}

/* A footer whose left side is only checkboxes (no labelled inputs): centre them on the buttons
   instead of sitting them on the bottom edge (Licensor Contracts' Show Expired). */
.r2-filter-footer--center {
    align-items: center;
}

.r2-filter-footer--center > .r2-filter-footer-left {
    align-items: center;
}

.r2-filter-footer-left {
    display: flex;
    align-items: flex-end;
    gap: 10px 14px;
    flex-wrap: wrap;
    min-width: 0;
    flex: 1 1 320px;
}

/* Report layout (Sales Recap): one wrapping row of filters. Actions go last and sit right. */
.r2-filter-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px 14px;
    padding-top: 10px;
}

.r2-filter-row > .products-action-cluster,
.r2-filter-row > .r2-push {
    margin-left: auto;
}

.r2-search-field {
    flex: 1 1 260px;
    max-width: 520px;
}

.filter-label--checkbox {
    margin: 0;
}

/* ── 3. Buttons and checkboxes ──────────────────────────────────────────────────────────────── */
/* .products-action-cluster and .products-action-button live in app.css. */

.products-action-button {
    margin: 0;
}

.products-action-button:disabled,
.products-action-button.disabled {
    opacity: 0.6;
    box-shadow: none;
    pointer-events: none;
}

/* The dashed "Drop .xlsx to Import" button (Wholesale Pricing, Factory, Customer Pricing): drop a file
   anywhere on the page, or click it to choose one. Wired by setupDropZone in js/factory.js. */
.drop-hint {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem 0.85rem;
    font-size: 0.875rem;
    color: #1d4ed8;
    border: 1px dashed #93c5fd;
    border-radius: 10px;
    background: #eff6ff;
    white-space: nowrap;
    user-select: none;
    cursor: pointer;
    line-height: 1.5;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.75), 0 2px 8px rgba(15, 23, 42, 0.10);
}

.drop-hint:hover {
    background: #dbeafe;
}

.drop-hint:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

/* The page while a file is dragged over it. */
.r2-page.drag-over {
    outline: 3px dashed #0d6efd;
    outline-offset: -4px;
    background: rgba(13, 110, 253, 0.04);
    transition: background 0.15s;
}

/* "Reading file, please wait…" over the page while an import is read. */
.import-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2000;
}

.import-overlay-card {
    background: #fff;
    border-radius: 12px;
    padding: 28px 36px;
    display: flex;
    align-items: center;
    font-size: 1rem;
    font-weight: 500;
    color: #1e293b;
    box-shadow: 0 16px 40px rgba(15, 23, 42, 0.22);
}

/* A plain checkbox with its label, the height of a filter input (Sales Recap). */
.r2-check {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    margin: 0;
    font-size: 0.875rem;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.r2-check input {
    width: 16px;
    height: 16px;
    margin: 0;
}

/* Two or three mutually exclusive views (Sales Recap's Table | Cards). */
.r2-segmented {
    display: inline-flex;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 4px;
    overflow: hidden;
    min-height: 34px;
    /* Inside a column .filter-field the default align-items: stretch made it as wide as the field (Delivery Log, 2026-10-16). */
    align-self: flex-start;
    width: max-content;
    max-width: 100%;
}

.r2-segmented button {
    font-size: 0.85rem;
    padding: 0 12px;
    border: 0;
    background: transparent;
    color: #495057;
    cursor: pointer;
    white-space: nowrap;
}

.r2-segmented button + button {
    border-left: 1px solid var(--bs-border-color, #dee2e6);
}

.r2-segmented button.active {
    background: var(--bs-primary, #0d6efd);
    color: #fff;
}

/* A filter field that must not shrink below its content: a segmented control (overflow: hidden) in a
   flexible .filter-field was clipping its last option (Invoices, 2026-10-16). */
.filter-field--fit {
    flex: 0 0 auto;
}

/* A toolbar button that opens a short menu of related actions (Invoices' PDF ▾: Preview / Download).
   Markup: .r2-dropdown > button.products-action-button + .r2-dropdown-backdrop + .r2-dropdown-menu > button.r2-dropdown-item.
   The backdrop is a transparent full-screen layer under the menu, so a click anywhere else closes it without JS. */
.r2-dropdown {
    position: relative;
    display: inline-flex;
}

.r2-dropdown-caret {
    font-size: 0.65rem;
    margin-left: 2px;
}

.r2-dropdown-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: transparent;
}

.r2-dropdown-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 1041;
    min-width: 180px;
    padding: 4px;
    background: #fff;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
    display: flex;
    flex-direction: column;
}

.r2-dropdown-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    border: 0;
    background: transparent;
    text-align: left;
    font-size: 0.875rem;
    padding: 6px 10px;
    border-radius: 4px;
    color: #212529;
    cursor: pointer;
    white-space: nowrap;
}

.r2-dropdown-item:hover:not(:disabled) {
    background: #eef3ff;
}

.r2-dropdown-item:disabled {
    opacity: 0.5;
    cursor: default;
}

.r2-dropdown-item .e-icons {
    font-size: 0.8rem;
    color: #6c757d;
}

/* A row's icon button (edit, delete) — Users' pencil. */
.summary-edit-button {
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: #1d4ed8;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.summary-edit-button:hover:not(:disabled) {
    background: #eff6ff;
}

.summary-edit-button--danger {
    color: #b91c1c;
}

.summary-edit-button--danger:hover:not(:disabled) {
    background: #fff1f2;
}

.summary-edit-button:disabled {
    opacity: 0.4;
}

.row-action-buttons {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* A link that looks like text in a table (PO numbers that open a drawer). */
.r2-link-button {
    border: 0;
    background: none;
    padding: 0;
    color: var(--bs-link-color, #0d6efd);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-align: left;
}

.r2-link-button:hover {
    text-decoration: underline;
}

/* ── 4. Panels, grid cards and SfGrid fill ──────────────────────────────────────────────────── */

/* A white card holding one SfGrid that fills the rest of the page (Users). */
.r2-grid-card {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    background: #fff;
    border: 1px solid rgba(148, 163, 184, 0.25);
    border-radius: 12px;
    padding: 12px;
    display: flex;
    flex-direction: column;
}

/* The same fill inside a panel (Tags). */
.r2-grid-fill {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.r2-grid-card .e-grid,
.r2-grid-fill .e-grid {
    height: 100%;
    flex: 1 1 auto;
    min-height: 0;
}

.r2-grid-card .e-grid .e-gridcontent,
.r2-grid-fill .e-grid .e-gridcontent {
    overflow-x: auto;
}

.r2-grid-card .content-loading-overlay-shell,
.r2-grid-card .content-loading-overlay-body,
.r2-grid-fill .content-loading-overlay-shell,
.r2-grid-fill .content-loading-overlay-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    height: 100%;
    min-height: 0;
}

/* A grid whose whole row opens something. */
.r2-grid-clickable .e-grid .e-rowcell {
    cursor: pointer;
}

/* Side-by-side panels. Fill variant (Tags) takes the page's remaining height. */
.r2-panels {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    align-items: start;
}

.r2-panels--fill {
    flex: 1;
    min-height: 0;
    align-items: stretch;
}

.r2-panels--fill > .r2-panel {
    min-height: 0;
    overflow: hidden;
}

.r2-span2 {
    grid-column: 1 / -1;
}

.r2-panel {
    min-width: 0;
    background: #fff;
    border: 1px solid rgba(148, 163, 184, 0.25);
    border-radius: 12px;
    padding: 12px;
    display: flex;
    flex-direction: column;
}

.r2-panel-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 12px;
    flex-wrap: wrap;
}

.r2-panel-header > div:first-child {
    min-width: 0;
    flex: 1 1 260px;
}

.r2-panel-header h5 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: #0f172a;
}

.r2-panel-header p {
    margin: 0.3rem 0 0;
    color: #64748b;
    font-size: 0.92rem;
}

/* "Order Dashboard →" in a panel header. */
.r2-panel-link {
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

/* Collapsible panel / expandable row: an r2-expander toggles it (SO Shipments containers, Order
   Matching recon rows); a collapsed panel header sits flush. The
   bordered chevron rotates 90° when open (the look Seth approved on Order Matching, 2026-08-12). */
.r2-panel--collapsed > .r2-panel-header {
    padding-bottom: 0;
}

/* One panel that takes the page's remaining height, its r2-grid-fill grid scrolling inside (ASN Prep). */
.r2-panel--fill {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

/* Explanatory text under a panel's grid: ruled off so it never reads as another row. */
.r2-panel-footnote {
    flex-shrink: 0;
    margin: 10px 0 0;
    padding-top: 8px;
    border-top: 1px solid #e2e8f0;
    color: #64748b;
    font-size: 0.8rem;
}

.r2-expander {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    background: #fff;
    color: #475569;
    cursor: pointer;
    padding: 0;
}

.r2-expander svg {
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

/* The app's primary blue (.btn-primary in app.css), so the expander matches the buttons beside it
   (Seth, 2026-09-30: the earlier teal didn't go with the theme). */
.r2-expander:hover {
    border-color: #1b6ec2;
    color: #1861ac;
    background: #eef4fb;
}

.r2-expander.open {
    border-color: #1861ac;
    background: #1b6ec2;
    color: #fff;
}

.r2-expander.open svg {
    transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
    .r2-expander svg {
        transition: none;
    }
}

/* A count beside a panel title. */
.r2-count {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0 8px;
    font-size: 0.72rem;
    font-weight: 700;
    background: #e8ecf1;
    color: #5b6470;
}

.r2-count--bad { background: #f9dede; color: #b03030; }
.r2-count--warn { background: #fbefd2; color: #9a6a12; }

@media (max-width: 1100px) {
    .r2-panels {
        grid-template-columns: minmax(0, 1fr);
    }

    .r2-panels--fill {
        grid-template-rows: minmax(260px, 1fr) minmax(220px, 1fr);
    }
}

/* ── 5. Summary tiles (Sales Recap) ─────────────────────────────────────────────────────────── */

.r2-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 2px;
    background: var(--bs-border-color, #dee2e6);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;
}

.r2-summary--compact {
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
}

.r2-tile {
    background: var(--bs-body-bg, #fff);
    padding: 10px 14px;
    min-width: 0;
}

.r2-tile-value {
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.r2-summary--compact .r2-tile-value {
    font-size: 1.1rem;
}

.r2-tile-label {
    font-size: 0.78rem;
    color: #6c757d;
}

/* A second, smaller line of context under the label. */
.r2-tile-detail {
    font-size: 0.74rem;
    color: #495057;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A tile that filters or navigates. */
button.r2-tile,
a.r2-tile {
    display: block;
    border: 0;
    border-radius: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

button.r2-tile:hover,
a.r2-tile:hover {
    background: #f5f8fc;
}

.r2-tile.is-on {
    box-shadow: inset 0 -3px 0 var(--bs-primary, #0d6efd);
    background: #f5f8fc;
}

.r2-tile.is-off {
    opacity: 0.55;
}

/* Status stripe down the tile's left edge (the Logistics tiles). */
.r2-tile--bad,
.r2-tile--warn,
.r2-tile--ok,
.r2-tile--acc,
.r2-tile--none {
    position: relative;
    padding-left: 18px;
}

.r2-tile--bad::before,
.r2-tile--warn::before,
.r2-tile--ok::before,
.r2-tile--acc::before,
.r2-tile--none::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
}

.r2-tile--bad::before { background: #b03030; }
.r2-tile--warn::before { background: #9a6a12; }
.r2-tile--ok::before { background: #1e7a4b; }
.r2-tile--acc::before { background: #1d5c9e; }
.r2-tile--none::before { background: #6b7889; }

/* ── 6. Report table (Sales Recap) ──────────────────────────────────────────────────────────── */
/* Cells are left-aligned; add .num for figures and .ctr for centered marks, on the th AND the td. */

.r2-table-wrap {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 8px;
    background: var(--bs-body-bg, #fff);
}

/* Inside a panel the panel is the frame, and the table scrolls sideways on its own. */
.r2-table-wrap--bare {
    border: 0;
    border-radius: 0;
    overflow-x: auto;
}

/* A panel table that scrolls vertically too; its header sticks. */
.r2-table-wrap--scroll {
    max-height: 340px;
    overflow: auto;
    scrollbar-gutter: stable;
}

.r2-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.r2-table th,
.r2-table td {
    padding: 6px 10px;
    text-align: left;
    border-bottom: 1px solid #e9ecef;
    vertical-align: middle;
    white-space: nowrap;
}

.r2-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bs-body-bg, #fff);
    font-weight: 600;
    font-size: 0.74rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6c757d;
    box-shadow: 0 1px 0 #e9ecef;
}

.r2-table th.num,
.r2-table td.num {
    text-align: right;
}

.r2-table th.ctr,
.r2-table td.ctr {
    text-align: center;
}

.r2-table td.top {
    vertical-align: top;
}

.r2-table tbody tr:last-child td {
    border-bottom: 0;
}

.r2-table tfoot td {
    border-bottom: 0;
    border-top: 2px solid #dee2e6;
    font-weight: 600;
    background: #f8f9fa;
}

/* Dense variant for tables inside side-by-side panels. */
.r2-table--compact {
    font-size: 0.8rem;
}

.r2-table--compact th,
.r2-table--compact td {
    padding: 4px 8px;
}

.r2-table--compact th {
    font-size: 0.68rem;
}

/* A second line under a column title: which window the figure covers. */
.r2-th-sub {
    display: block;
    margin-top: 1px;
    font-weight: 500;
    font-size: 0.66rem;
    letter-spacing: 0;
    text-transform: none;
    color: #adb5bd;
}

/* A second line inside a cell. Stays on one line: squeezed, a right-aligned sentence breaks into
   ragged fragments that read as damage. */
.r2-sub {
    display: block;
    font-size: 0.75rem;
    color: #6c757d;
    line-height: 1.25;
}

.r2-table td .r2-sub {
    white-space: nowrap;
}

.r2-table td.r2-wrap,
.r2-table td.r2-wrap .r2-sub {
    white-space: normal;
}

/* Alt SKU under a SKU (AltSkuLine): secondary, so never inherits a bold SKU cell. */
.r2-alt-sku {
    font-weight: 400;
    white-space: nowrap;
}

.r2-trunc {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.r2-table tr.is-off td,
.r2-table td.is-off,
.r2-table th.is-off {
    color: #adb5bd;
}

/* A row that opens something. */
.r2-row-click {
    cursor: pointer;
}

.r2-row-click:hover td,
.r2-row-click:focus-visible td {
    background: #f5f8fc;
}

.r2-row-click:focus-visible {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: -2px;
}

/* Status edge on a row's first cell. */
.r2-row--bad td:first-child { box-shadow: inset 3px 0 0 #b03030; }
.r2-row--warn td:first-child { box-shadow: inset 3px 0 0 #9a6a12; }
.r2-row--ok td:first-child { box-shadow: inset 3px 0 0 #1e7a4b; }
.r2-row--acc td:first-child { box-shadow: inset 3px 0 0 #1d5c9e; }

.r2-empty,
.r2-loading {
    padding: 24px 4px;
    font-size: 0.9rem;
    color: #6c757d;
}

@media (max-width: 768px) {
    .r2-table-wrap {
        overflow-x: auto;
    }

    .r2-table th {
        position: static;
    }
}

/* ── 7. Text helpers, legends, section titles ───────────────────────────────────────────────── */

.r2-dim {
    color: #6c757d;
    font-size: 0.8rem;
}

.r2-note {
    margin: 0;
    color: #6c757d;
    font-size: 0.8rem;
}

.r2-bad { color: #b03030; }
.r2-warn { color: #9a6a12; }
.r2-good { color: #1e7a4b; }
.r2-strong { font-weight: 600; }

/* Small uppercase blue heading for a block inside a panel or modal (Users' Roles/Customers cards). */
.r2-section-title {
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #1d4ed8;
}

.r2-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    font-size: 0.78rem;
    color: #6c757d;
}

.r2-legend > span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.r2-legend-push {
    margin-left: auto;
}

/* ── 8. Maintenance modal (Users / Tags) ────────────────────────────────────────────────────── */

.maintenance-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 1100;
}

.maintenance-modal {
    width: min(760px, 100%);
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 18px;
    box-shadow: 0 24px 54px rgba(15, 23, 42, 0.22);
}

.maintenance-modal--narrow {
    width: min(560px, 100%);
}

.maintenance-modal--wide {
    width: min(1080px, 100%);
}

.maintenance-modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.1rem 1.25rem 1rem;
    border-bottom: 1px solid #e2e8f0;
}

.maintenance-modal-header h5 {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
    font-size: 1.05rem;
    color: #0f172a;
}

.maintenance-modal-header p {
    margin: 0.3rem 0 0;
    color: #64748b;
    font-size: 0.92rem;
}

.modal-close-button {
    border: 0;
    background: transparent;
    color: #64748b;
    font-size: 1.1rem;
    line-height: 1;
}

.maintenance-modal-body {
    padding: 1.25rem;
    overflow: auto;
    display: grid;
    gap: 1rem;
    min-height: 0;
}

.maintenance-modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    padding: 1rem 1.25rem 1.2rem;
    border-top: 1px solid #e2e8f0;
}

/* A sentence at the left of the footer, buttons at the right. */
.maintenance-modal-footer-note {
    margin-right: auto;
    color: #64748b;
    font-size: 0.88rem;
}

/* A document viewer in a modal (invoice PDF on Unpaid Invoices, a sent email on Delivery Log).
   The body must be allowed to take the modal's height; a flex child that scrolls needs min-height: 0. */
.maintenance-modal--preview {
    width: min(960px, 96vw);
}

.maintenance-modal-body--preview {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0;
}

.maintenance-modal-preview-frame {
    width: 100%;
    height: min(72vh, 900px);
    border: 0;
    background: #525659;
}

/* An email is a white page, not a PDF on the viewer's grey. */
.maintenance-modal-preview-frame--email {
    background: #fff;
}

/* A mail client's header block above the viewer: From / To / Bcc / Subject / Attachments. */
.maintenance-modal-envelope {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.2rem 0.75rem;
    margin: 0;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid #e2e8f0;
    font-size: 0.88rem;
}

.maintenance-modal-envelope dt {
    color: #64748b;
    font-weight: 500;
}

.maintenance-modal-envelope dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.maintenance-modal-envelope .r2-bad {
    font-weight: 500;
}

/* A plain-text email, when there is no HTML part. */
.maintenance-modal-preview-text {
    margin: 0;
    padding: 1rem;
    height: min(60vh, 800px);
    overflow: auto;
    white-space: pre-wrap;
    font-size: 0.88rem;
}

/* A grid inside a modal: a fixed share of the viewport to fill. */
.maintenance-modal-grid {
    height: 55vh;
    min-height: 240px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.maintenance-modal-grid .e-grid {
    height: 100%;
}

.maintenance-modal-grid .content-loading-overlay-shell,
.maintenance-modal-grid .content-loading-overlay-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    height: 100%;
    min-height: 0;
}

.modal-form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

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

/* Four fields a row, for a --wide modal with many short fields (Customer / Factory editor). */
.modal-form-grid--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.75rem 1rem;
}

/* A field twice as wide as its neighbours (a name, a long dropdown). */
.modal-form-grid .modal-span2 {
    grid-column: span 2;
}

/* A checkbox in a field row: put an empty .filter-label above an .r2-check, and the checkbox
   centres on the inputs beside it rather than on any hint line under them. Modal inputs are 32px
   (measured 2026-09-28), not the 34px of a filter bar. */
.modal-form-grid .r2-check {
    min-height: 32px;
}

/* One titled group of fields in a modal: an .r2-section-title, then its .modal-form-grid.
   A rule separates it from the group above. */
.modal-section {
    display: grid;
    gap: 0.5rem;
}

.modal-section + .modal-section {
    padding-top: 0.9rem;
    border-top: 1px solid #e2e8f0;
}

.modal-form-grid .filter-field {
    max-width: none;
}

.modal-form-grid .filter-field--sm {
    max-width: 220px;
}

.modal-checkbox-row {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

/* Two cards on Users, three on the Customer / Factory editor: one row either way. */
.modal-linked-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
}

/* A tinted box grouping related values or lines inside a modal. */
.linked-summary-card {
    border: 1px solid #dbeafe;
    background: linear-gradient(180deg, #f8fbff 0%, #f1f5f9 100%);
    border-radius: 14px;
    padding: 0.85rem 0.95rem;
}

.linked-summary-label {
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #1d4ed8;
}

.linked-summary-value {
    margin-top: 0.45rem;
    color: #1e293b;
    line-height: 1.4;
}

@media (max-width: 1100px) {
    .modal-form-grid--4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 768px) {
    .modal-form-grid,
    .modal-linked-actions {
        grid-template-columns: 1fr;
    }

    .modal-form-grid .modal-span2 {
        grid-column: auto;
    }
}

/* ── 9. Messages ────────────────────────────────────────────────────────────────────────────── */

.error-bar {
    background: #fee2e2;
    border: 1px solid #fca5a5;
    border-radius: 4px;
    padding: 6px 12px;
    font-size: 0.85rem;
    color: #b91c1c;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}

.error-close {
    cursor: pointer;
    font-weight: 700;
    padding-left: 12px;
}

.validation-summary {
    border: 1px solid #fecaca;
    background: #fff1f2;
    color: #b91c1c;
    border-radius: 10px;
    padding: 0.85rem 0.95rem;
    display: grid;
    gap: 0.3rem;
}

.r2-warning-box {
    border: 1px solid #fde68a;
    background: #fffbeb;
    color: #92400e;
    border-radius: 10px;
    padding: 0.85rem 0.95rem;
}

.r2-info-box {
    border: 1px solid #dbeafe;
    background: #eff6ff;
    color: #1e3a8a;
    border-radius: 10px;
    padding: 0.85rem 0.95rem;
}

/* Bootstrap alerts on a page: flat, no bottom margin (the page gap spaces them). */
.r2-page > .alert {
    margin: 0;
    flex-shrink: 0;
}

/* QuickBooks actions (Post to QuickBooks on Royalty Payments): QuickBooks' own green, so the button
   reads as "this goes to QuickBooks" the way Export to Excel reads as Excel. Shape from .btn-primary. */
.btn-quickbooks {
    color: #fff;
    background-color: #2ca01c;
    border-color: #258a17;
}
.btn-quickbooks:hover, .btn-quickbooks:focus {
    color: #fff;
    background-color: #258a17;
    border-color: #1f7513;
}
.btn-quickbooks:disabled, .btn-quickbooks.disabled {
    color: #fff;
    background-color: #2ca01c;
    border-color: #258a17;
    opacity: .55;
}

/* File drop zone: a label wrapping an <InputFile>; app.setupFileDropZone adds .drag-over while a file is over it.
   (FedEx tracking import on Unpaid Invoices; Invoice Adjustments still has its own copy.) */
.r2-drop-zone {
    position: relative;
    display: grid;
    place-items: center;
    gap: 0.25rem;
    min-height: 150px;
    padding: 1rem;
    border: 2px dashed #94a3b8;
    border-radius: 16px;
    background: #f8fafc;
    color: #475569;
    cursor: pointer;
    text-align: center;
}

.r2-drop-zone:hover,
.r2-drop-zone.drag-over {
    border-color: #4f46e5;
    background: #eef2ff;
}

.r2-drop-zone input[type=file] {
    max-width: 100%;
}

.r2-drop-zone-title {
    font-size: 1.1rem;
    font-weight: 800;
    color: #1e293b;
}
