/* Rapport editor (/reports/editor/{id}): the page around the grid, and ReportValueGrid itself - a hand-built
   table with frozen line columns, two-row banded headers, drag and drop and resizable columns. */

.report-header td, .report-header div {
    font-weight: bold;
    font-size: .95rem;
}

.report-sum {
    background-color: var(--mud-palette-background-gray);
}

.report-header .rvg-input {
    font-weight: bold;
    font-size: .95rem;
}

.header-align-right {
    justify-content: flex-end !important;
    flex-direction: row-reverse !important;
    text-align: right;
}

.header-align-center {
    text-align: center;
}

.cell-align-left {
    text-align: left;
}

.cell-align-center {
    text-align: center;
}

.cell-align-right {
    text-align: right;
}

/* Line-state text colors for EDITABLE cells (the always-on field). Read-only cells are colored
   by the per-state "td" rules further down; these cover the field text those don't reach. */
.not-visible-line .rvg-input {
    color: var(--ms-ink-3) !important;
    font-style: italic;
}

.error-line .rvg-input {
    color: var(--mud-palette-error) !important;
}

/* Warning-severity lines (e.g. UnhandledMixedType). Orange — less alarming than red,
           but still calls for attention. */
.warning-line .rvg-input {
    color: var(--ms-warning-accent) !important;
}

/* Info-severity lines. Blue — informational only, no action required. */
.info-line .rvg-input {
    color: var(--mud-palette-info) !important;
}


.report-column-header-text {
    white-space: nowrap;
}

/* Chips give up width first and clip, so a long filter label can't wrap the toolbar row. */
.report-filter-chips {
    flex-shrink: 1;
    min-width: 0;
    overflow: hidden;
}

.selected-line {
    background-color: var(--mud-palette-primary-lighten);
}

/* The line warnings: a strip in the editor's card between its toolbar and the grid. */
.warnings-panel {
    border-bottom: 1px solid var(--mud-palette-lines-default);
    background-color: var(--mud-palette-surface);
}

/* ---- Report editor value grid ---- */
/* --- Editor layout: fixed viewport-height flex column so only the grid scrolls --- */
/* Height = the window less the bar, the system messages and the page column's vertical padding, as .ms-fill-page. */
.report-editor-root {
    display: flex;
    flex-direction: column;
    height: calc(100dvh - var(--ms-top-h) - 32px);
    min-height: 0;
}

/* The page header keeps its height; the card holding the toolbar, the warnings and the grid takes the rest. */
.report-editor-root > .report-editor-toolbars {
    flex: 0 0 auto;
}

.report-editor-card {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.report-editor-card > .report-editor-toolbars,
.report-editor-card > .warnings-panel {
    flex: 0 0 auto;
}

/* The column setup and the button that edits the setups, joined into one control. */
.report-editor-collection-picker {
    display: inline-flex;
    align-items: center;
}

/* Sized by the selected name between a floor and a cap; past the cap the name ends in an ellipsis. */
.report-editor-collection-picker > .mud-select {
    min-width: 200px;
    max-width: 320px;
}

.report-editor-collection-picker .mud-input-control-input-container,
.report-editor-collection-picker .mud-input {
    min-width: 0;
}

/* The list grows past the field for longer names, up to a cap where a name wraps instead. Important: the
   popover's script writes max-width: none inline. */
.report-editor-collection-list {
    max-width: 420px !important;
}

.report-editor-collection-picker .mud-input-control {
    margin: 0;
}

.report-editor-collection-picker .mud-input.mud-input-outlined .mud-input-outlined-border {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.report-editor-collection-picker__edit {
    display: inline-grid;
    place-items: center;
    width: 38px;
    height: 40px; /* the select's dense outlined box */
    margin-left: -1px;
    padding: 0;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 0 var(--mud-default-borderradius) var(--mud-default-borderradius) 0;
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-secondary);
    cursor: pointer;
}

.report-editor-collection-picker__edit:hover {
    background-color: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-primary);
}

.report-editor-collection-picker__edit .material-symbols-outlined {
    font-size: 19px;
}

/* Lagre's dropdown: a narrow segment with a small arrow, the full height of the group. */
.report-editor-save .mud-menu,
.report-editor-save .mud-menu > * {
    display: flex;
    align-self: stretch;
}

.report-editor-save .mud-menu .mud-icon-button {
    width: 32px;
    height: 100%;
    padding: 0;
    border-radius: 0 var(--mud-default-borderradius) var(--mud-default-borderradius) 0;
}

.report-editor-save .mud-menu .mud-icon-button .mud-icon-root {
    font-size: 20px;
}

.report-editor-notice {
    margin: 0 14px 12px;
}

/* Over the top of the grid while values load, so nothing below moves. */
.report-editor-progress {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 30;
}

.report-editor-grid {
    flex: 1 1 0; /* takes the remaining height */
    min-height: 0; /* allow it to shrink below content so the inner wrapper can scroll */
    display: flex;
    position: relative; /* anchors the floating fullscreen actions */
}

/* Fullscreen: the editor covers the window beside the side menu and under the bar, past the page column's
   max width, and hides the toolbars; the warnings row and grid stay. */
.report-editor-root.report-editor--fullscreen {
    position: fixed;
    top: calc(var(--ms-top-h) + 8px);
    left: calc(var(--ms-rail-w) + 8px);
    right: 8px;
    bottom: 8px;
    height: auto;
}

.report-editor-root.report-editor--fullscreen .report-editor-toolbars {
    display: none;
}

/* Floating action cluster shown in fullscreen (grid's top-right corner), above the sticky headers and
   clear of the vertical scrollbar. */
.report-editor-fs-actions {
    position: absolute;
    top: 6px;
    right: 24px;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--ms-radius-sm);
    box-shadow: var(--ms-shadow-pop);
}

.ms-row-menu.report-editor-fs-add {
    color: var(--mud-palette-primary);
}

.ms-row-menu.report-editor-fs-save {
    position: relative;
    color: var(--mud-palette-success);
}

.ms-row-menu.report-editor-fs-save:disabled {
    color: var(--mud-palette-action-disabled);
}

/* Unsaved changes: a dot on the icon's corner, in the header status's warning colour. */
.ms-row-menu.report-editor-fs-save.is-dirty::after {
    content: "";
    position: absolute;
    top: 3px;
    right: 3px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--ms-warning-accent);
    box-shadow: 0 0 0 2px var(--mud-palette-surface);
}

.report-editor-fs-actions__gap {
    width: 1px;
    height: 20px;
    margin: 0 4px;
    background-color: var(--mud-palette-lines-default);
}

/* The row menu's top row: move, then the line's switches, each drawn on while the line has it set. */
.rvg-menu-tools {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px 8px 6px;
}

.rvg-menu-tools__gap {
    width: 1px;
    height: 20px;
    margin: 0 6px;
    background-color: var(--mud-palette-lines-default);
}

.rvg-menu-tool {
    display: inline-grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--ms-radius-sm);
    background: transparent;
    color: var(--mud-palette-action-default);
    cursor: pointer;
}

.rvg-menu-tool .material-symbols-outlined {
    font-size: 20px;
}

.rvg-menu-tool:hover:not(:disabled) {
    background-color: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-text-primary);
}

.rvg-menu-tool.is-on {
    background-color: var(--mud-palette-primary-lighten);
    color: var(--mud-palette-primary);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mud-palette-primary) 45%, transparent);
}

.rvg-menu-tool:disabled {
    opacity: .38;
    cursor: default;
}

/* The grid's box fills the grid area and clips; the wrapper inside is the scroll region. */
.report-editor-grid-paper {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.report-value-grid-wrapper {
    flex: 1;
    min-height: 0;
    overflow: auto; /* both axes: horizontal for wide reports, vertical for long ones */
    width: 100%;
}

.report-value-grid {
    border-collapse: collapse;
    /* width:0 + table-layout:fixed makes the table shrink-wrap to the SUM of the <col> widths (by the
       fixed-layout rule "table width = max(width, sum of columns)") and clip cell content to those
       widths. `max-content` isn't a definite width, so fixed layout wouldn't engage — the table would
       fall back to auto layout, where nowrap read-only cells force the column to their content width
       and can't be resized narrower. width:0 keeps columns authoritative so any column can shrink. */
    width: 0;
    font-family: var(--ms-font-data);
    font-size: .875rem;
    font-variant-numeric: tabular-nums;
}

/* Once column widths are measured, fixed layout makes each column's width authoritative so resizing
   one column doesn't reflow the others (Excel-style). Content that exceeds the width is clipped. */
.report-value-grid.rvg-fixed-cols {
    table-layout: fixed;
}

/* --- Pinned (sticky-left) metadata columns (line number / data / accounts / status) --- */
/* Border handling: with border-collapse the cell borders belong to the TABLE, so they're left behind
   when the cell sticks. box-shadow borders don't work either — Chrome fails to re-composite a sticky
   cell's SHADOW phase as content scrolls under it (the right/freeze borders vanish or flicker), even
   though the cell's BACKGROUND repaints fine. So we drop the collapsed border and draw the right +
   bottom borders as 1px lines in the cell's background-image, which inherits that reliable repaint. */
.report-value-grid .rvg-meta-cell {
    position: sticky;
    /* All borders drawn in-background, none collapsed: a collapsed border belongs to the TABLE and is
       dropped when the sticky cell is composited (e.g. it re-layers on the fullscreen relayout, blanking
       the row dividers). The report body cells draw their bottom divider the same way (below), so the
       two stay aligned at the cell's bottom edge.
       - Left vertical divider: drawn on the LEFT edge (not right) because during horizontal scroll the
         sticky cells' opaque backgrounds overlap by a subpixel, and the right neighbour would paint over
         a right-edge line — anchoring to the cell's own left edge keeps it visible.
       - Bottom row divider: a horizontal line at the cell's bottom edge. */
    border: none;
    background-color: var(--mud-palette-surface); /* opaque so scrolling report cells pass underneath */
    background-image: linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0)),
                      linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 1px 100%, 100% 1px;
    background-position: top left, left bottom;
    background-repeat: no-repeat;
}

.report-value-grid td.rvg-meta-cell {
    z-index: 5;
}

/* The line-number column (first metadata column) is narrow; the default 40px of horizontal cell
   padding leaves it right at its content floor, where a sticky first column loses a pixel or two
   during scroll. Trim its padding so the digits fit comfortably and the width stays stable. */
.report-value-grid .rvg-meta-cell[data-meta-index="0"] {
    padding-left: 8px;
    padding-right: 12px;
}

/* The line number is right-aligned; when a hidden line renders it italic, the slanted last digit
   overruns the clip edge. A little right padding on the text leaves room for the slant. */
.report-value-grid .rvg-meta-cell[data-meta-index="0"] .rvg-cell-text {
    padding-right: 3px;
}

.report-value-grid th.rvg-meta-cell {
    z-index: 9;
}

/* The header of the frozen line columns (spans the band + header rows): deeper than the report's own headers,
   with full-strength text, so the always-visible header marks where the line columns end. Only the fill is
   set - the border lines come from .rvg-meta-cell's background-image. */
.report-value-grid .rvg-header-row th.rvg-meta-header,
.report-value-grid .rvg-band-row th.rvg-meta-header {
    background-color: color-mix(in srgb, var(--mud-palette-text-primary) 10%, var(--ms-surface-2));
}

.report-value-grid .rvg-header-row th.rvg-meta-header .report-column-header-text {
    color: var(--mud-palette-text-primary);
}

/* The last frozen column: left divider + a heavier 2px right freeze line + the bottom row divider, all
   in-background so they repaint reliably (unlike a box-shadow or collapsed border). */
.report-value-grid .rvg-meta-cell.rvg-meta-last {
    background-image: linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0)),
                      linear-gradient(var(--ms-ink-3), var(--ms-ink-3)),
                      linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 1px 100%, 2px 100%, 100% 1px;
    background-position: top left, top right, left bottom;
    background-repeat: no-repeat;
}

/* Line-state row colors must also paint the (opaque) sticky metadata cells. Set background-COLOR only
   so the background-image border lines survive (the `background` shorthand would reset them). */
.report-value-grid tr.report-sum td.rvg-meta-cell {
    background-color: var(--mud-palette-background-gray);
}

.report-value-grid tr.selected-line td.rvg-meta-cell {
    background-color: var(--mud-palette-primary-lighten);
}

/* Lines the focused formula refers to (js/ReportEditor.js sets data-formula-ref): a tint and a coloured left
   edge per reference. After the line-state rules so a referenced sum line takes the tint too. */
[data-formula-ref="1"] { --rvg-ref: var(--ms-formula-ref-1); }
[data-formula-ref="2"] { --rvg-ref: var(--ms-formula-ref-2); }
[data-formula-ref="3"] { --rvg-ref: var(--ms-formula-ref-3); }
[data-formula-ref="4"] { --rvg-ref: var(--ms-formula-ref-4); }
[data-formula-ref="5"] { --rvg-ref: var(--ms-formula-ref-5); }
[data-formula-ref="6"] { --rvg-ref: var(--ms-formula-ref-6); }
[data-formula-ref="7"] { --rvg-ref: var(--ms-formula-ref-7); }
[data-formula-ref="8"] { --rvg-ref: var(--ms-formula-ref-8); }

.report-value-grid tr[data-formula-ref] > td,
.report-value-grid tr[data-formula-ref] > td.rvg-meta-cell {
    background-color: color-mix(in srgb, var(--rvg-ref) var(--ms-formula-ref-tint), var(--mud-palette-surface));
}

/* A pseudo-element, not a border or box-shadow: those drop out when the sticky cell re-composites. */
.report-value-grid tr[data-formula-ref] > td.rvg-meta-cell[data-meta-index="0"]::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background-color: var(--rvg-ref);
}

/* Under the focused formula field: the references whose lines are not in view. */
.rvg-formula-hint {
    position: fixed;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-width: 340px;
    padding: 6px 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;
    pointer-events: none;
}

.rvg-formula-hint[hidden] {
    display: none;
}

.rvg-formula-hint__row {
    display: flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.rvg-formula-hint__dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--rvg-ref);
}

.rvg-formula-hint__ref {
    font-family: var(--ms-font-data);
    font-weight: 600;
}

.rvg-formula-hint__text {
    color: var(--mud-palette-text-secondary);
}

/* Report body cells: both dividers are background lines (left edge, bottom edge), as on the header and the
   metadata cells, so every grid line comes from one mechanism. Firefox snaps collapsed borders to the device
   pixel grid differently from backgrounds, which put the body's column lines a pixel off the header's and left
   gaps at the cell corners. */
/* Line columns hidden to see the report as it prints: still in the DOM, since the column scripts index the
   cells by position, but their columns are 0 wide (ReportValueGrid) and the cells draw nothing. */
.report-value-grid.rvg-meta-hidden .rvg-meta-cell {
    padding: 0 !important;
    background-image: none;
}

/* Important: the fixed-layout rules that make cell content fill its cell are more specific. */
.report-value-grid.rvg-meta-hidden .rvg-meta-cell > * {
    display: none !important;
}

.report-value-grid tbody td:not(.rvg-meta-cell) {
    border: none;
    background-image: linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0)),
                      linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 1px 100%, 100% 1px;
    background-position: left top, left bottom;
    background-repeat: no-repeat;
}

/* The first report column sits against the freeze line, which is its divider; as in the header. */
.report-value-grid tbody td.rvg-meta-last + td {
    background-size: 0 0, 100% 1px;
}

/* Ellipsis on the read-only cell content only (header text + static value/name cells) — NOT the
   cell itself (so the drag insertion-line overlay isn't clipped) and NOT editable field cells (so
   the MudTextField's focus underline isn't clipped). */
.report-value-grid.rvg-fixed-cols .report-column-header-text,
.report-value-grid.rvg-fixed-cols .rvg-cell-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* In fixed layout each cell has a hard width, but read-only content WRAPPERS (a MudTooltip root, or a
   plain div's inner wrapper) shrink-wrap to their text and spill into the next column — so the inner
   .rvg-cell-text never gets constrained and can't ellipsize. Force the cell's direct child and its
   first-level children to fill the cell width so the nested text clips with an ellipsis. */
.report-value-grid.rvg-fixed-cols td > .rvg-cell-text,
.report-value-grid.rvg-fixed-cols td > .rvg-cell-text > * {
    display: block;
    width: 100%;
    min-width: 0;
}

/* MudStack cells (Value breakdown = expand button + value; the Status meta cell = a row of icons).
   MudStack renders a `.d-flex` container (MudBlazor has no `.mud-stack` class). A flex container
   doesn't clip its items, and flex items default to min-width:auto so they refuse to shrink and spill
   past the fixed cell into the next column. Target the flex container that is a DIRECT child of the
   cell (so nested d-flex inside a MudTextField is untouched): constrain it to the cell width and clip
   its overflow; the value span additionally ellipsizes. */
.report-value-grid.rvg-fixed-cols td > .d-flex {
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
}

.report-value-grid.rvg-fixed-cols td > .d-flex > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Value cells whose line has an account breakdown: the whole cell opens it on click. Only these cells
   get the affordance (cursor + blue underlined text on hover); plain value cells look unchanged. */
.report-value-grid .rvg-cell-clickable {
    cursor: pointer;
}

.report-value-grid .rvg-cell-clickable:hover {
    color: var(--mud-palette-primary);
    text-decoration: underline;
}


/* Right-edge column resize handle on the header cells. Straddles the column boundary so it's easy
   to grab; z-index keeps it above the header content and reorder area. */
.report-value-grid .rvg-col-resize {
    position: absolute;
    top: 0;
    right: 0;
    width: 12px;
    height: 100%;
    cursor: col-resize;
    z-index: 7;
    touch-action: none;
}

.report-value-grid th,
.report-value-grid td {
    border: 1px solid var(--mud-palette-table-lines, #E0E0E0);
    position: relative; /* hosts the drag insertion-line overlay (::before) */
}

/* Drop the top edge border that border-collapse would otherwise add to the first header row. */
.report-value-grid thead tr:first-child th {
    border-top: none;
}

/* Compact body-cell metrics (3px padding + ~25px content). Editable cells use an always-on MudTextField
   (capped below) at the same height as the read-only cells, so editable and non-editable rows match. */
.report-value-grid td {
    padding: 3px 24px 3px 16px;
    vertical-align: middle;
}

.report-value-grid td > div {
    min-height: 25px;
}

.report-value-grid .mud-input-control {
    max-height: 25px;
}

/* Match the edit field's font to the static cell text (.875rem) so editable and read-only cells
   are the same height. */
.report-value-grid .mud-input,
.report-value-grid .mud-input-root,
.report-value-grid .mud-input-slot,
.report-value-grid input {
    font-size: .875rem;
}

/* Body editable cells: a native input that reads like a plain cell until focused, then shows MudTextField's
   focus line - 2px primary, growing from the middle. An input has no pseudo-elements, so the line lives on
   the wrapper. The ellipsis sits on the input, so an unfocused, overflowing field truncates like the
   read-only cells; focused, the browser scrolls the text as normal. */
.report-value-grid .rvg-field {
    position: relative;
    height: 25px;
}

.report-value-grid .rvg-input {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 25px;
    margin: 0;
    padding: 3px 0 6px;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--mud-palette-text-primary);
    font-family: var(--mud-typography-default-family, Roboto, Helvetica, Arial, sans-serif);
    font-weight: inherit;
    line-height: 1.1876;
    overflow: hidden;
    text-overflow: ellipsis;
}

.report-value-grid .rvg-field::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    border-bottom: 2px solid var(--mud-palette-primary);
    transform: scaleX(0);
    transition: transform 200ms cubic-bezier(0, 0, .2, 1);
    pointer-events: none;
}

.report-value-grid .rvg-field:focus-within::after {
    transform: scaleX(1);
}

/* Column header row: the quiet header every grid has. Opaque, since it sticks over the rows. */
.report-value-grid .rvg-header-row th {
    height: 44px;
    padding: 0 16px;
    background-color: var(--ms-surface-2);
    user-select: none;
}

/* Grab cursor only when reordering is actually enabled (not for read-only dynamic columns), and never
   on the pinned metadata columns — they're structurally locked, so a grab cursor would mislead. */
.report-value-grid.rvg-reorderable .rvg-header-row th:not(.rvg-meta-cell),
.report-value-grid.rvg-reorderable .rvg-band-chip {
    cursor: grab;
}

.report-value-grid .rvg-header-row th .report-column-header-text {
    color: var(--mud-palette-text-secondary);
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
    font-weight: 600;
}

/* --- Sticky headers --- */
/* The grid wrapper is the vertical scroll region, so the header rows pin to its top. Band row at 0;
   the column-header row below it (band row is 44px tall) when bands are present, else at 0. All header
   backgrounds are opaque (blue header / light band gap / dark metadata), so rows pass underneath. */
.report-value-grid .rvg-band-row th,
.report-value-grid .rvg-header-row th {
    position: sticky;
    top: 0;
}

.report-value-grid.has-bands .rvg-header-row th {
    top: 44px;
}

/* No top border on the column-header row: with bands it's the second sticky row, and a collapsed top
   border there is left behind as the body scrolls under it — the 1px gap it leaves is what bled through
   between the band and header rows. Without the border the two opaque rows abut cleanly. (Without bands
   the header is the first row, where the top border is already removed above.) */
.report-value-grid .rvg-header-row th {
    border-top: none;
}

/* Header cells must sit above the scrolling body cells (which are position:relative). Non-metadata
   header cells get z-index 6; the metadata header cells keep their higher z-index (9, set above) so the
   frozen top-left corner stays above both the sticky-top headers and the sticky-left body column. */
.report-value-grid .rvg-band-row th:not(.rvg-meta-cell),
.report-value-grid .rvg-header-row th:not(.rvg-meta-cell) {
    z-index: 6;
}

/* Parent band row: cells are transparent (page background) so un-banded columns read as a gap;
   a banded segment paints a square chip the same height as a normal header. */
.report-value-grid .rvg-band-row th {
    height: 44px;
    background-color: var(--mud-palette-surface);
    border: none;
    padding: 0;
}

.report-value-grid .rvg-band-chip {
    position: relative; /* hosts the edge resize handles */
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 14px;
    font-family: var(--ms-font-ui);
    font-size: .8125rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden; /* clip the label when the band is narrower than its name */
    /* cursor handled by .rvg-reorderable scope above */
    color: var(--mud-palette-primary);
    /* Opaque, since the row is sticky; the bottom edge caps the columns the band spans. */
    background-color: color-mix(in srgb, var(--mud-palette-primary) 12%, var(--mud-palette-surface));
    box-shadow: inset 0 -2px 0 var(--mud-palette-primary);
}

/* Band name clips with an end-ellipsis (like the column headers) instead of overflowing the chip. */
.report-value-grid .rvg-band-chip-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Drag these edges (on the band's outermost header cells) to grow/shrink its column membership. */
.report-value-grid .rvg-band-resize {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 12px;
    cursor: ew-resize;
    z-index: 6;
    display: flex;
    align-items: center;
    justify-content: center;
}

.report-value-grid .rvg-band-resize-left {
    left: 0;
}

.report-value-grid .rvg-band-resize-right {
    right: 0;
}

/* Inline band-name editor: the band's own look, with a field underline, caret and save/cancel buttons. */
.report-value-grid .rvg-band-edit {
    display: flex;
    align-items: center;
    gap: 2px;
    width: 100%;
    height: 100%;
    padding: 0 4px;
    color: var(--mud-palette-primary);
    background: color-mix(in srgb, var(--mud-palette-primary) 12%, var(--mud-palette-surface));
    box-shadow: inset 0 0 0 1px var(--mud-palette-primary);
}

.report-value-grid .rvg-band-edit-field {
    flex: 1 1 auto;
    min-width: 40px;
}

.report-value-grid .rvg-band-edit .mud-input-slot,
.report-value-grid .rvg-band-edit input {
    color: var(--mud-palette-primary);
    caret-color: var(--mud-palette-primary);
    text-align: center;
    font-size: .8125rem;
    font-weight: 600;
}

.report-value-grid .rvg-band-edit .mud-input-underline::before {
    border-bottom-color: color-mix(in srgb, var(--mud-palette-primary) 50%, transparent);
}

.report-value-grid .rvg-band-edit .mud-input-underline::after {
    border-bottom-color: var(--mud-palette-primary);
}

.report-value-grid .rvg-band-edit-actions {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* Visible grip so the handle is discoverable. */
.report-value-grid .rvg-band-resize::before {
    content: "";
    width: 3px;
    height: 50%;
    border-radius: 2px;
    background: var(--mud-palette-primary);
    opacity: 0.45;
    transition: opacity 0.1s ease, background-color 0.1s ease;
}

.report-value-grid .rvg-band-resize:hover::before {
    opacity: 1;
}

/* Live band-resize preview overlays (don't affect cells at rest — only while resizing). */
.report-value-grid .rvg-resize-add::after,
.report-value-grid .rvg-resize-remove::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
}

.report-value-grid .rvg-resize-add::after {
    background: color-mix(in srgb, var(--mud-palette-success) 28%, transparent); /* will join the band */
}

.report-value-grid .rvg-resize-remove::after {
    background: color-mix(in srgb, var(--mud-palette-error) 28%, transparent); /* will leave the band */
}

/* Band/segment divider: a strong 2px line at the group boundary, in the header only. A collapsed border-left is left behind
   when the header cell sticks (the divider vanished on vertical scroll), so the line is drawn in the
   cell's background-image, which repaints reliably while stuck.
   - Header row: also keep the collapsed border-left so it wins over the neighbour's light border at
     rest (no light "double" line); the background line is coincident (same colour/width/edge) and is
     what remains once the border scrolls off. Header cells are blue via a background-COLOR, so the
     background-image composes over it.
   - Band row: cells have no default border, so the background line alone is a clean single line. The
     banded cell's chip covers the th background, so the line is painted on the chip as well. */
/* Report column-header cells: drop the vertical collapsed borders (they'd be left behind when the header
   sticks, and would double with the dark band divider — the cause of the 2px/1px + turns-white glitch)
   and redraw the inter-column separator as a 1px background line on the LEFT edge, which survives sticky
   scroll. The dark band-divider rule below overrides this same edge on divider cells, so band boundaries
   stay a single dark line. The header/body bottom border stays collapsed (it repaints fine on scroll). */
.report-value-grid .rvg-header-cell {
    border-left: none;
    border-right: none;
    background-image: linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 1px 100%;
    background-position: left top;
    background-repeat: no-repeat;
}

/* First report header (immediately after the frozen metadata corner): suppress its left separator so it
   doesn't sit next to the freeze-boundary line. It's never a band divider, so nothing dark is lost. */
.report-value-grid .rvg-header-row th.rvg-meta-cell + th.rvg-header-cell {
    background-image: none;
}

/* Export-hidden column (ExportOptions.Visible == false): a tinted header with the text in the faint ink, so
   it reads as left out of the export. The `not-visible-column` class is on the inner header-text div, so
   match the cell that contains it (:has). */
.report-value-grid .rvg-header-cell:has(.not-visible-column) {
    background-color: color-mix(in srgb, var(--mud-palette-text-primary) 9%, var(--ms-surface-2));
}

.report-value-grid .rvg-header-cell:has(.not-visible-column) .report-column-header-text {
    color: var(--ms-ink-3);
    font-style: italic;
}

.report-value-grid .rvg-header-icon {
    vertical-align: text-bottom;
    margin-right: 4px;
}

/* Band-boundary divider: a 2px line drawn ONLY in the cell's background (no collapsed border), so
   it's a single consistent line that survives sticky scroll. Same on the band row and the column-header
   row; on a banded cell the chip covers the th background, so it's painted on the chip too. */
.report-value-grid .rvg-header-row th.rvg-seg-divider,
.report-value-grid .rvg-band-row th.rvg-band-divider,
.report-value-grid .rvg-band-row th.rvg-band-divider .rvg-band-chip {
    background-image: linear-gradient(var(--ms-line-strong), var(--ms-line-strong));
    background-size: 2px 100%;
    background-position: left top;
    background-repeat: no-repeat;
}

/* Separator line between the band row and the column-header row, drawn along the band row's bottom in
   the background so it survives sticky scroll. Excludes the metadata cells (they draw their own
   borders); on banded cells the chip covers the th, so it's painted on the chip too. */
.report-value-grid.has-bands .rvg-band-row th:not(.rvg-meta-cell),
.report-value-grid.has-bands .rvg-band-row th:not(.rvg-meta-cell) .rvg-band-chip {
    background-image: linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 100% 1px;
    background-position: left bottom;
    background-repeat: no-repeat;
}

/* A band divider cell needs BOTH the dark divider (left) and the seam (bottom) — combined into one
   background-image (higher specificity, so it wins over the two single-layer rules above). */
.report-value-grid.has-bands .rvg-band-row th.rvg-band-divider,
.report-value-grid.has-bands .rvg-band-row th.rvg-band-divider .rvg-band-chip {
    background-image: linear-gradient(var(--ms-line-strong), var(--ms-line-strong)),
                      linear-gradient(var(--mud-palette-table-lines, #E0E0E0), var(--mud-palette-table-lines, #E0E0E0));
    background-size: 2px 100%, 100% 1px;
    background-position: left top, left bottom;
    background-repeat: no-repeat;
}

/* Insertion cue while dragging: a dotted blue vertical line at the drop boundary, spanning the
   header(s) and the data cells. !important so it wins over the band/segment dividers and the base
   cell borders (and, being wider, also wins border-collapse resolution). The cells' own left/right
   padding gives the line breathing room on both sides. */
.report-value-grid .rvg-insert-line::before {
    content: "";
    position: absolute;
    top: -1px;         /* overlap the collapsed row borders so the line is continuous, not segmented */
    bottom: -1px;
    left: -2px;        /* straddle the collapsed cell border so it sits on the boundary */
    width: 4px;
    background: var(--mud-palette-primary);
    z-index: 3;
    animation: rvg-line-in 0.18s ease-out;
}

/* Grow + fade the line in as it lands on a boundary, so it reads clearly rather than popping. */
@keyframes rvg-line-in {
    from {
        opacity: 0;
        transform: scaleX(0.2);
    }
}

/* The column/band being dragged is dimmed in place so it's clear what's moving (the drag image
   under the cursor is a separate labelled chip). */
.report-value-grid .rvg-dragging-source {
    opacity: 0.4;
}

/* Grabbing cursor for the whole grid while a drag is in progress. */
.report-value-grid.rvg-dragging,
.report-value-grid.rvg-dragging th,
.report-value-grid.rvg-dragging td {
    cursor: grabbing !important;
}

/* --- Row (line) drag-and-drop reorder --- */
/* The line-number cell is the row's drag handle. */
.report-value-grid .rvg-line-handle {
    cursor: grab;
}

.report-value-grid.rvg-dragging-line .rvg-line-handle {
    cursor: grabbing;
}

/* Dim the row being dragged. */
.report-value-grid tr.rvg-line-source > td {
    opacity: 0.4;
}

/* Full-width blue insertion line at the drop slot (top of the target row, or bottom of the last row
   when dropping past the end). box-shadow doesn't shift layout, and a row drag is vertical so there's
   no horizontal scroll to expose the sticky-cell shadow-repaint quirk. */
.report-value-grid tr.rvg-line-insert-before > td {
    box-shadow: inset 0 2px 0 0 var(--mud-palette-primary);
}

.report-value-grid tr.rvg-line-insert-after > td {
    box-shadow: inset 0 -2px 0 0 var(--mud-palette-primary);
}

/* Trailing drop zone / end-of-row spacer. */
/* The strip after the last column: where a column is dropped to move it to the end, and room for the last
   column's resize handle. It draws nothing, so it reads as the space beside the grid. */
.report-value-grid .rvg-header-row th.rvg-spacer,
.report-value-grid tbody td.rvg-spacer {
    width: 8px;
    padding: 0;
    border-color: transparent;
    background-color: var(--mud-palette-surface);
    background-image: none;
}

/* Cells draw their divider on their own left edge, so the last column's right edge is drawn here. No side
   borders, or the line would start inside one. */
.report-value-grid .rvg-header-row th.rvg-spacer,
.report-value-grid tbody td.rvg-spacer {
    border-left: none;
    border-right: none;
    background-image: linear-gradient(var(--mud-palette-table-lines), var(--mud-palette-table-lines));
    background-size: 1px 100%;
    background-position: left top;
    background-repeat: no-repeat;
}


/* Line-state text colors for read-only cells (the editable-field variants are near the top of this
   block). Hidden lines are greyed + italic; error/warning/info follow severity. */
.not-visible-line td {
    color: var(--ms-ink-3) !important;
    font-style: italic;
}

.error-line td {
    color: var(--mud-palette-error) !important;
}

.warning-line td {
    color: var(--ms-warning-accent) !important;
}

.info-line td {
    color: var(--mud-palette-info) !important;
}
