/* /Pages/AuditManager/AuditConduct.razor.rz.scp.css */
/*
    Audit conduct + findings scoped styles (SOL-289 / SOL-290). Fluent-not-Material: hairline borders,
    modest radius, no shadow. Repeated styling lives here, not as inline style= smells on the markup.
*/

/* ---- Checklist lines ---- */
.checklist-line[b-wxeeburzg8] {
    padding: 12px 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.checklist-line:last-child[b-wxeeburzg8] {
    border-bottom: none;
}

/* ---- Evidence sub-lists (checklist line + finding) ---- */
.evidence-block[b-wxeeburzg8] {
    padding-left: 10px;
    border-left: 2px solid var(--mud-palette-lines-default);
}

.evidence-row[b-wxeeburzg8] {
    padding: 3px 0;
    font-size: 0.8rem;
}

/* ---- Finding panels ---- */
.finding-panel[b-wxeeburzg8] {
    padding: 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    margin-bottom: 10px;
}

.finding-panel:last-child[b-wxeeburzg8] {
    margin-bottom: 0;
}

/* Attention accent: an open nonconformity with no verified-Effective CAPA, or a CAPA still in flight.
   A left border draws the eye without borrowing a conformant/green colour (false-assurance guard). */
.finding-panel--attention[b-wxeeburzg8] {
    border-left: 3px solid var(--mud-palette-warning);
}
/* /Pages/AuditManager/AuditFindingsList.razor.rz.scp.css */
/*
    Findings worklist scoped styles (SOL-319). Named classes rather than inline `style=` smells; nothing
    here encodes status meaning — all colour comes from AuditCoverageVisuals + the theme palette.
*/

.af-muted[b-q1pwtjr3dx] {
    opacity: 0.7;
}

.af-dash[b-q1pwtjr3dx] {
    opacity: 0.5;
}

.af-empty[b-q1pwtjr3dx] {
    opacity: 0.75;
}

/* Dense, spreadsheet-grade rows: the statement is the one free-text column, clamped to two lines with the
   full text available on hover/focus via the tooltip. */
.af-statement[b-q1pwtjr3dx] {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    max-width: 34rem;
    line-height: 1.25rem;
}

.af-audit-title[b-q1pwtjr3dx] {
    display: block;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The effectiveness chip sits under the CAPA link as a secondary line — tighten it so the cell stays dense. */
.af-chip-tight[b-q1pwtjr3dx] {
    margin: 0;
}
/* /Pages/AuditManager/AuditPlan.razor.rz.scp.css */
/*
    Audit planning page scoped styles (SOL-288). Fluent-not-Material: hairline borders, modest radius,
    no shadow. Repeated styling lives here, not as inline style= smells on the markup.
*/

/* ---- Read-only clause tree (criteria set transparency) ---- */
.clause-line[b-dibwkbo5ai] {
    padding: 3px 0;
    font-size: 0.82rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.clause-line:last-child[b-dibwkbo5ai] {
    border-bottom: none;
}

.clause-line--child[b-dibwkbo5ai] {
    padding-left: 18px;
    opacity: 0.8;
}

/* ---- Team roster rows ---- */
.team-member[b-dibwkbo5ai] {
    padding: 6px 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.team-member:last-child[b-dibwkbo5ai] {
    border-bottom: none;
}

/* ---- Refused-attempt evidence rows ---- */
.refused-row[b-dibwkbo5ai] {
    padding: 4px 0 4px 6px;
    border-left: 3px solid var(--mud-palette-error);
    margin-bottom: 4px;
}
/* /Pages/AuditManager/AuditProgramme.razor.rz.scp.css */
/*
    Audit program + coverage surface scoped styles (SOL-287). Fluent-not-Material: hairline borders,
    modest radius, no shadow. Repeated styling lives here, not as inline style= smells on the markup.
*/

/* ---- Programme list items (clickable, keyboard-selectable) ---- */
.programme-item[b-j05pt45glq] {
    padding: 8px 10px;
    border: 1px solid var(--mud-palette-lines-default);
    border-left: 3px solid transparent;
    border-radius: 2px;
    margin-bottom: 4px;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.programme-item:hover[b-j05pt45glq] {
    background-color: var(--mud-palette-action-default-hover);
}

.programme-item:focus-visible[b-j05pt45glq] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 1px;
}

.programme-item--selected[b-j05pt45glq] {
    border-left-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

/* ---- Coverage row: attention accent for a NOT-ASSESSED area (the TF-6 guard, never green) ---- */
.coverage-cell[b-j05pt45glq] {
    border-left: 3px solid transparent;
    padding-left: 6px;
}

.coverage-cell--attention[b-j05pt45glq] {
    /* Neutral "warning" hue — an amber attention accent, deliberately NOT a success/green cue. */
    border-left-color: var(--mud-palette-warning);
}

/* ---- Audit row (clickable, keyboard-selectable → navigates to the audit plan) ---- */
.audit-row[b-j05pt45glq] {
    cursor: pointer;
    outline-offset: 2px;
}

.audit-row:focus-visible[b-j05pt45glq] {
    outline: 2px solid var(--mud-palette-primary);
}
/* /Pages/AuditManager/AuditReportPage.razor.rz.scp.css */
/* Version-history rows — Fluent-dense: a hairline divider between rows, no shadow, no card-per-row. */
.report-version-row[b-4fp3odxe2z] {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.report-version-row:last-child[b-4fp3odxe2z] {
    border-bottom: none;
}
/* /Pages/AuditManager/EditAuditProgrammeDialog.razor.rz.scp.css */
/*
    Edit audit program header — scoped styles (SOL-324). Fluent-not-Material: hairline borders, modest
    radius, no shadow, muted secondary text. The repeated "this is fixed / not editable here" caption
    treatment lives here once rather than as an inline style= on each occurrence.

    Note the wrapping <div>: Blazor CSS isolation stamps its scope attribute onto plain HTML elements this
    component renders, not onto a child component's internal markup — so the class goes on a div and
    cascades into the MudText inside it.
*/

.audit-locked-note[b-6ivnoz3fe7] {
    color: var(--mud-palette-text-secondary);
}

/* Keep the inline info/lock icon optically aligned with the caption it prefixes. */
.audit-locked-note .mud-icon-root[b-6ivnoz3fe7] {
    vertical-align: text-bottom;
}
/* /Pages/AuditManager/RaiseAuditFindingDialog.razor.rz.scp.css */
/*
    Raise-finding dialog scoped styles (SOL-290). Fluent-not-Material: hairline, no shadow.
*/

.evidence-row[b-bg93j57257] {
    padding: 4px 0;
    font-size: 0.82rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.evidence-row:last-child[b-bg93j57257] {
    border-bottom: none;
}
/* /Pages/DMS/Admin/FileImports/AmbiguousLinkAuditSet.razor.rz.scp.css */
/*
    Ambiguous-link audit set (SOL-618 F7c) — surface styling.

    Layout and density only, like the page next door: colour comes from the MudTheme palette tokens and
    DmsVisuals, and there is not one hex value in this file by design.

    ⚠ The classes this component shares with DocumentFileImports.razor.css — cv-fileimport-lede,
    cv-fileimport-subtle, cv-fileimport-table, cv-fileimport-actions, cv-fileimport-pager,
    cv-fileimport-inline-icon — are SCOPED PER COMPONENT by Blazor's CSS isolation, so this file must carry
    its own copy of the ones it uses. That is duplication with intent: promoting them to app.css would make
    them globals with two owners, which is exactly the trade the parent's own header records.

    The rules below that are NOT in the parent are the verbatim-rendering ones, and they are the reason this
    file exists at all — cv-fileimport-verbatim is load-bearing evidence, not decoration.
*/

/* Secondary/explanatory copy. Muted through the theme's text-secondary token, never a literal grey. */
.cv-fileimport-lede[b-2oa1jvfs1z] {
    color: var(--mud-palette-text-secondary);
}

.cv-fileimport-subtle[b-2oa1jvfs1z] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Dense, spreadsheet-grade candidate tables — an operator compares two documents, they don't browse them.
   Wrapped in a scoped <div> so ::deep has a scoped ancestor: MudSimpleTable renders its own root, which
   never carries this component's scope attribute. */
.cv-fileimport-table[b-2oa1jvfs1z]  table {
    width: 100%;
}

.cv-fileimport-table[b-2oa1jvfs1z]  th {
    font-weight: 600;
    white-space: nowrap;
}

.cv-fileimport-table[b-2oa1jvfs1z]  td {
    vertical-align: middle;
}

.cv-fileimport-table[b-2oa1jvfs1z]  td.cv-fileimport-actions,
.cv-fileimport-table[b-2oa1jvfs1z]  th.cv-fileimport-actions {
    text-align: right;
    white-space: nowrap;
}

/* An icon sitting inline with text — nudged onto the text baseline, since MudIcon is a block-ish
   inline-flex by default and otherwise rides high. */
.cv-fileimport-inline-icon[b-2oa1jvfs1z] {
    vertical-align: text-bottom;
    margin-right: 0.15rem;
}

/* The pager. A thin strip under the list rather than a bordered block — chrome on a list, not a section. */
.cv-fileimport-pager[b-2oa1jvfs1z] {
    margin-top: 0.5rem;
}

/* ───────────────────── THE VERBATIM BOX — the one rule that carries meaning ─────────────────────

   The whole surface exists because two candidates share a normalized key, so the raw reference is
   frequently the only thing that separates them. Rendered as ordinary HTML text, `  QF-19 ` and `QF-19`
   are INDISTINGUISHABLE: the browser collapses runs of whitespace and drops it at the edges, so the
   discriminator disappears silently and the row still looks perfectly fine.

   Three properties fix that, and each is doing a job:
     • white-space: pre     — every space is rendered, including leading and trailing ones.
     • monospace            — 'l' vs '1' and 'O' vs '0' are separable, and the casing difference that is
                              usually the signal ("QF-19" against a key reading "qf-19") is legible.
     • a hairline border    — bounds the value, so whitespace at the edges has a visible EXTENT rather than
                              being an invisible gap the eye reads as layout padding.

   Depth from a border, not a fill or a shadow (Fluent, not Material), and the colour is the theme's own
   divider/surface token so the box follows the theme rather than pinning its own. */
.cv-fileimport-verbatim[b-2oa1jvfs1z] {
    display: inline-block;
    max-width: 100%;
    padding: 0.05rem 0.35rem;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 2px;
    background-color: var(--mud-palette-background-gray);
    font-family: var(--mud-typography-caption-family, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: 0.8125rem;
    white-space: pre;
    overflow-wrap: anywhere;
    vertical-align: middle;
}

/* The key block. A narrow fixed label column puts "Normalized key" and "Written as" on one axis, so the
   two values line up and a casing difference between them is read at a glance instead of hunted for. */
.cv-fileimport-ambig-keys[b-2oa1jvfs1z] {
    min-width: 0;
}

.cv-fileimport-ambig-line[b-2oa1jvfs1z] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}

.cv-fileimport-ambig-label[b-2oa1jvfs1z] {
    min-width: 8rem;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* A broken invariant — a missing mFILE, or a key whose candidates did not come through. The warning token,
   never colour alone: an icon sits beside it and the sentence itself says what is wrong. */
.cv-fileimport-ambig-alarm[b-2oa1jvfs1z] {
    color: var(--mud-palette-warning);
    font-size: 0.8125rem;
}

/* The blast-radius caption. Never wrapped mid-figure, and held off the key block so a long mFILE pushes it
   down rather than through it. */
.cv-fileimport-ambig-blast[b-2oa1jvfs1z] {
    white-space: nowrap;
    flex-shrink: 0;
}

/* A header that exists only for screen readers — the candidate "Open" column has an accessible name without
   printing a redundant word above a one-word link. */
.cv-fileimport-visually-hidden[b-2oa1jvfs1z] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
/* /Pages/DMS/Admin/FileImports/DocumentFileImports.razor.rz.scp.css */
/*
    Document File Import (SOL-618, F7a) — surface styling.

    Layout and density only. Colour comes from the MudTheme palette tokens and DmsVisuals; there is not a
    single hex value in this file by design, so the surface follows the theme rather than pinning its own.

    Tables are wrapped in a scoped <div> so ::deep has a scoped ancestor to hang off — MudSimpleTable and
    MudDataGrid each render their own root, which never carries this component's scope attribute.

    Same class vocabulary as the metadata-import surface next door (cv-import-*), renamed cv-fileimport-*
    rather than shared: the two are different pages with different scope attributes, so a shared class would
    have to move into app.css and become a global with two owners.
*/

/* Secondary/explanatory copy. Muted through the theme's text-secondary token, never a literal grey. */
.cv-fileimport-lede[b-879i3zzujv] {
    color: var(--mud-palette-text-secondary);
}

/* Secondary detail inside a table cell — a manifest name under a drop name, "Not in the drop" where a
   staged file would be. Smaller and muted so the cell reads as one value with a qualifier, not two values. */
.cv-fileimport-subtle[b-879i3zzujv] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Dense, spreadsheet-grade tables — an operator scans an import run, they don't browse it. */
.cv-fileimport-table[b-879i3zzujv]  table {
    width: 100%;
}

.cv-fileimport-table[b-879i3zzujv]  th {
    font-weight: 600;
    white-space: nowrap;
}

.cv-fileimport-table[b-879i3zzujv]  td {
    vertical-align: middle;
}

/* Numeric columns read as columns of figures: right-aligned, tabular so the digits line up. */
.cv-fileimport-table[b-879i3zzujv]  th.cv-fileimport-num,
.cv-fileimport-table[b-879i3zzujv]  td.cv-fileimport-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The row action column. Right-aligned and never wrapped, so the register button sits on one axis down the
   list instead of drifting with the width of the cell before it. */
.cv-fileimport-table[b-879i3zzujv]  td.cv-fileimport-actions {
    text-align: right;
    white-space: nowrap;
}

/* A drop whose manifest was refused. Offered rather than hidden — an empty list with a folder plainly
   sitting in the drop is the worse failure — but visibly not actionable. Dimmed through opacity rather than
   a grey token so the severity colour on its rejection line keeps its contrast. */
.cv-fileimport-row-muted[b-879i3zzujv]  td,
.cv-fileimport-table[b-879i3zzujv]  tr.cv-fileimport-row-muted td {
    opacity: 0.7;
}

/* Coverage lines ("Missing batches 3 and 7"). Icon and text on one baseline, wrapping as a unit so a long
   ordinal list never leaves an orphaned icon on its own line. */
.cv-fileimport-coverage[b-879i3zzujv] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

/* An icon sitting inline with caption text — nudged onto the text baseline, since MudIcon is a block-ish
   inline-flex by default and otherwise rides high. */
.cv-fileimport-inline-icon[b-879i3zzujv] {
    vertical-align: text-bottom;
    margin-right: 0.15rem;
}

/* Label/value summary: a fixed narrow label column keeps every value on one axis. */
.cv-fileimport-summary[b-879i3zzujv]  td:first-child {
    width: 12rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* The count inside a rollup chip. Tabular so a strip of chips reads as a column of figures rather than
   ragged text, and weighted so the number is separable from the code beside it. */
.cv-fileimport-rollup-count[b-879i3zzujv] {
    margin-left: 0.4rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Filter bars. Wrap rather than overflow — these surfaces are reachable on a narrow window, and a filter
   that scrolls off the edge is a filter nobody knows is applied. */
.cv-fileimport-filters[b-879i3zzujv] {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

/* Filter inputs are controls, not content: bounded so they read as a compact command strip instead of
   stretching to the container width the way a form field would. */
.cv-fileimport-filter-status[b-879i3zzujv],
.cv-fileimport-filter-severity[b-879i3zzujv] {
    max-width: 14rem;
}

.cv-fileimport-filter-search[b-879i3zzujv] {
    max-width: 22rem;
}

/* The run-list pager. Sits under the table as a thin strip rather than a bordered block — it is chrome on a
   list, not a section of its own. */
.cv-fileimport-pager[b-879i3zzujv] {
    margin-top: 0.5rem;
}

/* ───────────────────────── SOL-713 (F7b) ─────────────────────────
   Still not one hex value: the disagreement colour is the theme's warning token, the group rule is the
   theme's divider token. */

/* The canonical link host input. Bounded like the filter controls — it is a short, single-value field, and a
   full-width text box implies free-form prose where the server wants one hostname. */
.cv-fileimport-host[b-879i3zzujv] {
    max-width: 28rem;
}

/* The declared|observed split in the parts table. A hairline down the left of each group is what makes the
   two sides read as two SIDES rather than as seven peer columns — Fluent depth from a border, not a fill. */
.cv-fileimport-table[b-879i3zzujv]  th.cv-fileimport-group,
.cv-fileimport-table[b-879i3zzujv]  td.cv-fileimport-group {
    border-left: 1px solid var(--mud-palette-divider);
}

/* A figure that disagrees with its counterpart. Weight AND colour, and never colour alone — the row's own
   sentence underneath states the disagreement in words, which is what carries it for a screen reader and
   under bad lighting (§6.9 AA).

   --mud-palette-warning, NOT --mud-palette-warning-text: the latter is Mud's CONTRAST token (the colour used
   ON a warning-filled surface, near-white by default), so it would render this figure invisible on the
   table's own background. The same token the audit surfaces use for warning-tinted borders. */
.cv-fileimport-disagree[b-879i3zzujv] {
    color: var(--mud-palette-warning);
    font-weight: 600;
}

/* Load-outcome figures. A wrapping row of stat blocks rather than a table: these are six independent
   outcomes, not a series, and putting them in rows invites reading them as a running total. */
.cv-fileimport-outcome[b-879i3zzujv] {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem 2.5rem;
}

.cv-fileimport-stat[b-879i3zzujv] {
    display: flex;
    flex-direction: column;
    min-width: 8rem;
}

.cv-fileimport-stat-value[b-879i3zzujv] {
    font-size: 1.5rem;
    line-height: 1.2;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.cv-fileimport-stat-label[b-879i3zzujv] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}
/* /Pages/DMS/Admin/Imports/DocumentImports.razor.rz.scp.css */
/*
    Document Import (SOL-545) — surface styling.

    Layout and density only. Colour comes from the MudTheme palette tokens and DmsVisuals; there is not a
    single hex value in this file by design, so the surface follows the theme rather than pinning its own.

    The tables are wrapped in a scoped <div> so ::deep has a scoped ancestor to hang off — MudSimpleTable
    renders its own root, which never carries this component's scope attribute.
*/

/* Secondary/explanatory copy. Muted through the theme's text-secondary token, never a literal grey. */
.cv-import-lede[b-n6asriz2ex] {
    color: var(--mud-palette-text-secondary);
}

/* Dense, spreadsheet-grade tables — an operator scans an import report, they don't browse it. */
.cv-import-table[b-n6asriz2ex]  table {
    width: 100%;
}

.cv-import-table[b-n6asriz2ex]  th {
    font-weight: 600;
    white-space: nowrap;
}

.cv-import-table[b-n6asriz2ex]  td {
    vertical-align: middle;
}

/* Numeric columns read as columns of figures: right-aligned, tabular so the digits line up. */
.cv-import-table[b-n6asriz2ex]  th.cv-import-num,
.cv-import-table[b-n6asriz2ex]  td.cv-import-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Label/value summary: a fixed narrow label column keeps every value on one axis. */
.cv-import-summary[b-n6asriz2ex]  td:first-child {
    width: 12rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* Outcome counters — a compact strip, not a row of consumer stat cards. */
.cv-import-counters[b-n6asriz2ex] {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
}

.cv-import-counter[b-n6asriz2ex] {
    min-width: 7rem;
}

.cv-import-counter-value[b-n6asriz2ex] {
    font-size: 1.375rem;
    line-height: 1.7rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.cv-import-counter-label[b-n6asriz2ex] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* ── Findings report (SOL-601) ──────────────────────────────────────────────────────────────────────── */

/* The count inside a rollup chip. Tabular so a strip of chips reads as a column of figures rather than
   ragged text, and weighted so the number is separable from the code it sits beside. */
.cv-import-rollup-count[b-n6asriz2ex] {
    margin-left: 0.4rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Filter bar. Wraps rather than overflowing — the report is reachable on a narrow window and a filter
   that scrolls off the edge is a filter nobody knows is applied. */
.cv-import-filters[b-n6asriz2ex] {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

/* Filter inputs are controls, not content: bounded so they read as a compact command strip instead of
   stretching to the container width the way a form field would. */
.cv-import-filter-severity[b-n6asriz2ex] {
    max-width: 12rem;
}

.cv-import-filter-search[b-n6asriz2ex] {
    max-width: 22rem;
}

/* The "no placement" fold notice: message left, its one control right. Wraps rather than crushing the
   button, because the control is the whole point of the notice — a statement that rows are hidden with
   no visible way to open them would be worse than not folding at all. */
.cv-import-fold-notice[b-n6asriz2ex] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    width: 100%;
}

/* ── Default placement (SOL-603) ────────────────────────────────────────────────────────────────────── */

/* The picker is a form, not a data surface. Held narrow so the three selects stack as one readable column
   rather than spanning a large container, which would make a three-field decision look like a table. */
.cv-import-placement[b-n6asriz2ex] {
    max-width: 28rem;
}

/* Live region wrapper around the placement refusal alert (SOL-626). The refusal is an error STATE rather
   than helper text under a field — the server's message is deliberately node-agnostic, so it is announced
   as a block, not re-attached to the control as though a value were malformed. */
.cv-import-refusal[b-n6asriz2ex] {
    margin-top: 0.5rem;
}
/* /Pages/DMS/Admin/Settings/DmsSettings.razor.rz.scp.css */
/*
    DMS Settings — acknowledgment-audience picker styling (SOL-724).

    Density and layout only. Every colour is a MudTheme palette token; there is not one hex value in this
    file by design, so the surface follows the theme rather than pinning its own (Fluent, not Material).

    The rules here exist because the picker carries an EXPLANATION, not just a label: a withheld role's
    reason is a full sentence (the Auditor arm is three), and a Mud list item is built for one line of
    nowrap text. Without these it truncates — and a truncated reason is the same defect as a filtered-out
    role, just quieter.
*/

/* One option row. Wrapping is the load-bearing property: MudListItem's text slot is nowrap by default,
   which would clip the reason to "The 'Auditor' role does not hold…" and lose the control it explains. */
.cv-dms-ackrole[b-tgte1ech50] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    white-space: normal;
    padding: 0.15rem 0;
    min-width: 0;
}

/* The role name plus its inline meta — the thing being chosen, so it stays the strongest element in the
   row. Wraps rather than overflows: MudBlazor 9.1 renders this same fragment inside the closed field for
   the selected item, where a horizontal overflow would sit under the dropdown/clear adornments. */
.cv-dms-ackrole-name[b-tgte1ech50] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
    font-weight: 500;
    line-height: 1.4;
}

/* Inline meta after the role name — the audience size, or the zero-member hint. Muted through the
   theme's text-secondary token, never a literal grey, and separated by a middot rather than a chip so
   the row stays one line inside the field. */
.cv-dms-ackrole-meta[b-tgte1ech50] {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

.cv-dms-ackrole-meta[b-tgte1ech50]::before {
    content: "·";
    margin-right: 0.2rem;
}

/* An eligible role with nobody in it — the second zero-signer route. Warning token, and the icon plus the
   words carry it as well as the hue (never colour alone). */
.cv-dms-ackrole-meta--warn[b-tgte1ech50] {
    color: var(--mud-palette-warning);
}

/* The withheld reason. Muted, wrapped, and capped so a three-sentence explanation reads as a readable
   column rather than running the full width of the popover. Only ever on a disabled row. */
.cv-dms-ackrole-note[b-tgte1ech50] {
    display: flex;
    align-items: flex-start;
    gap: 0.3rem;
    max-width: 42rem;
    font-size: 0.75rem;
    line-height: 1.45;
    color: var(--mud-palette-text-secondary);
    white-space: normal;
}

/* The non-selectable group header above the withheld roles. Reads as a section label, not as an option:
   smaller, tracked out, and in the secondary text colour. */
.cv-dms-ackrole-group[b-tgte1ech50] {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    white-space: normal;
}

/* An icon sitting inline with text — nudged onto the text baseline, since MudIcon is inline-flex by
   default and otherwise rides high (same fix as the file-import surfaces). */
.cv-dms-ackrole-inline-icon[b-tgte1ech50] {
    flex-shrink: 0;
    vertical-align: text-bottom;
}

/* The footnote naming the capability the eligibility is computed from. */
.cv-dms-ackrole-footnote[b-tgte1ech50] {
    display: block;
    margin-top: 0.35rem;
    color: var(--mud-palette-text-secondary);
}

/* The permission tag itself, rendered verbatim: it is an exact identifier an admin may go and look up in
   the roles surface, so it gets a monospace face and a hairline bound rather than blending into prose. */
.cv-dms-ackrole-tag[b-tgte1ech50] {
    padding: 0.02rem 0.25rem;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 2px;
    background-color: var(--mud-palette-background-gray);
    font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace;
    white-space: nowrap;
}
/* /Pages/DMS/Compliance/ComplianceDashboard.razor.rz.scp.css */
/* Compliance dashboard — the summary tile row.

   Grid math: five tiles do not fit MudGrid's twelve columns. `md="2"` × 5 = 10/12, which left a dead
   gutter on the right while squeezing every tile narrower than it needed to be; `xs="6" sm="4"`
   orphaned the fifth card alone on the last row. A CSS grid states the intent directly and always
   fills the width:

     xs  (<600px)   2 tracks — tiles 1-4 pair up, tile 5 spans both (no lonely half-card)
     sm  (600-960)  3 tracks — tiles 1-3, then tile 4 + tile 5 spanning the remaining two tracks
     md+ (>=960px)  5 tracks — one exact row, no dead gutter

   `align-items: stretch` (the grid default, restated for intent) gives every tile in a row the same
   height; the tile's own bottom-pinned footer is what keeps the values on a shared baseline. */

.compliance-tiles[b-4cpkee88pt] {
    display: grid;
    gap: 0.75rem;
    align-items: stretch;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.compliance-tiles__cell[b-4cpkee88pt] {
    display: flex;
    min-width: 0;
}

.compliance-tiles__cell--fills-row[b-4cpkee88pt] {
    grid-column: span 2;
}

@media (min-width: 600px) {
    .compliance-tiles[b-4cpkee88pt] {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 960px) {
    .compliance-tiles[b-4cpkee88pt] {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .compliance-tiles__cell--fills-row[b-4cpkee88pt] {
        grid-column: auto;
    }
}
/* /Pages/DMS/Compliance/ComplianceMetricTile.razor.rz.scp.css */
/* ComplianceMetricTile — Fluent idiom: outlined hairline, no elevation, modest radius, dense padding.

   Every rule pierces with ::deep from the authored `.compliance-tile-host` wrapper: MudPaper/MudText
   render their own roots, which do NOT carry this component's CSS-isolation scope attribute, so a bare
   `.compliance-tile { ... }` rule here would compile to a selector that matches nothing.

   The tile is a flex COLUMN at full height so that (a) every tile in a row is the same height, (b) the
   label/value block sits at the top on a shared baseline across the row, and (c) the optional footer is
   pushed to the bottom edge instead of stretching the tile taller than its footer-less neighbours.
   Every colour is a palette token — no hexes, no inline styles. */

.compliance-tile-host[b-zjmfy6vnxo] {
    display: flex;
    height: 100%;
    /* Fill the grid cell the dashboard places us in, whatever its width. */
    flex: 1 1 auto;
    min-width: 0;
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    padding: 0.75rem 1rem;
    border-radius: var(--mud-default-borderradius);
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile__label {
    line-height: 1.2;
    /* A label that wraps must not push its value a line below the neighbouring tile's value. */
    min-height: 1.2em;
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile__figure {
    margin-top: 0.25rem;
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile__value {
    font-weight: 600;
    line-height: 1.1;
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile__suffix {
    line-height: 1.1;
}

.compliance-tile-host[b-zjmfy6vnxo]  .compliance-tile__footer {
    /* Pin to the bottom edge; this is what keeps footer-less tiles from collapsing shorter. */
    margin-top: auto;
    padding-top: 0.5rem;
    line-height: 1.2;
}
/* /Pages/DMS/Documents/DocumentDetail.razor.rz.scp.css */
/* DocumentDetail — scoped styling for the read hub (spec §5.2, SOL-566).

   Every rule here exists so the markup carries no inline `style=` attributes: the module's styling
   convention is tokens + a shared class, never a per-element style string. Values come from MudBlazor
   theme variables so the surface follows the Fluent palette rather than pinning its own. */

/* Command bar. Depth from a hairline rule, not a drop shadow — the bar is a boundary, not a floating card. */
.dms-detail-commandbar[b-h8auylemty] {
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* The title sits next to the (bolder) document number and must yield to it, and truncate rather than
   push the command buttons off the right edge on a narrow viewport. */
.dms-detail-title[b-h8auylemty] {
    opacity: 0.85;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Panels sit on a shared row and should agree on height so the grid reads as a strip, not a staircase. */
.dms-detail-panel[b-h8auylemty] {
    height: 100%;
}

/* Field labels — the quiet half of a label/value pair. */
.dms-detail-label[b-h8auylemty] {
    opacity: 0.6;
}

/* Identifiers that are meant to be read character-by-character (import batch id). */
.dms-detail-mono[b-h8auylemty] {
    font-family: var(--mud-typography-caption-family, monospace);
    word-break: break-all;
}

/* Revision change record (ISO 9001 §7.5.3). Up to 2000 characters against a dense grid cell, so the cell
   is width-capped and line-clamped with the full text on hover — the row is never the only copy of a
   controlled record. Same treatment the authoring surface's revision grid uses. */
.dms-detail-change[b-h8auylemty] {
    max-width: 22rem;
    min-width: 0;
}

.dms-detail-change > *[b-h8auylemty] {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Uploader stamp. Resolves to a name where the identity row could be read; where it could not, the id is
   retained (never a raw GUID passed off as a person) and clamped so it cannot stretch the column. */
.dms-detail-uploader[b-h8auylemty] {
    display: block;
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Permanent link (SOL-812) — the one deep-link control, sitting in the header's identifying-facts row.
   Borrowed geometry, not a new pattern: a hairline border and the theme's own (modest) radius, so it reads
   as a sibling of the outlined chips beside it rather than as a card that floats above them. */
.dms-detail-deeplink[b-h8auylemty] {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    padding-left: 0.5rem;
    min-width: 0;
    max-width: 100%;
}

/* The URL itself. Selectable text, never a control — the manual-selection route has to survive a browser
   that refuses the Clipboard API. Capped and ellipsised because a full canonical URL is long enough to push
   the rest of the header strip off a laptop viewport; the `title` attribute carries the untruncated value. */
.dms-detail-deeplink-url[b-h8auylemty] {
    max-width: 26rem;
    min-width: 0;
    margin-left: 0.375rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    opacity: 0.85;
}

/* Row-action column — sized to its icon button so it does not steal width from the change record. */
.dms-detail-actions-col[b-h8auylemty] {
    width: 3rem;
    text-align: right;
}
/* /Pages/DMS/Documents/DocumentLifecycleRail.razor.rz.scp.css */
/* DocumentLifecycleRail — scoped styling for the DMS lifecycle spine (spec §6, SOL-566).

   Scoped rather than inline: CapaLifecycleRail carries its node styling as inline `style=` attributes
   (`font-size:0.6rem`, hand-written opacities), which is the exact smell the DMS design-system work is
   moving away from. Everything below is expressed against MudBlazor theme tokens, so the rail follows
   the Fluent palette rather than pinning its own values. */

.dms-rail-lane[b-84m4594wzn] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* Lane label ("Document" / "Revision B") — fixed gutter so both tracks start on the same column and
   the two state machines read as parallel lanes rather than one long chain. */
.dms-rail-lane-label[b-84m4594wzn] {
    min-width: 7.5rem;
    opacity: 0.7;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dms-rail-track[b-84m4594wzn] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}

.dms-rail-cell[b-84m4594wzn] {
    display: flex;
    align-items: center;
}

.dms-rail-connector[b-84m4594wzn] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 46px;
}

.dms-rail-gate[b-84m4594wzn] {
    font-size: 0.62rem;
}

.dms-rail-node[b-84m4594wzn] {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 88px;
}

/* States a plain stepper would misrepresent. "Next" is simply not yet reached; "N/A" is a transition
   that does not exist for this record (Archived from Draft, or the approval tail of a rejected review) —
   struck through, so it never reads as an unfinished step someone forgot. */
.dms-rail-node--upcoming[b-84m4594wzn] {
    opacity: 0.7;
}

.dms-rail-node--na[b-84m4594wzn] {
    opacity: 0.45;
}

.dms-rail-node--na[b-84m4594wzn]  .mud-typography-caption {
    text-decoration: line-through;
}

.dms-rail-node-state[b-84m4594wzn] {
    font-size: 0.6rem;
}

.dms-rail-caption[b-84m4594wzn] {
    margin-top: 0.5rem;
    opacity: 0.85;
}
/* /Pages/DMS/Documents/ManageDocument.razor.rz.scp.css */
/* ManageDocument — scoped styling for the authoring surface.

   Kept here rather than in app.css because every rule below is specific to this page's revision
   grid; app.css already carries the cross-DMS `.dms-level-row`. Scoped CSS also keeps the
   Fluent-not-Material direction expressible in tokens instead of inline `style=` attributes. */

/* Tab strip (SOL-563). `dms-manage-tabs` was referenced by the markup but defined nowhere, so the
   class did nothing at all. Defined here rather than deleted: it is the hook that pulls the tab strip
   away from Material's airy default toward the denser Fluent/Office rhythm the rest of the app uses. */
.dms-manage-tabs[b-eqs25vj7a8] {
    margin-bottom: 0.5rem;
}

.dms-manage-tabs[b-eqs25vj7a8]  .mud-tabs-tabbar {
    min-height: 40px;
}

/* Sticky action bar (SOL-563). The markup called this bar "sticky" in a comment and referenced
   `dms-manage-action-bar`, but the class was never defined — so on a long authoring form (classification
   rows, tags, translations) Save scrolled off the bottom and the primary action of the page was simply
   not reachable without scrolling back. This makes the comment true.

   `bottom: 0` pins it to the viewport floor once the form is taller than the screen; the border and the
   surface background keep it legible over content scrolling underneath, and depth comes from a hairline
   border rather than a drop shadow. z-index sits above form fields but below MudBlazor's overlays
   (popovers/dialogs start at 1200+), so a date picker or a dialog still covers it correctly. */
.dms-manage-action-bar[b-eqs25vj7a8] {
    position: sticky;
    bottom: 0;
    z-index: 2;
    border: 1px solid var(--mud-palette-lines-default);
    background-color: var(--mud-palette-surface);
}

/* Revision change record (SOL-560). The change description is up to 2000 characters against a
   dense grid cell, so the cell is width-capped and line-clamped; the full text is always reachable
   via the cell's `title` (the row is never the only copy of a controlled record). */
.dms-revision-change[b-eqs25vj7a8] {
    max-width: 22rem;
    min-width: 0;
}

.dms-revision-change > *[b-eqs25vj7a8] {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Uploader stamp. `DocumentFileItem.CreatedBy` is the framework audit stamp — a user id, not a
   display name — so it is clamped to one line with the full value on hover rather than allowed to
   stretch the Uploaded column. Remove the clamp once the read resolves a name. */
.dms-revision-uploader[b-eqs25vj7a8] {
    display: block;
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Pages/Insights/AuditMetricTile.razor.rz.scp.css */
/* AuditMetricTile (SOL-292) — one headline figure. Fluent idiom: outlined hairline, no elevation,
   modest radius. A drill-through tile (.audit-tile--link, wrapped in .audit-tile-link) lifts to the
   primary edge on hover/focus rather than floating on a shadow; a static tile is inert. Every colour
   is a palette token — no hexes; the number's tone comes from AuditCoverageVisuals via the Accent
   parameter (never-green). */

.audit-tile-link[b-kvp3z72liy] {
    display: block;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.audit-tile[b-kvp3z72liy] {
    height: 100%;
    padding: 0.75rem 1rem;
    border-radius: var(--mud-default-borderradius);
    transition: border-color 120ms ease, background-color 120ms ease;
}

.audit-tile__value[b-kvp3z72liy] {
    font-weight: 600;
    line-height: 1.1;
}

.audit-tile__caption[b-kvp3z72liy] {
    line-height: 1.1;
}

.audit-tile__chevron[b-kvp3z72liy] {
    color: var(--mud-palette-text-secondary);
    opacity: 0;
    transition: opacity 120ms ease, color 120ms ease;
}

.audit-tile-link:hover .audit-tile--link[b-kvp3z72liy],
.audit-tile-link:focus-visible .audit-tile--link[b-kvp3z72liy] {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.audit-tile-link:hover .audit-tile__chevron[b-kvp3z72liy],
.audit-tile-link:focus-visible .audit-tile__chevron[b-kvp3z72liy] {
    opacity: 1;
    color: var(--mud-palette-primary);
}

.audit-tile-link:focus-visible[b-kvp3z72liy] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    border-radius: var(--mud-default-borderradius);
}
/* /Pages/Insights/AuditOverviewBoard.razor.rz.scp.css */
/* Audit Manager Overview board (SOL-292) — Fluent-not-Material: outlined panels, no elevation, modest
   radius, dense rows. Colour is reserved for coverage/finding tone via AuditCoverageVisuals (never-green);
   nothing here hardcodes a hex. Section heads are quiet dividers, not Material heroes.

   Layout classes sit on the authored `.audit-board` wrapper and on the MudPaper (.audit-mf4) inside it.
   A component's rendered root does not receive this component's CSS-isolation scope attribute, so rules
   that target a MudBlazor root are anchored on `.audit-board` and pierce the boundary with ::deep. */

/* ── Section heads — a quiet label strip between metric groups ───────────────────────────────── */
.audit-board .audit-section-head[b-gtvuk5pxcv] {
    display: flex;
    align-items: center;
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.5rem;
}

/* ── MF-4 readiness readout — the coverage-weighted conformance headline ─────────────────────── */
.audit-board[b-gtvuk5pxcv]  .audit-mf4 {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1rem 1.25rem;
}

.audit-board[b-gtvuk5pxcv]  .audit-mf4__icon {
    flex-shrink: 0;
    margin-top: 0.25rem;
}

.audit-board[b-gtvuk5pxcv]  .audit-mf4__body {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

.audit-board[b-gtvuk5pxcv]  .audit-mf4__value {
    font-weight: 700;
    line-height: 1.05;
}
/* /Pages/Insights/DmsMetricTile.razor.rz.scp.css */
/* DmsMetricTile (SOL-103) — one drill-through headline figure. Fluent idiom: outlined hairline, no
   elevation, modest radius; the tile lifts to the primary edge on hover/focus rather than floating on
   a shadow. Hover/focus affordances live here on the tile's own anchor (the whole tile is the link).
   Every colour is a palette token — no hexes. */

.dms-tile-link[b-c9dto7cn8v] {
    display: block;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.dms-tile[b-c9dto7cn8v] {
    height: 100%;
    padding: 0.75rem 1rem;
    border-radius: var(--mud-default-borderradius);
    transition: border-color 120ms ease, background-color 120ms ease;
}

.dms-tile__value[b-c9dto7cn8v] {
    font-weight: 600;
    line-height: 1.1;
}

.dms-tile__chevron[b-c9dto7cn8v] {
    color: var(--mud-palette-text-secondary);
    opacity: 0;
    transition: opacity 120ms ease, color 120ms ease;
}

.dms-tile-link:hover .dms-tile[b-c9dto7cn8v],
.dms-tile-link:focus-visible .dms-tile[b-c9dto7cn8v] {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.dms-tile-link:hover .dms-tile__chevron[b-c9dto7cn8v],
.dms-tile-link:focus-visible .dms-tile__chevron[b-c9dto7cn8v] {
    opacity: 1;
    color: var(--mud-palette-primary);
}

.dms-tile-link:focus-visible[b-c9dto7cn8v] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    border-radius: var(--mud-default-borderradius);
}
/* /Pages/Insights/DmsOverviewBoard.razor.rz.scp.css */
/* DMS Overview board (SOL-103) — Fluent-not-Material: outlined panels, no elevation, modest radius,
   dense rows. Colour is reserved for status/risk (overdue = error, overdue acks = warning) via the
   MudBlazor palette tokens; nothing here hardcodes a hex. Hover/focus lifts a drill-through surface
   to the primary edge rather than floating it on a shadow. */

/* Metric-tile styling lives in the tile's own scoped CSS (DmsMetricTile.razor.css), the way the
   Enterprise Overview card owns its own face — a class passed to a child component is not in this
   board's scope. */

/* All layout classes below sit on MudBlazor components (MudPaper = .dms-panel, MudLink =
   .dms-panel__head / .dms-doc-row) or on authored children inside them. A component's rendered root
   does NOT receive this component's CSS-isolation scope attribute, so the rules are anchored on the
   authored `.dms-board` wrapper and pierce the component boundary with ::deep. Without ::deep the
   panels/rows collapse to inline anchors and the lists render as run-together text. */

/* ── Panels (overdue / upcoming / acks / classification / most-requested) ──────────────────── */
.dms-board[b-u9ozeo7s0y]  .dms-panel {
    height: 100%;
    overflow: hidden;
}

/* Panel header — a drill-through anchor when it links out, a static strip otherwise. */
.dms-board[b-u9ozeo7s0y]  .dms-panel__head {
    display: flex;
    align-items: center;
    padding: 0.625rem 1rem;
    color: inherit;
    text-decoration: none;
    transition: background-color 120ms ease;
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__head:not(.dms-panel__head--static):hover,
.dms-board[b-u9ozeo7s0y]  .dms-panel__head:not(.dms-panel__head--static):focus-visible {
    background-color: var(--mud-palette-action-default-hover);
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__head:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__title {
    font-weight: 600;
    font-size: 0.8125rem;
    flex-grow: 1;
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__count {
    font-weight: 600;
    margin-left: auto;
    margin-right: 0.5rem;
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__chevron {
    opacity: 0.4;
    transition: opacity 120ms ease, color 120ms ease;
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__head:hover .dms-panel__chevron,
.dms-board[b-u9ozeo7s0y]  .dms-panel__head:focus-visible .dms-panel__chevron {
    opacity: 1;
    color: var(--mud-palette-primary);
}

.dms-board[b-u9ozeo7s0y]  .dms-panel__empty {
    padding: 1rem;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

/* ── Dense document rows inside a panel ─────────────────────────────────────────────────────── */
.dms-board[b-u9ozeo7s0y]  .dms-doc-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.4rem 1rem;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid var(--mud-palette-divider);
    transition: background-color 120ms ease;
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row:last-child {
    border-bottom: none;
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row:hover,
.dms-board[b-u9ozeo7s0y]  .dms-doc-row:focus-visible {
    background-color: var(--mud-palette-action-default-hover);
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row__num {
    font-family: var(--mud-typography-caption-family, monospace);
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    flex-shrink: 0;
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row__title {
    flex-grow: 1;
    font-size: 0.8125rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row__meta {
    flex-shrink: 0;
    font-size: 0.8125rem;
    font-weight: 600;
    text-align: right;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.2;
}

/* Overdue is the one place a risk hue is allowed to do work on a row. */
.dms-board[b-u9ozeo7s0y]  .dms-doc-row__meta--overdue {
    color: var(--mud-palette-error);
}

.dms-board[b-u9ozeo7s0y]  .dms-doc-row__meta-sub {
    font-size: 0.6875rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

/* ── Acknowledgments split cell ─────────────────────────────────────────────────────────────── */
.dms-board[b-u9ozeo7s0y]  .dms-ack {
    display: flex;
    align-items: stretch;
    justify-content: space-around;
    padding: 0.75rem 1rem;
    gap: 1rem;
}

.dms-board[b-u9ozeo7s0y]  .dms-ack__cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-grow: 1;
}
/* /Pages/Insights/EnterpriseOverviewBoard.razor.rz.scp.css */
/* Enterprise Overview board (SOL-101) — the drill-through wrapper around each module card.

   The whole card is the drill-through link, so the interactive affordances (hover lift, focus ring,
   chevron brighten) live on the anchor here and reach into the child card face with ::deep — the
   card component (EnterpriseOverviewModuleCard) owns the card's own resting styles. Fluent idiom:
   the card lifts to the primary edge on hover/focus, no elevation, no fill flood. */

/* The anchor/wrapper is stretched so every card in a row is the same height. */
.eo-card-link[b-4ab55pt55a] {
    display: block;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

/* Hover / focus on the drill-through anchor lifts the present card to the primary edge — ::deep
   pierces the child component boundary to reach the card face it renders. */
.eo-card-link:hover[b-4ab55pt55a]  .eo-card--present,
.eo-card-link:focus-visible[b-4ab55pt55a]  .eo-card--present {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.eo-card-link:hover[b-4ab55pt55a]  .eo-card__chevron,
.eo-card-link:focus-visible[b-4ab55pt55a]  .eo-card__chevron {
    opacity: 1;
    color: var(--mud-palette-primary);
}

.eo-card-link:focus-visible[b-4ab55pt55a] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    border-radius: var(--mud-default-borderradius);
}
/* /Pages/Insights/EnterpriseOverviewModuleCard.razor.rz.scp.css */
/* EnterpriseOverviewModuleCard (SOL-101) — the card face.

   The non-Present cards deliberately mirror the SOL-114 InsightScoreCellStatus treatment: muted grey
   on a dashed hairline border, OFF the health colour scale (no success/warning/error hue, no score
   bar), so a "not assessed" / "no data yet" card can never be read as a healthy figure. The explicit
   label + icon carry the meaning (colour-blind safe). Board-level alarm lives on the shared Degraded
   banner, never on a card. Fluent idiom throughout: hairline borders, modest radius, dense spacing,
   no elevation. Hover/focus affordances live on the parent anchor (EnterpriseOverviewBoard.razor.css)
   because the whole card is the drill-through. */

.eo-card[b-uqbssuq0lp] {
    height: 100%;
    padding: 16px;
    border-radius: var(--mud-default-borderradius);
    background: transparent;
    transition: border-color .12s ease, background-color .12s ease;
}

/* Present (live headline) — a solid hairline card that reads as interactive (the parent anchor
   lifts it to the primary edge on hover/focus). */
.eo-card--present[b-uqbssuq0lp] {
    border: 1px solid var(--mud-palette-lines-default);
}

/* Structurally-absent (Empty — "no data yet"): dashed hairline, the non-colour "absent" signal. */
.eo-card--absent[b-uqbssuq0lp] {
    border: 1px dashed var(--mud-palette-lines-default);
}

/* Held-out (Faulted / Stale — "not assessed"): a stronger dashed border so a failed assessment is
   visually distinct from the benign no-data-yet card, still without borrowing any health hue. */
.eo-card--held-out[b-uqbssuq0lp] {
    border: 1px dashed var(--mud-palette-text-secondary);
}

.eo-card__module-icon[b-uqbssuq0lp] {
    color: var(--mud-palette-text-secondary);
}

/* Chevron only appears on drillable cards; it brightens as the drill affordance on hover/focus
   (that state is driven from the parent anchor via ::deep). */
.eo-card__chevron[b-uqbssuq0lp] {
    color: var(--mud-palette-text-secondary);
    opacity: .5;
    transition: opacity .12s ease, color .12s ease;
}

.eo-card__value[b-uqbssuq0lp] {
    line-height: 1.1;
    font-weight: 600;
}

/* A Stale card shows its older value dimmed — present, but never as a current reading. */
.eo-card__value--muted[b-uqbssuq0lp] {
    color: var(--mud-palette-text-secondary);
}

/* The explicit status line (label + icon + reason) — the load-bearing "not assessed" treatment. */
.eo-card__state[b-uqbssuq0lp] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0 8px;
    margin-top: 8px;
}

.eo-card__state-icon[b-uqbssuq0lp] {
    align-self: center;
    color: var(--mud-palette-text-secondary);
}

.eo-card__state-label[b-uqbssuq0lp] {
    font-size: var(--mud-typography-body2-size);
    color: var(--mud-palette-text-secondary);
}

/* "Not assessed" reads bold — the unmissable, non-colour emphasis for the held-out pair. */
.eo-card__state-label--held-out[b-uqbssuq0lp] {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.eo-card__state-detail[b-uqbssuq0lp] {
    flex-basis: 100%;
    font-size: var(--mud-typography-caption-size);
    color: var(--mud-palette-text-secondary);
}
/* /Pages/Insights/InsightScoreCellStatus.razor.rz.scp.css */
/* InsightScoreCellStatus (SOL-114) — the "not assessed" / "not included" cell treatment.
   Deliberately OFF the health colour scale: muted grey text on a dashed hairline border, no
   fill on the Mud palette's success/warning/error hues, no score bar. The dashed border is the
   non-colour "absent" signal (survives colour-blind viewing); the explicit label + icon carry
   the meaning. Fluent idiom: hairline border, modest radius, dense spacing, no elevation. */

.insight-cell-status[b-xjqsnqkr8t] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0 8px;
    padding: 6px 10px;
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    background: transparent;
    margin-bottom: 8px;
}

/* Held-out (Faulted / Stale) — the pair that degrades the board. Slightly stronger border so a
   failed assessment is visually distinct from the benign structurally-absent set, without ever
   borrowing a health hue (the board-level alarm colour lives on the Degraded banner). */
.insight-cell-status--held-out[b-xjqsnqkr8t] {
    border-color: var(--mud-palette-text-secondary);
}

.insight-cell-status__icon[b-xjqsnqkr8t] {
    align-self: center;
    color: var(--mud-palette-text-secondary);
}

.insight-cell-status__label[b-xjqsnqkr8t] {
    min-width: 160px;
    font-size: var(--mud-typography-body2-size);
    color: var(--mud-palette-text-primary);
}

.insight-cell-status__state[b-xjqsnqkr8t] {
    font-size: var(--mud-typography-body2-size);
    color: var(--mud-palette-text-secondary);
}

/* "Not assessed" reads bold — the unmissable, non-colour emphasis for the held-out pair. */
.insight-cell-status__state--held-out[b-xjqsnqkr8t] {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.insight-cell-status__detail[b-xjqsnqkr8t] {
    font-size: var(--mud-typography-caption-size);
    color: var(--mud-palette-text-secondary);
}
/* /Pages/Insights/TrainMetricTile.razor.rz.scp.css */
/* TrainMetricTile (SOL-192).

   Fluent idiom, matching the Train surfaces and the sibling tiles: hairline border, no elevation, modest
   radius. Every colour resolves to a MudTheme palette token so light and dark both work for free — no
   hard-coded hex, ever.

   The muted treatment is load-bearing, not decorative: it is how a "Not assessed" measure is visibly
   held off the health scale. An unassessed figure must never read as a result — that is the CF-1
   false-assurance trap in visual form. */

.cv-train-tile[b-0ek67rnbpu] {
    border-radius: 4px;
    height: 100%;
}

/* Drill-through form. Absent from every count tile in v1 (D2) — kept because the section-header links
   and SOL-503's filtered drills use it, and because a rule that exists only sometimes is worse to
   rediscover than one that is simply here. */
.cv-train-tile--link[b-0ek67rnbpu] {
    transition: border-color 120ms linear, background-color 120ms linear;
}

.cv-train-tile--link:hover[b-0ek67rnbpu] {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.cv-train-tile-link[b-0ek67rnbpu] {
    display: block;
    height: 100%;
}

/* Not assessed. Tinted off the ordinary surface so the tile reads as deliberately outside the score
   rather than as a low one. */
.cv-train-tile--muted[b-0ek67rnbpu] {
    background-color: var(--mud-palette-background-gray);
}

.cv-train-tile__value[b-0ek67rnbpu] {
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

/* "Not assessed" is words, not a number — smaller than a figure so it never competes with the real
   values beside it, and secondary in colour so it cannot be mistaken for a result. */
.cv-train-tile__value--muted[b-0ek67rnbpu] {
    font-size: 1.25rem;
    color: var(--mud-palette-text-secondary);
}

.cv-train-tile__icon[b-0ek67rnbpu] {
    flex: 0 0 auto;
}

.cv-train-tile__chevron[b-0ek67rnbpu] {
    color: var(--mud-palette-text-secondary);
    flex: 0 0 auto;
}

.cv-train-tile__caption[b-0ek67rnbpu] {
    color: var(--mud-palette-text-secondary);
}
/* /Pages/Insights/TrainOverviewBoard.razor.rz.scp.css */
/* Training & Awareness Overview board (SOL-192).

   Scoped sheet: only the board's own chrome lives here. The tiles carry their own scoped sheet
   (TrainMetricTile.razor.css) — a scoped sheet cannot reach into a child component, and duplicating the
   tile rules here would give two places to change one look.

   House style follows the Train surfaces and the sibling boards: hairline borders, no elevation,
   restrained radius, every colour resolved from a MudTheme palette token so light and dark both work.
   No hard-coded hex. */

/* The section note under "Awareness posture" — it carries the load-bearing sentence about why coverage
   and compliance are never averaged, so it reads as guidance rather than as a caption on a tile. */
.cv-train-board__note[b-43vlxydsiy] {
    max-width: 62ch;
    line-height: 1.45;
}
/* /Pages/Portal/Portal.razor.rz.scp.css */
/* ===========================================================================
   PORTAL ("My Work") — scoped styles (net-new, registry-exempt).
   =========================================================================== */

.portal-header[b-3ua82fjdhs] {
    background: linear-gradient(135deg, var(--mud-palette-primary-hover), transparent);
    border-radius: var(--mud-default-borderradius);
}

.portal-wave[b-3ua82fjdhs] {
    display: inline-block;
}

.portal-task-row[b-3ua82fjdhs] {
    border-bottom: 1px solid var(--mud-palette-divider);
    border-radius: 4px;
    /* transparent left accent reserved so overdue rows don't shift content sideways */
    border-left: 3px solid transparent;
}

.portal-task-row:last-child[b-3ua82fjdhs] {
    border-bottom: none;
}

/* Clickable affordance: pointer + subtle hover highlight, whole row is the target. */
.portal-task-clickable[b-3ua82fjdhs] {
    cursor: pointer;
    transition: background-color .12s ease;
}

.portal-task-clickable:hover[b-3ua82fjdhs] {
    background-color: var(--mud-palette-action-default-hover);
}

/* Overdue rows get a thin red left accent so urgency reads without chip color. */
.portal-task-overdue[b-3ua82fjdhs] {
    border-left: 3px solid var(--mud-palette-error);
}

/* Celebratory zero-state card. */
.portal-empty[b-3ua82fjdhs] {
    border-style: dashed;
}

/* Fixed-width tag column so every task description starts at the same x.
   88px comfortably fits the widest tag ("Signals") + small-chip padding. */
.portal-tag-col[b-3ua82fjdhs] {
    flex: 0 0 88px;
    min-width: 88px;
    display: flex;
}

/* Make every module chip render at an identical width so the badges form a
   clean uniform column of pills. The chip fills the 88px tag column and its
   label is centered for a tidy stacked-pill look. */
.portal-tag-col[b-3ua82fjdhs]  .mud-chip {
    width: 100%;
    margin: 0;
    justify-content: center;
}

.portal-tag-col[b-3ua82fjdhs]  .mud-chip-content {
    width: 100%;
    justify-content: center;
}

.portal-quick[b-3ua82fjdhs] {
    background: var(--mud-palette-background-gray);
}

/* Featured-signal hero: gentle branded gradient card. */
.portal-signal-hero[b-3ua82fjdhs] {
    background: linear-gradient(135deg, var(--mud-palette-primary), var(--mud-palette-secondary));
    color: var(--mud-palette-primary-text);
}

.portal-signal-hero .mud-icon-root[b-3ua82fjdhs],
.portal-signal-hero .mud-typography[b-3ua82fjdhs] {
    color: var(--mud-palette-primary-text);
}

/* --- Mini calendar styled as a read-only display, not a form input --------- */
/* Hide the hidden text-field shell MudDatePicker renders above the static calendar. */
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-infrom,
.portal-calendar-picker[b-3ua82fjdhs]  .mud-input-control {
    display: none;
}

/* Flatten the static paper so it sits inside our own MudPaper cleanly. */
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-container,
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-paper {
    box-shadow: none;
    background: transparent;
}

/* Stretch the static picker to fill the card width instead of its fixed ~310px,
   so the day grid spans the card and the right-hand gap is gone. The card is
   ~300-360px wide (md=4 rail), so this is a small delta — cells stay sensible. */
.portal-calendar-picker[b-3ua82fjdhs],
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-container,
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-paper,
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-content,
.portal-calendar-picker[b-3ua82fjdhs]  .mud-picker-calendar-container {
    width: 100%;
    max-width: 100%;
}

/* Due-day marker: a small dot under the day number.
   The .portal-due-day class is injected via AdditionalDateClasses onto the day button. */
.portal-calendar-picker[b-3ua82fjdhs]  .portal-due-day {
    position: relative;
    font-weight: 600;
}

.portal-calendar-picker[b-3ua82fjdhs]  .portal-due-day::after {
    content: "";
    position: absolute;
    bottom: 4px;
    left: 50%;
    transform: translateX(-50%);
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--mud-palette-error);
}
/* /Pages/Signals/SignalNoAccessPanel.razor.rz.scp.css */
/*
    SOL-31 — mirrors LoadStateView's `.ds-loadstate-detail` rather than repeating the
    `style="opacity:.7; max-width:520px;"` inline smell on a fourth panel shape.
*/
.signal-noaccess-detail[b-lq90bvi549] {
    opacity: 0.7;
    max-width: 520px;
}
/* /Pages/Train/AcknowledgeTrainingDialog.razor.rz.scp.css */
/* ── C1 attestation dialog ───────────────────────────────────────────────────
   The statement outweighs the chrome: the sentence the worker is signing is the
   largest thing in the body, and the meaning-of-signature note sits under the
   gesture so it is read before the button, not after. */

.train-ackdialog__statement[b-inl3hf5m13] {
    margin: 1rem 0 0.5rem;
    font-size: 0.9375rem;
    color: var(--mud-palette-text-primary);
}

.train-ackdialog__meaning[b-inl3hf5m13] {
    margin: 0.75rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--mud-palette-lines-default);
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}
/* /Pages/Train/AssigneePicker.razor.rz.scp.css */
/* ── Bulk assignee picker (SOL-483) ──────────────────────────────────────────
   One hook: the chip list has to stay reviewable when a bulk selection grows,
   so it wraps and is capped in height rather than pushing the dialog's actions
   off-screen. Colours come from MudTheme tokens; nothing is hard-coded. */

.cv-train-assignees__chips[b-l2v252rt9w] {
    max-height: 9rem;
    overflow-y: auto;
    padding: 0.25rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
}
/* /Pages/Train/MyTraining.razor.rz.scp.css */
/* ── My Training (BRD F3) ────────────────────────────────────────────────────
   Fluent/Office, not Material: hairline borders instead of shadows, dense
   gutters, restrained radius. Every colour resolves to a MudTheme palette
   token — no hard-coded hexes, no inline style= on the page. */

.train-commandbar[b-4ocbud5lyy] {
    border-bottom: 1px solid var(--mud-palette-lines-default);
    padding-left: 0;
    padding-right: 0;
}

.train-subtitle[b-4ocbud5lyy] {
    margin: 0.5rem 0 1.25rem;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

/* ── Groups ─────────────────────────────────────────────────────────────── */

.train-bucket[b-4ocbud5lyy] {
    margin-bottom: 1.75rem;
}

.train-bucket__header[b-4ocbud5lyy] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.train-bucket__title[b-4ocbud5lyy] {
    font-weight: 600;
}

.train-bucket__description[b-4ocbud5lyy] {
    margin: 0.375rem 0 0.75rem;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Positive done-state inside the Outstanding group — reassurance, not a blank. */
.train-allclear[b-4ocbud5lyy] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 0.25rem;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* ── Rows ───────────────────────────────────────────────────────────────── */

.train-row[b-4ocbud5lyy] {
    border-radius: 4px;
}

.train-row:hover[b-4ocbud5lyy] {
    border-color: var(--mud-palette-primary);
}

.train-row__main[b-4ocbud5lyy] {
    min-width: 16rem;
    flex: 1 1 20rem;
}

.train-row__title[b-4ocbud5lyy] {
    font-weight: 600;
    cursor: pointer;
}

.train-row__meta[b-4ocbud5lyy] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.25rem;
}

.train-row__competency[b-4ocbud5lyy] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Gloves-on target for the floor tablet (P7) — the row's primary action is never a small hit area. */
.train-row__action[b-4ocbud5lyy] {
    min-width: 8.5rem;
    min-height: 3rem;
}

/* ── Due state ──────────────────────────────────────────────────────────── */

.train-due[b-4ocbud5lyy] {
    display: inline-flex;
    align-items: center;
    font-size: 0.875rem;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
}

/* Overdue carries colour AND an icon AND the word "Overdue" — never colour alone (a11y). */
.train-due--overdue[b-4ocbud5lyy] {
    color: var(--mud-palette-error);
    font-weight: 600;
}

/* ── Empty state ────────────────────────────────────────────────────────── */

.train-emptystate__body[b-4ocbud5lyy] {
    max-width: 32rem;
    margin-top: 0.5rem;
    text-align: center;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}
/* /Pages/Train/TrainingAssignmentDetail.razor.rz.scp.css */
/* ── Read & acknowledge (BRD C1) ─────────────────────────────────────────────
   Fluent/Office: hairline borders, dense gutters, restrained radius, colour only
   where it carries status meaning. All colours resolve to MudTheme palette tokens. */

.train-commandbar[b-81txoifpbs] {
    border-bottom: 1px solid var(--mud-palette-lines-default);
    padding-left: 0;
    padding-right: 0;
    margin-bottom: 1rem;
}

.train-detail__chips[b-81txoifpbs] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.375rem;
}

.train-detail__description[b-81txoifpbs] {
    margin: 0.75rem 0 0;
    font-size: 0.875rem;
    color: var(--mud-palette-text-primary);
    white-space: pre-wrap;
}

/* ── Two-step ceremony ──────────────────────────────────────────────────── */

.train-step[b-81txoifpbs] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.train-step__number[b-81txoifpbs] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
}

.train-step__body[b-81txoifpbs] {
    flex: 1 1 auto;
    min-width: 0;
}

.train-step__hint[b-81txoifpbs] {
    margin: 0.25rem 0 0.75rem;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* Gloves-on target for the floor tablet (P7). */
.train-step__action[b-81txoifpbs] {
    min-width: 12rem;
    min-height: 3rem;
}

.train-step__done[b-81txoifpbs] {
    display: inline-flex;
    align-items: center;
    margin-left: 0.75rem;
    font-size: 0.8125rem;
    color: var(--mud-palette-success);
}

/* ── Closure is final and visibly immutable (P5) ────────────────────────── */

.train-ack-locked[b-81txoifpbs] {
    display: flex;
    align-items: flex-start;
    margin-top: 0.5rem;
    padding: 0.875rem 1rem;
    border: 1px solid var(--mud-palette-success);
    border-radius: 4px;
    background-color: var(--mud-palette-background-gray);
}

.train-ack-locked__title[b-81txoifpbs] {
    font-weight: 600;
}

.train-ack-locked__body[b-81txoifpbs] {
    margin: 0.25rem 0 0;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

/* ── Fact list ──────────────────────────────────────────────────────────── */

.train-facts[b-81txoifpbs] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.375rem 1rem;
    margin: 0;
    font-size: 0.8125rem;
}

.train-facts dt[b-81txoifpbs] {
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.train-facts dd[b-81txoifpbs] {
    margin: 0;
    color: var(--mud-palette-text-primary);
}

/* ── Due state (shared vocabulary with the worklist) ────────────────────── */

.train-due[b-81txoifpbs] {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

.train-due--overdue[b-81txoifpbs] {
    color: var(--mud-palette-error);
    font-weight: 600;
}
/* /Pages/Train/TrainingAssignments.razor.rz.scp.css */
/* ── Assignment roster (BRD B1/B2, SOL-483) ──────────────────────────────────
   Only the hooks this surface genuinely adds. The shared Train list vocabulary
   — cv-train-panel / -row / -hint / -filter / -search / -empty / -pager — is
   defined once for the module and is deliberately NOT redefined here.

   Fluent/Office, not Material: hairline rules instead of shadows, dense
   gutters, restrained radius. Every colour resolves to a MudTheme palette
   token — no hard-coded hexes, no inline style= on the page. */

/* The filter rows wrap rather than scroll: an admin on a 13" laptop must be
   able to see which filters are on, not hunt for them off the right edge. */
.cv-train-filterbar[b-o8ymbq3i6y] {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

/* ── Due state ──────────────────────────────────────────────────────────── */

.cv-train-due[b-o8ymbq3i6y] {
    display: inline-flex;
    align-items: center;
    font-size: 0.875rem;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
}

/* Overdue carries colour AND an icon AND the word "Overdue" — never colour
   alone (a11y). The flag itself is the server's; this only draws it. */
.cv-train-due--overdue[b-o8ymbq3i6y] {
    color: var(--mud-palette-error);
    font-weight: 600;
}

/* ── Row flags ──────────────────────────────────────────────────────────── */

.cv-train-rowflags[b-o8ymbq3i6y] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.125rem;
}

/* ── Overdue rows ───────────────────────────────────────────────────────── */

/* ::deep because MudTable renders the <tr> itself, so it carries no scope id.
   A hairline lead edge, not a fill: the row must read as flagged without
   drowning the status chip that says why. */
.cv-train-panel[b-o8ymbq3i6y]  tr.cv-train-row--overdue td:first-child {
    box-shadow: inset 2px 0 0 0 var(--mud-palette-error);
}
/* /Shared/Components/DesignSystem/LoadStateView.razor.rz.scp.css */
/*
    LoadStateView scoped styles — replaces the inline `style="opacity:.7; max-width:520px;"` smell
    that was repeated across the CAPA error / not-in-scope / empty panels with one named class.
*/
.ds-loadstate-detail[b-p2g4349wia] {
    opacity: 0.7;
    max-width: 520px;
}
