/* ── Train module — shared surface vocabulary (SOL-482) ──────────────────────
   Defines the `cv-train-*` classes referenced across Pages/Train/. These are
   deliberately NOT in a Blazor scoped `.razor.css`: scoped CSS is attribute-
   scoped per component, and this vocabulary is cross-component (cv-train-hint
   alone spans nine files, cv-train-dialog five). A scoped sheet cannot serve it.

   House style — Fluent/Office, not Material:
     • hairline borders instead of shadows; nothing floats
     • dense gutters, restrained radius (4px, matching MyTraining.razor.css)
     • EVERY colour resolves to a MudTheme palette token, so light and dark
       themes both work for free. No hard-coded hex, ever.
     • no inline style= on the pages — repeated styling lives here

   Naming note: the SOL-191 surfaces (MyTraining, TrainingAssignmentDetail) use
   an unprefixed `train-*` vocabulary in their scoped sheets. The `cv-train-*`
   divergence is known and deliberately deferred by the architect — do not
   rename either side without that decision.

   Loaded from wwwroot/index.html, immediately after css/app.css. */

/* ── Shared text vocabulary ─────────────────────────────────────────────────
   cv-train-hint is the single most-used class in the module: secondary,
   explanatory caption text that sits under a control, a row title, or a
   panel heading. Secondary by colour AND by size — never the primary read. */

.cv-train-hint {
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--mud-palette-text-secondary);
}

/* The "no value" placeholder in a grid cell. Muted below secondary so an
   absent value never competes with a present one for attention. */
.cv-train-dash {
    color: var(--mud-palette-text-disabled);
}

/* Two-line description clamp inside a dense grid row: a long description must
   not be able to blow the row height out and break the spreadsheet rhythm. */
.cv-train-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── List panel + command bar ───────────────────────────────────────────────
   The wrapper around a whole list surface (command bar + load/empty/error +
   grid + pager). min-width:0 lets the grid inside actually shrink rather than
   forcing the flex/tab parent wider. */

.cv-train-panel {
    display: block;
    min-width: 0;
}

/* Fluent command bar: primary action right-aligned, defined by a hairline
   rather than elevation. Wraps rather than overflowing on a tablet.

   Two selectors, one treatment. The list surfaces put their toolbar inside
   .cv-train-panel, so a descendant selector reaches it. A DETAIL surface
   (AwarenessCampaignDetail) has no panel wrapper — it is not a list — so it
   carries .cv-train-commandbar directly. Same bar, same rule; do not let the
   two drift apart. */
.cv-train-panel .mud-toolbar,
.cv-train-commandbar {
    flex-wrap: wrap;
    gap: 0.25rem 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    margin-bottom: 0.75rem;
}

/* Search does not stretch to eat the bar; the filters keep a stable width so
   the toolbar does not reflow every time an option label changes length. */
.cv-train-search {
    flex: 0 1 18rem;
    min-width: 11rem;
}

.cv-train-filter {
    flex: 0 0 auto;
    width: 10.5rem;
}

/* ── Grid ───────────────────────────────────────────────────────────────────
   Dense, spreadsheet-grade rows. The row itself is the edit affordance
   (MudTable OnRowClick), so it reads as clickable. */

.cv-train-row {
    cursor: pointer;
}

/* The name cell carries a title plus a clamped description while its siblings
   are single-line — top alignment keeps the dense grid on one baseline. */
.cv-train-row > td {
    vertical-align: top;
}

/* Trailing row-action column: shrink to content, never wrap, hug the right
   edge. Applied to both the MudTh and the MudTd so the header lines up. */
.cv-train-actions-col {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

/* ── Empty state ────────────────────────────────────────────────────────────
   Success + empty is a clean done-state, never a blank and never an error.
   The panel is outlined (Elevation=0 on the page), tinted just enough to read
   as a deliberate state rather than a failed render. */

.cv-train-empty {
    border-radius: 4px;
    background-color: var(--mud-palette-background-gray);
}

.cv-train-empty .mud-typography-body2 {
    max-width: 32rem;
    color: var(--mud-palette-text-secondary);
}

.cv-train-empty .mud-icon-root {
    color: var(--mud-palette-text-secondary);
}

/* ── Pager ──────────────────────────────────────────────────────────────────
   Sits directly under the grid and is separated from it by a hairline, not a
   gap. Renders in both its forms (paged control / bare count line). */

.cv-train-pager {
    margin-top: 0.25rem;
    padding-top: 0.375rem;
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* ── Dialogs ────────────────────────────────────────────────────────────────
   A width floor so an authoring dialog does not collapse to its content on a
   desktop, capped at 100% so it can never overflow the MudDialog's own
   MaxWidth on a tablet or a narrow window. */

.cv-train-dialog {
    min-width: 0;
    max-width: 100%;
}

@media (min-width: 600px) {
    .cv-train-dialog {
        min-width: 26rem;
    }
}

/* The requirement author (subject + target + schedule in one pass) needs more
   room than a simple name/description dialog. */
@media (min-width: 960px) {
    .cv-train-dialog--wide {
        min-width: 32rem;
    }
}

/* ── Link + audience lists ──────────────────────────────────────────────────
   Two structurally identical read lists: the competency ⇄ training-item edge
   editor, and the resolved-audience preview. Bounded height so a large
   audience scrolls inside the dialog instead of pushing the actions off. */

.cv-train-link-list,
.cv-train-audience-list {
    max-height: 18rem;
    overflow-y: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
}

.cv-train-link-row {
    padding: 0.5rem 0.625rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.cv-train-link-row:last-child {
    border-bottom: none;
}

.cv-train-link-row:hover {
    background-color: var(--mud-palette-action-default-hover);
}

/* The "who this resolves to" heading above the audience list — states the
   target and the scope cap before the list itself. */
.cv-train-audience-head {
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* ── Requirement target picker ──────────────────────────────────────────────
   The four RequirementTargetType values side by side, each with the axis it
   resolves to spelled out, so the author picks on meaning rather than on a
   word in a dropdown. */

.cv-train-target {
    display: block;
    min-width: 0;
}

.cv-train-target-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.5rem;
    margin-top: 0.25rem;
}

.cv-train-target-option {
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    transition: border-color 120ms linear, background-color 120ms linear;
}

.cv-train-target-option:hover {
    border-color: var(--mud-palette-primary);
}

/* Selected. Colour is a reinforcement only — the real signal is the MudRadio
   inside the tile, which carries the checked state for a screen reader and
   for anyone who cannot separate the two border tones (a11y). */
.cv-train-target-option--on {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary-hover);
}

/* The per-option hint, indented to sit under the radio's label rather than
   under the radio button itself. */
.cv-train-target-hint {
    margin-left: 2rem;
    margin-top: 0.125rem;
}

/* ── Awareness-campaign surfaces (SOL-479 markup, styled here 2026-08-07) ────
   These six classes were referenced by the SOL-479 campaign markup but never
   defined: this stylesheet merged as PR #131, second of the six-PR Train train,
   and the campaign surfaces landed at #135 — so the audit that produced the
   original class set ran against a tree that did not yet contain them. Found
   by the SOL-484 pre-flight (referenced 34, defined 27).

   Same house style as above: hairline borders, palette tokens only, no hex. */

/* Retained long-form text — the campaign message and both §7.3(f) limb texts.

   pre-wrap is the load-bearing declaration, not a nicety. This is the exact
   text a worker acknowledges and an auditor reads back; an author who types
   the two limbs as separate paragraphs must not have that structure collapsed
   into a wall by the renderer. The record must read as it was written.

   The measure cap is the other half: retained text is read carefully, and a
   full-width line on a desktop is measurably harder to track back. */
.cv-train-body {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    max-width: 68ch;
}

/* ── CF-4 — the ISO 45001 §7.3(f) both-limbs block ──────────────────────────
   Carries the one paragraph on the page an auditor is specifically looking
   for, so it is set apart from the ordinary outlined panels around it. The
   left accent does that work; the parent MudPaper already supplies the border,
   so this adds a rule rather than a second box. Restrained on purpose — the
   block is evidence, not an alert. */

.cv-train-limbs {
    border-left: 3px solid var(--mud-palette-primary);
    background-color: var(--mud-palette-background-gray);
}

/* "Limb 1 of 2 · …" — labels the limb it introduces. Deliberately a LABEL and
   not a heading in weight: the limb text under it is the record, and the label
   must not out-shout it. The top margin separates limb 2 from limb 1's text
   without needing a divider between them. */
.cv-train-limb-heading {
    color: var(--mud-palette-text-secondary);
    font-weight: 600;
    margin-bottom: 0.25rem;
}

/* ── Detail facts table ─────────────────────────────────────────────────────
   The key/value block under the message (audience, published, by whom). A
   borderless MudSimpleTable, so the label column has to hold the alignment on
   its own: fixed-ish width, secondary colour, top-aligned so a wrapping value
   does not drag its label off the baseline. */

.cv-train-facts td:first-child {
    width: 12rem;
    padding-left: 0;
    color: var(--mud-palette-text-secondary);
    vertical-align: top;
    white-space: nowrap;
}

.cv-train-facts td {
    vertical-align: top;
    border-bottom: none;
}

/* ── Publish dialog — the three irreversible consequences ───────────────────
   Separated by hairlines, matching cv-train-link-row, so the three read as
   three distinct commitments rather than one paragraph of prose. This is the
   last screen before an act that cannot be undone; each line has to be
   individually readable. */

.cv-train-publish-list .mud-list-item {
    align-items: flex-start;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.cv-train-publish-list .mud-list-item:last-child {
    border-bottom: none;
}

/* ── Campaign audience picker ───────────────────────────────────────────────
   The bare container. Same job as .cv-train-target: min-width:0 lets the
   selects inside shrink instead of forcing the dialog wider. (Only the
   -list and -head children were defined before; the wrapper was not.) */

.cv-train-audience {
    display: block;
    min-width: 0;
}
