/* MS25-α (incremental-memo MS24-α + bold-memo prep) — Design token
   foundation. Establishes a single :root palette + spacing + typography
   + radius + shadow + transition scale that the rest of app.css and
   downstream component CSS draws from.
   Naming mirrors the --se-* convention already in MainLayout.razor.css
   so the layout chrome + global styles converge.
   Audit: replaced the 4 competing primary colors (#1b6ec2, #1f3a5f,
   #0071c1, #c2410c) — orange is now the only primary accent. Status
   colors moved out of the primary palette into a separate
   --se-status-* set used only on semantic surfaces (status pills,
   validation messages). */
:root {
    /* --- Color: text + surfaces -------------------------------- */
    --se-color-text-strong: #18181b;        /* zinc-900 */
    --se-color-text-default: #3f3f46;       /* zinc-700 */
    --se-color-text-muted: #71717a;         /* zinc-500 */
    --se-color-text-subtle: #a1a1aa;        /* zinc-400 */
    --se-color-text-inverse: #ffffff;
    --se-color-surface: #ffffff;
    --se-color-surface-raised: #ffffff;
    --se-color-surface-sunken: #fafafa;
    --se-color-app-bg: #f5f5f4;              /* stone-50 */
    --se-color-border-default: #e4e4e7;      /* zinc-200 */
    --se-color-border-strong: #d4d4d8;       /* zinc-300 */
    --se-color-border-subtle: #f4f4f5;       /* zinc-100 */

    /* --- Color: accent (orange) — the only primary ------------- */
    --se-color-accent: #f97316;              /* orange-500 */
    --se-color-accent-strong: #c2410c;       /* orange-700 */
    --se-color-accent-soft: rgba(249, 115, 22, 0.09);
    --se-color-accent-ring: rgba(249, 115, 22, 0.2);

    /* --- Color: semantic status (only on status surfaces) ----- */
    --se-color-success-bg: #d1fae5;
    --se-color-success-fg: #065f46;
    --se-color-warning-bg: #fef3c7;
    --se-color-warning-fg: #92400e;
    --se-color-danger-bg: #fee2e2;
    --se-color-danger-fg: #991b1b;
    --se-color-info-bg: #dbeafe;
    --se-color-info-fg: #1e40af;
    --se-color-neutral-bg: #e5e7eb;
    --se-color-neutral-fg: #6b7280;

    /* --- Spacing scale (multiples of 0.25rem) ----------------- */
    --se-space-1: 0.25rem;
    --se-space-2: 0.5rem;
    --se-space-3: 0.75rem;
    --se-space-4: 1rem;
    --se-space-5: 1.25rem;
    --se-space-6: 1.5rem;
    --se-space-8: 2rem;
    --se-space-10: 2.5rem;
    --se-space-12: 3rem;
    --se-space-16: 4rem;

    /* --- Type scale ------------------------------------------- */
    --se-text-xs: 0.72rem;
    --se-text-sm: 0.82rem;
    --se-text-base: 0.92rem;
    --se-text-lg: 1.05rem;
    --se-text-xl: 1.25rem;
    --se-text-2xl: 1.5rem;
    --se-text-3xl: 1.85rem;
    --se-line-tight: 1.25;
    --se-line-normal: 1.5;
    --se-line-relaxed: 1.65;

    /* --- Radius ---------------------------------------------- */
    --se-radius-sm: 0.25rem;
    --se-radius: 0.375rem;
    --se-radius-md: 0.5rem;
    --se-radius-lg: 0.75rem;
    --se-radius-pill: 999px;

    /* --- Shadow ---------------------------------------------- */
    --se-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
    --se-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
    --se-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.04);
    --se-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.07), 0 4px 6px rgba(0, 0, 0, 0.04);

    /* --- Transition ----------------------------------------- */
    --se-transition: 0.15s ease;
    --se-transition-fast: 0.1s ease;
    --se-transition-slow: 0.25s ease;

    /* --- MS25-β.2 — Display density ------------------------- */
    /* User preference: Compact / Standard / Comfortable. Applied to
       row-level padding via calc(base * var(--se-density)) so the
       same rule renders three densities without three variants.
       JS sets data-density="compact|comfortable" on <html>; default
       is Standard (attribute absent). */
    --se-density: 1;
}

:root[data-density="compact"]      { --se-density: 0.75; }
:root[data-density="comfortable"]  { --se-density: 1.25; }

/* MS25-δ — Incident narrative reader, rendered inside the two-pane
   shell's left pane on /incidents/edit/{id}. Comfortable line-height
   + max-width on lines (~70ch) for readable narrative content. */
.incident-narrative-reader {
    color: var(--se-color-text-default);
    line-height: var(--se-line-relaxed);
}
.incident-narrative-body {
    margin: 0;
    white-space: pre-wrap;     /* preserve newlines as the user typed them */
    word-break: break-word;
    font-size: var(--se-text-base);
    max-width: 70ch;
}
.incident-narrative-empty {
    margin: 0;
    color: var(--se-color-text-muted);
    font-style: italic;
}

/* MS25-β.3 — Sidebar rail mode. The .sidebar--rail class on the
   layout wrapper narrows the column to 56px + hides text-bearing nav
   chrome (spotlight placeholder, kbd badge, link labels, group
   headers). Only the spotlight icon + rail-toggle button remain
   visible at the top. Hover over the sidebar (handled in
   MainLayout.razor.css) expands the column back to full width as an
   overlay over content — text becomes visible again on hover via
   the inverse of the rules below.

   Cross-component scope: these need to apply to NavMenu's children
   while keyed off MainLayout's wrapping div, so they live here in
   app.css (global) rather than in either component's scoped CSS. */
.sidebar.sidebar--rail .nav-spotlight-placeholder,
.sidebar.sidebar--rail .nav-spotlight-hotkey {
    display: none;
}
.sidebar.sidebar--rail .nav-spotlight {
    width: 1.85rem;
    padding: 0.35rem;
    justify-content: center;
}
.sidebar.sidebar--rail .nav-link,
.sidebar.sidebar--rail .nav-group-header,
.sidebar.sidebar--rail .navbar-brand {
    visibility: hidden;
}
.sidebar.sidebar--rail:hover .nav-spotlight-placeholder,
.sidebar.sidebar--rail:hover .nav-spotlight-hotkey {
    display: inline;
}
.sidebar.sidebar--rail:hover .nav-spotlight {
    width: auto;
    padding: 0.45rem 0.65rem;
    justify-content: flex-start;
}
.sidebar.sidebar--rail:hover .nav-link,
.sidebar.sidebar--rail:hover .nav-group-header,
.sidebar.sidebar--rail:hover .navbar-brand {
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --se-transition: 0s;
        --se-transition-fast: 0s;
        --se-transition-slow: 0s;
    }
}

html, body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    color: var(--se-color-text-default);
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: var(--se-color-accent-strong);
    text-decoration: none;
    transition: color var(--se-transition-fast);
}

a:hover, .btn-link:hover {
    color: var(--se-color-accent);
    text-decoration: underline;
}

.btn-primary {
    color: var(--se-color-text-inverse);
    background-color: var(--se-color-accent);
    border-color: var(--se-color-accent);
}

.btn-primary:hover {
    background-color: var(--se-color-accent-strong);
    border-color: var(--se-color-accent-strong);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem var(--se-color-surface), 0 0 0 0.25rem var(--se-color-accent-ring);
}

.content {
    padding-top: 1.1rem;
}

/* MS25-α — Deleted the Blazor-template `.valid.modified` green
   outline. Decorating every touched-and-valid field with a green
   ring is pure template noise — modern UX surfaces validation via
   focus + inline messages, not always-on rings. The
   `.invalid` outline survives but goes through the token system. */
.invalid {
    outline: 1px solid var(--se-color-danger-fg);
}

.validation-message {
    color: var(--se-color-danger-fg);
    font-size: var(--se-text-sm);
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--se-color-accent);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* --- M13 additions --- */

.welcome { max-width: 780px; }
.welcome .tagline { color: #566; font-size: 1.1rem; }
.welcome .status-grid { list-style: none; padding: 0; margin-top: 1.5rem; }
.welcome .status-grid li { padding: 0.4rem 0; border-bottom: 1px solid #eee; }

.placeholder-note {
    background: #fff8e1;
    border-left: 3px solid #fbc02d;
    padding: 0.75rem 1rem;
    color: #5f4a0a;
}

.tenant-indicator {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.9rem;
    margin-left: auto;
}
.tenant-indicator .tenant-label { color: #666; text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.75rem; }
.tenant-indicator .tenant-select { font-size: 0.85rem; background: #f1f3f5; border: 1px solid #ccc; border-radius: 3px; padding: 0.2rem 0.5rem; cursor: pointer; max-width: 16rem; }
.tenant-indicator .tenant-select:hover { background: #e9ecef; }

/* Pre-boot skeleton — rendered from static HTML before WASM loads. */
.app-skeleton {
    display: grid;
    grid-template-columns: 250px 1fr;
    height: 100vh;
    background: #fafafa;
    color: #888;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.skeleton-sidebar {
    background: var(--se-color-app-bg);
    color: var(--se-color-text-muted);
    border-right: 1px solid var(--se-color-border-default);
    padding: 1rem;
}
.skeleton-brand {
    font-weight: 600;
    padding: 0.75rem 0;
    color: #fff;
}
.skeleton-nav-item {
    height: 1.25rem;
    margin: 0.75rem 0;
    background: rgba(255,255,255,0.12);
    border-radius: 3px;
}
.skeleton-main {
    display: flex;
    flex-direction: column;
}
.skeleton-topbar {
    height: 3.5rem;
    background: #fff;
    border-bottom: 1px solid #eee;
}
.skeleton-content {
    padding: 2rem;
}
.skeleton-heading {
    height: 2rem;
    width: 40%;
    background: #eee;
    border-radius: 3px;
    margin-bottom: 1.5rem;
}
.skeleton-line {
    height: 1rem;
    background: #eee;
    border-radius: 3px;
    margin: 0.6rem 0;
}
.skeleton-line:nth-child(2) { width: 85%; }
.skeleton-line:nth-child(3) { width: 65%; }
.skeleton-progress {
    position: absolute;
    inset: auto 0 2rem 0;
    text-align: center;
}

/* --- M14 additions: list + dialog + forms --- */

.jobtitles-list { max-width: 1000px; }

/* MS25-β (incremental memo Moves 5 + 4) — Page-header + empty-state
   primitives. .page-header is the single canonical page-top component;
   .list-header / .chemical-safety-hero / .readiness-page-header all
   share its rules via the joined selector so existing markup keeps
   working without a Razor sweep. New pages use .page-header directly.

   .empty-state replaces the bare .list-status grey-line empty
   message with a centered icon + title + body + CTA composition.
   EntityListView opts in via the EmptyAction RenderFragment
   parameter; callers without an action get the same shape minus the
   CTA slot. */

.page-header,
.list-header,
.chemical-safety-hero,
.readiness-page-header {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-4);
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: var(--se-space-6);
    padding-bottom: var(--se-space-3);
    border-bottom: 1px solid var(--se-color-border-default);
}

.page-header h1,
.list-header h1,
.chemical-safety-hero h1,
.readiness-page-header h1,
.page-header-title {
    margin: 0;
    font-size: var(--se-text-2xl);
    font-weight: 700;
    color: var(--se-color-text-strong);
    letter-spacing: -0.015em;
    line-height: var(--se-line-tight);
}

.page-header-subtitle,
.chemical-safety-subtitle {
    margin: var(--se-space-2) 0 0;
    color: var(--se-color-text-muted);
    font-size: var(--se-text-base);
    line-height: var(--se-line-normal);
    flex-basis: 100%;     /* drop below the title row when the actions slot is present */
}

.page-header-actions {
    display: flex;
    gap: var(--se-space-2);
    align-items: center;
    flex-shrink: 0;
}

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--se-space-12) var(--se-space-6);
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-lg);
    color: var(--se-color-text-default);
}

.empty-state-icon {
    width: 3rem;
    height: 3rem;
    border-radius: var(--se-radius-md);
    background: var(--se-color-accent-soft);
    color: var(--se-color-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    margin-bottom: var(--se-space-4);
}

.empty-state-title {
    margin: 0 0 var(--se-space-2);
    font-size: var(--se-text-lg);
    font-weight: 600;
    color: var(--se-color-text-strong);
}

.empty-state-body {
    margin: 0 0 var(--se-space-5);
    max-width: 38ch;
    color: var(--se-color-text-muted);
    line-height: var(--se-line-normal);
}

.empty-state-action {
    display: flex;
    gap: var(--se-space-2);
    align-items: center;
}

/* MS25-α.3 (incremental memo Move 11) — Card primitive. .card is the
   white-surface outline card (chemical-safety overview cards, readiness
   signal cards, the reconciler row chrome). .card--inset is the grey-bg
   sub-form-row variant (affected-persons / reportability / outcome-
   follow-ups blocks). Existing bespoke classes are joined into the
   shared selector so the legacy markup picks up the chrome without a
   Razor sweep; per-consumer layout (display, gap, margin-bottom) stays
   in each consumer's block so the chrome shares but the rhythm doesn't
   flatten. */
.card,
.chemical-safety-card,
.readiness-signal-card {
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
    padding: var(--se-space-5);
    box-shadow: var(--se-shadow-sm);
}

.card--inset,
.reportability-row,
.affected-persons-row,
.outcome-follow-ups-row {
    background: var(--se-color-surface-sunken);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-sm);
    padding: var(--se-space-3) var(--se-space-4);
}

.list-status {
    padding: var(--se-space-4) var(--se-space-5);
    background: var(--se-color-surface-sunken);
    border-radius: var(--se-radius);
    color: var(--se-color-text-muted);
}
.list-status-warning {
    background: var(--se-color-warning-bg);
    border-left: 3px solid var(--se-color-warning-fg);
    color: var(--se-color-warning-fg);
}
.list-status-error {
    background: var(--se-color-danger-bg);
    border-left: 3px solid var(--se-color-danger-fg);
    color: var(--se-color-danger-fg);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--se-space-4);
}

/* MS25-α.2 (incremental memo Move 3) — Data-grid primitive.
   Modern Linear/Vercel/Notion shape: no zebra stripes, no uppercase
   tracked-out header, no cool-cast hover fighting the warm-stone app
   background. Hairline row dividers, small-caps muted header text,
   full-row hover tint in the same warm neutral as the app. Optional
   .data-grid--sticky modifier keeps the thead pinned while a long
   list scrolls; pair with a height-capped scroll container around
   the table for use cases like the AI usage page or any drilldown
   that needs to keep column context while scrolling. */
.data-grid {
    width: 100%;
    border-collapse: collapse;
    background: var(--se-color-surface);
    font-size: var(--se-text-sm);
    color: var(--se-color-text-default);
}
.data-grid th, .data-grid td {
    /* MS25-β.2 — Vertical padding flexes with --se-density. */
    padding: calc(var(--se-space-3) * var(--se-density)) var(--se-space-4);
    border-bottom: 1px solid var(--se-color-border-subtle);
    text-align: left;
}
.data-grid th {
    background: transparent;
    font-weight: 600;
    font-size: var(--se-text-xs);
    color: var(--se-color-text-muted);
    letter-spacing: 0.04em;
    border-bottom: 1px solid var(--se-color-border-default);
    /* deliberately no text-transform — the small-caps + muted color
       carry the header role; uppercase tracked-out felt 2015 */
}
.data-grid tbody tr {
    transition: background-color var(--se-transition-fast);
}
.data-grid tbody tr:hover {
    background: var(--se-color-surface-sunken);
}
.data-grid tbody tr:last-child td {
    border-bottom: none;
}
.data-grid .col-actions { text-align: right; white-space: nowrap; }

.data-grid--sticky thead th {
    position: sticky;
    top: 0;
    background: var(--se-color-surface);  /* opaque so rows don't bleed through */
    z-index: 1;
}

/* M172 — AI-generated summary cell on the /incidents grid. Caps the
   column width + ellipsizes overflow; full text on hover via the
   title attribute. */
.ai-summary-cell {
    display: inline-block;
    max-width: 22rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}
.ai-summary-cell--empty {
    color: #999;
}

.btn-primary {
    background: var(--se-color-accent);
    color: var(--se-color-text-inverse);
    border: none;
    padding: 0.5rem 1rem;
    border-radius: 3px;
    cursor: pointer;
    font-weight: 500;
    transition: background var(--se-transition-fast);
}
.btn-primary:hover:not(:disabled) {
    background: var(--se-color-accent-strong);
}
.btn-primary:hover:not(:disabled) { background: #17304f; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-secondary {
    background: #fff;
    color: #444;
    border: 1px solid #ccc;
    padding: 0.5rem 1rem;
    border-radius: 3px;
    cursor: pointer;
}
.btn-secondary:hover:not(:disabled) { background: #f5f5f5; }

.btn-danger {
    background: #c62828;
    color: #fff;
    border: none;
    padding: 0.5rem 1rem;
    border-radius: 3px;
    cursor: pointer;
}
.btn-danger:hover:not(:disabled) { background: #8b1010; }

.btn-link {
    background: none;
    border: none;
    color: var(--se-color-accent-strong);
    cursor: pointer;
    padding: 0.2rem 0.5rem;
}
.btn-link:hover { text-decoration: underline; }
.btn-danger-link { color: #c62828; }

/* MS25-α.4 (incremental memo Move 8) — Dialog modernisation. Slate
   warm-neutral scrim (no more navy tint fighting the rest of the
   app), .se-radius-lg corner, softer overlay shadow, three size
   variants for the three real use cases. Destructive-confirm
   dialogs (delete confirms, RCA closeout, etc.) get a 3px accent
   top-border via .dialog-card--destructive — same cue as GitHub's
   "are you sure" modals. */
.dialog-scrim {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);   /* slate-900 @ 45% */
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}
.dialog-card {
    background: var(--se-color-surface);
    border-radius: var(--se-radius-lg);
    padding: var(--se-space-6);
    min-width: 400px;
    max-width: 520px;       /* default — form variant */
    /* Cap to viewport so long forms (e.g. Incident with 14 fields)
       don't push the action buttons off-screen — the entire card
       scrolls; users scroll down to reach Cancel/Save. */
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    box-shadow: var(--se-shadow-lg);
}
.dialog-card--confirm {
    min-width: 320px;
    max-width: 24rem;
}
.dialog-card--wide {
    max-width: 48rem;
}
.dialog-card--destructive {
    border-top: 3px solid var(--se-color-accent);
    /* keep the rest of the chrome shared with .dialog-card; the
       top stripe alone is the assertive "you are about to lose
       data" cue. */
}
.dialog-card h2 { margin-top: 0; }
.dialog-message { color: #444; }
.dialog-actions {
    display: flex;
    gap: 0.75rem;
    justify-content: flex-end;
    margin-top: 1.25rem;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 1rem;
}
.form-field label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--se-color-text-strong);
}
.form-field input, .form-field textarea, .form-field select {
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--se-color-border-strong);
    border-radius: var(--se-radius-sm);
    font-family: inherit;
    font-size: 1rem;
    background: var(--se-color-surface);
}
/* MS25 — Explicit border on type=date because some browsers strip the
   surrounding box styling once the native picker overlay claims the
   control. Without this the date input looks unbordered next to the
   text inputs that DO render the outer border. Scott surfaced after
   the MS25-α palette consolidation made the existing #ccc border too
   faint against the new app background. */
.form-field input[type="date"],
.form-field input[type="datetime-local"],
.form-field input[type="time"] {
    border: 1px solid var(--se-color-border-strong);
    background: var(--se-color-surface);
    min-height: 2.4rem;
}
.form-field input:focus, .form-field textarea:focus, .form-field select:focus {
    outline: 2px solid var(--se-color-accent);
    outline-offset: -1px;
    border-color: var(--se-color-accent);
}
.form-field .validation-message {
    color: var(--se-color-danger-fg);
    font-size: 0.85rem;
}

/* MS25 — Inline field-help. [Help("...")] on a domain property
   surfaces as a small `?` chip next to the field's label; click
   opens a popover with the supplied text. Uses HTML-native
   <details>/<summary> for click-toggle so no JS is required.
   Authoring is code-co-located (attribute on the property); see
   se.Shared/Attributes/HelpAttribute.cs. */
.field-help {
    display: inline-block;
    margin-left: 0.35rem;
    position: relative;
    vertical-align: middle;
}
.field-help summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border-radius: 999px;
    background: var(--se-color-border-default);
    color: var(--se-color-text-muted);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    user-select: none;
    transition: background var(--se-transition-fast), color var(--se-transition-fast);
}
.field-help summary::-webkit-details-marker {
    display: none;
}
.field-help summary::marker {
    display: none;
    content: "";
}
.field-help summary:hover {
    background: var(--se-color-border-strong);
    color: var(--se-color-text-default);
}
.field-help[open] summary {
    background: var(--se-color-accent);
    color: var(--se-color-text-inverse);
}
.field-help-popover {
    position: absolute;
    top: 1.5rem;
    left: 0;
    z-index: 50;
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-strong);
    box-shadow: var(--se-shadow-md);
    border-radius: var(--se-radius-md);
    padding: 0.6rem 0.8rem;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--se-color-text-default);
    min-width: 14rem;
    max-width: 24rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
}

/* MS26 follow-up (performance, Slice 3) — EntityListView Virtualize
   placeholder. Renders during the brief moment between Virtualize
   asking for a row range and the ItemsProvider returning it. Same
   visual height as a real row so the scrollbar doesn't jump.
   Subtle shimmer-free skeleton (no animation — Blazor renders this
   briefly enough that animation would be more distracting than
   helpful). */
.entity-row-placeholder {
    opacity: 0.55;
    pointer-events: none;
}
.entity-row-title-skeleton {
    height: 1rem;
    width: 12rem;
    background: var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    margin: 0.5rem 0;
}

/* MS25-α.7 (incremental memo Move 7) — Content skeleton utilities.
   Subtler successor to the bare <p>Loading...</p> branch every list
   + detail page currently renders. Three building blocks:
     .skeleton        base — pulse animation on a token bg
     .skeleton-block  rectangular block (e.g. card preview)
     .skeleton-row    full-width row with internal layout
     .skeleton-line   short bar (heading / value)
   Compose into a list-loading shape: ~5 .skeleton-row, each carrying
   .skeleton-line children at varying widths. Pulses respect
   prefers-reduced-motion. Spinners stay on action buttons (audit-
   packet download, etc.) — anywhere there's no pre-existing layout
   to skeleton-fill. */
@keyframes se-skeleton-pulse {
    0%   { opacity: 0.55; }
    50%  { opacity: 0.85; }
    100% { opacity: 0.55; }
}
.skeleton {
    background: var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    animation: se-skeleton-pulse 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; opacity: 0.7; }
}
.skeleton-list {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-3);
    list-style: none;
    margin: 0;
    padding: 0;
}
.skeleton-row {
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
    padding: var(--se-space-3) var(--se-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}
.skeleton-line {
    background: var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    height: 0.85rem;
    animation: se-skeleton-pulse 1.4s ease-in-out infinite;
}
.skeleton-line--title { width: 60%; height: 1rem; }
.skeleton-line--meta  { width: 30%; height: 0.7rem; }
.skeleton-line--full  { width: 95%; }
.skeleton-block {
    background: var(--se-color-border-subtle);
    border-radius: var(--se-radius-md);
    animation: se-skeleton-pulse 1.4s ease-in-out infinite;
}

/* MS25-α.7 — Screen-reader-only utility for live regions that pair
   with the skeleton (so "Loading…" still announces while the
   visible chrome shows the skeleton). Standard recipe — visually
   hidden but readable by AT. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* MS26 follow-up — RiskHeatMap shape. The component (M219, used by
   HazardRegister) renders an inline-SVG matrix with class names on
   each <text> element, but had zero CSS rules — so SVG text
   inherited the body font-size (16px) and exploded against the
   viewBox's user-space coordinates (cells are 60×46 user units).
   Scott surfaced via screenshot: "Almost certain" / "Likely" /
   "Possible" axis labels rendered as huge overlapping text.

   Treatment: explicit font-size in user-space units on every text
   class (SVG inherits these via the SVG inheritance tree, not the
   HTML body); container max-width so the SVG scales gracefully on
   narrow screens; figure / caption / empty-state in tokenised colors. */
.risk-heatmap {
    margin: 0 0 1.5rem;
    max-width: 100%;
}
.risk-heatmap-title {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--se-color-text-strong);
    margin: 0 0 0.5rem;
}
.risk-heatmap-empty {
    color: var(--se-color-text-muted);
    font-style: italic;
    padding: 0.6rem 0;
}
.risk-heatmap-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 720px;
    font-family: inherit;
}
.risk-heatmap-axis-label {
    font-size: 11px;
    fill: var(--se-color-text-default);
    font-weight: 500;
}
.risk-heatmap-axis-title {
    font-size: 12px;
    fill: var(--se-color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.risk-heatmap-count {
    font-size: 16px;
    fill: var(--se-color-text-strong);
    font-weight: 700;
}
.risk-heatmap-score {
    font-size: 9px;
    fill: var(--se-color-text-muted);
}
.risk-heatmap-cell {
    transition: opacity var(--se-transition-fast);
}
.risk-heatmap-cell:hover {
    opacity: 0.85;
}

/* MS26 follow-up — CitationPicker sub-field shape. The picker
   wraps a DocumentPicker, two inline labelled inputs (Page +
   Paragraph anchor), and a block textarea (Excerpt text). The
   .citation-picker-fields children used `label.inline` with no
   matching CSS rules, so browser-default rendering shoved labels
   to whatever width their text took and the input boxes didn't
   line up across rows. Scott surfaced via screenshot on the
   Obligations Citation editor — wanted "text fields lined up"
   with "labels left justified for these sorts of components".

   Treatment: 2-column grid (fixed label column + flex input
   column). Same pattern future composite widgets can adopt by
   inheriting `.citation-picker-fields label.inline` semantics. */
.citation-picker-fields {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
}
.citation-picker-fields label.inline {
    display: grid;
    grid-template-columns: 9rem 1fr;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--se-color-text-strong);
    margin: 0;
}
.citation-picker-fields label.inline input {
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--se-color-border-strong);
    border-radius: var(--se-radius-sm);
    font-family: inherit;
    font-size: 1rem;
    background: var(--se-color-surface);
    width: 100%;
    box-sizing: border-box;
    font-weight: 400;
}
.citation-picker-fields label.inline input:focus {
    outline: 2px solid var(--se-color-accent);
    outline-offset: -1px;
    border-color: var(--se-color-accent);
}
.citation-picker-excerpt {
    margin-top: 0.5rem;
}

/* MS25 — MultiSelectPicker shape. The component (used by
   PermissionKeyPicker / IndustryPacksPicker / RolePicker /
   DepartmentMultiPicker / JobTitlePicker / etc.) markup
   carried .multi-select-* class names since ADR-18 / M41 but
   never had any matching CSS, so it rendered as a default-
   browser <ul> with bullets + a single label-line concatenating
   the item name and description with no whitespace separator.
   Scott surfaced on Edit Role: "Approve corpus documentsAdmin-
   tier permission..." with the checkbox standalone above the
   label. Now: bullets dropped, checkbox aligned inline with
   the first line of the label, name + description stacked
   inside the label as two clear lines. */
.multi-select-picker {
    margin-bottom: 1rem;
}
.multi-select-label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--se-color-text-strong);
    margin-bottom: 0.45rem;
    display: block;
}
.multi-select-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface);
    max-height: 22rem;
    overflow-y: auto;
    /* 2026-05-23 — Defensive: bind the list to its container width so
       even if a sibling form widget overflows horizontally (Location-
       Picker's address input was the trigger; reverse-geocoded
       addresses run ~80+ chars), this list doesn't get pushed off
       the visible viewport. width:100% + min-width:0 lets the flex
       cross-axis honour the parent column's track width rather than
       expanding to fit item content. */
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}
.multi-select-item {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.55rem 0.75rem;
    border-bottom: 1px solid var(--se-color-border-subtle);
}
.multi-select-item:last-child {
    border-bottom: none;
}
.multi-select-item:hover {
    background: var(--se-color-surface-sunken);
}
.multi-select-item input[type="checkbox"] {
    margin: 0.22rem 0 0 0;
    accent-color: var(--se-color-accent);
    cursor: pointer;
    flex-shrink: 0;
}
.multi-select-item label {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    cursor: pointer;
    flex: 1;
    font-weight: 400;
    color: inherit;
}
.multi-select-item-label {
    font-weight: 500;
    color: var(--se-color-text-strong);
    font-size: 0.92rem;
}
.multi-select-item-description {
    font-size: 0.8rem;
    color: var(--se-color-text-muted);
    line-height: 1.4;
}
.multi-select-empty {
    color: var(--se-color-text-muted);
    font-style: italic;
    padding: 0.75rem;
}

/* MS25 — Boolean Yes / No radio pair shape. Renders inline + tight
   so it visually reads as a single grouped control (the way the
   text inputs do as a single bordered box) rather than two
   competing-equal-weight labels. Used by DynamicAddFields'
   IsBoolean branch + FormFieldAutoSave's IsBooleanType branch. */
.form-field.form-field-boolean {
    border: none;
    padding: 0;
}
.form-field.form-field-boolean legend {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--se-color-text-strong);
    margin-bottom: 0.3rem;
    padding: 0;
}
.form-field-boolean-option {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-right: 1.25rem;
    font-size: 0.95rem;
    color: var(--se-color-text-default);
    cursor: pointer;
}
.form-field-boolean-option input[type="radio"] {
    accent-color: var(--se-color-accent);
    cursor: pointer;
}
/* Edit-form variant: rendered inside FormFieldAutoSave's wrapper. */
.form-field-autosave-boolean {
    display: flex;
    gap: 1.25rem;
    align-items: center;
    padding: 0.4rem 0;
}
.form-field-autosave-boolean label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 400;
    font-size: 0.95rem;
    cursor: pointer;
}
.form-field-autosave-boolean input[type="radio"] {
    accent-color: var(--se-color-accent);
    cursor: pointer;
}

/* M272 (MS22 follow-up) — `<label class="block">` is used in ~14
   editor / picker / dialog components (WitnessStatementsEditor,
   AffectedPersonsEditor, HazardCandidateReconciler, etc.) as a
   wrapping label that should stack its child input below the label
   text. Originally a Tailwind-style utility from earlier iterations;
   no CSS rule actually defined the layout. Without it, labels and
   inputs render inline, which Scott surfaced in the marketing-video
   review (Approve Hazard Candidate dialog had Title + Description +
   Site labels jammed next to their inputs). Mirrors the .form-field
   shape so the two patterns produce visually identical output. */
label.block {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 1rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: #555;
}
label.block input,
label.block textarea,
label.block select {
    padding: 0.5rem;
    border: 1px solid #ccc;
    border-radius: 3px;
    font-family: inherit;
    font-size: 1rem;
    color: #0f172a;
}
label.block input:focus,
label.block textarea:focus,
label.block select:focus {
    outline: 2px solid var(--se-color-accent);
    outline-offset: -1px;
    border-color: var(--se-color-accent);
}

.form-error {
    padding: 0.5rem 0.75rem;
    background: #ffebee;
    border-left: 3px solid #c62828;
    color: #8b1010;
    margin-bottom: 1rem;
    border-radius: 3px;
}

.form-hint-attention {
    padding: 0.5rem 0.75rem;
    background: #fef3c7;
    border-left: 3px solid #d97706;
    color: #92400e;
    margin-bottom: 1rem;
    border-radius: 3px;
}

/* ADR-21 / M48-β — PDF.js viewer + side-by-side review layout. */
.extraction-run-review-layout {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}
.extraction-run-review-pdf {
    flex: 1 1 50%;
    min-width: 0;
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
}
.extraction-run-review-candidates.with-pdf {
    flex: 1 1 50%;
    min-width: 0;
}
.extraction-run-review-candidates.full-width {
    flex: 1 1 100%;
}
@media (max-width: 1100px) {
    .extraction-run-review-layout {
        flex-direction: column;
    }
    .extraction-run-review-pdf {
        position: static;
        max-height: none;
    }
}

.source-pdf-viewer {
    border: 1px solid #d4d4d4;
    border-radius: 4px;
    background: #f5f5f5;
}
.source-pdf-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    background: #ececec;
    border-bottom: 1px solid #d4d4d4;
    border-radius: 4px 4px 0 0;
    font-size: 0.9rem;
}
.source-pdf-page-input {
    width: 4rem;
    padding: 0.15rem 0.35rem;
    border: 1px solid #b6b6b6;
    border-radius: 3px;
    font-size: 0.9rem;
    text-align: center;
}
.source-pdf-page-indicator {
    flex: 1;
    text-align: center;
}
.source-pdf-canvas-container {
    padding: 0.75rem;
    overflow: auto;
    text-align: center;
}
.source-pdf-canvas-container canvas {
    background: #fff;
    max-width: 100%;
}
.source-pdf-canvas-stack {
    position: relative;
    display: inline-block;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.source-pdf-canvas-overlay {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    background: transparent;
}
.source-pdf-error {
    padding: 0.75rem;
    color: #8b1010;
}
/* Click-to-scroll: candidate page-number rendered as a button when a
   side-by-side PDF viewer is mounted. Looks like inline text by
   default; visibly underlined on hover so the affordance is
   discoverable without competing with the candidate's title. */
.extraction-run-page-link {
    background: none;
    border: none;
    padding: 0;
    color: inherit;
    cursor: pointer;
    font: inherit;
    text-decoration: none;
}
.extraction-run-page-link:hover {
    text-decoration: underline;
    color: var(--se-color-accent-strong);
}

/* ADR-17 / M49.1 — Reportability matrix. Stacked rows with the flag
   inline at the top of each row, optional jurisdiction + audit stamp
   in the middle, and a compact notes textarea below. */
.reportability-matrix {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.reportability-matrix-label {
    font-weight: 600;
}
/* MS25-α.3 — chrome (bg / border / radius / padding) joins .card--inset
   above. Layout (display / gap) is per-consumer. */
.reportability-row {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}
.reportability-row-flag {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.reportability-row-flag label {
    margin: 0;
    cursor: pointer;
}
.reportability-stamp {
    margin: 0;
    font-size: 0.8rem;
    color: #595959;
    font-style: italic;
}
.reportability-notes {
    width: 100%;
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.35rem 0.5rem;
    font-family: inherit;
    resize: vertical;
}
.reportability-jurisdiction {
    width: 100%;
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-size: 0.95rem;
}

/* ADR-17 / M50.3 — AffectedPersons repeating sub-record editor. */
.affected-persons-editor {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.affected-persons-label {
    font-weight: 600;
}
.affected-persons-empty {
    margin: 0;
    color: #595959;
    font-style: italic;
}
.affected-persons-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
/* MS25-α.3 — chrome joins .card--inset above. */
.affected-persons-row {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}
.affected-persons-row-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.affected-persons-row-number {
    font-weight: 600;
    color: #595959;
}
.affected-persons-remove {
    color: #c62828;
}
.affected-persons-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.6rem;
}
.affected-persons-fields label.block {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: #595959;
    gap: 0.2rem;
}
.affected-persons-fields label.block input,
.affected-persons-fields label.block select {
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-size: 0.95rem;
    color: initial;
}
.affected-persons-add {
    align-self: flex-start;
}

/* M335 — guided establishment setup nudge (above the edit form). Helpful
   setup tone, distinct from the amber warning banners. Self-hides via the
   component once the seed placeholders are replaced. */
.establishment-setup-guidance {
    margin: 0 0 1rem;
    padding: 0.85rem 1rem;
    background: #e8f0fe;
    border-left: 4px solid #1a73e8;
    color: #1f3a5f;
    border-radius: 4px;
}
.establishment-setup-guidance h3 {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}
.establishment-setup-guidance p {
    margin: 0 0 0.5rem;
}
.establishment-setup-guidance ul {
    margin: 0;
    padding-left: 1.25rem;
}
.establishment-setup-guidance li {
    margin: 0.2rem 0;
}

/* ADR-19 / M51 — Corrective actions sub-section + banner + create form. */
.incident-task-list-banner {
    margin: 0.5rem 0 0.75rem;
    padding: 0.6rem 0.75rem;
    background: #fff8e1;
    border-left: 3px solid #f9a825;
    color: #5d4037;
    border-radius: 3px;
}
.incident-task-list-create {
    margin-top: 0.75rem;
}
.incident-task-list-form {
    border: 1px solid #d4d4d4;
    border-radius: 4px;
    padding: 0.75rem;
    background: #fafafa;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.incident-task-list-form label.block {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: #595959;
    gap: 0.2rem;
}
.incident-task-list-form input[type="text"],
.incident-task-list-form input[type="date"],
.incident-task-list-form textarea {
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-size: 0.95rem;
    color: initial;
    font-family: inherit;
}
.incident-task-list-form-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.incident-task-list-due {
    color: #595959;
    font-size: 0.85rem;
    margin-left: 0.4rem;
}
.incident-task-list-assignees {
    color: #595959;
    font-size: 0.85rem;
    margin-left: 0.4rem;
    font-style: italic;
}
.incident-task-list-other-heading {
    margin-top: 1.25rem;
}
.incident-task-list-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* ADR-23 / M52 — Per-outcome follow-ups editor + supporting bits. */
.outcome-follow-ups-editor {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.outcome-follow-ups-label {
    font-weight: 600;
}
.outcome-follow-ups-empty,
.outcome-follow-ups-exhausted {
    margin: 0;
    color: #595959;
    font-style: italic;
    font-size: 0.9rem;
}
.outcome-follow-ups-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
/* MS25-α.3 — chrome joins .card--inset above. */
.outcome-follow-ups-row {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}
.outcome-follow-ups-row-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.outcome-follow-ups-row-number {
    font-weight: 600;
    color: #595959;
}
.outcome-follow-ups-remove {
    color: #c62828;
}
.outcome-follow-ups-fields {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.outcome-follow-ups-fields label.block {
    display: flex;
    flex-direction: column;
    font-size: 0.85rem;
    color: #595959;
    gap: 0.2rem;
}
.outcome-follow-ups-fields label.inline {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
    color: initial;
}
.outcome-follow-ups-fields input[type="checkbox"] {
    margin: 0;
}
.outcome-follow-ups-fields select,
.outcome-follow-ups-fields textarea {
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-size: 0.95rem;
    color: initial;
    font-family: inherit;
}
.outcome-follow-ups-feeds-hint {
    color: #595959;
    font-size: 0.8rem;
    margin-left: 0.3rem;
}
.outcome-follow-ups-add {
    align-self: flex-start;
}

/* ADR-23 / M55 — /quick mobile capture surface. Touch-optimised:
   bigger tap targets, single-column layout, large text inputs,
   bottom-anchored submit button. */
.quick-page {
    max-width: 540px;
    margin: 0 auto;
    padding: 1rem;
    box-sizing: border-box;
}
.quick-page-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.quick-page-header h1 {
    margin: 0;
    font-size: 1.4rem;
}
.quick-back {
    color: var(--se-color-text-muted);
    text-decoration: none;
    font-size: 0.95rem;
    padding: 0.25rem 0.5rem;
    margin-left: -0.5rem;
}
.quick-back:hover {
    text-decoration: underline;
}
.quick-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.quick-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.quick-field-label {
    font-size: 0.85rem;
    color: #595959;
    font-weight: 600;
}
.quick-field select,
.quick-field input[type="text"],
.quick-field input[type="number"],
.quick-field textarea {
    border: 1px solid #c8c8c8;
    border-radius: 4px;
    padding: 0.6rem 0.7rem;
    font-size: 1rem;
    font-family: inherit;
    color: initial;
    min-height: 2.5rem;
    box-sizing: border-box;
}
.quick-field textarea {
    resize: vertical;
    min-height: 4rem;
}
.quick-evidence input[type="file"] {
    font-size: 0.95rem;
    padding: 0.4rem 0;
}
.quick-hint {
    margin: 0.25rem 0 0;
    color: #595959;
    font-size: 0.85rem;
}
.quick-submit {
    margin-top: 0.75rem;
    padding: 0.85rem 1rem;
    font-size: 1rem;
    width: 100%;
}
.quick-success {
    margin: 0.5rem 0 0;
    padding: 0.6rem 0.75rem;
    background: #e8f5e9;
    border-left: 3px solid #2e7d32;
    color: #1b5e20;
    border-radius: 3px;
}
.quick-loading,
.quick-empty {
    color: #595959;
    text-align: center;
    margin: 2rem 0;
}

/* Status badge convention — used by every cell-display + lifecycle-widget
   badge across the app (DocumentApprovalStatusBadge, HazardSourceBadge,
   IncidentLifecycleWidget, WorkflowTaskStatusBadge, etc.). The base
   .status class is the pill shape; .status-{lowercase-state} sets the
   colour pair. Mirrors se.Management's same-named convention so customers
   and operators see identical visual language. */

.status {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    border-radius: 9999px;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}

/* MS25-α — Status-pill consolidation. Before this pass, ~25
   `.status-*` variants existed across the file with 4 different
   greys for "neutral", 3 reds for "danger", 2 oranges for "warning"
   — visual noise + maintenance debt every time a state was added.
   Consolidation rule: every status pill maps onto one of 5 semantic
   token pairs (--se-color-{success,warning,danger,info,neutral}-
   {bg,fg}). Five pairs is the design-system canon (Linear, Vercel,
   Stripe all settle here). The hazard-control hierarchy ramp
   further down the file is the one intentional exception — it's a
   domain-specific 5-step gradient, not a status. */

/* ADR-29 / M58 — Hazard source discriminator. */
.status-investigation { background: var(--se-color-info-bg); color: var(--se-color-info-fg); }
.status-standalone    { background: var(--se-color-neutral-bg); color: var(--se-color-neutral-fg); }

/* ADR-29 / M60 — Risk-matrix tier badges. Low → Extreme maps onto
   success → warning → warning → danger; unassessed = neutral. The
   "tier-high" orange tone collapses into warning rather than
   carrying its own colour — Cority/Intelex use the same 4-step
   green/amber/red convention. */
.status-tier-low        { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-tier-medium     { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); }
.status-tier-high       { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); font-weight: 700; }
.status-tier-extreme    { background: var(--se-color-danger-bg); color: var(--se-color-danger-fg); }
.status-tier-unassessed { background: var(--se-color-neutral-bg); color: var(--se-color-neutral-fg); }

/* ADR-29 / M61 — HazardControl lifecycle. Planned neutral, InPlace
   info (ambitious), Verified success, Removed neutral (terminal
   state needs to read as "done", not "danger"). */
.status-planned  { background: var(--se-color-neutral-bg); color: var(--se-color-neutral-fg); }
.status-inplace  { background: var(--se-color-info-bg); color: var(--se-color-info-fg); }
.status-verified { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-removed  { background: var(--se-color-neutral-bg); color: var(--se-color-neutral-fg); font-style: italic; }

/* ADR-29 / M61 — HazardControl Kind. Mirrors the hazard-control
   hierarchy ramp below — Eliminate/Substitute are preferred
   (success), Engineering/Administrative intermediate (info/warning),
   PPE last-resort (warning, emphasised). */
.status-controlkind-eliminate      { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-controlkind-substitute     { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-controlkind-engineering    { background: var(--se-color-info-bg); color: var(--se-color-info-fg); }
.status-controlkind-administrative { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); }
.status-controlkind-ppe            { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); font-weight: 700; }

/* ADR-32 / M76 + M77 — HazardCandidate lifecycle + ExtractStatus on
   Obligation / PolicyClause. Pending/Proposed → warning,
   Approved → success, Rejected → danger. */
.status-pending  { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); }
.status-approved { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-rejected { background: var(--se-color-danger-bg); color: var(--se-color-danger-fg); }
.status-proposed { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); }

/* ADR-58 / M164 (Phase 3L-α) — Inspection-readiness. */
.status-pass           { background: var(--se-color-success-bg); color: var(--se-color-success-fg); }
.status-caution        { background: var(--se-color-warning-bg); color: var(--se-color-warning-fg); }
.status-blocked        { background: var(--se-color-danger-bg); color: var(--se-color-danger-fg); }
.status-not-applicable { background: var(--se-color-neutral-bg); color: var(--se-color-neutral-fg); }

/* ADR-58 / M164 — Inspection-readiness page chrome. List + detail
   page styles. Card-per-signal layout with header / metrics body /
   drill-through footer. */
.readiness-page {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
/* .readiness-page-header now picks up its layout from the shared
   .page-header rule above (MS25-β). The duplicate block that lived
   here through M179 is gone — kept the class on the markup as a
   compatibility shim. */
.readiness-meta {
    color: #4b5563;
    font-size: 0.9rem;
}
.readiness-overall {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem;
    background: #f9fafb;
    border-radius: 0.5rem;
}
.readiness-signals-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}
/* MS25-α.3 — chrome (bg / border / radius / padding / shadow) joins
   .card above. Layout (display / gap) is per-consumer. */
.readiness-signal-card {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}
.readiness-signal-card header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.readiness-signal-card h2 {
    margin: 0;
    font-size: 1rem;
}
.readiness-signal-card dl {
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.25rem 0.75rem;
    font-size: 0.875rem;
}
.readiness-signal-card dt {
    color: #6b7280;
}
.readiness-signal-card dd {
    margin: 0;
}
.readiness-signal-card .drill-through {
    font-size: 0.875rem;
    margin-top: auto;
}
.readiness-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.readiness-list-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border: 1px solid #e5e7eb;
    border-radius: 0.5rem;
    background: #fff;
}
.readiness-list-row a {
    font-weight: 600;
}

/* M180 — Bulk-action strip. Surfaces only when ≥ 1 row is selected;
   "Select all visible" checkbox always renders so admin can one-click
   select the currently-filtered + searched view. */
.readiness-list-bulk-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.4rem 0;
    font-size: 0.85rem;
    color: #444;
}
.readiness-list-bulk-select-all {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.readiness-list-bulk-action {
    font-size: 0.85rem;
    padding: 0.35rem 0.8rem;
}
.readiness-list-row-left {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.readiness-list-row-select {
    cursor: pointer;
}

/* M179 — Trend chip + right-side row container. Trend chip sits to
   the left of the status badge so admin's eye reads "Blocked · was
   Blocked 5 days ago" as a unit. ContinuouslyBlocked = red
   accent (chronic problem); RecentlyBlocked = amber accent (recovered). */
.readiness-list-row-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.readiness-trend-chip {
    font-size: 0.75rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-weight: 500;
}
.readiness-trend-chip--continuouslyblocked {
    background: var(--se-color-danger-bg);
    color: var(--se-color-danger-fg);
}
.readiness-trend-chip--recentlyblocked {
    background: var(--se-color-warning-bg);
    color: var(--se-color-warning-fg);
}

/* M177 — Readiness list controls (summary strip + filter chips +
   search). Sits between the page header and the row list; gives
   the admin at-a-glance fleet posture + a one-click narrow-by-
   status. */
.readiness-list-controls {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0.75rem 0 1rem;
}
.readiness-summary-counts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}
.readiness-summary-pill {
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    font-size: 0.85rem;
}
.readiness-summary-pill strong {
    font-weight: 700;
}
.readiness-list-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    justify-content: space-between;
}
/* MS25-α.6 (incremental memo Move 10) — Filter-chip primitive.
   .chip-filter is the canonical filter-chip surface (toggleable
   facet pills on lists / dashboards / reconcilers). The two pre-
   existing implementations (.readiness-filter-chip + .reconciler-
   filter-chip) are joined-selector aliases so legacy markup picks
   up the chrome without a Razor sweep. .chip-filter--active is the
   selected state; .chip-filter-count is the nested numeric pill. */
.chip-filter,
.readiness-filter-chip,
.reconciler-filter-chip {
    background: var(--se-color-surface-sunken);
    color: var(--se-color-text-default);
    border: 1px solid var(--se-color-border-default);
    padding: var(--se-space-1) var(--se-space-3);
    border-radius: var(--se-radius-pill);
    font-size: var(--se-text-sm);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: var(--se-space-2);
    transition: background-color var(--se-transition-fast),
                border-color var(--se-transition-fast);
}
.chip-filter:hover,
.readiness-filter-chip:hover,
.reconciler-filter-chip:hover {
    background: var(--se-color-border-subtle);
    border-color: var(--se-color-border-strong);
}
.chip-filter--active,
.readiness-filter-chip-active,
.reconciler-filter-chip-active {
    background: var(--se-color-accent);
    color: var(--se-color-text-inverse);
    border-color: var(--se-color-accent-strong);
    font-weight: 500;
}
.chip-filter--active:hover,
.readiness-filter-chip-active:hover,
.reconciler-filter-chip-active:hover {
    background: var(--se-color-accent-strong);
    border-color: var(--se-color-accent-strong);
}
.chip-filter-count,
.reconciler-filter-chip-count {
    background: rgba(255, 255, 255, 0.25);
    color: inherit;
    border-radius: var(--se-radius-pill);
    padding: 0 var(--se-space-2);
    font-size: var(--se-text-xs);
    font-weight: 600;
    min-width: 1.5rem;
    text-align: center;
}
.chip-filter:not(.chip-filter--active) .chip-filter-count,
.reconciler-filter-chip:not(.reconciler-filter-chip-active) .reconciler-filter-chip-count {
    background: var(--se-color-border-subtle);
    color: var(--se-color-text-muted);
}
/* Readiness's "chip" carried its count inline (no pill) — that
   shape stays as a thin override on the existing class so its
   visual rhythm doesn't change. */
.readiness-filter-chip-count {
    margin-left: var(--se-space-2);
    opacity: 0.8;
    font-weight: 500;
}

/* ADR-117 / M384 — Document library (the single /documents surface). */
.documents-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--se-space-4);
}
.documents-headline {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-2);
    margin: var(--se-space-4) 0;
}
.documents-search {
    margin-bottom: var(--se-space-3);
    max-width: 28rem;
}
.documents-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-5);
    margin-bottom: var(--se-space-4);
}
.documents-filter-group {
    border: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--se-space-2);
}
.documents-filter-group legend {
    font-size: var(--se-text-xs);
    font-weight: 600;
    color: var(--se-color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-right: var(--se-space-2);
    padding: 0;
}
.documents-row-actions {
    display: flex;
    align-items: center;
    gap: var(--se-space-2);
    white-space: nowrap;
}
.documents-rows tr.documents-row-overdue td:first-child {
    box-shadow: inset 3px 0 0 0 var(--se-color-danger-fg);
}
.documents-rows tr.documents-row-attention td:first-child {
    box-shadow: inset 3px 0 0 0 var(--se-color-warning-fg, #b8860b);
}

.readiness-filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-2);
}
.readiness-list-search {
    border: 1px solid #d0d5dc;
    border-radius: 0.35rem;
    padding: 0.3rem 0.6rem;
    font-size: 0.85rem;
    min-width: 14rem;
}

/* M178 — Signal category sections on the readiness detail page.
   Each category renders as its own <section> with a heading + sub-
   grid. Categories surface in a fixed order (Forms & Filings →
   Open Work → Recent Activity → Coverage → Other); empty categories
   are omitted upstream so the page doesn't render blank headings. */
.readiness-signals-category {
    margin-top: 1.5rem;
}
.readiness-signals-category:first-of-type {
    margin-top: 0;
}
.readiness-signals-category-heading {
    font-size: 0.9rem;
    font-weight: 600;
    color: #555;
    margin: 0 0 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* M177 — Signal-card severity prominence. Blocked cards carry a
   thicker left border in the inspector-visible red so the eye lands
   on them first when the grid is dense. Other tiers use the existing
   neutral card chrome. */
.readiness-signal-card--blocked {
    border-left: 4px solid #b91c1c;
    padding-left: calc(1rem - 4px);
}
.readiness-signal-card--caution {
    border-left: 4px solid #b45309;
    padding-left: calc(1rem - 4px);
}

/* ADR-33 / M77 — Reconciler shell + row layout. The shell is the page-
   level container; rows render as cards with a left content column +
   a right action column. Empty / loading / error states sit between
   the chips and the row list. */
.reconciler-shell {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.reconciler-shell-header h1 {
    margin: 0 0 0.25rem 0;
}
.reconciler-shell-help {
    color: #4b5563;
    font-size: 0.9rem;
    margin: 0 0 0.5rem 0;
    max-width: 60ch;
}
.reconciler-shell-status,
.reconciler-shell-empty {
    color: #6b7280;
    font-style: italic;
    padding: 1rem 0;
}
.reconciler-shell-error {
    color: #b91c1c;
}
.reconciler-dialog {
    max-width: 32rem;
}
.reconciler-dialog-subject {
    color: #4b5563;
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

/* Filter chips at the top of the reconciler. Active chip carries
   slightly heavier styling; inactive chips are flatter so the
   active chip reads as the focus. */
/* MS25-α.6 — .reconciler-filter-chip + .reconciler-filter-chip-active +
   .reconciler-filter-chip-count chrome moved into the joined .chip-filter
   rule above. Only the container layout stays per-consumer (it has a
   bottom-border the canonical primitive doesn't). */
.reconciler-filter-chips {
    display: flex;
    gap: var(--se-space-2);
    flex-wrap: wrap;
    padding: var(--se-space-1) 0 var(--se-space-2) 0;
    border-bottom: 1px solid var(--se-color-border-default);
}

/* Row list — each row is a card. Layout is two columns: main content
   (title + body + citation) on the left, actions (status pill + buttons)
   right-aligned. Confidence-tier classes (high/medium/low) and status
   classes (pending/approved/rejected) compose on the row itself. */
.reconciler-row-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* M175 — AI corrective-action suggestion sub-panel on the RCA
   conclude form. Lives between the root-cause + recommendations
   textareas as an inline picker. */
.rca-session-ai-suggestions {
    margin: 0.75rem 0;
    padding: 0.5rem 0.75rem;
    background: #f8f9fb;
    border: 1px dashed #d0d5dc;
    border-radius: 4px;
}
.rca-session-ai-suggestions-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.85rem;
}
.rca-session-ai-suggest-hint {
    color: #888;
    font-size: 0.8rem;
}
.rca-session-ai-suggest-note {
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
    color: #555;
}
.rca-session-ai-suggestion-list {
    list-style: none;
    padding: 0;
    margin: 0.5rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.rca-session-ai-suggestion {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.9rem;
}
.rca-session-ai-suggestion-badge {
    font-size: 0.7rem;
    text-transform: uppercase;
    flex-shrink: 0;
}
.rca-session-ai-suggestion-text {
    flex: 1;
}
/* Hierarchy-of-controls badge palette. Most-preferred control tier
   (Eliminate) renders darkest; PPE renders lightest — visual cue
   that strong controls outrank weak ones at a glance.
   MS25-α — re-pointed from navy ramp to neutral zinc ramp so the
   only saturated colour on the surface is the orange brand
   accent. Hierarchy stays a domain-specific 5-step gradient. */
.status-hierarchy-eliminate     { background: #18181b; color: #ffffff; }   /* zinc-900 */
.status-hierarchy-substitute    { background: #3f3f46; color: #ffffff; }   /* zinc-700 */
.status-hierarchy-engineering   { background: #71717a; color: #ffffff; }   /* zinc-500 */
.status-hierarchy-administrative{ background: #d4d4d8; color: #18181b; }   /* zinc-300 */
.status-hierarchy-ppe           { background: #f4f4f5; color: #71717a; }   /* zinc-100 */

/* M174 — Split-by-source sections in the hazard reconciler. Stacked
   sections, each with its own heading + row list. The headings act
   as visual separators between SDS-sourced and incident-sourced
   candidates while the per-section <ul> keeps semantic grouping. */
.reconciler-source-section {
    margin-top: 1rem;
}
.reconciler-source-section:first-of-type {
    margin-top: 0;
}
.reconciler-source-section-heading {
    font-size: 0.95rem;
    font-weight: 600;
    color: #444;
    margin: 0 0 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.reconciler-row-source-line {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    margin-bottom: 0.5rem;
    font-size: 0.85rem;
}
.reconciler-row-source-badge {
    font-size: 0.75rem;
    text-transform: uppercase;
}
.status-source-sds {
    background: var(--se-color-info-bg);
    color: var(--se-color-info-fg);
}
.status-source-incident {
    background: #fff0e3;
    color: #8a4a14;
}
.reconciler-row-drillthrough {
    color: var(--se-color-accent-strong);
    text-decoration: none;
}
.reconciler-row-drillthrough:hover {
    text-decoration: underline;
}
.reconciler-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 1rem;
    padding: 0.75rem 1rem;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 0.5rem;
    transition: opacity 0.15s ease;
}
.reconciler-row-main {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: 0;
}
.reconciler-row-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.reconciler-row-title {
    font-weight: 600;
    color: #111827;
    flex-shrink: 1;
}
.reconciler-row-body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.reconciler-row-description {
    color: #4b5563;
    font-size: 0.9rem;
    margin: 0;
}
.reconciler-row-suggested-codes {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}
.reconciler-row-suggested-codes code {
    background: #f3f4f6;
    color: #1f2937;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    font-size: 0.8rem;
}
.reconciler-row-citation {
    font-size: 0.85rem;
    color: #6b7280;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.reconciler-row-citation-anchor {
    color: #4b5563;
    font-weight: 500;
}
.reconciler-row-citation-excerpt {
    margin: 0;
    padding: 0.4rem 0.75rem;
    border-left: 3px solid #d1d5db;
    color: #4b5563;
    font-style: italic;
    background: #f9fafb;
    font-size: 0.85rem;
}

.reconciler-row-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
}
.reconciler-row-action-buttons {
    display: flex;
    gap: 0.4rem;
}
.reconciler-row-terminal-note {
    color: #6b7280;
    font-size: 0.8rem;
    font-style: italic;
    text-align: right;
    margin: 0;
    max-width: 16rem;
}

/* ADR-33 Decision D — Confidence-tier visual treatment. Subdued styling
   on lower-confidence rows so reviewers can tell at a glance which
   suggestions are confident vs hedged. Thresholds match M75's chip
   styling (>=0.7 high, >=0.4 medium, <0.4 low). High path looks
   standard; medium + low rows fade incrementally. */
.reconciler-row-high {
    /* High confidence: standard treatment, no special styling. */
}
.reconciler-row-medium {
    background: #fafafa;
}
.reconciler-row-medium .reconciler-row-title {
    color: #374151;
    font-weight: 500;
}
.reconciler-row-low {
    opacity: 0.78;
    background: #fafafa;
}
.reconciler-row-low .reconciler-row-title {
    color: #4b5563;
    font-weight: 500;
    font-style: italic;
}

/* ADR-33 Decision D — Confidence badge. Same three-tier scheme. Sits
   alongside the row title in the header. Low-confidence rendering
   uses italic + lower opacity per Decision E's "advisory only" posture. */
.confidence-badge {
    display: inline-block;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.02em;
}
.confidence-badge-high {
    background: var(--se-color-success-bg);
    color: var(--se-color-success-fg);
}
.confidence-badge-medium {
    background: var(--se-color-warning-bg);
    color: var(--se-color-warning-fg);
}
.confidence-badge-low {
    background: var(--se-color-danger-bg);
    color: var(--se-color-danger-fg);
    font-style: italic;
}

/* ADR-33 Decision E — Un-grounded warning indicator. Small ⚠ icon
   that signals "AI claimed an excerpt the verifier couldn't locate".
   Advisory only — doesn't block actions; tooltip explains the gap. */
.grounded-indicator-warning {
    display: inline-block;
    color: var(--se-color-warning-fg);
    background: var(--se-color-warning-bg);
    padding: 0 0.35rem;
    border-radius: 0.25rem;
    font-size: 0.85rem;
    cursor: help;
}

/* ADR-33 / M79 — Source-badge palette for catalog list views. Used by
   HazardCategorySourceBadge + CategorySourceBadge +
   RcaSessionTemplateSourceBadge. Three canonical variants:
     - standard / universal — neutral grey (universal seeded entries)
     - pack — pack-tagged seed (only seeds when the matching IndustryPack
       is ticked on TenantSettings); rendered in a distinct blue so admins
       can pick out pack-driven entries from the universal core
     - custom — tenant-authored entry; rendered in a calm green so admins
       can pick out their own additions
   Visual treatment is calibrated to be informative without competing
   with the row's primary content. */
.source-badge {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 0.25rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: help;
}
.source-badge-standard,
.source-badge-universal {
    background: #f3f4f6;
    color: #4b5563;
    border: 1px solid #e5e7eb;
}
.source-badge-pack {
    background: var(--se-color-info-bg);
    color: var(--se-color-info-fg);
    border: 1px solid #93c5fd;
}
.source-badge-custom {
    background: var(--se-color-success-bg);
    color: var(--se-color-success-fg);
    border: 1px solid #6ee7b7;
}

/* M239 / ADR-92 — Stacked-row entity list shape. Replaces the
   data-grid table render in EntityListView. Each row carries a
   status/severity/timestamp head strip, a prominent title, a
   3-line-clamped narrative, and up to 4 chip metadata items.
   Whole row is clickable (role=link / tabindex=0 → EditNavigateTo);
   the ⋮ actions menu lives top-right via a <details> element.
   The pre-existing .status badges + .status-{state} variants above
   are reused as-is — this block adds only the row chrome. */
.entity-row-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}
/* MS25-α.5 (incremental memo Move 9) — Entity-row tightening + token
   sweep. The indigo hover / focus glow was already gone (replaced by
   accent-ring in an earlier slice); this pass:
     - moves background / border / radius / transition onto tokens
     - tightens vertical padding (0.85rem → 0.7rem) to claim ~17%
       vertical real-estate back on lists rendering 50+ rows. */
.entity-row {
    position: relative;
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
    transition: border-color var(--se-transition-fast), box-shadow var(--se-transition-fast);
}
.entity-row:hover {
    border-color: var(--se-color-border-strong);
    box-shadow: var(--se-shadow);
}
.entity-row:focus-within {
    border-color: var(--se-color-accent);
    box-shadow: 0 0 0 2px var(--se-color-accent-ring);
}
/* The clickable-content area reserves right padding for the ⋮ menu
   so a click in the row's far right corner doesn't accidentally fire
   the row's EditNavigateTo handler — the menu owns that space. */
/* MS25-β.2 — Vertical padding scales with --se-density (Compact 0.75 /
   Standard 1 / Comfortable 1.25). Horizontal stays fixed to preserve
   the right-edge ⋮ menu gutter the entity-row layout depends on. */
.entity-row-clickable {
    display: block;
    padding: calc(0.7rem * var(--se-density)) 3rem calc(0.7rem * var(--se-density)) 1rem;
    cursor: pointer;
    outline: none;
}
.entity-row-static {
    display: block;
    padding: calc(0.7rem * var(--se-density)) 3rem calc(0.7rem * var(--se-density)) 1rem;
}
.entity-row-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
    font-size: 0.78rem;
    color: #6b7280;
}
.entity-row-severity {
    display: inline-flex;
    align-items: center;
}
.entity-row-meta {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
    color: #6b7280;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 0.72rem;
}
.entity-row-id { letter-spacing: 0.02em; }
.entity-row-title {
    margin: 0 0 0.25rem 0;
    font-size: 1rem;
    font-weight: 600;
    color: #1f2937;
    line-height: 1.35;
}
/* 3-line clamp with ellipsis. -webkit-line-clamp is the de-facto
   standard for vertical line clamping; the standardised line-clamp
   property is listed alongside for forward-compatibility. */
.entity-row-narrative {
    margin: 0 0 0.4rem 0;
    color: #4b5563;
    font-size: 0.88rem;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.entity-row-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.6rem;
    font-size: 0.78rem;
    color: #6b7280;
}
.chip {
    display: inline-block;
    background: #f3f4f6;
    color: #374151;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
}
.chip-attention {
    background: #fef3c7;
    color: #92400e;
    font-weight: 600;
}
.entity-row-actions {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
}
.entity-row-actions > summary {
    list-style: none;
    cursor: pointer;
    width: 1.8rem;
    height: 1.8rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    color: #6b7280;
    font-size: 1.1rem;
    user-select: none;
}
.entity-row-actions > summary::-webkit-details-marker {
    display: none;
}
.entity-row-actions > summary:hover {
    background: #f3f4f6;
    color: #1f2937;
}
.entity-row-actions[open] > summary {
    background: #e5e7eb;
    color: #1f2937;
}
.entity-row-actions-menu {
    position: absolute;
    top: 100%;
    right: 0;
    margin: 0.25rem 0 0 0;
    padding: 0.3rem 0;
    list-style: none;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 5px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    min-width: 8rem;
    z-index: 10;
}
.entity-row-actions-menu li { display: block; }
.entity-row-actions-menu button {
    width: 100%;
    text-align: left;
    padding: 0.4rem 0.85rem;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.85rem;
    color: #1f2937;
}
.entity-row-actions-menu button:hover { background: #f3f4f6; }
.entity-row-actions-menu .btn-danger-link { color: var(--se-color-danger-fg); }
.entity-row-actions-menu .btn-danger-link:hover { background: var(--se-color-danger-bg); }

/* Mobile: same shape, tighter padding to claim more screen width.
   MS25-α.5 — Tightened further (0.7 → 0.6 vertical / 2.6 → 2.4 right)
   to keep the desktop-mobile delta proportional after the desktop
   tightening. */
@media (max-width: 640px) {
    .entity-row-clickable,
    .entity-row-static {
        padding: 0.6rem 2.4rem 0.6rem 0.8rem;
    }
    .entity-row-title { font-size: 0.95rem; }
    .entity-row-narrative { font-size: 0.85rem; }
}

/* =================================================================
   M295 (gap-03 T1 #2) — RCA diagram styles
   -----------------------------------------------------------------
   Visual encoding for the M293 Cause Map (`cause-map-diagram-*`) and
   M294 Bow-Tie (`bow-tie-diagram-*`) read-only SVG diagrams. Stays
   on the MS25-α design-token palette (orange accent; semantic
   status pairs for the danger / warning / success ramp; zinc for
   neutral chrome). No new colour tokens introduced; barrier
   effectiveness ramp uses the existing status pairs.

   Both panels mount on the RcaSession edit page; each methodology-
   gates so only one renders at a time. Focus-dialog inherits from
   `.dialog-scrim` / `.dialog-card` already defined above.
   ================================================================= */

/* Cause Map diagram (M293) ----------------------------------------- */

.cause-map-diagram {
    margin-top: var(--se-space-4);
    padding: var(--se-space-4);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.cause-map-diagram h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-default);
}

.cause-map-diagram-empty {
    margin: var(--se-space-3) 0;
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
}

.cause-map-diagram-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
    background: var(--se-color-surface-sunken);
    border-radius: var(--se-radius-sm);
}

.cause-map-diagram-chain-label {
    fill: var(--se-color-text-muted);
    font-size: 11px;
    font-weight: 600;
}

/* Node rect — default white background + grey border for cause
   nodes; effect node overrides with the accent fill below. */
.cause-map-diagram-node-rect {
    fill: var(--se-color-surface-raised);
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
    transition: fill var(--se-transition);
}

.cause-map-diagram-node:hover .cause-map-diagram-node-rect,
.cause-map-diagram-node:focus-visible .cause-map-diagram-node-rect {
    stroke: var(--se-color-accent);
    stroke-width: 2;
}

.cause-map-diagram-node-effect .cause-map-diagram-node-rect {
    fill: var(--se-color-accent);
    stroke: var(--se-color-accent-strong);
}

.cause-map-diagram-node-text-effect {
    fill: #ffffff;
    font-size: 11px;
    font-weight: 600;
}

.cause-map-diagram-node-text-cause {
    fill: var(--se-color-text-default);
    font-size: 11px;
}

.cause-map-diagram-arrow {
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
}

.cause-map-diagram-arrow-head {
    fill: var(--se-color-border-strong);
}

.cause-map-diagram-evidence-badge {
    fill: var(--se-color-accent);
    stroke: var(--se-color-surface-raised);
    stroke-width: 1;
}

/* Legend — small key under the SVG. */
.cause-map-diagram-legend,
.bow-tie-diagram-legend {
    list-style: none;
    margin: var(--se-space-3) 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-4);
    font-size: var(--se-text-xs);
    color: var(--se-color-text-muted);
}

.cause-map-diagram-legend li,
.bow-tie-diagram-legend li {
    display: flex;
    align-items: center;
    gap: var(--se-space-2);
}

.cause-map-diagram-legend-swatch,
.bow-tie-diagram-legend-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: var(--se-radius-sm);
    border: 1px solid var(--se-color-border-strong);
}

.cause-map-diagram-legend-swatch-effect {
    background: var(--se-color-accent);
    border-color: var(--se-color-accent-strong);
}

.cause-map-diagram-legend-swatch-cause {
    background: var(--se-color-surface-raised);
}

.cause-map-diagram-legend-evidence-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--se-color-accent);
}

/* Bow-Tie diagram (M294) ------------------------------------------- */

.bow-tie-diagram {
    margin-top: var(--se-space-4);
    padding: var(--se-space-4);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.bow-tie-diagram h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-default);
}

.bow-tie-diagram-empty,
.bow-tie-diagram-panel-status {
    margin: var(--se-space-3) 0;
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
}

.bow-tie-diagram-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
    background: var(--se-color-surface-sunken);
    border-radius: var(--se-radius-sm);
}

/* Node rects — shared base; per-kind fill overrides below. */
.bow-tie-diagram-node-rect {
    fill: var(--se-color-surface-raised);
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
    transition: stroke var(--se-transition);
}

.bow-tie-diagram-node:hover .bow-tie-diagram-node-rect,
.bow-tie-diagram-node:focus-visible .bow-tie-diagram-node-rect {
    stroke: var(--se-color-accent);
    stroke-width: 2;
}

.bow-tie-diagram-node-topevent .bow-tie-diagram-node-rect {
    fill: var(--se-color-accent);
    stroke: var(--se-color-accent-strong);
    stroke-width: 2;
}

.bow-tie-diagram-node-threat .bow-tie-diagram-node-rect {
    fill: var(--se-color-warning-bg);
    stroke: var(--se-color-warning-fg);
}

.bow-tie-diagram-node-consequence .bow-tie-diagram-node-rect {
    fill: var(--se-color-danger-bg);
    stroke: var(--se-color-danger-fg);
}

.bow-tie-diagram-node-text {
    font-size: 11px;
    fill: var(--se-color-text-default);
}

.bow-tie-diagram-node-text-topevent {
    font-size: 12px;
    font-weight: 600;
    fill: #ffffff;
}

.bow-tie-diagram-node-text-threat {
    font-size: 11px;
    fill: var(--se-color-warning-fg);
    font-weight: 500;
}

.bow-tie-diagram-node-text-consequence {
    font-size: 11px;
    fill: var(--se-color-danger-fg);
    font-weight: 500;
}

.bow-tie-diagram-connector {
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
    fill: none;
}

/* Barrier base + per-effectiveness ramp. The five
   HazardControlEffectiveness tiers map to the danger → warning →
   info → success ramp from the existing status tokens, with the
   middle Moderate tier sitting between warning and success. The
   ramp visually conveys "this barrier reduces risk" as the colour
   greens. Null Effectiveness = neutral grey. */

.bow-tie-diagram-barrier-rect {
    stroke: var(--se-color-border-strong);
    stroke-width: 1;
    transition: stroke var(--se-transition);
}

.bow-tie-diagram-barrier:hover .bow-tie-diagram-barrier-rect,
.bow-tie-diagram-barrier:focus-visible .bow-tie-diagram-barrier-rect {
    stroke: var(--se-color-accent);
    stroke-width: 2;
}

.bow-tie-diagram-barrier-ineffective .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-danger-fg);
}

.bow-tie-diagram-barrier-limited .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-warning-fg);
}

.bow-tie-diagram-barrier-moderate .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-warning-bg);
    stroke: var(--se-color-warning-fg);
}

.bow-tie-diagram-barrier-effective .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-success-bg);
    stroke: var(--se-color-success-fg);
}

.bow-tie-diagram-barrier-highly-effective .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-success-fg);
}

.bow-tie-diagram-barrier-unrated .bow-tie-diagram-barrier-rect {
    fill: var(--se-color-neutral-bg);
    stroke: var(--se-color-neutral-fg);
}

/* Bow-Tie legend swatches — match the per-kind fills above. */
.bow-tie-diagram-legend-swatch-threat {
    background: var(--se-color-warning-bg);
    border-color: var(--se-color-warning-fg);
}

.bow-tie-diagram-legend-swatch-topevent {
    background: var(--se-color-accent);
    border-color: var(--se-color-accent-strong);
}

.bow-tie-diagram-legend-swatch-consequence {
    background: var(--se-color-danger-bg);
    border-color: var(--se-color-danger-fg);
}

.bow-tie-diagram-legend-barrier-effective {
    background: var(--se-color-success-fg);
    border-color: var(--se-color-success-fg);
}

.bow-tie-diagram-legend-barrier-ineffective {
    background: var(--se-color-danger-fg);
    border-color: var(--se-color-danger-fg);
}

/* Focus dialogs — inherit dialog-scrim / dialog-card; this just
   sizes the card sensibly for the diagram's per-node detail view. */

.cause-map-diagram-focus-dialog,
.bow-tie-diagram-focus-dialog {
    max-width: 480px;
}

.cause-map-diagram-focus-close,
.bow-tie-diagram-focus-close {
    margin-left: auto;
}

/* Apollo diagram (M296) ------------------------------------------- */

.apollo-diagram {
    margin-top: var(--se-space-4);
    padding: var(--se-space-4);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.apollo-diagram h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-default);
}

.apollo-diagram-empty,
.apollo-diagram-panel-status {
    margin: var(--se-space-3) 0;
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
}

.apollo-diagram-problem-statement {
    margin: 0 0 var(--se-space-3);
    padding: var(--se-space-2) var(--se-space-3);
    background: var(--se-color-surface-sunken);
    border-left: 3px solid var(--se-color-accent);
    border-radius: var(--se-radius-sm);
    font-size: var(--se-text-sm);
}

.apollo-diagram-svg {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
    background: var(--se-color-surface-sunken);
    border-radius: var(--se-radius-sm);
}

.apollo-diagram-edge {
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
    fill: none;
}

.apollo-diagram-node-rect {
    fill: var(--se-color-surface-raised);
    stroke: var(--se-color-border-strong);
    stroke-width: 1.5;
    transition: stroke var(--se-transition);
}

.apollo-diagram-node:hover .apollo-diagram-node-rect,
.apollo-diagram-node:focus-visible .apollo-diagram-node-rect {
    stroke: var(--se-color-accent);
    stroke-width: 2;
}

/* Per-ApolloCauseKind fill encoding. Effects = accent (the thing
   being explained, like Bow-Tie's TopEvent). Actions = warning-
   tinted (something that happened). Conditions = info-tinted
   (something that existed). The Action / Condition colour
   distinction makes Apollo's forcing-function pairing read at a
   glance — each Why? answer should have at least one of each
   colour underneath it. */

.apollo-diagram-node-effect .apollo-diagram-node-rect {
    fill: var(--se-color-accent);
    stroke: var(--se-color-accent-strong);
}

.apollo-diagram-node-action .apollo-diagram-node-rect {
    fill: var(--se-color-warning-bg);
    stroke: var(--se-color-warning-fg);
}

.apollo-diagram-node-condition .apollo-diagram-node-rect {
    fill: var(--se-color-info-bg);
    stroke: var(--se-color-info-fg);
}

.apollo-diagram-node-text-effect {
    fill: #ffffff;
    font-size: 11px;
    font-weight: 600;
}

.apollo-diagram-node-text-action {
    fill: var(--se-color-warning-fg);
    font-size: 11px;
    font-weight: 500;
}

.apollo-diagram-node-text-condition {
    fill: var(--se-color-info-fg);
    font-size: 11px;
    font-weight: 500;
}

.apollo-diagram-evidence-badge {
    fill: var(--se-color-accent);
    stroke: var(--se-color-surface-raised);
    stroke-width: 1;
}

.apollo-diagram-legend {
    list-style: none;
    margin: var(--se-space-3) 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-4);
    font-size: var(--se-text-xs);
    color: var(--se-color-text-muted);
}

.apollo-diagram-legend li {
    display: flex;
    align-items: center;
    gap: var(--se-space-2);
}

.apollo-diagram-legend-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: var(--se-radius-sm);
    border: 1px solid var(--se-color-border-strong);
}

.apollo-diagram-legend-swatch-effect {
    background: var(--se-color-accent);
    border-color: var(--se-color-accent-strong);
}

.apollo-diagram-legend-swatch-action {
    background: var(--se-color-warning-bg);
    border-color: var(--se-color-warning-fg);
}

.apollo-diagram-legend-swatch-condition {
    background: var(--se-color-info-bg);
    border-color: var(--se-color-info-fg);
}

.apollo-diagram-legend-evidence-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--se-color-accent);
}

.apollo-diagram-focus-dialog {
    max-width: 480px;
}

.apollo-diagram-focus-close {
    margin-left: auto;
}

/* Narrow-screen behaviour — the SVG already scales (max-width 100%);
   on tight viewports the focus-dialog also tightens. */
@media (max-width: 640px) {
    .cause-map-diagram,
    .bow-tie-diagram,
    .apollo-diagram {
        padding: var(--se-space-3);
    }

    .cause-map-diagram-focus-dialog,
    .bow-tie-diagram-focus-dialog,
    .apollo-diagram-focus-dialog {
        max-width: 92vw;
    }
}

/* =================================================================
   M298 (M293-M296 carry-forward) — Print stylesheet for the RCA
   diagrams
   -----------------------------------------------------------------
   Browser print already renders the page; this block tightens what
   prints so the cause-tree diagrams come out as a clean reference
   page (white bg + dark text; no nav chrome / sidebar / focus-
   dialog / interactive hover rings; preserved SVG viewBox scaling).
   The diagrams + their legends print; everything else hides.

   Auditors regularly print investigation report PDFs (M224) and
   want the corresponding visual diagram as a paper companion. Now
   they can — `print` from any RcaSession edit page renders the
   diagram alone.
   ================================================================= */

@media print {
    /* Force light surface + dark text across the diagram containers
       so printer ink usage stays sensible regardless of any future
       dark-mode theme. */
    .cause-map-diagram,
    .bow-tie-diagram,
    .apollo-diagram {
        background: #ffffff !important;
        color: #000000 !important;
        border: 1px solid #999999 !important;
        padding: 0.5rem !important;
        page-break-inside: avoid;
    }

    /* SVG canvas backdrop — print white, no rounded background. */
    .cause-map-diagram-svg,
    .bow-tie-diagram-svg,
    .apollo-diagram-svg {
        background: #ffffff !important;
        max-width: 100%;
    }

    /* Hide focus-dialog scrim if one happens to be open at the
       moment of print. Diagrams print as the reference document,
       not the interactive surface. */
    .cause-map-diagram-focus-dialog,
    .bow-tie-diagram-focus-dialog,
    .apollo-diagram-focus-dialog,
    .dialog-scrim {
        display: none !important;
    }

    /* Disable hover/focus accent rings (no interactivity on paper). */
    .cause-map-diagram-node:hover .cause-map-diagram-node-rect,
    .cause-map-diagram-node:focus-visible .cause-map-diagram-node-rect,
    .bow-tie-diagram-node:hover .bow-tie-diagram-node-rect,
    .bow-tie-diagram-node:focus-visible .bow-tie-diagram-node-rect,
    .bow-tie-diagram-barrier:hover .bow-tie-diagram-barrier-rect,
    .bow-tie-diagram-barrier:focus-visible .bow-tie-diagram-barrier-rect,
    .apollo-diagram-node:hover .apollo-diagram-node-rect,
    .apollo-diagram-node:focus-visible .apollo-diagram-node-rect {
        stroke-width: 1.5 !important;
    }

    /* Legend prints in black so swatches stay visible without
       relying on browser colour-adjust defaults. */
    .cause-map-diagram-legend,
    .bow-tie-diagram-legend,
    .apollo-diagram-legend {
        color: #000000 !important;
    }

    /* Apollo problem statement — print as a normal paragraph; drop
       the accent border to save ink. */
    .apollo-diagram-problem-statement {
        background: #ffffff !important;
        border-left: none !important;
        color: #000000 !important;
        padding: 0 !important;
    }

    /* Honour SVG fills + strokes literally instead of the browser's
       default print-economy "convert to grayscale" behaviour — the
       diagram's encoding only reads correctly in colour. Print
       drivers respect this on most browsers. */
    .cause-map-diagram-svg *,
    .bow-tie-diagram-svg *,
    .apollo-diagram-svg * {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* M372 — printing the Location QR codes poster (and any future
       print-oriented page) should drop the app chrome and any element
       opting out via .no-print, leaving only the page content on paper. */
    .sidebar,
    main > .top-row,
    .no-print {
        display: none !important;
    }

    /* QR images must print at full fidelity — the browser's default
       print-economy grayscale pass can soften module edges enough to
       hurt scanability. */
    .qr-card-image {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/* M305 (gap-08 T1 #3 / M292 carry-forward, M301 + M302 + M303
   visual polish) — Bundled CSS for the three ergonomics
   worksheet panels.

   All three panels emit a parallel class hierarchy
   (.{family}-panel / -help / -question / -option / -result /
   -result-grid). The grouped selectors keep one rule per visual
   concern across the three families; family-specific selectors
   only appear where genuinely needed (NIOSH's input grid +
   coupling-aware result emphasis).

   Stays on the MS25-α design-token palette — no new tokens
   introduced. Mirrors the .cause-map-diagram + .action-tracking-
   section conventions for outer-card framing. */

.reba-worksheet-panel,
.rula-worksheet-panel,
.niosh-lifting-panel {
    margin-top: var(--se-space-4);
    padding: var(--se-space-5);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.reba-worksheet-panel h3,
.rula-worksheet-panel h3,
.niosh-lifting-panel h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-default);
}

.reba-worksheet-help,
.rula-worksheet-help,
.niosh-lifting-help {
    margin: 0 0 var(--se-space-4);
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
}

/* Per-question fieldset framing. Each question is its own
   bordered box so the worksheet feels like a step-by-step form
   rather than a wall of radios. Legend sits at the top, picks
   up the strong text colour so it reads as the question label. */
.reba-worksheet-question,
.rula-worksheet-question,
.niosh-lifting-question {
    margin: 0 0 var(--se-space-4);
    padding: var(--se-space-3) var(--se-space-4);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface);
}

.reba-worksheet-question legend,
.rula-worksheet-question legend,
.niosh-lifting-question legend {
    padding: 0 var(--se-space-2);
    font-weight: 600;
    color: var(--se-color-text-strong);
    font-size: var(--se-text-sm);
}

/* Radio-option labels render as block-level click targets so the
   whole row is hit-testable. Hover adds an accent-soft background
   for affordance; focus-within keeps it visible while the radio
   has focus (keyboard navigation). */
.reba-worksheet-option,
.rula-worksheet-option,
.niosh-lifting-option {
    display: block;
    padding: var(--se-space-1) var(--se-space-2);
    margin: var(--se-space-1) 0;
    border-radius: var(--se-radius-sm);
    cursor: pointer;
    transition: background var(--se-transition);
    color: var(--se-color-text-default);
    font-size: var(--se-text-sm);
}

.reba-worksheet-option:hover,
.rula-worksheet-option:hover,
.niosh-lifting-option:hover,
.reba-worksheet-option:focus-within,
.rula-worksheet-option:focus-within,
.niosh-lifting-option:focus-within {
    background: var(--se-color-accent-soft);
}

/* Result-panel framing — distinct from the question fieldsets so
   the "here's your score" payload reads as its own section. */
.reba-worksheet-result,
.rula-worksheet-result,
.niosh-lifting-result {
    margin: var(--se-space-5) 0 var(--se-space-4);
    padding: var(--se-space-4);
    background: var(--se-color-surface-sunken);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.reba-worksheet-result h4,
.rula-worksheet-result h4,
.niosh-lifting-result h4 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-md);
    color: var(--se-color-text-strong);
}

/* Two-column grid for the dt/dd pairs — labels right-aligned so
   the values column lines up cleanly down the panel. */
.reba-worksheet-result-grid,
.rula-worksheet-result-grid,
.niosh-lifting-result-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--se-space-2) var(--se-space-4);
    margin: 0;
}

.reba-worksheet-result-grid dt,
.rula-worksheet-result-grid dt,
.niosh-lifting-result-grid dt {
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
    text-align: right;
}

.reba-worksheet-result-grid dd,
.rula-worksheet-result-grid dd,
.niosh-lifting-result-grid dd {
    margin: 0;
    color: var(--se-color-text-default);
    font-size: var(--se-text-sm);
}

/* NIOSH-specific: 6 continuous numeric inputs sit in a responsive
   grid (auto-fit, minimum 14rem per cell — comfortably wide enough
   for the longest label like "Travel distance D (cm) — vertical
   travel..."). Wraps to one column on narrow viewports. */
.niosh-lifting-inputs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--se-space-3) var(--se-space-4);
    margin: 0 0 var(--se-space-4);
}

.niosh-lifting-input {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-1);
    font-size: var(--se-text-sm);
    color: var(--se-color-text-default);
}

.niosh-lifting-input > span {
    font-weight: 500;
    color: var(--se-color-text-strong);
}

.niosh-lifting-input > input {
    padding: var(--se-space-2);
    border: 1px solid var(--se-color-border-strong);
    border-radius: var(--se-radius-sm);
    font-size: var(--se-text-sm);
    color: var(--se-color-text-default);
    background: var(--se-color-surface);
    transition: border-color var(--se-transition);
}

.niosh-lifting-input > input:focus {
    outline: none;
    border-color: var(--se-color-accent);
    box-shadow: 0 0 0 3px var(--se-color-accent-ring);
}

/* M307 (M299 + M306 visual polish) — Bundled CSS for the
   /citation-closure dashboard. ~13 semantic class names emitted
   by the page (header / controls / chips / section / rows table /
   red-flag highlight / expand toggle / expanded sub-row / linked-
   tasks list / omitted-tasks footer); M307 styles them on the
   MS25-α design-token palette. Mirrors the M305 worksheet-CSS-
   bundle pattern. No new tokens introduced. */

/* Page-level frame — uses existing app-page spacing conventions. */
.citation-closure-page {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-5);
}

.citation-closure-page-header h1 {
    margin: 0 0 var(--se-space-2);
}

/* Window-selector row sits above the report. Compact + right-
   aligned-by-content so it doesn't dominate the page. */
.citation-closure-controls {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-4);
    align-items: flex-end;
}

/* Headline chip row — the 6 top-level counters (Total /
   FullClosedLoop / red-flag CitationClosedTasksOpen / etc).
   Flex-wrap so small viewports get a clean two-row layout. */
.citation-closure-headline {
    display: flex;
    flex-wrap: wrap;
    gap: var(--se-space-2);
    align-items: center;
}

/* Per-section card framing (by-agency table + rows table). Same
   surface treatment as .cause-map-diagram / .reba-worksheet-panel
   so the dashboard reads as a stack of consistent panels. */
.citation-closure-section {
    padding: var(--se-space-5);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.citation-closure-section h2 {
    margin: 0 0 var(--se-space-2);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-strong);
}

/* Rows-table sizing. Inherits .data-grid for cell padding +
   border colours; M307 adds dashboard-specific tweaks. */
.citation-closure-rows {
    width: 100%;
    table-layout: auto;
}

/* Red-flag row highlight — CitationClosedTasksOpen rows lead the
   list per the StatePriority ordering. Background tint + left
   border draw the eye without making the table feel cluttered. */
.citation-closure-row-redflag > td {
    background: var(--se-color-danger-bg);
}

.citation-closure-row-redflag > td:first-child {
    box-shadow: inset 3px 0 0 var(--se-color-danger-fg);
}

/* Expand-column sizing — narrow column just wide enough for the
   carrot button. */
.citation-closure-expand-col {
    width: 2.25rem;
    text-align: center;
}

/* Expand toggle button — minimal chrome (no border / background
   in resting state) so it sits comfortably in the table cell.
   Hover + focus add the accent ring affordance shared with
   .nav-spotlight and the row PDF menu items. */
.citation-closure-expand-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--se-radius-sm);
    color: var(--se-color-text-default);
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    transition: background var(--se-transition), border-color var(--se-transition);
}

.citation-closure-expand-toggle:hover,
.citation-closure-expand-toggle:focus-visible {
    background: var(--se-color-accent-soft);
    border-color: var(--se-color-accent-ring);
    outline: none;
}

/* Expanded sub-row. Distinct background tint (sunken) so the
   detail rows read as nested content rather than another sibling
   row — and so the eye doesn't lose the parent row's column
   alignment. */
.citation-closure-row-expanded > td {
    background: var(--se-color-surface-sunken);
    padding: var(--se-space-4);
    border-top: 1px dashed var(--se-color-border-default);
}

.citation-closure-linked-tasks h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-md);
    color: var(--se-color-text-strong);
}

/* Linked-tasks list — single column of compact rows, each with
   a status badge, title, optional due-date chip, and a deep-link.
   Reset default ul margins/padding; gap-driven spacing. */
.citation-closure-linked-tasks-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--se-space-2);
}

.citation-closure-linked-task {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--se-space-2) var(--se-space-3);
    padding: var(--se-space-2) var(--se-space-3);
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    font-size: var(--se-text-sm);
}

.citation-closure-linked-task-title {
    flex: 1 1 12rem;
    color: var(--se-color-text-default);
}

.citation-closure-linked-task-due {
    color: var(--se-color-text-muted);
    font-size: 0.8rem;
}

/* Omitted-tasks footer — muted italic note when the inline list
   is shorter than LinkedTaskCount (some linked tasks fell
   outside the caller's site scope). Reads as an FYI, not an
   alert. */
.citation-closure-linked-tasks-omitted {
    margin: var(--se-space-3) 0 0;
    color: var(--se-color-text-muted);
    font-style: italic;
    font-size: var(--se-text-sm);
}

/* M309 (M308 visual polish) — Bundled CSS for the NIOSH composite
   (multi-task) lifting panel. ~13 semantic class names emitted by
   the panel; M309 styles them on the MS25-α design-token palette.
   Third sibling in the worksheet/dashboard-CSS-bundle pattern
   (M305 = worksheets, M307 = citation-closure dashboard, M309 =
   this). No new tokens introduced. */

/* Outer panel — mirrors .reba-worksheet-panel + .niosh-lifting-
   panel + .cause-map-diagram outer-card convention. */
.niosh-composite-lifting-panel {
    margin-top: var(--se-space-4);
    padding: var(--se-space-5);
    background: var(--se-color-surface-raised);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.niosh-composite-lifting-panel h3 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-lg);
    color: var(--se-color-text-default);
}

.niosh-composite-lifting-help {
    margin: 0 0 var(--se-space-4);
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
}

/* Duration fieldset (shared shift-level setting). Same shape as
   the per-question fieldsets on the M305 worksheet panels. */
.niosh-composite-lifting-question {
    margin: 0 0 var(--se-space-4);
    padding: var(--se-space-3) var(--se-space-4);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface);
}

.niosh-composite-lifting-question legend {
    padding: 0 var(--se-space-2);
    font-weight: 600;
    color: var(--se-color-text-strong);
    font-size: var(--se-text-sm);
}

/* Radio-option label — block-level click target with accent-soft
   hover. Mirrors the M305 worksheet-option styling so the look is
   consistent across all five panels. */
.niosh-composite-lifting-option {
    display: block;
    padding: var(--se-space-1) var(--se-space-2);
    margin: var(--se-space-1) 0;
    border-radius: var(--se-radius-sm);
    cursor: pointer;
    transition: background var(--se-transition);
    color: var(--se-color-text-default);
    font-size: var(--se-text-sm);
}

.niosh-composite-lifting-option:hover,
.niosh-composite-lifting-option:focus-within {
    background: var(--se-color-accent-soft);
}

/* Task list container — flex column with generous gap so adjacent
   task cards read as separate items, not as a continuous wall. */
.niosh-composite-lifting-tasks {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-4);
    margin-bottom: var(--se-space-4);
}

/* Each task card — bordered + slightly-elevated surface so the
   "this is task N" boundary is obvious. accent-soft top-border
   draws the eye to the header (Task N + Remove). */
.niosh-composite-lifting-task {
    padding: var(--se-space-4);
    background: var(--se-color-surface);
    border: 1px solid var(--se-color-border-default);
    border-top: 3px solid var(--se-color-accent);
    border-radius: var(--se-radius-sm);
}

.niosh-composite-lifting-task-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--se-space-4);
    margin: 0 0 var(--se-space-3);
}

.niosh-composite-lifting-task-header h4 {
    margin: 0;
    font-size: var(--se-text-md);
    color: var(--se-color-text-strong);
}

/* Numeric inputs — responsive grid matching the M305 NIOSH single-
   task panel (auto-fit, 14rem minimum cell width; wraps to single
   column on narrow viewports). */
.niosh-composite-lifting-task-inputs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--se-space-3) var(--se-space-4);
    margin: 0 0 var(--se-space-3);
}

.niosh-composite-lifting-task-input {
    display: flex;
    flex-direction: column;
    gap: var(--se-space-1);
    font-size: var(--se-text-sm);
    color: var(--se-color-text-default);
}

.niosh-composite-lifting-task-input > span {
    font-weight: 500;
    color: var(--se-color-text-strong);
}

.niosh-composite-lifting-task-input > input {
    padding: var(--se-space-2);
    border: 1px solid var(--se-color-border-strong);
    border-radius: var(--se-radius-sm);
    font-size: var(--se-text-sm);
    color: var(--se-color-text-default);
    background: var(--se-color-surface);
    transition: border-color var(--se-transition);
}

.niosh-composite-lifting-task-input > input:focus {
    outline: none;
    border-color: var(--se-color-accent);
    box-shadow: 0 0 0 3px var(--se-color-accent-ring);
}

/* Coupling fieldset inside each task card. Same shape as the
   composite-level Duration fieldset; sub-card visual weight via
   slightly different background. */
.niosh-composite-lifting-task-coupling {
    margin: 0 0 var(--se-space-3);
    padding: var(--se-space-2) var(--se-space-3);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface-sunken);
}

.niosh-composite-lifting-task-coupling legend {
    padding: 0 var(--se-space-2);
    font-weight: 600;
    color: var(--se-color-text-strong);
    font-size: var(--se-text-sm);
}

/* Per-task result dl — two-column grid with right-aligned terms.
   Mirrors the M305 worksheet-result-grid pattern. */
.niosh-composite-lifting-task-result {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--se-space-2) var(--se-space-4);
    margin: var(--se-space-2) 0 0;
    padding-top: var(--se-space-3);
    border-top: 1px dashed var(--se-color-border-default);
}

.niosh-composite-lifting-task-result dt {
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
    text-align: right;
}

.niosh-composite-lifting-task-result dd {
    margin: 0;
    color: var(--se-color-text-default);
    font-size: var(--se-text-sm);
}

/* Composite-result panel (CLI + risk). Sunken background matches
   the M305/M307 result-panel convention so the user reads "this
   is the rolled-up answer" at a glance. */
.niosh-composite-lifting-result {
    margin: var(--se-space-5) 0 var(--se-space-4);
    padding: var(--se-space-4);
    background: var(--se-color-surface-sunken);
    border: 1px solid var(--se-color-border-default);
    border-radius: var(--se-radius-md);
}

.niosh-composite-lifting-result h4 {
    margin: 0 0 var(--se-space-3);
    font-size: var(--se-text-md);
    color: var(--se-color-text-strong);
}

.niosh-composite-lifting-result-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--se-space-2) var(--se-space-4);
    margin: 0;
}

.niosh-composite-lifting-result-grid dt {
    color: var(--se-color-text-muted);
    font-size: var(--se-text-sm);
    text-align: right;
}

.niosh-composite-lifting-result-grid dd {
    margin: 0;
    color: var(--se-color-text-default);
    font-size: var(--se-text-sm);
}

/* M310 (gap-08 T1 #3 / M292 + M303 + M308 visual polish) —
   NioshGeometryDiagram inline reference figures. Renders the
   hand-coded SVG between the input label and the number input
   on both the M303 single-task + M308 composite NIOSH panels.
   currentColor-driven so the figure picks up the surrounding
   text-default colour (light theme + future dark theme work
   without per-mode rules). */

.niosh-geometry-diagram {
    /* Compact figure beside the input. Width chosen to fit
       comfortably inside the 14rem-min input grid cells; height
       fixed at 88px keeps each input row at roughly the same
       height as the M305 worksheet questions. */
    max-width: 110px;
    margin: var(--se-space-1) 0 var(--se-space-2);
    color: var(--se-color-text-muted);
}

.niosh-geometry-diagram-svg {
    display: block;
    width: 100%;
    height: 88px;
    overflow: visible;
}

/* Stick-figure worker silhouette + load box outlines. Uses
   currentColor stroke so the figure carries the surrounding text
   colour; fill stays transparent so the line-art reads cleanly. */
.niosh-geometry-diagram-figure,
.niosh-geometry-diagram-load {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
}

/* Floor line — slightly muted vs the figure for visual hierarchy. */
.niosh-geometry-diagram-floor {
    stroke: var(--se-color-border-strong);
    stroke-width: 1;
}

/* Ghost (origin) box on the Travel diagram — dashed outline. */
.niosh-geometry-diagram-load-ghost {
    fill: none;
    stroke: currentColor;
    stroke-width: 1;
    stroke-dasharray: 3 2;
    opacity: 0.55;
}

/* Reference axis (Asymmetry forward direction) — dashed muted. */
.niosh-geometry-diagram-reference {
    stroke: var(--se-color-border-strong);
    stroke-width: 1;
}

/* Measurement arrows — accent colour so the answer (the thing
   the user is being asked to measure) stands out from the
   structural figure. */
.niosh-geometry-diagram-measure {
    stroke: var(--se-color-accent);
    stroke-width: 1.5;
    fill: none;
}

.niosh-geometry-diagram-arrow-head {
    fill: var(--se-color-accent);
    stroke: none;
}

/* H / V / D / A° label — matches the measurement-arrow colour. */
.niosh-geometry-diagram-label {
    fill: var(--se-color-accent);
    font-size: 12px;
    font-weight: 600;
    font-family: sans-serif;
}

/* M314 (ADR-104) — Toolbar above the entity-row-list. Search input on
   the left, sort dropdown + direction toggle in the middle, result
   count on the right. Wraps on narrow viewports. */
.entity-list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--se-space-3);
    margin: var(--se-space-2) 0 var(--se-space-3);
    padding: var(--se-space-2) var(--se-space-3);
    background: var(--se-color-surface-subtle);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-md);
}
.entity-list-search {
    flex: 1 1 16rem;
    min-width: 0;
    padding: var(--se-space-2) var(--se-space-3);
    border: 1px solid var(--se-color-border);
    border-radius: var(--se-radius-sm);
    font-size: 0.95rem;
    background: var(--se-color-surface);
    transition: var(--se-transition);
}
.entity-list-search:focus {
    outline: 2px solid var(--se-color-accent);
    outline-offset: -1px;
    border-color: var(--se-color-accent);
}
.entity-list-sort {
    display: inline-flex;
    align-items: center;
    gap: var(--se-space-2);
    flex: 0 0 auto;
}
.entity-list-sort-label {
    font-size: 0.85rem;
    color: var(--se-color-text-muted);
    white-space: nowrap;
}
.entity-list-sort select {
    padding: var(--se-space-2) var(--se-space-3);
    border: 1px solid var(--se-color-border);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface);
    font-size: 0.95rem;
    min-width: 10rem;
}
.entity-list-sort-direction {
    padding: var(--se-space-1) var(--se-space-2);
    border: 1px solid var(--se-color-border);
    border-radius: var(--se-radius-sm);
    background: var(--se-color-surface);
    cursor: pointer;
    line-height: 1;
    font-size: 0.85rem;
    transition: var(--se-transition);
}
.entity-list-sort-direction:hover:not(:disabled) {
    background: var(--se-color-surface-subtle);
    border-color: var(--se-color-accent);
}
.entity-list-sort-direction:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.entity-list-result-count {
    margin-left: auto;
    font-size: 0.85rem;
    color: var(--se-color-text-muted);
    white-space: nowrap;
}

/* M314 — Empty filter result. Reads better than a Virtualize rendering
   nothing under the row list. */
.entity-list-no-results {
    padding: var(--se-space-4) var(--se-space-3);
    text-align: center;
    color: var(--se-color-text-muted);
    background: var(--se-color-surface-subtle);
    border: 1px dashed var(--se-color-border-subtle);
    border-radius: var(--se-radius-md);
    font-style: italic;
}

/* M316 (gap-02 #14) — Recurrence stats block on the hazard
   realized-incidents panel. Sits between the summary line + the
   incident list. Current-window count + trend arrow + prior-window
   count read as one row on desktop, stack on narrow viewports. */
.hazard-realized-recurrence {
    margin: var(--se-space-3) 0;
    padding: var(--se-space-3);
    background: var(--se-color-surface-subtle);
    border: 1px solid var(--se-color-border-subtle);
    border-radius: var(--se-radius-md);
}
.hazard-realized-recurrence-heading {
    margin: 0 0 var(--se-space-2) 0;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--se-color-text-muted);
}
.hazard-realized-recurrence-stats {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--se-space-3);
    margin: 0;
}
.hazard-realized-recurrence-stats dt,
.hazard-realized-recurrence-stats dd {
    margin: 0;
    font-size: 0.95rem;
    color: var(--se-color-text);
}
.hazard-realized-recurrence-current-label {
    font-weight: 600;
}
.hazard-realized-recurrence-prior-label {
    color: var(--se-color-text-muted);
}
.hazard-realized-recurrence-arrow {
    display: inline-block;
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1;
}
.hazard-realized-recurrence-arrow.trend-increasing { color: var(--se-color-danger-fg); }
.hazard-realized-recurrence-arrow.trend-decreasing { color: var(--se-color-success-fg); }

/* ADR-113 / M379 — read-only /contractor portal chrome. Minimal layout: a slim
   header over a centred content column. Deliberately distinct from the customer
   app shell (no sidebar / command palette). */
.contractor-portal {
    min-height: 100vh;
    background: var(--se-color-app-bg);
}
.contractor-portal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--se-space-4) var(--se-space-6);
    background: var(--se-color-surface);
    border-bottom: 1px solid var(--se-color-border-default);
}
.contractor-portal-brand {
    display: flex;
    align-items: baseline;
    gap: var(--se-space-3);
}
.contractor-portal-title {
    font-weight: 700;
    color: var(--se-color-text-strong);
}
.contractor-portal-org {
    color: var(--se-color-text-muted);
    font-size: var(--se-text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.contractor-portal-body {
    max-width: 880px;
    margin: 0 auto;
    padding: var(--se-space-8) var(--se-space-6);
}
.contractor-portal-greeting {
    margin-bottom: var(--se-space-6);
}
.contractor-portal-summary {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--se-space-2) var(--se-space-6);
}
.contractor-portal-summary dt {
    color: var(--se-color-text-muted);
    font-weight: 600;
}
.contractor-portal-summary dd {
    margin: 0;
}
.hazard-realized-recurrence-arrow.trend-steady     { color: var(--se-color-text-muted); }