/* Shared building blocks: custom controls and the parts several dialogs and pages use. */

/* ---- Tones ----
   What a state means, as a colour for washes and bars (--ms-tone) and one for icons and words (--ms-tone-ink).
   Warning washes in the brighter amber, so at a glance it cannot be mistaken for an error. */

.ms-tone-neutral { --ms-tone: var(--mud-palette-text-secondary); --ms-tone-ink: var(--mud-palette-text-secondary); }
.ms-tone-info { --ms-tone: var(--mud-palette-info); --ms-tone-ink: var(--mud-palette-info); }
.ms-tone-success { --ms-tone: var(--mud-palette-success); --ms-tone-ink: var(--mud-palette-success); }
.ms-tone-warning { --ms-tone: var(--ms-warning-accent); --ms-tone-ink: var(--mud-palette-warning); }
.ms-tone-error { --ms-tone: var(--mud-palette-error); --ms-tone-ink: var(--mud-palette-error); }

/* ---- Page header (MsPageHeader) ---- */

.ms-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px 16px;
    margin: 4px 0 20px;
}

.ms-page-head--compact {
    margin-bottom: 12px;
}

/* A page laid out as a column of blocks with even spacing. The header's own margin gives way to the gap. */
.ms-stack {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.ms-stack > .ms-page-head {
    margin-bottom: 4px;
}

.ms-page-head__text {
    flex: 1 1 320px;
    min-width: 0;
}

.ms-page-head__back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 4px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
    font-weight: 500;
    text-decoration: none;
}

.ms-page-head__back .material-symbols-outlined {
    font-size: 16px;
}

.ms-page-head__back:hover {
    color: var(--mud-palette-primary);
}

.ms-page-head__title {
    margin: 0;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: 1.625rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.02em;
}

.ms-page-head__sub {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 16px;
    margin: 4px 0 0;
    color: var(--mud-palette-text-secondary);
    font-size: .875rem;
}

.ms-page-head__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

/* ---- Card (MsCard) ---- */

.ms-card {
    min-width: 0;
    padding: 18px 20px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--ms-radius);
    background-color: var(--mud-palette-surface);
}

.ms-card--flush {
    padding: 0;
    overflow: hidden;
}

.ms-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    margin-bottom: 14px;
}

.ms-card--flush .ms-card__head {
    margin: 0;
    padding: 16px 20px 12px;
}

.ms-card__title {
    margin: 0;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: .9375rem;
    font-weight: 600;
}

.ms-card__aside {
    margin-left: auto;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

/* Cards side by side where there is room for two, one under the other where there is not. */
.ms-card-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
    gap: 16px;
}

/* The label over a control that is not a text field - a radio group, a set of switches - in the same type as
   the labels the fields carry. */
.ms-field-label {
    margin-bottom: 5px;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
    font-weight: 600;
}

/* ---- Grid pages ---- */

/* A page whose grid fills the window: the header, toolbar and pager stay in view and only the rows scroll.
   The height is the window less the bar, the system messages under it and the page column's vertical padding. On a short window there
   would be too few rows to work with, so the page scrolls as an ordinary block instead. */
@media (min-height: 650px) {
    .ms-fill-page {
        display: flex;
        flex-direction: column;
        height: calc(100dvh - var(--ms-top-h) - 32px);
        min-height: 0;
    }

    .ms-fill-page > * {
        flex: 0 0 auto;
    }

    .ms-fill-page > .ms-fill {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .ms-fill .ms-fill-grid {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .ms-fill .ms-fill-grid > .mud-table-container {
        flex: 1 1 0;
        min-height: 0;
    }

    /* MudTabs as the filling part (Class="ms-fill"): the tab row keeps its height and the open panel takes the
       rest. MudBlazor renders the open panel as display: contents, so each panel's content goes in a
       <div class="ms-tab-fill">. */
    .ms-fill-page > .mud-tabs.ms-fill > .mud-tabs-tabbar {
        flex: 0 0 auto;
    }

    .ms-fill-page > .mud-tabs.ms-fill > .mud-tabs-panels {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .ms-fill .ms-tab-fill {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    /* A card holding the grid inside a tab panel. */
    .ms-fill .ms-tab-fill > .ms-fill {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }
}

/* A grid inside an expanded row: set in from the row it belongs to, and never sticky - MudBlazor's
   fixed-header rule matches every nested header in the outer grid, and a second sticky header would overlap
   the real one. */
.sub-grid {
    border-left: 3px solid var(--mud-palette-lines-default);
}

.ms-fill-grid .sub-grid .mud-table-head .mud-table-cell {
    position: static !important;
}

/* A grid standing in a dialog or a wizard gets the frame the page grids get from their card, so its toolbar sits
   inside it. */
.ms-grid-frame {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    overflow: hidden;
}

/* The controls over a grid in a flush card: search and filters on the left, the grid's own actions right. */
.ms-grid-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-grid-toolbar > .mud-input-control {
    flex: 0 1 320px;
    min-width: 200px;
    margin: 0;
}

/* A search across several fields, wide enough for a placeholder that names them. */
.ms-grid-toolbar > .mud-input-control.ms-search-wide {
    flex-basis: 440px;
}

.ms-grid-toolbar__spacer {
    flex: 1 1 auto;
}

.ms-grid-toolbar__actions {
    display: flex;
    align-items: center;
    gap: 4px;
}

.ms-grid-count {
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
    white-space: nowrap;
}

.ms-grid-count strong {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

/* The same toolbar as the grid's own toolbar row, which keeps the grid's settings button on its line. */
.ms-card .mud-table-toolbar,
.mud-table-toolbar:has(> .ms-grid-toolbar) {
    height: auto;
    min-height: 0;
    padding: 12px 8px 12px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.mud-table-toolbar > .ms-grid-toolbar {
    flex: 1 1 auto;
    padding: 0;
    border-bottom: 0;
}

.ms-grid-toolbar .mud-switch {
    margin: 0;
}

/* A grid inside a card, or inside a rounded MudTabs: the card draws the frame and clips the corners. */
.ms-card .mud-table,
.mud-tabs-rounded .mud-tabs-panels .mud-table {
    border-radius: 0;
}

/* Square header corners wherever the header is not the top of the grid's own rounded frame: under a card's
   edge, a tab row or a toolbar. A fixed header gets its rounding from a MudBlazor rule these must outrank. A
   grid standing alone keeps it, since its header follows the frame's corner. */
.ms-card table th:first-child,
.ms-card table th:last-child,
.mud-tabs-rounded .mud-tabs-panels table th:first-child,
.mud-tabs-rounded .mud-tabs-panels table th:last-child,
.ms-card .mud-table .mud-table-root .mud-table-head .mud-table-cell:first-child,
.ms-card .mud-table .mud-table-root .mud-table-head .mud-table-cell:last-child,
.mud-tabs-rounded .mud-tabs-panels .mud-table-root .mud-table-head .mud-table-cell:first-child,
.mud-tabs-rounded .mud-tabs-panels .mud-table-root .mud-table-head .mud-table-cell:last-child,
.mud-table:has(> .mud-table-toolbar) .mud-table-root .mud-table-head .mud-table-cell:first-child,
.mud-table:has(> .mud-table-toolbar) .mud-table-root .mud-table-head .mud-table-cell:last-child {
    border-radius: 0;
}

/* A heading over a row of tiles, quieter than a card title since the tiles carry the weight. */
.ms-section-title {
    margin: 12px 0 0;
    color: var(--mud-palette-text-secondary);
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
    font-weight: 600;
}

/* A small table inside a card: plain rows, not a data grid's header. */
.ms-plain-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .8125rem;
}

.ms-plain-table th {
    padding: 0 8px 6px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    background-color: transparent;
    color: var(--ms-ink-3);
    font-size: .75rem;
    font-weight: 500;
    text-align: left;
}

.ms-plain-table td {
    padding: 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-data);
    font-variant-numeric: tabular-nums;
}

.ms-plain-table tr:last-child td {
    border-bottom: 0;
}

.ms-plain-table th:first-child,
.ms-plain-table td:first-child {
    padding-left: 0;
}

.ms-plain-table th:last-child,
.ms-plain-table td:last-child {
    padding-right: 0;
}

.ms-plain-table .is-figure {
    text-align: right;
}

/* ---- Grid rows ---- */

/* A figure column, as HeaderClass, CellClass and FooterClass alike; on a field, its input. The header's sort
   button goes before the title, so the title lines up with the figures. */
.ms-figure,
.ms-figure input {
    text-align: right;
}

/* Laid out right to left, so flex-start is the right edge. */
th.ms-figure .column-header {
    flex-direction: row-reverse !important;
    justify-content: flex-start !important;
}

/* A column kept to one line, as CellClass and HeaderClass. */
.ms-nowrap,
th.ms-nowrap .column-header {
    white-space: nowrap;
}

/* The row a grid is pointing at: the one picked, or the one whose details are open beside it. */
.mud-table-row.is-selected > td {
    background-color: var(--mud-palette-primary-lighten);
}

.mud-table-row.is-selected > td:first-child {
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}

/* The narrow column holding a row's menu or remove button. */
.mud-table-cell.ms-row-action {
    width: 44px;
    padding: 0 !important;
    text-align: center;
}

/* The button that opens a grid's one shared row menu (MudMenu PositionAtCursor). Plain markup, since a
   MudMenu per row is a component per row. */
.ms-row-menu {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--mud-palette-action-default);
    cursor: pointer;
}

.ms-row-menu:hover:not(:disabled) {
    background-color: var(--mud-palette-action-default-hover);
}

.ms-row-menu:disabled {
    color: var(--mud-palette-action-disabled);
    cursor: default;
}

.ms-row-menu .material-symbols-outlined {
    font-size: 20px;
}

/* A toggle that is on, such as a filter that is set. */
.ms-row-menu.is-on {
    background-color: var(--mud-palette-primary-lighten);
    color: var(--mud-palette-primary);
}

/* The MudMenu a grid's row buttons open (Class="ms-menu-host"). It has no activator of its own, but MudBlazor
   lays it out inline, so even empty it takes a line of height wherever it is placed - enough to make a page
   that fills the window scroll. */
.mud-menu.ms-menu-host {
    position: absolute;
}

/* A dialog that enters lines in a grid (eliminations, postings): its fields over the grid, at a width the
   columns need, since the dialog otherwise sizes to them. */
.ms-lines-dialog {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: min(1240px, 90vw);
}

/* Rows that each open a view of a dialog (the export dialogs): an icon, what the view is, a line saying what
   it holds now, and a chevron. Plain buttons, so the whole row is the target and takes keyboard focus. */
.ms-nav-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    overflow: hidden;
}

.ms-nav-row {
    display: grid;
    grid-template-columns: 24px minmax(0, 1fr) auto;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 11px 12px 11px 14px;
    border: 0;
    border-top: 1px solid var(--mud-palette-lines-default);
    background: none;
    color: var(--mud-palette-text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.ms-nav-row:first-child {
    border-top: 0;
}

.ms-nav-row:hover {
    background-color: var(--mud-palette-action-default-hover);
}

.ms-nav-row:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.ms-nav-row .material-symbols-outlined {
    color: var(--mud-palette-primary);
    font-size: 22px;
}

.ms-nav-row .ms-nav-row__chevron {
    color: var(--mud-palette-action-default);
}

.ms-nav-row__title {
    font-weight: 500;
}

.ms-nav-row__caption {
    display: block;
    margin-top: 1px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

/* MsExporter's form: the short choices side by side, the style under them, then the way to the style editor. */
.ms-export-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
    width: min(520px, 86vw);
}

.ms-export-form__row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 12px;
}

.ms-export-form .mud-input-control {
    margin: 0;
}
/* A grid with nothing to show draws its message in a cell spanning 1000 columns. A fixed-layout grid (one that
   virtualizes) would make those 1000 real columns and squeeze its free column to nothing, so while the message
   is showing the table lays out on its own. */
.mud-table-root:has(.mud-table-empty-row) {
    table-layout: auto !important;
}

/* A row's name that opens the record: a real link, so it can be opened in a new tab. */
.ms-grid-link {
    color: var(--mud-palette-primary);
    font-weight: 500;
    text-decoration: none;
}

.ms-grid-link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* The name with a status after it, wrapping under it when the column is narrow. */
.ms-grid-name {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 10px;
}

/* A short form in a dialog: a width that reads as one column, the fields spaced alike. */
.ms-form-dialog {
    display: flex;
    flex-direction: column;
    gap: 14px;
    width: min(480px, 86vw);
}

.mud-form.ms-form-dialog__fields {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* The question in MsConfirmDialog. */
.ms-confirm {
    margin: 0;
    color: var(--mud-palette-text-primary);
    line-height: 1.5;
}

/* Removes a row not yet saved, so it is quiet until pointed at. */
.mud-icon-button.ms-row-remove {
    color: var(--mud-palette-action-default);
}

.mud-icon-button.ms-row-remove:hover {
    color: var(--mud-palette-error);
}

/* ---- Status banner (MsBanner) ---- */

.ms-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 18px;
    padding: 18px 22px;
    border: 1px solid color-mix(in srgb, var(--ms-tone) 30%, var(--mud-palette-lines-default));
    border-left: 5px solid var(--ms-tone);
    border-radius: var(--ms-radius);
    background-color: color-mix(in srgb, var(--ms-tone) 6%, var(--mud-palette-surface));
}

:root[data-theme="dark"] .ms-banner {
    background-color: color-mix(in srgb, var(--ms-tone) 12%, var(--mud-palette-surface));
}

.ms-banner__icon {
    flex: none;
    color: var(--ms-tone-ink);
    font-size: 36px;
}

.ms-banner__text {
    flex: 1 1 280px;
    min-width: 0;
}

.ms-banner__label {
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
    font-weight: 500;
}

.ms-banner__title {
    margin-top: 1px;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -.015em;
}

.ms-banner__detail {
    margin-top: 2px;
    color: var(--mud-palette-text-secondary);
}

.ms-banner__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-left: auto;
}

/* ---- System message (SystemNotice) ----
   A strip in the message's tone: a bar down its left edge, the level in words after the icon, then the text and
   its link. The frame stacks them under the header; the sign-in pages and the dialog's preview round them. */

.ms-notice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 9px 20px;
    border-bottom: 1px solid color-mix(in srgb, var(--ms-tone) 40%, var(--mud-palette-lines-default));
    background-color: color-mix(in srgb, var(--ms-tone) 14%, var(--mud-palette-surface));
    box-shadow: inset 4px 0 0 var(--ms-tone);
    color: var(--mud-palette-text-primary);
    font-size: .875rem;
    line-height: 1.45;
}

:root[data-theme="dark"] .ms-notice {
    background-color: color-mix(in srgb, var(--ms-tone) 20%, var(--mud-palette-surface));
}

.ms-notice__icon.mud-icon-root {
    flex: none;
    margin-top: 0;
    color: var(--ms-tone-ink);
}

.ms-notice__text {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    overflow-wrap: anywhere;
}

.ms-notice__level {
    margin-right: 6px;
    color: var(--ms-tone-ink);
    font-weight: 600;
}

.ms-notice__link {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-left: 8px;
    color: var(--mud-palette-primary);
    font-weight: 500;
    text-underline-offset: 3px;
    white-space: nowrap;
}

.ms-notice__link-icon.mud-icon-root {
    font-size: 15px;
}

/* ---- Stat tiles (MsTile in .ms-tiles) ---- */

.ms-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px;
}

.ms-tile {
    display: block;
    min-width: 0;
    padding: 14px 16px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--ms-radius);
    background-color: var(--mud-palette-surface);
    color: inherit;
    text-decoration: none;
}

.ms-tile__label {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

.ms-tile__go {
    font-size: 18px;
    color: var(--ms-ink-3);
}

.ms-tile__value {
    margin-top: 4px;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-data);
    font-size: 1.75rem;
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
}

.ms-tile__value small {
    margin-left: 1px;
    color: var(--ms-ink-3);
    font-size: 1rem;
}

/* Words rather than a figure, on the baseline a figure would sit on. */
.ms-tile__value--words {
    display: flex;
    align-items: center;
    gap: 6px;
    padding-top: 6px;
    font-family: var(--ms-font-ui);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: 0;
}

.ms-tile__value--words .material-symbols-outlined {
    font-size: 20px;
}

.ms-tile__value--words .ms-status {
    font-size: inherit;
    font-weight: inherit;
}

.ms-tile--link {
    transition: border-color 120ms ease;
}

.ms-tile--link:hover {
    border-color: var(--mud-palette-primary);
}

.ms-tile--link:hover .ms-tile__go {
    color: var(--mud-palette-primary);
}

.ms-tile.ms-tone-warning {
    border-color: color-mix(in srgb, var(--ms-tone) 55%, var(--mud-palette-lines-default));
}

.ms-tile.ms-tone-warning .ms-tile__value {
    color: var(--ms-tone-ink);
}

/* ---- Inline status (MsStatus, or the same markup in a grid row) ---- */

.ms-status {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--ms-tone-ink);
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
    font-weight: 500;
    white-space: nowrap;
}

.ms-status .material-symbols-outlined {
    font-size: 16px;
}

.ms-status--link {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* Only the words underline: an icon's glyph box sits lower than the text, so its line would too. */
.ms-status--link:hover .ms-status__text {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ---- Charts (MsTimeChart) ---- */

.ms-chart {
    width: 100%;
    min-width: 0;
}

/* The chart's hover box. ECharts places it; the look is ours, so it follows the theme like a menu does. */
.ms-chart-tip {
    min-width: 160px;
    padding: 8px 10px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--ms-radius-sm);
    background-color: var(--mud-palette-surface);
    box-shadow: var(--ms-shadow-pop);
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
}

.ms-chart-tip__title {
    margin-bottom: 4px;
    color: var(--mud-palette-text-secondary);
    font-size: .75rem;
    font-weight: 600;
}

.ms-chart-tip__row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.ms-chart-tip__row strong {
    margin-left: auto;
    padding-left: 12px;
    font-family: var(--ms-font-data);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.ms-chart-tip__key {
    width: 10px;
    height: 3px;
    border-radius: 2px;
}

/* A twelve-month trend in a grid row: one polyline, no component. */
.ms-sparkline {
    display: block;
    width: 96px;
    height: 24px;
    overflow: visible;
}

.ms-sparkline polyline {
    fill: none;
    stroke: var(--ms-chart-1);
    stroke-width: 1.5;
    stroke-linejoin: round;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}

/* Facts about one record, label over value, as many to a row as fit: <dl class="ms-facts"> with a <div> per
   pair. */
.ms-facts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
    gap: 14px 24px;
    margin: 0;
}

.ms-facts dt {
    margin-bottom: 2px;
    color: var(--mud-palette-text-secondary);
    font-family: var(--ms-font-ui);
    font-size: .75rem;
    font-weight: 600;
}

.ms-facts dd {
    margin: 0;
    color: var(--mud-palette-text-primary);
    font-size: .875rem;
    overflow-wrap: anywhere;
}

/* A neutral label, such as a role a user holds. A state takes .ms-status instead. */
.ms-tag {
    display: inline-flex;
    align-items: center;
    padding: 0 8px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    background-color: var(--ms-surface-2);
    color: var(--mud-palette-text-secondary);
    font-family: var(--ms-font-ui);
    font-size: .75rem;
    font-weight: 500;
    line-height: 1.25rem;
    white-space: nowrap;
}

.ms-tags {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* Import wizard grids. Hundreds of rows sit side by side and most of the difference between them is
   whether they can be picked at all, so the row's two controls carry the primary colour when they can be
   used (the checkbox gets it from mud.css) and fade when they cannot. Inputs sit at the size of the text
   around them; at their own default they tower over a dense row. */
.import-grid tbody > tr > td:first-child button:not(:disabled) {
    color: var(--mud-palette-primary);
}

.import-grid .mud-checkbox .mud-disabled,
.import-grid tbody > tr > td:first-child button:disabled {
    opacity: 0.3;
}

.import-grid .mud-input-root {
    font-size: 0.875rem;
}

/* The owner grid inside an expanded row. Its headers sit under the outer grid's fixed-header rule, which
   is both sticky and primary-coloured and outranks .sub-grid on specificity, so a second dark bar lands
   in the middle of the table. */
.import-grid .sub-grid .mud-table-head .mud-table-cell {
    position: static !important;
    background-color: var(--mud-palette-background-gray) !important;
}

/* MsRadio components (MsRadioGroup / MsRadioOption) */

.ms-radio-group {
    display: flex;
    gap: 8px;
    outline: none;
}

.ms-radio-group-vertical {
    flex-direction: column;
}

.ms-radio-group-horizontal {
    flex-direction: row;
    flex-wrap: nowrap;
}

.ms-radio-group-horizontal > .ms-radio-option {
    flex: 1 1 0;
    min-width: 0;
}

.ms-radio-option {
    outline: none;
    border-radius: 8px;
    cursor: pointer;
    position: relative;
}

.ms-radio-option__checkmark {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 1;
    pointer-events: none;
}

/* When selected, the heading text also picks up the primary color so the selection
   reads more strongly. Targets the .ms-radio-option__header class which the default
   layout already applies; ChildContent consumers can opt in by adding the same class
   to their heading element. */
.ms-radio-option--selected .ms-radio-option__header {
    color: var(--mud-palette-primary);
}

.ms-radio-option:focus-visible > .mud-paper {
    box-shadow: var(--ms-focus) !important;
}

.ms-radio-option > .mud-paper {
    width: 100%;
    border-radius: var(--ms-radius);
    border: 1px solid var(--mud-palette-lines-default);
    transition: border-color 120ms ease, background-color 120ms ease;
}

.ms-radio-option:not(.ms-radio-option--disabled):hover > .mud-paper {
    border-color: var(--mud-palette-primary);
}

.ms-radio-option--selected > .mud-paper {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary-lighten);
    /* Inner ring gives "thicker border" visual weight without nudging the layout
       (a real border-width change would shift the card by 2px when toggling). */
    box-shadow: inset 0 0 0 1px var(--mud-palette-primary);
}

.ms-radio-option--disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.ms-radio-option__subtext {
    text-align: left;
    color: var(--mud-palette-text-secondary);
}

.ms-radio-option--small .ms-radio-option__header {
    font-size: 1.1em;
    font-weight: 420;
}

.ms-radio-option--small .ms-radio-option__subtext {
    color: var(--mud-palette-text-secondary);
    font-size: 1em;
    font-weight: 400;
}

/* MsFileUpload */

.ms-file-upload {
    width: 100%;
}

/* MudFileUpload overlays a transparent <input> on top of the zone to capture the click that
   opens the file dialog. That overlay swallows the mouse, so hover styling is driven from the
   wrapper (which contains both overlay and zone) and the pointer cursor is set on the overlay. */
.ms-file-upload__input {
    cursor: pointer;
    opacity: 0;
}

.ms-file-upload__dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    min-height: 180px;
    padding: 24px;
    margin-top: 4px;
    border: 2px dashed var(--ms-line-strong);
    border-radius: 12px;
    background-color: var(--ms-surface-2);
    text-align: center;
    cursor: pointer;
    transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease;
}

.ms-file-upload:hover .ms-file-upload__dropzone {
    border-color: var(--mud-palette-primary);
    background-color: color-mix(in srgb, var(--mud-palette-primary) 4%, var(--mud-palette-surface));
}

/* Solid border + inner ring on drag-over, matching the selected-card treatment used by
   .ms-radio-option--selected so the highlight reads consistently across the app. */
.ms-file-upload__dropzone--dragging {
    border-style: solid;
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary-lighten);
    box-shadow: inset 0 0 0 1px var(--mud-palette-primary);
}

.ms-file-upload__icon {
    width: 48px;
    height: 48px;
    font-size: 48px;
    color: var(--mud-palette-primary);
    transition: transform 150ms ease;
}

.ms-file-upload:hover .ms-file-upload__icon,
.ms-file-upload__dropzone--dragging .ms-file-upload__icon {
    transform: translateY(-2px) scale(1.05);
}

.ms-file-upload__title {
    font-weight: 500;
    color: var(--mud-palette-text-primary);
}

/* ---- Import (ImportWizard and its steps) ---- */

/* ImportDialog sizes to its content, so the steps need a width to fill. */
.ms-import {
    width: min(1100px, 88vw);
}

.ms-import__step,
.ms-import__preview {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.ms-import__intro {
    margin: 0;
    color: var(--mud-palette-text-primary);
}

.ms-import__file {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: var(--mud-palette-text-secondary);
}

.ms-import__file .material-symbols-outlined {
    font-size: 20px;
}

.ms-import__file-name {
    overflow: hidden;
    color: var(--mud-palette-text-primary);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-import__layout {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
}

.ms-import__layout-field {
    flex: 0 1 240px;
    min-width: 0;
}

.ms-import__layout-field--wide {
    flex-basis: 460px;
}

.ms-import__note {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding-bottom: 6px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

.ms-import__note .material-symbols-outlined {
    font-size: 18px;
}

/* The fields and the file's rows under them: scrolls both ways, the two header rows staying in view. */
.ms-import__map-frame {
    max-height: min(52vh, 520px);
    overflow: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
}

.ms-import__map {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: .8125rem;
}

/* The two header rows stick as one block: stuck row by row, the second sat at a whole pixel under a first of
   fractional height, and the rows showed through the gap between them. */
.ms-import__map thead {
    position: sticky;
    top: 0;
    z-index: 2;
}

.ms-import__map thead th {
    padding: 8px 10px 4px;
    background-color: var(--ms-surface-2);
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}

.ms-import__map thead tr.ms-import__choice th {
    padding: 0 6px 8px;
    border-bottom: 1px solid var(--ms-line-strong);
    font-weight: 400;
}

.ms-import__map td {
    max-width: 280px;
    padding: 6px 10px;
    overflow: hidden;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-data);
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-import__map tbody tr:last-child td {
    border-bottom: 0;
}

.ms-import__map .ms-import__line {
    width: 1%;
    color: var(--ms-ink-3);
    text-align: right;
}

/* A column picker takes the width of what it names. Its clear button shows only where the user is about to use
   it, on hover or focus, so at rest the name has the whole box; deleting the text clears it as well. */
.ms-import__select {
    min-width: 150px;
}

.ms-import__select .mud-input-clear-button {
    display: none;
}

.ms-import__select:hover .mud-input-clear-button,
.ms-import__select:focus-within .mud-input-clear-button {
    display: inline-flex;
}

.ms-import__required {
    color: var(--mud-palette-error);
}

.ms-import__example {
    color: var(--mud-palette-text-secondary);
    font-size: .75rem;
}

/* Under a column list cut short by its limit, or in place of an empty one. */
.ms-import__more {
    padding: 8px 16px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

/* A value the field cannot read: the icon and the cell's title say so, the wash points to it. */
.ms-import__map td.ms-import__bad {
    background-color: color-mix(in srgb, var(--mud-palette-warning) 12%, transparent);
    color: var(--mud-palette-warning);
}

.ms-import__bad .material-symbols-outlined {
    margin-right: 4px;
    font-size: 15px;
    vertical-align: -3px;
}

.ms-import__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

.ms-import__foot strong {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

.ms-import__period {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 180px));
    gap: 12px;
}

.ms-import__options {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.ms-import__radios.mud-input-control .mud-radio-group {
    flex-flow: column;
    align-items: flex-start;
}

.ms-import__hint {
    margin-left: 8px;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

/* Holds a progress bar's height whether or not one is showing, so nothing moves when it comes and goes. */
.ms-import__progress {
    height: 4px;
}

/* A preview's choices side by side, wrapping under each other where the dialog is narrow. */
.ms-import__settings {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 16px 48px;
}

/* The line right over a preview's rows: what is left out on the left, what the import does on the right. */
.ms-import__summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px 24px;
}

.ms-import__summary-notes {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 20px;
}

.ms-import__muted {
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

.ms-import__muted strong {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

.ms-import__tally {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 16px;
    margin-left: auto;
    color: var(--mud-palette-text-secondary);
    font-size: .8125rem;
}

.ms-import__tally strong {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

/* A preview's rows, one line each so the grid can draw only those in view; a cut-off text is in the title. */
.ms-import__lines table {
    table-layout: fixed;
}

.ms-import__lines td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-import__lines td > span[title] {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The companies the file names: a short list that scrolls in its frame when the file names many. */
.ms-import__companies {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.ms-import__companies-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
}

.ms-import__companies-head .ms-field-label {
    margin: 0;
}

.ms-import__companies-frame {
    max-height: 240px;
    overflow: auto;
    padding: 0 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
}

.ms-import__companies-frame thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding-top: 8px;
    background-color: var(--mud-palette-surface);
}

/* Rows as tight as their picker allows, so a dozen names fit without the frame scrolling. */
.ms-import__companies-frame td {
    padding-top: 2px;
    padding-bottom: 2px;
}

.ms-import__companies-frame .mud-input.mud-input-outlined > input.mud-input-root {
    padding-top: 5px;
    padding-bottom: 5px;
}

.ms-import__company-pick {
    width: 45%;
}

.ms-import__company-skip {
    width: 1%;
    padding-right: 4px;
    padding-left: 4px;
}

.ms-import__problem-list {
    margin: 4px 0 0;
    padding-left: 18px;
}

.ms-file-upload__hint {
    color: var(--mud-palette-text-secondary);
}

/* A row of problems, each a pill with an icon and the words: the report editor's warnings, an export
   style's errors. A pill that leads somewhere is a button and looks no different. */
.ms-issues {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
}

.ms-issue {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px 3px 8px;
    border: 0;
    border-radius: 999px;
    background-color: color-mix(in srgb, var(--ms-tone) 12%, transparent);
    color: var(--mud-palette-text-primary);
    font: inherit;
    font-size: .8125rem;
    text-align: left;
}

button.ms-issue {
    cursor: pointer;
}

button.ms-issue:hover {
    background-color: color-mix(in srgb, var(--ms-tone) 20%, transparent);
}

.ms-issue .material-symbols-outlined {
    color: var(--ms-tone-ink);
    font-size: 17px;
}

.ms-issue strong {
    color: var(--ms-tone-ink);
    font-weight: 600;
}

/* A rail of pages down the left of a panel: its own ground and a border tell the eye where the list ends and
   the page itself starts. Shared, so two rails a click apart in the same dialog are the same thing. Groups
   are optional - a rail of a handful of pages has no need of them. */
.ms-rail {
    flex: 0 0 204px;
    display: flex;
    flex-direction: column;
    padding: 14px 12px;
    background: var(--mud-palette-background-gray);
    border-right: 1px solid var(--mud-palette-lines-default);
    overflow-y: auto;
}

/* A heading, not a page: a rule above it, a lighter ink and no hover set it apart from the items under it. */
.ms-rail__group {
    margin-top: 10px;
    padding: 12px 10px 6px;
    border-top: 1px solid var(--mud-palette-lines-default);
    font-family: var(--ms-font-ui);
    font-size: .75rem;
    font-weight: 600;
    color: var(--ms-ink-3);
    cursor: default;
    user-select: none;
}

.ms-rail__group:first-child {
    margin-top: 0;
    padding-top: 2px;
    border-top: 0;
}

/* A button centres its content by default, and does it again as a flex container - so the leading edge has
   to be asked for in both. */
.ms-rail__item {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    appearance: none;
    border: 0;
    background: none;
    font: inherit;
    font-size: .84375rem;
    color: var(--mud-palette-text-primary);
    padding: 9px 10px;
    margin-bottom: 2px;
    border-radius: 8px;
    cursor: pointer;
}

.ms-rail__item:hover {
    background: var(--mud-palette-action-default-hover);
}

.ms-rail__item--current {
    background: var(--mud-palette-primary-hover);
    color: var(--mud-palette-primary);
    font-weight: 600;
}

/* Smaller than the app's ordinary fields. This is a dense panel of settings - forty short values rather than
   a form you fill in - and at the app's 16px the numbers and hex codes crowd their boxes. Set on the editor
   rather than on the theme, so nothing else moves with it. */
.ms-form .mud-input-control input.mud-input-root,
.ms-form .mud-input-control .mud-input-root,
.ms-form .mud-input-control .mud-input-adornment {
    font-size: .84375rem;
}

/* The resting label sits in the field and has to match it; the floating one is scaled from there by
   MudBlazor's own transform. */
.ms-form .mud-input-label.mud-input-label-inputcontrol {
    font-size: .84375rem;
}

/* The fields that belong together, under the name of the part they set. Two to a row at a width that does not
   change with the number of fields, so moving between sections leaves the frame where it was. */
.ms-form__group + .ms-form__group,
.ms-form__group + .style-roles {
    margin-top: 24px;
}

.ms-form__label {
    margin-bottom: 12px;
    color: var(--mud-palette-text-primary);
    font-family: var(--ms-font-ui);
    font-size: 1rem;
    font-weight: 600;
}

/* Two to a row where there is room, one where the divider has taken the room away. auto-fill rather than
   auto-fit: a group with a single field keeps the column width the others have instead of stretching it
   across the whole row. */
.ms-form__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    align-items: start;
    gap: 14px 18px;
    max-width: 620px;
}

/* DeleteDialog. */

.ms-delete__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: var(--mud-palette-error-hover);
    color: var(--mud-palette-error);
    flex: 0 0 auto;
}

/* Grows with the rows up to about seven and scrolls inside itself after that, so a delete that reaches many
   kinds of rows does not push the confirmation below the fold. The theme's radius, the one the dialog and
   its buttons use. */
.ms-delete__contents {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    overflow: hidden;
}

.ms-delete__contents-header {
    padding: 8px 14px;
    background: var(--mud-palette-background-gray);
    border-bottom: 1px solid var(--mud-palette-lines-default);
    font-family: var(--ms-font-ui);
    font-size: .75rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
}

.ms-delete__contents-list {
    max-height: 252px;
    overflow-y: auto;
}

.ms-delete__row {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 7px 14px;
    font-size: .875rem;
}

.ms-delete__row + .ms-delete__row {
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* Figures of different lengths line up on their last digit. */
.ms-delete__count {
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The step the user has to take, set apart from what they are being told. */
.ms-delete__confirm {
    padding-top: 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.ms-delete__name {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}
