/* LoadMaster Industries Business Portal - Site Styles */

/* Per-row action icon columns (edit / view / delete) used by every DataGrid.
   Without an explicit width these empty-header columns size to auto and sprawl,
   pushing the pencil and trash icons far apart. Pin them to the icon's footprint
   so the two action icons sit snug at the start of each row. */
.edit-column,
.view-column,
.delete-column {
    width: 39px;
}

/* Application version footer */
.application-version {
    text-align: center;
    font-size: 0.875rem;
    color: #6c757d;
}

/* Flex content layout */
.flex-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    padding-bottom: 50px;
}

/* Card styling */
.card {
    margin-bottom: 1.5rem;
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}

/* Page title box.
   Match the theme's (and the RMG/PCI reference portals') full-bleed white banner: a
   white background with a soft shadow, spanning the full content width while the title
   text stays held in the content column. The theme pairs `padding: 0 30px` with
   `margin: 0 -30px` for a 30px container gutter; LoadMaster's container gutter is 12px,
   so the equivalent is `padding: 0 12px` + `margin: 0 -12px` (the theme's -30px overhung
   the fixed sidebar here). The banner height comes from the 60px `line-height` on
   `.page-title`, restored in the v3 chrome block below - which is why the vertical
   padding here is 0 and must stay 0. Measured on production, this pairing gives a
   60px bar; adding vertical padding on top of the 60px line would double-count it.

   Bleed the banner all the way out to the .content-page border edges (the fixed
   sidebar on the left, the window edge on the right) like the reference portals,
   while the page content keeps its gutter. The box's natural position is inset from
   the .content-page edge by the content-page padding (15px) plus the container-fluid
   gutter (12px) = 27px, so -27px margin reaches the edge and 27px padding holds the
   title text in the content column. .content-page has overflow:hidden, so the bleed
   is clipped cleanly (no horizontal scroll); it is independent of sidebar width, so
   it also holds when the sidebar collapses (.enlarged). */
.page-title-box {
    position: relative;
    background-color: #fff;
    box-shadow: 0 0 35px 0 rgba(73, 80, 87, 0.15);
    padding: 0 27px;
    margin: 0 -27px 1.5rem -27px;
}

/* Module list pages set neither a page title nor a breadcrumb, so their title box is
   empty — collapse it instead of showing an empty banner and its bottom margin. The
   Application Settings shell sets HeaderText and a breadcrumb, so it is unaffected. */
.page-title-box:has(> .page-title:empty):not(:has(.breadcrumb)) {
    display: none;
}
.page-title {
    font-size: 1.25rem;
    margin: 0;
    font-weight: 600;
    color: #143d58;
}

/* Form styling */
.form-group {
    margin-bottom: 1rem;
}

.form-label {
    font-weight: 500;
    margin-bottom: 0.5rem;
}

/* Brand toolbar background. Every module list/settings view uses
   `navbar navbar-dark bg-theme` for its action toolbar; `bg-theme` is not a
   Bootstrap class, so without this rule the toolbar is transparent and its
   white (navbar-dark) text/icons render invisibly on the white card. */
.bg-theme {
    background-color: #143d58;
}

/* The sidebar brand logo is a white wordmark, so it's invisible on the otherwise
   white side-menu header — give it a dark background so it shows. */
.logo {
    background-color: #2b3d51;
}

/* ---------------------------------------------------------------------------
   Module action toolbars (shared across every list/settings screen — DPRs,
   TimeSheets, Employees, Project Tasks, Pay Periods, Lookups, GSS Data, Company
   Settings). Every one uses `navbar navbar-dark bg-theme`, so these rules give
   them a consistent look: vertical dividers between the action buttons, the
   search box + its buttons the same height as the action buttons, and a neutral
   (non-red) Delete button.
   --------------------------------------------------------------------------- */

/* Keep the toolbar's trailing control off the edge. The search box and its
   Search/Refresh buttons sit in a right-aligned input group, so without this the
   green Refresh button butts against the toolbar's right edge while the action
   buttons on the left sit comfortably inset. */
.navbar.bg-theme {
    padding-right: 1rem;
}

/* Vertical dividers between adjacent action buttons. */
.navbar.bg-theme .navbar-nav > .nav-item + .nav-item {
    border-left: 1px solid rgba(255, 255, 255, 0.25);
}

/* Style any explicit `.divider-vertical` separators the markup still carries so
   they match the CSS dividers above. */
.navbar.bg-theme .divider-vertical {
    align-self: stretch;
    width: 1px;
    padding: 0;
    margin: 0.4rem 0;
    background-color: rgba(255, 255, 255, 0.25);
}

/* Equalize the height of every interactive control in the toolbar so the search
   box and its Search/Refresh buttons line up with each other and the action
   buttons. box-sizing keeps the input (which carries a border) the same outer
   height as the buttons; flex-centering is only applied to the buttons/links
   (an <input> must not be a flex container). */
.navbar.bg-theme .nav-link.btn-touch,
.navbar.bg-theme .input-group .form-control,
.navbar.bg-theme .input-group .btn {
    /* 44px matches the btn-touch minimum touch-target height, so the search box
       lines up exactly with the Search/Refresh buttons and the action buttons. */
    height: 44px;
    box-sizing: border-box;
    line-height: 1.2;
}

.navbar.bg-theme .nav-link.btn-touch,
.navbar.bg-theme .input-group .btn {
    display: inline-flex;
    align-items: center;
}

/* Give the action buttons breathing room so they don't crowd the dividers. */
.navbar.bg-theme .navbar-nav .nav-link.btn-touch {
    padding-left: 1.15rem;
    padding-right: 1.15rem;
}

/* Delete must not stand out in red — render it like its sibling action buttons
   (navbar-dark light text), keeping only the disabled state. */
.navbar.bg-theme .nav-link.text-danger {
    color: rgba(255, 255, 255, 0.5) !important;
}

.navbar.bg-theme .nav-link.text-danger:hover,
.navbar.bg-theme .nav-link.text-danger:focus {
    color: rgba(255, 255, 255, 0.75) !important;
}

.navbar.bg-theme .nav-link.text-danger.disabled {
    color: rgba(255, 255, 255, 0.25) !important;
}

/* Button styling - LoadMaster brand colors */
.btn-primary {
    background-color: #143d58;
    border-color: #143d58;
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: #0f2e44;
    border-color: #0f2e44;
}

.btn-toolbar {
    margin-bottom: 1rem;
}

/* Grid toolbar */
.grid-toolbar {
    margin-bottom: 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* Grid pager. The framework grid renders .GridPager as a block child of the
   .DataGrid scroll container, which left-aligns it by default. Lay it out as a
   flex row so the row-count text stays on the left and the page navigation floats
   to the right, and sticky-pin it to the scroll viewport so the nav stays right
   at any horizontal scroll position (a no-op on grids that don't scroll). */
div.GridPager {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
}

div.GridPager > span {
    display: inline-block;
    text-align: left;
}

div.GridPager > span > span {
    float: left;
    line-height: 32px;
}

div.GridPager > span > span.row-count {
    padding-left: 10px;
    vertical-align: middle;
    line-height: 32px;
}

div.GridPager > nav {
    margin-left: auto;
}

.DataGrid > div.GridPager {
    position: sticky;
    left: 0;
}

/* Status badges */
.badge-status {
    padding: 0.35em 0.65em;
    font-size: 0.75em;
}

.badge-status-active {
    background-color: #7EBEC5;
    color: white;
}

.badge-status-inactive {
    background-color: #6c757d;
    color: white;
}

.badge-status-pending {
    background-color: #f8c80A;
    color: #212529;
}

.badge-status-approved {
    background-color: #7EBEC5;
    color: white;
}

.badge-status-rejected {
    background-color: #dc3545;
    color: white;
}

/* Dashboard widgets */
.dashboard-widget {
    background-color: #fff;
    border-radius: 0.25rem;
    padding: 1.5rem;
    margin-bottom: 1.5rem;
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}

.dashboard-widget-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: #6c757d;
    text-transform: uppercase;
    margin-bottom: 0.5rem;
}

.dashboard-widget-value {
    font-size: 2rem;
    font-weight: 700;
    color: #143d58;
}

/* Document folder styles */
.folder-tree {
    list-style: none;
    padding-left: 1rem;
}

.folder-item {
    padding: 0.25rem 0;
}

.folder-icon {
    color: #f8c80A;
    margin-right: 0.5rem;
}

.file-icon {
    color: #6c757d;
    margin-right: 0.5rem;
}

/* LoadMaster accent link color */
a {
    color: #143d58;
}

a:hover {
    color: #7EBEC5;
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .page-title {
        font-size: 1rem;
    }
}

/* Pin the grid pager to the horizontal scroll viewport. The .DataGrid container
   is the horizontal scroll element, and the framework renders .GridPager as a
   block child of it - so by default the pager is anchored at the table's content
   origin (content-space left:0) and slides leftward, "floating" mid-grid, as the
   user scrolls right. A block child of an overflow-x:auto box is only as wide as
   the viewport (not the scroll width), so sticky left:0 keeps the pager's left
   edge at the scrollport: the right-aligned nav/pagination stays pinned right and
   the row-count stays left. Harmless (no-op) for grids that don't scroll. */
.DataGrid > div.GridPager {
    position: sticky;
    left: 0;
}
/* ============================================================================
   RMG mobile/card CSS parity (ported 2026-06-07)
   Grid sort-header reset (UI.Grid .127+) + Phase 0 mobile foundation + card
   polish + grid totals-footer card view. Portal-agnostic framework/theme
   selectors; RMG-specific selectors (cubics, etc.) are harmless no-ops.
   ============================================================================ */

    /* UI.Grid (>= .127) renders sortable column headers as a
       <button class="grid-sort-button"> instead of an <a> (for a11y:
       role="columnheader" / aria-sort). The old "thead td > a" styling no
       longer matches, so the buttons fall back to native chrome (a 2px outset
       border box). Reset them to read as plain, left-aligned header text. */
    .DataGrid .grid-sort-button {
        padding: 0;
        border: 0;
        background: transparent;
        font: inherit;
        color: #495057;
        cursor: pointer;
        text-align: inherit;
    }

        .DataGrid .grid-sort-button:hover {
            text-decoration: underline;
        }

/* ==========================================================================
   MOBILE-FIRST FOUNDATION (Phase 0)
   Cross-cutting responsive rules for phone/tablet. site.css loads AFTER
   app.css, so these override the theme. Everything is scoped to
   <= 767.98px (Bootstrap's md breakpoint) so desktop is untouched. Per-module
   and per-page mobile polish (Inventory, VesselLoading, ...) builds on top.
   Note: module modal-width overrides are all gated to @media (min-width:1200px),
   so on mobile Bootstrap's near-full-width modal defaults already apply — the
   real mobile gaps are form-field stacking, popup overflow, and shell chrome.
   ========================================================================== */
@media (max-width: 767.98px) {

    /* --- Forms: stack the label above the input --------------------------
       Module forms use a fixed-width left label (.left-label, often
       ID-scoped) or a table-based field layout (.field-wrapper) that stays
       side-by-side and overflows a phone. Force a stacked (label-over-input)
       layout. !important beats the ID-scoped per-dialog width rules. */
    .left-label {
        width: auto !important;
        display: block !important;
        margin-bottom: 0.25rem;
        text-align: left !important;
    }

    .field-wrapper,
    .field-wrapper > tbody,
    .field-wrapper > tbody > tr {
        display: block !important;
        width: 100% !important;
    }

        .field-wrapper > tbody > tr > td {
            display: block !important;
            width: 100% !important;
            padding: 2px 0 !important;
        }

    /* --- Server-rendered wide tables scroll, not the page ----------------
       Some grids (e.g. VesselLoading's barge tables and the stow plan) are
       server-rendered <table>s inside .DataGrid.table-responsive, not
       client-rendered grids that collapse into cards. Here the wrapper's
       overflow-x resolves to visible, so a table wider than the phone pushes
       the whole page into horizontal scroll. Constrain it so the wide table
       scrolls inside its own box instead. (Card-collapsing grids have no
       overflow, so this is a no-op for them.) */
    .DataGrid.table-responsive {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* --- Fixed-width form controls cap to the container ------------------
       Some dialogs hardcode a control width (e.g. a comments textarea at
       width:500px) that overflows a phone and pushes the page into
       horizontal scroll even while the dialog is off-screen. Cap to the
       container; box-sizing keeps padding/border inside the cap. */
    textarea {
        max-width: 100% !important;
        box-sizing: border-box;
    }

    /* A native <select> sizes to its widest option, so a long option (e.g. a
       commodity name) can push the control past a narrow dialog and force the
       modal to scroll horizontally. Cap selects inside dialogs to the
       container. (Scoped to .modal so page/grid editors are untouched.) */
    .modal select {
        max-width: 100% !important;
    }

    /* --- Autocomplete / date-picker popups fit the viewport --------------
       Tom Select dropdowns append to <body> and size to their widest option
       (min-width: max-content); flatpickr calendars can overflow a narrow
       screen. Cap both to the viewport so options stay reachable. */
    body > .ts-dropdown,
    .ts-wrapper .ts-dropdown {
        max-width: 95vw !important;
        min-width: 0 !important;
    }

    .flatpickr-calendar {
        max-width: 95vw !important;
    }

    /* Bootstrap popovers append to <body> and some modules widen them to a
       fixed width (e.g. .popover { width:400px; max-width:none }), which
       overflows a phone narrower than that width. Cap to the viewport. */
    .popover {
        max-width: calc(100vw - 1rem) !important;
    }

    /* --- Modal button rows wrap instead of overflowing ------------------- */
    .modal .button-container {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }

    /* Making .button-container a flexbox (above) defeats its .text-center
       (text-align does not center flex items — they default to flex-start),
       so a centered section button like "Add Email" ends up left-aligned on
       mobile. Honor the centering intent under flex. */
    .modal .button-container.text-center {
        justify-content: center;
    }

    /* Many dialogs lay out their footer buttons as a 2-cell <table> (a
       text-left group — often a save-progress spinner — and a text-right
       button group). On a phone the cells stay side-by-side and the buttons
       overflow. Stack the cells full-width so each group wraps cleanly, and
       give the buttons a little vertical breathing room for touch. Shared
       across every module's dialogs (Inventory, Common, Railcar, ...). */
    .modal-footer > table,
    .modal-footer > table tbody,
    .modal-footer > table tr {
        display: block;
        width: 100%;
    }

    .modal-footer > table td {
        display: block;
        width: 100% !important;
        max-width: none !important;
    }

    .modal-footer > table .btn {
        margin-top: 0.25rem;
    }

    /* --- App shell ------------------------------------------------------- */
    /* Treat the slide-in left menu as a modal drawer: dim + scroll-lock the
       page behind it (menu.js already toggles body.sidebar-enable and closes
       on outside click). The sidebar is z-index 10 when open, so the backdrop
       sits just under it at 9. */
    body.sidebar-enable {
        overflow: hidden;
    }

        body.sidebar-enable::before {
            content: "";
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.4);
            z-index: 9;
        }

    /* The profile dropdown is a fixed 200px and the portal switcher is laid
       out for desktop (fixed width + large left margin); both cause horizontal
       overflow on a phone. Let them fit the viewport. */
    .profile-dropdown {
        width: auto !important;
        max-width: 90vw;
    }

    .portal-list {
        margin-left: 0 !important;
        max-width: 100%;
    }

        .portal-list #ddPortalList,
        #ddPortalList {
            width: 100% !important;
            max-width: 100%;
        }

    /* Align the page-title gutters with the reduced mobile content padding so
       the title box doesn't overhang and trigger horizontal scroll. */
    .page-title-box {
        padding-left: 10px !important;
        padding-right: 10px !important;
        margin-left: -10px !important;
        margin-right: -10px !important;
    }

    /* Keep toasts on-screen, below the topbar, and full-width (clear of the
       sidebar drawer) instead of a fixed top-right box that can clip. */
    #toast-container {
        top: 80px !important;
        right: 10px !important;
        left: 10px !important;
        width: auto !important;
    }

        #toast-container > div {
            width: 100% !important;
            max-width: none !important;
        }

    /* --- Touch targets: enlarge small controls toward ~44px -------------
       Grid per-row action buttons/icons, pager links, the modal close
       button, and nested (level 2-3) menu items all render below the ~44px
       touch minimum. Enlarge the tap area (and the tiny 11px grid-button
       glyph). In the responsive card layout the action buttons ride the
       card's top-right corner, so this enlarges them there too. */

    /* Per-row grid action buttons (edit/delete/print) — were 27x27 @ 11px */
    .DataGrid > table > thead > tr > td > .button-container > button,
    .DataGrid > table > tbody > tr > td > .button-container > button {
        width: 40px !important;
        height: 40px !important;
        font-size: 15px !important;
    }

    /* Per-row action icon links (edit / delete / info) */
    .DataGrid td.icon-column a,
    .DataGrid td.edit-column a,
    .DataGrid td.delete-column a {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        min-height: 40px;
    }

    /* Grid pager links */
    .GridPager .page-link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        min-height: 40px;
        padding: 0.4rem 0.6rem;
    }

    /* Modal close button */
    .modal .close {
        min-width: 44px;
        min-height: 44px;
        padding: 0.25rem 0.6rem;
        font-size: 1.6rem;
    }

    /* Nested sidebar menu items (drawer, level 2-3) — were ~26px tall.
       Uplon v3 renders every nested level as .sub-menu (metisMenu's
       .nav-second-level / .nav-third-level are gone with the plugin), and the
       links are .side-nav-link. The old selectors are kept alongside so this
       still applies if any view has not been migrated. */
    .sub-menu li a,
    .sub-menu li .side-nav-link,
    .nav-second-level li a,
    .nav-thrid-level li a {
        padding-top: 11px !important;
        padding-bottom: 11px !important;
        padding-left: 16px !important;
    }

    /* --- Responsive card polish ----------------------------------------- */

    /* Empty/colspan message rows ("No rows to display.", loading) inherit the
       card value alignment (right); center them across the card. */
    .mt-grid-responsive tbody td[colspan] {
        text-align: center !important;
        justify-content: center !important;
    }

    /* Hide the grid's own outer frame (div.DataGrid > table draws
       border-left/right/bottom) once it has collapsed into cards — the per-card
       borders are the only frame wanted in card view. */
    .DataGrid.mt-grid-responsive > table {
        border: 0 !important;
    }

    /* Tighten the dead space around a card-collapsed grid: the .card-body
       padding (20px) stacks with the grid's own top margin (20px) and its
       table's bottom margin (16px) into ~40px gaps on a phone. */
    .card-body:has(.mt-grid-responsive) {
        padding: 0.5rem;
    }

    .DataGrid.mt-grid-responsive {
        margin-top: 0;
    }

        .DataGrid.mt-grid-responsive > table {
            margin-bottom: 0;
        }

    /* Each card carries a bottom margin for inter-card spacing; on the last
       card that margin lands against the card-body padding and makes the
       below-grid gap larger than the above-grid gap. Drop it so the stack is
       flush and the whitespace above/below the grid is equal. */
    .mt-grid-responsive tbody tr:last-child {
        margin-bottom: 0;
    }

    /* With the last card flush (above) and the table's bottom margin zeroed,
       the pager would butt against the last card; restore a gap above it. */
    .mt-grid-responsive .GridPager {
        margin-top: 0.75rem;
    }

    /* Cubics/Holds table: the Cubics + Depth fields use float:left to sit side
       by side on desktop. Once the table cells stack on mobile (Phase 0), the
       uncleared floats leak into the next row and shove each following hold's
       "Available" checkbox to the right edge. Drop the float so each hold
       stacks cleanly (available checkbox, then Cubics, then Depth). */
    .cubics-wrapper .holds-table .field {
        float: none;
    }

    /* Card-header bars (e.g. "Search Options") lay out their title + collapse
       caret as a 2-cell .field-wrapper table. The generic .field-wrapper
       stacking (above) drops the caret onto its own line; keep header
       field-wrappers as a single title-left / caret-right row. */
    .card-header .field-wrapper {
        display: table !important;
        width: 100% !important;
    }

        .card-header .field-wrapper > tbody {
            display: table-row-group !important;
        }

        .card-header .field-wrapper > tbody > tr {
            display: table-row !important;
        }

            .card-header .field-wrapper > tbody > tr > td {
                display: table-cell !important;
                width: auto !important;
            }

    /* A centered section button (e.g. "Add Email") sits in a .button-container
       with a .divider spacer; once the container is flex the divider shares
       the line and pushes the button off-center — give it its own row. */
    .modal .button-container.text-center .divider {
        flex-basis: 100%;
    }
}

/* ==========================================================================
   GRID TOTALS FOOTER IN CARD VIEW
   A grid <tfoot> totals row is laid out to align each total under its column
   (the non-total columns are empty cells carrying colspan). If it cards like a
   data row, those empty spacer cells stack into a tall mostly-blank block
   (e.g. the LoadOrders Lots grid showed ~282px of empty lines below the data).
   Instead, present the footer as one compact, bold, right-aligned totals line:
   hide the empty colspan spacer cells, drop the data-label gutter, and set off
   the row with a top border so the totals stay visible but tidy.
   ========================================================================== */
@container (max-width: 600px) {
    .mt-grid-responsive tfoot {
        display: block;
    }

    .mt-grid-responsive tfoot tr {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        align-items: baseline;
        gap: 0.25rem 0.75rem;
        margin-top: 0.25rem;
        padding: 0.5rem 0.75rem;
        border-top: 2px solid var(--mt-grid-card-border, #dee2e6);
        font-weight: 600;
    }

    .mt-grid-responsive tfoot td {
        display: inline-block;
        min-height: 0;
        padding: 0;
        border: 0;
        text-align: right;
    }

        /* Empty alignment spacers (they carry colspan); the totals are in the
           non-spanning cells. */
        .mt-grid-responsive tfoot td[colspan] {
            display: none;
        }

        .mt-grid-responsive tfoot td::before {
            content: none;
        }
}

/* A11y: Bootstrap's default .text-muted (#6c757d) is 4.44:1 on the light page
   background and cards — just under the WCAG 2 AA 4.5:1 minimum. Darken it
   slightly so muted helper text passes contrast. */
.text-muted {
    color: #61686e !important;
}

/* ---------------------------------------------------------------------------
   Uplon v3 chrome compatibility.

   The page-title and user-menu markup is unchanged from v2, but v3 ships rules
   for .page-title-box only. .page-title, .page-title-right and .noti-title are
   undefined there, so those classes stay on the elements and simply stop doing
   anything: the breadcrumb stops floating and stacks above the heading, the
   heading falls back to the plain h4 size (15.84px), and the user-menu header
   loses its bar. Nothing errors, which is why it is easy to miss.

   Values are the v2 ones, INCLUDING v2's `line-height: 60px` on .page-title.
   The shared uplon-v3-compat.css drops that line-height, because it assumes a
   portal on v3's own `.page-title-box { padding: 20px 24px }`, where the two
   would double-count to a ~100px bar. This portal is not that case: it
   overrides .page-title-box to `padding: 0 27px` for the full-bleed banner, so
   with no line-height the bar had nothing to give it height and collapsed to
   the height of its text - measured 19.8px against production's 60px.

   Keep the two in step: the 60px here is what the `padding: 0` up there relies
   on, and vice versa. Change one and the banner breaks.

   No sidebar logo override is needed - Menu.cshtml sizes it with an explicit
   height attribute, so v3's --bs-logo-lg-height never reaches it.

   Superseded by uplon-v3-compat.css in MeyerTechnologies.UI.Shared.Epsilon.js
   once this portal takes that package; remove this block then so the two cannot
   drift.
   --------------------------------------------------------------------------- */
.page-title-box .page-title {
    font-size: 18px;
    margin: 0;
    line-height: 60px;
}

/* The `margin-top: 7px` is correct and deliberate, not a leftover. It centres the
   breadcrumb against the 60px title line above, together with the .breadcrumb's own
   `padding: .75rem 0`. Measured on production: offset 0.3px.

   Do not zero these two here. That is the right fix only for a portal taking its bar
   height from v3's .page-title-box padding (PCI and RMG do, and zero them for exactly
   that reason); on this portal, which keeps the 60px line, zeroing them moves the
   breadcrumb off-centre instead of onto it. */
.page-title-box .page-title-right {
    float: right;
    margin-top: 7px;
}

/* The other half of that centring. v2's stylesheet gave the breadcrumb
   `padding: .75rem 0` (12px); under v3 it computes to 16px, which is enough to
   push it 3.5px off the heading's centre. Restoring 12px lands the offset at
   0.3px - the same figure production measures. */
.page-title-box .breadcrumb {
    padding: .75rem 0;
}

.dropdown-menu .noti-title {
    background-color: var(--bs-primary, #64b0f2);
    padding: 15px 20px;
    border-radius: .25rem .25rem 0 0;
    margin-top: -7px;
}

    .dropdown-menu .noti-title,
    .dropdown-menu .noti-title h5,
    .dropdown-menu .noti-title h6 {
        color: #fff;
    }

/* v2 had `.page-dropdown{width:auto!important}`; v3 ships no rule for the class
   at all, so the page-size select stretched to its container - 306px for a
   two-character value on the portals where this was measured. */
.page-dropdown {
    width: auto !important;
}

/* Sidebar menu.

   Not part of the uplon-v3-compat.css block above: that sheet only replaces
   rules v3 leaves *undefined*, whereas v3 defines the menu perfectly well and
   simply defines it differently. It will not be superseded by taking the
   UI.Shared package, so it stays here.

   v2 styled the links as `#sidebar-menu > ul > li > a` at 15.5px in a soft grey
   (#6e768e) with no font-weight, so they sat at the body's normal 400 and
   inherited the body's 1.5 line-height. v3 restyles the same links as
   `.side-nav-link` and drives all of it from tokens: `--bs-menu-item-color`
   (#495057), `font-weight: 500`, and a font-size AND line-height both set from
   `--bs-menu-item-font-size` (15px) - which together make the menu read darker,
   heavier and tighter than the one this portal has always had. Brought back in
   line with PCI and RMG, which already carry this override.

   The colour goes through the theme's own variable, scoped to `.side-nav`, so
   the states derived from it stay in step. Weight and size have to be reclaimed
   as properties, because v3 sets them from two places:

     .side-nav .side-nav-item .side-nav-link                           (0,3,0)
     .side-nav > .side-nav-item.active .side-nav-link.active,
     .side-nav > .side-nav-item.active > a                            (0,4,0)

   so a plain `.side-nav .side-nav-link` (0,2,0) loses to both - which is why
   the ACTIVE item in particular would stay bold. Matching the same selectors
   wins on source order, since site.css loads after app.min.css.

   Sub-menu links are deliberately left at v3's size (14.25px): v2 gave them no
   size of their own, so they inherited the body's ~14.4px (production measures
   14.4px), and forcing the top-level 15.5px on them would make them bigger than
   they have ever been. This is why the font-size rule below is scoped to direct
   children only, and is the one place this block differs from RMG's copy, which
   applies 15.5px at every level.

   SELECTED ITEM - note the selector. PCI and RMG hang their active rules off
   `.side-nav-item.active` (the `<li>`), because their menu markup puts the class
   there. This portal's Menu.cshtml puts `active` on the ANCHOR and never on the
   `<li>` - and so does production - so those selectors match nothing here and the
   selected item rendered identically to an unselected one. Targeting
   `.side-nav-link.active` is what matches the markup this portal actually emits.

   Values measured off loadmaster.meyertechnologies.net: label #003D79 on a
   #f5f8fb band. (Same navy as PCI; the earlier #143d58 here was this portal's
   brand accent guessed in lieu of a measurement, and was wrong.) The theme's
   --bs-menu-item-active-* tokens are not used, since v3 only consumes them from
   the `.side-nav-item.active` selectors that never match. */
.side-nav {
    --bs-menu-item-color: #6e768e;
}

    .side-nav .side-nav-item .side-nav-link {
        font-weight: 400;
        line-height: 1.5;
    }

    .side-nav > .side-nav-item > .side-nav-link {
        font-size: 15.5px;
    }

    .side-nav .side-nav-link.active {
        background-color: #f5f8fb;
        color: #003D79;
    }

    /* v2's menu heading was 11px/600; v3 derives 10.5px/700 from the item
       font-size token. */
    .side-nav .side-nav-title {
        font-size: 11px;
        font-weight: 600;
    }

/* Tab and pill labels. v3 inherits Bootstrap's own .nav-link weight, which
   reads heavier than the rest of the portal's chrome - the sidebar links above
   are already pulled back to 400. Match them so tabs and the menu agree. */
.nav-pills > li > a,
.nav-tabs > li > a {
    font-weight: 400;
}
