/* intent: CSS variables and component-scoped overrides (inputs, chips, badges, animations) */

/* #region 01  Variables / :root */

:root {
    --emr-appbar-height: 76px;
    --emr-drawer-width-open: 200px;
    --emr-drawer-width-mini: 84px;

    /* Legacy-fidelity exception: Discharge status uses #BF6161 in the legacy EMR; no matching semantic token exists in the brand palette. */
    --emr-status-discharge: #BF6161;

    /* Filled input background tokens — brand-primary derived (2026-08-19 dedup pass, corrected
       from raw hex/near-match literals to exact palette mixes). */
    --emr-input-filled-bg:       color-mix(in srgb, var(--mud-palette-primary) 4%, transparent);
    --emr-input-filled-hover-bg: color-mix(in srgb, var(--mud-palette-primary) 10%, var(--mud-palette-surface));

    /* Needs Selection header band (2026-08-14, developer-directed) — paints the grid's sticky
       thead (the bulk-apply selector row) so it reads as a header rather than white page. The
       dialog toolbar above it stays transparent by design; see .emr-needs-header. Neutral grey by
       request; no MudBlazor palette token matches this value (gray-lighter is #e0e0e0), so it is
       a named token rather than a literal buried in the rule. */
    --emr-needs-header-bg: #ebebeb;

    /* HME Equipment badge — brand-primary derived (2026-08-19: corrected from Material-stock
       purple #673AB7/#4527a0, mistaken for brand purple #4E288E, to true brand-primary mixes). */
    --emr-hme-badge-hme-bg:        color-mix(in srgb, var(--mud-palette-primary) 12%, transparent);
    --emr-hme-badge-hme-text:      var(--mud-palette-primary);
    /* Supplies badge — product-specific teal, no MudBlazor token */
    --emr-hme-badge-supplies-bg:   rgba(0, 137, 123, 0.12);
    --emr-hme-badge-supplies-text: #00695c;

    /* Shared hairline / scrim tokens (2026-08-19 dedup pass) — converge the file's two
       competing "neutral black overlay" idioms onto one palette-derived pair. */
    --emr-grid-header-bg: color-mix(in srgb, var(--mud-palette-surface) 70%, var(--mud-palette-background));
    --emr-hairline:       color-mix(in srgb, var(--mud-palette-text-primary) 12%, transparent);
    --emr-scrim-subtle:   color-mix(in srgb, var(--mud-palette-text-primary) 5%, transparent);

    /* Moved from app.mudblazor.css (D2, 2026-08-19) — one :root owning every --emr-* custom
       property. Corrected from Material-stock purple #673AB7 to brand-primary. */
    --emr-tab-background: color-mix(in srgb, var(--mud-palette-primary) 4%, transparent);

    /* Neutral surface tokens — sanctioned raw-hex exceptions to design.md's Override Policy
       (developer-approved 2026-08-20; see plans/2026-08-19-app-components-css-dedup-and-tokens-plan.md §0/§2 Tier 3).
       No palette-derived expression reproduces these values. */
    --emr-kpi-card-bg:              #ededed;
    --emr-kpi-muted-text:           #858585;
    --emr-kpi-muted-text-active:    #cccccc;
    --emr-needs-level-need-bg:      #70e9b6;
    --emr-needs-level-specifier-bg: #e9f9f2;
}

/* 01.1  Filled input */

.emr-input-filled {
    background-color: var(--emr-input-filled-bg);
}

.emr-input-filled:hover {
    background-color: var(--emr-input-filled-hover-bg);
}

/* #endregion */
/* #region 02  Navigation / App Shell */

.emr-appbar {
    height: var(--emr-appbar-height);
    border-bottom: 1px solid color-mix(in srgb, var(--mud-palette-text-primary) 6%, transparent);
    overflow: visible;
}

.emr-appbar .mud-toolbar {
    height: var(--emr-appbar-height);
    align-items: center;
    overflow: visible;
}


/* 02.1  Side Drawer */

.emr-drawer {
    background-color: var(--mud-palette-drawer-background);
    color: var(--mud-palette-drawer-text);
}

.emr-drawer-header {
    padding: 0;
    min-height: var(--emr-appbar-height);
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--mud-palette-drawer-background);
}

.emr-drawer-logo-full {
    width: 100%;
    padding: 0.75rem 1rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.emr-drawer-logo-mini {
    width: 100%;
    text-align: center;
}

.emr-drawer-logo-title {
    color: var(--mud-palette-drawer-text);
    font-weight: 300;
    letter-spacing: 1px;
    line-height: 1.1;
}

.emr-drawer-logo-meta {
    color: var(--mud-palette-drawer-text);
    opacity: 0.85;
    font-size: 0.7rem;
    font-weight: 300;
    letter-spacing: 0.5px;
}

/* 02.2  Nav Menu */

/* Shared container for every purple drawer nav list in the app (EmrNavMenu,
   PatientScopedNavMenu, EncounterNav) — all render through EmrDrawerNav, which owns this
   class. Replaces the old per-consumer .emr-nav-menu / .emr-encounter-nav containers. */
.emr-drawer-nav {
    display: flex;
    flex-direction: column;
    padding: 0.5rem 0.5rem 0 0.5rem;
}

/* Row layout for click-to-select rows (EmrNavItem), applied by EmrDrawerNav. Routed rows
   (EmrNavButton / MudNavLink) get their padding from .emr-nav-link + MudBlazor's own
   16px inset instead — this class only targets the EmrNavItem shape. Left/right padding
   matches EmrNavGroupHeader's 12px so row content lines up flush under its own group
   header instead of sitting indented from it (2026-07-20: was 16px, read as an unwanted
   indent). Replaces the old .emr-encounter-nav-row. */
.emr-drawer-nav-row {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    cursor: pointer;
    transition: background 0.15s;
}

/* EmrNavItem's inner MudStack (Row=true) — fills the row's own flex item so its MudSpacer
   pushes trailing content (CP chip / error icon) to a consistent right edge regardless of
   label length, instead of hugging the end of shorter/longer text (see 2026-07-20 encounter
   left-nav alignment fix). MudStack doesn't stretch on its own inside a row-direction flex
   parent, so this needs its own flex-grow. */
.emr-nav-link-row {
    flex: 1;
    min-width: 0;
}

/* CP chip + error/check icon as one unit — never shrinks, so it keeps its own size and the
   label (which does shrink, see .emr-nav-link-text) truncates first. */
.emr-nav-link-trailing {
    flex-shrink: 0;
}

.emr-drawer-nav-row:hover {
    background: color-mix(in srgb, var(--mud-palette-drawer-text) 8%, transparent);
}

.emr-nav-link {
    color: color-mix(in srgb, var(--mud-palette-drawer-text) 70%, transparent);
    font-weight: 400;
    border-radius: 4px;
    margin-block: 4px;
}

/* MudBlazor sets internal colors; !important is a scoped legacy-fidelity override. */
.emr-nav-active {
    background-color: var(--mud-palette-surface) !important;
    color: var(--mud-palette-primary) !important;
    border-radius: 4px !important;
}

.emr-nav-link .mud-nav-link-icon {
    color: color-mix(in srgb, var(--mud-palette-drawer-icon) 70%, transparent);
}

.emr-nav-active .mud-nav-link-icon {
    color: var(--mud-palette-primary) !important;
}

/* DESIGN-OVERRIDE: encounter-drawer — inverts the app-shell nav-active rule on purpose.
   Encounter left nav: light drawer (EmrTheme.Encounter supplies the drawer colors), so the
   active row inverts to a filled primary row with contrast text, and rows are full-bleed with
   a hairline divider between them. */
.emr-drawer--encounter .emr-drawer-nav {
    padding-inline: 0;
    padding-top: 0;
}

.emr-drawer--encounter .emr-drawer-nav-row {
    margin-block: 0;
    border-radius: 0;
    border-bottom: 1px solid var(--emr-hairline);
}

/* Group headers (encounter-type label, SECTIONS, VISIT END): a darker band with bold, spaced
   caps and the same divider as the rows. */
.emr-drawer--encounter .emr-drawer-nav-title,
.emr-drawer--encounter .emr-nav-group-header {
    padding: 10px 12px;
    background-color: color-mix(in srgb, var(--mud-palette-drawer-text) 7%, var(--mud-palette-drawer-background));
    border-bottom: 1px solid var(--emr-hairline);
}

.emr-drawer--encounter .emr-drawer-nav-title .mud-typography-subtitle1,
.emr-drawer--encounter .emr-nav-section {
    font-weight: 700;
    letter-spacing: 0.15em;
}

.emr-drawer--encounter .emr-nav-section {
    font-size: 0.75rem;
    line-height: 1.4;
}

.emr-drawer--encounter .emr-nav-active {
    background-color: var(--mud-palette-primary) !important;
    color: var(--mud-palette-primary-text) !important;
    border-radius: 0 !important;
}

.emr-drawer--encounter .emr-nav-active .mud-nav-link-icon {
    color: var(--mud-palette-primary-text) !important;
}

/* Standard (non-mini) routed nav rows (EmrNavButton): MudBlazor's own .mud-nav-link-text
   truncates with nowrap+ellipsis by default, which cuts off longer labels
   ("Unsubmitted Encounters") instead of letting them wrap onto a second line. .mini rows
   get their own wrap rule below (.emr-nav-link--mini .mud-nav-link-text) — this only
   targets the open-drawer shape. */
.emr-nav-link:not(.emr-nav-link--mini) .mud-nav-link-text {
    white-space: normal;
    overflow: visible;
    text-overflow: unset;
    line-height: 1.25;
}

/* Mini rail: strip side padding so nav items fill the compact drawer width */
.mud-drawer--closed.mud-drawer-mini .emr-drawer-nav {
    padding: 0.5rem 0 0 0;
}

/* Section headers don't fit the compact rail */
.mud-drawer--closed.mud-drawer-mini .emr-nav-section {
    display: none !important;
}

/* Group-header label ("GENERAL" / "CLINICAL" / "SECTIONS" / "VISIT END" / "Recent Patients") — the
   single owned style for EmrNavGroupHeader, used by every purple drawer nav list in the app
   (PatientScopedNavMenu, EncounterNav, EmrNavMenu). Explicit color, not inherited from .emr-drawer,
   so an unrelated ancestor can never silently break it again (see EncounterNav .emr-section-header
   collision, 2026-07-06). */
.emr-nav-section {
    color: var(--mud-palette-drawer-text);
}

/* Flex so an optional leading icon and trailing collapse chevron sit on the label's line. Harmless
   for the icon-less, non-collapsible headers: a single flex child still renders left-aligned. */
.emr-nav-group-header {
    padding: 12px 12px 4px 12px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Drawer-safe section icon. Deliberately NOT .emr-section-icon — that class is a dark color-mix of
   text-primary built for white panels, which is invisible on the purple rail. */
.emr-nav-group-icon {
    color: var(--mud-palette-drawer-text);
}

/* Collapse chevron: pushed to the far end, and shrunk so it does not inflate the caption-height
   header row past the surrounding group headers. */
.emr-nav-group-toggle {
    margin-inline-start: auto;
    padding: 2px;
    color: var(--mud-palette-drawer-text);
}

/* Secondary line under a nav row's label (recent patients: MRN on top, name here). Block so the two
   spans stack inside MudNavLink's text container. */
.emr-nav-button__secondary {
    display: block;
    font-size: 0.75rem;
    line-height: 1.2;
    opacity: 0.7;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Mini rail: remove MudBlazor's 8px 16px padding and zero the 12px text margin */
.emr-nav-link--mini.mud-nav-item .mud-nav-link {
    width: calc(100% - 8px);
    margin-inline: 4px;
    padding: 4px 0 !important;
}

.emr-nav-link--mini .mud-nav-link-text {
    width: 100%;
    margin-left: 0 !important;
    margin-inline-start: 0 !important;
}

.emr-nav-badge {
    display: block;
    position: relative;
    margin-block: 4px;
}

.emr-nav-badge .emr-nav-link {
    margin-block: 0;
}

.emr-nav-badge .mud-badge-top.right.mud-badge-overlap {
    top: 50%;
    right: 12px;
    bottom: auto;
    left: auto;
    transform: translateY(-50%);
}

/* The count badge above is an absolutely-positioned overlay, not a flex sibling of the
   label — it reserves no space in normal flow. Without this, a long label ("Unsubmitted
   Encounters") uses the row's full width and its wrapped/unwrapped text runs straight
   under the badge instead of stopping short of it. */
.emr-nav-badge .mud-nav-link-text {
    padding-right: 28px;
}


.emr-section-header-badge {
    display: inline-flex;
    position: relative;
    padding-right: 30px;
}

.emr-section-header-badge .mud-badge {
    height: 22px;
    min-width: 22px;
    font-size: 0.8rem;
    padding: 0 5px;
}

.emr-section-header-badge .mud-badge-top.right.mud-badge-overlap {
    top: 50%;
    right: -4px;
    bottom: auto;
    left: auto;
    transform: translateY(-50%);
}

/* Clickable text in a grid or list. Always a MudButton Variant=Text. Purple = clickable. */
.emr-link.mud-button-root {
    text-transform: none;
    color: var(--mud-palette-primary);
    min-width: 0;
    padding: 2px 4px;
    justify-content: flex-start;
    text-align: left;
    font-weight: 400;
}

/* Left-edge alignment fix (audit §4, plan §B6): the 4px left padding above starts link text inside
   the cell while plain cell text starts at 0, so a grid row's link text sat 4px right of both the
   header caption above it and any plain-text sibling cell. Width-agnostic — applies at every width,
   including phone, since the defect exists at every width (Breakpoint.None renders link cells the
   same way regardless of band). Scoped to grid cells only so unrelated .emr-link buttons elsewhere
   (toolbars, dialogs) keep their own left inset. */
.mud-table-cell .emr-link.mud-button-root {
    padding-left: 0;
}

/* Grid headers top-align app-wide. At Tablet's fixed-layout percentage widths some titles wrap to
   two lines while their siblings stay on one; MudBlazor's vertical-align:inherit then centers the
   single-line titles against the wrapped ones. The needs grid's own bottom-align rule is more
   specific and still wins. */
.mud-table-head th.mud-table-cell {
    vertical-align: top;
}

/* Shared sortable-header layout (audit §4 sort-caret gap, plan §B6) — replaces the ad-hoc
   `MudStack Row Spacing="0"` each grid header used to wrap its caption + sort icon in. Zero gap plus
   a caption free to wrap (in a narrow column) read as the sort icon floating away from its caption;
   this fixes both: a real 4px gap, and `white-space: nowrap` so the caption never wraps and the icon
   is always exactly 4px after the last glyph. No icon slot is reserved — the 22px sort-icon
   allowance is already baked into every header width in plan §B4/§B5. Width-agnostic: MudBlazor's
   own `.column-header` flex layout is the same at every width, so the defect and the fix are too. */
.emr-grid-sort-header {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    cursor: pointer;
}

/* Primary identity item of a row — bold regardless of clickability. */
.emr-important {
    font-weight: 600 !important;
    color: var(--mud-palette-primary-darken) !important;
}

/* Bold, default-color text — same weight as .emr-important without its accent color. Used by the
   Pending Approval card, which shows primary-identity fields as plain black text (matching legacy)
   rather than this app's usual primary-darken accent. Scoped as its own class rather than changing
   .emr-important's color, since that class is shared across many other screens. */
.emr-neutral-important {
    font-weight: 600 !important;
}

/* Signature-capture draw pad (SignatureCaptureDialog) — a plain SVG pointer-event surface, no
   MudBlazor component provides this. Border/background/cursor here so the .razor file needs no
   inline style; sizing mirrors legacy's own sig-svg (see legacy-physician-signature-capture.md §2). */
.emr-signature-pad {
    width: 100%;
    height: 150px;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 4px;
    background: var(--mud-palette-background);
    cursor: crosshair;
    touch-action: none;
}

/* Orange "sign in the box above" hint next to Clear — legacy's #d08a2c inline style, ported as a
   class so it survives dark mode via a token instead of a hardcoded hex. */
.emr-signature-hint {
    color: var(--mud-palette-warning);
}

/* Shared "Preview" row (below the Draw/Select Style tabs, not inside them) — shows exactly what
   will be saved: ink + credential for Draw, "{Name}, {Credentials}" text for Select Style. Mirrors
   legacy's .sig-preview/.sig-preview-draw/.sig-preview-init (SignatureCaptureDialog.razor). */
.emr-signature-preview {
    flex: 1;
    min-height: 80px;
    display: flex;
    align-items: center;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 4px;
    padding: 6px 10px;
    font-family: 'Segoe Script', 'Brush Script MT', cursive;
    font-size: 1.25rem;
}

.emr-signature-preview-draw {
    align-items: flex-start;
    flex-direction: column;
    justify-content: center;
}

.emr-signature-preview-draw svg {
    width: 100%;
    height: 65px;
}

.emr-signature-preview-placeholder {
    font-family: 'Segoe UI', sans-serif;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-disabled);
}

.emr-signature-preview-initials {
    flex: 0 0 90px;
    justify-content: center;
}

/* Per-group issue count in the Encounter Issues accordion header (EncounterIssuesDialog). Kept short
   so the header row never grows taller than the expansion chevron next to it; same proportions as
   SectionErrorBadge's .section-error-chip so the two read as one visual language. */
.emr-issue-count-chip {
    height: 22px;
    font-weight: 700;
}

/* Error-group heading, shared by SectionErrorListDialog and EncounterIssuesDialog via
   EmrIssueGroupPanels (issue-group unification, 2026-08-17). NOT Color="Color.Error" + emr-important:
   both .mud-error-text and .emr-important are flat-selector !important rules of equal specificity, and
   app.components.css loads after MudBlazor.min.css, so emr-important's primary-darken silently wins the
   tie over the error red. A dedicated class avoids the collision. */
.emr-issue-group-heading {
    color: var(--mud-palette-error) !important;
    font-weight: 600;
}

/* Warning text that must stay legible on a light surface. MudBlazor paints Color="Color.Warning"
   text with the warning BASE (.mud-warning-text, !important), and the base is tuned as a fill —
   #e09600 is only 2.46:1 on white, under the 4.5:1 text floor. WarningDarken is the palette's
   text-safe amber, so route the label there and keep Color="Color.Warning" for the semantics.
   Equal specificity to .mud-warning-text (0,1,0) with !important on both, and app.components.css
   loads after MudBlazor.min.css, so source order decides. If this ever stops applying, check the
   link order in index.html first. Icons deliberately keep the base — see app.mudblazor.css. */
.emr-warning-text {
    color: var(--mud-palette-warning-darken) !important;
}

/* Warning variant of the heading above (EmrIssueGroupPanels Color="Color.Warning" — the Alerts
   dialog's Warnings tab). Uses warning-DARKEN, not the warning base: the base is tuned to work as a
   fill (#e09600, 2.46:1 on white) and misses the 4.5:1 text floor, while WarningDarken is the palette's
   text-safe amber. Still one source of truth — the value lives in EmrTheme.cs, not here. */
.emr-issue-group-heading--warning {
    color: var(--mud-palette-warning-darken) !important;
    font-weight: 600;
}

/* Bulleted item under an EmrIssueGroupPanels group. Caption-scale: a single group can hold many short
   field-name items ("End Section", 8+), so body2 reads as too heavy at that volume.
   --freetext items are standalone full-sentence instructions (e.g. the "Other" bucket) rather than short
   field names — a bullet in front of a sentence reads oddly, so they render without one. */
.emr-issue-list-item {
    font-size: var(--mud-typography-caption-size);
}

/* MudListItem wraps its content in .mud-list-item-text, which adds a 4px top/bottom margin on top of
   the Dense item's own 4px padding — 16px of air between lines, and an 8px extra gap under the group
   divider. Dropped so a group's items sit as one block. */
.emr-issue-list-item .mud-list-item-text {
    margin-top: 0;
    margin-bottom: 0;
}

/* EmrIssueGroupPanels (Alerts, Section Errors, Encounter Issues dialogs): each group reads as one
   compact block — heading row, hairline divider, items directly under it, one spacing unit (4px)
   before the next heading. Four things were stacking into the gaps:
   - MudBlazor gives every EXPANDED panel margin: 16px 0 (.mud-expand-panel.mud-panel-expanded); flex
     children do not collapse margins, so groups sat 32px apart. No parameter controls it.
   - app.mudblazor.css makes every accordion header 56px min-height with 18px top/bottom padding (iPad
     touch target); on a heading + chip row that put ~18px between heading and divider. Held at 44px here
     (the iPad touch floor) rather than shrunk further.
   - app.components.css gives every .mud-expand-panel-content a 12px top floor and MudBlazor adds 16px
     bottom; Dense on the panels (component parameter) zeroes both via .mud-expand-panel-dense.
   - .mud-list-item-text margin, handled above.
   Scoped under .emr-issue-groups so the global touch header and content floor are untouched elsewhere. */
.emr-issue-groups .mud-expand-panel.mud-panel-expanded {
    margin: 0;
}

.emr-issue-groups .mud-expand-panel + .mud-expand-panel {
    margin-top: 4px;
}

.emr-issue-groups .mud-expand-panel .mud-expand-panel-header {
    min-height: 44px;
    padding-top: 4px;
    padding-bottom: 4px;
}

.emr-issue-list-item:not(.emr-issue-list-item--freetext)::before {
    content: "\2022";
    margin-right: 8px;
    color: var(--mud-palette-text-secondary);
}

/* EmrPagination page-number badge — soft primary tint, pill shape, same height as icon buttons.
   .mud-typography selector raises specificity to beat MudBlazor's body2 line-height;
   display:flex makes the span a flex container so the anonymous text node can be centered. */
.emr-pagination-page.mud-typography {
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--mud-palette-primary) 12%, transparent);
    color: var(--mud-palette-primary);
    font-weight: 600;
    border-radius: 18px;
    padding: 0 18px;
    height: 36px;
    min-width: 44px;
    line-height: normal;
}

.emr-pagination-page.emr-pagination-page--disabled.mud-typography {
    background: var(--emr-hairline);
    color: rgba(0, 0, 0, 0.38);
}

.landing-patient-grid .mud-table-root {
    width: 100%;
}

.landing-patient-grid .mud-table-cell {
    padding: 6px 4px !important;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Stacked wrapper: icon above, label below */
.emr-nav-mini-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    text-align: center;
    padding: 4px 0;
}

.emr-nav-mini-icon {
    font-size: 1.2rem !important;
    margin-bottom: 2px;
}

/* overflow-wrap: break-word (word-boundary-first), not anywhere -- matches the standard open-drawer
   nav row's already-correct .emr-nav-link-text treatment (2026-09-10 audit: no text container should
   default to `anywhere`). -webkit-line-clamp gives the 3-line cap (max-height's previous role) a real
   truncation signal (ellipsis) instead of silently hard-clipping mid-word with no visual indication. */
.emr-nav-mini-wrapper .emr-nav-button__label {
    font-size: 0.65rem;
    line-height: 1.15;
    white-space: normal;
    overflow: hidden;
    overflow-wrap: break-word;
    max-width: 76px;
    max-height: 3.45em;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

/* Active state: color the custom icon in mini mode */
.emr-nav-active .emr-nav-mini-icon {
    color: var(--mud-palette-primary) !important;
}

@media (max-width: 599.98px) {
    .emr-appbar .mud-toolbar {
        padding-left: 8px;
        padding-right: 8px;
    }
}


/* 02.3  User Info (App Bar) */

.emr-user-info {
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.15;
    margin-left: 0.5rem;
}

.emr-user-info-clickable {
    cursor: pointer;
}

.emr-user-info-line {
    color: var(--mud-palette-text-primary);
    font-weight: 400;
}

.emr-user-info-meta {
    color: var(--mud-palette-text-secondary);
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}

.emr-user-info-discipline {
    color: var(--mud-palette-primary);
    font-weight: 500;
}

.emr-user-info-env {
    color: var(--mud-palette-success);
    font-weight: 500;
}

/* PBI 4287: visible text marker, not a tooltip — tablets have no hover. */
.emr-user-info-discipline-override {
    color: var(--mud-palette-warning);
    font-weight: 500;
    font-style: italic;
}

.emr-impersonation-button {
    color: var(--mud-palette-text-secondary);
    margin-left: -0.15rem;
}

.emr-impersonation-button-active {
    color: var(--mud-palette-primary);
}


.emr-impersonation-id-field {
    width: 120px;
}


/* #endregion */
/* #region 03  Toolbar */

/* Home/Patient shell's app-bar tool cluster. The buttons themselves are EmrToolbarButton
   (.toolbar-icon-btn, defined in section 06.2 below) — this just lays out the row. */
.emr-toolbar-group {
    display: flex;
    align-items: center;
}

/* Toolbar group: tighter spacing on phone, where Search/Favorites/My Links/My Team have
   already collapsed into the "More" menu (EmrToolbarOverflow) and only Connectivity +
   Impersonate remain inline. */
@media (max-width: 599.98px) {
    .emr-toolbar-group {
        gap: 0;
    }
}


/* #endregion */
/* #region 04  Layout / Page Shell */

.emr-page-scroll-host {
    height: 100%;
    overflow: hidden;
}

.emr-page-scroll-content {
    flex: 1;
    /* min-width:0 lets this flex item shrink below the grid's intrinsic width so
       the inner overflow:auto contains horizontal scroll instead of widening the page. */
    min-width: 0;
    overflow: auto;
}

/* Leave MudBlazor's built-in top padding (appbar offset) alone; only add side/bottom padding and
   background. ADO #4210: side padding trimmed from 24px (1.5rem) to 8px — the wider value wasted
   too much usable screen width, worst on smaller devices where every pixel of content width
   counts. Kept symmetric with the phone media query below, which already used 8px. */
.emr-main-content {
    padding-top: calc(var(--emr-appbar-height) + 1.5rem);
    padding-right: 8px;
    padding-bottom: 1.5rem;
    padding-left: 8px;
    background-color: var(--mud-palette-background);
    min-height: 100vh;
    box-sizing: border-box;
}

.emr-search-field { min-width: 220px; max-width: 400px; flex: 1 1 auto; }

/* Separates the search / paginator row from the tab strip below it, so the two read as distinct
   controls rather than one run-on band (developer-directed 2026-09-02). */
.emr-toolbar-divider {
    border-color: var(--emr-hairline);
}

.emr-patient-search-input {
    width: 100%;
}

.emr-patient-panel {
    overflow: hidden;
    border-color: var(--emr-hairline);
    background-color: var(--mud-palette-surface);
}

/* Patient profile section panels: same outlined, rounded surface as .emr-patient-panel.
   Two classes each so this beats MudBlazor's .mud-expand-panel.mud-panel-expanded and
   :first-child / :last-child rules, which set border-radius: inherit (0 here) and drop the
   bottom border on an expanded panel. */
.mud-expand-panel.emr-info-card,
.mud-expand-panel.emr-be-aware-card {
    border: 1px solid var(--emr-hairline);
    border-radius: var(--mud-default-borderradius);
    overflow: hidden;
    background-color: var(--mud-palette-surface);
}

.emr-patient-panel-icon {
    color: color-mix(in srgb, var(--mud-palette-text-primary) 42%, transparent);
}

/* SPC-014: .emr-patient-panel-controls removed — border-left separator migrated to MudDivider Vertical in all toolbars */

/* Content area: reduce side/bottom padding on phone, preserve app bar offset.
   overflow-x:hidden clips MudGrid's negative-margin gutters that would otherwise
   widen the page and cause page-level horizontal scroll on card-based pages. */
@media (max-width: 599.98px) {
    .emr-main-content {
        padding-top: calc(var(--emr-appbar-height) + 8px) !important;
        padding-right: 8px !important;
        padding-bottom: 8px !important;
        padding-left: 8px !important;
        overflow-x: hidden;
    }
}


/* #endregion */
/* #region 05  Drawer / Detail Panel */

/* Pull the detail drawer to full viewport height, covering the appbar zone so the
   dark html/body splash background never shows through the top gap. */
.emr-detail-panel {
    top: 0 !important;
    height: 100vh !important;
    background-color: var(--mud-palette-surface);
}

.emr-detail-panel .mud-drawer-content {
    padding-top: 0 !important;
}

.emr-details-drawer-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding-top: var(--mud-appbar-height);
}

.emr-details-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-white);
    padding: 8px 8px 8px 16px;
    flex-shrink: 0;
}

.emr-details-drawer-header .mud-button-root,
.emr-details-drawer-header .mud-icon-button {
    color: var(--mud-palette-white);
}

.emr-details-drawer-body {
    background-color: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px 12px 80px 12px;
}

/* Alerts and Warnings icon row — horizontal, wraps on very narrow panels */
.emr-alerts-row {
    flex-wrap: wrap;
}


/* #endregion */
/* #region 06  Typography / Data Display */

/* Section header — used for all named groups in a drawer or panel.
   CSS owns all typography so Typo= in Razor is not needed and must not override it. */
.emr-section-header {
    font-size: var(--mud-typography-body1-size);
    font-weight: var(--mud-typography-subtitle2-weight);
    line-height: var(--mud-typography-subtitle2-lineheight);
    letter-spacing: var(--mud-typography-subtitle2-letterspacing);
    color: var(--mud-palette-primary);
}

/* Decorative icon paired with a section header (expansion panel title, named section row).
   Muted so it recedes behind the primary-colored header text (CMP-041). */
.emr-section-icon {
    color: color-mix(in srgb, var(--mud-palette-text-primary) 42%, transparent);
}

/* Field label — the "key" of a key-value pair in any detail view.
   CSS owns typography; remove Typo= from MudText when using this class. */
.emr-field-label {
    font-size: var(--mud-typography-caption-size);
    font-weight: 600;
    line-height: var(--mud-typography-caption-lineheight);
    letter-spacing: var(--mud-typography-caption-letterspacing);
    color: var(--mud-palette-dark);
}

/* Field value — the "value" of a key-value pair.
   CSS owns typography; remove Typo= from MudText when using this class. */
.emr-field-value {
    font-size: var(--mud-typography-caption-size);
    font-weight: var(--mud-typography-caption-weight);
    line-height: var(--mud-typography-caption-lineheight);
    letter-spacing: var(--mud-typography-caption-letterspacing);
    color: var(--mud-palette-dark);
}

/* Row wrapper for label/value pairs — layout only, no visual opinions */
.emr-info-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}

/* Caption-size font for table rows in expansion panels — !important beats mud-table-cell specificity */
.emr-row-caption td {
    font-size: 0.75rem !important;
}

/* Compact label above a grid section (Entries tab "Interventions", legacy IntervalChartHome.razor:584).
   NOT .emr-section-header: that class is purple/primary, which legacy does not use here — text-secondary
   is the closer match. MudBlazor's default subtitle2 weight (--mud-typography-subtitle2-weight, 500)
   reads lighter than legacy's inline font-weight:700, so this uses the literal weight instead of the
   typography token (developer-directed 2026-09-02). */
.emr-grid-section-label {
    font-weight: 700;
    color: var(--mud-palette-text-secondary);
}


/* #endregion */
/* #region 07  KPI Cards / Dashboard */

.emr-kpi-mobile-paper {
    overflow: hidden;
}

.emr-kpi-mobile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    cursor: pointer;
    user-select: none;
}

.emr-kpi-mobile-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.65rem 1rem;
    cursor: pointer;
    user-select: none;
    color: var(--mud-palette-text-primary);
    transition: background-color 0.1s;
}

.emr-kpi-mobile-row:active {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 6%, transparent);
}

.emr-kpi-mobile-row-active {
    color: var(--mud-palette-primary) !important;
}

.emr-kpi-mobile-row-zero {
    color: var(--mud-palette-text-disabled);
}

.emr-kpi-mobile-row-count {
    min-width: 1.5rem;
    text-align: right;
    font-weight: 500;
}

.emr-kpi-mobile-reset {
    display: flex;
    justify-content: flex-end;
    padding: 0.25rem 0.5rem;
}

.emr-kpi-card {
/*    border: 1px solid color-mix(in srgb, var(--mud-palette-text-primary) 12%, transparent); */
    background-color: var(--emr-kpi-card-bg);
    transition: border-color 0.15s ease, background-color 0.15s ease;
    height: 100%;
    cursor: pointer;
}

.emr-kpi-card-disabled {
    cursor: default;
    pointer-events: none;
}

.emr-kpi-card:hover {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent);
}

.emr-kpi-card-active {
    border-color: var(--mud-palette-primary) !important;
    background-color: var(--mud-palette-primary) !important;
}

.emr-kpi-count {
    min-width: 2rem;
    font-weight: 300;
    line-height: 1;
    color: var(--emr-kpi-muted-text);
}

.emr-kpi-count-active {
    color: var(--mud-palette-white);
}

.emr-kpi-title {
    font-weight: 400;
    line-height: 1.2;
}

.emr-kpi-subtitle {
    line-height: 1.2;
    color: var(--emr-kpi-muted-text) !important;
}

.emr-kpi-subtitle-active {
    line-height: 1.2;
    color: var(--emr-kpi-muted-text-active) !important;
}

.emr-kpi-title-active {
    color: var(--mud-palette-white) !important;
}

.emr-kpi-row-static {
    cursor: default;
}


/* #endregion */
/* #region 08  Grid / Table */

.emr-row-selected td {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 10%, transparent) !important;
}

/* COL-023 / CMP-025: use token instead of raw hex */
.grid-row-active { background-color: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent); font-weight: 500; }
/* BR-166 — Shift POC tab above-goal row (symptom_warning_original.png): red-tinted row, every
   cell's text in error red, symptom name bold. All four !important overrides here are necessary,
   not decorative -- confirmed via a render probe of the actual MudDataGrid markup (Dense/Striped),
   not assumed:
   - background: MudBlazor's own .mud-table-row-stripe sets a background-color on the SAME <tr>
     (equal specificity), so a plain declaration is a coin flip; !important removes the ambiguity.
   - .mud-table-cell (the <td> itself) carries MudBlazor's own explicit
     `color: var(--mud-palette-text-primary)`. The four plain-value cells (Current Level/At, Goal
     Level/Date) are raw text or an unstyled <p> nested directly in that <td> with no color of
     their own, so they inherit from the <td> -- and inheritance always loses to that <td>'s own
     explicit (even non-!important) rule, never reaching a color set on the ancestor <tr>. Only
     overriding .mud-table-cell's color directly reaches them.
   - .emr-shift-poc-type / .emr-important set their own explicit color directly on the symptom
     name / type-tag <p> elements (same collision class as .emr-issue-group-heading above), so
     they need their own overrides too -- the .mud-table-cell override above does not reach them,
     since they have an explicit rule of their own blocking inheritance the same way. */
.emr-row-above-goal {
    background-color: color-mix(in srgb, var(--mud-palette-error) 8%, transparent) !important;
    font-weight: 600;
}
.emr-row-above-goal .mud-table-cell,
.emr-row-above-goal .emr-shift-poc-type,
.emr-row-above-goal .emr-important {
    color: var(--mud-palette-error) !important;
}

/* Shift POC tab (legacy "shiftPOC_original.png"): careplan section header is a solid purple bar
   with white text, matching .emr-dialog's title-bar / .emr-patient-search-header's established
   convention. MudExpansionPanel's class names differ from the "expansion-panel" name you'd guess
   from the component name -- .mud-expand-panel-header, confirmed via a render probe rather than
   assumed. Scoped to .emr-shift-poc-panels so this never leaks onto an unrelated expansion panel
   elsewhere in the app. */
.emr-shift-poc-panels .mud-expand-panel-header {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-white);
    border-radius: 0;
    padding: 6px 16px;
    min-height: 0;
}

.emr-shift-poc-panels .mud-expand-panel-header .mud-expand-panel-icon {
    color: var(--mud-palette-white);
}

/* The careplan name itself -- NOT .emr-section-header, whose purple text color would sit
   invisibly on this same bar's purple background (developer-reported 2026-09-08 "missing the
   careplan name" -- it was rendering, just the same color as its own background). */
.emr-shift-poc-careplan-name {
    color: var(--mud-palette-white);
    font-weight: 700;
}

/* The "Symptoms / Needs / PONs" / "Interventions" sub-header band under each careplan -- a
   light tint of the same purple, bold uppercase purple text (legacy mock). text-transform, not
   an uppercase string literal, so the underlying text stays normal-case for anything reading the
   DOM (tests, screen readers). */
.emr-shift-poc-subheader {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 12%, transparent);
    color: var(--mud-palette-primary);
    font-weight: 700;
    text-transform: uppercase;
    padding: 4px 8px;
}

/* Type column ("PON" / "Need" / "Symptom") -- muted, distinct from the bold symptom/intervention
   name next to it (legacy mock). */
.emr-shift-poc-type {
    color: var(--mud-palette-text-secondary);
}

/* Every width, not just >960px: same reason as .landing-patient-grid .mud-table-root below —
   an auto-layout table only obeys the fixed-layout percentages once it also fills its container,
   otherwise it just shrinks to its content and the percentages never engage. Cells ellipsize
   rather than wrap so a long value degrades to "…" instead of forcing the column wider. */
.emr-workitems-grid .mud-table-root {
    width: 100%;
}

.emr-workitems-grid .mud-table-cell {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Status chip opts out of the ellipsize-by-default rule above — B7's status chip has no max-width
   and must never clip to "…", even if the sized column comes in a few px under its target. */
.emr-workitems-grid .mud-table-cell.emr-col-status {
    overflow: visible;
    text-overflow: unset;
}

/* Fixed-width grid columns for the workitems grid. */
.emr-col-nowrap     { white-space: nowrap; }
.emr-col-word-break { word-break: break-all; }

/* Entries tab grid (EntriesTab) — legacy IntervalChartHome.razor's MudSimpleTable inline-styles
   every <th> to font-weight:700; MudBlazor 8 ships no bold-header utility, so the grid opts in via
   this class instead of per-column HeaderClass. Replaces the removed .emr-col-header-strong,
   which only covered one column. */
.emr-entries-grid th {
    font-weight: 700;
}

/* Fixed-width grid columns for the Entries tab grid (legacy <th> widths). Interventions/Elaborations
   is intentionally unset — it absorbs the remaining row width, same as legacy.
   Symptom is the one deliberate departure: legacy sets 150px, which wraps a typical authored
   need ("Discourage factors that provoke PAIN symptoms") onto four lines. 220px brings that to
   two, and the width comes out of Interventions/Elaborations, which absorbs the remainder
   (developer-directed 2026-09-02). */
.emr-col-entries-time      { width: 110px; }
.emr-col-entries-careplan  { width: 150px; }
.emr-col-entries-symptom   { width: 220px; }
.emr-col-entries-severity  { width: 110px; }
.emr-col-entries-status    { width: 100px; }
.emr-col-entries-by        { width: 130px; }

/* Entries tab Interventions/Elaborations cell — legacy Style="font-weight: 700;" with no color
   override. NOT .emr-important: that class also forces the primary/purple color, which legacy
   does not use here. */
.emr-entries-detail {
    font-weight: 700;
}

/* Shared expander-column width (HierarchyExpanderColumn's HeaderClass, plan §B1 item 6 — renamed
   from emr-col-rowaction so PatientGrid's pin/UE + favorite columns, which keep that name, can never
   collide with the expander again). Unscoped so every grid that renders the widget and does not
   declare its own per-band width (the ~10 grids untouched by this plan) keeps its current 40px
   expander, same as the old .emr-col-rowaction base rule did. Grids/bands with their own measured
   width (e.g. .emr-workitems-grid--tablet .emr-col-expander below) override it by
   specificity. */
.emr-col-expander { width: 40px; }

/* Fixed-width grid columns for the landing patient grid. Replaces per-column HeaderStyle=
   inline widths so the phone rules below can relax them without !important. */
.emr-col-rowaction      { width: 40px; }
.emr-col-name           { min-width: 140px; }
.emr-col-mrn            { width: 90px; }
.emr-col-patient-status { width: 90px; }
.emr-col-statusdate     { width: 100px; }
.emr-col-loc            { width: 50px; }
.emr-col-institution    { width: 110px; }
.emr-col-program        { width: 75px; }
.emr-col-team           { width: 75px; }
.emr-col-fc             { width: 55px; }

/* Every width, not just phone. The name renders inside a MudButton, and MudBlazor buttons are
   white-space:nowrap — a long name becomes one unbreakable box that stretches the Name column past
   its 140px and pushes the right-hand columns out of the viewport. Above phone width there is no
   phone card to fall back on and HorizontalScrollbar="false" leaves nothing to scroll, so on a
   tablet (Breakpoint.Sm/Md, 600-1279px, where IsPhone is false) those columns are simply clipped.
   Wrapping the name to a second line inside the column it already has is what keeps the table narrow. */
.landing-patient-grid .emr-link.mud-button-root {
    white-space: normal;
    text-align: left;
}

/* All-columns layout, >=960px (bug 4281) — was >=1280px (desktop-only) until the wide (Md,
   960-1399px) Tablet sub-band started rendering all columns too instead of folding six of them
   (PatientGrid.razor.cs FoldsColumns). At Md the grid never carries the `.landing-patient-grid--tablet`
   modifier (that class is Sm-only now — see the `--tablet` block below), so extending this block's
   media query down to 960px is safe: the two blocks never both match the same element. Tablet
   (Sm only now, 600-959px) gets its own folded column set below (.landing-patient-grid--tablet)
   instead of these percentages. Legacy fits all ten columns at every width by letting the columns
   divide the table; ours declared ~865px of fixed px, and an auto-layout table grows past its
   container to honour them. With HorizontalScrollbar="false" and .emr-patient-panel
   overflow:hidden there is nothing to scroll, so whatever does not fit is clipped outright — which
   is why iPad loses the right-hand columns instead of scrolling to them, and why landscape can lose
   MORE than portrait: a fixed-width table does not adapt, so what survives depends on where the
   clip falls, not on how much room there is.

   Fixed layout + percentages makes the table mathematically unable to exceed its container: the
   columns shrink together and cells ellipsize (.landing-patient-grid .mud-table-cell above). Same
   technique as the phone block below, same reason percentages rather than px + auto. Percentages
   fit the ~950px content width a 1080px iPad-landscape viewport leaves after the mini drawer, same
   as any wider desktop viewport, because they are proportional rather than fixed px.

   Cell padding standardized to 16px horizontal (6px 8px), 12px on the first cell — audit §3's
   finding that inconsistent padding (this grid's old 8px vs. workitems' inherited 40px dense
   padding) was itself a cause of the wrap/dead-space defects (plan §A2). The last cell's 12px
   padding-right comes from the shared .mud-table-cell:last-child rule above, not repeated here.

   Widths below are `target px ÷ reference width`, not hand-tuned round numbers (plan §A4/§B5):
   desktop reference is 1306px (measured/derived, see plan §A4, OQ-2), iPad reference is 890px
   (measured on-device at a 1024px viewport). Favorite now carries its own .emr-col-favorite class
   (plan §B1 item 6) instead of sharing .emr-col-rowaction with the pin/UE column and being narrowed
   via a fragile :last-of-type selector — that selector broke the moment an iPad expander column
   (also historically .emr-col-rowaction-shaped) entered the picture. Widths sum to 100 in each tier.

   MRN bumped 6%->7% (Name 30%->29%) when this block's floor dropped to 960px (bug 4281): at the
   wide-tablet content width (~950px, iPad landscape with mini drawer) 6% (~57px) clipped an 8-digit
   MRN's ~64px content — confirmed with a static repro of this exact markup/CSS pair against real
   Chromium layout; Name has slack to give up a point without wrapping. */
@media (min-width: 960px) {
    .landing-patient-grid .mud-table-root {
        table-layout: fixed;
    }

    .landing-patient-grid .mud-table-cell {
        padding: 6px 8px;
    }

    .landing-patient-grid .mud-table-cell:first-child {
        padding-left: 12px;
    }

    .landing-patient-grid .emr-col-rowaction      { width: 9%; }
    .landing-patient-grid .emr-col-name           { width: 29%; min-width: 0; }
    .landing-patient-grid .emr-col-mrn            { width: 7%; }
    .landing-patient-grid .emr-col-patient-status { width: 8%; }
    .landing-patient-grid .emr-col-statusdate     { width: 9%; }
    .landing-patient-grid .emr-col-loc            { width: 5%; }
    .landing-patient-grid .emr-col-institution    { width: 12%; }
    .landing-patient-grid .emr-col-program        { width: 7%; }
    .landing-patient-grid .emr-col-team           { width: 5%; }
    .landing-patient-grid .emr-col-fc             { width: 4%; }
    .landing-patient-grid .emr-col-favorite       { width: 5%; }
}

/* Folded Tablet sub-band (`.landing-patient-grid--tablet`, PatientGrid.razor.cs FoldsColumns —
   Sm only now, 600-959px). Bug 4281: this class used to apply across the whole LayoutContext.IsTablet
   range (Sm/Md, 600-1279px before the Lg=1400 override; 600-1399px after), which made Md
   (iPad-landscape, 960-1399px) fold columns it has plenty of room for. The grid now only adds this
   class when FoldsColumns is true — Md instead falls through to the all-columns block above (its
   media query starts at 960px), so this selector and that one's media query never both match the
   same element and there is no specificity fight to reason about at Md.

   Revised 2026-09-19: developer reported this grid still forced horizontal scrolling on iPad
   portrait — Status Date and Team, kept as real columns below, added enough width that the row
   overflowed even before the missing `table-layout: fixed` (just added) is accounted for. Legacy's
   equivalent view at this width showed only Name/MRN/Status plus the favorite star; Status Date and
   Team now fold into the same expandable child row LOC/Institution/Program/FC already use, leaving
   six visible columns: expander, actions (offline-pin/UE), Name, MRN, Status, Favorite.

   `table-layout: fixed; width: 100%;` was missing from this block entirely — every other grid's
   `--tablet` selector (encounters, medications, allergies/hme, diagnoses/physicians/other-orders,
   caregivers/staff) sets it unscoped, since the modifier class itself is what scopes "tablet" here,
   not a media query. Without it the table used the browser's default auto layout, which sizes
   columns from content and ignores the percentages below as hints only — that is what actually
   produced the scrollbar/clipped-Favorites defect, independent of the column count.

   Widths are the prior six-column shares proportionally redistributed to 100 after removing
   Status Date (14%) and Team (8%) — old-share × (100 ÷ 78) — not a fresh on-device remeasurement;
   revisit against a real iPad if Name or Status still feel tight. */
.landing-patient-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.landing-patient-grid--tablet .emr-col-rowaction      { width: 17%; }
.landing-patient-grid--tablet .emr-col-name           { width: 38%; }
.landing-patient-grid--tablet .emr-col-mrn            { width: 12%; }
.landing-patient-grid--tablet .emr-col-patient-status { width: 14%; }
.landing-patient-grid--tablet .emr-col-favorite       { width: 9%; }
.landing-patient-grid--tablet .emr-col-expander       { width: 10%; }

/* Phone (matches LayoutContext.IsPhone at Breakpoint.Xs) — the six wide columns are already
   removed in markup; the four that remain must be free to shrink, or their desktop widths add up
   past a phone viewport and the grid clips with HorizontalScrollbar="false". Pinned to phone only,
   not widened to Tablet's 1279.98px: this is the phone-specific 4-column set, distinct from
   Tablet's own 6-column set (.landing-patient-grid--tablet above) — widening would let this rule's
   percentages collide with (and, by source order, override) the Tablet block at Tablet widths. */
@media (max-width: 599.98px) {
    /* An auto-layout table grows to its content's min-width no matter what widths the columns ask
       for, which pushed the expander past the viewport and produced a horizontal scroll. Fixed
       layout makes the table honour its container; the columns below then divide that width. */
    .landing-patient-grid .mud-table-root {
        table-layout: fixed;
    }

    /* Percentages summing to 100, NOT px + auto. Under fixed layout an auto column only gets what
       the fixed ones leave over, and the expanded child row is wide enough to take all of it — that
       collapsed the Name column to zero width the moment a row was expanded. Percentages are
       resolved from the table width alone, so expanding a row cannot resize the columns.
       At 390px this is roughly 179 / 86 / 82 / 43 px; the last clears the 44px touch target. */
    .landing-patient-grid .emr-col-name { width: 46%; min-width: 0; }
    .landing-patient-grid .emr-col-mrn { width: 22%; }
    .landing-patient-grid .emr-col-patient-status { width: 21%; }
    .landing-patient-grid .emr-col-expander { width: 11%; }
}

/* Touch targets in grid rows. Grouped with the needs-grid rule in block 20, which sets the same
   44px floor for the same reason. */
@media (pointer: coarse) {
    .landing-patient-grid .mud-table-cell .mud-icon-button,
    .emr-workitems-grid .mud-table-cell .mud-icon-button,
    .emr-encounters-grid .mud-table-cell .mud-icon-button,
    .emr-medications-grid .mud-table-cell .mud-icon-button,
    .emr-allergies-grid .mud-table-cell .mud-icon-button,
    .emr-hme-grid .mud-table-cell .mud-icon-button,
    .emr-diagnoses-grid .mud-table-cell .mud-icon-button,
    .emr-physicians-grid .mud-table-cell .mud-icon-button,
    .emr-other-orders-grid .mud-table-cell .mud-icon-button,
    .emr-caregivers-grid .mud-table-cell .mud-icon-button,
    .emr-staff-grid .mud-table-cell .mud-icon-button {
        min-width: 44px;
        min-height: 44px;
    }
}

/* HierarchyExpanderColumn's chevron toggle (2026-09-10 audit: sat flush against the row/panel edge
   on narrower widths, e.g. WorkitemsGrid "All Tasks" on iPad portrait). TemplateColumn only exposes
   HeaderClass -- not a body CellClass -- for this column, so .emr-col-expander reaches its <th> but
   never its <td>; :first-child is the only CSS-only hook available without touching
   HierarchyExpanderColumn.razor. Same grid list as the touch-target rule above.
   Grid Tiering Standard (responsive-grid-tiering, Phase 1/2): the chevron moved from trailing to
   leading position in every one of these grids' <Columns> declaration, so the flush edge it needs
   room against is now the LEFT edge, not the right — this rule moved from :last-child/padding-right
   to :first-child/padding-left with it. When the chevron column is Hidden (Desktop, or any tier
   that folds nothing), :first-child falls through to whatever real data column now leads the row,
   which already carried its own left padding from the per-grid tier blocks below — this rule simply
   guarantees the 12px floor never regresses under it. 12px minimum edge padding, same universal
   convention as the expansion-panel floor above; !important matches the specificity of each grid's
   own base .mud-table-cell padding override it needs to beat. */
.landing-patient-grid .mud-table-cell:first-child,
.emr-workitems-grid .mud-table-cell:first-child,
.emr-encounters-grid .mud-table-cell:first-child,
.emr-medications-grid .mud-table-cell:first-child,
.emr-allergies-grid .mud-table-cell:first-child,
.emr-hme-grid .mud-table-cell:first-child,
.emr-diagnoses-grid .mud-table-cell:first-child,
.emr-physicians-grid .mud-table-cell:first-child,
.emr-other-orders-grid .mud-table-cell:first-child,
.emr-caregivers-grid .mud-table-cell:first-child,
.emr-staff-grid .mud-table-cell:first-child {
    padding-left: 12px !important;
}

/* Every width, not just phone. Task and Patient render inside a MudButton, and MudBlazor buttons
   are white-space:nowrap — a long name becomes one unbreakable box that stretches its column past
   whatever percentage it was given and pushes the columns after it out of the viewport. Above
   phone width there is no phone card to fall back on, .emr-patient-panel is overflow:hidden, and
   HorizontalScrollbar is not used, so with nothing to scroll a tablet would simply clip. Wrapping
   the link text to a second line inside the column it already has is what keeps the table narrow,
   same fix PR 4814 hoisted out of the phone query for the landing patient grid. */
.emr-workitems-grid .emr-link.mud-button-root {
    white-space: normal;
    text-align: left;
}

/* Desktop only (>=1280px) — Tablet (600-1279px) gets its own column set below
   (.emr-workitems-grid--tablet) instead. Same defect PR 4814 fixed for the landing patient grid: an auto-layout
   table grows to its content's width, and with .emr-patient-panel overflow:hidden and no
   horizontal scrollbar there is nothing to scroll, so a tablet clips the right-hand columns
   outright instead of showing them. Fixed layout + percentages makes the table mathematically
   unable to exceed its container: the columns shrink together and cells ellipsize
   (.emr-workitems-grid .mud-table-cell above).

   The expander column (HierarchyExpanderColumn, Hidden="@(!ShowExpander)") is absent at this width
   too — wide desktop (Breakpoint.Lg+) is the one band where ShowExpander is false. Status is back as
   its own sortable column (plan §B7 / audit §5) instead of folding into the Task cell's second line,
   so the desktop set is now eight: Task, Patient, Status, Assigned To, Team, Due Date, Updated Date,
   Updated By. Patient stays visible here even on Patient Tasks — HidePatientColumn is IsPhone &&
   !ShowPatientLink, which is always false once IsPhone is false, so ShowPatientLink only ever hides
   the column on phone.

   Cell padding standardized to 16px horizontal (6px 8px), 12px on the first cell (plan §A2) — this
   grid inherited MudBlazor's 40px dense padding with no override, which alone ate 280px of a ~890px
   iPad row and is why columns wrapped "despite free space" (plan §A2/§A3). The last cell's 12px
   padding-right comes from the shared .mud-table-cell:last-child rule above, not repeated here.

   Widths below are `target px ÷ 1306px` (plan §A4 desktop reference; see OQ-2), not hand-tuned round
   numbers — that derivation is itself the §3 fix. Status gets the widest content-driven share
   (170px for "Pending Manual Workflow" / "Pending Signed Document", the longest real status labels,
   plan §A3) with no max-width/ellipsis, reversing the two workarounds audit §5 rejected. Assigned To
   and Team are the ADO-4158-era Assigned Employee / Assigned Team columns, renamed per plan §B2 (the
   caption, not the value, drove their old widths). Widths sum to 100.

   Task, Status and Due Date were re-measured after the exact-fit targets above visibly failed on a
   real render: Status's chip text spilled past its own pill border and Due Date's "MM/dd/yyyy" value
   clipped to "08/25…", both at their originally computed 14%/7% (zero margin over the 170px/89px
   content targets — a chip border or a font-rendering rounding difference was enough to tip either
   over). Task was also flagged as visibly over-wide at its original 29% (379px) against its actual
   content need (~230px, including the inline Vx icon added after this plan). Task is trimmed to the
   room it actually needs; the freed width goes to Status and Due Date as real margin, not another
   exact fit — sized to survive rendering variance the plan's derivation could not. */
@media (min-width: 1280px) {
    .emr-workitems-grid .mud-table-root {
        table-layout: fixed;
    }

    .emr-workitems-grid .mud-table-cell {
        padding: 6px 8px;
    }

    .emr-workitems-grid .mud-table-cell:first-child {
        padding-left: 12px;
    }

    .emr-workitems-grid .emr-col-task     { width: 20%; }
    .emr-workitems-grid .emr-col-patient  { width: 14%; }
    .emr-workitems-grid .emr-col-status   { width: 18%; }
    .emr-workitems-grid .emr-col-employee { width: 12%; }
    .emr-workitems-grid .emr-col-assignedteam { width: 7%; }
    .emr-workitems-grid .emr-col-duedate  { width: 9%; }
    .emr-workitems-grid .emr-col-updated  { width: 10%; }
    .emr-workitems-grid .emr-col-updatedby { width: 10%; }
}

/* Tablet tier (Sm/Md, 600-1279px — LayoutContext.IsTablet) — ADO 4158 follow-up,
   extended by plan §B2/§B4: Due Date no longer folds into the expander at this band (audit §2's
   headline fix — it was hidden alongside Updated Date/Updated By with no documented rule), and
   Status joins as a real column instead of the Task cell's second line (plan §B7). Assigned To and
   Team still fold into the expandable child row phone already has — HierarchyExpanderColumn's
   Hidden binds to !ShowExpander (IsPhone || IsTablet), so the chevron appears here too, for
   Assigned To, Team, Updated Date, Updated By (count 4).

   Five columns instead of eight, so this needs its own percentages, not the wide-desktop block
   above — same selector shape and specificity, so source order is what makes this one win whenever
   emr-workitems-grid--tablet is present. Widths are `target px ÷ 890px` (plan §A4 iPad
   reference, measured on-device at a 1024px viewport) and sum to 100, including the expander.

   .emr-col-expander is 9%, not the round 5% the leftover math would otherwise suggest: at the ~890px
   iPad table area, 5% (~44px) exactly matches the chevron button's own 44px touch-target floor with
   nothing left for the .mud-table-cell:last-child 12px padding-right rule above — the button
   overflowed past the cell's right edge instead of leaving a gap (confirmed: measured a -15px
   overlap on real iPad Pro dimensions). 9% (~80px) clears 44px button + 12px padding with a clean
   ~12px gap, confirmed on a real device — this overrides the shared 40px .emr-col-expander base
   below for this grid/band only.

   Task/Status/Due Date re-measured after a real render: the original 41/21/10 split (target px with
   no margin) let Status's chip text spill past its pill border and clipped Due Date's value to
   "08/25…", while Task sat visibly over-wide at 41% (365px) against its actual need (~230px with the
   inline Vx icon). Same fix as the desktop block above — trim Task to its real requirement, give the
   freed width to Status and Due Date as margin rather than another zero-tolerance exact fit. */
/* The percentages below are inert without this. `.emr-workitems-grid .mud-table-root` sets
   width:100% unconditionally but declares table-layout:fixed only inside @media (min-width:1280px),
   so at Tablet the table stays auto-layout and treats every percentage as a hint it may ignore —
   the table then sizes from content and overflows the iPad-portrait table area. The landing patient
   grid had the identical omission and produced a visible horizontal scrollbar on iPad portrait. */
.emr-workitems-grid--tablet .mud-table-root {
    table-layout: fixed;
}

/* Due Date is 21%, not the 14% this block carried first. 14% was derived against a ~890px table
   area (iPad Pro, 1024px viewport) where it yields ~125px — ample. The Tablet band starts at
   600px, and on an iPad Mini in portrait the same 14% is roughly 90px against a date that needs
   about 96px once the cell's own padding is counted, so "09/18/2026" clipped to "09/18/..." with
   no way to read the rest: emr-col-nowrap stops it wrapping but cannot stop it clipping. Sized for
   the NARROW end of the band rather than the reference device, since that is where it fails.
   The 7 points come from Task, which had the most slack. */
.emr-workitems-grid--tablet .emr-col-task { width: 24%; }
.emr-workitems-grid--tablet .emr-col-patient { width: 19%; }
.emr-workitems-grid--tablet .emr-col-status { width: 27%; }
.emr-workitems-grid--tablet .emr-col-duedate { width: 21%; }
.emr-workitems-grid--tablet .emr-col-expander { width: 9%; }

/* iPad-portrait defect: "Pending Manual Workflow" spilled past its own pill border at the narrow
   end of the Tablet range (iPad Mini/11" portrait) even with the 27% share above — the same
   nowrap-plus-60px-floor failure mode already fixed for the encounters grid at
   .emr-encounters-grid .emr-status-chip.mud-chip (app.components.css:1449-1453, phone tier).
   Same fix, ported here: let the chip wrap and grow vertically instead of clipping. */
.emr-workitems-grid--tablet .emr-status-chip.mud-chip {
    white-space: normal;
    height: auto;
    min-width: 0;
}

/* Phone row for the workitems grid (All Tasks + Patient Tasks). Same construction as the landing
   patient grid above: Breakpoint.None keeps rows horizontal, up to five columns move to the child
   row (neither Status nor Vx is one of them — ADO 4158 — both render inline under the task name),
   and these percentages divide the remaining width. .emr-col-task / .emr-col-patient carry different
   widths here than in the desktop block above — TemplateColumn does not support per-breakpoint
   HeaderClass, so the media query is what makes the same class mean two different percentages.
   Patient Tasks hides the patient column; under the fixed-table algorithm its 32% is redistributed
   across the survivors in proportion to their widths, which widens both rather than only the
   task column. Nothing clips either way.

   Pinned to phone only, not widened to Tablet's 1279.98px: this is the phone-specific 3-column set
   (task/patient/expander), distinct from Tablet's own 5-column set (.emr-workitems-grid--tablet
   above) — widening would let this rule's percentages collide with (and, by source order, override)
   the Tablet block at Tablet widths. */
@media (max-width: 599.98px) {
    /* Fixed layout, and percentages rather than px: an auto-layout table grows to its content's
       min-width and pushes the expander off screen, and under fixed layout a px/auto mix lets the
       wide expanded child row starve the text columns to zero. */
    .emr-workitems-grid .mud-table-root {
        table-layout: fixed;
    }

    .emr-workitems-grid .emr-col-task { width: 57%; }
    .emr-workitems-grid .emr-col-patient { width: 32%; }
    .emr-workitems-grid .emr-col-expander { width: 11%; }

    /* Patient Tasks (ShowPatientLink=false) hides the Patient column, and these widths MUST still
       sum to 100 — they cannot be left to redistribute.

       MudBlazor renders the hierarchy child row as <td colspan="1000">. A table's column count is
       the max across its rows, so that one cell gives the table 1000 columns while the header
       declares three. Under table-layout:fixed the three real columns take their declared widths
       and every leftover percent is handed to the 997 phantom columns — so at 68% the collapsed
       rows ended a third of the way short of the expanded card, which is exactly the "grid breaks
       when I expand it" report. Re-proportioned to 100, there is no leftover to leak.
       WorkitemsGridPhoneTests pins the colspan value this depends on. */
    .emr-workitems-grid--no-patient .emr-col-task { width: 84%; }
    .emr-workitems-grid--no-patient .emr-col-expander { width: 16%; }
}

/* Phone row for the patient encounter history grid. Breakpoint.None keeps rows horizontal and seven
   columns move to the child row, leaving a two-column row: the type cell carries the encounter type
   over the start timestamp, with status and the expander trailing.

   Three text columns (type / start / status) was tried first and failed: each got too little width,
   so the status chip clipped mid-word and the timestamp wrapped onto a third line while the short
   type names left space unused. Folding start into the type cell gives both survivors real width. */
/* Every width, not just phone: the type is a link that can run long ("Comprehensive Assessment"),
   and a link that will not wrap is one unbreakable box that stretches its column and pushes the
   columns after it out of the viewport. Above phone width there is no phone card to fall back on and
   .emr-patient-panel is overflow:hidden, so a tablet would clip rather than scroll. Same reason PR
   4814 hoisted this out of the phone query for the landing patient and workitems grids. */
.emr-encounters-grid .emr-col-encounter-type .mud-link {
    white-space: normal;
    text-align: left;
}

/* Tablet tier (`.emr-encounters-grid--tablet`, LayoutContext.IsTablet — Sm/Md, 600-1279px). This
   grid has the widest fold list in the app (9 real columns), so Tablet is deliberately generous:
   identity (Name, Discipline), Type, the Orders/POC affordances, and Status all stay — only the
   three timestamps (Start, End, Submit) fold, per the standard's "timestamps fold first" rule.
   Fixed layout + percentages, same reasoning as the phone block below: engineering estimates, no
   on-device iPad measurement pass for this grid. */
.emr-encounters-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-encounters-grid--tablet .emr-col-encounter-name { width: 16%; }
/* Discipline widened 12% -> 22%, taken from Type (30% -> 20%): at the 744px iPad Mini portrait
   width, 12% (~89px) is narrower than "REGISTERED" — a single unbreakable token in the rendered
   "(RN) / REGISTERED / NURSE" value — so it overflowed the cell to the right and painted over Type.
   Type's value ("Focus Encounter") is space-delimited and wraps cleanly, so it can give up 10
   points without clipping. Developer-directed split (do not re-litigate): widen Discipline, shrink
   its font (see .emr-col-encounter-discipline font-size rule below) rather than truncate it —
   text-overflow:ellipsis was explicitly rejected, since a clipped clinical discipline is worse
   than a wrapped one. Sum unchanged at 100 (22 - 12 == 30 - 20). */
.emr-encounters-grid--tablet .emr-col-encounter-discipline { width: 22%; }
.emr-encounters-grid--tablet .emr-col-encounter-type { width: 20%; }
.emr-encounters-grid--tablet .emr-col-encounter-orders { width: 8%; }
.emr-encounters-grid--tablet .emr-col-encounter-poc { width: 8%; }
.emr-encounters-grid--tablet .emr-col-encounter-status { width: 16%; }
.emr-encounters-grid--tablet .emr-col-expander { width: 10%; }

/* De-emphasized cell text, house convention (.emr-field-value / .emr-issue-list-item / .emr-row-
   caption above): caption-scale via the typography token, never a hardcoded px value. Scoped to
   Tablet only — Desktop's wider Discipline column has no overflow problem and must not change.
   The cell has no MudText wrapper to hang Typo="Typo.caption" on (plain interpolated text in the
   CellTemplate), so CSS owns it directly; CellClass="emr-col-encounter-discipline" added
   (EncountersListGrid.razor) alongside the existing HeaderClass so this reaches the <td>. td only:
   the <th> carries the same class and must keep the grid's single header size. */
.emr-encounters-grid--tablet td.emr-col-encounter-discipline {
    font-size: var(--mud-typography-caption-size);
}

/* Pinned to phone only, not widened to Tablet's 1279.98px: Tablet has its own column set now (the
   modifier block above), which folds a narrower set (Start/End/Submit) than phone folds (Name/
   Discipline/Start/End/Submit/Orders/POC) — the two bands cannot share one percentage table. */
@media (max-width: 599.98px) {
    /* width:100% alongside table-layout:fixed — an auto-layout table only obeys the percentages
       once it also fills its container, otherwise it shrinks to its content and they never engage. */
    .emr-encounters-grid .mud-table-root {
        table-layout: fixed;
        width: 100%;
    }

    /* Degrade a long value to "…" rather than let it force its column wider. */
    .emr-encounters-grid .mud-table-cell {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .emr-encounters-grid .emr-col-encounter-type { width: 54%; }
    .emr-encounters-grid .emr-col-encounter-status { width: 31%; }
    .emr-encounters-grid .emr-col-expander { width: 15%; }

    /* MudChip is nowrap with a 60px floor (.emr-status-chip), so a status longer than its column
       clips instead of wrapping — that is what cut "Completed" to "Comple". Letting it wrap and
       grow vertically means no status can be truncated regardless of length. */
    .emr-encounters-grid .emr-status-chip.mud-chip {
        white-space: normal;
        height: auto;
        min-width: 0;
    }
}

/* Tablet tier (`.emr-medications-grid--tablet`, LayoutContext.IsTablet — Sm/Md, 600-1399px, both
   compact portrait ~810px and wide landscape): ADO 4135 follow-up — QA found Start Date,
   Indications, and Relatedness folded behind the chevron on iPad landscape (1080 CSS px), leaving
   only Medication/Directions/End Date visible. Developer decision: at the whole Tablet tier all
   six columns render inline and the chevron is hidden (MedicationsListGrid.razor — every column's
   Hidden now reads IsPhone only); ChildRowContent opens at phone only. Every declared column needs
   an explicit HeaderClass under table-layout:fixed — MudBlazor renders the hierarchy child row as
   <td colspan="1000">, and a table's column count is the max across its rows, so a column with no
   declared width would have its share silently redivided across ~996 phantom columns the moment a
   row expands elsewhere in the grid; not reachable here since the chevron is hidden, but kept
   explicit for consistency with the other tiered grids.

   ADO 4135 follow-up #2 (root cause of a still-horizontal-scrolling grid reported at 580-600 CSS
   px): the phone block below matches on `.emr-medications-grid` alone, this block matches on
   `.emr-medications-grid--tablet`, and both are two-class selectors, so they are EQUAL specificity.
   `LayoutContext.IsTablet` (Sm/Md, JS ResizeObserver-driven) and the phone media query's
   `max-width: 599.98px` (evaluated by the browser against the live CSS viewport) are two
   INDEPENDENT measurements of the same boundary and are not guaranteed to agree to the pixel —
   at a real narrow-Tablet width the grid can carry BOTH `emr-medications-grid--tablet` (from
   LayoutContext) and be inside the sub-600px media query at the same time. When that happens the
   phone rule wins on source order (it is declared later in the file) and silently overwrites two
   of this block's six column widths with Phone's 4-column percentages — breaking the "sums to
   100" invariant and overflowing the table. Verified with a static MudBlazor-CSS + rendered-markup
   repro in Playwright: at 590px with only this stylesheet loaded, `.emr-col-medication` resolved
   to Phone's 60% and `.emr-col-medication-end` to Phone's 25% instead of this block's 20%/12%,
   confirmed via the browser's own matched-rule list. Fix: the phone rules now explicitly exclude
   `.emr-medications-grid--tablet` (`:not(...)`) so they can never apply to a Tablet-classed grid
   regardless of any px/JS timing mismatch — the two column sets are mutually exclusive by
   selector, not just by the media query's nominal range.

   Widths retuned for the reported failure width (580-600px, not just the ~700-1000px iPad range
   this block originally targeted): Medication trimmed from 24% to 20% (its content — drug name +
   dosage — tolerates two lines better than Directions/Indications losing more room), Start/End
   raised from 11% to 15% and Indications/Relatedness from 11%/13% to 14% so a "MM/dd/yyyy" date
   and a one-word header ("Indications", "Relatedness") both have a fighting chance at 600px, and
   Directions absorbs the remainder (22%). Directions/Indications/Relatedness also drop to
   caption-scale type at this tier (design.md typography table — `var(--mud-typography-caption-
   size)`, the same token the encounters grid already uses for its Tablet Discipline column) to
   give the narrow text columns more characters per line, and their DATA cells (not headers — see
   below) gain `overflow-wrap: anywhere` so one unbroken clinical term (e.g. "Aggregation",
   "HYPERACTIVITY") cannot force its column wider than its declared percentage. Even at caption
   size, MudBlazor's fixed-width sort icon left no room for a whole header word on one line inside
   a ~15%-wide column — the header's own flex row is allowed to wrap (see below) rather than widen
   the column further, since a header only ever holds one short label while a data cell must hold
   arbitrary clinical text. Start/End Date stay nowrap (.emr-col-nowrap) — at 600px, 15% is ~90px,
   enough for "MM/dd/yyyy" with the tightened 4px date padding below — but nowrap is intentionally
   NOT paired with overflow:hidden, so if a future narrower band still can't fit the date it wraps
   to a second line instead of clipping or forcing the column wider. Engineering estimates
   confirmed against a Playwright measurement of the actual rendered markup at 590/600/700/1000px,
   with the app's real MudBlazor typography CSS variables (Typography.cs Caption=.75rem/
   Subtitle2=.875rem) injected since a static repro has no MudThemeProvider to set them, in all
   three grouping states (ungrouped, grouped-indications, grouped-relatedness) — revisit if a
   column still clips or wraps awkwardly on a real device. */
.emr-medications-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-medications-grid--tablet .emr-col-medication { width: 20%; }
.emr-medications-grid--tablet .emr-col-medication-directions { width: 22%; }
.emr-medications-grid--tablet .emr-col-medication-start { width: 15%; }
.emr-medications-grid--tablet .emr-col-medication-end { width: 15%; }
.emr-medications-grid--tablet .emr-col-medication-indications { width: 14%; }
.emr-medications-grid--tablet .emr-col-medication-relatedness { width: 14%; }

/* ADO 4135 GroupBy follow-up: at Tablet the grouped column's data cell is hidden (the group
   header row already carries the value — see MedicationsListGrid.razor), which would otherwise
   leave a gap under table-layout:fixed. The freed width (14% either grouped column) is folded
   into Directions, the column with the most benefit from extra room; the remaining five visible
   columns' widths still sum to 100%. */
.emr-medications-grid--tablet.emr-medications-grid--grouped-indications .emr-col-medication-directions,
.emr-medications-grid--tablet.emr-medications-grid--grouped-relatedness .emr-col-medication-directions {
    width: 36%;
}

/* ADO 4305: Active mode hides the End Date column, which under table-layout:fixed would leave its
   15% as dead space on the right. Its share is handed back so the visible columns sum to 100%. */
.emr-medications-grid--tablet.emr-medications-grid--active .emr-col-medication { width: 24%; }
.emr-medications-grid--tablet.emr-medications-grid--active .emr-col-medication-directions { width: 26%; }
.emr-medications-grid--tablet.emr-medications-grid--active .emr-col-medication-start { width: 16%; }
.emr-medications-grid--tablet.emr-medications-grid--active .emr-col-medication-indications { width: 17%; }
.emr-medications-grid--tablet.emr-medications-grid--active .emr-col-medication-relatedness { width: 17%; }
.emr-medications-grid--tablet.emr-medications-grid--active.emr-medications-grid--grouped-indications .emr-col-medication-directions,
.emr-medications-grid--tablet.emr-medications-grid--active.emr-medications-grid--grouped-relatedness .emr-col-medication-directions {
    width: 43%;
}

/* Specificity note: MudBlazor's dense padding is `.mud-table-dense * .mud-table-row .mud-table-cell`
   (0,3,0) — matched here by chaining grid/cell/nowrap classes so this rule wins on source order,
   same pattern already used for the needs grid above. Applies to the nowrap date cells and to
   every cell (header and data) of the four narrow 14-15% columns; Medication and Directions keep
   the default dense padding. Headers are included because, for a 70-80px-wide header:
   MudBlazor's sort-icon button (`.mud-icon-button`, ~26px) sits in a `display:flex; flex-wrap:
   nowrap` header row alongside the title text, and the header's DEFAULT (un-tightened) padding
   left the flex row only ~30px to fit both, so "Start Date"/"Indications"/"Relatedness" scrolled
   past their own cell even though the data-row date text below was already correctly tightened. */
.emr-medications-grid--tablet .mud-table-row .mud-table-cell.emr-col-nowrap,
.emr-medications-grid--tablet .mud-table-cell.emr-col-medication-start,
.emr-medications-grid--tablet .mud-table-cell.emr-col-medication-end,
.emr-medications-grid--tablet .mud-table-cell.emr-col-medication-indications,
.emr-medications-grid--tablet .mud-table-cell.emr-col-medication-relatedness {
    padding-left: 4px;
    padding-right: 4px;
}

/* Caption-scale type for the long-text data cells (house convention — see the identical pattern
   for .emr-encounters-grid--tablet .emr-col-encounter-discipline above). td only: the <th> carries
   the same class through HeaderClass, and every header keeps the grid's single header size. */
.emr-medications-grid--tablet td.emr-col-medication-directions,
.emr-medications-grid--tablet td.emr-col-medication-indications,
.emr-medications-grid--tablet td.emr-col-medication-relatedness {
    font-size: var(--mud-typography-caption-size);
}

/* MudBlazor's header lays the title text and its sort-icon button out as `display:flex;
   flex-wrap: nowrap` (Styles/components/_table.scss). That single icon is a fixed ~26px the
   narrow 14%-width tablet columns cannot spare alongside a whole word ("Indications",
   "Relatedness") on one line — confirmed in the Playwright repro: even after the caption-size
   font-size above, the header's own scrollWidth still exceeded its column. Letting the flex row
   wrap (icon drops under the title instead of beside it) uses the column's existing height instead
   of forcing width, matching this tier's already-documented allowance for two-line headers. */
.emr-medications-grid--tablet th.emr-col-medication-start .column-header,
.emr-medications-grid--tablet th.emr-col-medication-end .column-header,
.emr-medications-grid--tablet th.emr-col-medication-indications .column-header,
.emr-medications-grid--tablet th.emr-col-medication-relatedness .column-header {
    flex-wrap: wrap;
}

/* overflow-wrap:anywhere only on the DATA cell (td), never the header (th): a header carries the
   same HeaderClass/CellClass pair as its column's <td> (Grid Tiering Standard), and "anywhere"
   applied to a one-word header ("Indications", "Relatedness") breaks it mid-word into a vertical
   stack of single letters the moment the header's own text is tight against MudBlazor's sort-icon
   flex row — confirmed visually in the Playwright repro. Data rows carry real clinical terms that
   can be much longer than any header ("Platelet Aggregation Inhibitor"), so they still need it. */
.emr-medications-grid--tablet td.emr-col-medication-indications,
.emr-medications-grid--tablet td.emr-col-medication-relatedness,
.emr-medications-grid--tablet td.emr-col-medication-directions {
    overflow-wrap: anywhere;
}

/* Phone row for the patient medications grid. Same shape as the encounter history grid above: the
   medication cell carries the drug name over its directions, with the end date and the expander
   trailing. Directions is the longest field in the row and the one worth reading beside a drug
   name, so it rides in the primary cell rather than taking a column that would starve the rest.

   Pinned to phone only, not widened to Tablet's 1279.98px: Tablet has its own column set now (the
   modifier block above), which folds a different, narrower set of columns than phone (Start Date/
   Indications/Relatedness vs. phone's Directions/Start Date/Indications/Relatedness) — the two
   bands cannot share one percentage table. `:not(.emr-medications-grid--tablet)` on the two rules
   that collide by class name (`.emr-col-medication`, `.emr-col-medication-end`) makes that
   separation structural instead of relying on the media query's nominal range never overlapping
   LayoutContext.IsTablet in practice — see the root-cause note on the Tablet block above. */
@media (max-width: 599.98px) {
    /* width:100% alongside table-layout:fixed — an auto-layout table only obeys the percentages
       once it also fills its container, otherwise it shrinks to its content and they never engage. */
    .emr-medications-grid .mud-table-root {
        table-layout: fixed;
        width: 100%;
    }

    .emr-medications-grid:not(.emr-medications-grid--tablet) .emr-col-medication { width: 60%; }
    .emr-medications-grid:not(.emr-medications-grid--tablet) .emr-col-medication-end { width: 25%; }
    .emr-medications-grid .emr-col-expander { width: 15%; }
    .emr-medications-grid--active:not(.emr-medications-grid--tablet) .emr-col-medication { width: 85%; }

    /* Two lines, then ellipsis. A full sig ("Take 1 tablet by mouth twice daily as needed for
       pain, do not exceed 4 doses in 24 hours") would otherwise make a single row taller than the
       viewport and defeat the point of collapsing the grid. The untruncated text is in the card.
       -webkit- prefixed line-clamp is the only cross-browser form; display:-webkit-box is required
       with it, and overflow:hidden is what actually clips. */
    .emr-medications-grid .emr-medication-phone-directions {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
}

/* HME desktop column widths, moved verbatim off per-column HeaderStyle= (forbidden for sizing —
   inline style in disguise). Unprefixed by a media query so they remain the desktop widths; the
   phone block below overrides the two columns that survive there. Sums to 97%, as the inline
   values did — the remainder falls to the unsized expander column, absent above 960px. */
.emr-col-hme-type { width: 9%; }
.emr-col-hme-name { width: 22%; }
.emr-col-hme-qty { width: 5%; }
.emr-col-hme-instructions { width: 28%; }
.emr-col-hme-relatedness { width: 15%; }
.emr-col-hme-startdate { width: 9%; }
.emr-col-hme-enddate { width: 9%; }

/* Tablet tier for the allergies and HME grids (`--tablet` modifier, LayoutContext.IsTablet —
   Sm/Md, 600-1279px). Allergen/Reaction and Type/Name/Instructions are the identity + primary
   content that stay; Allergies also keeps Status and the edit/delete Actions (row affordances
   outrank the classifier/timestamp/free-text fields that fold). Fixed layout + percentages, same
   reasoning as the phone block below: engineering estimates, no on-device iPad measurement pass
   for these two grids. */
.emr-allergies-grid--tablet .mud-table-root,
.emr-hme-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-allergies-grid--tablet .emr-col-allergen { width: 30%; }
.emr-allergies-grid--tablet .emr-col-allergy-reaction { width: 25%; }
.emr-allergies-grid--tablet .emr-col-allergy-status { width: 15%; }
.emr-allergies-grid--tablet .emr-col-allergy-actions { width: 15%; }
.emr-allergies-grid--tablet .emr-col-expander { width: 15%; }

.emr-hme-grid--tablet .emr-col-hme-type { width: 12%; }
.emr-hme-grid--tablet .emr-col-hme-name { width: 28%; }
.emr-hme-grid--tablet .emr-col-hme-qty { width: 8%; }
.emr-hme-grid--tablet .emr-col-hme-instructions { width: 37%; }
.emr-hme-grid--tablet .emr-col-expander { width: 15%; }

/* Phone rows for the allergies and HME grids. Same shape as the encounter and medication grids
   above: the primary cell carries the identifier over its one paired free-text field, with a short
   categorical column and the expander trailing. Allergen/Reaction and Name/Instructions are the
   pairs you scan these lists by; giving each half its own narrow column starves both.

   Pinned to phone only, not widened to Tablet's 1279.98px: Tablet has its own column set now (the
   modifier blocks above), which folds a narrower set than phone folds — the two bands cannot share
   one percentage table. */
@media (max-width: 599.98px) {
    /* width:100% alongside table-layout:fixed — an auto-layout table only obeys the percentages
       once it also fills its container, otherwise it shrinks to its content and they never engage. */
    .emr-allergies-grid .mud-table-root,
    .emr-hme-grid .mud-table-root {
        table-layout: fixed;
        width: 100%;
    }

    /* Edit/delete were tried inline and reverted: two 44px touch targets plus the expander needed
       ~43% of the row, leaving Allergen 38%, which crowded the name and its reaction caption. With
       the actions in the card, Allergen keeps 60% and the row stays legible. */
    .emr-allergies-grid .emr-col-allergen { width: 60%; }
    .emr-allergies-grid .emr-col-allergy-status { width: 25%; }
    .emr-allergies-grid .emr-col-expander { width: 15%; }

    .emr-hme-grid .emr-col-hme-name { width: 60%; }
    .emr-hme-grid .emr-col-hme-type { width: 25%; }
    .emr-hme-grid .emr-col-expander { width: 15%; }

    /* The item name is a MudLink and will not wrap on its own; a long name would otherwise be one
       unbreakable box that stretches its column and pushes the expander off screen. */
    .emr-hme-grid .emr-col-hme-name .mud-link {
        white-space: normal;
        text-align: left;
    }

    /* Two lines, then ellipsis — a long instruction would otherwise make one row taller than the
       viewport and defeat the point of collapsing the grid. Full text is in the card. -webkit-
       prefixed line-clamp is the only cross-browser form; display:-webkit-box is required with it,
       and overflow:hidden is what actually clips. */
    .emr-hme-grid .emr-hme-phone-instructions {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
}

/* Diagnosis code: nowrap + monospace, moved off a per-column CellStyle (forbidden for sizing and
   alignment). Applies at every width — it is the code's typography, not a phone rule — and is
   reused by the phone secondary line under the diagnosis name. */
.emr-col-diagnosis-code {
    white-space: nowrap;
    font-family: monospace;
}

/* The secondary line under a primary value in a phone grid row (start date under an encounter type,
   reaction under an allergen, code under a diagnosis, category under an order comment).

   display:block is the whole point: MudText renders Typo.caption as a <span>, so without this the
   caption flows inline and the value runs straight onto the end of the name with no separator —
   "Cerebral atherosclerosisI67.2". The medications and HME sublines escape it only because their
   two-line clamp sets display:-webkit-box, which is already block-level. Only ever rendered inside
   an @if (IsPhone), so it needs no media query. */
.emr-grid-subline {
    display: block;
}

/* Tablet tier for the diagnoses, physicians and other-orders grids (`--tablet` modifier,
   LayoutContext.IsTablet — Sm/Md, 600-1279px). All three fold only Start Date (a timestamp) at
   this tier — everything else that fits at Phone width fits comfortably wider at Tablet, so only
   the one field the standard calls out to fold first actually folds. Fixed layout + percentages
   for the same reason as the phone block below: engineering estimates, no on-device iPad
   measurement pass for these three grids. */
.emr-diagnoses-grid--tablet .mud-table-root,
.emr-physicians-grid--tablet .mud-table-root,
.emr-other-orders-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-diagnoses-grid--tablet .emr-col-diagnosis-codehdr { width: 15%; }
.emr-diagnoses-grid--tablet .emr-col-diagnosis { width: 45%; }
.emr-diagnoses-grid--tablet .emr-col-diagnosis-enddate { width: 20%; }
.emr-diagnoses-grid--tablet .emr-col-expander { width: 10%; }
/* Relatedness previously had no dedicated HeaderClass and took the 10% these four left over —
   the same phantom-column defect as Medications' Directions above: MudBlazor's <td colspan="1000">
   hierarchy child row hands every unclaimed percent to ~996 phantom columns instead of the one
   real column that was relying on leftover allocation, collapsing it to min-content on expand.
   Relatedness now carries HeaderClass="emr-col-diagnosis-relatedness" (DiagnosesListGrid.razor)
   so its 10% share is explicit; the value itself is unchanged. */
.emr-diagnoses-grid--tablet .emr-col-diagnosis-relatedness { width: 10%; }

.emr-physicians-grid--tablet .emr-col-physician-name { width: 35%; }
.emr-physicians-grid--tablet .emr-col-physician-role { width: 20%; }
.emr-physicians-grid--tablet .emr-col-physician-enddate { width: 15%; }
.emr-physicians-grid--tablet .emr-col-expander { width: 10%; }
/* Preferences previously had no dedicated HeaderClass and took the 20% these four left over —
   same phantom-column defect as above. Preferences now carries
   HeaderClass="emr-col-physician-preferences" (PhysiciansListGrid.razor) so its 20% share is
   explicit; the value itself is unchanged. */
.emr-physicians-grid--tablet .emr-col-physician-preferences { width: 20%; }

.emr-other-orders-grid--tablet .emr-col-otherorder-comment { width: 40%; }
.emr-other-orders-grid--tablet .emr-col-otherorder-category { width: 15%; }
.emr-other-orders-grid--tablet .emr-col-otherorder-coverage { width: 15%; }
.emr-other-orders-grid--tablet .emr-col-otherorder-enddate { width: 20%; }
.emr-other-orders-grid--tablet .emr-col-expander { width: 10%; }

/* ADO 4305: Active mode hides End Date; its share goes to the widest column so widths sum to 100%. */
.emr-diagnoses-grid--tablet.emr-diagnoses-grid--active .emr-col-diagnosis { width: 65%; }
.emr-physicians-grid--tablet.emr-physicians-grid--active .emr-col-physician-name { width: 50%; }
.emr-other-orders-grid--tablet.emr-other-orders-grid--active .emr-col-otherorder-comment { width: 60%; }

/* Phone rows for the diagnoses, physicians and other-orders grids. All three are date-bounded
   records with short qualifiers, so all three take the same shape as the grids above: identifier
   (plus, for physicians, Role — ADO 4134, distinguishes a contact appearing in multiple roles) in
   the leading cells, End Date trailing, everything else in the card. End Date rather than Start
   Date is inline because whether a record is still current is what you scan for; the row-level
   expiry styling that would otherwise carry it is dead (.v-c-error is applied by six grids and
   defined by none).

   Pinned to phone only, not widened to Tablet's 1279.98px: Tablet has its own column set now (the
   modifier blocks above), which folds a narrower set (Start Date only) than phone folds — the two
   bands cannot share one percentage table. */
@media (max-width: 599.98px) {
    /* width:100% alongside table-layout:fixed — an auto-layout table only obeys the percentages
       once it also fills its container, otherwise it shrinks to its content and they never engage. */
    .emr-diagnoses-grid .mud-table-root,
    .emr-physicians-grid .mud-table-root,
    .emr-other-orders-grid .mud-table-root {
        table-layout: fixed;
        width: 100%;
    }

    .emr-diagnoses-grid .emr-col-diagnosis { width: 60%; }
    .emr-diagnoses-grid .emr-col-diagnosis-enddate { width: 25%; }
    .emr-diagnoses-grid .emr-col-expander { width: 15%; }

    .emr-physicians-grid .emr-col-physician-name { width: 40%; }
    .emr-physicians-grid .emr-col-physician-role { width: 25%; }
    .emr-physicians-grid .emr-col-physician-enddate { width: 20%; }
    .emr-physicians-grid .emr-col-expander { width: 15%; }

    .emr-other-orders-grid .emr-col-otherorder-comment { width: 60%; }
    .emr-other-orders-grid .emr-col-otherorder-enddate { width: 25%; }
    .emr-other-orders-grid .emr-col-expander { width: 15%; }

    .emr-diagnoses-grid--active .emr-col-diagnosis { width: 85%; }
    .emr-physicians-grid--active .emr-col-physician-name { width: 60%; }
    .emr-other-orders-grid--active .emr-col-otherorder-comment { width: 85%; }

    /* Two lines, then ellipsis. An order comment is free text with no length limit and would
       otherwise make one row taller than the viewport. Full text is in the card. -webkit- prefixed
       line-clamp is the only cross-browser form; display:-webkit-box is required with it, and
       overflow:hidden is what actually clips. */
    .emr-other-orders-grid .emr-otherorder-phone-comment {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
}

/* Tablet tier for the caregivers and staff-assignment grids (`--tablet` modifier,
   LayoutContext.IsTablet — Sm/Md, 600-1279px). Both are people lists: identity (First/Last Name or
   Kind+Name) and contact info (Phone, or Cellular+Business) stay, plus caregivers' edit Action —
   only the classifiers (Relation/Legal Relationship, or Prof Discipline/Type) fold, per the
   standard's "identity/status/affordances stay, classifiers fold" ordering. Fixed layout +
   percentages, same reasoning as the phone block below: engineering estimates, no on-device iPad
   measurement pass for these two grids. */
.emr-caregivers-grid--tablet .mud-table-root,
.emr-staff-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-caregivers-grid--tablet .emr-col-caregiver-firstname { width: 18%; }
.emr-caregivers-grid--tablet .emr-col-caregiver-lastname { width: 18%; }
.emr-caregivers-grid--tablet .emr-col-caregiver-phone { width: 22%; }
.emr-caregivers-grid--tablet .emr-col-caregiver-type { width: 15%; }
.emr-caregivers-grid--tablet .emr-col-caregiver-actions { width: 12%; }
.emr-caregivers-grid--tablet .emr-col-expander { width: 15%; }

.emr-staff-grid--tablet .emr-col-staff-kind { width: 8%; }
/* Name gives up 3 points and Expander 5 (both go to Cellular/Business below) — Expander is the
   more generous donor: at 15% (~112px on the 744px iPad Mini portrait reference) it is nearly
   triple the ~44px+12px-padding floor the chevron actually needs (same floor already measured for
   .emr-workitems-grid--tablet .emr-col-expander above), so trimming it to 10% (~74px) still clears
   that floor with margin. Sum unchanged at 100. */
.emr-staff-grid--tablet .emr-col-staff-name { width: 24%; }
.emr-staff-grid--tablet .emr-col-staff-role { width: 20%; }
/* Cellular/Business widened 15% -> 19% each: a phone number is one atomic value ("(933) 003-8920"),
   and browsers break at the hyphen, so at 15% (~112px) it fragmented across two or three lines —
   "(933)" / "003-" / "8920" — a misreading risk in a clinical context. white-space:nowrap below
   stops the fragmentation outright; 19% (~141px) is the room freed from Name/Expander to hold the
   now-unbreakable value with margin. */
.emr-staff-grid--tablet .emr-col-staff-cellular { width: 19%; }
.emr-staff-grid--tablet .emr-col-staff-business { width: 19%; }
.emr-staff-grid--tablet .emr-col-expander { width: 10%; }

/* CellClass="emr-col-staff-cellular"/"emr-col-staff-business" added alongside the existing
   HeaderClass (StaffAssignmentsListGrid.razor) so this reaches the <td> — PatientPhoneLink renders
   a plain div/MudLink with no class of its own to hang white-space on, and white-space is
   inherited, so setting it here on the cell reaches the link text inside. Scoped to Tablet only:
   Desktop has no declared width for these columns (auto layout sizes to content, so nothing
   fragments there) and must not change. */
.emr-staff-grid--tablet .mud-table-cell.emr-col-staff-cellular,
.emr-staff-grid--tablet .mud-table-cell.emr-col-staff-business {
    white-space: nowrap;
}

/* The single-character E/V chip (StaffAssignmentsListGrid.razor ~:115) hit the same MudChip 60px
   min-width floor already fixed twice elsewhere in this file (.emr-status-chip.mud-chip above) —
   at 8% (~60px on the 744px iPad Mini portrait reference) the chip's own 60px floor left it with no
   margin, so the glyph was visibly mangled. Unlike the status chips, there is nothing here to
   wrap — a single character never needs white-space:normal/height:auto — so min-width:0 alone (plus
   flex-shrink:0 so the cell's flex layout cannot compress it back out of round) is the narrower,
   correct fix; widening emr-col-staff-kind was deliberately not spent on this. Scoped to Tablet:
   Desktop's "" column has no declared width and the chip is not crushed there. */
.emr-staff-grid--tablet .emr-staff-kind-chip.mud-chip {
    min-width: 0;
    flex-shrink: 0;
}

/* Phone rows for the caregivers and staff-assignment grids. Both are people lists, so the primary
   cell carries the name; caregivers put the single primary phone underneath (a caregiver list on a
   phone exists to be called from) while staff put the primary role, because with both a cellular
   and a business number present, picking one for the row would be arbitrary — both stay tap-to-call
   in the card instead. Staff keeps its one-character E/V chip inline: it encodes employee-vs-
   volunteer and active-vs-inactive in 15%, which is the cheapest signal in either grid.

   Pinned to phone only, not widened to Tablet's 1279.98px: Tablet has its own column set now (the
   modifier blocks above), which folds a narrower set than phone folds — the two bands cannot share
   one percentage table. */
@media (max-width: 599.98px) {
    /* width:100% alongside table-layout:fixed — an auto-layout table only obeys the percentages
       once it also fills its container, otherwise it shrinks to its content and they never engage. */
    .emr-caregivers-grid .mud-table-root,
    .emr-staff-grid .mud-table-root {
        table-layout: fixed;
        width: 100%;
    }

    .emr-caregivers-grid .emr-col-caregiver-name { width: 60%; }
    .emr-caregivers-grid .emr-col-caregiver-type { width: 25%; }
    .emr-caregivers-grid .emr-col-expander { width: 15%; }

    .emr-staff-grid .emr-col-staff-kind { width: 15%; }
    .emr-staff-grid .emr-col-staff-name { width: 70%; }
    .emr-staff-grid .emr-col-expander { width: 15%; }
}

/* Tablet tier (`.emr-documents-grid--tablet` / `.emr-encounter-documents-grid--tablet`,
   LayoutContext.IsTablet — Sm/Md, 600-1279px). Both grids share this identical shape: a hidden
   grouping column plus Category, File Name, and Date. The developer chose sizing over folding here
   — no HierarchyExpanderColumn, no child row, nothing hidden — so Grid Tiering Standard's "tier
   down, don't squeeze" is deliberately not applied to this pair. Without `table-layout: fixed` the
   table sized itself from content instead of the container, so a long file name pushed the table
   past its panel and Date was clipped off the right edge (commit a7a58e74 turned that clip into a
   horizontal scrollbar instead of fixing it). Percentages sized for the 744px narrow end of the
   Tablet band (iPad Mini portrait), not an iPad Pro. */
.emr-documents-grid--tablet .mud-table-root,
.emr-encounter-documents-grid--tablet .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.emr-documents-grid--tablet .emr-col-doc-category,
.emr-encounter-documents-grid--tablet .emr-col-doc-category {
    width: 25%;
}

/* A patient document's file name is often one long dot-delimited token with no spaces
   ("word.word.date.number.number.s.2.pdf") — browsers only break lines at spaces, so that token's
   min-content width is the full string. Under table-layout:fixed that no longer widens the table,
   but without a break rule it still overflows this column's own 55% and spills across Date.
   overflow-wrap: anywhere breaks it mid-string, same technique as the qualifier-chip and
   .emr-needs-col-label wide-text cells elsewhere in this file. */
.emr-documents-grid--tablet .emr-col-doc-filename,
.emr-encounter-documents-grid--tablet .emr-col-doc-filename {
    width: 55%;
    overflow-wrap: anywhere;
}

.emr-documents-grid--tablet .emr-doc-action-col,
.emr-encounter-documents-grid--tablet .emr-doc-action-col {
    width: 20%;
}

/* Uniform width so single-word and multi-word status labels align across the grid; grouped
   (D10) with .emr-needs-level-chip in the Needs Selection dialog block, which points back here. */
.emr-status-chip.mud-chip,
.emr-needs-level-chip.mud-chip {
    min-width: 60px;
    justify-content: center;
}

/* Entries tab Status chip — legacy Style="min-width: 80px;" (IntervalChartHome.razor). Wider than
   the shared 60px .emr-status-chip floor above, so this stacks on top rather than editing it —
   other components rely on the 60px width. */
.emr-status-chip-wide.mud-chip {
    min-width: 80px;
}

/* ADO 4158: status renders as plain colored text under the task name (Vx alongside it), not a chip
   in its own column — the Task cell is percentage-wide, not a fixed 180px, so on most viewports
   there is room for the full label without the chip's border/background chrome. Truncation is a
   floor for the narrow end of the Task cell's range (small phones, or a shrunk desktop window):
   workitem status_name runs up to 24 chars ("Pending Signed Document"), and unlike MudChip this
   plain text does wrap on its own without display:inline-block + a definite max-width. 150px
   comfortably fits every status_name in the current lookup except the two 24-char ones (Pending
   Manual Workflow / Pending Signed Document), which are meant to truncate — in the grid only; the
   Task Details dialog reuses "emr-status-chip" on its own full-width row and must show the name
   uncut, which is why this rule is scoped to the grid rather than a bare status class. */
.emr-workitems-grid .emr-status-text {
    display: inline-block;
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}

/* MudBlazor chip colors are set via internal palette vars; !important is a scoped legacy-fidelity override for statuses that have no matching semantic token. */
.emr-chip-discharge.mud-chip {
    background-color: var(--emr-status-discharge) !important;
    color: var(--mud-palette-white) !important;
}

/* QualifierBlockView / FlagRowsBlockView / Impact placeholder text — MudTextField-style
   hint shown only while empty; not interactive, matches other muted placeholder text. */
.qualifier-placeholder-text {
    color: var(--mud-palette-text-secondary);
    font-style: italic;
}

/* ADO 4203: a REQTEXT qualifier value ("Other – <up to 200 chars>") overran the field bounds
   when the symptom was viewed in the encounter — MudChip is single-line by design (fixed
   height, nowrap). Scoped to the QualifierBlockView (Time / Effect / Quality, wound location)
   and FlagRowsBlockView (Palliation / Provocation) chips: let the chip grow vertically and
   wrap its text inside the field's width. overflow-wrap:anywhere covers a 200-character
   unbroken string, which normal word wrapping would still overrun. */
.qualifier-block .mud-chip,
.flag-rows-block .mud-chip {
    height: auto;
    min-height: 24px; /* MudChip Size.Small height — single-line chips render unchanged */
    max-width: 100%;
    white-space: normal;
}

.qualifier-block .mud-chip .mud-chip-content,
.flag-rows-block .mud-chip .mud-chip-content {
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.3;
    padding-top: 2px;
    padding-bottom: 2px;
}

.emr-grid-actions {
    text-align: right;
    white-space: nowrap;
    padding-right: 8px !important;
}

.emr-grid-actions .emr-action-edit {
    color: var(--mud-palette-text-secondary);
}

.emr-grid-actions .emr-action-delete {
    color: var(--mud-palette-error);
}

.emr-pending-encounter-type-col {
    width: 320px;
}

.emr-pending-encounter-updated-col {
    width: 200px;
}

/* min-width, not width: the actions row wraps (see PendingEncounterGrid.razor) so it
   no longer needs to fit 3 buttons on one line — a fixed 300px used to force the
   buttons themselves to flex-shrink below their label width, clipping button text. */
.emr-pending-encounter-action-col {
    min-width: 220px;
}

/* Buttons/badge must never compress below their content on the line they land on —
   the optional not-validated caption renders on its own line below them and wraps there. */
.emr-pending-encounter-action-col .mud-button-root,
.emr-pending-encounter-action-col .mud-badge-root {
    flex-shrink: 0;
}

/* Safety net, not the primary fix: the action row wraps before this is needed, but an
   explicit scroll (vs. clipping) is required if content ever still exceeds the column. */
.emr-pending-encounter-grid .mud-table-container {
    overflow-x: auto;
}

/* Patient summary inner tables (Diagnoses / Allergies / Medications) sit inside
   the mini-case dialog tabs and inside the landing drawer. They must fill their
   container and clip horizontal overflow so column-width settings stay honoured
   regardless of host width. */
.emr-summary-table {
    width: 100%;
    overflow-x: hidden;
}

/* Interval Chart tab content (IntervalChartPage) — ports legacy IntervalChartHome.razor's
   .ic-scroll/.ic-sticky-thead/.mi-table trio, renamed to our emr- prefix and re-targeted at
   MudDataGrid's real DOM: MudDataGrid renders a <table> inside .mud-table-container, the same
   class MudTable used (confirmed via bUnit render; .emr-impersonation-saved-grid above already
   relies on this same class). Left alone, .mud-table-container's own overflow-y:auto
   (MudBlazor.min.css) traps scroll inside each grid and truncates rows below the fold long before
   the page itself needs to scroll — legacy's own documented bug, and the "content must not be
   truncated" complaint this whole block exists to fix: the truncation is missing ROWS scrolled out
   of view, not clipped characters.
   Applied ONCE, at the tab-panel level (MudTabs' TabPanelsClass on IntervalChartPage.razor) rather
   than per-tab, so it becomes the ONE scrollable region for whichever of the five tabs (Shifts,
   Shift POC, Vitals, MARs, Entries) is active at a time — MudTabs does not keep inactive panels in
   the DOM, so .mud-tabs-panels only ever wraps the current tab's content. */
.emr-ic-scroll {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
    /* Fixed height (not max-height) so the container fills the page down to the bottom instead of
       shrinking to its rows — it still scrolls internally when content is taller, the same
       fixed-vs-max-height choice legacy's own comment makes.
       --emr-ic-scroll-offset (320px) is this page's current header stack: app bar, main-content
       padding, heading row, toolbar, paginator, tab strip. It is a measurement, not a contract —
       override the custom property rather than editing this rule when the stack changes or another
       page reuses .emr-ic-scroll. Legacy's own value was 280px; our app bar alone is 76px. */
    height: calc(100dvh - var(--emr-ic-scroll-offset, 320px) - var(--emr-ic-scroll-extra, 0px));
    padding-bottom: 1.5rem;
    box-sizing: border-box;
}

/* Neutralizes MudDataGrid's own internal scroll so .emr-ic-scroll is the only scrollbar — left
   active, the grid's own max-height:100%/overflow-y:auto would either re-truncate its rows inside
   the fixed-height panel (the exact bug this block exists to avoid) or, once it also grew past its
   own limit, hand the page two nested scrollbars instead of one.
   No !important: MudBlazor's plain rule is a single class (.mud-table-container, specificity
   0-1-0); the sticky-header/footer variant is 0-2-0 (.mud-table-sticky-header .mud-table-container)
   but none of the five Interval Chart grids set FixedHeader/FixedFooter, so it never applies here.
   Either way this two-class selector already wins on specificity, and app.components.css loads
   after MudBlazor.min.css, so source order would break the tie even if it were equal. */
.emr-ic-scroll .mud-table-container {
    overflow: visible;
    max-height: none;
}

/* Sticky column headers — legacy's .ic-sticky-thead, which legacy applied to one table only (the
   Entries MudSimpleTable), never page-wide. Kept opt-in here for the same reason: unlike
   .emr-ic-scroll above (applied once, at the tab-panel level, for every tab), a page-wide sticky
   rule breaks the Shift POC tab, which renders two MudDataGrids per care plan inside expansion
   panels that are all open by default — each grid's own thead sticks to the shared scroll
   container's top and is then pushed off by the next grid's thead, stacking into a cascading
   multi-header effect instead of one clean sticky header. .emr-ic-sticky-thead is applied only to
   the Entries grid (EntriesTab.razor), the one tab where a single always-visible header earns its
   keep. position:sticky still anchors to the nearest scrolling ancestor, which is .emr-ic-scroll
   itself now that the grid's own container no longer scrolls (the rule above) — hence the
   .emr-ic-scroll ancestor in this selector, matching where the sticky positioning actually resolves. */
.emr-ic-scroll .emr-ic-sticky-thead thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--mud-palette-surface);
    box-shadow: inset 0 -1px 0 var(--emr-hairline);
}

/* Fixed table layout — legacy's .mi-table. Scoped to the Entries grid, the only one of the five
   tabs that declares per-column widths: under fixed layout a grid with no declared widths sizes
   its columns off the first row alone, so the other four keep auto layout. Here it makes the
   .emr-col-entries-* widths authoritative instead of hints, so a long value wraps onto a second
   line inside its own column rather than the browser silently growing the column past it — the
   horizontal counterpart to .emr-patient-panel's overflow:hidden, which would otherwise clip
   that overflow outright instead of scrolling to it. */
.emr-entries-grid table {
    table-layout: fixed;
    width: 100%;
}

/* text-overflow:ellipsis is kept for parity with legacy's source but is inert without
   white-space:nowrap — deliberately not set here. word-wrap:break-word is what actually does the
   work: wrapping, not clipping, is the desired behavior for every column except the nowrap
   date/time columns (.emr-col-nowrap, design.md Data Tables), which are intentionally short and
   exempted by carrying that class instead of relying on this default. */
.emr-ic-scroll td {
    overflow: hidden;
    text-overflow: ellipsis;
    word-wrap: break-word;
}

/* The header stack above .emr-ic-scroll grows taller on phone — IntervalChartToolbar and
   IntervalChartPaginator restack into extra rows (design.md Phone Adaptations, "Page toolbar
   strips... restacks vertically") — so the scroll container needs that difference given back.
   Mirrors legacy's own --ic-scroll-extra:130px small-screen override (reused verbatim; our phone
   toolbar restacking is the same shape), but keyed to design.md's own Phone breakpoint
   (max-width:599.98px / LayoutContext.IsPhone), not legacy's own media query value.
   Pinned to phone only, not widened to Tablet's 1279.98px: design.md's Phone Adaptations list the
   toolbar-strip restack as Phone-only — Tablet keeps the single-row Desktop toolbar, so the extra
   scroll compensation is not needed there. */
@media (max-width: 599.98px) {
    :root {
        --emr-ic-scroll-extra: 130px;
    }
}


/* #endregion */
/* #region 09  Patient Search */

.emr-patient-search-dialog {
    background: transparent;
    box-shadow: none;
    max-width: 100%;
}

.emr-patient-search-dialog .mud-dialog-content {
    padding: 16px;
    background: var(--mud-palette-background);
    height: 100vh;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}

.emr-patient-search-panel {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    background-color: transparent !important;
    background-image: url('/magnify.png');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

.emr-patient-search-layout {
    flex: 1 1 auto;
}

/* Shared "flex-fill, allow shrink" idiom (D7), reused by .emr-impersonation-body and
   .emr-alerts-body .mud-tabs below — their own rules point back here. */
.emr-patient-search-body,
.emr-impersonation-body,
.emr-alerts-body .mud-tabs {
    flex: 1 1 auto;
    min-height: 0;
}

.emr-patient-search-status-strip {
    row-gap: 0.5rem;
}

.emr-patient-search-header {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-white);
    border-radius: 4px 4px 0 0;
}

.emr-patient-search-header .mud-icon-root,
.emr-patient-search-header .mud-button-root,
.emr-patient-search-header .mud-icon-button {
    color: var(--mud-palette-white);
}

.emr-advanced-filters-rail {
    width: 280px;
    flex: 0 0 280px;
    align-self: stretch;
    border-right: 1px solid var(--emr-hairline);
    background-color: color-mix(in srgb, var(--mud-palette-surface) 92%, var(--mud-palette-background));
}

.emr-patient-search-results-wrap {
    overflow-x: auto;
    border-top: 1px solid var(--emr-hairline);
}

.emr-patient-search-grid {
    background: var(--mud-palette-surface);
}

.emr-patient-search-grid .mud-table-container {
    overflow-x: auto;
}

/* Grid header tint (D1) shared with .emr-offline-patients-grid below — same two-consumer rule,
   grouped rather than a new class (see plan §4). */
.emr-patient-search-grid .mud-table-head th,
.emr-offline-patients-grid .mud-table-head th {
    white-space: nowrap;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    background: var(--emr-grid-header-bg);
}

.emr-patient-search-grid .mud-table-body td {
    white-space: nowrap;
    font-size: 0.9375rem;
    color: var(--mud-palette-text-primary);
}

/* D11: .emr-patient-search-name's identity-text emphasis now comes from .emr-important
   (applied in the .razor markup) rather than a bespoke weight-500 rule — see design.md
   Typography Scale. */

/* Pinned to phone only, not widened to Tablet's 1279.98px: design.md's Phone Adaptations list the
   patient search dialog's reduced padding and stacked, top/bottom-bordered filter rail as Phone-only
   behavior. Tablet has room for the fixed-width filter rail sidebar and keeps Desktop's layout. */
@media (max-width: 599.98px) {
    .emr-patient-search-dialog .mud-dialog-content {
        padding: 8px;
    }

    .emr-patient-search-panel {
        min-height: calc(100vh - 16px);
    }

    .emr-patient-search-body {
        flex-direction: column;
    }

    .emr-advanced-filters-rail {
        width: auto;
        flex-basis: auto;
        border-right: 0;
        border-top: 1px solid var(--emr-hairline);
        border-bottom: 1px solid var(--emr-hairline);
    }
}

@media (max-width: 599.98px) {
    .emr-patient-search-grid .mud-table-head th,
    .emr-patient-search-grid .mud-table-body td {
        white-space: normal;
    }
}


/* #endregion */
/* #region 10  Offline Patients */

.emr-offline-patients-grid {
    background: var(--mud-palette-surface);
}

.emr-offline-patients-grid .mud-table-container {
    overflow-x: auto;
}

/* .mud-table-head th grouped with .emr-patient-search-grid above (D1) — the header tint is
   copied verbatim from patient search, not unique to this screen. */
.emr-offline-patients-grid .mud-table-body td {
    white-space: nowrap;
    font-size: 0.9375rem;
    color: var(--mud-palette-text-primary);
    vertical-align: middle;
}

/* D11: .emr-offline-patient-name's identity-text emphasis now comes from .emr-important
   (applied in the .razor markup) rather than a bespoke weight-500 rule — see design.md
   Typography Scale. */

.emr-offline-patient-card {
    position: relative;
    padding: 12px 16px;
    border-bottom: 1px solid var(--emr-hairline);
    cursor: pointer;
}

.emr-offline-patient-card:last-child {
    border-bottom: 0;
}

.emr-offline-patient-card-actions {
    position: absolute;
    top: 4px;
    right: 4px;
    display: flex;
    align-items: center;
    z-index: 1;
}

.emr-offline-patient-card-content {
    padding-right: 92px;
}

@media (max-width: 599.98px) {
    .emr-offline-patients-grid .mud-table-head th,
    .emr-offline-patients-grid .mud-table-body td {
        white-space: normal;
    }
}


/* #endregion */
/* #region 11  Mini Case Sheet */

/* Mini case sheet tile: compact patient identity card mounted in the app bar */
.emr-mini-case-tile {
    cursor: pointer;
    padding: 2px 10px;
    border: 1px solid var(--emr-hairline);
    border-radius: 8px;
    min-width: 120px;
    max-width: 220px;
    align-self: center;
}

.emr-mini-case-tile-row {
    display: flex;
    align-items: center;
    gap: 4px;
}

.emr-mini-case-tile-name {
    flex: 1 1 0;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.emr-mini-case-tile .mud-icon-button {
    width: 26px;
    height: 26px;
    padding: 2px;
}

.emr-mini-case-tile .mud-icon-root {
    font-size: 18px;
    width: 18px;
    height: 18px;
}

/* Mini-case dialog: lock to 70vh so tab switches don't resize the dialog
   (long Diagnoses/Medications vs short General tab cause flicker otherwise).
   The dialog content area scrolls; the title stays pinned. */
.emr-mini-case-dialog {
    height: 70vh;
    display: flex;
    flex-direction: column;
}

/* Shared "flex-fill, scroll on overflow" content body (D9), reused by
   .emr-workitem-detail-dialog below — its own rule points back here. */
.emr-mini-case-dialog .mud-dialog-content,
.emr-workitem-detail-dialog .mud-dialog-content {
    flex: 1 1 auto;
    overflow: auto;
}

/* Vertical rule between the left tab bar and the tab content panel */
.emr-mini-case-dialog .mud-tabs-tabbar {
    border-right: 1px solid var(--emr-hairline);
}

/* Vertical rule separating the alerts sidebar from the main content area */
.emr-mini-case-alerts {
    border-left: 1px solid var(--emr-hairline);
    padding-left: 16px;
    height: 100%;
}

/* Individual alert item — icon + label pair in the alerts sidebar */
.emr-mini-case-alert {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* General tab content wrapper — semantic identifier, layout owned by parent */
.emr-mini-case-general { }

/* Body grid: full-height flex container for the tab area + alerts sidebar */
.emr-mini-case-body {
    height: 100%;
}


/* #endregion */
/* #region 12  Dialogs */

/* === EMR dialog chrome (opt-in) ===
   Add Class="emr-dialog" to <MudDialog> to apply the EMR-AI design language:
     - Purple (primary) background + white text on the title bar
     - White close-button icon so it is visible on the purple background
     - 1px divider line above the action-button row
   Two-class selector (.mud-dialog.emr-dialog) wins specificity over MudBlazor defaults. */
.mud-dialog.emr-dialog .mud-dialog-title {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-white);
}

.mud-dialog.emr-dialog .mud-dialog-title .mud-button-root,
.mud-dialog.emr-dialog .mud-dialog-title .mud-icon-button,
.mud-dialog.emr-dialog .mud-dialog-title .mud-icon-root {
    color: var(--mud-palette-white);
}

.mud-dialog.emr-dialog .mud-dialog-actions {
    border-top: 1px solid var(--emr-hairline);
}

/* Minimum touch target for every DialogActions button (Cancel/Close/Save/Confirm/etc.) — Design.md Dialogs standard. */
.emr-dialog-action-btn {
    min-width: 100px;
}

/* Diagnostics viewer dialogs (ConsoleOutputDialog, LocalStorageDialog): the scrolling entry
   list/grid keeps a fixed viewport height so the dialog itself never grows past the screen. */
.emr-diagnostics-entry-list {
    max-height: 60vh;
    overflow-y: auto;
    gap: 2px;
}

/* Level-filter dropdown in ConsoleOutputDialog's toolbar row — narrow by design, not full-width. */
.emr-diagnostics-level-filter {
    max-width: 200px;
}

/* PDF viewer dialog only: it opens FullScreen and must let ONLY the PDF's own iframe scroll.
   Make the dialog a column so the content flexes to fill between the title and the actions, and
   kill the content area's default padding + scroll so there's no dialog-level scrollbar. Scoped
   to .emr-pdf-dialog so other .emr-dialog dialogs keep their normal scrolling content. */
.mud-dialog.emr-pdf-dialog {
    display: flex;
    flex-direction: column;
}
.mud-dialog.emr-pdf-dialog .mud-dialog-content {
    flex: 1 1 auto;
    min-height: 0;
    padding: 0;
    overflow: hidden;
}

/* Workitem detail dialog sizing (70% viewport).
   .mud-dialog.emr-workitem-detail-dialog has higher CSS specificity (2 classes) than MudBlazor's
   .mud-dialog-width-xl (1 class), so this max-width: 70vw rule overrides the 1920px constraint.
   The flexbox layout with flex: 1 1 auto on .mud-dialog-content makes it fill available space
   and enables internal scrolling when content exceeds dialog height, preventing layout flicker
   when tabs/data change. */
.mud-dialog.emr-workitem-detail-dialog {
    max-width: 60vw;
    height: 85vh;
    display: flex;
    flex-direction: column;
}

/* .mud-dialog-content flex body: see .emr-mini-case-dialog .mud-dialog-content grouped rule above (D9). */

@media (max-width: 1279.98px) {
    .mud-dialog.emr-workitem-detail-dialog {
        max-width: 100%;
        height: 100%;
        border-radius: 0;
        margin: 0;
    }
}

/* Med Orders dialog sizing (85% viewport).
   .mud-dialog.emr-med-orders-dialog has higher CSS specificity (2 classes) than MudBlazor's
   mud-dialog-width-xl (1 class), so this max-width: 85vw rule overrides the default constraint. */
.mud-dialog.emr-med-orders-dialog {
    max-width: 85vw;
}

@media (max-width: 1279.98px) {
    .mud-dialog.emr-med-orders-dialog {
        max-width: 100%;
    }
}

/* Training dialog: the careplan-grouped training list is long, so the list scrolls at a fixed
   height instead of letting the dialog grow past the viewport. Two classes beat MudBlazor's
   single-class mud-dialog-width-lg, same trick as emr-med-orders-dialog above. */
/* Training dialog: fixed height so switching between the Search and Training Provided tabs
   never resizes it. The list previously carried max-height:55vh, which sizes to content — the
   Provided tab is usually much shorter (often a single alert), so the dialog collapsed on every
   switch. The flex chain below (dialog -> content -> EmrTabs -> .mud-tabs-panels) hands the fixed
   height down to exactly ONE scrollable region, the active tab panel, so the list must NOT scroll
   independently or the dialog gets two scrollbars. Same approach as emr-impersonation-dialog.
   min() keeps it bounded on short viewports, where a flat 620px would overflow the screen. */
.mud-dialog.emr-training-dialog {
    max-width: 900px;
    height: min(620px, 80vh);
    display: flex;
    flex-direction: column;
}

/* Shared "fixed-height dialog, one flexible scrollable region" content body (D6), reused by
   .emr-picker-dialog and .emr-impersonation-dialog below — their own rules point back here. */
.emr-training-dialog .mud-dialog-content,
.emr-picker-dialog .mud-dialog-content,
.emr-impersonation-dialog .mud-dialog-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Matches the adjacent .mud-icon-button-size-medium (40px) so the "UE" button and the
   refresh icon button in the profile header share one row height. */
.emr-profile-header-action {
    min-height: 40px;
}

/* "Flex-fill tabs" idiom (D8). (The impersonation dialog used to share this before its
   three-tab layout was replaced by the list-first design.) */
.mud-tabs.emr-training-tabs {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
}

.emr-training-tab-panels {
    min-height: 0;
    overflow-y: auto;
}

/* Careplan group rows, tightened to legacy's compact ~40px header. MudBlazor's default is
   min-height:48px, and there is no min-height spacing utility to express this — the header padding
   and the expanded panel's margin are handled by py-2/px-3 and ma-0 utilities at the call site.
   One class more than MudBlazor's own .mud-expand-panel .mud-expand-panel-header, so this wins. */
.emr-training-dialog .mud-expand-panel .mud-expand-panel-header {
    min-height: 40px;
}

/* Ordering Physician / RN Collaborator pickers: fixed height so switching the source radio
   never resizes the dialog. Each source renders different content — the offline source has no
   search box and often shows a single "none on file" alert, the server sources show a spinner,
   then an empty-result caption or up to a page of rows — so a content-sized dialog jumped on
   every switch and again as results landed. The flex chain below (dialog -> .mud-dialog-content
   -> .emr-picker-body) hands the fixed height down to exactly ONE scrollable region,
   .emr-picker-results, so nothing inside it may scroll independently or the dialog gets two
   scrollbars. Same approach as emr-training-dialog / emr-impersonation-dialog above.
   min() keeps it bounded on short viewports, where a flat 560px would overrun the screen. */
.mud-dialog.emr-picker-dialog {
    height: min(560px, 80vh);
    display: flex;
    flex-direction: column;
}

/* .mud-dialog-content flex body: see .emr-training-dialog .mud-dialog-content grouped rule above (D6). */

.emr-picker-body {
    flex: 1 1 auto;
    min-width: 480px;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* Enforce the "static header + one flexible region" split the comment above promises. Without
   this, every direct child of the column flex container above shares the free height — MudBlazor's
   input wrappers (the radio group, the search field) grow by default — so a result list shorter
   than the dialog was pushed into the vertical middle with equal gaps above and below it instead
   of sitting at the top. Only .emr-picker-results may grow. */
.emr-picker-body > *:not(.emr-picker-results) {
    flex: 0 0 auto;
}

.emr-picker-results {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    /* Top-anchor the rows explicitly, so a short list cannot be centered by whatever
       layout the children end up in. */
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

/* Create Encounter dialog: wider than MaxWidth.Small (600px) to prevent chip truncation */
.mud-dialog.emr-create-encounter-dialog {
    max-width: 720px;
}

/* User Impersonation dialog: fixed width/height so switching between the List and Add views
   never resizes the dialog. The flex chain (content -> .emr-impersonation-body -> the view's
   grid/list) carries the fixed height down to exactly ONE scrollable region per view —
   .emr-impersonation-saved-grid on the list, .emr-impersonation-search-results on Add —
   instead of letting both the dialog content and an inner grid/list scroll independently
   (double scrollbars). */
.mud-dialog.emr-impersonation-dialog {
    width: 40vw;
    min-width: 500px;
    max-width: 700px;
    height: 560px;
    display: flex;
    flex-direction: column;
}

/* .mud-dialog-content flex body: see .emr-training-dialog .mud-dialog-content grouped rule above (D6). */

/* flex-fill idiom: see .emr-patient-search-body grouped rule above (D7). */

/* MudDivider's default "fullwidth" class carries flex-grow:1 (meant for dividers used as
   flex items inside a ROW, to stretch and separate items horizontally). Inside our COLUMN
   flex body it greedily grows on the vertical axis instead, pushing content down into the
   middle of the dialog whenever the view is short. Pin it back to its natural (thin) size. */
.emr-impersonation-body > .mud-divider {
    flex-grow: 0;
    flex-shrink: 0;
}

/* List view: the saved-people grid is the ONE scrollable region. It flex-fills the fixed-height
   body so the Current User row above and the Add button below never leave the screen, and its
   .mud-table-container scrolls internally once the list outgrows the space — QA lists of 12-15
   people previously clipped past the dialog edge (overflow:hidden content) and hid Add entirely.
   FixedHeader="true" on the grid keeps the column headers pinned while rows scroll. */
.emr-impersonation-saved-grid {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.emr-impersonation-saved-grid .mud-table-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* Add view: the search-results list is that view's one scrollable region — a discipline or
   program search returns up to 20 people, taller than the fixed dialog. */
.emr-impersonation-search-results {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

@media (max-width: 599.98px) {
    .mud-dialog.emr-impersonation-dialog {
        width: 100%;
        max-width: 100%;
        height: 100%;
        border-radius: 0;
        margin: 0;
    }
}

/* === Encounter Diagnoses dialog === */

.emr-diagnoses-body {
    min-width: 640px;
}

/* The ACTIVE list runs to many rows while the HISTORY tab is a single line of text, so the panel
   holds a floor height — otherwise the whole dialog collapses and re-expands on every tab switch.
   The list scrolls inside the panel rather than growing the dialog past the viewport. */
.emr-diagnoses-tabpanel {
    min-height: 420px;
    max-height: 55vh;
    overflow-y: auto;
}

/* Row layout: code | text | actions. Only the TEXT column flexes, so a long diagnosis name wraps
   inside its own column and the code and buttons keep their places. Letting the row itself wrap put
   the buttons on their own line and opened a gap above the dates. `min-width: 0` is what actually
   permits the wrap — without it a flex item refuses to shrink below its content width. */
.emr-diagnosis-row-main {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    flex-wrap: nowrap;
}

.emr-diagnosis-row-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Pinned right and never squeezed — these are tap targets. */
.emr-diagnosis-row-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
}

/* Description and dates align under the diagnosis NAME, clearing the fixed-width code column, so
   the row reads as one block rather than three left-aligned lines. */
.emr-diagnosis-code {
    min-width: 88px;
    flex: 0 0 auto;
}

.emr-diagnosis-detail,
.emr-diagnosis-dates {
    padding-left: 88px;
}

/* MudBlazor's own .mud-expand-panel-content sets padding-bottom:16px but defines no padding-top at
   all (_expansionpanel.scss), so every MudExpansionPanel in the app inherits a flush header-to-content
   gap unless something happens to compensate. Base (unscoped) 12px minimum floor — the same universal
   edge-padding convention used elsewhere in this audit pass — fixes six confirmed flush-to-header
   instances at once (My Links, Demographics/Patient Care/Contact, Be Aware/Animal Alert, Start
   Encounter, Outcomes, Elaborations). Scoped overrides with a documented reason for tighter spacing,
   like .emr-diagnosis-groups directly below, still win on specificity. */
.mud-expand-panel-content {
    padding-top: 12px;
}

/* MudBlazor gives an EXPANDED panel a 16px vertical margin and pads its content, which stacked with
   each row's own padding into a visible gap under the last row of every group. The rows already carry
   their own spacing, so the panel's is removed and only the content padding is kept, tight. */
.emr-diagnosis-groups .mud-expand-panel.mud-panel-expanded {
    margin-top: 0;
    margin-bottom: 0;
}

.emr-diagnosis-groups .mud-expand-panel-content {
    padding-top: 0;
    padding-bottom: 4px;
}

.emr-diagnosis-groups .mud-expand-panel-text {
    padding: 0;
}

/* Eight columns of change log will not fit a narrow screen; the table scrolls in place so the dialog
   itself never scrolls sideways. */
.emr-diagnosis-history-scroll {
    overflow-x: auto;
    max-width: 100%;
}

/* Phone. The 640px floor and the 88px indents are desktop affordances — on a narrow screen they force
   the whole dialog to scroll horizontally, clipping the diagnosis text (the row Stack already wraps).
   Below MudBlazor's sm breakpoint they are dropped and the row reads as stacked lines. */
@media (max-width: 599.98px) {
    .emr-diagnoses-body {
        min-width: 0;
    }

    .emr-diagnosis-code {
        min-width: 0;
    }

    /* Only here does the row itself wrap: on a phone the actions genuinely cannot share a line with
       the text, so they drop below it rather than crushing it. */
    .emr-diagnosis-row-main {
        flex-wrap: wrap;
    }

    .emr-diagnosis-detail,
    .emr-diagnosis-dates {
        padding-left: 0;
    }

    /* A phone dialog is full screen, so the list gets the height instead of a fixed panel. */
    .emr-diagnoses-tabpanel {
        min-height: 0;
        max-height: none;
    }
}

/* A diagnosis end-dated or removed during this encounter stays listed so it can be checked or undone,
   but it is no longer active — muted rather than removed, and never conveyed by color alone (the row
   still carries its explicit "End: <date>" text or "Removed" chip). */
.emr-diagnosis-row--ended {
    opacity: 0.6;
}

/* Rule violations (R01-R09). The panel keeps the error tint of the alert it replaced, so a COLLAPSED
   panel still reads as a problem — the header's icon and count carry the rest. */
.emr-diagnosis-violations-panel .mud-expand-panel {
    background-color: var(--mud-palette-error-hover);
    border-radius: var(--mud-default-borderradius);
}


/* === Allergies feature styles === */
/* Delete Allergy confirm dialog */
.mud-dialog.emr-allergy-delete-dialog .emr-delete-allergy-name {
    font-size: var(--mud-typography-body1-size);
    font-weight: var(--mud-typography-body1-weight);
    line-height: var(--mud-typography-body1-lineheight);
    letter-spacing: var(--mud-typography-body1-letterspacing);
    color: var(--mud-palette-primary);
}


/* #endregion */

/* #region 12b  Dialogs — design-audit additions (2026-10-01) */

/* QuestionHistoryDialog */
.emr-question-history-body {
    min-height: 160px;
    max-height: 60vh;
    overflow-y: auto;
}

.emr-question-history-question {
    min-width: 260px;
    flex-shrink: 0;
}

/* MedOrdersDialog / HmeOrdersDialog / OtherOrdersListDialog */
.emr-col-order-careplan {
    width: 35%;
}

/* AllowedSecondariesDialog / DiagnosisSearchDialog */
.emr-secondaries-dialog-body {
    min-width: 460px;
}

.emr-secondaries-list {
    max-height: 320px;
    overflow-y: auto;
}

/* MedOrdersDialog / EncounterDocumentsDialog — grid cells and group rows left-aligned */
.mud-table-cell.emr-col-justify-start {
    justify-content: flex-start;
}

.emr-doc-group-title {
    flex: 1;
    text-align: left;
}

.mud-typography.emr-grid-header-label {
    font: inherit;
    letter-spacing: inherit;
}

/* ViewEncounterJsonDialog */
.emr-view-json-tree {
    max-height: 60vh;
    overflow: auto;
    padding: 12px;
    border-radius: 4px;
    background: var(--mud-palette-background-gray, #f5f5f5);
    border: 1px solid var(--mud-palette-lines-default, #e0e0e0);
}

/* LookupTreeDialog */
.emr-lookup-tree-scroll {
    min-width: 360px;
    min-height: 480px;
    max-height: 480px;
    overflow-y: auto;
}

.emr-lookup-tree-row {
    border-radius: 4px;
}

.emr-lookup-tree-row:hover {
    background-color: var(--mud-palette-action-hover);
}

.emr-lookup-tree-toggle {
    flex-shrink: 0;
}

.emr-lookup-tree-toggle-spacer {
    width: 28px;
    flex-shrink: 0;
}

.emr-lookup-tree-label {
    flex: 1;
}

.emr-lookup-tree-clickable {
    cursor: pointer;
    padding: 5px 8px;
    border-radius: 4px;
    user-select: none;
}

.emr-lookup-tree-selected {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    font-weight: 500;
}

/* DiagnosisEndDateDialog / DiagnosisDetailsDialog */
.emr-diagnosis-enddate-body {
    min-width: 420px;
}

.emr-diagnosis-details-body {
    min-width: 480px;
}

.emr-diagnosis-code-col {
    min-width: 88px;
}

/* MedicationPickerDialog — one medication per row, same fixed-geometry list treatment as the
   qualifier picker, with the PON card's name/directions/coverage stack. */
.emr-med-picker-body {
    min-width: 480px;
}

.mud-stack.emr-med-pick-row {
    gap: 10px;
    padding: 8px 10px;
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
}

.emr-med-pick-row:not(:last-of-type) {
    border-bottom: 1px solid rgba(0,0,0,0.05);
}

.emr-med-pick-row:hover {
    background: rgba(0,0,0,0.04);
}

.emr-med-pick-row-selected {
    background: var(--mud-palette-primary-hover);
}

.emr-med-pick-icon {
    flex-shrink: 0;
    margin-top: 2px;
}

/* ResetRtcWarningDialog / NeedFullyDiscontinuedDialog / ResponseToCareDialog */
.emr-rtc-dialog-body {
    min-width: 460px;
    max-width: 600px;
}

/* ResponseToCareDialog (class names shared with RtcOptionView, which is outside this batch) */
.rtc-group-head { font-size: 12px; letter-spacing: .04em; }
.rtc-opt-row {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 7px 8px; border-radius: 4px; cursor: pointer; user-select: none;
}
.rtc-opt-row:hover { background: rgba(0,0,0,0.04); }
.rtc-opt-row-selected { background: var(--mud-palette-primary-hover); }

/* PhysicianPickerDialog / StaffPickerDialog / MedicationPickerDialog */
.emr-pick-row-text {
    flex: 1;
    min-width: 0;
}

.phys-pick-row,
.staff-pick-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
}
.phys-pick-row:not(:last-of-type),
.staff-pick-row:not(:last-of-type) {
    border-bottom: 1px solid rgba(0,0,0,0.05);
}
.phys-pick-row:hover,
.staff-pick-row:hover {
    background: rgba(0,0,0,0.04);
}
.phys-pick-row-selected,
.staff-pick-row-selected {
    background: var(--mud-palette-primary-hover);
}
.phys-pick-icon,
.staff-pick-icon {
    flex-shrink: 0;
    margin-top: 2px;
}

/* SymptomHistoryDialog */
.symptom-history-tabs .mud-tabs-panels {
    min-height: 200px;
    max-height: 60vh;
    overflow-y: auto;
}

/* RnReportPreviewDialog */
.emr-rn-report-body {
    min-width: 480px;
}

/* PalliationProvocationDialog */
.emr-pp-grid .mud-table-head .mud-table-cell {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}

.emr-pp-grid .mud-table-head .mud-table-cell.emr-pp-col-flag,
.emr-pp-grid .mud-table-body .mud-table-cell.emr-pp-col-flag {
    text-align: center;
    width: 1%;
    white-space: nowrap;
}

.emr-pp-grid .mud-table-body .mud-table-row:nth-child(even) {
    background: rgba(0, 0, 0, 0.025);
}

.emr-pp-other-bar {
    border-top: 1px solid rgba(0, 0, 0, 0.08);
    padding-top: 12px;
}

.emr-pp-other-row {
    max-width: 480px;
}

/* AddSymptomDialog — the dialog body is a fixed height so the search box doesn't bounce around as the
   list filters down. The list itself scrolls inside this region. */
.emr-add-symptom-content {
    min-height: 480px;
}

.emr-add-symptom-list-scroll {
    flex: 1;
    min-height: 420px;
    max-height: 420px;
    overflow-y: auto;
}

/* EditLabelDialog */
.emr-text-bold {
    font-weight: 700;
}

.emr-pre-wrap {
    white-space: pre-wrap;
    word-break: break-word;
}

/* AddOtherOrderDialog / CloseReasonDialog — content min-width 480px plus dialog padding */
.mud-dialog.emr-add-other-order-dialog,
.mud-dialog.emr-close-reason-dialog {
    min-width: 528px;
}

/* InterventionBuilderDialog */
.mud-dialog.emr-intervention-builder-dialog {
    min-width: 568px;
}

.emr-intervention-preview {
    background: color-mix(in srgb, var(--mud-palette-info) 6%, transparent);
}

/* The read-only Specifier can be a long custom Need name — let it wrap and grow
   instead of clipping to a single line. */
.spec-field .mud-input-control-input-container {
    white-space: normal;
    word-break: break-word;
}

/* QualifierPickerDialog */
.emr-qualifier-list {
    min-width: 360px;
}

/* One option per row — fixed geometry, so nothing moves when a row is picked
   (the chip layout reflowed on selection because chip widths changed). */
.emr-qualifier-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
}
.emr-qualifier-row:not(:last-of-type) {
    border-bottom: 1px solid rgba(0,0,0,0.05);
}
.emr-qualifier-row:hover {
    background: rgba(0,0,0,0.04);
}
.emr-qualifier-row-selected {
    background: var(--mud-palette-primary-hover);
}
.emr-qualifier-row-disabled {
    opacity: 0.45;
    cursor: default;
    pointer-events: none;
}
.emr-qualifier-row-icon {
    flex-shrink: 0;
}
.emr-qualifier-row-label {
    word-break: break-word;
}

/* REQTEXT input sits indented under its row, aligned with the label text. */
.emr-qualifier-row-text {
    margin: 2px 10px 10px 36px;
}

/* SpecifierInterventionsDialog */
.mud-dialog.emr-specifier-interventions-dialog {
    min-width: 588px;
}

.emr-spec-row {
    width: 100%;
    padding: 4px 0;
}
.emr-spec-row:not(:last-child) {
    border-bottom: 1px solid rgba(0,0,0,0.05);
}
/* Service items (Meds / HME / Supplies / Other Orders) read as cards — one item
   per row with the name on the option line and the description beneath. */
.emr-spec-row-card {
    border: 1px solid rgba(0,0,0,0.10);
    border-radius: 4px;
    padding: 6px 10px;
    margin-bottom: 6px;
}
.emr-spec-row-card:not(:last-child) {
    border-bottom: 1px solid rgba(0,0,0,0.10);
}
/* Description sits under the checkbox/radio label, aligned with its text. */
.emr-spec-description {
    display: block;
    margin-left: 32px;
    margin-top: -4px;
    white-space: pre-wrap;
    word-break: break-word;
}
/* Force the radio options to stack one-per-row (MudRadioGroup lays children out
   inline by default). The selected option's interventions then render beneath it.
   Target both the group root and its inner container so it works regardless of
   MudRadioGroup's internal DOM. */
.emr-spec-radio-group,
.emr-spec-radio-group > .mud-input-control-input-container {
    display: flex !important;
    flex-direction: column;
    align-items: stretch;
}
/* Intervention group sits indented under its checkbox/radio, like the screenshot. */
.emr-spec-interventions {
    margin-left: 32px;
    margin-bottom: 8px;
}

/* One plus, one color: the label dropped its literal "+" (the StartIcon is
   the plus) and the icon is pinned to the button's text color so it never
   renders darker than the label. */
.emr-add-intervention-btn .mud-icon-root {
    color: inherit;
}

/* EncounterStatisticsDialog */
.emr-col-right { text-align: right; }

/* PdfViewerDialog */
.emr-pdf-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ImpersonationDisciplineDialog */
.emr-impersonation-search-name { max-width: 200px; }
.emr-impersonation-search-discipline { min-width: 220px; }
.emr-impersonation-search-program { max-width: 160px; }

/* FavoritesDialog */
.emr-min-w-0 { min-width: 0; }

/* WorkitemDetailDialog */
.mud-divider.emr-workitem-lock-divider { height: 24px; }
.emr-workitem-status-chip { width: fit-content; }

/* #endregion */
/* #region 13  Notifications / Animations */

/* EncounterLoadingOverlay — full-page dark scrim, centered progress card. */
.emr-encounter-loading-card {
    min-width: 340px;
    text-align: center;
}

.emr-encounter-loading-bar .mud-progress-linear-bar {
    transition: transform 0.35s ease;
}

/* Probing/Checking dot: pulse opacity to signal in-progress state without color alone (DL-14.4). */
@keyframes emr-dot-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.25; }
}

.emr-status-dot--probing {
    animation: emr-dot-pulse 1.2s ease-in-out infinite;
}

/* Honour reduced-motion preference — fall back to a solid dot with no animation. */
@media (prefers-reduced-motion: reduce) {
    .emr-status-dot--probing {
        animation: none;
    }
}

/* Page transition: MainLayout keys the @Body wrapper on the route so Blazor remounts
   it on navigation, letting this run fresh each time (e.g. Encounters "Resume", Home → patient details). */
@keyframes emr-page-fade-in {
    from { opacity: 0; transform: translateY(127px); }
    to   { opacity: 1; transform: translateY(0); }
}

.emr-page-transition {
    animation: emr-page-fade-in 200ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .emr-page-transition {
        animation: none;
    }
}

/* ── Progress notification pill ─────────────────────────────────────── */
.emr-progress-notification-overlay {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9998;
}

.emr-progress-notification-pill {
    position: absolute;
    top: 68px;
    left: 50%;
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 9999px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-info);
    color: var(--mud-palette-white);
    white-space: nowrap;
    font-size: 0.875rem;
}

.emr-pill-enter {
    animation: emr-pill-drop 200ms ease-out forwards;
}

.emr-pill-exit {
    animation: emr-pill-rise 200ms ease-in forwards;
}

@keyframes emr-pill-drop {
    from { transform: translateX(-50%) translateY(-120%); opacity: 0; }
    to   { transform: translateX(-50%) translateY(0);     opacity: 1; }
}

@keyframes emr-pill-rise {
    from { transform: translateX(-50%) translateY(0);     opacity: 1; }
    to   { transform: translateX(-50%) translateY(-120%); opacity: 0; }
}

@keyframes emr-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.emr-progress-notification-message {
    max-width: 480px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* === Shared classes extracted from inline styles (design-issues-2026-06-04) === */

.emr-progress-notification-icon {
    flex-shrink: 0;
}

.emr-progress-notification-spinner {
    animation: emr-spin 1.2s linear infinite;
}

/* === EmrAnimate === */

.emr-animate-host {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.emr-animate--in-progress {
    pointer-events: none;
}

.emr-animate-content--hidden {
    visibility: hidden;
}

.emr-animate-dots {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
}

.emr-animate-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background-color: currentColor;
    animation: emr-dot-pulse 1.2s ease-in-out infinite;
}

.emr-animate-dot:nth-child(2) { animation-delay: 0.2s; }
.emr-animate-dot:nth-child(3) { animation-delay: 0.4s; }

@media (prefers-reduced-motion: reduce) {
    .emr-animate-dot {
        animation: none;
        opacity: 0.4;
    }
}


/* #endregion */
/* #region 14  Badges / Status Indicators */

.emr-hme-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 3px;
    font-size: var(--mud-typography-caption-size);
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.emr-hme-badge--hme      { background: var(--emr-hme-badge-hme-bg);      color: var(--emr-hme-badge-hme-text); }
.emr-hme-badge--supplies { background: var(--emr-hme-badge-supplies-bg);  color: var(--emr-hme-badge-supplies-text); }

/* "NEW" indicator on interventions/symptoms/needs added during the current encounter —
   a compact, non-interactive badge (shorter than a standard chip, close to the text line
   height) that flows inline at the end of the item's text. Shared by the care-plan Needs
   list (InterventionGroupList), the RTC worklist (RtcGroupView), NeedItem, and SymptomItem.
   Color is owned entirely here (not by a MudChip Color= prop at each call site) so it can
   be changed in one place — every "NEW" chip omits Color= and relies on this rule instead;
   the two-class selector beats MudChip's own size/margin/color rules. */
.emr-new-chip.mud-chip {
    height: 16px;
    padding: 0 6px;
    font-size: 10px;
    font-weight: 600;
    border-radius: 8px;
    margin: 0 0 0 6px;
    vertical-align: middle;
    background-color: var(--mud-palette-info);
    color: var(--mud-palette-info-text);
}


/* #endregion */
/* #region 15  Contact / Links */

.emr-contact-link {
    color: var(--mud-palette-primary);
    text-decoration: none;
    font-weight: 500;
}

.emr-contact-link-type {
    font-size:   var(--mud-typography-caption-size);
    font-weight: var(--mud-typography-caption-weight);
    color: var(--mud-palette-text-secondary);
}


/* #endregion */
/* #region 16  Utilities */

.emr-icon-sm {
    font-size: 1.1rem;
}

.emr-dim {
    opacity: 0.5 !important;
}

/* Muted/zero value indicator — used when a numeric field is 0 or empty */
.emr-muted { color: var(--mud-palette-text-disabled); }

.emr-select-min-width {
    min-width: 140px;
}

/* Pending Approval / Active / All Tasks filter rows: Tablet and Phone collapse Program/Team/Vx/
   Status behind a filter-toggle button (AllTasksPage.razor, PendingApprovalTab.razor) instead of
   wrapping the whole control set onto multiple lines, so .emr-tasks-filter-row only ever needs to
   fit Search + the toggle at those widths. The expanded panel is a sibling MudStack with its own
   Row/Wrap/Spacing props — no dedicated CSS class needed. */

.emr-doc-action-col {
    width: 140px;
}

.emr-dev-error-stacktrace {
    font-family: monospace;
    font-size: 0.75rem;
    max-height: 200px;
    overflow: auto;
    white-space: pre-wrap;
    margin-top: 0.5rem;
}

/* PDF viewer dialog — fullscreen MudDialog with iframe */
/* Fill the dialog content area (not the viewport) so the container doesn't overflow and add
   its own scrollbar. */
.emr-pdf-container {
    width: 100%;
    height: 100%;
    display: flex;
}

/* Two renderers live in here (see pdf-viewer.js). On desktop the child is the browser's own PDF
   <iframe>, which scrolls internally — this wrapper must not add a second scrollbar. On iPhone
   and iPad the children are canvases and this element is the scroll root, which is what
   .emr-pdf-scrolls switches on. WebKit gives an inline-PDF subframe no scroll region of its own,
   so clipping the wrapper there left no way at all to reach page 2. */
.emr-pdf-viewer {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.emr-pdf-viewer.emr-pdf-scrolls {
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch; /* momentum scrolling on iPad */
    background-color: var(--mud-palette-background-grey);
}

.emr-pdf-frame {
    width: 100%;
    height: 100%;
    border: 0;
}

/* Height is set per page from the PDF's own aspect ratio before rasterising, so the scrollbar is
   correct immediately and pages do not jump as they render in. */
.emr-pdf-page {
    margin: 0 auto 8px;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .24);
}

.emr-pdf-page-canvas {
    display: block; /* kills the inline-element baseline gap under each page */
    width: 100%;
    height: 100%;
}


/* ─── EmrChipItem ──────────────────────────────────────────────────────── */

.emr-chip-group {
    display: contents; /* invisible wrapper — no layout effect */
}

/* Override MudChip's default centered content with our left-aligned flex row */
.emr-chip-item.mud-chip {
    justify-content: flex-start !important;
    cursor: pointer;
    user-select: none;
}

/* MudStack Row wrapper: careplan name pinned left, indicators pinned right via MudSpacer */
.emr-chip-item__content {
    width: 100%;
}

.emr-chip-item__icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--mud-palette-primary);
    transition: color 0.15s ease;
}

/* Selected icon: white with slight transparency (sits on the filled purple chip) */
.emr-chip-item--selected .emr-chip-item__icon {
    color: color-mix(in srgb, var(--mud-palette-white) 80%, transparent);
}

.emr-chip-item__label {
    flex: 0 1 auto;
}

/* Single-line clamp only when TruncateText > 0 */
.emr-chip-item__label--truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Vertical divider between label and indicator */
.emr-chip-item__divider {
    flex-shrink: 0;
    opacity: 0.35;
}

.emr-chip-item__indicator {
    flex-shrink: 0;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.03em;
}

.emr-chip-item--disabled.mud-chip {
    opacity: 0.45;
    pointer-events: none;
    cursor: default;
}

/* #endregion */
/* #region 17  Encounter editor shell */
/* Encounter editor now shares MainLayout's app-bar/drawer/main-content structure
   (EncounterLayout.razor). These rules cover the pieces specific to the encounter:
   the app-bar Save & Close action, the content-area tool strip (formerly the
   standalone EncounterToolbar), and the left-nav rows hosted in the shared purple
   drawer (.emr-drawer / .emr-nav-link / .emr-nav-active, defined in section 02.2). */

/* 06.1  App-bar Save & Close action (EncounterAppBarActions) */

.emr-encounter-appbar-actions {
    display: flex;
    align-items: center;
}

.emr-encounter-save-split {
    display: inline-flex;
    align-items: center;
}

.emr-encounter-save-split .toolbar-icon-btn {
    margin-right: 0;
}

/* The caret is a MudMenu with a built-in ArrowDropDown activator. Widen its icon button and
   make it full-height with a left divider so it reads as attached to Save & Close. */
.emr-encounter-save-caret .mud-icon-button {
    width: 56px;
    height: 70px;
    border-radius: 0 6px 6px 0;
    border-left: 1px solid var(--mud-palette-lines-default);
}

.emr-encounter-save-caret .mud-icon-button:hover {
    background: var(--mud-palette-action-default-hover);
}

/* 06.2  App-bar tool strip (EncounterToolStrip)
   Lives inside .emr-appbar's toolbar row, between EmrAppBarHeader and the MudSpacer that
   pins EncounterAppBarActions right. flex/min-width/overflow let it shrink under the
   ResizeObserver-driven overflow logic in EncounterToolStrip.razor.cs instead of pushing
   Save & Close out of the bar. */

.emr-encounter-toolstrip {
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 4px;
    /* flex-grow:1 so this claims its share of available app-bar width instead of
       ceding all surplus to the trailing MudSpacer — otherwise, once the strip
       shrinks once (e.g. during initial full-content render), it never grows back
       and the overflow ellipsis stays stuck even on a wide desktop viewport. */
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: hidden;
}

.emr-encounter-toolstrip-tools {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    /* This box fills the whole center group (needed so its measured clientWidth reflects the
       full available width for the ResizeObserver overflow logic) — center its buttons within
       that box so they read as EmrAppBar's center group, same as the Home/Patient toolbar. */
    justify-content: center;
    /* overflow-x only: the joined warning/error pill (EmrMultiBadge) on a button like Alerts
       protrudes above the icon's top edge same as any single badge. overflow:hidden here
       clipped that top edge; overflow-x still lets the ResizeObserver width logic work. */
    overflow-x: hidden;
}

.emr-encounter-toolstrip-overflow {
    margin: 0 4px;
    flex-shrink: 0;
}

/* Finger-friendly tool button: large icon + label stacked, ~70px slot
   (68px + 1px margins each side — keep in sync with ToolSlotPx in EncounterToolStrip.razor.cs).
   Narrowed from 80px so about two more buttons stay inline before the overflow "More" menu takes
   them; the label still clamps to two lines, so longer labels wrap rather than truncate.
   Shared by ToolbarIconButton (used by both the tool strip and the app-bar Save & Close action). */
.toolbar-icon-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 68px;
    min-width: 68px;
    height: 70px;
    margin: 0 1px;
    padding: 4px 2px;
    gap: 2px;
    flex-shrink: 0;
    border: none;
    background: transparent;
    border-radius: var(--mud-default-borderradius);
    cursor: pointer;
    color: var(--mud-palette-text-primary);
}

/* Icon size: 32px, down from MudBlazor's Size.Large (36px). The inline-SVG path sizes via an
   inline style, so it needs !important to be overridden. */
.toolbar-icon-btn .mud-icon-root {
    font-size: 2rem;
}

.toolbar-icon-btn .icon-ref-svg {
    width: 2rem !important;
    height: 2rem !important;
}

.toolbar-icon-btn:hover:not(:disabled) {
    background: var(--mud-palette-action-default-hover);
}

.toolbar-icon-btn:disabled {
    opacity: 0.5;
    cursor: default;
}

/* One-off widening for the impersonation toggle's "Impersonating" label — one
   unbreakable word, too wide for the shared 68px slot with no space to wrap at
   (unlike "My Links"/"My Team"). Declared after .toolbar-icon-btn to win on equal
   specificity; every other toolbar item is unaffected. */
.emr-impersonation-toggle {
    width: 84px;
    min-width: 84px;
}

.toolbar-icon-label {
    font-size: 11px;
    line-height: 1.1;
    text-align: center;
    max-width: 100%;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* EmrMultiBadge: one joined pill over the icon, top-right, instead of two overlapping
   MudBadges — a warning segment and an error segment fused into a single rounded shape so
   both counts read as one badge rather than a stack. */
.emr-multi-badge-anchor {
    position: relative;
    display: inline-flex;
}

.emr-multi-badge {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(35%, -35%);
    display: flex;
    align-items: center;
    border-radius: 10px;
    overflow: hidden;
    height: 18px;
    font-size: 11px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
}

.emr-multi-badge-seg {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-width: 18px;
    padding: 0 5px;
    height: 100%;
}

.emr-multi-badge-seg.warning {
    background: var(--mud-palette-warning);
    color: var(--mud-palette-warning-text);
}

.emr-multi-badge-seg.error {
    background: var(--mud-palette-error);
    color: var(--mud-palette-error-text);
}

/* Divider so the two fills read as joined but distinct segments, not one blended color. */
.emr-multi-badge-seg.warning + .emr-multi-badge-seg.error {
    border-left: 1px solid var(--mud-palette-surface);
}

/* 06.3  Left-nav rows (EncounterNav), hosted inside the shared .emr-drawer */

/* Container (.emr-drawer-nav) and row (.emr-drawer-nav-row) styling now live in section 02.2
   — EncounterNav renders through the same EmrDrawerNav container as EmrNavMenu /
   PatientScopedNavMenu, so there is no EncounterNav-specific container/row CSS left here. */

/* The encounter-type title ("UCA", "ICA", ...) is a real header, not a nav-section
   group label (those use EmrNavGroupHeader / .emr-nav-section) — bigger, plain
   drawer-text white, no dimming or uppercase treatment. */
.emr-drawer-nav-title {
    padding: 12px 12px 8px 12px;
}

.emr-drawer-nav-title .mud-typography-subtitle1 {
    color: var(--mud-palette-drawer-text);
    font-weight: 500;
    margin: 0;
}

/* No flex-grow here — .emr-nav-link-row's MudSpacer now owns pushing trailing content to
   the right edge; growing the text too would split the space between them. Normal wrapping
   is intentional (multi-word labels like "General End of Life" should wrap onto a second
   line, not truncate) — min-width:0 + overflow-wrap:break-word instead handles the one case
   wrapping can't: a single unbreakable word longer than the row ("Musculoskeletal") breaks
   mid-word onto its own line instead of overflowing under the CP/warning badges. */
.emr-nav-link-text {
    min-width: 0;
    overflow-wrap: break-word;
}

/* CP (active care plan) indicator: readable on both the unselected row's purple
   background and the selected row's white background, so it's fixed regardless
   of MudBlazor's Color/Variant-driven chip classes. */
.emr-encounter-nav-cp-chip.mud-chip {
    height: 18px;
    width: 18px;
    min-width: 18px;
    font-size: 9px;
    font-weight: 700;
    border-radius: 50%;
    justify-content: center;
    background-color: color-mix(in srgb, var(--mud-palette-primary) 25%, var(--mud-palette-white)) !important;
    color: var(--mud-palette-secondary) !important;
}

/* 06.4  Content region (EncounterPage) */

.emr-encounter-content {
    background-color: var(--mud-palette-background);
}

/* Wound / Skin Impairment details panel — reads as an entry surface, not a plain
   card, by borrowing the same fill token the filled inputs around it use
   (--emr-input-filled-bg, applied to .mud-input-filled in app.mudblazor.css).
   Elevation stays off per design.md §Elevation (feature panels are Outlined). */
.wound-details-panel {
    background-color: var(--emr-input-filled-bg);
}

/* #endregion */
/* #region 18  Platform Widgets */

/* EmrChipSelect — the wrapping div has no intrinsic width, so in a flex/grid
   container (e.g. a MudDataGrid header or cell) it shrinks to its content
   instead of filling the column, same failure mode fixed before on
   .emr-pain-level and the EndSection picker fields. MudField's own
   FullWidth="true" only fills THIS div, not the div's own box. */
.emr-chip-select {
    width: 100%;
}

/* EmrPainLevel — full-width launcher field; the whole control opens the non-verbal pain
   dialog (large touch target). */
.emr-pain-level {
    width: 100%;
}

/* Whole-field-clickable pattern (D5, grouped rather than a shared class — each name below is
   already conditional in its own component's markup, only emitted when the control is
   editable; threading a shared class through five components' conditional class logic would
   risk breaking a ReadOnly state for zero gain over grouping the identical rule here):
     - .emr-chip-select--interactive     EmrChipSelect, opens its selection dialog
     - .emr-group-select--interactive    EmrGroupSelect, opens its grouping dialog (always editable)
     - .emr-pain-level--interactive      EmrPainLevel, opens the non-verbal pain dialog
     - .qualifier-block--interactive     QualifierBlockView / inline Impact field
     - .flag-rows-block--interactive     FlagRowsBlockView (Palliation / Provocation), always editable
     - .end-picker-block--interactive    EndSection Ordering Physician / RN Collaborator pickers, always editable
     - .emr-pocr-physician-picker-block--interactive   PocrRecertOrderDialog's physician picker, always editable
   The descendant selector is needed because browsers resolve the default `cursor: auto` on
   selectable text (label, placeholder, chip text) to a text-select I-beam regardless of the
   pointer set on the wrapper — every descendant needs it explicitly. */
.emr-chip-select--interactive,
.emr-chip-select--interactive *,
.emr-group-select--interactive,
.emr-group-select--interactive *,
.emr-pain-level--interactive,
.emr-pain-level--interactive *,
.qualifier-block--interactive,
.qualifier-block--interactive *,
.flag-rows-block--interactive,
.flag-rows-block--interactive *,
.end-picker-block--interactive,
.end-picker-block--interactive *,
.emr-pocr-physician-picker-block--interactive,
.emr-pocr-physician-picker-block--interactive * {
    cursor: pointer;
}

/* EmrChipSelect chip — width:60%/max-width:60% used to be set here to give the
   chip a comfortable tap target on tablets, paired with a .mud-chip-content
   override (display:flex; justify-content:space-between; width:100%) meant to
   spread the label and close icon across that wider box. Live inspection
   (computed styles + bounding boxes) showed the 60% never actually took
   effect — the chip's parent (.mud-chip-container, display:contents, inside
   the field's flex row) never resolves a definite width for the percentage
   to compute against, so the chip was already rendering at its natural
   content width regardless. The .mud-chip-content override was still active
   though, and space-between plus MudBlazor's own -4px right margin on
   .mud-chip-close-button (built for a content-sized chip, where the chip's
   own padding absorbs it) pushed the close button past the chip's own right
   edge — the chip has overflow:visible, so nothing clipped it, and the (X)
   visibly spilled outside the pill (worse the shorter the label, since
   space-between had more empty width to distribute). Confirmed live: with
   both overrides removed, MudBlazor's own default chip sizing keeps the
   close button flush inside the pill for both short ("Change") and long
   ("(LPN) Licensed Prac Nurse") labels. No override needed here — the whole
   field (the wrapping <div data-testid="emr-chip-select">) is already the
   real tap target via its own @onclick, so the chip itself was never load-
   bearing for touch-friendliness in the first place. */

/* Reusable utility (2026-08-10, developer ask): any Filled-variant MudField/MudTextField/etc.
   that never sets Label — only Placeholder — inherits MudBlazor's floating-label padding anyway
   (div.mud-input-slot.mud-input-root.mud-input-root-filled { padding: 27px 12px 10px }, reserved
   for a label shrinking into the top of the field), which just pushes empty-looking content down
   instead of centering it. Add this class to the control's own Class parameter wherever that
   applies (EmrChipSelect below is the first consumer; anything else with the same no-Label,
   Filled-variant shape can reuse it).

   Needs !important, not just a longer selector: DevTools confirmed the competing MudBlazor rule's
   specificity is (0,3,1) — three classes AND a `div` type selector — so a same-depth descendant
   selector without also naming `div` only ties on class count and then LOSES on the type-selector
   tiebreak (a bug in this file's own prior attempt at this fix, which used a 3-class selector with
   no type selector and consequently never took visual effect despite looking like an override).
   Vertical padding is 6px, not 0 (developer ask, 2026-08-10): 0 pinned the chip flush against the
   row's top/bottom borders with no breathing room at all — some vertical padding is still wanted,
   just nowhere near MudBlazor's 27px/10px reserved for a label that was never there.

   align-items: center is load-bearing, not tidiness: at 0 vertical padding the row was exactly the
   chip's own height, so there was no room for a misalignment to be visible regardless of the flex
   default. Once padding gave the row more height than the (fixed-height) chip, the default
   align-items: normal — effectively stretch, but a no-op against a chip with an explicit height —
   left the chip pinned to the row's top edge, clipping its bottom edge (and the close button on
   it) against the row's own fixed height instead of floating centered inside the extra space. */
.emr-textfield-narrow .mud-input-root-filled {
    padding: 6px 4px !important;
    display: flex;
    align-items: center;
}

/* EmrChipSelectDialog — row layout for its MudListItem options, matching
   QualifierPickerDialog's .qualifier-row box model (spacing/divider only;
   selected-row color comes natively from MudList's Color parameter). */
.emr-chip-select-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 4px;
    cursor: pointer;
    user-select: none;
}

.emr-chip-select-option:not(:last-of-type) {
    border-bottom: 1px solid var(--emr-scrim-subtle);
}

/* Generic vertical picker-dialog option row - icon + label + optional
   description, one row per value. Introduced for ImpactPickerDialog (moved
   out of its former inline <style> block per §2 Operating Rules) but named
   generically so any other single/multi-select picker dialog can reuse it
   instead of re-declaring its own row styling (see QualifierPickerDialog's
   .qualifier-row for a near-identical, not-yet-unified pattern). */
.emr-picker-question {
    font-weight: 500;
}

.emr-picker-option-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.emr-picker-option-row {
    display: flex;
    align-items: flex-start;
    padding: 8px 12px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s;
}

.emr-picker-option-row:hover {
    background: var(--emr-scrim-subtle);
}

.emr-picker-option-row.selected {
    background: color-mix(in srgb, var(--mud-palette-primary) 10%, transparent);
}

.emr-picker-option-content {
    flex: 1;
}

.emr-picker-option-label {
    font-weight: 700;
}

.emr-picker-option-description {
    color: rgba(0, 0, 0, 0.9);
}

/* EmployeePickerDialog's currently-assigned row highlight — same pattern as
   PhysicianPickerDialog's .phys-pick-row-selected, so the two pickers read consistently. */
.emr-employee-picker-row-selected {
    background: var(--mud-palette-primary-hover);
    outline: 1px solid var(--mud-palette-primary);
}

/* EmrCountdown — the warn state is a class rather than a bound MudBlazor Color so crossing the
   threshold costs one render instead of one per tick. Tabular figures stop the text jittering
   as digits change width each second. */
.emr-countdown {
    font-variant-numeric: tabular-nums;
}

.emr-countdown--warn {
    color: var(--mud-palette-warning);
    font-weight: 500;
}

/* ══════════════════════════════════════════════════════════════════════════
   NEEDS SELECTION DIALOG — Features/Encounter/Needs. Edit only within this block.
   Careplan/Need/Specifier are hand-rolled pseudo-rows (no MudDataGrid grouping/expander —
   both disabled below), indented by class rather than nested markup.

   LOAD-BEARING — do not remove without re-measuring (Nemo lesson #952, authority 80):
     - table-layout: fixed on .mud-table-root — the ONLY thing keeping this grid responsive.
       MudBlazor's default auto layout lets nowrap cells set an unshrinkable min-content floor.
     - Column widths live ONLY in the <colgroup> (col.emr-needs-col-*), by class, never on
       th/td, never inline style. As of the 2026-09-23 layout rework the label <col> is a
       fixed-width "chip column" (80px) and the four identity <col>s are the widthless ones —
       they split whatever's left over equally under table-layout: fixed. This is the reverse of
       the original design (label absorbed leftover); see the col rules below for the current
       numbers and why.
     - .emr-needs-span-content takes row content out of flow (position:absolute, pinned
       between the rail and action columns) as a colspan substitute, so a long label
       ellipsizes instead of inflating the table. Its width:auto and its typography's
       min-width:0 are both measured fixes for real overflow bugs. Components opt in by name
       (Phase 11 note: AddInterventionCell, which never took this class, was retired outright —
       its footer row is no longer emitted or rendered).
   ══════════════════════════════════════════════════════════════════════════ */

/* Row indent ladder (developer spec, final): Careplan 0, Need 24px, Specifier 48px — one
   repeating step. Adds to .emr-needs-span-content's own box, never overrides its position/width. */
.emr-needs-row-indent-careplan { padding-left: 0; }
.emr-needs-row-indent-need { padding-left: 24px; }
.emr-needs-row-indent-specifier { padding-left: 48px; }

/* Hierarchy-level chips, one presentation at all three levels. Careplan's color is set in the
   .razor markup (Color.Primary); Need/Specifier use custom hex via these classes since MudChip's
   Color enum can't carry arbitrary hex — values are developer-specified, final.
   .emr-needs-level-chip.mud-chip min-width/justify-content grouped (D10) with .emr-status-chip —
   see §08 Grid / Table. */

.emr-needs-level-chip-need.mud-chip {
    background-color: var(--emr-needs-level-need-bg);
    color: rgba(0, 0, 0, 0.87);
}

.emr-needs-level-chip-specifier.mud-chip {
    background-color: var(--emr-needs-level-specifier-bg);
    color: rgba(0, 0, 0, 0.87);
}

/* Touch-target floor (44px, Apple's minimum) for the Careplan/Need expanders on coarse pointers
   (iPad portrait) — MudBlazor's Size.Small icon button is ~30px, under that floor. */
@media (pointer: coarse) {
    .emr-needs-grid .emr-needs-row-indent-need .mud-icon-button,
    .emr-needs-grid .emr-needs-careplan-group .mud-icon-button {
        min-width: 44px;
        min-height: 44px;
    }
}

/* Anchor wrapper for the Required chip's popover. */
.emr-required-chip-anchor { position: relative; }

.emr-careplan-readonly-note { color: var(--mud-palette-warning-darken); }

/* Careplan group header row spans full width so Justify.SpaceBetween can push its
   "Add Custom Need" button flush right. */
.emr-needs-careplan-group { width: 100%; }

/* The <tr> is NO LONGER the containing block for .emr-needs-span-content — the label <td> is
   (see the span rules below). History, so nobody re-introduces the old approach:
   ADO 4125 fixed "every row-span label lands at the same spot" by adding transform: translate(0)
   here, because Safari treats a <tr> with only position:relative as non-positioned. That held
   until Safari 26 / iPadOS 26, where a NEW defect appeared: the row does become a containing
   block, but WebKit computes its ORIGIN wrong, so every label rendered a constant 169.25px BELOW
   its own row (ADO 4223 — empty-looking rows with the text further down, overlapping the row
   beneath). Re-measured 2026-09-18 on iPad Pro 11" (iPadOS sim), Safari 26.6.2 and Chrome:
     - transform / perspective / backdrop-filter: containing block established, all displaced 169.25px
     - filter / will-change / contain: layout: no containing block at all on a table-row — labels
       collapse to one spot exactly as in the original 4125 bug
   So no property swap fixes it: the defect is WebKit's containing-block origin for promoted table
   rows generally, not transform specifically. Anchoring to the <td> measured clean on all three
   engines. Removing transform here is safe ONLY because the <td> now provides the containing
   block; removing it while the <tr> was still the anchor would reopen 4125. */
.emr-needs-row-careplan { position: relative; }
.emr-needs-row-careplan .emr-needs-careplan-add-btn { margin-right: 16px; }

/* Rows locked by an active RTC response, or by a read-only careplan. */
.emr-need-row-locked { opacity: 0.62; }

/* Grid shell: 6 columns plus a sticky action column, no MudDataGrid grouping. Row-span lets a
   Careplan/Need/AddIntervention row (and an unactivated SpecifierHeader) paint its label across
   its empty neighbors instead of colspanning; row-conflict tints a duplicate pair.

   Column WIDTHS live only in the <colgroup> below (NeedsSelectionGrid.razor's ColGroup), never
   on th/td — under table-layout: fixed a <col> is authoritative, th/td widths are only hints. As
   of the 2026-09-23 rework the label <col> is a fixed-width chip column and the identity <col>s
   are the widthless, leftover-absorbing ones — see the LOAD-BEARING banner above for the current
   split, before changing table-layout or moving a width off a <col>. */
.emr-needs-grid .mud-table-root { table-layout: fixed; width: 100%; }

/* MudDataGrid wraps header content in `.column-header` (flex), which shrink-wraps a bare
   MudStack to its own content instead of the cell's real width — EmrChipSelect's width:100% then
   resolves against that shrunken box. Scoped to an explicit class on the affected header stacks
   (the bulk-apply selectors) rather than `.column-header
   > *`, so MudDataGrid's own sort/filter affordances are untouched. */
.emr-needs-grid .column-header > .emr-needs-header-field {
    flex: 1 1 auto;
    min-width: 0;
}

.emr-needs-grid col.emr-needs-col-rail { width: 46px; }
/* Developer-directed (2026-09-23, layout rework): the label <col> is no longer the leftover-
   absorbing column — at MaxWidth.Small (~552px table width, every tier) it only ever held the
   New/RTC status badge (Add) or, before this rework, a name+breadcrumb that wrapped 4-5 lines
   (Edit). It is now a narrow FIXED-width "chip column" sized for that badge alone (see the
   .emr-needs-status-chip override below for how the widest badge, "RTC - other discipline",
   still fits: it shrinks and ellipsizes with a title= tooltip rather than clipping raw). Edit's
   name+breadcrumb, and Add's Intervention OtherText when present, move to a full-width top line
   instead (NeedsEditRowCell / NeedsSelectionGrid.razor, reusing the SpecifierHeaderCell
   .emr-needs-row-spec-active mechanism — see .emr-needs-row-span-tall below).
   The four identity <col>s are now WIDTHLESS instead: under table-layout: fixed, several
   widthless columns split whatever's left over EQUALLY (CSS2.1 fixed-table-layout — no cell in
   the first row sets a width either, width lives only on <col>, the LOAD-BEARING rule above), so
   they no longer need an explicit percentage. At 552px: (552 - 46 rail - 80 chip - 56 action) / 4
   ≈ 92.5px per identity column — measured against real MudBlazor markup in the Playwright layout
   harness (see plans/ note), not just computed. MudBlazor's dense cell padding (16px left / 24px
   right) was eating ~40px of every ~90px identity column; trimmed on the identity and label/chip
   cells only. Padding never moves the absolutely positioned span content — it anchors to the td's
   padding box. Headers bottom-align so a wrapped label ("Performed By") can't push its picker
   below its neighbours'. */
.emr-needs-grid col.emr-needs-col-label { width: 80px; }
/* Phone: the four identity <col>s are dropped from the ColGroup (Hidden="@IsPhone") and their
   content folds inline into THIS column instead (NeedsIdentityPhoneFields) — a 2x2 field grid plus
   the row's own name/breadcrumb/badge, far wider than the badge alone. It can't stay pinned at the
   80px desktop chip width; it has to go back to being the leftover-absorbing column, the role the
   original (pre-2026-09-23) widthless label <col> played at every tier. Only 3 <col>s remain at
   Phone (rail/label/action) — without one widthless column among them, table-layout: fixed would
   stretch rail/action past their declared px sizes to fill 100%. width: auto (equivalent to no
   width at all for the fixed-layout algorithm) restores that leftover-absorbing role; applied only
   when NeedsSelectionGrid.razor / NeedsEditGrid.razor add this class (IsPhone). */
.emr-needs-grid col.emr-needs-col-label-phone { width: auto; }
.emr-needs-grid .mud-table-row .mud-table-cell.emr-needs-col-identity { padding-left: 6px; padding-right: 6px; }
.emr-needs-grid .mud-table-row .mud-table-cell.emr-needs-col-label { padding-left: 4px; padding-right: 4px; }
.emr-needs-grid .mud-table-head th.mud-table-cell { vertical-align: bottom; }
.emr-needs-grid col.emr-needs-col-action { width: 56px; }

/* Developer-directed (2026-08-14, manager request): the dedicated status column (previously here,
   112px, holding New/RTC Active for both SpecifierHeader and Intervention rows) is removed — those
   badges now render inline: SpecifierHeaderCell's own IsNew right after its label text, and an
   Intervention row's badge in its own (otherwise empty) label cell. Removing this fixed-width
   column hands its space straight to the widthless label <col>, per D9's own "absorbs whatever's
   left over" design — no other column changes. */

/* An Intervention row's label cell has no text of its own (the specifier text is shown once on
   the SpecifierHeaderCell row above) — this invisible spacer is the SAME icon/size
   SpecifierHeaderCell's own visible one renders, so the badge that follows it lands under the
   exact x position that row's label TEXT starts at (indent padding + icon box + its ml-3), not
   the column's raw left edge. visibility:hidden keeps the layout box without painting it. */
.emr-needs-status-badge-spacer {
    visibility: hidden;
}

.emr-needs-status-cell {
    display: flex;
    justify-content: center;
    /* Defect 2 fix (2026-08-12), still true now that Add's dedicated status column is gone
       (2026-08-14) — every context this renders in is a flex row sibling (SpecifierHeaderCell's
       own MudStack, Edit's NeedsEditRowCell, Add's new indent-matched MudStack), and a flex
       item's default flex-shrink is 1: when the row's content together exceeds the available
       width, the badge (an inline-flex MudChip with white-space: nowrap and no shrink guard of
       its own) would shrink right along with any label text, clipping its nowrap content
       mid-glyph instead of ever wrapping. flex-shrink: 0 pins the badge to its natural content
       width, leaving separately-shrinkable text to absorb any squeeze. */
    flex-shrink: 0;
}

/* Compact status badge, not a selectable/removable chip — shrunk below MudBlazor's normal
   Size.Small chip height. */
.emr-needs-grid .emr-needs-status-chip.mud-chip {
    height: 20px;
    padding: 0 8px;
    font-size: 11px;
    white-space: nowrap;
    /* Defect 2, second half (2026-08-12): the first fix put flex-shrink: 0 on
       .emr-needs-status-cell, which is the flex ITEM in Edit (inside NeedsEditRowCell's row
       stack) but the flex CONTAINER in Add (its own status <col>). That fixed Edit and left Add
       clipping, because there the chip itself is the shrinking item: "RTC Active" is the widest
       badge the status column ever holds (now 112px, see the col rule above), and a nowrap
       MudChip squeezed below its content width clips mid-glyph rather than wrapping. Pinning the
       badge here fixes the Add context the same way the cell rule fixed Edit's — no ColGroup
       width, CellClass, or .emr-needs-span-content change. */
    flex-shrink: 0;
}

/* Hides two sub-pixel/overflow leaks that survive table-layout: fixed (rounding, and the
   row-span paint-across bounding at the row edge) — never content a user needs to reach.
   overflow-y is set alongside overflow-x here (not left to its 'visible' initial value) for a
   CSS-spec reason, not a style preference: per the overflow-x/overflow-y pairing rule, an axis
   left at 'visible' computes to 'auto' whenever the OTHER axis is anything but 'visible' — so
   overflow-x: hidden alone silently turned overflow-y into 'auto' too. See the ADO #4057 note
   below for why that mattered (a real, if tiny, second scrollbar). */
.emr-needs-grid .mud-table-container {
    overflow: hidden;
    /* Container-query root for the row-span width below (100cqw = this element's inline size,
       which is the table's width). Deliberately NOT `size` — inline-size applies inline-size
       containment only, leaving block size free, so the uncapped-height contract the ADO #4057
       note below depends on is unchanged. */
    container-type: inline-size;
}

/* Non-span rows wrap normally; span rows (below) go nowrap + ellipsize instead. Careplan/Need/
   AddIntervention rows and an unactivated SpecifierHeader use the span mechanism because their
   identity cells are empty; an ACTIVATED SpecifierHeader's identity cells hold live EmrChipSelect
   controls, so it keeps this plain wrapping treatment instead — spanning would paint text over
   live inputs. */
.emr-needs-grid .emr-needs-col-label {
    overflow: hidden;
    white-space: normal;
    overflow-wrap: anywhere;
}
.emr-needs-grid .emr-needs-col-label .flex-nowrap { flex-wrap: wrap; }
/* !important beats MudBlazor's own `.flex-shrink-0 { flex-shrink: 0 !important }` utility —
   a plain override loses every time. */
.emr-needs-grid .emr-needs-col-label .flex-shrink-0 { flex-shrink: 1 !important; min-width: 0; }

.emr-needs-row-span .emr-needs-col-label {
    overflow: visible;
    white-space: nowrap;
}
.emr-needs-row-span .emr-needs-col-label .flex-nowrap { flex-wrap: nowrap; }

/* THE SPAN ITSELF (colspan substitute — see LOAD-BEARING banner above). Taking the row's content
   stack out of flow bounds it exactly between the rail and action columns regardless of viewport,
   so a long label ellipsizes there instead of overflowing the table. left: 16px matches the
   dense table's own checkbox inset (not the rail column's 46px width) so labels align with other
   rows' checkboxes. Applied by explicit class rather than a positional selector because
   AddIntervention's label cell holds a button, not text, and must not be stretched the same way. */
/* Anchored to the label <td>, not the <tr> — see the WebKit note on .emr-needs-row-careplan.
   The <td> only spans the label column, so the full rail→action width the colspan substitute
   needs comes from container-query units against .mud-table-container instead of `right`:
     left  = 16px (checkbox inset) - 46px (rail <col>) = -30px
     width = table width - 16px - 56px (action <col>)  = 100cqw - 72px
   box-sizing: border-box is load-bearing — the indent ladder above is padding-left on this same
   box, and without it each indent adds to the width and overshoots the action column by exactly
   the indent (measured: -24px at Need, -48px at Specifier). */
.emr-needs-row-span .emr-needs-span-content {
    position: absolute;
    left: -30px;
    right: auto;
    width: calc(100cqw - 72px);
    box-sizing: border-box;
    top: 50%;
    transform: translateY(-50%);
    min-width: 0;
}
.emr-needs-row-span > td { height: 44px; position: static; } /* out-of-flow stack can't size the row; 44px also meets the iPad touch-target floor */
/* The label cell is the containing block. Higher specificity than the `> td` rule above, which
   deliberately keeps every OTHER cell static so only this one anchors the span. */
.emr-needs-row-span > td.emr-needs-col-label { position: relative; }
.emr-needs-row-span { position: relative; }
.emr-needs-row-span .emr-needs-span-content > .mud-typography {
    min-width: 0; /* lifts the flex item's default min-width:auto so ellipsis can actually engage */
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Activated SpecifierHeader can never use the span mechanism (its identity cells hold live
   controls), so its label gets its own dedicated top-anchored line instead — same absolute-
   positioning technique, anchored to the row's top rather than centered, with the rest of the
   row's cells padded down to make room. Out of flow, it still contributes nothing to column width. */
/* Anchored to its label <td> like .emr-needs-row-span — see the WebKit note above. */
.emr-needs-row-spec-active { position: relative; }

/* Specificity note: MudBlazor's dense padding is `.mud-table-dense * .mud-table-row .mud-table-cell`
   (0,4,0) — a shorter selector here loses to it. 56px = label's 4px top offset + the row's
   MudIconButton depth marker (Size.Medium, ~40px tall) + breathing room — raised from the prior
   32px (tuned for a bare small icon) when the depth marker became a real MudIconButton; re-measure
   if the identity selectors still crowd the label line. */
.emr-needs-grid .mud-table-row.emr-needs-row-spec-active > td.mud-table-cell {
    position: static;
    padding-top: 56px;
}
/* Re-positions ONLY the label cell, which is this row's containing block now that the <tr> no
   longer is. Must out-specify the static rule directly above (0,4,1) or the anchor is lost and
   the label escapes the row again — this is (0,5,1). */
.emr-needs-grid .mud-table-row.emr-needs-row-spec-active > td.mud-table-cell.emr-needs-col-label {
    position: relative;
    /* The label col is a fixed ~80px chip column (2026-09-23); the base .emr-needs-col-label
       overflow: hidden would clip this row's full-width top line to that cell. */
    overflow: visible;
}

.emr-needs-row-spec-active .emr-needs-span-content {
    position: absolute;
    left: -30px; /* same td-anchored geometry as .emr-needs-row-span above */
    right: auto;
    width: calc(100cqw - 72px);
    box-sizing: border-box;
    top: 4px;
    min-width: 0;
}

.emr-needs-row-spec-active .emr-needs-span-content > .mud-typography {
    min-width: 0;
    flex-shrink: 1 !important; /* reverses SpecifierHeaderCell's own flex-shrink-0; this treatment wants the label to shrink */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 2026-09-23 layout rework: an ADDITIVE modifier on top of .emr-needs-row-spec-active, not a new
   mechanism (Nemo #952 — reuse by name). .emr-needs-row-spec-active still owns the absolute
   positioning/anchoring; this only raises the clearance below the top line for content taller
   than SpecifierHeaderCell's own one-liner:
     - NeedsEditGrid: every row's top line is an intervention name (up to 2 lines, clamped) plus a
       one-line breadcrumb underneath — always applied (NeedsEditGrid.razor.cs RowClass).
     - NeedsSelectionGrid (Add): an Intervention row whose OtherText is non-empty gets this too,
       moving that free text off the ~80px chip column onto its own top line (the chip column
       alone was never wide enough for OtherText — see the col.emr-needs-col-label rule above).
       A row with no OtherText is untouched: its badge stays in the chip column, no top line.
   72px = label's 4px top offset + 2 label lines (measured 40.03px, real MudBlazor body2/Typo
   values) + 1 breadcrumb line (measured 20.02px, caption) + ~8px breathing room — measured against
   real MudBlazor markup/CSS in the Playwright layout harness at the worst case (a ~190-char
   custom need name clamped to 2 lines). 64px left the picker line touching the label line's last
   pixel (bottom == top, zero clearance); re-measure if either line's typography changes. */
.emr-needs-grid .mud-table-row.emr-needs-row-span-tall > td.mud-table-cell {
    padding-top: 72px;
}

/* ADO 4294: an activated header with free text (REQTEXT "Other") puts name + Add on the first
   line and the text on its own full-width line below, indented to the name (40px icon slot +
   12px gap = 52px). 104px clearance = 4px top + 40px icon-button line + 4px gap + 2 clamped text
   lines (40px) + ~16px breathing room (96px left the selectors touching a 2-line text); this out-specifies the -tall rule's 72px. */
.emr-needs-row-spec-active .emr-needs-span-content.emr-needs-header-has-text {
    flex-wrap: wrap;
}
.emr-needs-row-spec-active .emr-needs-span-content.emr-needs-header-has-text > .emr-needs-spanline-primary {
    flex: 0 0 calc(100% - 52px);
    margin: 4px 0 0 52px;
}
.emr-needs-grid .mud-table-row.emr-needs-row-span-tall.emr-needs-row-header-text > td.mud-table-cell {
    padding-top: 104px;
}

/* The top line's primary text (Edit's intervention name; Add's OtherText) — 2-line clamp instead
   of the single-line nowrap ellipsis the generic `.emr-needs-row-spec-active ... > .mud-typography`
   rule above gives SpecifierHeaderCell's short catalog name. Placed after that generic rule and
   matched on an equal-specificity, more explicit class (.emr-needs-spanline-primary) so source
   order decides in its favor for the elements that carry both classes. word-break: break-word
   backstops a single unbroken token (e.g. a very long custom need name) that would otherwise
   overflow the clamp box before wrapping. */
.emr-needs-row-span-tall .emr-needs-span-content > .emr-needs-spanline-primary {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: break-word;
}

/* The top line's secondary text (Edit's Careplan › Need breadcrumb) — single line, ellipsized;
   the generic `.mud-typography` rule above already gives this exact treatment, this class just
   names the element so NeedsEditRowCell/tests can target it without relying on element order. */
.emr-needs-row-span-tall .emr-needs-span-content > .emr-needs-spanline-secondary {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Chip column is now ~80px (col.emr-needs-col-label above), narrower than InterventionStatusCell's
   widest badge ("RTC - other discipline") at its natural content width. flex-shrink: 0 (the base
   rule, higher up this section) is right for every OTHER context that badge used to render in
   (full-width label column, or inline next to a specifier name); scoped to the chip column itself,
   it must shrink instead — New/RTC Active still render in full at this width, only the "other
   discipline" badge ellipsizes. A title= attribute (InterventionStatusCell.razor) gives the
   truncated text a hover tooltip rather than losing it outright. */
.emr-needs-grid .emr-needs-col-label .emr-needs-status-cell {
    flex-shrink: 1;
    min-width: 0;
}
/* MudChip's own root is display: inline-flex (MudBlazor.min.css) — text-overflow: ellipsis does
   not reliably engage on a flex container across engines, so this override also drops it to
   inline-block (this badge is text-only, no avatar/close icon, so losing flex costs nothing
   visually) and forces its inner .mud-chip-content span inline too, so the ellipsis has one plain
   inline run to truncate instead of a nested flex box. */
.emr-needs-grid .emr-needs-col-label .emr-needs-status-chip.mud-chip {
    flex-shrink: 1;
    min-width: 0;
    max-width: 100%;
    display: inline-block;
    line-height: 20px; /* inline-block drops the flex centering — re-center the text in the 20px chip */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* MudChip's own base rule sets margin: 4px on every side (MudBlazor.min.css) — at this
       column's ~72px content width (80px col minus the 4px/4px trim above) that alone ate 8px,
       leaving "RTC Active" (measured ~69px) too little room and clipping it needlessly (Playwright
       harness). .emr-needs-status-cell already centers the chip with flex, so the margin buys
       nothing here. */
    margin: 0;
}
.emr-needs-grid .emr-needs-col-label .emr-needs-status-chip.mud-chip .mud-chip-content {
    display: inline;
}

/* Careplan pseudo-row reads as a section-header band (2026-08-11 visual redesign Phase 2),
   matching the visual weight Diagnoses gives "Primary Diagnosis (1)".
   2026-08-14: this used to echo .emr-needs-header's own primary-hover band, but that toolbar is
   now transparent and the grid's thead moved to --emr-needs-header-bg grey, so this is the last
   primary-hover surface in the dialog. Kept deliberately — it distinguishes a careplan grouping
   row from the grey header band rather than merging with it. Title weight/color reuse .emr-important
   (font-weight 600 / primary-darken) rather than a duplicate rule. Background/typography only —
   G3 forbids this rule from touching width/layout, so it must never gain a width, min-width, or
   table-layout declaration. */
.emr-needs-row-careplan td { background: var(--mud-palette-primary-hover); }
.emr-needs-row-conflict  td { background: var(--mud-palette-error-hover); }
.emr-needs-row-conflict  td:first-child { border-left: 3px solid var(--mud-palette-error); }

/* Bug fix (ADO #4057, "double scrollbars", regressed and reapplied 2026-09-16): the grid used to
   carry its own FixedHeader="true" Height="620px", giving .mud-table-container a second,
   independently scrolling viewport nested inside the dialog's own scrolling .mud-dialog-content —
   two competing scrollbars on screen at once. .emr-needs-header's toolbar (below) is already
   `position: sticky; top: 4px` against .mud-dialog-content, which only makes sense if
   .mud-dialog-content is THE scroll container — so the grid must not open a second one. Both
   NeedsSelectionGrid.razor and NeedsEditGrid.razor render without FixedHeader/Height; this
   wrapper stays uncapped so .mud-dialog-content (MudBlazor's own default overflow-y: auto) is
   the single scroller, and the sticky thead below still works — position: sticky needs a
   scrolling ancestor, not specifically FixedHeader's own container.
   Removing FixedHeader/Height wasn't enough on its own: MudDataGrid's own .mud-table-container
   (the div MudBlazor wraps the <table> in, distinct from .emr-needs-grid which is the <table>
   itself) ships `overflow-y: auto` unconditionally, regardless of FixedHeader — confirmed live
   via getComputedStyle. Setting `overflow-y: visible` here on its own does NOT fix it — the
   .mud-table-container rule above already pins overflow-x, and by the CSS pairing rule that
   forces a `visible` overflow-y to compute back to `auto` regardless. The `overflow: hidden`
   above (both axes, no 'visible' in the pair) is what actually removes it; this rule just keeps
   the <table> element itself uncapped so it isn't a second, independent height constraint. */
.emr-needs-grid { max-height: none; overflow-y: visible; }

/* Grid's own column header (label caption + the four bulk-apply selectors) stays visible while
   scrolling the grid's own scroll box — distinct from the dialog's Expand/Collapse + Quick Filter
   rows above it, which stick via .emr-needs-header instead.
   Amendment A6 (2026-08-12): this thead row IS the bulk container in both NeedsSelectionGrid
   (Add) and NeedsEditGrid (Edit) — its only row is the caption + four bulk-apply pickers, no
   separate spanning band.
   Developer-directed (2026-08-14): background moved off --emr-input-filled-bg (which matched the
   Quick Filter textbox and read as an input surface, not a header) onto --emr-needs-header-bg — a
   token named for this role, not shared with .emr-needs-header (which stays transparent, see
   below), so this thead row is the dialog's single tinted header band.

   LOAD-BEARING SELECTOR SHAPE — do not shorten to `.emr-needs-grid .mud-table-head th`.
   MudBlazor 9.7.0 ships `.mud-table-sticky-header * .mud-table-root .mud-table-head .mud-table-cell
   { background-color: var(--mud-palette-surface) }` at specificity (0,4,0). The short form is
   (0,2,1) and LOSES, which is why this row painted white regardless of which token was named here.
   The form below is (0,4,1) — four classes plus the `th` element — so it beats MudBlazor's rule on
   specificity alone, independent of stylesheet order. Any edit that drops `.mud-table-root` or the
   `th` qualifier silently reverts the row to white.
   Applied to every th in the row (not just the four identity headers) so the whole row paints as
   one continuous band with no untinted gaps between cells. */
.emr-needs-grid .mud-table-root .mud-table-head th.mud-table-cell {
  position: sticky;
  top: 0;
  z-index: 3;
  background-color: var(--emr-needs-header-bg);
}

/* Bulk-apply pickers sitting on the tinted header band above (2026-08-14, developer-directed).
   EmrChipButton's Outlined variant is deliberately transparent so the pill picks up whatever
   surface it sits on — correct on white rows, but on --emr-needs-header-bg it reads as unfilled
   chrome. Variant.Filled is NOT the fix: on EmrChipButton, Filled is the has-a-value state, so
   using it here would make an empty picker look selected. Instead the empty/outlined pill keeps
   its Outlined semantics and only its background is repainted, scoped to the bulk header field.
   `.emr-needs-header-field` covers all four pickers and both branches (EmrChipButtonSelect and
   the CondensedChips EmrChipButtonSetSelect) without threading a Class parameter through two
   component layers. NeedsBulkFieldHeader is the only consumer today; the selector is anchored on
   .emr-chip-button rather than the wrapper alone so a future consumer of the same wrapper class
   picks this background up automatically.
   LOAD-BEARING: `.mud-chip-outlined` is required, not decoration. EmrChipButtonSelect and
   EmrChipButtonSetSelect swap to Variant.Filled the moment a value is picked; without the
   variant qualifier this rule would repaint the filled (has-a-value) pill white too and erase
   the selected state entirely.
   Specificity (0,4,0) clears MudBlazor's base `.mud-chip-outlined` transparency; its
   `:hover`/`:active` rules are (0,5,0) and still win, so hover feedback is unchanged. */
.emr-needs-header-field .emr-chip-button .mud-chip.mud-chip-outlined {
    background-color: var(--mud-palette-surface);
}

/* EmrChipSelect's Multiple mode renders its value chip and "+N" overflow chip as two inline
   boxes with no white-space rule, so the "+N" wraps onto its own line once both don't fit the
   ~130-200px identity column. Scoped to this grid only — other EmrChipSelect call sites are
   untouched. */
.emr-needs-grid .emr-chip-select .mud-input-slot {
    white-space: nowrap;
    overflow: hidden;
    display: flex;
    min-width: 0;
}

/* The "+N" overflow badge moves off the row into a small pinned corner badge (below) instead of
   competing with the value chip for space — applied to both EmrChipSelect branches (Multiple's
   value+overflow pair and Single's lone chip). Forcing nowrap here (below) is what actually lets
   the value chip shrink into the remaining room instead of hard-clipping: EmrChipSelect's own
   MudField carries MudBlazor's `.flex-wrap` utility (`!important`), which defeats flex-shrink
   unless beaten by an equally `!important` override. Scoped to this grid only. */
.emr-needs-grid .emr-chip-select .mud-field {
    flex-wrap: nowrap !important;
}

.emr-needs-grid .emr-chip-select-chip-wrap {
    position: relative;
    display: inline-flex;
    max-width: 100%;
    min-width: 0;
}

.emr-needs-grid .emr-chip-select-chip {
    max-width: 100%;
    min-width: 0;
}

/* A closable chip's close button lives inside .mud-chip-content as a sibling of the text, so
   ellipsizing that element directly would clip the button too. Ellipsize the dedicated label span
   (emr-chip-select-chip-label below) instead; this rule only lets the content shrink. */
.emr-needs-grid .emr-chip-select-chip .mud-chip-content {
    min-width: 0;
}

.emr-needs-grid .emr-chip-select-chip-label {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex: 1 1 auto;
}

/* "+N" overflow count badge — reuses MudChip's pill shape but every sizing default is overridden
   down to a small solid-color circle. */
.emr-needs-grid .emr-chip-select-overflow.mud-chip {
    position: absolute;
    top: -6px;
    right: -6px;
    height: 16px;
    min-width: 16px;
    padding: 0 3px;
    border-radius: 50%;
    background: var(--mud-palette-info);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    color: var(--mud-palette-info-text, var(--mud-palette-white));
}

.emr-needs-grid .emr-chip-select-overflow.mud-chip .mud-chip-content {
    padding: 0;
    font-size: 10px;
    line-height: 14px;
    justify-content: center;
}

/* Missing-required-field tint on a bulk-apply selector (Discipline/Verb/For/Frequency). Targets
   .mud-input-root-filled specifically — that's the element that actually paints the Filled
   variant's background, not the outer wrapping div the Class param lands on. color-mix keeps this
   on the --mud-palette-error token rather than a raw hex; !important wins the specificity tie
   against MudBlazor's own rule on this class. */
.emr-chip-select.emr-needs-field-missing .mud-input-root-filled {
    background-color: color-mix(in srgb, var(--mud-palette-error) 12%, transparent) !important;
}

/* Amendment A4 fallback (2026-08-12): a saved row's identity cell in Add
   (SavedIdentityCell) has no EmrChipSelect picker to carry the rule above — when the
   identity's id is null, or no longer matches a loaded option, the placeholder text itself
   carries emr-needs-field-missing directly instead of the picker's filled-input descendant. */
.emr-needs-identity-placeholder.emr-needs-field-missing {
    color: var(--mud-palette-error) !important;
}

/* Phase 8 (2026-08-11 visual redesign plan): NeedsEditRowCell's breadcrumb note — load-bearing
   (explains why the specifier isn't shown as its own row), styled as a caption aside, not a
   status/warning cue, so no color token beyond the caption's own inherited secondary text. */
.emr-needs-edit-collapsed-note { font-style: italic; }

/* Top-anchor cell content instead of MudDataGrid's default vertical-align:middle, so a cell that
   grows extra content (multi-line selectors, captions) doesn't stagger against shorter neighbors. */
.emr-needs-grid .mud-table-cell { vertical-align: top; }

/* Hide MudDataGrid's own group-expander chevron; GroupTemplate's own icon button is the one
   working per-careplan collapse toggle (Expand All/Collapse All). */
.emr-needs-grid .mud-table-row-expander { display: none; }

/* Row-actions column: trash only, right-anchored. position:sticky pins it to the right edge of
   whatever is currently visible so it can't be scrolled off by the row-span mechanism growing the
   table (same technique as the sticky header, opposite axis). */
.emr-needs-actions-cell {
  text-align: right;
  white-space: nowrap;
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--mud-palette-surface);
}

.emr-needs-grid .mud-table-head th.emr-needs-col-action {
  right: 0;
}

/* Dialog toolbar (Quick Filter, ADD|EDIT, ALL/ACTIVE/SELECTED, Expand/Collapse All) stays pinned
   above the scrolling grid. Developer-directed (2026-08-14): background was transparent so the
   toolbar read as dialog surface and the grid's own --emr-needs-header-bg thead was the single
   tinted header band — an earlier pass tinted both and the doubled band read as heavy.
   Reversed (2026-09-18, developer-reported on iPad-portrait screenshots): rows scrolling underneath
   a transparent sticky bar showed through it, which read as broken rather than "dialog surface".
   --mud-palette-background-gray is the app's own page-canvas token (#F4F4F4 in EmrTheme, distinct
   from --emr-needs-header-bg's #ebebeb grid-thead grey) — darker than the white dialog surface it
   sits on, so it reads as a real toolbar, but a visibly different shade from the grid's own thead
   band below it, so the two tinted bands don't merge into the "doubled/heavy" look the 2026-08-14
   pass was trying to avoid. The bottom hairline gives the sticky edge a deliberate boundary once
   rows scroll under it, instead of an unbordered band that looks like a rendering glitch. */
.emr-needs-header {
    position: sticky;
    top: 4px;
    z-index: 5;
    background: var(--mud-palette-background-gray);
    border-bottom: 1px solid var(--emr-hairline);
    margin-bottom: 8px;
    padding: 12px;
    border-radius: 12px;
}

/* Phase 10 (2026-08-11 visual redesign plan) — Edit's post-bulk-apply confirmation banner.
   Spacing only; MudAlert's own Severity.Success supplies the color token. */
.emr-bulk-apply-banner {
    margin-bottom: 8px;
}

/* ─── Tablet/Phone compact pickers (2026-09-23) ───────────────────────────
   Approved design: at Tablet (LayoutContext.Data.IsTablet, ~600-1279.98px) and Phone
   (LayoutContext.Data.IsPhone, <599.98px) the four identity pickers (header bulk row and
   staged/new rows) drop the chip chrome for a chromeless link — see EmrChipButton.Compact and
   its consumers (EmrChipButtonSelect/EmrChipButtonSetSelect/SavedIdentityCell/
   NeedsBulkFieldHeader). C# (LayoutContext-driven) decides WHETHER this markup renders; these
   rules only style it once it does, so no width-based media query is needed here. Desktop never
   sets Compact, so none of this touches desktop rendering. */
.emr-needs-phone-fields {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 16px;
    margin-top: 6px;
}

.emr-needs-phone-field-cap {
    font-size: 10px;
    color: var(--mud-palette-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 1px;
}

.emr-needs-phone-field .emr-chip-button-link {
    font-size: 12px;
}

/* ══════════════════════════ END Needs Selection dialog ══════════════════════════ */

/* ─── EmrChipButton / EmrChipButtonSet ───────────────────────────────────
   Everything about the pill's own shape (radius, border, fill, height) comes
   from MudChip's Variant/Color/Size — these rules only cover the gaps MudChip
   has no parameter for: the status dot, the count badge, label truncation,
   placeholder muting, and the root's min/max-width contract (plan
   2026-08-12-emr-chip-button-component.md, D6/D9). */

.emr-chip-button {
    display: inline-flex;
    flex-direction: column;
    min-width: var(--emr-chip-button-min-width, 0);
    max-width: 100%;
}

/* Default fill mirrors .emr-chip-button__count/.mud-chip-close-button below: a translucent
   currentColor mix, so an unstyled dot reads as a lighter shade of this chip's own Color/Variant
   rather than a fixed hue. A caller-supplied StatusColor overrides this via an
   .emr-chip-button__status-dot--<color> modifier (EmrChipButton.razor.cs StatusDotClass),
   declared later in the stylesheet (region 21) so it wins at equal specificity. */
.emr-chip-button__status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
    margin-right: 6px;
    background: color-mix(in srgb, currentColor 18%, transparent);
}

/* Count badge and MudChip's native +/x close button both need a visible border + a
   translucent fill so they read as a button against any Variant/Color — currentColor
   picks up whatever text color MudChip already computed, so no new color logic is needed.
   Scoped under .emr-chip-button so other MudChip usages in the app are unaffected. */
.emr-chip-button .mud-chip .mud-chip-close-button {
    width: 24px;
    height: 24px;
    background: color-mix(in srgb, currentColor 18%, transparent);
    border-radius: 50%;
    /* Bulk-apply header defect (2026-09-18, Needs "Performed By"/"Frequency" pickers): the
       trailing +/x/lock affordance must never shrink or clip — it has absolute priority over the
       label text. Without this, .mud-chip-close-button is a normal flex item (flex-shrink:1 by
       default) sitting beside .mud-chip-content in .mud-chip's row; under real width pressure
       (long placeholders sharing one fixed-width column with short ones like "Verb"/"For") the
       automatic-minimum-size math was letting the icon squeeze down instead of holding steady.
       flex-shrink: 0 makes the floor explicit rather than relying on the icon's own incidental
       content-box size. */
    flex-shrink: 0;
}

.emr-chip-button__count {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
    background: color-mix(in srgb, currentColor 18%, transparent);
    color: inherit;
    border: none;
    padding: 0;
}

/* .mud-chip-content is display:inline-flex with max-width:100% but no width:100% of its own,
   so it only ever shrinks to its content — our MudStack's width:100% has nothing to grow into
   without this. Scoped under .emr-chip-button so no other MudChip usage in the app is affected. */
.emr-chip-button .mud-chip .mud-chip-content {
    width: 100%;
    /* Bulk-apply header defect follow-up: sibling of .mud-chip-close-button in .mud-chip's row. A
       flex item's default min-width is auto (content-based), which blocked this box from
       shrinking below its un-ellipsized label width, in turn refusing to give up the space
       flex-shrink:0 above now reserves for the +/x/lock button — the label text was staying wide
       and the button was the one giving way instead. min-width: 0 lets this box (and
       .emr-chip-button__label's own ellipsis below) actually shrink. */
    min-width: 0;
}

.emr-chip-button__content {
    width: 100%;
    /* Same min-width chain as .mud-chip-content above — this is its single flex-item child. */
    min-width: 0;
}

.emr-chip-button__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Outlined: placeholder text sits on the surface background, so mute it with the same
   muted-secondary token EmrChipSelect.razor:45 uses for its own placeholder. Filled: the
   text sits on a solid color fill, so muting by a fixed grey would fight every Color — opacity
   reads correctly against any fill instead. */
/* Bug (2026-08-13, live testing): "For" clipped its trailing r under overflow:hidden on
   .emr-chip-button__label — italic glyphs commonly render a hair past their measured advance
   width, and overflow:hidden chops that overshoot right at the box edge with no buffer.
   padding-right absorbs it; 2px is well under anything a real width shortage would need. */
.emr-chip-button__placeholder {
    font-style: italic;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
    padding-right: 2px;
}

.mud-chip-filled .emr-chip-button__placeholder {
    color: inherit;
    opacity: 0.75;
}

.emr-chip-button__helper {
    margin-top: 0;
    padding-left: 0;
}

/* The no-value and CondensedChips branches render EmrChipButton as .emr-chip-button-set's
   direct child — a solo pill that should fill its slot exactly like EmrChipButtonSelect's own
   chip does. Scoped to the DIRECT child only: the well branch's per-value chips (nested under
   .emr-chip-button-set__chips, one level deeper) must stay content-width so they can sit side by
   side in a wrapping row — this selector never reaches them. */
.emr-chip-button-set > .emr-chip-button {
    width: 100%;
}

/* EmrChipButtonSet (D9) — the well is the one genuinely new visual in the design system;
   no sibling widget has a recessed multi-value panel. */
.emr-chip-button-set__well {
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-background-gray);
    display: flex;
    align-items: stretch;
    gap: 8px;
    padding: 12px;
}

.emr-chip-button-set__chips {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-content: center;
    gap: 8px;
}

.emr-chip-button-set__divider {
    flex: 0 0 auto;
}

.emr-chip-button-set__add {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

/* ─── EmrChipButton Compact (2026-09-23 Tablet/Phone Needs Selection pickers) ────────────
   No chip outline/fill, no +/x/count affordance — the whole element is a clickable, underlined
   link (rule #1: "the picker is a link, not a chip"). .emr-chip-button--compact is the same
   root .emr-chip-button div EmrChipButton always renders (RootClass), so MinWidth/Class pass-
   through and AdditionalAttributes still land in the same place as the non-compact branch. */
.emr-chip-button--compact {
    display: inline-flex;
    min-width: var(--emr-chip-button-min-width, 0);
    max-width: 100%;
}

.emr-chip-button-link {
    display: inline-flex;
    align-items: center;
    /* The root is a column flex (.emr-chip-button), so this button stretches to the full header
       cell; without this the button's content centers inside that width. */
    justify-content: flex-start;
    gap: 4px;
    max-width: 100%;
    min-width: 0;
    padding: 2px 0;
    border: none;
    border-bottom: 1px solid currentColor;
    background: none;
    font-family: inherit;
    text-align: left;
    color: var(--mud-palette-primary);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
}

.emr-chip-button-link:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

.emr-chip-button-link:hover {
    background: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent);
}

/* Rule #2: empty reads as muted italic "Select…", not a truncated field-specific placeholder. */
.emr-chip-button-link--empty {
    color: var(--mud-palette-text-secondary);
    font-weight: 400;
    font-style: italic;
}

.emr-chip-button-link--error {
    color: var(--mud-palette-error);
}

.emr-chip-button-link__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Rule #4: a saved/locked value is plain green text with a small lock, not a narrow chip that
   could never fit the value. No border-bottom/hover — this one is not clickable. */
.emr-chip-button-link--saved {
    border-bottom: none;
    cursor: default;
    color: var(--mud-palette-success);
    font-size: 0.8125rem;
    font-weight: 500;
}

.emr-chip-button-link__lock {
    flex: none;
    font-size: 14px !important;
    width: 14px;
    height: 14px;
    opacity: 0.85;
}



/* Encounter Alerts dialog (EncounterAlertsDialog) — every error and warning across the encounter,
   split into two tabs. Fixed body height so switching tabs does not resize the dialog: the two tabs
   almost always hold very different numbers of rows, and a dialog that jumps on each switch is the
   same complaint the Diagnoses dialog's Active/History tabs raised. */
.emr-alerts-body {
    height: 60vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* flex-fill idiom: see .emr-patient-search-body grouped rule above (D7). */

/* The scroll lives on the panel, not the dialog, so the tab strip stays put while a long error list
   scrolls under it. */
.emr-alerts-panel {
    overflow-y: auto;
    max-height: 100%;
}

.emr-alerts-empty {
    padding: 12px 4px;
}

/* Phone: the dialog goes full screen (FullScreen when LayoutContext.Data.IsPhone), so the fixed
   viewport-relative height would leave dead space below the list. */
@media (max-width: 599.98px) {
    .emr-alerts-body {
        height: 100%;
    }
}

/* Blood-pressure pair (NumericAnswerInput) — keep the two halves aligned when one is in error.

   MudBlazor renders a field's error text inside that field's own helper slot, so an error on the
   systolic alone grew only that box and knocked the pair — and the "/" between them — out of
   vertical alignment. The per-field text is suppressed here (the red outline is kept, which is the
   part that marks WHICH half is wrong) and the component renders one message beneath both.

   The HELPER CONTAINER is hidden, not just the text inside it: the container carries its own
   padding and reserves ~60px even when its text is display:none, so hiding only the text left the
   misalignment in place.

   !important is required here, not sloppiness: MudBlazor puts its own .d-flex utility class on the
   helper element, declared `display: flex !important`. Nothing outranks an !important without one,
   so this rule carries it too — and wins on specificity, two classes to .d-flex's one. */
.emr-bp-fields .mud-input-control-helper-container,
.emr-bp-fields .mud-input-helper-text {
    display: none !important;
}

/* Blood Pressure example hints (e.g. 120 / e.g. 80) are placeholders, and a browser's default
   placeholder grey alone was not enough to stop them reading as recorded values. Italic separates
   them from anything the clinician typed. Scoped to the pair so no other numeric input changes.

   The hints are also dropped entirely when the inputs are read-only (BpSystolicPlaceholder /
   BpDiastolicPlaceholder return null) -- a greyed field showing an example looks like a value that
   cannot be edited, which is the opposite of the truth. */
.emr-bp-fields input::placeholder {
    font-style: italic;
}
/* The message slot spans the full pair and reserves its height, so nothing below shifts when the
   caption is replaced by an error.

   Reserved at TWO lines. Measured at the pair's fixed 224px width and Typo.caption's 12px/19.92px:
   the range caption and the both-halves-wrong message each wrap to 2 lines (40px), while a
   single-half error is 1 line. Without the reserve the block bounced 100px <-> 89px as the message
   changed. The width is fixed, so the wrap point does not move with the viewport. */
.emr-bp-message {
    min-height: 3.4em;
    max-width: 224px;
}

/* Appearance theme toggle. The settings sections are flex columns, so the group would stretch edge
   to edge without an explicit shrink; the item floor keeps both options the same width. */
.emr-theme-toggle {
    width: fit-content;
    align-self: flex-start;
}

.emr-theme-toggle .mud-toggle-item {
    min-width: 70px;
}
/* #endregion */

/* #region 19  SymptomItem / BodySystem — moved from SymptomItem.razor inline <style>.
   Shared by other BodySystem components (not just SymptomItem); classes are not emr-*
   prefixed and renaming is deferred to a separate task. */
.symptom-item {
    border-radius: 4px;
}

/* Keeps the IDG-not-agreed warning triangle vertically centered with the
   chip text (MudIcon defaults to baseline inside the chip's flex row). */
.flag-chip-warning {
    vertical-align: middle;
    align-self: center;
}

/* Collapsed-row severity/goal summary — right-aligned next to the chevron,
   kept on one line so the header height doesn't jump. The labels use the
   neutral text-secondary GREY (the CSS var), not the theme's Secondary
   accent color. */
.loc-summary {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    flex-shrink: 0;
    font-size: 0.8rem;
}

.loc-summary-label {
    color: var(--mud-palette-text-secondary);
}

.symptom-header {
    display: flex;
    align-items: center;
    padding: 4px 4px 4px 8px;
    cursor: pointer;
    min-height: 40px;
}

.symptom-header:hover {
    background: rgba(0,0,0,0.03);
}

.symptom-detail {
    border-top: 1px solid rgba(0,0,0,0.08);
}

/* Inline shape+color pill that prefixes a severity/goal level. Matches the larger
   indicator inside NonVerbalPainScoreDialog (kept in sync via ShapeClipPath / hex). */
.level-shape {
    display: inline-block;
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

/* Tint the floating MudSelect / MudTextField label red when its required value is
   still empty, matching the row-name color and signaling the missing field.
   !important wins against MudBlazor's default theme color, which is more specific
   than `.required-empty .mud-input-label`. */
.required-empty .mud-input-label,
.required-empty .mud-input-label-text,
.required-empty label {
    color: var(--mud-palette-error) !important;
}
/* Multi-select MudSelect renders the label inside the box as part of the input
   slot rather than floating it on the border — color the input slot too so the
   qualifier labels (Effect / Palliation / Provocation / Quality / Time) read
   red while empty. */
.required-empty .mud-input-slot,
.required-empty .mud-select-input {
    color: var(--mud-palette-error) !important;
}


/* "— Not set —" placeholder shown by RenderLevelChip when no level is picked.
   Defaults to the secondary text color; the .required-empty rule above paints
   it red when the field is required-and-empty so it matches the floating label. */
.level-chip-empty {
    color: var(--mud-palette-text-secondary);
}
.required-empty .level-chip-empty {
    color: var(--mud-palette-error) !important;
}

/* Level-of-Concern-only (access_control = "L"): every grid item that ISN'T
   flagged ac-loc (Initial Severity / Goal / Post Level) is dimmed and
   non-interactive. The marker class .ac-loc opts a MudItem out. */
.ac-loc-only .mud-grid-item:not(.ac-loc) {
    pointer-events: none;
    opacity: 0.55;
}

/* View-only (access_control = "V"): the discipline can see the symptom but cannot
   edit anything — unlike "L", even the Level-of-Concern fields are locked. Dim and
   disable the entire detail panel. (The activate toggle lives in the header outside
   this panel and is gated separately via _editingLocked.) */
.ac-read-only {
    pointer-events: none;
    opacity: 0.55;
}
/* #endregion */

/* POCR care plan card header - a focusable, clickable region rather than a button element,
   so it carries its own affordance and focus ring. */
.emr-pocr-card-header {
    cursor: pointer;
    user-select: none;
}

.emr-pocr-card-header:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

/* POCR card header status tint - legacy PocrCarePlanCard.razor.cs GetStatusColor(), 8% of the
   same status color used full-strength for the card's left accent bar and status chip
   (PocrStatusDisplay.HeaderClass). Any status code other than I/M/D renders as "C"
   / info, matching legacy's default branch. */
.emr-pocr-header-i { background-color: color-mix(in srgb, var(--mud-palette-success) 8%, transparent); border-left: 5px solid var(--mud-palette-success); }
.emr-pocr-header-c { background-color: color-mix(in srgb, var(--mud-palette-info)    8%, transparent); border-left: 5px solid var(--mud-palette-info); }
.emr-pocr-header-m { background-color: color-mix(in srgb, var(--mud-palette-warning) 8%, transparent); border-left: 5px solid var(--mud-palette-warning); }
.emr-pocr-header-d { background-color: color-mix(in srgb, var(--mud-palette-error)   8%, transparent); border-left: 5px solid var(--mud-palette-error); }

/* POCR Symptoms table header - solid purple with white text, legacy PocrSymptomsTable.razor.
   Scoped to this table only: legacy's other POCR sub-tables (Needs/Interventions/Orders/Data
   Collections) keep MudBlazor's default header, same as legacy's MudSimpleTable default there.
   Selector pattern (.scope .mud-table-head th) matches the render-probe-confirmed one already
   used for .emr-patient-search-grid / .emr-offline-patients-grid above (§08 Grid / Table). */
/* !important on color: MudBlazor's own .mud-table-cell text-color rule is otherwise !important
   itself (confirmed by render probe - the plain color declaration here was silently losing to it,
   leaving near-invisible dark text on this purple background), same collision class as
   .emr-issue-group-heading above. */
.emr-pocr-symptoms-table .mud-table-head th {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-white) !important;
    font-weight: 600;
    white-space: nowrap;
    padding: 8px 12px;
}

/* MarDialog: only the non-PRN medication table scrolls independently — the rest of the dialog
   (date/time, Other Medications rows) stays fixed height (legacy §5.4). Two classes beat
   MudBlazor's single-class dialog width rule, same trick as emr-med-orders-dialog above. */
.mud-dialog.emr-mar-dialog .emr-mar-medication-table {
    max-height: calc(80dvh - 360px);
    overflow-y: auto;
}

/* PocrRecertOrderDialog — a payer row whose benefit period could not be computed
   (IsSelectable == false) stays VISIBLE, just dimmed: hiding it was the original QA
   complaint (a plan silently disappearing reads as "the patient has no such plan", not
   "this plan can't be ordered from here right now"). */
.emr-pocr-recert-row-disabled {
    opacity: 0.55;
}

/* Insurance name can run long; let it wrap instead of forcing the row wide. */
.emr-pocr-recert-col-insurance {
    white-space: normal;
    min-width: 9rem;
}

/* VitalsDialog: ShiftQuestionRow's VitalsMode renders a MudDivider after every question row
   (parent-before-children and sibling-before-sibling alike) so the recursive tree stays flat,
   which leaves the very last row's divider dangling directly above the dialog footer's own
   border-top divider. Suppress just that trailing one. */
.mud-dialog.emr-vitals-dialog .mud-dialog-content .mud-divider:last-child {
    display: none;
}

/* DESIGN-OVERRIDE: vitals-legacy-alignment — design.md's "left-align by default" is deliberately
   not applied to this dialog's control column. VitalsDialog is a like-for-like port of the legacy
   Apollo dialog and clinicians read it daily; the original right-justifies every control against
   the row's right edge, so left-aligning them relocates every input a clinician reaches for
   (developer-directed 2026-09-04, on the legacy-parity/user-familiarity grounds in
   "vitalsquestions_input_label.png"). This reinstates the flush-right layout that a 2026-09-03
   pass had replaced with left-alignment — do not "correct" it back to rule 11 without asking.

   The compact 260px width is kept so the helper caption beneath starts at the input's own left
   edge rather than spanning the column. */
.emr-vitals-control {
    max-width: 260px;
    width: 100%;
    margin-left: auto;
}

/* Start/End Shift control-column width parity with legacy Apollo's fixed-width, right-aligned
   input column (developer-established 2026-09-04): Start Shift's .sq-input-side is
   min-width:220px/max-width:280px/text-align:right; End Shift's .ev-input-side is
   min-width:280px/max-width:360px/text-align:right. margin-left:auto stands in for the legacy
   text-align:right — it pushes the whole control block (not just its text) flush against the
   column's right edge, matching .emr-vitals-control's approach above. */
.emr-shift-control-start {
    width: 100%;
    max-width: 280px;
    margin-left: auto;
}

.emr-shift-control-end {
    width: 100%;
    max-width: 360px;
    margin-left: auto;
}

/* Controlled Substance Review's per-entry medication label — legacy renders it bold black,
   distinct from the purple section/sub-section headers above it
   ("end shift original_control substances.png"). CSS owns the weight; remove Typo= from
   MudText when using this class, same convention as .emr-field-label. */
.emr-controlled-med-label {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

/* MudRadioGroup renders a full-width block, so justify on a wrapping MudStack has nothing to push
   against and the options read as centred. The Class lands on the outer
   mud-input-control-boolean-input, and the radios themselves live one level down in
   .mud-radio-group — that inner element is the one that has to become the flex row.

   DESIGN-OVERRIDE: vitals-legacy-alignment — flex-end so the radios share the numeric inputs' and
   Unable to Collect checkbox's right edge, per the same legacy-parity decision documented on
   .emr-vitals-control above. The legacy screenshot stops the radio row ~117px short of that edge;
   that gap reads as incidental padding in the old framework, so the port aligns all three control
   types to one edge instead (developer-directed 2026-09-04). */
.emr-vitals-radio-group > .mud-radio-group {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

/* IntervalChartPage tab strip reads as button-style pills (legacy reference
   intervalchart_default2.png): the selected tab is a filled purple rounded rectangle, the rest
   are plain text. MudTabs' own ActiveTabClass/HideSlider handle which tab gets the class and
   remove the underline slider; this class only supplies the pill look itself. No !important
   needed: MudBlazor's only unqualified active-tab rule is .mud-tab.mud-tab-active (2 classes),
   and this page does not set MudTabs' Color, so the higher-specificity .mud-tabs-tabbar-*
   color variants never apply. */
.emr-interval-chart-tabs .mud-tab {
    min-height: 40px;
    margin: 4px 4px;
    border-radius: var(--mud-default-borderradius);
}

/* Inactive tabs read as buttons, not floating words: design.md's toggle-group vocabulary pairs a
   Variant.Filled/Color.Primary active item with a Variant.Outlined/Color.Primary inactive one, and
   this tab strip is that pattern. Only the active half had been implemented, leaving the rest as
   bare text with no boundary (developer-directed 2026-09-02). */
.emr-interval-chart-tabs .mud-tab:not(.emr-interval-chart-tab-active) {
    border: 1px solid var(--mud-palette-primary);
    color: var(--mud-palette-primary);
    padding-left: 20px;
    padding-right: 20px;
}

.emr-interval-chart-tabs .mud-tab.emr-interval-chart-tab-active {
    /* Matches the inactive tabs' 1px border so the filled tab is not 2px smaller than its
       neighbours; transparent because the fill already provides the boundary. */
    border: 1px solid transparent;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    border-radius: var(--mud-default-borderradius);
    padding-left: 20px;
    padding-right: 20px;
}

/* Vitals tab pivots to one column per vital (Time + up to ~8 vitals + By), which runs wider than
   the panel on smaller viewports. design.md forbids page-level horizontal overflow but allows a
   grid that explicitly scrolls; this is that opt-in, scoped to the vitals grid only. */
.emr-vitals-grid-scroll {
    overflow-x: auto;
}

/* Shift POC tab: the Symptoms/Needs/PONs grid (6 columns) and Interventions grid run wider than
   the expansion panel on iPad landscape (>960px, desktop layout per design.md). Same documented
   opt-in as emr-vitals-grid-scroll, scoped to these two grids only. */
.emr-shift-poc-grid-scroll {
    overflow-x: auto;
}

/* MAR tab: a medication with no dose yet is still listed (BR-053/BR-055) but recedes, so the eye
   lands on what has actually been administered. The "No doses administered" caption carries the
   meaning — this dimming only reinforces it, per design.md's "colour is never the only signal". */
.emr-mar-row-unadministered td {
    opacity: 0.55;
}

/* #region 20  Outcomes / Elaborations Panels (BodySystem) — moved from OutcomesPanel.razor and
   ElaborationsPanel.razor inline <style> blocks (2026-09-10 css-placement audit). */

.emr-outcome-subtitle,
.emr-elaboration-subtitle {
    color: var(--mud-palette-text-secondary);
}

/* Light grey row band so the outcomes read as a stack of equally-sized items instead of a wall of
   text (matches the screenshot's banded look), shared with the two empty-state placeholders. */
.emr-outcomes-empty,
.emr-elaborations-empty,
.emr-outcome-row {
    background: rgba(0, 0, 0, 0.02);
    border-radius: 4px;
}

.emr-outcome-text,
.emr-elaboration-note-text {
    white-space: pre-wrap;
    word-break: break-word;
}

.emr-outcome-text {
    flex: 1;
}

.emr-outcome-check {
    flex-shrink: 0;
}

.emr-elaboration-history {
    background: rgba(0, 0, 0, 0.02);
}

/* #endregion */

/* #region 21  Design-audit moved styles — P1 Encounter, P2 Patient grids/Pocr, P3 Platform widgets. P3 last: status-dot variants depend on source order. */

/* EndSection */
.emr-verbal-order-value {
    min-height: 32px;
}

/* BodySystemSection (section add buttons) */
.section-add-btn {
    min-width: 160px;
}

.section-add-btn .mud-icon-root {
    color: var(--mud-palette-primary-text);
}

/* NeedItem */
.need-item {
    border-radius: 4px;
}

.need-header {
    display: flex;
    align-items: center;
    padding: 4px 4px 4px 8px;
    cursor: pointer;
    min-height: 40px;
}

.need-header:hover {
    background: rgba(0,0,0,0.03);
}

.need-toggle {
    display: inline-flex;
    align-items: center;
    position: relative;
}

/* Padlock overlays the (disabled) toggle for derived needs (§16.7). */
.need-lock {
    margin-left: -6px;
}

.need-detail {
    border-top: 1px solid rgba(0,0,0,0.08);
}

/* View-only ("V") access: the role can see the saved specifiers/interventions but
   can't change them. Dim and disable the whole detail so any leftover affordance
   (e.g. an intervention-group delete) is non-interactive. */
.need-detail.ac-read-only {
    pointer-events: none;
    opacity: 0.55;
}

.specifier-block:not(:last-child) {
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(0,0,0,0.05);
}

/* The specifier chip replaces the subtitle the block used to render — give it
   the same vertical breathing room a GutterBottom MudText had above the
   intervention list below it. */
.specifier-chip {
    margin-bottom: 6px;
}

/* Card presentation for service specifiers (Meds / HME / Supplies / Other
   Orders): one item per row, name + description. */
.service-spec-card {
    border: 1px solid rgba(0,0,0,0.10);
    border-radius: 4px;
    padding: 6px 10px;
    margin-bottom: 6px;
}

.emr-need-name {
    flex: 1;
    display: flex;
    align-items: center;
}

.emr-flex-fill-shrink {
    flex: 1;
    min-width: 0;
}

.emr-pre-wrap-block {
    white-space: pre-wrap;
    word-break: break-word;
    display: block;
}

/* QuestionItem */
.emr-flex-1 {
    flex: 1;
}

.question-item {
    padding: 8px 0;
}

.question-header {
    min-height: 32px;
}

/* Fixed-width status-icon column so question text never shifts when the icon
   changes between the answered / required-unanswered / disabled / pending states.
   The imminent flag sits between the status icon and the question text with the same
   fixed width, so the prompt text doesn't shift when the flag turns on/off. */
.question-status-icon,
.question-imminent-icon {
    width: 24px;
    flex-shrink: 0;
    display: flex;
    justify-content: center;
}

/* mt-1 inside MudIcon already aligns it with the prompt baseline. */
.question-imminent-icon {
    margin-top: 4px;
}

.question-answer {
    padding-left: 4px;
}

/* RepeatGroupItem */
.repeat-instance {
    background: rgba(0, 0, 0, 0.02);
}

/* Aligns the "#N" prefix with the first question's text baseline. Fixed
   reserved width so the indent below stays identical regardless of the
   ordinal's digit count. */
.repeat-ordinal {
    line-height: 24px;
    flex-shrink: 0;
    min-width: 28px;
    margin-right: 8px;
}

/* Sibling template questions indent by the ordinal's reserved width
   (28px + 8px margin) so their status icons line up with the first
   question's, instead of hugging the card edge. */
.repeat-question-indent {
    margin-left: 36px;
}

/* Template questions inside an instance pack tighter than top-level rows
   (the instance card already provides the breathing room). */
.repeat-instance .question-item {
    padding: 2px 0;
}

/* NumericAnswerInput */
.emr-numeric-field {
    max-width: 220px;
}

.emr-bp-field {
    width: 100px;
}

/* LookupAnswerInput */
/* Lookup-value chip wrapping: MudChip ships with white-space:nowrap which
   chops or overflows long option labels on narrow screens. Allow the
   label to wrap inside the chip and let the chip itself grow vertically
   to fit. Cap max-width so a wall-of-text option doesn't span the whole
   row; the flex-wrap on the parent still lets the row break between chips. */
.chip-wrap-row :is(.mud-chip) {
    height: auto;
    min-height: 28px;
    min-width: 60px;
    justify-content: center;
    max-width: 100%;
    white-space: normal;
}

.chip-wrap-row :is(.mud-chip) > * {
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: left;
}

/* Locked-option explanation. Italic and in the default text colour rather than a
   state colour: it explains why a chip is greyed, it is not itself an error. */
.lookup-footer-note {
    font-style: italic;
    color: var(--mud-palette-text-primary);
}

/* DateTimeField */
.datetime-field {
    width: fit-content;
}

.datetime-field-date {
    width: 160px;
}

.datetime-field-time {
    width: 130px;
}

/* MedicationsListGrid / DocumentsPage (grid group rows) */
.emr-group-start,
.emr-cell-start {
    justify-content: flex-start;
}

.emr-group-label {
    flex: 1;
    text-align: left;
}

/* DocumentsPage (cells and sortable header labels) */
.emr-doc-sort-header {
    cursor: pointer;
}

.emr-doc-sort-header .mud-typography {
    font-weight: inherit;
}

/* PatientMedicationsTable */
.emr-col-summary-start {
    width: 72px;
}

/* PocrCarePlanCard (status chip; the accent bar is on the .emr-pocr-header-* rules) */
.emr-status-chip.emr-pocr-status-chip.mud-chip {
    color: var(--mud-palette-white) !important;
    font-weight: 700;
}

/* IconRef */
.icon-ref-image {
    height: 1.5em;
    width: 1.5em;
    object-fit: contain;
    vertical-align: middle;
}

.icon-ref-svg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
}

.icon-ref-svg > * {
    width: 100%;
    height: 100%;
    display: block;
}

.icon-ref-svg--small {
    width: 1.25rem;
    height: 1.25rem;
}

.icon-ref-svg--medium {
    width: 1.5rem;
    height: 1.5rem;
}

.icon-ref-svg--large {
    width: 2.25rem;
    height: 2.25rem;
}

.icon-ref-svg--primary { color: var(--mud-palette-primary); }
.icon-ref-svg--secondary { color: var(--mud-palette-secondary); }
.icon-ref-svg--tertiary { color: var(--mud-palette-tertiary); }
.icon-ref-svg--info { color: var(--mud-palette-info); }
.icon-ref-svg--success { color: var(--mud-palette-success); }
.icon-ref-svg--warning { color: var(--mud-palette-warning); }
.icon-ref-svg--error { color: var(--mud-palette-error); }
.icon-ref-svg--dark { color: var(--mud-palette-dark); }

/* VxGrid */
.vx-grid__col--align-start { text-align: left; }
.vx-grid__col--align-center { text-align: center; }
.vx-grid__col--align-end { text-align: right; }
.vx-grid__col--align-justify { text-align: justify; }
.vx-grid__col--align-justify-all { text-align: justify-all; }
.vx-grid__col--align-match-parent { text-align: match-parent; }

/* EmrChipButton */
.emr-chip-button__status-dot--default,
.emr-chip-button__status-dot--transparent,
.emr-chip-button__status-dot--inherit { background: transparent; }
.emr-chip-button__status-dot--primary { background: color-mix(in srgb, var(--mud-palette-primary) 18%, transparent); }
.emr-chip-button__status-dot--secondary { background: color-mix(in srgb, var(--mud-palette-secondary) 18%, transparent); }
.emr-chip-button__status-dot--tertiary { background: color-mix(in srgb, var(--mud-palette-tertiary) 18%, transparent); }
.emr-chip-button__status-dot--info { background: color-mix(in srgb, var(--mud-palette-info) 18%, transparent); }
.emr-chip-button__status-dot--success { background: color-mix(in srgb, var(--mud-palette-success) 18%, transparent); }
.emr-chip-button__status-dot--warning { background: color-mix(in srgb, var(--mud-palette-warning) 18%, transparent); }
.emr-chip-button__status-dot--error { background: color-mix(in srgb, var(--mud-palette-error) 18%, transparent); }
.emr-chip-button__status-dot--dark { background: color-mix(in srgb, var(--mud-palette-dark) 18%, transparent); }

/* PendingApprovalCard */
.emr-min-w-0 {
    min-width: 0;
}

/* Weight-only emphasis: .emr-important minus its accent color. */
.emr-text-semibold { font-weight: 600; }

/* #endregion */
