@import '_content/Quartz.Dashboard/Quartz.Dashboard.0oac2rqtdq.bundle.scp.css';

/* /Components/Layout/AuthenticatedLayout.razor.rz.scp.css */
/* Nav drawer color scheme as CSS custom properties, so the light defaults and the dark overrides
   live in one place and the footer toggle just flips a class on .page. NavMenu.razor.css consumes the
   --nav-* tints (custom properties inherit through the DOM, so a different scoped file still sees
   them); the drawer bg/text/icon reuse MudBlazor's own palette vars, overridden for the dark scheme.
   Light is the default (matches main); .nav-dark overrides. */
.page[b-66t3jbdclp] {
    height: 100%;
    font-family: var(--bs-font-sans-serif);
    --nav-hover-bg: rgba(var(--mud-palette-primary-rgb), 0.08);
    --nav-active-bg: rgba(var(--mud-palette-primary-rgb), 0.14);
    --nav-footer-text: var(--mud-palette-text-secondary);
    --nav-footer-border: var(--mud-palette-divider);
}

.page.nav-dark[b-66t3jbdclp] {
    --mud-palette-drawer-background: #191F6C;
    --mud-palette-drawer-text: #ffffff;
    --mud-palette-drawer-icon: #ffffff;
    --nav-hover-bg: rgba(255, 255, 255, 0.10);
    --nav-active-bg: rgba(255, 255, 255, 0.18);
    --nav-footer-text: rgba(255, 255, 255, 0.70);
    --nav-footer-border: rgba(255, 255, 255, 0.15);
}

[b-66t3jbdclp] .navigation-drawer .navigation-drawer-header {
    width: 100%;
    display: flex;
    align-items: center;
    /* Center the logo in the full drawer width. The collapse hamburger is taken out of flow
       (position:absolute below) so it doesn't steal width on the right and pull the "centered"
       mark off-centre — position:relative here anchors that absolute toggle. */
    justify-content: center;
    position: relative;
    /* 2rem top+bottom left ~48px of dead space below the small logo (very noticeable as a
       tall overlay on thin screens). 1rem keeps modest breathing room without the big gap. */
    padding: 1rem 1rem;
    border-bottom: none;
}

/* Center the stacked mark; no flex:1 so it stays its natural width and the header's
   justify-content:center centres it across the whole drawer rather than beside the hamburger. */
[b-66t3jbdclp] .navigation-drawer .navigation-drawer-header .navigation-drawer-logo {
    display: flex;
    justify-content: center;
}

/* The collapse hamburger sits on the navy fill, so its icon knocks out to white
   (Color.Inherit alone would leave it the default dark). */
[b-66t3jbdclp] .navigation-drawer .navigation-drawer-header .menu-button .mud-icon-root {
    color: var(--mud-palette-drawer-icon);
}

/* Take the collapse toggle out of flow and pin it to the top-right corner, near the drawer edge, so
   it doesn't affect the centred logo. right:0.375rem sits it close to the edge; top:1rem matches the
   content row's top padding so the button is at the same height whether the nav is expanded (here) or
   collapsed (the reopen hamburger in the content row). min-width:0 + tight padding drop MudButton's
   64px min-width so the compact icon sits right at the corner. */
[b-66t3jbdclp] .navigation-drawer .navigation-drawer-header .menu-button {
    position: absolute;
    top: 1rem;
    right: 0.375rem;
    min-width: 0;
    padding: 0.25rem;
}

/* Cap the width and let height scale so the stacked lockup stays compact (120px) inside the 240px
   drawer. The header shows it in the current scheme's own colors — the native multi-color lockup on
   the light scheme, the steel recolor on dark (see CompanyInfoConstants) — as a plain img, so no
   filter/mask is needed here. */
[b-66t3jbdclp] .navigation-drawer .navigation-drawer-header .logo {
    max-width: 120px;
    height: auto;
}

/* Grow to fill the drawer's flex column so the footer is pinned to the bottom instead of sitting
   directly below the last nav item. MudBlazor already makes .mud-drawer-content a full-height
   column (height:100%; display:flex; flex-direction:column), so this body just needs to be the
   flexible child; the footer, at natural height, then lands at the bottom. min-height:0 +
   overflow-y let a long menu scroll within the body rather than pushing the footer off-screen. */
[b-66t3jbdclp] .navigation-drawer-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 1rem 0;
}

[b-66t3jbdclp] .navigation-drawer-footer {
    padding: 1rem 1.5rem 1.5rem;
    display: flex;
    justify-content: center;
    border-top: none;
}

/* Headerless control row over the content — replaces the old top app bar. It carries the reopen
   hamburger (rendered only while collapsed), the back button, and user/logout. flex:0 0 auto so it
   sits at natural height at the top of the flex-column content pane; auth-controls is pushed right.
   Its buttons and icons take the brand navy on the light content surface (the navy nav's own icons
   knock out to white via the drawer rules above). */
.nav-buttons-container[b-66t3jbdclp] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 1rem 1.5rem;
}

.nav-buttons-container .auth-controls[b-66t3jbdclp] {
    margin-left: auto;
}

.nav-buttons-container[b-66t3jbdclp]  .mud-button-root,
.nav-buttons-container[b-66t3jbdclp]  .mud-icon-root {
    color: var(--mud-palette-appbar-text);
}

/* The drawer runs full-height on the left, starting directly under the env banner. With no app bar
   there is nothing above it and nothing beside it — the content pane simply fills the width to its
   right. ClipMode is Always so this explicit height governs; MudBlazor adds no top offset of its own. */
[b-66t3jbdclp] .mud-drawer.navigation-drawer {
    top: var(--env-banner-height, 0px);
    height: calc(100vh - var(--env-banner-height, 0px));
}

/* No padding-top: there is no app bar to clear (the .environment-banner-spacer already holds
   --env-banner-height of flow above MudLayout, and the nav-buttons-container supplies the top gap).
   Filling the remaining viewport (border-box, so the padding stays inside that height) lets a page
   stretch to the fold and centre itself; block-level pages are unaffected by the flex.

   height, not min-height: a flex child only shrinks against a definite height, and that shrink is what
   lets a grid stop at the fold instead of growing the page. The trade is that this element scrolls rather
   than the window, so anything taller than the fold — a long form, a grid on a short viewport — needs the
   overflow here to stay reachable.

   dvh over vh where supported, for the same reason UnauthenticatedLayout carries -webkit-fill-available:
   mobile 100vh is the height with the browser chrome collapsed, so the bottom of a definite-height, own-
   scrolling pane would sit behind the URL bar with nothing left to scroll. It has to be @supports rather
   than two height declarations — Blazor's scoped-css bundler keeps only the first of a repeated property,
   so the usual fallback pair silently ships as vh alone. */
[b-66t3jbdclp] .mud-main-content {
    box-sizing: border-box;
    padding-top: 0;
    height: calc(100vh - var(--env-banner-height, 0px));
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

@supports (height: 100dvh) {
    [b-66t3jbdclp] .mud-main-content {
        height: calc(100dvh - var(--env-banner-height, 0px));
    }
}

/* Passes that fill down to @Body, so a page can stretch to the fold with `flex: 1` of its own.
   min-height: 0 so a tall child shrinks to the fold instead of forcing this box past it. */
.page-body[b-66t3jbdclp] {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* The bottom gap, as a flex item rather than this box's padding. With flex-basis 0 the box is exactly the
   pane's height, so a page taller than the fold overflows it — and an overflowed box's padding sits above
   the overflow rather than after it, leaving the last field flush against the pane's edge at full scroll.
   A spacer is content, so it lands at the end of the scrollable area where the gap belongs. */
.page-body[b-66t3jbdclp]::after {
    content: "";
    flex: 0 0 1rem;
}

.auth-controls.display-desktop[b-66t3jbdclp] {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* On tablet/phone widths (≤1024px) hide the header auth controls; the same actions
   (user name + log out) are surfaced inside the drawer's mobile menu instead. */
@media (max-width: 1024px) {
    .auth-controls.display-desktop[b-66t3jbdclp] {
        display: none;
    }
}

.user-info[b-66t3jbdclp] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    color: var(--mud-palette-appbar-text);
}

/* Footer colors follow the nav scheme via --nav-footer-* (light defaults on .page, dark on
   .page.nav-dark), so the divider and text read on either fill. */
.sidebar-footer[b-66t3jbdclp] {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem;
    gap: 1rem;
    border-top: 1px solid var(--nav-footer-border);
}

.copyright-info[b-66t3jbdclp] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    font-size: 0.75rem;
    color: var(--nav-footer-text);
    line-height: 1.4;
}

.sidebar-footer-text[b-66t3jbdclp] {
    margin: 0.1rem 0;
}
.sidebar-footer-text.version-info[b-66t3jbdclp] { transition: opacity 0.2s ease; }
.sidebar-footer-text.version-info:hover[b-66t3jbdclp] { opacity: 0.7; }

/* The dev-facing dark/light toggle, below the version. Both the label and the icon take the footer
   text colour so they read on either scheme (the navy footer hid a MudSwitch's track). */
.nav-theme-toggle[b-66t3jbdclp] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.nav-theme-toggle-label[b-66t3jbdclp] {
    color: var(--nav-footer-text);
    font-size: 0.75rem;
}

[b-66t3jbdclp] .nav-theme-toggle-btn .mud-icon-root {
    color: var(--nav-footer-text);
}
/* /Components/Layout/Drawer.razor.rz.scp.css */
[b-lwizixhn2r] .navigation-drawer {
    height: calc(100vh - var(--env-banner-height, 0px));
    max-height: 100%;
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
#sidebar[b-zswk0q6kaa] {
    /* Fluid, not a fixed width: fill the drawer's content area and shrink when the vertical scrollbar
       appears. A fixed width equal to the drawer stayed full-width while the scrollbar ate into the
       container, so it overflowed by the scrollbar's width — the horizontal scrollbar on an expanded
       group (widening the drawer didn't help, the fixed sidebar just got wider too). The MudDrawer
       Width sets the nav's actual width. */
    width: 100%;
    min-width: 0;
    transition: transform 0.1s ease-out;
    height: 100%;
    max-height: 100%;
    display: block;
    background: inherit;
}

.logo[b-zswk0q6kaa] {
    text-align: center;
}

[b-zswk0q6kaa] .menu.display-mobile {
    margin-bottom: 2rem;
}

[b-zswk0q6kaa] .menu.display-iam {
    margin-bottom: 2rem;
}

[b-zswk0q6kaa] .menu {
    background-color: inherit;
}

[b-zswk0q6kaa] .menu {
    gap: 0.5rem;
}

[b-zswk0q6kaa] .menu-item {
    color: var(--mud-palette-drawer-text);
    display: flex;
    align-items: center;
    /* A <button>.menu-item (the logout row) defaults to justify-content: center, which
       centers its icon+text; divs/links default to flex-start. Force flex-start so every
       row's icon lines up on the same left edge regardless of element type. */
    justify-content: flex-start;
    gap: 0.75rem;
    padding: 0.5rem 1rem;
    text-decoration: none;
    border-radius: 0.25rem;
}

/* Row tints follow the nav scheme via --nav-hover-bg / --nav-active-bg (defaults set on .page,
   dark overrides on .page.nav-dark, both in AuthenticatedLayout.razor.css). */
[b-zswk0q6kaa] .menu-item:hover {
    background-color: var(--nav-hover-bg);
    color: var(--mud-palette-drawer-text);
}

[b-zswk0q6kaa] .menu-item.active {
    background-color: var(--nav-active-bg);
    /* Brand-red (#EA0A2A, the logo's accent) bar on the left edge of the selected row. An inset
       box-shadow rather than a border-left: it adds no width and shifts no content, and it follows
       the row's border-radius. NavLink adds .active on the matched route, so only real links get it
       (not the Admin/WIP/Master Data group-header buttons). Works on both the light and navy schemes. */
    box-shadow: inset 3px 0 0 0 #EA0A2A;
}

[b-zswk0q6kaa] .menu-item .mud-icon-root {
    color: var(--mud-palette-drawer-icon);
}

/* user-display and the logout button both carry the .menu-item class, so they inherit its
   padding (1rem) and gap (0.75rem) and line up with the nav links — every sidebar row shares
   one icon column and one text column (matches TWC). These rules only add what differs. */
.user-display[b-zswk0q6kaa] {
    cursor: default; /* a label, not a link */
}

.user-display:hover[b-zswk0q6kaa] {
    background-color: transparent; /* no hover affordance on the non-clickable label */
}

/* Admin group. The chevron is pushed to the right edge of the header row and rotates to point
   right while the group is collapsed, down while it is open. */
[b-zswk0q6kaa] .menu-group-chevron {
    margin-left: auto;
    transition: transform 0.15s ease;
}

[b-zswk0q6kaa] .menu-group-header:not(.expanded) .menu-group-chevron {
    transform: rotate(-90deg);
}

/* Child rows sit indented under the header so the group reads as a nested list. The extra left
   padding outranks .menu-item's own (higher-specificity selector), shifting the icon column in. */
[b-zswk0q6kaa] .menu-group-children {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* 2.25rem, not 2.75: the wider indent pushed the longest sub-labels (e.g. Master Data's
   "Services on a Job") close enough to the edge that once an expanded group triggered the vertical
   scrollbar — which eats a few px of width — the row overflowed and a horizontal scrollbar appeared.
   This keeps a clear nested indent while leaving that tolerance. */
[b-zswk0q6kaa] .menu-group-children .menu-subitem {
    padding-left: 2.25rem;
}

/* On tablet/phone widths (≤1024px) the drawer is an overlay. #sidebar is already fluid (width:100%),
   so only the logo alignment needs adjusting here. 1024px keeps iPads in this mode. */
@media (max-width: 1024px) {
    .logo[b-zswk0q6kaa] {
        text-align: inherit;   /* Drop the centered desktop alignment in the narrow drawer. */
    }
}
/* /Components/Layout/UnauthenticatedLayout.razor.rz.scp.css */
.page[b-njgkfb2cva] {
    position: relative;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Brand lockup centered above the page body (the login/account form). The
   top padding gives the mark breathing room from the viewport edge. */
.logo-container[b-njgkfb2cva] {
    width: 100%;
    display: flex;
    justify-content: center;
    padding: 4.5rem 1rem 0.5rem;
}

.logo-container .logo[b-njgkfb2cva] {
    max-width: 350px;
    height: auto;
}

.main-content[b-njgkfb2cva] {
    flex: 1;
    padding: 1rem;
}

/* Override site.css's global .main-content vertical centering so the form
   stacks directly below the brand lockup. ::deep compiles to a descendant
   selector rooted at this layout's scope, which reaches both the layout's
   own <main> (the scope attribute sits on .page) and the account pages'
   inner .main-content wrappers rendered via @Body. */
[b-njgkfb2cva] .main-content {
    align-items: flex-start;
    height: auto;
}

.footer[b-njgkfb2cva] {
    width: 100%;
    background-color: #f8f9fa;
    border-top: 1px solid #dee2e6;
    padding: 1rem;
    margin-top: auto;
}

.footer-content[b-njgkfb2cva] {
    text-align: center;
    color: #6c757d;
    font-size: 0.875rem;
}

/* The lockup shrinks earlier than the 480px auth adaptations below — 576px
   matches the sibling apps, so a narrow window never shows the full-size
   mark towering over the form. */
@media (max-width: 576px) {
    .logo-container .logo[b-njgkfb2cva] {
        max-width: 150px;
    }
}

/* Mobile adaptations for auth pages */
@media (max-width: 480px) {
    .page[b-njgkfb2cva] {
        min-height: -webkit-fill-available; /* iOS Safari 100vh fix */
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .main-content[b-njgkfb2cva] {
        padding: 0.75rem 1rem;
    }

    .footer[b-njgkfb2cva] {
        padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    }
}

/* Hide footer on very short/landscape screens */
@media (max-width: 480px) and (max-height: 700px) {
    .footer[b-njgkfb2cva] {
        display: none;
    }
}
/* /Components/Pages/Admin/ReferenceData/JobTemplatesSection.razor.rz.scp.css */
/* Column sizing for the Job Templates grid.
   ─────────────────────────────────────────
   MudDataGrid with ResizeMode.Container shares the container's width across the columns, and with no
   hints it gives a column holding the number 3 as much room as one holding a sentence. The result
   was two prose columns squeezed into a narrow ribbon while Equipment and From DT sat mostly empty,
   and Actions — last in the row — took what was left and clipped its buttons.

   The fix is the classic table pair: the columns that should shrink are set to width 1% and told not
   to wrap, which makes the browser size them to their content; the prose columns are allowed to wrap
   and given a floor, so they absorb the slack instead.

   ::deep throughout because MudBlazor renders the cell, so the isolation attribute lands on this
   component's wrapper rather than on the td the class is applied to — the same reason
   JobManagementIndex's .job-cell-figure is written this way. */

/* Prose. Wraps onto as many lines as it needs rather than being clipped to one, with a floor so it
   cannot be squeezed back into a ribbon by a long value in another column. */
[b-aoad2wiwla] .tpl-col-wrap {
    white-space: normal;
    min-width: 12rem;
}

/* Status holds a chip — and, when authorized, a second line naming the reviewer and date — or, on a
   template awaiting review, the Authorize button itself. Narrower floor than the description
   because the chip and the button set their own width and the caption is short. */
[b-aoad2wiwla] .tpl-col-status {
    white-space: normal;
    min-width: 10rem;
}

/* Short values — a count and a DT number. width: 1% is not a literal width: it is the standard way
   to ask a table cell to shrink to its content, since the browser treats it as "as small as
   possible" and the nowrap stops it wrapping to get there. Right-aligned because both are numeric,
   the same reasoning as .job-cell-figure.

   What they shrink to is the header, not the value — a "3" needs a few pixels, while the header
   carried its label, 32px of padding and 63px of hover-only icons (sort button, sort index and the
   column-options menu), all taking space while invisible. The markup turns the options menu off on
   these two, and the padding here is halved; measured in the running app, Equipment went from 164px
   to 122px and From DT from 148px to 106px, which was the width the table overflowed its card by. */
[b-aoad2wiwla] .tpl-col-tight {
    width: 1%;
    white-space: nowrap;
    text-align: right;
    padding-inline: 0.5rem;
}

/* No horizontal scroll: the table is held to the card's width.

   ColumnResizeMode.Container — which GridConventionTests require on every grid — writes an inline
   width: max-content on the table container. At max-content every cell is laid out on one line, so
   white-space: normal above never got a chance to wrap anything: the table grew past the card,
   which is what produced the horizontal scroll and kept "When to use it" on a single line. Holding
   the container at 100% hands the width back to the table's own layout, which wraps the prose
   columns to fit. !important because the value it overrides is an inline style.

   The trade: a dragged column can no longer push the table wider than the card — widening one
   column now narrows the others instead. Measured in the running app: at 1646px and at 1280px the
   table fits its card exactly, where before it overflowed by 126px and 339px. */
[b-aoad2wiwla] .mud-table-container {
    width: 100% !important;
}

/* Actions: shrink to its buttons so the prose columns absorb any squeeze. */
[b-aoad2wiwla] .tpl-col-actions {
    width: 1%;
    white-space: nowrap;
}

/* The buttons' row, inside the cell rather than on it. The cell used to carry d-flex itself, and a
   td made display: flex drops out of the table's column layout: it collapsed to 32px and started
   under the Status header instead of Actions. As a table-cell it lines up under its header, while
   this div keeps the three buttons right-aligned on one line. Every row carries the same three —
   Authorize lives in the Status column — so they sit in the same place on every row. */
[b-aoad2wiwla] .tpl-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: nowrap;
}
/* /Components/Pages/Admin/ReferenceData/VendorDetail.razor.rz.scp.css */
/* Label column then value column — the classic definition-list two-up, matching the asset detail
   read view. Scoped to this page; the dt/dd elements are authored directly in VendorDetail.razor so
   the scope attribute lands on them without needing ::deep. */
.vendor-detail-list[b-9ohaxci6wa] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.35rem 1rem;
    margin: 0;
}

.vendor-detail-list dt[b-9ohaxci6wa] {
    color: var(--mud-palette-text-secondary);
}

.vendor-detail-list dd[b-9ohaxci6wa] {
    margin: 0;
}
/* /Components/Pages/HrCertifications/CertificationFilterChips.razor.rz.scp.css */
/* The chips wrap as a group, without MudChip's outer margin doubling the gap. */
.certification-filter-chips[b-3gyhxkpdkw] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.certification-filter-chips[b-3gyhxkpdkw]  .mud-chip {
    margin: 0;
}
/* /Components/Pages/HrCertifications/CertificationGroupChips.razor.rz.scp.css */
/* Chips wrap onto as many lines as the groups need, without MudChip's outer margin doubling the gap. */
.certification-group-chips[b-jdqme4kmhu] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.certification-group-chips[b-jdqme4kmhu]  .mud-chip {
    margin: 0;
}
/* /Components/Pages/HrCertifications/CertificationSections.razor.rz.scp.css */
/* The sections a filter emptied, named once under the panels. */
.certification-sections-hidden-sections[b-xoemylyaxh] {
    margin-top: 0.75rem;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* A section's header: its name, the status counts, and the coverage at the far right. */
.certification-sections-section-header[b-xoemylyaxh] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
}

/* A section's name: navy like the Certifications heading above it, but a step smaller, so it reads as a
   subsection of it. */
.certification-sections-section-name[b-xoemylyaxh] {
    font-family: var(--mud-typography-h6-family);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--mud-palette-primary);
}

.certification-sections-section-counts[b-xoemylyaxh] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    flex: 1 1 auto;
}

.certification-sections-section-counts[b-xoemylyaxh]  .mud-chip {
    margin: 0;
}

.certification-sections-section-coverage[b-xoemylyaxh] {
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

/* A section's grid stays inside its panel: it scrolls sideways rather than clipping the actions column when
   the window is narrow, and a long section (All Crew runs past 100 courses) scrolls within a capped height,
   which is also what gives the pinned header something to stick inside. */
.certification-sections[b-xoemylyaxh]  .mud-table-container {
    max-width: 100%;
    max-height: 28rem;
    overflow: auto;
}

/* A renewal's superseded record: kept as history, set back so the current record for the course reads
   first. Mirrors the roster's inactive rows. ::deep because the row element belongs to MudDataGrid. */
[b-xoemylyaxh] .certification-sections-row-superseded {
    opacity: 0.55;
}

/* A plain word rather than a status chip — superseded is history, not a compliance verdict. */
.certification-sections-superseded[b-xoemylyaxh] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Certify / Recertify and the ⋮ menu, kept on one line at the end of the row. */
.certification-sections-cert-actions[b-xoemylyaxh] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: nowrap;
    white-space: nowrap;
}
/* /Components/Pages/HrCertifications/CertificationTestReminderDialog.razor.rz.scp.css */
/* What the technician's email lists, as a quiet inset under the fields. */
.cert-reminder-preview[b-swv4ngk7bh] {
    padding: 12px 16px;
    border-radius: 4px;
    background: var(--mud-palette-background-gray);
    font-size: 0.875rem;
}

.cert-reminder-subject[b-swv4ngk7bh] {
    font-weight: 600;
    margin-bottom: 6px;
}

.cert-reminder-preview ul[b-swv4ngk7bh] {
    margin: 0;
    padding-left: 20px;
}
/* /Components/Pages/HrCertifications/CrewSchedulingIndex.razor.rz.scp.css */
/* Title row: the page heading on the left, the unscheduled-jobs button pinned to the right at the same height. */
.crew-scheduling-titlebar[b-mekji5pi99] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.crew-availability-filters[b-mekji5pi99] {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-end;
    margin-bottom: 12px;
}

/* A plain wrapper this component owns, so scoped CSS can size it — the MudBlazor inputs inside default
   to full width, so they fill it. */
.crew-availability-field[b-mekji5pi99] {
    width: 240px;
    max-width: 100%;
}

/* The date-range picker renders "start – end" in one field, so it needs more room than a single input
   or the end date is clipped. */
.crew-availability-field-range[b-mekji5pi99] {
    width: 300px;
}

/* Lives in the filter row now (pushed right, vertically centred with the controls) rather than its own band. */
.crew-availability-legend[b-mekji5pi99] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    margin-left: auto;
    align-self: center;
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
}

/* The conflict swatch in the legend — the same red as a conflicting bar. */
.crew-conflict-swatch[b-mekji5pi99] {
    background-color: #d30000;
}

.availability-swatch[b-mekji5pi99] {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
    border: 1px solid var(--mud-palette-lines-default);
    margin-right: 4px;
    vertical-align: middle;
}

/* Semi-transparent so the fill tints whatever surface shows through — it reads in both the light and the
   navy theme rather than being pinned to one background. */
.availability-on[b-mekji5pi99] {
    background-color: rgba(46, 125, 50, 0.3);
}

.availability-off[b-mekji5pi99] {
    background-color: rgba(128, 128, 128, 0.22);
}

/* Time off (PTO) — a hatch, distinct from the plain grey of "no rotation group", reading as blocked. */
.availability-timeoff[b-mekji5pi99] {
    background-image: repeating-linear-gradient(
        45deg,
        rgba(120, 120, 120, 0.28),
        rgba(120, 120, 120, 0.28) 4px,
        rgba(120, 120, 120, 0.1) 4px,
        rgba(120, 120, 120, 0.1) 8px
    );
}

/* The grid scrolls horizontally inside its own box; the page body never does. */
.crew-availability-table-wrap[b-mekji5pi99] {
    overflow-x: auto;
    max-width: 100%;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
}

/* Fixed layout means every day column is equal width, so a ticket bar sized as a % of one cell spans an exact
   number of days. The table fills its container (width:100%) and the day columns share the leftover space after
   the fixed name column — so a short range stretches to fill rather than leaving the right half empty. The
   inline min-width (name + --crew-day-min per day) is the floor: past it the wrapper scrolls. box-sizing:
   border-box keeps a cell's border inside its width so the columns stay on the grid. */
.crew-availability-table[b-mekji5pi99] {
    --crew-name-width: 240px;
    --crew-day-min: 46px;
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.8rem;
}

.crew-availability-table th[b-mekji5pi99],
.crew-availability-table td[b-mekji5pi99] {
    box-sizing: border-box;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    border-right: 1px solid var(--mud-palette-lines-default);
}

/* The inter-day vertical dividers are lightened so the grid reads as rows — one person scanned left to
   right — rather than a heavy lattice, and so the ticket bars carry the colour. The row bottom borders and
   the name column's own right edge stay at full strength (they are the structure that matters). color-mix
   with transparent keeps it correct in both the light and the navy theme; it changes only the line colour,
   never the box model, so the bar-span math is untouched. */
.crew-availability-table thead th:not(.crew-availability-person-col)[b-mekji5pi99],
.crew-availability-table tbody td:not(.crew-availability-person-col)[b-mekji5pi99] {
    border-right-color: color-mix(in srgb, var(--mud-palette-lines-default) 40%, transparent);
}

/* Pinned header row. */
.crew-availability-table thead th[b-mekji5pi99] {
    position: sticky;
    top: 0;
    z-index: 3;
    background-color: var(--mud-palette-surface);
    padding: 4px 6px;
    white-space: nowrap;
    overflow: hidden;
    font-weight: 600;
}

/* Pinned first column — opaque so cells scroll under it, and above the ticket bars so they cannot spill over it.
   A soft right-side shadow lifts it over the scrolling grid so the frozen column reads as frozen; it sits on
   top of the crisp full-strength right border the general rule gives this column. */
.crew-availability-person-col[b-mekji5pi99] {
    position: sticky;
    left: 0;
    z-index: 4;
    width: var(--crew-name-width);
    background-color: var(--mud-palette-surface);
    text-align: left;
    padding: 4px 10px;
    box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.18);
}

/* The top-left corner is pinned on both axes, so it must sit above both. */
.crew-availability-table thead .crew-availability-person-col[b-mekji5pi99] {
    z-index: 6;
}

.crew-availability-name[b-mekji5pi99] {
    display: block;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.crew-availability-sub[b-mekji5pi99] {
    display: block;
    font-size: 0.7rem;
    color: var(--mud-palette-text-secondary);
}

/* No explicit width: under table-layout: fixed the day columns divide the space left by the name column
   equally, down to the table's min-width floor. */
.crew-availability-day-col[b-mekji5pi99] {
    text-align: center;
}

.crew-availability-dow[b-mekji5pi99] {
    display: block;
    font-size: 0.64rem;
    line-height: 1.2;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.crew-availability-dom[b-mekji5pi99] {
    display: block;
    font-size: 0.72rem;
    line-height: 1.2;
}

.crew-availability-cell[b-mekji5pi99] {
    position: relative; /* anchors the bars that overlay this and the following cells */
    /* height is set inline per row: it grows with the number of stacked bars (job lanes + on-call). */
    padding: 0;
}

/* The DT ticket bar — one stacked line, its vertical slot (top) set inline from its lane, spanning its days.
   Width is set inline from the span; it starts in the first day's cell and reaches across the rest. */
.crew-assignment-seg[b-mekji5pi99] {
    position: absolute;
    left: 2px;
    z-index: 1;
    height: 20px;
    line-height: 20px;
    padding: 0 3px;
    border-radius: 3px;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    cursor: pointer;
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A double-booked bar — more than one ticket on the same day. Red instead of the standard primary, so a
   scheduling collision on an already-saved job is unmistakable against the blue bars around it. */
.crew-assignment-seg.is-conflict[b-mekji5pi99] {
    /* Collision red — a literal hex so it shows a clickable swatch/picker in the editor. Darker than the
       MudBlazor error default; adjust to taste. */
    background-color: #d30000;
    color: #ffffff;
}

/* A bar's MudTooltip wrapper carries the bar's position and span (top and width set inline via RootStyle),
   so the tooltip anchors on the whole bar; the bar inside just fills it. ::deep because the wrapper is
   MudTooltip's own markup. Same stacking as the bars themselves: saved bars at 1, the preview above at 2. */
[b-mekji5pi99] .crew-bar-tip {
    position: absolute;
    left: 2px;
    z-index: 1;
    height: 20px;
}

[b-mekji5pi99] .crew-bar-tip.is-preview {
    z-index: 2;
}

.crew-assignment-seg.in-tip[b-mekji5pi99],
.crew-oncall-seg.in-tip[b-mekji5pi99],
.crew-preview-seg.in-tip[b-mekji5pi99] {
    position: static;
    display: block;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
}

.crew-oncall-seg.in-tip[b-mekji5pi99] {
    display: flex;
}

/* The warning glyph beside a double-booked technician's name. */
.crew-conflict-flag[b-mekji5pi99] {
    color: #d30000;
    margin-left: 4px;
    font-size: 0.8rem;
}

/* The on-call bar — one stacked line below the job lanes, its vertical slot (top) set inline. Standardized to
   the job bar's height and type (20px / 0.78rem) so it reads as the same bar family, not a thinner strip.
   Spans its weekend days by the same fixed-width calc. */
.crew-oncall-seg[b-mekji5pi99] {
    position: absolute;
    left: 2px;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: 20px;
    line-height: 20px;
    padding: 0 3px;
    border-radius: 3px;
    /* Amber with a fixed near-black text: distinct from the navy DT bar above and the green/red rotation
       fill, and legible — the theme's steel (tertiary) is documented as ~2.4:1, decorative only, but this
       strip carries real text and a clear action. Amber is the same in both palettes, so the text colour is
       pinned rather than a theme var that would invert to white and drop below the AA floor. */
    background-color: var(--mud-palette-warning);
    color: #212529;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
}

.crew-oncall-text[b-mekji5pi99] {
    overflow: hidden;
    text-overflow: ellipsis;
}

.crew-oncall-clear[b-mekji5pi99] {
    cursor: pointer;
    font-weight: 700;
    line-height: 1;
}

/* The on-call swatch in the legend. */
.crew-oncall-swatch[b-mekji5pi99] {
    display: inline-block;
    width: 14px;
    height: 10px;
    border-radius: 3px;
    background-color: var(--mud-palette-warning);
    margin-right: 4px;
    vertical-align: middle;
}

/* The unsaved-preview bar — same top slot and size as the DT bar, but a dashed, translucent ghost so it
   reads as provisional and any real bar beneath still shows through. Above the saved bar so it is never hidden. */
.crew-preview-seg[b-mekji5pi99] {
    position: absolute;
    left: 2px;
    z-index: 2;
    height: 20px;
    line-height: 18px;
    padding: 0 3px;
    border-radius: 3px;
    background-color: color-mix(
        in srgb,
        var(--mud-palette-primary) 24%,
        transparent
    );
    border: 1px dashed var(--mud-palette-primary);
    color: var(--mud-palette-text-primary);
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A preview bar that lands on an off-rotation or PTO day — the same dashed ghost, re-tinted to the error
   colour so the collision is visible before the schedule is saved. Text stays primary for legibility on the
   translucent fill. */
.crew-preview-seg.is-conflict[b-mekji5pi99] {
    background-color: rgba(183, 28, 28, 0.22);
    border-color: #b71c1c;
}

/* Name/position on the left, the manager actions menu pinned to the right of the sticky name cell. */
.crew-person-cell[b-mekji5pi99] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}

/* min-width:0 lets the name/position (block spans) take the remaining width and ellipsis-truncate instead of
   pushing the pinned menu out of the cell. */
.crew-person-id[b-mekji5pi99] {
    min-width: 0;
    overflow: hidden;
}

.crew-person-id .crew-availability-name[b-mekji5pi99],
.crew-person-id .crew-availability-sub[b-mekji5pi99] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The on-call / PTO actions menu — pinned right, never shrinking. */
.crew-row-actions[b-mekji5pi99] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

/* District band header — the top grouping level, above the crew bands, so a crew is not prefixed with its
   district on every row. Stronger than a crew band: a primary top rule and an uppercase accent label. */
.crew-availability-table tbody tr.crew-district-row th[b-mekji5pi99],
.crew-availability-table tbody tr.crew-district-row td[b-mekji5pi99] {
    background-color: var(--mud-palette-background-gray);
    border-top: 3px solid var(--mud-palette-primary);
}

.crew-district-label[b-mekji5pi99] {
    font-weight: 800;
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--mud-palette-primary);
    white-space: nowrap;
}

/* Crew band header — one row per rotation group, labelling the members beneath it. Indented so it reads as
   a sub-level of the district band above. */
.crew-availability-table tbody tr.crew-group-row th[b-mekji5pi99],
.crew-availability-table tbody tr.crew-group-row td[b-mekji5pi99] {
    background-color: var(--mud-palette-background-gray);
    border-top: 2px solid var(--mud-palette-lines-default);
}

.crew-group-label[b-mekji5pi99] {
    padding-left: 16px;
    white-space: nowrap;
}

.crew-group-name[b-mekji5pi99] {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.crew-group-cadence[b-mekji5pi99] {
    margin-left: 8px;
    font-size: 0.72rem;
    color: var(--mud-palette-text-secondary);
}

/* Today's column, highlighted top to bottom with the theme's primary accent. */
.crew-availability-table th.is-today[b-mekji5pi99] {
    color: var(--mud-palette-primary);
}

/* The vertical accents are drawn with an inset box-shadow, not border-left/right, on purpose: a border would
   consume 4px of the today cell's padding box, and the overlay bars size as a % of that box — so a bar starting
   on today would come up short by its span. box-shadow paints the same 2px lines without changing the box model,
   keeping every day column's padding box uniform so the bar math holds on any start column. */
.crew-availability-table th.is-today[b-mekji5pi99],
.crew-availability-table td.is-today[b-mekji5pi99] {
    box-shadow:
        inset 2px 0 0 0 var(--mud-palette-primary),
        inset -2px 0 0 0 var(--mud-palette-primary);
}

/* Row hover: tint the frozen name cell so the technician row under the pointer is easy to track across the
   wide day grid. Data rows only — the district and crew band headers are not hover targets. The day cells keep
   their availability colours; anchoring the row's identity cell is enough to guide the eye along it. */
.crew-availability-table tbody tr:not(.crew-district-row):not(.crew-group-row):hover .crew-availability-person-col[b-mekji5pi99] {
    background-color: var(--mud-palette-action-default-hover);
}

/* --- Unscheduled-jobs drawer ---
   A right-anchored panel that slides in over the calendar. Fixed so it spans the viewport height and
   stays put as the grid scrolls; translated off-screen when closed and animated in, so there is no
   layout shift and the grid keeps its full width. Colours come from the MudBlazor palette so it reads
   in both the light and the navy theme. */
.unscheduled-drawer[b-mekji5pi99] {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 430px;
    max-width: 92vw;
    z-index: 1300;
    display: flex;
    flex-direction: column;
    background-color: var(--mud-palette-surface);
    border-left: 1px solid var(--mud-palette-lines-default);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.18);
    transform: translateX(100%);
    transition: transform 0.2s ease;
    visibility: hidden;
}

.unscheduled-drawer.is-open[b-mekji5pi99] {
    transform: translateX(0);
    visibility: visible;
}

.unscheduled-drawer-header[b-mekji5pi99] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 12px 8px 12px 16px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.unscheduled-drawer-title[b-mekji5pi99] {
    font-weight: 600;
}

.unscheduled-drawer-body[b-mekji5pi99] {
    flex: 1 1 auto;
    /* min-height:0 lets this flex child shrink below its content height so overflow-y can scroll. Without
       it the default min-height:auto makes the body grow to fit an expanded card, pushing the date fields
       past the fixed drawer's bottom with no way to scroll to them. */
    min-height: 0;
    overflow-y: auto;
    padding: 12px 16px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.unscheduled-card[b-mekji5pi99] {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    background-color: var(--mud-palette-background);
    overflow: hidden;
    /* Keep each card at its natural height so the drawer body scrolls when it overflows, instead of flex-shrinking
       the cards (which, with overflow:hidden, would clip their text). */
    flex-shrink: 0;
}

/* The whole header is the collapse toggle — a chevron, then the DT/client title and the summary line. */
.unscheduled-card-head[b-mekji5pi99] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    cursor: pointer;
    user-select: none;
}

.unscheduled-card-head:hover[b-mekji5pi99] {
    background-color: var(--mud-palette-action-default-hover);
}

.unscheduled-card-headtext[b-mekji5pi99] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

/* The district tag rides on the right of the header, aligned with the title — a property of the job, not an edit. */
.unscheduled-card-district[b-mekji5pi99] {
    flex: 0 0 auto;
    align-self: center;
}

.unscheduled-card-titlerow[b-mekji5pi99] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.unscheduled-card-summary[b-mekji5pi99] {
    font-size: 0.78rem;
    color: var(--mud-palette-text-secondary);
}

.unscheduled-card-dt[b-mekji5pi99] {
    font-weight: 600;
}

.unscheduled-card-client[b-mekji5pi99] {
    color: var(--mud-palette-text-secondary);
    font-size: 0.85rem;
}

/* A small dot marking a collapsed card that holds unsaved edits, so pending work is visible without expanding. */
.unscheduled-dirty-dot[b-mekji5pi99] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--mud-palette-warning);
    flex: 0 0 auto;
    align-self: center;
}

.unscheduled-card-body[b-mekji5pi99] {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 0 12px 12px;
}

.unscheduled-chip[b-mekji5pi99] {
    font-size: 0.72rem;
    line-height: 1;
    padding: 4px 8px;
    border-radius: 999px;
    white-space: nowrap;
}

.chip-muted[b-mekji5pi99] {
    background-color: rgba(128, 128, 128, 0.16);
    color: var(--mud-palette-text-secondary);
}

/* Two pickers side by side, wrapping to stacked when the drawer is narrowed on a small screen. */
.unscheduled-card-dates[b-mekji5pi99] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.unscheduled-card-dates > *[b-mekji5pi99] {
    flex: 1 1 140px;
}

.unscheduled-card-actions[b-mekji5pi99] {
    display: flex;
    justify-content: flex-end;
}
/* /Components/Pages/HrCertifications/HrCertificationsIndex.razor.rz.scp.css */
/* Title on the left, status summary on the right. baseline alignment rather than centre so the
   counts sit on the title's own baseline instead of floating against a heading twice their height.
   flex-wrap so a narrow window drops the summary under the title rather than crushing either. */
.hr-header[b-eij1xghlzd] {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem 1.5rem;
}

/* Right-aligned on the title row. margin-left: auto rather than relying on
   space-between alone, so the summary stays right even after the row wraps and it is the only item
   on its line. */
.hr-status-summary[b-eij1xghlzd] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    /* The same 0.5rem the filter row uses, so the two sit on one rhythm. */
    gap: 0.5rem;
    margin-left: auto;
}

/* The four labels, restyled to read as the same kind of control as the page's small filter buttons
   rather than as chips.

   The numbers are measured off a real small MudButton rather than guessed: 6px radius,
   4px/10px padding, 13px at weight 600, 30.75px tall, 64px min-width. MudChip's own small-outlined
   defaults are 12px radius, 12px at weight 400 and 24px tall — visibly a different family of
   element, which is what made the summary read as a legend rather than as a control.

   Deliberately still a chip and a span, not MudButtons. These are read-only figures; a real button
   is focusable and announces itself as a button, so it would offer an interaction that does not
   exist. Matching the appearance is the ask, and it does not require borrowing the semantics.

   ::deep because the chips' root element belongs to MudChip and so never carries this component's
   scope attribute. The same rule reaches the plain span for the None entry, which does carry it —
   ::deep matches descendants either way, so one rule covers both.

   No border-color here on purpose: the outlined chip supplies its own, which is what keeps each
   status its colour. Only the shape and the type are being changed. */
.hr-status-summary[b-eij1xghlzd]  .hr-summary-label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 1.875rem;
    min-width: 4rem;
    padding: 0 0.625rem;
    /* MudChip ships its own 4px margin for chip sets, which stacked on top of the flex gap and put
       the entries 16px apart where the filter buttons are 8px — and 12px against the plain span,
       which has no margin of its own, so the row was unevenly spaced as well as too loose.
       Measured, not assumed: the computed gap read 8px on both rows while the rendered distance
       did not. Zeroing it hands spacing entirely to the container's gap. */
    margin: 0;
    border-width: 1px;
    border-style: solid;
    border-radius: 6px;
    font-size: 0.8125rem;
    font-weight: 600;
    /* The count now sits inside the label, so the digits are part of this box's width. tabular-nums
       keeps that width steady as the figures change with the business unit filter, instead of the
       whole row reflowing on every click. */
    font-variant-numeric: tabular-nums;
    /* "3 Expiring Soon" is wide enough to break inside its own border once the row is tight, which
       reads as two stacked fragments rather than one control. Let the row wrap between labels
       instead — the summary already wraps as a flex container. */
    white-space: nowrap;
}

/* The gap entry has no status and therefore no status colour, so it takes the neutral line and
   secondary text tokens. Bordered like the three beside it — that is what puts it in the row as an
   equal instead of leaving it as loose text — but uncoloured, because an absence of records is not
   a verdict. No italic: inside a bordered control it reads as a typo rather than as emphasis. */
.hr-status-summary[b-eij1xghlzd]  .hr-summary-none {
    border-color: var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
}

/* The filter chips on the left, the admin's test reminder and the column chooser on the right; every other
   field filters on its column header. */
.hr-filters[b-eij1xghlzd] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-bottom: 12px;
}

/* Pushes the test reminder and the column chooser to the far right of the filter row. */
.hr-filters-end[b-eij1xghlzd] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

/* Fills the height left over below the title and filter row rather than taking a fixed
   one: AuthenticatedLayout's .page-body is already a definite-height flex column, and its own
   stylesheet says a page may stretch to the fold with flex: 1 of its own.

   min-height: 0 is what makes the growth safe. A flex child defaults to min-height: auto, so the
   block would refuse to shrink below its content and a full table would push the page instead of
   scrolling inside the grid. min-width: 0 for the same reason horizontally — ColumnResizeMode
   .Container writes an intrinsic width inside. */
.hr-grid-block[b-eij1xghlzd] {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
}

/* Sits in the grid's own toolbar, which supplies the padding, so this only lays the two pieces out
   on one baseline. */
.hr-grid-title[b-eij1xghlzd] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}

.hr-grid-heading[b-eij1xghlzd] {
    font-size: 1.125rem;
    font-weight: 700;
}

/* The row count, set back from the heading. */
.hr-grid-count[b-eij1xghlzd] {
    font-size: 1rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

/* Deliberately not a chip and deliberately not red — an absence of records is not a compliance
   verdict. Italic and set back so it reads as "nothing here" rather than as a status. */
.hr-no-certs[b-eij1xghlzd] {
    font-style: italic;
    color: var(--mud-palette-text-secondary);
}



/* The date under the course name in Next to Expire — secondary, since the column sorts on it but the
   course is what you read first. */
.hr-next-expiry-date[b-eij1xghlzd] {
    display: block;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* The Status column's tags, wrapping as a group without MudChip's outer margin doubling the gap. */
.hr-status-tags[b-eij1xghlzd] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.hr-status-tags[b-eij1xghlzd]  .mud-chip {
    margin: 0;
}


/* Expanded rows — the "inset panel": the expanded person's row and its course panel share a pale tint of
   the theme's navy and a navy rule down the left, so the pair reads as one unit apart from the rows around
   it; the certification sections sit inside. Colours derive from --mud-palette-primary so they follow the
   theme. ::deep throughout: the rows and cells are MudDataGrid's own markup. */
.hr-grid-block[b-eij1xghlzd] {
    --hr-expanded-tint: color-mix(in srgb, var(--mud-palette-primary) 5%, var(--mud-palette-surface));
    --hr-expanded-line: color-mix(in srgb, var(--mud-palette-primary) 16%, var(--mud-palette-surface));
}

/* The parent: the row directly followed by a child-content row. */
[b-eij1xghlzd] tr.mud-table-row:has(+ tr > td.mud-table-child-content) > td {
    background: var(--hr-expanded-tint);
}

[b-eij1xghlzd] tr.mud-table-row:has(+ tr > td.mud-table-child-content) > td:first-child {
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}

[b-eij1xghlzd] tr.mud-table-row:has(+ tr > td.mud-table-child-content) a {
    font-weight: 700;
}

/* The panel the person's certification sections sit in, continuing the parent's tint and rule. */
[b-eij1xghlzd] td.mud-table-child-content {
    background: var(--hr-expanded-tint);
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
    padding: 0.25rem 1rem 0.875rem 2.75rem;
    border-bottom: 1px solid var(--hr-expanded-line);
}

/* The expanded certifications take the row's width without adding to it: width 0 keeps their wide course
   tables out of the roster table's sizing, and min-width 100% lets them fill the row. Without it, one open row
   widened every column and pushed Coverage off-screen. */
.hr-child-sections[b-eij1xghlzd] {
    width: 0;
    min-width: 100%;
}
/* /Components/Pages/HrCertifications/PersonDetail.razor.rz.scp.css */
/* The name and its state badge, grouped as the left side of the shared eb-detail-header-row (which lays
   out title-left / actions-right). Centred so the Inactive chip sits level with the name. */
.person-detail-title[b-mb5uc14uas] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* Two cards, so two columns rather than the shared four: Employment's group chips and a long email need
   the width. Stacks on a phone, where the shared grid goes to one column too. */
.person-detail-groups[b-mb5uc14uas] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 767px) {
    .person-detail-groups[b-mb5uc14uas] {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The Certifications heading with its filter chips beside it, above the section panels. */
.person-detail-certs-header[b-mb5uc14uas] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

/* The Cogniform sign-in email under App Access, shown only when it differs from the work email. */
.person-detail-app-email[b-mb5uc14uas] {
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/Index.razor.rz.scp.css */
/* Top-align the hero within the full-height .main-content (which centers its child): centering
   left a large empty band above the logo. align-self:flex-start overrides .main-content's
   align-items:center; margin:0 auto keeps it horizontally centered. A modest top padding gives it
   a little breathing room below the content control row without the old wasted space. */
[b-x322wzfnr4] .welcome-gridlayout {
    margin: 0 auto;
    align-self: flex-start;
    width: auto;
    height: auto;
    padding-top: 1.5rem;
    padding-bottom: 2rem;
}

[b-x322wzfnr4] .welcome-gridlayout {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3rem;
}

/* welcome-gridlayout is a centred flex column, so the block centres itself; the cap is
   what matters. The stacked lockup is 700px at source; kept small (180px) so the hero doesn't
   dominate the viewport and the navigation cards stay above the fold on a laptop without scrolling. */
[b-x322wzfnr4] .welcome-logo img {
    max-width: 325px;
    width: 100%;
    height: auto;
}

[b-x322wzfnr4] .title {
    text-align: center;
}

[b-x322wzfnr4] .title-header-text {
    font-size: 2.25rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

[b-x322wzfnr4] .title-content-text {
    font-size: 1.25rem;
    /* Semantic token, not the raw --bs-gray-600 (#a1a1a1): that scale names a hue and sat at
       2.6:1 on white, under the 4.5:1 AA floor — and tinting the page field pushed it lower. */
    color: var(--mud-palette-text-secondary);
    /* No margin-bottom: the layout's own 3rem gap sets title→cards spacing. The extra 2rem here
       stacked on top of that gap, leaving ~5rem (~an inch) below the title. */
}

[b-x322wzfnr4] .welcome-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    justify-content: center;
}

/* Responsive adjustments
   Cards keep their default width down to phone size; the old intermediate 992px
   step (width: 18rem) was dropped so tablets show full-size cards like desktop. */
@media (max-width: 768px) {
    [b-x322wzfnr4] .welcome-card {
        width: 100%;          /* Stretch to the row on phones... */
        max-width: 25rem;     /* ...but cap so a single card doesn't get oversized. */
    }
}

.checklist-section[b-x322wzfnr4] {
    margin-bottom: 2rem;
    padding: 1rem;
    background-color: #f8f9fa;
    border-radius: 4px;
}

.checklist-section h3[b-x322wzfnr4] {
    margin-bottom: 1rem;
    color: #495057;
}

.checklist[b-x322wzfnr4] {
    list-style-type: none;
    padding-left: 0;
    margin: 0;
}

.checklist li[b-x322wzfnr4] {
    padding: 0.5rem 0;
    color: #212529;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.checklist li input[type="checkbox"][b-x322wzfnr4] {
    width: 1.2rem;
    height: 1.2rem;
    margin: 0;
    cursor: not-allowed;
}

.checklist li span[b-x322wzfnr4] {
    flex: 1;
}

.checklist li.completed[b-x322wzfnr4] {
    color: #6c757d;
}

.checklist li.completed span[b-x322wzfnr4] {
    text-decoration: line-through;
}
/* /Components/Pages/JobManagement/ClientJobHistory.razor.rz.scp.css */
/* Secondary text colour rather than a --bs-gray-* grey, for the AA-contrast reason
   JobEntry.razor.css's .job-entry-intro gives. */
.client-job-history-intro[b-aewy1vg20k],
.client-job-history-empty[b-aewy1vg20k] {
    color: var(--mud-palette-text-secondary);
    margin-bottom: 0.75rem;
}

/* The table keeps its columns and scrolls sideways on a narrow screen, rather than the page. */
.client-job-history-scroll[b-aewy1vg20k] {
    overflow-x: auto;
}

.client-job-history-toggle[b-aewy1vg20k] {
    width: 2.5rem;
}

.client-job-history-nowrap[b-aewy1vg20k] {
    white-space: nowrap;
}

/* The second line in a cell — start/finish under the date, county/state under the lease. */
.client-job-history-secondary[b-aewy1vg20k] {
    color: var(--mud-palette-text-secondary);
    font-size: 0.8125rem;
}

/* The expanded strings sit on a faint tint so they read as belonging to the row above. */
.client-job-history-lines > td[b-aewy1vg20k] {
    background-color: var(--mud-palette-background-gray);
}

.client-job-history-action[b-aewy1vg20k] {
    text-align: right;
    white-space: nowrap;
}

/* Sits under the rig and well text, so it is tucked in rather than padded like a free button. */
[b-aewy1vg20k] .client-job-history-use-rig {
    padding: 0 0.25rem;
    min-width: 0;
}

.client-job-history-lines-head[b-aewy1vg20k] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.25rem;
}
/* /Components/Pages/JobManagement/JobDetail.razor.rz.scp.css */
/* Label column sized to its content, value column taking the rest. Left-aligned values, unlike
   MSA Pricing's billing list: these are mostly names and grades, and right-aligning text against
   a ragged left edge is harder to scan than the figures a summary column holds. The Invoice card is
   its own component, so these rules reach into it through ::deep on its host. */
.job-detail-list[b-nb5sqsddhu],
.job-invoice-host[b-nb5sqsddhu]  .job-detail-list {
    display: grid;
    grid-template-columns: minmax(7rem, auto) 1fr;
    gap: 0.5rem 1.5rem;
    margin: 0;
}

.job-detail-list dt[b-nb5sqsddhu],
.job-invoice-host[b-nb5sqsddhu]  .job-detail-list dt {
    color: var(--mud-palette-text-secondary);
    font-weight: 400;
}

.job-detail-list dd[b-nb5sqsddhu],
.job-invoice-host[b-nb5sqsddhu]  .job-detail-list dd {
    margin: 0;
}

/* Only the numeric fields. tabular-nums keeps digits on a common width so figures in adjacent rows
   line up by place value. */
.job-detail-figure[b-nb5sqsddhu],
.job-invoice-host[b-nb5sqsddhu]  .job-detail-figure {
    font-variant-numeric: tabular-nums;
}

/* The estimate and the icon that opens its request stay on one line in the narrow Billing column. */
.job-detail-sales-estimate[b-nb5sqsddhu] {
    display: flex;
    align-items: center;
    white-space: nowrap;
}

/* The one figure on the page worth emphasis — it is what the board sums and what the summary strip
   reports. Weight rather than colour, so it carries in both themes without a contrast check. */
.job-detail-grand-total[b-nb5sqsddhu],
.job-invoice-host[b-nb5sqsddhu]  .job-detail-grand-total {
    font-weight: 700;
}

/* The free-text fields. pre-line preserves the line breaks a dated running log was typed with —
   reflowing it into a paragraph would run separate days together — while still collapsing the runs
   of spaces that pasted boilerplate arrives with. overflow-wrap so an unbroken token (a long URL in
   a note) cannot push the card wider than its grid column. */
.job-detail-longtext[b-nb5sqsddhu] {
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* A flex column capped in height, so a long grid scrolls under its FixedHeader inside the cap while a
   short one takes only the height of its rows — a fixed height left a few-row grid sitting over a
   block of empty space. */
.job-detail-activity-block[b-nb5sqsddhu] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    max-height: 22rem;
    margin-bottom: 1.5rem;
}

/* Shortage-row styling. ::deep because MudDataGrid renders the row and cell elements outside this
   component's CSS-isolation scope; the wrapper div carries the scope. */
.job-detail-activity-block[b-nb5sqsddhu]  tr.job-detail-equipment-short {
    background-color: var(--mud-palette-error-hover);
}

.job-detail-activity-block[b-nb5sqsddhu]  .job-detail-equipment-short-label {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    /* The error color itself, not error-text: error-text is the contrast color for text on an
       error-filled background (white), which vanishes on the shortage row's light tint. */
    color: var(--mud-palette-error);
    font-weight: 600;
}

/* The close-out card's wrapper, a cell of the Billing tab's split. */
.job-detail-signoffs[b-nb5sqsddhu] {
    min-width: 0;
}

/* Checkbox and attribution on one line, wrapping on a narrow screen rather than letting the name
   and timestamp push the card wider than its column. */
.job-detail-signoff[b-nb5sqsddhu] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* Secondary to the label beside it: who signed off matters when it is asked about, not while the
   page is being scanned. */
.job-detail-signoff-by[b-nb5sqsddhu] {
    color: var(--mud-palette-text-secondary);
    font-size: 0.8125rem;
}

.job-detail-cell-text[b-nb5sqsddhu] {
    max-width: 22rem;
    white-space: normal;
    overflow-wrap: anywhere;
}

.job-detail-cell-when[b-nb5sqsddhu] {
    white-space: nowrap;
}

.job-detail-history-change[b-nb5sqsddhu] {
    font-weight: 500;
}

/* The second line of a cell: who made a change or uploaded a document, or where on the job a change was made. */
.job-detail-cell-secondary[b-nb5sqsddhu] {
    color: var(--mud-palette-text-secondary);
    font-size: 0.75rem;
}

/* A column of the split holding more than one card or grid. */
.job-detail-stack[b-nb5sqsddhu] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

.job-detail-stack .job-detail-activity-block[b-nb5sqsddhu] {
    margin-bottom: 0;
}

/* The close-out checklist under the sign-offs. */
.job-detail-checks[b-nb5sqsddhu] {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.job-detail-check[b-nb5sqsddhu] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 2rem;
}

.job-detail-check-unmet[b-nb5sqsddhu] {
    font-weight: 600;
}

/* The link to the tab where an unmet check is fixed, at the end of its line. */
.job-detail-check[b-nb5sqsddhu]  .job-detail-check-go {
    margin-left: auto;
}
/* /Components/Pages/JobManagement/JobEntry.razor.rz.scp.css */
/* Semantic token rather than a raw grey: the --bs-gray-* scale sits under the 4.5:1 AA floor
   against the tinted page field. See Index.razor.css. */
.job-entry-intro[b-w3dv77q7p5] {
    color: var(--mud-palette-text-secondary);
    margin: 0 0 1rem;
}

/* The validation summary. ::deep because ValidationSummary renders its own ul/li, which Blazor
   never stamps with this component's scope attribute.

   Styled on the list rather than the wrapper div, which is what keeps a clean form from showing an
   empty red box: ValidationSummary emits no list at all until there is something to report, so the
   border and padding only exist when they have content. */
.job-entry-validation[b-w3dv77q7p5]  .validation-errors {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--mud-palette-error);
    border-radius: 4px;
    background-color: var(--mud-palette-error-hover);
}

.job-entry-validation[b-w3dv77q7p5]  .validation-message {
    /* The error colour itself, not error-text: error-text is the contrast colour for text sitting ON a
       solid error fill (white), which is illegible on the light error-hover background this banner uses. */
    color: var(--mud-palette-error);
}

/* Four columns, as the Details view uses, so a field is edited in the position it was read. Each
   column takes an equal share as a column of its own rather than a fixed quarter, so when every card
   in one is hidden the rest widen to fill the page instead of leaving a gap at its right.
   align-items:start rather than the grid default of stretch: stretch made every card in a row as
   tall as the tallest, padding Scheduling out to match Location and Well. */
.job-entry-groups[b-w3dv77q7p5] {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: start;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

/* A column is a stack, so cards inside it are content-height too. */
.job-entry-column[b-w3dv77q7p5] {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    min-width: 0;
}

/* .job-entry-group is a flex wrapper so its card can fill a stretched cell. Inside a column there
   is nothing to fill, and leaving it would re-stretch what the column just stopped stretching. */
.job-entry-column .job-entry-group[b-w3dv77q7p5] {
    display: block;
}

/* Narrower, the columns wrap into fixed tracks again, so flow goes back to rows. */
@media (max-width: 1279px) {
    .job-entry-groups[b-w3dv77q7p5] {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .job-entry-groups[b-w3dv77q7p5] {
        grid-auto-flow: row;
        grid-template-columns: minmax(0, 1fr);
    }
}

.job-entry-group[b-w3dv77q7p5] {
    min-width: 0;
    display: flex;
}

/* The grid stretches the wrapper; this passes that width to the card inside it. ::deep because
   MudCard renders its own root element. */
.job-entry-group[b-w3dv77q7p5]  .mud-card {
    width: 100%;
}

/* A Crew Members option: the name, its certification flag, then the availability badge pushed to the right
   edge (CrewAvailabilityBadge's own margin-left: auto), as the Crew Scheduling picker lays a member out. */
.job-entry-crew-option[b-w3dv77q7p5] {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-width: 0;
}

/* A date picker and a time picker that together make one DateTime, laid on a single row so the pair
   is nearly as compact as one field. ::deep on the children because MudDatePicker/MudTimePicker each
   render their own root element, which the component's scope attribute never lands on. */
.job-entry-datetime[b-w3dv77q7p5] {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
}

.job-entry-datetime[b-w3dv77q7p5]  > * {
    flex: 1 1 0;
    min-width: 0;
}

/* The foot-level cards are bare siblings outside .job-entry-groups, so neither the grid's gap nor a
   column's supplies the space between them — .job-entry-groups' own margin-bottom only separates the
   grid from the first of them. A modifier rather than a `+` sibling rule, because .job-entry-group
   elements are also adjacent inside .job-entry-column, where the flex gap already spaces them and a
   margin would double it. */
.job-entry-group-foot[b-w3dv77q7p5] {
    margin-top: 1.5rem;
}

/* The note under the Client picker that the client has completed jobs further down.
   The info colour and an icon, rather than an alert box, so it reads as a pointer beside the field
   and not as a problem with it. */
.job-entry-history-note[b-w3dv77q7p5] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    color: var(--mud-palette-info-darken);
    font-size: 0.875rem;
}

.job-entry-history-note a[b-w3dv77q7p5] {
    font-weight: 600;
    margin-left: 0.25rem;
}

/* Spans whatever column count auto-fit settled on. 1 / -1 rather than a number, precisely because
   that count is not known here. Notes holds multi-line inputs, which want the full width. */
.job-entry-group-wide[b-w3dv77q7p5] {
    grid-column: 1 / -1;
}

/* Save on the right, cancel beside it — the destructive-ish action furthest from the pointer's
   resting place after filling the last field. Sticky so the pair stays reachable on a form this
   tall without scrolling back down; the surface colour keeps the fields from showing through. */
.job-entry-actions[b-w3dv77q7p5] {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
    position: sticky;
    bottom: 0;
    padding: 0.75rem 0;
    background-color: var(--mud-palette-background);
}

/* The chosen customer's details, under the Client picker (FF-3157).

   Set back from the inputs around it on purpose: everything else in this card is something the user
   types onto the ticket, and this is the one block that belongs to another record and cannot be
   edited here. The left rule and the secondary text colour are what say "read, do not fill in"
   without needing a disabled input, which would look like a field that has stopped working.

   Secondary text colour rather than a grey from the --bs-gray-* scale, for the AA-contrast reason
   .job-entry-intro gives. */
.job-entry-client-detail[b-w3dv77q7p5] {
    border-left: 2px solid var(--mud-palette-lines-default);
    padding: 0.25rem 0 0.25rem 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* The heading that names where the values come from. Tighter than MudBlazor's overline default,
   which is spaced for a standalone label rather than a caption sitting on top of its own block. */
.job-entry-client-detail[b-w3dv77q7p5]  .mud-typography-overline {
    display: block;
    line-height: 1.4;
    color: var(--mud-palette-text-disabled);
}

/* Below this the cards stop being a row and stack. 768px matches JobDetail.razor.css and
   MsaPricingIndex.razor.css, so a normal laptop window never falls into the stacked layout. */
@media (max-width: 768px) {
    .job-entry-groups[b-w3dv77q7p5] {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* A column whose every card is hidden leaves the grid, so the columns left share its width. */
.job-entry-column:not(:has(> .job-entry-group:not(.d-none)))[b-w3dv77q7p5] {
    display: none;
}
/* /Components/Pages/JobManagement/JobFieldCard.razor.rz.scp.css */
.job-field-card[b-lfszqea8bd] {
    min-width: 0;
}

/* ::deep because MudCard renders these elements, which never carry this component's scope. */
.job-field-card[b-lfszqea8bd]  .mud-card {
    width: 100%;
}

.job-field-card[b-lfszqea8bd]  .mud-card-header {
    padding-bottom: 0.25rem;
}

.job-field-card[b-lfszqea8bd]  .mud-card-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
/* /Components/Pages/JobManagement/JobManagementIndex.razor.rz.scp.css */
/* --- Summary strip ---------------------------------------------------------------------------
   Count and value per status, then the grand total, as a row of ordinary-height buttons.

   This began as a CSS grid of tall stacked cards, which read well in isolation but took more of the
   page than the grid it summarises — on a laptop the strip and the filter row together pushed the
   first job row below the fold. A wrapping flex row of button-height controls says the same thing in
   one line each. */
.job-summary-strip[b-buppq4i6pv] {
    display: flex;
    flex-wrap: wrap;
    /* Right-aligned, under the Add Job button on the same edge. flex-end rather than a margin-left
       auto on the first card, so a wrapped strip keeps every row against the same edge instead of
       leaving the second row ragged. */
    justify-content: flex-end;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

/* The district picker sits at the strip's left end and pushes the cards to the right edge they
   already keep. A fixed width so the placeholder "All business units" never truncates, and
   flex: none so a wrapping strip does not squeeze it. ::deep because MudSelect renders its own root
   element. */
.job-summary-strip[b-buppq4i6pv]  .job-bu-filter {
    flex: none;
    width: 14rem;
    margin-right: auto;
}

/* Title on the left, primary action on the right, sharing one line. space-between rather than a
   margin-left auto on the button, so the pair stays correct if anything is ever added between them.
   align-items: center because the title is set much larger than the button — aligning on baselines
   would leave the button sitting oddly low against it. */
.job-board-header[b-buppq4i6pv] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

/* The header's two actions travel together, so space-between has two children to separate rather
   than three to spread. */
.job-board-header-actions[b-buppq4i6pv] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* The cards are <button> elements so they are focusable and keyboard-operable for free, which means
   the browser's button chrome has to be undone before the card styling reads. Font and text
   alignment are inherited rather than reset to the button defaults for the same reason.

   The three spans sit on one baseline-aligned row, so the control is a normal button tall. The
   status accent stays a left bar: it is the one part that has to survive at this size, and a
   background tint would put the label's contrast at the mercy of the hue. */
.job-summary-card[b-buppq4i6pv] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-left: 3px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    background-color: var(--mud-palette-surface);
    font: inherit;
    line-height: 1.5;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease;
}

.job-summary-card:hover[b-buppq4i6pv] {
    background-color: var(--mud-palette-action-default-hover);
}

/* Left to the browser rather than removed: these are the primary controls on the strip, and a
   custom ring would have to re-solve contrast in both themes for no gain. */
.job-summary-card:focus-visible[b-buppq4i6pv] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* The pressed state. A border and a tint rather than a filled background, so the numbers keep their
   contrast against the card instead of having to be re-checked against a saturated fill. Exactly
   one card carries this at a time — "All jobs" holds it when no status is selected. */
.job-summary-card-selected[b-buppq4i6pv] {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

/* Status accents, matching JobStatusChip's colour reasoning: grey for Upcoming (nothing to act on
   yet), info for work in flight, success for the good terminal state, error for the Tickets with
   Issues flag — the only thing needing attention. Colour is never the only carrier — each card
   prints its label as text. */
.job-summary-card-upcoming[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-text-disabled);
}

.job-summary-card-ongoing[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-info);
}

.job-summary-card-ready[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-success);
}

.job-summary-card-issues[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-error);
}

/* The archive. Muted rather than another accent hue: the four above it are states someone acts on,
   and a fifth competing colour would imply this one is too. It matches the Completed chip. */
.job-summary-card-completed[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-dark);
}

.job-summary-card-grand[b-buppq4i6pv] {
    border-left-color: var(--mud-palette-primary);
}

.job-summary-label[b-buppq4i6pv] {
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

/* The count leads: it is the number people read first off the ops boards. Sized up relative to the
   label rather than made large outright, so the control stays button-height. */
.job-summary-count[b-buppq4i6pv] {
    font-size: 1rem;
    font-weight: 700;
}

/* Tabular figures so the dollar amounts line up down a wrapped strip rather than jittering on digit
   width. */
.job-summary-total[b-buppq4i6pv] {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* --- Filters ---------------------------------------------------------------------------------
   Just the Job date range now — the field filters moved onto the grid columns. align-items:
   flex-start keeps a control that has grown a validation message from stretching its neighbours. */
.job-filters[b-buppq4i6pv] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

/* Narrower than the control's natural width and capped, so the date range stays compact rather than
   spanning the row. */
.job-filter-field[b-buppq4i6pv] {
    flex: 0 1 13rem;
    min-width: 10rem;
    max-width: 15rem;
}

/* MudBlazor's dense outlined input is still built for a form, not a filter bar. ::deep because the
   input element is rendered by MudSelect rather than by this component, so the isolation attribute
   lands on the wrapper the class is applied to and not on the control inside it. */
[b-buppq4i6pv] .job-filter-field .mud-input-slot {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
}

/* --- Grid ------------------------------------------------------------------------------------
   Fills the height left over below the title, intro, strip and filters, rather than taking a fixed
   height: AuthenticatedLayout's .page-body is already a definite-height flex column
   (flex: 1; min-height: 0; display: flex; flex-direction: column), so growing into it is what
   "as large as it can be" means here — and it needs no magic number that would drift as the header
   above it changes.

   min-height: 0 is what makes the growth safe. A flex child defaults to min-height: auto, so the
   block would refuse to shrink below its content and a full table would push the page instead of
   scrolling inside the grid — exactly the failure the fixed height was avoiding.

   min-width: 0 for the same reason horizontally: ColumnResizeMode.Container writes an intrinsic
   width inside, which an auto minimum would let push the page sideways. That matters more here than
   it did at six columns — with every column shown the grid is genuinely wider than the viewport and
   is meant to scroll inside itself. */
.job-grid-block[b-buppq4i6pv] {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
}

/* Shorter rows than the app-wide default. site.css pins .eb-mud-grid body rows to a fixed 72px,
   which suits a grid of a dozen wide rows but turns a twelve-job board into a page of scrolling —
   only seven rows fit a laptop viewport. Overridden here rather than in site.css because that
   height is load-bearing elsewhere: TimeCardsIndex virtualises on it with ItemSize="72", so
   changing the global value would desynchronise the scroll maths from the rendered rows.

   height: auto lets the padding decide, and the padding is what is actually being reduced. The
   ::deep prefix carries this component's scope attribute, which outranks site.css's unscoped
   selector without needing !important. */
[b-buppq4i6pv] .job-grid-compact tbody tr.mud-table-row,
[b-buppq4i6pv] .job-grid-compact tbody tr.mud-table-row td {
    height: auto;
}

[b-buppq4i6pv] .job-grid-compact .mud-table-body .mud-table-row .mud-table-cell {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* Sits in the grid's own toolbar, which supplies the padding, so this only lays the two pieces out
   on one baseline. */
.job-grid-title[b-buppq4i6pv] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}

.job-grid-heading[b-buppq4i6pv] {
    font-size: 1.125rem;
    font-weight: 700;
}

/* The row count, set back from the heading. Semantic token rather than a raw grey: the --bs-gray-*
   scale sits under the 4.5:1 AA floor against the tinted page field. See Index.razor.css. */
.job-grid-count[b-buppq4i6pv] {
    font-size: 1rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

/* Numeric columns. ::deep because MudBlazor renders the cell, so the isolation attribute lands on
   this component's wrapper rather than on the td the class is applied to. Tabular figures and right
   alignment together are what let a column of dollar amounts be compared by eye. */
[b-buppq4i6pv] .job-cell-figure {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
/* /Components/Pages/JobManagement/JobSummaryStrip.razor.rz.scp.css */
/* One bordered surface split into cells, rather than five cards: the figures are read as a row. */
.job-summary[b-wl8s8c9hle] {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 12px;
    margin-bottom: 1rem;
}

.job-summary-cell[b-wl8s8c9hle] {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    padding: 0.75rem 1rem;
    border-left: 1px solid var(--mud-palette-lines-default);
}

.job-summary-cell:first-child[b-wl8s8c9hle] {
    border-left: 0;
}

.job-summary-label[b-wl8s8c9hle],
.job-summary-detail[b-wl8s8c9hle] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

.job-summary-value[b-wl8s8c9hle] {
    font-size: 1rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* Darkened from the palette's own warning and success, which are too light for text on white. */
.job-summary-warning[b-wl8s8c9hle] {
    color: color-mix(in srgb, var(--mud-palette-warning) 55%, black);
}

.job-summary-done[b-wl8s8c9hle] {
    color: color-mix(in srgb, var(--mud-palette-success) 85%, black);
}

.job-summary-muted[b-wl8s8c9hle] {
    color: var(--mud-palette-text-secondary);
    font-weight: 400;
}

/* Two to a row on a narrow screen, each cell divided from the one above. */
@media (max-width: 767px) {
    .job-summary[b-wl8s8c9hle] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .job-summary-cell[b-wl8s8c9hle] {
        border-left: 0;
        border-top: 1px solid var(--mud-palette-lines-default);
    }

    .job-summary-cell:nth-child(-n + 2)[b-wl8s8c9hle] {
        border-top: 0;
    }

    .job-summary-cell:nth-child(even)[b-wl8s8c9hle] {
        border-left: 1px solid var(--mud-palette-lines-default);
    }
}
/* /Components/Pages/JobManagement/JobTemplatePickerDialog.razor.rz.scp.css */
/* The templates read as rows of text by default: MudBlazor gives a clickable list item a pointer
   cursor and a faint action tint on hover, but no boundary, so nothing says "these are the things
   you pick". Borrowing the grid's vocabulary makes them look chosen-from rather than read.

   ::deep throughout because MudList and MudListItem render their own elements. */

.template-picker[b-3g1vsv443h]  .mud-list-item {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    margin-bottom: 0.5rem;
}

.template-picker[b-3g1vsv443h]  .mud-list-item:last-child {
    margin-bottom: 0;
}

/* Gated on a real pointer, as MudBlazor's own row hover is: an ungated :hover sticks on a touch
   device after a tap, leaving a row that looks permanently hovered. */
@media (hover: hover) {
    .template-picker[b-3g1vsv443h]  .mud-list-item:hover {
        background-color: var(--mud-palette-table-hover);
        border-color: var(--mud-palette-primary);
    }
}

/* The same tint the grid gives a selected row, so "this one is chosen" means the same thing on both
   screens. Border as well as fill, because the fill alone is easy to miss against the dialog. */
.template-picker[b-3g1vsv443h]  .mud-list-item.mud-selected-item,
.template-picker[b-3g1vsv443h]  .mud-list-item.mud-selected-item:hover {
    background-color: rgba(var(--mud-palette-primary-rgb), 0.18);
    border-color: var(--mud-palette-primary);
}
/* /Components/Pages/JobManagement/LaborCrewPicker.razor.rz.scp.css */
.labor-crew-picker[b-7bfpvusi6f] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.labor-crew-member[b-7bfpvusi6f] {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* Someone who can't be ticked here (on another Labor line, or no personnel record) reads dimmed. */
.labor-crew-member.is-untaggable[b-7bfpvusi6f] {
    opacity: 0.6;
}

.labor-crew-note[b-7bfpvusi6f] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.labor-crew-empty[b-7bfpvusi6f] {
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/MsaPricing/MsaPricingIndex.razor.rz.scp.css */
.msa-intro[b-q3l2fua67t] {
    /* Semantic token rather than a raw grey: the --bs-gray-* scale sits under the 4.5:1 AA floor
       against the tinted page field. See Index.razor.css. */
    color: var(--mud-palette-text-secondary);
    margin: 0 0 1.5rem;
}

.msa-account-filters[b-q3l2fua67t] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

/* Grid on the left taking the free space, billing card fixed on the right.
   flex-start rather than stretch: the card is meant to end just below its button rather than being
   pulled down to match the grid's height. */
.msa-layout[b-q3l2fua67t] {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}

/* A bounded flex column for the grid. The height is what makes the grid's own Height="100%"
   resolve to a real pixel box, which is what MudBlazor's FixedHeader needs to stick inside — an
   unbounded parent leaves the header pinned to nothing and the rows push the page instead.
   min-width: 0 is load-bearing: a flex child defaults to min-width: auto, so a grid wider than the
   space available would refuse to shrink and push the billing card off the row. */
.msa-grid-block[b-q3l2fua67t] {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    height: 26rem;
}

/* The fixed right-hand column. This wrapper is a plain div in this component's markup, so the
   scoping attribute lands on it — unlike MudCard's own root element, which Blazor never scopes. */
.msa-billing-block[b-q3l2fua67t] {
    flex: 0 0 20rem;
    min-width: 0;
}

/* ::deep because this sits inside MudText, whose element this component does not render and
   therefore cannot target with a plain scoped selector. */
.msa-billing-block[b-q3l2fua67t]  .msa-billing-title {
    font-weight: 600;
}

/* Label left, figure right — a summary reads down the right-hand edge, so the values are the
   column that has to line up. */
.msa-billing-list[b-q3l2fua67t] {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.5rem 1rem;
    margin: 0;
}

.msa-billing-list dt[b-q3l2fua67t] {
    color: var(--mud-palette-text-secondary);
    font-weight: 400;
}

.msa-billing-list dd[b-q3l2fua67t] {
    margin: 0;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The total is set apart from the lines that produce it: a rule above, then larger and bolder. */
.msa-billing-total[b-q3l2fua67t] {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.msa-billing-total-label[b-q3l2fua67t] {
    font-size: 1.25rem;
    font-weight: 700;
}

.msa-billing-total-value[b-q3l2fua67t] {
    font-size: 1.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.msa-billing-action[b-q3l2fua67t] {
    margin-top: 1.25rem;
}

/* The account title sits in the grid's toolbar, which supplies its own padding — so this only
   needs to lay the three pieces out on one baseline. */
.msa-card-title[b-q3l2fua67t] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}

.msa-card-company[b-q3l2fua67t] {
    font-size: 1.125rem;
    font-weight: 700;
}

/* Lighter and unbolded against the company name, same AA-contrast reasoning as .msa-intro. */
.msa-card-meta[b-q3l2fua67t] {
    font-size: 1rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

.msa-card-separator[b-q3l2fua67t] {
    color: var(--mud-palette-text-secondary);
}

/* Only on genuinely narrow screens does the card stop being a sidebar and stack under the grid.
   768px rather than 900px so a normal laptop window never falls into the stacked layout. */
@media (max-width: 768px) {
    .msa-layout[b-q3l2fua67t] {
        flex-direction: column;
    }

    .msa-billing-block[b-q3l2fua67t] {
        flex: 1 1 auto;
    }
}
/* /Components/Pages/Personnel/AppAccessReviewPanel.razor.rz.scp.css */
/* Sits between the lifecycle filters and the roster grid. */
.app-access-review[b-0o1djpu2vc] {
    margin-bottom: 1rem;
}

.app-access-review-header[b-0o1djpu2vc] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.app-access-review-title[b-0o1djpu2vc] {
    font-weight: 600;
}

/* When the mirror was last refreshed, set back from the title. */
.app-access-review-checked[b-0o1djpu2vc] {
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/Personnel/PersonnelImportDialog.razor.rz.scp.css */
/* The three counts on one line, wrapping on a narrow screen. */
.personnel-import-summary[b-c1ncs46oqw] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* A long list scrolls inside the dialog rather than pushing its buttons off screen. On a wrapper this component
   renders, so the scoped style reaches it without ::deep. */
.personnel-import-table[b-c1ncs46oqw] {
    max-height: 18rem;
    overflow-y: auto;
}

/* Short columns (line, employee number) stay on one line. */
.personnel-import-table[b-c1ncs46oqw]  th {
    white-space: nowrap;
}
/* /Components/Pages/Personnel/PersonnelIndex.razor.rz.scp.css */
/* The lifecycle scope row (Active / Inactive / All). Every other field filters on the grid's own column
   headers, so this is the only top filter. */
.personnel-filters[b-9buttlf2fg] {
    display: flex;
    align-items: flex-start;
    margin-bottom: 1rem;
}

.personnel-lifecycle-filters[b-9buttlf2fg] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-width: 0;
}

/* Fills the height left below the title and filters, so the grid scrolls inside its own port rather than
   pushing the page. min-height/min-width: 0 keep the growth safe inside the flex column. */
.personnel-grid-block[b-9buttlf2fg] {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
}

.personnel-grid-title[b-9buttlf2fg] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}

.personnel-grid-heading[b-9buttlf2fg] {
    font-size: 1.125rem;
    font-weight: 700;
}

/* The row count, set back from the heading. */
.personnel-grid-count[b-9buttlf2fg] {
    font-size: 1rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

/* A deactivated person, shown only under the Inactive/All filters. Dimmed so the row reads as present but
   retired — ::deep because the class lands on the grid's own <tr>. */
[b-9buttlf2fg] .personnel-row-inactive {
    opacity: 0.55;
}

/* A small, muted tag beside a deactivated person's name — a plain word, not a status chip. */
.personnel-inactive-tag[b-9buttlf2fg] {
    margin-left: 0.5rem;
    padding: 0.05rem 0.4rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--mud-palette-text-secondary);
    vertical-align: middle;
}
/* /Components/Pages/Reports/PurchaseSpendReport.razor.rz.scp.css */
/* Number columns line up by place value, as the value band's do. Cells are rendered by MudDataGrid, so ::deep. */
[b-fg51mhukns] .mud-table-cell.eb-number-col {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Their headers sit right too, with the sort control to the title's left, as the value band's headers do. */
[b-fg51mhukns] .mud-table-head .mud-table-cell.eb-number-col .mud-drop-zone,
[b-fg51mhukns] .mud-table-head .mud-table-cell.eb-number-col .mud-drop-item {
    width: 100%;
}

[b-fg51mhukns] .mud-table-head .mud-table-cell.eb-number-col .column-header {
    justify-content: flex-end;
}

[b-fg51mhukns] .mud-table-head .mud-table-cell.eb-number-col .column-options {
    order: -1;
}

/* The price spread: plain until it is wide, then tinted as a warning — the items worth renegotiating. */
[b-fg51mhukns] .spend-spread {
    font-variant-numeric: tabular-nums;
}

[b-fg51mhukns] .spend-spread--wide {
    padding: 1px 8px;
    border-radius: 10px;
    background-color: color-mix(in srgb, var(--mud-palette-warning) 18%, transparent);
    color: var(--mud-palette-warning-darken);
    font-weight: 600;
}

/* An expanded item's vendors: a quiet nested table, indented past the expander, figures right-aligned. */
[b-fg51mhukns] .spend-vendors {
    width: calc(100% - 3rem);
    margin: 0.25rem 0 0.75rem 3rem;
    border-collapse: collapse;
    font-size: 0.8125rem;
}

[b-fg51mhukns] .spend-vendors th {
    text-align: left;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
    padding: 0.375rem 0.5rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

[b-fg51mhukns] .spend-vendors td {
    padding: 0.375rem 0.5rem;
    border-bottom: 1px solid var(--mud-palette-table-lines);
}

[b-fg51mhukns] .spend-vendors .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

[b-fg51mhukns] .spend-vendors-date {
    margin-left: 0.5rem;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/Transfers/AddTransferAssetsDialog.razor.rz.scp.css */
/* A dialog has no page-body flex column to bound the grid, so this wrapper plays that part: the grid
   fills it at Height="100%" and scrolls under its pinned header once the stock outgrows it. */
.add-assets-grid[b-3fv1i7kd5g] {
    display: flex;
    flex-direction: column;
    height: min(360px, 50vh);
}
/* /Components/Shared/CardChooser.razor.rz.scp.css */
.card-chooser[b-xg8n1bnllz] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 1rem;
}
/* /Components/Shared/CardCollapseToggle.razor.rz.scp.css */
/* MudIconButton renders its own root, so the rotation is reached through ::deep from this span. */
.card-collapse-toggle[b-zs7hrn7a27]  .mud-icon-root {
    transition: transform 0.15s ease;
}

.card-collapse-toggle.collapsed[b-zs7hrn7a27]  .mud-icon-root {
    transform: rotate(-90deg);
}
/* /Components/Shared/CrewAvailabilityBadge.razor.rz.scp.css */
.crew-avail[b-a0dgat0wyq] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
}

.crew-avail-reason[b-a0dgat0wyq] {
    font-size: 0.68rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* /Components/Shared/CrewMemberPicker.razor.rz.scp.css */
/* Panel + lead stacked with the same rhythm the drawer card body used between its fields. */
.crew-member-picker[b-ok5erfjqsb] {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* The grouped crew picker — a bordered, collapsible panel of crew bands, each with a whole-crew checkbox. */
.crew-picker[b-ok5erfjqsb] {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
}

/* Clickable header that folds the panel away; Clear-all rides on its right so it costs no extra row. */
.crew-picker-header[b-ok5erfjqsb] {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    cursor: pointer;
    user-select: none;
}

.crew-picker-header:hover[b-ok5erfjqsb] {
    background-color: var(--mud-palette-action-default-hover);
}

.crew-picker-count[b-ok5erfjqsb] {
    font-size: 0.85rem;
    font-weight: 600;
}

/* Pushes Clear-all to the far end of the header row. */
.crew-picker-clear[b-ok5erfjqsb] {
    margin-left: auto;
    display: flex;
    align-items: center;
}

/* The scrollable body — capped so a long multi-district list never pushes anything below it out of reach, but
   tall enough to show a useful number of crew at once. */
.crew-picker-body[b-ok5erfjqsb] {
    max-height: 480px;
    overflow-y: auto;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.crew-picker-group[b-ok5erfjqsb] {
    padding: 4px 8px 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.crew-picker-group:last-child[b-ok5erfjqsb] {
    border-bottom: none;
}

/* Loaner bands (crews from another district) get a tinted strip so a borrow is obvious at a glance. */
.crew-picker-group.is-loaner[b-ok5erfjqsb] {
    background-color: var(--mud-palette-action-default-hover);
}

.crew-picker-group-head[b-ok5erfjqsb] {
    display: flex;
    align-items: center;
    gap: 6px;
}

.crew-picker-group-head .mud-checkbox[b-ok5erfjqsb] {
    font-weight: 600;
}

.crew-picker-loaner[b-ok5erfjqsb] {
    font-size: 0.66rem;
    padding: 2px 6px;
    border-radius: 999px;
    background-color: rgba(128, 128, 128, 0.18);
    color: var(--mud-palette-text-secondary);
}

/* The techs within a band, indented under the crew checkbox. */
.crew-picker-members[b-ok5erfjqsb] {
    display: flex;
    flex-direction: column;
    padding-left: 24px;
}

/* One tech row: the checkbox, then the availability badge/reason pushed to the right. */
.crew-picker-member[b-ok5erfjqsb] {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* A tech already committed for the selected dates reads dimmed — clearly flagged, but still selectable. */
.crew-picker-member.is-unavailable[b-ok5erfjqsb] {
    opacity: 0.6;
}

/* /Components/Shared/NavigationCard.razor.rz.scp.css */
.welcome-card[b-2495iz0qga] {
    width: 20rem;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.1),
        0px 2px 4px -2px rgba(0, 0, 0, 0.1);
    transition: all 0.3s ease;
    border-radius: 1rem;
    color: var(--bs-link-color);
    padding: 2rem;
    text-decoration: none;
    position: relative;
    background-color: var(--bs-white);
}

.welcome-card:hover[b-2495iz0qga] {
    box-shadow: 0px 20px 25px -5px rgba(0, 0, 0, 0.1),
        0px 8px 10px -6px rgba(0, 0, 0, 0.1);
    transform: translateY(-5px);
}

.welcome-card .welcome-card-icon[b-2495iz0qga] {
    width: 4rem;
    height: 4rem;
    margin-top: 0.75rem;
    margin-bottom: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.welcome-card .welcome-card-icon[b-2495iz0qga]  .mud-icon-root {
    width: 100%;
    height: 100%;
    font-size: 3rem;
}

.welcome-card-content[b-2495iz0qga] {
    text-align: center;
    z-index: 1;
}

.welcome-card .welcome-card-title[b-2495iz0qga] {
    font-size: 1.5rem;
    font-weight: 600;
    margin-bottom: 1rem;
    color: var(--bs-body-color);
}

.welcome-card .welcome-card-description[b-2495iz0qga] {
    font-size: 1rem;
    /* See .title-content-text: --bs-gray-600 is too light to read as body copy. */
    color: var(--mud-palette-text-secondary);
    margin-bottom: 0.5rem;
}

.welcome-card-link[b-2495iz0qga] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    text-decoration: none;
    color: inherit;
    position: relative;
    z-index: 1;
}

.welcome-card-action[b-2495iz0qga] {
    display: block;
    margin: 0.75rem;
    padding: 0.5rem 1rem;
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    text-align: center;
    border-radius: 0.5rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.2s, box-shadow 0.2s;
    box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.04);
    border: none;
    cursor: pointer;
    font-size: 1rem;
    position: relative;
    z-index: 2;
}

.welcome-card-action:hover[b-2495iz0qga] {
    background: var(--mud-palette-secondary);
    color: var(--mud-palette-secondary-text);
    text-decoration: none;
}

/* Cards keep their default width down to phone size; the old intermediate 992px
   step (width: 18rem) was dropped so tablets show full-size cards like desktop. */
@media (max-width: 768px) {
    .welcome-card[b-2495iz0qga] {
        width: 100%;          /* Stretch to the row on phones... */
        max-width: 25rem;     /* ...but cap so a single card doesn't get oversized. */
    }
}

/* A card whose destination does not exist yet. It keeps its place in the grid so a section reads
   as a complete inventory of what it will hold, while dropping the hover lift and the pointer
   that would promise a page to go to. The dashed edge is the cue that survives a greyscale
   screenshot; the badge is the one that survives not noticing the edge. */
.welcome-card--placeholder[b-2495iz0qga] {
    box-shadow: none;
    border: 1px dashed var(--mud-palette-lines-default);
    background-color: var(--mud-palette-background-gray);
}

/* Same specificity as .welcome-card:hover, so this only wins by sitting later in the file. */
.welcome-card--placeholder:hover[b-2495iz0qga] {
    box-shadow: none;
    transform: none;
}

.welcome-card--placeholder .welcome-card-link[b-2495iz0qga] {
    cursor: default;
}

.welcome-card--placeholder .welcome-card-icon[b-2495iz0qga],
.welcome-card--placeholder .welcome-card-title[b-2495iz0qga] {
    opacity: 0.55;
}

.welcome-card-badge[b-2495iz0qga] {
    display: inline-block;
    /* Pushed to the foot of the card: the link is a stretched flex column, so auto absorbs the
       slack left by a short description and every badge in a row lands on the same line. */
    margin-top: auto;
    padding: 0.15rem 0.6rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 1rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Shared/TubularSpecLinesEditor.razor.rz.scp.css */
/* Where a line came from, set just above its row. Secondary text colour for the AA-contrast reason
   JobEntry.razor.css's .job-entry-intro gives. ::deep because MudText renders the element. */
[b-04j4t74z2o] .tubular-spec-line-caption {
    display: block;
    color: var(--mud-palette-text-secondary);
    margin: 0.5rem 0 0.125rem;
}
