/* ═══════════════════════════════════════════════════════════════════
   DataGrid Component (.dg-*)
   Reusable list/data-grid with sorting, selection, inline editing,
   column resize, and keyboard navigation.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Container ────────────────────────────────────────────────────── */

.dg-container {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    outline: none;
}

.dg-container:focus-visible {
    box-shadow: var(--shadow-sm), 0 0 0 2px color-mix(in srgb, var(--color-primary) 25%, transparent);
}

/* ── Batch Action Bar ─────────────────────────────────────────────── */

.dg-batch-bar {
    background: var(--color-bg-subtle);
    padding: 0.5rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.85rem;
}

.dg-batch-bar-count {
    font-weight: 600;
    color: var(--color-text);
}

.dg-batch-bar-clear {
    background: none;
    border: none;
    color: var(--color-primary);
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: 0.82rem;
    padding: 0.15rem 0.5rem;
    border-radius: 3px;
}

.dg-batch-bar-clear:hover {
    background: var(--color-bg-hover);
}

.dg-batch-bar-actions {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
}

/* ── Toolbar ──────────────────────────────────────────────────────── */

.dg-toolbar {
    display: flex;
    justify-content: flex-end;
    padding: 0.4rem 1rem;
    gap: 0.5rem;
    border-bottom: 1px solid var(--color-border-subtle);
}

.dg-toolbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 1px solid transparent;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    color: var(--color-text-muted);
    transition: background 0.15s, color 0.15s;
    gap: 0.3rem;
}

.dg-toolbar-btn:hover {
    background: var(--color-bg-hover);
    color: var(--color-text);
}

/* Quick-search sits between the left button group and the right controls; flex: 1 absorbs the
   toolbar's free space so the input centres in the middle of it. */
.dg-toolbar-search {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
}

.dg-toolbar-search-input {
    width: min(280px, 100%);
    padding: 0.25rem 0.6rem;
    border: 1px solid var(--color-border-subtle);
    border-radius: 4px;
    background: transparent;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    color: var(--color-text);
    transition: border-color 0.15s;
}

.dg-toolbar-search-input::placeholder {
    color: var(--color-text-muted);
}

.dg-toolbar-search-input:focus {
    border-color: var(--color-primary);
}

.dg-toolbar-btn.dg-active {
    color: var(--color-primary);
    border-color: var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}

/* ── Scroll Container ─────────────────────────────────────────────── */

/* flex-basis must stay auto so the inline height from the Height parameter is the flex base size.
   flex: 1 (basis 0) collapses the explicit height, letting a virtualised table's intrinsic height
   (rows × ItemSize) inflate the container on a reflow — the page goes thousands of px tall, the
   window scrollbar takes over and the tail is blank space. With no Height, basis auto resolves to
   the content size, same behaviour as before. */
.dg-scroll-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

/* ── Table ─────────────────────────────────────────────────────────── */

.dg-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

/* ── Header ────────────────────────────────────────────────────────── */

/* Host-overridable surfaces: the fallbacks are the original light-theme literals, so light hosts
   (Axe, LLB) render pixel-identically with no overrides, while dark hosts set --dg-header-bg /
   --dg-pinned-bg / --dg-control-bg alongside the shared design tokens. */
.dg-header {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--dg-header-bg, rgba(240, 242, 248, 0.75));
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

.dg-header th {
    padding: 0.6rem 1rem;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
    user-select: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
    text-align: left;
}

.dg-header th.dg-align-center {
    text-align: center;
}

.dg-header th.dg-align-right {
    text-align: right;
}

.dg-header th.dg-sortable {
    cursor: pointer;
}

.dg-header th.dg-sortable:hover {
    color: var(--color-text);
}

.dg-header th.dg-sorted {
    color: var(--color-text);
}

/* ── Sort Indicator ───────────────────────────────────────────────── */

.dg-sort-indicator {
    margin-left: 0.35rem;
    font-size: 0.65rem;
}

/* ── Vertical Headers ─────────────────────────────────────────────── */

/* Column.VerticalHeader: rotated single-line label reading bottom-to-top, footed at its column —
   the matrix/heat-map pattern (narrow 2ch columns). The header row auto-grows to the tallest
   rotated label; body-row heights (and Virtualize's ItemSize accounting) are untouched. */
.dg-header th.dg-vertical-header {
    vertical-align: bottom;
}

.dg-header th.dg-vertical-header .dg-header-label {
    display: inline-block;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    white-space: nowrap;
    line-height: 1;
    font-size: 0.65rem;
    text-transform: none;
    letter-spacing: 0;
}

/* Sort arrow compact and centred beneath the rotated label rather than floating beside it. */
.dg-header th.dg-vertical-header .dg-sort-indicator {
    display: block;
    text-align: center;
    margin: 0;
    font-size: 0.55rem;
}

/* Funnel (when a consumer leaves the column filterable) stacks centred below the sort arrow. */
.dg-header th.dg-vertical-header .dg-funnel-btn {
    display: block;
    margin: 0.15rem auto 0;
}

/* ── Resize Handle ────────────────────────────────────────────────── */

.dg-resize-handle {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 5px;
    cursor: col-resize;
    z-index: 3;
}

.dg-resize-handle:hover,
.dg-resizing .dg-resize-handle {
    background: var(--color-primary);
    opacity: 0.4;
}

/* ── Rows ──────────────────────────────────────────────────────────── */

/* The pinned height must match the row-height constants in DataGrid.razor.cs (Virtualize ItemSize +
   FocusItemAsync scroll offset). height on a table row is a minimum: single-line rows become exactly
   this tall so the virtualiser's spacer maths is exact; multi-line cell templates may exceed it,
   which Virtualize tolerates. */
.dg-row {
    height: 40px;
    transition: background 0.1s;
}

.dg-row:hover {
    background: var(--color-bg-hover);
}

.dg-row td {
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    border-bottom: 1px solid var(--color-border-subtle);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dg-row td.dg-align-center {
    text-align: center;
}

.dg-row td.dg-align-right {
    text-align: right;
}

/* ── Focus & Selection ────────────────────────────────────────────── */

.dg-row-focused {
    border-left: 3px solid var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 4%, transparent);
}

.dg-row-selected {
    background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}

.dg-row-focused.dg-row-selected {
    background: color-mix(in srgb, var(--color-primary) 10%, transparent);
}

/* ── Checkbox Column ──────────────────────────────────────────────── */

.dg-checkbox-cell {
    width: 40px;
    text-align: center;
    padding: 0 !important;
}

.dg-checkbox-cell input[type="checkbox"] {
    accent-color: var(--color-primary);
    cursor: pointer;
}

/* ── Pinned Columns ───────────────────────────────────────────────── */

.dg-pinned-left {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--dg-pinned-bg, rgba(255, 255, 255, 0.85));
    box-shadow: 2px 0 4px rgba(0, 0, 0, 0.05);
}

.dg-pinned-right {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--dg-pinned-bg, rgba(255, 255, 255, 0.85));
    box-shadow: -2px 0 4px rgba(0, 0, 0, 0.05);
}

.dg-header .dg-pinned-left,
.dg-header .dg-pinned-right {
    background: var(--dg-header-bg-solid, rgba(240, 242, 248, 0.85));
}

/* ── Column Config Dropdown ───────────────────────────────────────── */

.dg-column-config-wrapper {
    position: relative;
}

.dg-column-config {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 10;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    min-width: 200px;
    max-height: 300px;
    overflow-y: auto;
    padding: 0.35rem 0;
}

.dg-column-config label,
.dg-column-config-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.75rem;
    font-size: 0.82rem;
    cursor: pointer;
    border-radius: 4px;
    margin: 0 0.25rem;
}

.dg-column-config label:hover,
.dg-column-config-row:hover {
    background: var(--color-bg-hover);
}

.dg-column-config-label {
    flex: 1;
}

.dg-column-config-arrows {
    margin-left: auto;
    display: flex;
    gap: 2px;
    opacity: 0;
    transition: opacity 0.15s;
}

.dg-column-config-row:hover .dg-column-config-arrows {
    opacity: 1;
}

.dg-column-config-move {
    background: none;
    border: none;
    color: var(--color-text-muted);
    cursor: pointer;
    font-size: 0.55rem;
    padding: 2px 3px;
    line-height: 1;
}

.dg-column-config-move:hover {
    color: var(--color-primary);
}

.dg-column-config input[type="checkbox"] {
    accent-color: var(--color-primary);
}

.dg-column-config-reset {
    display: block;
    width: calc(100% - 0.5rem);
    margin: 0.25rem;
    padding: 0.3rem 0.5rem;
    font-size: 0.78rem;
    color: var(--color-primary);
    background: none;
    border: none;
    border-top: 1px solid var(--color-border-subtle);
    cursor: pointer;
    text-align: center;
    font-family: var(--font-sans);
}

.dg-column-config-reset:hover {
    background: var(--color-bg-hover);
}

/* ── Density Variants ─────────────────────────────────────────────── */

.dg-density-compact .dg-header th {
    padding: 0.4rem 0.75rem;
    font-size: 0.7rem;
}

/* Must match CompactRowHeightPx in DataGrid.razor.cs — see the .dg-row comment above. */
.dg-density-compact .dg-row {
    height: 32px;
}

.dg-density-compact .dg-row td {
    padding: 0.3rem 0.75rem;
    font-size: 0.8rem;
}

/* ── Inline Editing ───────────────────────────────────────────────── */

.dg-cell-editing {
    padding: 2px !important;
    position: relative;
}

.dg-cell-input,
.dg-cell-select {
    width: 100%;
    border: 1px solid var(--color-primary);
    border-radius: 3px;
    padding: 0.3rem 0.5rem;
    font-size: inherit;
    font-family: var(--font-sans);
    outline: none;
    background: var(--color-bg);
    color: var(--color-text);
}

.dg-cell-input.dg-invalid {
    border-color: #dc2626;
}

.dg-cell-error {
    position: absolute;
    font-size: 0.7rem;
    color: #dc2626;
    background: var(--color-bg);
    padding: 0.1rem 0.4rem;
    border: 1px solid #fecaca;
    border-radius: 3px;
    top: 100%;
    left: 0;
    z-index: 5;
    white-space: nowrap;
}

.dg-cell-checkbox {
    text-align: center;
}

.dg-cell-checkbox input[type="checkbox"] {
    accent-color: var(--color-primary);
    cursor: pointer;
}

/* ── Empty & Status ───────────────────────────────────────────────── */

.dg-empty {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.dg-status-bar {
    padding: 0.5rem 1rem;
    font-size: 0.75rem;
    color: var(--color-text-muted);
    border-top: 1px solid var(--color-border);
}

/* ── Screen Reader Only ───────────────────────────────────────────── */

.dg-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Multi-tier sort ──────────────────────────────────────────────── */

.dg-sort-tier-num {
    font-size: 0.55rem;
    margin-left: 1px;
    font-weight: 700;
}

/* ── Group rows ───────────────────────────────────────────────────── */

/* Same pinned .dg-row height as item rows — Virtualize assumes one uniform ItemSize. */
.dg-group-row {
    cursor: pointer;
    background: color-mix(in srgb, var(--color-primary) 5%, transparent);
    user-select: none;
}

.dg-group-row:hover {
    background: color-mix(in srgb, var(--color-primary) 10%, transparent);
}

.dg-group-cell {
    font-weight: 600;
    color: var(--color-text);
}

.dg-group-indent {
    display: inline-block;
}

.dg-group-chevron {
    display: inline-block;
    width: 1rem;
    color: var(--color-primary);
}

.dg-group-count {
    margin-left: 0.4rem;
    font-weight: 400;
    color: var(--color-text-muted);
    font-size: 0.78rem;
}

/* Per-column numeric aggregates appended to the group header label (#63). One line, inline —
   group rows must keep the uniform row height Virtualize accounting depends on. */
.dg-group-agg {
    margin-left: 0.9rem;
    font-weight: 400;
    color: var(--color-text-muted);
    font-size: 0.78rem;
    white-space: nowrap;
}

.dg-group-agg strong {
    color: var(--color-text);
    font-weight: 600;
}

/* ── Filtering: toolbar, header funnels, funnel panel, dialog ─────── */

.dg-toolbar-left {
    display: flex;
    gap: 0.5rem;
    margin-right: auto;
}

.dg-funnel-btn {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.1rem 0.25rem;
    margin-left: 0.2rem;
    border-radius: 4px;
    color: var(--color-text-muted);
    vertical-align: middle;
}

.dg-header th:hover .dg-funnel-btn {
    display: inline-flex;
}

.dg-funnel-btn:hover {
    color: var(--color-primary);
    background: var(--color-bg-hover);
}

/* A column with an active filter keeps its funnel visible and accent-coloured. */
.dg-funnel-btn.dg-funnel-btn-active {
    display: inline-flex;
    color: var(--color-primary);
}

.dg-funnel-panel {
    position: fixed;
    z-index: 1201;
    width: 280px;
    max-height: 430px;
    padding: 0.6rem;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.dg-funnel-title {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--glass-border);
}

.dg-funnel-search {
    width: 100%;
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 0.8rem;
    background: var(--dg-control-bg, rgba(255, 255, 255, 0.7));
}

.dg-funnel-note {
    font-size: 0.7rem;
    color: var(--color-text-muted);
    font-style: italic;
}

/* Body text of the discard-unsaved-tweaks confirmation (#65). */
.dg-discard-text {
    color: var(--color-text-secondary);
    font-size: 0.88rem;
    margin: 0 0 0.5rem;
}

/* Virtualised value list (#65): block layout with a pinned per-row height — flex gaps would
   drift Virtualize's fixed ItemSize accounting. Height must match the Virtualize ItemSize (24). */
.dg-funnel-values {
    overflow-y: auto;
    max-height: 200px;
}

.dg-funnel-values .dg-funnel-row {
    height: 24px;
    box-sizing: border-box;
}

.dg-funnel-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.22rem 0.3rem;
    border-radius: 5px;
    font-size: 0.82rem;
    color: var(--color-text);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dg-funnel-row:hover {
    background: var(--color-bg-hover);
}

.dg-funnel-selectall {
    font-weight: 600;
    border-bottom: 1px solid var(--color-border-subtle);
}

.dg-funnel-blanks {
    font-style: italic;
    color: var(--color-text-muted);
}

.dg-funnel-condition-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.2rem 0;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-align: left;
}

.dg-funnel-condition-toggle:hover {
    color: var(--color-text);
}

.dg-funnel-condition-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.dg-funnel-condition-body .filter-select {
    flex: 1 1 100%;
}

.dg-funnel-input {
    flex: 1 1 40%;
    min-width: 0;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 0.8rem;
    background: var(--dg-control-bg, rgba(255, 255, 255, 0.7));
}

.dg-funnel-and {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.dg-funnel-footer {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding-top: 0.45rem;
    border-top: 1px solid var(--glass-border);
}

.dg-funnel-spacer,
.dg-filter-footer-spacer {
    flex: 1;
}

/* ── Saved views menu ─────────────────────────────────────────────── */

.dg-view-menu {
    position: relative;
    display: inline-flex;
}

/* Click-away layer for the dropdown. Lives inside .dg-container, whose backdrop-filter makes it
   the containing block for position:fixed — so inset:0 covers the grid, not the viewport. That is
   accepted here (clicks elsewhere on the page hit real controls anyway); real modals must be
   hosted outside the container instead. */
.dg-view-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1200;
}

.dg-view-name {
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.dg-view-caret {
    font-size: 0.6rem;
}

.dg-view-dropdown {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 1201;
    min-width: 220px;
    max-width: 320px;
    padding: 0.3rem;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.dg-view-dropdown .ctx-menu-item {
    overflow: hidden;
    text-overflow: ellipsis;
}

.dg-view-dropdown .ctx-menu-item:disabled {
    opacity: 0.45;
    cursor: default;
}

.dg-view-dropdown .ctx-menu-item:disabled:hover {
    background: transparent;
    color: var(--color-text);
}

.dg-view-section {
    padding: 0.4rem 0.55rem 0.2rem;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}

.dg-view-divider {
    height: 1px;
    margin: 0.25rem 0;
    background: var(--glass-border);
}

.dg-view-item-active {
    color: var(--color-primary);
    font-weight: 600;
}

.dg-view-saveas {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0.75rem 0;
}

.dg-view-name-input {
    flex: 1;
    min-width: 0;
    padding: 0.45rem 0.65rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    background: var(--dg-control-bg, rgba(255, 255, 255, 0.7));
}

.dg-view-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
}

.dg-view-manage-rows {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0.75rem 0;
    max-height: 320px;
    overflow-y: auto;
}

.dg-view-manage-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.dg-view-manage-empty {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    font-style: italic;
    padding: 0.5rem 0;
}

.dg-view-badge {
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 600;
    background: color-mix(in srgb, var(--color-primary) 12%, transparent);
    color: var(--color-primary);
    white-space: nowrap;
}

.dg-view-badge-private {
    background: rgba(120, 120, 140, 0.12);
    color: var(--color-text-muted);
}

/* ── Filter dialog ────────────────────────────────────────────────── */

/* Implicit-filter tick boxes — sit above the condition rows, separated by a rule, because they
   gate which rows exist at all rather than adding another AND condition. */
.dg-filter-implicit {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0.75rem 0 0;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--glass-border, rgba(120, 120, 140, 0.25));
}

.dg-filter-implicit-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    cursor: pointer;
}

.dg-filter-implicit-row input[type="checkbox"] {
    flex: 0 0 auto;
    margin: 0;
    cursor: pointer;
}

.dg-filter-rows {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0.75rem 0;
}

.dg-filter-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.dg-filter-conjunction {
    flex: 0 0 3rem;
    text-align: right;
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

.dg-filter-row .filter-select {
    min-width: 0;
}

.dg-filter-column {
    flex: 1 1 30%;
}

.dg-filter-operator {
    flex: 1 1 24%;
}

.dg-filter-value {
    flex: 1 1 28%;
    min-width: 0;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 0.82rem;
    background: var(--dg-control-bg, rgba(255, 255, 255, 0.7));
}

.dg-filter-and {
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

.dg-filter-remove {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--color-text-muted);
    font-size: 1rem;
    padding: 0.15rem 0.35rem;
    border-radius: 5px;
    line-height: 1;
}

.dg-filter-remove:hover {
    color: var(--color-coral);
    background: var(--color-bg-hover);
}

.dg-filter-add {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.2rem 0;
    font-family: var(--font-sans);
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--color-primary);
    text-align: left;
}

.dg-filter-add:hover {
    text-decoration: underline;
}


/* ═══════════════════════════════════════════════════════════════════
   Modal dialog (shared with the grid's own dialogs)
   ═══════════════════════════════════════════════════════════════════ */

@keyframes modal-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes modal-slide-up {
    from { opacity: 0; transform: translateY(16px) scale(0.97); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(10, 12, 20, 0.4);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: modal-fade-in 0.2s ease-out;
}

.modal-dialog {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    padding: 1.75rem;
    min-width: 520px;
    max-width: 720px;
    /* Never let a modal grow taller than the viewport — long content scrolls inside the dialog. */
    max-height: 90dvh;
    overflow-y: auto;
    box-shadow: var(--shadow-lg), 0 0 60px rgba(24, 181, 164, 0.08);
    animation: modal-slide-up 0.25s ease-out;
}

/* Opt-in variant for modals with a long scrollable body and a pinned header/footer (e.g. the Users
   editor): the dialog itself clips, and the inner .…-body region does the scrolling instead. */
.modal-dialog.modal-flex {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.modal-dialog h4 {
    margin: 0 0 1.25rem;
    font-size: 1.05rem;
}

.modal-dialog .modal-footer {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
