﻿/*
    The maps and schemas libraries share this look. It lives in a stylesheet rather than in a component's
    <style> block so both pages get it whether or not the other one has rendered.
*/
/* ================================================== layout */
    .xm-library:focus {
        outline: none;
    }

    .xm-library {
        display: flex;
        flex-direction: column;
        flex: 1; /* .content is a 100vh flex column; take what is left of it */
        min-height: 0;
        /* .content pads 1rem each side; cancel it so the library uses the full width */
        margin: 0 -1rem;
        position: relative;
        color: var(--xm-text);
    }

    .xm-body {
        flex: 1;
        min-height: 0;
        display: flex;
        /* No gap: the drag handle sits directly between rail and content and draws the divider itself. */
        padding: 0 16px 16px 16px;
    }

    .xm-content {
        flex: 1;
        min-width: 0;
        overflow-y: auto;
        padding: 0 4px 0 16px;
    }

        /* The bulk bar floats over the bottom; leave it somewhere to float that is not the last row. */
        .xm-content.has-bulk {
            padding-bottom: 68px;
        }

    /* ================================================== command bar */
    .xm-bar {
        display: flex;
        align-items: center;
        gap: 16px;
        padding: 14px 16px 10px 16px;
    }

    .xm-search {
        flex: 1;
        min-width: 0;
        max-width: 520px;
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 0 10px;
        height: 38px;
        border: 1px solid var(--xm-control-border);
        border-radius: 10px;
        background: var(--xm-surface);
    }

        .xm-search:focus-within {
            border-color: var(--xm-accent);
            box-shadow: 0 0 0 3px color-mix(in srgb, var(--xm-accent) 18%, transparent);
        }

        .xm-search input {
            flex: 1;
            min-width: 0;
            border: none;
            outline: none;
            background: transparent;
            color: var(--xm-text);
            font-size: 14px;
        }

    .xm-search-icon {
        color: var(--xm-text-muted);
        font-size: 15px;
    }

    .xm-search-hint {
        flex: none;
        padding: 1px 6px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 5px;
        color: var(--xm-text-muted);
        font-size: 11px;
        line-height: 1.4;
    }

    .xm-search-clear {
        flex: none;
        border: none;
        background: transparent;
        color: var(--xm-text-muted);
        cursor: pointer;
        padding: 2px;
    }

    .xm-bar-actions {
        display: flex;
        align-items: center;
        gap: 8px;
        flex: none;
    }

    /* ================================================== filters */
    .xm-filters {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        flex-wrap: wrap;
        padding: 0 16px 12px 16px;
        border-bottom: 1px solid var(--xm-border-soft);
    }

    /* Sits with the other view controls, so it matches their height and border rather than the chips. */
.xm-selectall {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: none;
    padding: 5px 9px;
    border: 1px solid var(--xm-control-border);
    border-radius: 8px;
    background: var(--xm-surface);
    color: var(--xm-text-muted);
    font-size: 12px;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}

    .xm-selectall:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

    .xm-selectall input {
        margin: 0;
        cursor: pointer;
        accent-color: var(--xm-accent);
    }

    .xm-selectall:has(input:checked) {
        border-color: var(--xm-accent);
        color: var(--xm-accent-text);
    }

    .xm-selectall:has(input:disabled) {
        opacity: .5;
        cursor: default;
    }

    /*
        Some but not all of the shown rows are selected. The checkbox cannot say this on its own — its
        indeterminate state is a DOM property, not an attribute, so it does not survive being rendered.
    */
    .xm-selectall.is-partial {
        border-color: var(--xm-accent);
        color: var(--xm-accent-text);
    }

        .xm-selectall.is-partial span::after {
            content: "";
            display: inline-block;
            width: 7px;
            height: 2px;
            margin-left: 5px;
            vertical-align: middle;
            background: var(--xm-accent-text);
        }

.xm-chips {
        display: flex;
        align-items: center;
        gap: 6px;
        flex-wrap: wrap;
    }

    .xm-chip {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 5px 12px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 999px;
        background: transparent;
        color: var(--xm-text-muted);
        font-size: 12px;
        cursor: pointer;
        transition: background .12s, color .12s, border-color .12s;
    }

        .xm-chip:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

        .xm-chip.is-on {
            background: var(--xm-accent);
            border-color: var(--xm-accent);
            color: #fff;
        }

    /* Separates the format chips from the folder chips; they are two independent filters. */
.xm-chip-sep {
    width: 1px;
    height: 16px;
    margin: 0 4px;
    background: var(--xm-border-soft);
}

.xm-chip-count {
    margin-left: 6px;
    opacity: .7;
    font-size: 11px;
}

.xm-badge-format {
    font-weight: 600;
    letter-spacing: .03em;
}

/* A registration whose files are gone. Loud enough to stop a click, quiet enough not to shout down a
   list where several rows are broken at once. */
.xm-badge-broken {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-color: var(--xm-error-border);
    background: var(--xm-status-error);
    color: var(--xm-text);
    font-weight: 600;
}

    .xm-badge-broken .e-icons {
        font-size: 10px;
    }

/* The whole card is marked too, so a broken row is findable by scanning rather than by reading badges. */
.xm-card.is-broken {
    border-color: var(--xm-error-border);
    box-shadow: inset 3px 0 0 0 var(--xm-error-border);
}

    .xm-card.is-broken .xm-name {
        text-decoration: underline;
        text-decoration-style: wavy;
        text-decoration-color: var(--xm-error-border);
        text-underline-offset: 3px;
    }

/* A chip that is reporting rather than filtering: mid-check, or a clean result. */
.xm-chip.is-busy,
.xm-chip.is-quiet {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: default;
    color: var(--xm-text-muted);
}

    .xm-chip.is-quiet .e-icons {
        color: var(--xm-status-ok-text);
    }

/* A chip that counts something wrong. */
.xm-chip.is-bad {
    border-color: var(--xm-error-border);
}

    .xm-chip.is-bad.is-on {
        background: var(--xm-status-error);
        border-color: var(--xm-error-border);
        color: var(--xm-text);
    }

/* Marks a row that has a sample to test against. Quiet on purpose: it is a useful fact, not a warning,
   and it sits next to badges that carry more weight. */
.xm-badge-sample {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-color: var(--xm-status-ok-text);
    color: var(--xm-status-ok-text);
}

    .xm-badge-sample .e-icons {
        font-size: 10px;
    }

.xm-chip-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        flex: none;
    }

    .xm-filters-right {
        display: flex;
        align-items: center;
        gap: 12px;
    }

    .xm-sort {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 12px;
        color: var(--xm-text-muted);
    }

        .xm-sort select {
            border: 1px solid var(--xm-control-border);
            border-radius: 8px;
            background: var(--xm-surface);
            color: var(--xm-text);
            padding: 5px 8px;
            font-size: 12px;
        }

    .xm-count {
        font-size: 12px;
        color: var(--xm-text-muted);
        white-space: nowrap;
    }

    /* Filters are kept until cleared: the way out, next to the count it narrows. */
    .xm-count-clear {
        border: none;
        background: none;
        padding: 0 2px;
        font-size: 12px;
        color: var(--xm-accent);
        cursor: pointer;
        white-space: nowrap;
    }

        .xm-count-clear:hover {
            text-decoration: underline;
        }

    /* A pair, so it cannot be mistaken for the single reset button next to it. */
    .xm-density {
        display: inline-flex;
        border: 1px solid var(--xm-control-border);
        border-radius: 8px;
        overflow: hidden;
    }

        .xm-density button {
            border: none;
            background: transparent;
            color: var(--xm-text-muted);
            padding: 6px 9px;
            cursor: pointer;
            line-height: 1;
        }

            .xm-density button:hover {
                background: var(--xm-surface-hover);
                color: var(--xm-text);
            }

            .xm-density button.is-on {
                background: var(--xm-accent);
                color: #fff;
            }

    .xm-reset {
        border: 1px solid var(--xm-control-border);
        border-radius: 8px;
        background: transparent;
        color: var(--xm-text-muted);
        padding: 6px 9px;
        cursor: pointer;
    }

        .xm-reset:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

    .xm-enriching {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 11px;
        color: var(--xm-text-muted);
    }

    /* ================================================== namespace rail */
    .xm-rail {
        /* width comes from the inline style so it can be dragged */
        flex: none;
        overflow-y: auto;
        padding-top: 14px;
    }

    /* The divider itself: always a visible line, and a 9px target around it to grab. */
    .xm-rail-handle {
        flex: none;
        width: 9px;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: col-resize;
        touch-action: none;
    }

        /* the line the user sees */
        .xm-rail-handle::before {
            content: "";
            position: absolute;
            top: 0;
            bottom: 0;
            width: 1px;
            background: var(--xm-border-soft);
            transition: background .12s, width .12s;
        }

        .xm-rail-handle:hover::before,
        .xm-rail-handle.is-dragging::before {
            width: 3px;
            border-radius: 2px;
            background: var(--xm-accent);
        }

    /* the grip marks, so it reads as draggable before you touch it */
    .xm-rail-grip {
        position: relative;
        width: 3px;
        height: 26px;
        border-radius: 2px;
        background: var(--xm-border);
        transition: background .12s;
    }

    .xm-rail-handle:hover .xm-rail-grip,
    .xm-rail-handle.is-dragging .xm-rail-grip {
        background: var(--xm-accent);
    }

    /* Covers the page while dragging so the pointer cannot escape the handle mid-drag. */
    .xm-drag-overlay {
        position: fixed;
        inset: 0;
        z-index: 60;
        cursor: col-resize;
        user-select: none;
    }

    .xm-rail-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 6px;
        padding: 0 8px 8px 4px;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--xm-text-muted);
    }

    .xm-rail-toggle {
        border: none;
        background: transparent;
        color: var(--xm-text-muted);
        border-radius: 5px;
        padding: 3px 4px;
        cursor: pointer;
        line-height: 1;
    }

        .xm-rail-toggle:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

    /* Collapsed: a full-height strip, wide enough to hit and labelled so it reads as a way back. */
    .xm-rail-strip {
        width: 30px;
        flex: none;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 10px;
        padding: 14px 0 10px 0;
        border: none;
        border-right: 1px solid var(--xm-border-soft);
        background: transparent;
        color: var(--xm-text-muted);
        cursor: pointer;
    }

        .xm-rail-strip:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

    .xm-rail-strip-text {
        writing-mode: vertical-rl;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .06em;
        text-transform: uppercase;
    }

    .xm-rail-strip-dot {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--xm-accent);
    }

    .xm-rail-item {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 7px 12px 7px 4px;
        border: none;
        border-left: 3px solid transparent;
        background: transparent;
        color: var(--xm-text-muted);
        font-size: 13px;
        text-align: left;
        cursor: pointer;
    }

        .xm-rail-item:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

        .xm-rail-item.is-on {
            border-left-color: var(--xm-accent);
            color: var(--xm-text);
            font-weight: 600;
        }

    .xm-rail-name {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .xm-rail-count {
        flex: none;
        font-size: 11px;
        color: var(--xm-text-muted);
        font-weight: 400;
    }

    /* ================================================== cards */
    .xm-cards {
        display: flex;
        flex-direction: column;
        gap: 8px;
        padding-top: 14px;
    }

    .xm-group-head {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 18px 2px 0 2px;
        font-size: 12px;
        font-weight: 600;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--xm-text-muted);
    }

    .xm-group-count {
        font-weight: 400;
        text-transform: none;
        letter-spacing: 0;
    }

    .xm-card {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 10px 12px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 10px;
        background: var(--xm-surface);
        transition: border-color .12s, box-shadow .12s;
    }

        .xm-card:hover {
            border-color: var(--xm-accent);
            box-shadow: 0 1px 6px var(--xm-shadow);
        }

        .xm-card.is-selected {
            border-color: var(--xm-accent);
            background: var(--xm-selection);
        }

        .xm-card.is-busy {
            opacity: .65;
        }

    .xm-check {
        flex: none;
        display: flex;
        align-items: center;
        cursor: pointer;
    }

        .xm-check input {
            cursor: pointer;
        }

    .xm-card-main {
        flex: 1;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: 3px;
        border: none;
        background: transparent;
        color: inherit;
        text-align: left;
        cursor: pointer;
        padding: 0;
    }

        .xm-card-main:disabled {
            cursor: default;
        }

    .xm-card-title {
        display: flex;
        align-items: center;
        gap: 8px;
        min-width: 0;
    }

    .xm-name {
        font-size: 14px;
        font-weight: 600;
        color: var(--xm-text);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .xm-badge {
        flex: none;
        padding: 1px 7px;
        border-radius: 999px;
        border: 1px solid var(--xm-border-soft);
        color: var(--xm-text-muted);
        font-size: 11px;
    }

    .xm-ns {
        flex: none;
        font-size: 11px;
        color: var(--xm-text-muted);
    }

    .xm-card-sub {
        display: flex;
        align-items: center;
        min-height: 18px;
    }

    .xm-flow {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        min-width: 0;
        font-size: 12px;
        color: var(--xm-text-muted);
    }

    .xm-path {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 240px;
    }

    .xm-arrow {
        flex: none;
        color: var(--xm-accent);
    }

    .xm-conv {
        flex: none;
        padding: 1px 7px;
        border-radius: 999px;
        color: #fff;
        font-size: 10px;
        letter-spacing: .02em;
    }

    .xm-muted {
        font-size: 12px;
        color: var(--xm-text-muted);
        font-style: italic;
    }

    .xm-card-when {
        flex: none;
        font-size: 11px;
        color: var(--xm-text-muted);
        white-space: nowrap;
    }

    /* ================================================== row menu */
    .xm-menu-wrap {
        position: relative;
        flex: none;
        display: flex;
        align-items: center;
        min-width: 30px;
        justify-content: center;
    }

    .xm-more {
        border: none;
        background: transparent;
        color: var(--xm-text-muted);
        border-radius: 6px;
        padding: 5px 7px;
        cursor: pointer;
    }

        .xm-more:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

    .xm-menu {
        position: absolute;
        top: calc(100% + 4px);
        right: 0;
        max-height: 60vh;
        overflow-y: auto;
        z-index: 40;
        min-width: 230px;
        padding: 5px;
        border: 1px solid var(--xm-border);
        border-radius: 10px;
        background: var(--xm-surface);
        box-shadow: 0 8px 24px var(--xm-shadow);
    }

        .xm-menu button {
            width: 100%;
            display: flex;
            align-items: center;
            gap: 9px;
            padding: 7px 10px;
            border: none;
            border-radius: 6px;
            background: transparent;
            color: var(--xm-text);
            font-size: 13px;
            text-align: left;
            cursor: pointer;
        }

            .xm-menu button:hover {
                background: var(--xm-surface-hover);
            }

            .xm-menu button.is-danger {
                color: var(--xm-error-text);
            }

        /* Near the bottom of the list there is no room below, so hang it off the top edge instead. */
        .xm-menu.is-up {
            top: auto;
            bottom: calc(100% + 4px);
        }

    .xm-menu-versions {
        min-width: 180px;
    }

    .xm-menu-note {
        display: flex;
        align-items: center;
        gap: 7px;
        padding: 6px 10px 4px 10px;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--xm-text-muted);
    }

    .xm-menu-row {
        display: flex;
        align-items: center;
        gap: 2px;
    }

        .xm-menu-row > button:first-child {
            flex: 1;
            min-width: 0;
        }

    .xm-menu-del {
        flex: none;
        width: auto !important;
        padding: 7px 8px !important;
        color: var(--xm-text-muted) !important;
    }

        .xm-menu-del:hover:not(:disabled) {
            background: var(--xm-error-text) !important;
            color: #fff !important;
        }

        .xm-menu-del:disabled {
            opacity: .3;
            cursor: default;
        }

    .xm-menu-tag {
        padding: 0 6px;
        border-radius: 999px;
        background: var(--xm-accent);
        color: #fff;
        font-size: 10px;
    }

    .xm-menu button.is-current {
        font-weight: 600;
    }

    .xm-menu-when {
        margin-left: auto;
        font-size: 11px;
        color: var(--xm-text-muted);
    }

    .xm-ver-wrap {
        position: relative;
        flex: none;
    }

    .xm-badge-btn {
        display: inline-flex;
        align-items: center;
        gap: 3px;
        background: transparent;
        cursor: pointer;
        font: inherit;
        font-size: 11px;
        line-height: 1.5;
    }

        .xm-badge-btn:hover {
            border-color: var(--xm-accent);
            color: var(--xm-accent);
        }

    .xm-badge-caret {
        font-size: 8px;
    }

    /* ---- compact density ---- */
    .xm-cards.is-compact {
        gap: 4px;
    }

        .xm-cards.is-compact .xm-card {
            padding: 4px 10px;
            gap: 8px;
            border-radius: 7px;
        }

        .xm-cards.is-compact .xm-card-main {
            flex-direction: row;
            align-items: center;
            gap: 12px;
        }

        .xm-cards.is-compact .xm-card-title {
            flex: none;
            max-width: 42%;
        }

        .xm-cards.is-compact .xm-name {
            font-size: 13px;
        }

        .xm-cards.is-compact .xm-card-sub {
            min-height: 0;
            min-width: 0;
            overflow: hidden;
        }

    /* Virtualize emits spacer elements, which a flex column would treat as gapped items. */
    .xm-cards.is-virtual {
        display: block;
    }

        .xm-cards.is-virtual .xm-card {
            margin-bottom: 8px;
        }

        .xm-cards.is-virtual.is-compact .xm-card {
            margin-bottom: 4px;
        }

    .xm-menu-sep {
        height: 1px;
        margin: 4px 6px;
        background: var(--xm-border-soft);
    }

    .xm-menu-backdrop {
        position: fixed;
        inset: 0;
        z-index: 30;
    }

    /* ================================================== bulk bar */
    .xm-bulkbar {
        position: absolute;
        left: 50%;
        bottom: 20px;
        transform: translateX(-50%);
        z-index: 25;
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 9px 14px;
        border-radius: 12px;
        background: var(--xm-text);
        color: var(--xm-bg);
        box-shadow: 0 8px 26px rgba(0,0,0,.28);
    }

    .xm-bulk-count {
        display: flex;
        flex-direction: column;
        font-size: 13px;
        font-weight: 600;
        line-height: 1.3;
    }

    .xm-bulk-hidden {
        font-size: 11px;
        font-weight: 400;
        opacity: .75;
    }

    .xm-bulk-action {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 5px 11px;
        border: 1px solid transparent;
        border-radius: 8px;
        background: rgba(127,127,127,.28);
        color: inherit;
        font-size: 12px;
        cursor: pointer;
    }

        .xm-bulk-action:hover {
            background: rgba(127,127,127,.45);
        }

        .xm-bulk-action.is-danger:hover {
            background: var(--xm-danger);
            color: #fff;
        }

    .xm-bulk-clear {
        border: none;
        background: transparent;
        color: inherit;
        opacity: .75;
        font-size: 12px;
        cursor: pointer;
    }

    .xm-bulk-progress {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        font-size: 12px;
    }

    /* ================================================== states */
    .xm-empty {
        max-width: 460px;
        margin: 60px auto;
        text-align: center;
        color: var(--xm-text-muted);
    }

    .xm-empty-title {
        font-size: 17px;
        font-weight: 600;
        color: var(--xm-text);
        margin-bottom: 6px;
    }

    .xm-empty .xm-bar-actions {
        justify-content: center;
        margin-top: 16px;
    }

    .xm-card.is-skeleton {
        flex-direction: column;
        align-items: stretch;
        gap: 7px;
        pointer-events: none;
    }

    .xm-skel {
        display: block;
        border-radius: 5px;
        background: linear-gradient(90deg, var(--xm-surface-alt) 25%, var(--xm-surface-hover) 37%, var(--xm-surface-alt) 63%);
        background-size: 400% 100%;
        animation: xm-shimmer 1.3s ease-in-out infinite;
    }

    .xm-skel-title {
        height: 13px;
        width: 34%;
    }

    .xm-skel-sub {
        height: 11px;
        width: 52%;
        min-width: 120px;
    }

    @keyframes xm-shimmer {
        0% { background-position: 100% 50%; }
        100% { background-position: 0 50%; }
    }

    /* The one spinner. A gold arc on a soft track, in two sizes: inline next to text (xm-spin) and on its own
       in a panel or overlay (xm-spin xm-spin-lg). Components use these classes rather than drawing their own. */
    .xm-spin {
        display: inline-block;
        width: 14px;
        height: 14px;
        flex: none;
        box-sizing: border-box;
        border: 2px solid var(--xm-border-soft);
        border-top-color: var(--xm-highlight);
        border-radius: 50%;
        vertical-align: -2px;
        animation: xm-spin .7s linear infinite;
    }

    .xm-spin-lg {
        width: 36px;
        height: 36px;
        border-width: 3px;
    }

    @keyframes xm-spin {
        to { transform: rotate(360deg); }
    }

    @media (prefers-reduced-motion: reduce) {
        .xm-spin {
            animation-duration: 1.6s;
        }
    }

    /* Controls/BusySpinner.razor: blocks the page while work runs that the user must wait for. */
    .xm-busy {
        position: fixed;
        inset: 0;
        z-index: 9000;
        display: flex;
        align-items: center;
        justify-content: center;
        background: color-mix(in srgb, var(--xm-surface) 55%, transparent);
    }

    .xm-busy-box {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        min-width: 180px;
        max-width: 360px;
        padding: 20px 24px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 12px;
        background: var(--xm-surface);
        color: var(--xm-text);
        box-shadow: 0 8px 28px rgba(0, 0, 0, .18);
        text-align: center;
        font-size: 13px;
    }

    @media (max-width: 900px) {
        .xm-rail,
        .xm-rail-handle {
            display: none;
        }

        .xm-bar {
            flex-wrap: wrap;
        }
    }

    .custom-confirm-dialog .e-primary {
        background-color: var(--xm-accent) !important;
        border-color: var(--xm-accent) !important;
        color: white !important;
    }

        .custom-confirm-dialog .e-primary:hover {
            background-color: var(--xm-accent-hover) !important;
            border-color: var(--xm-accent-hover) !important;
        }

    /* Syncfusion's own spinners (grids, file manager) match .xm-spin: gold arc on a soft track. */
    .e-spinner-pane svg path,
    .e-spinner-pane .e-path-arc,
    .e-spinner-pane .e-arc {
        stroke: var(--xm-highlight) !important;
    }

    .e-spinner-pane .e-path-circle {
        stroke: var(--xm-border-soft) !important;
    }

/* ================================================== dialogs
   Every dialog in the app, Syncfusion's own and the app's message boxes alike: one light card (no header rule,
   no footer band), and buttons that are the command bar's (.xc-btn): 32px, 8px corners, sentence case, the
   main action filled, the rest outlined. The main action always sits last, at the right, whatever order a
   dialog declares its buttons in. Here, after the Syncfusion theme, so these win without !important. */
.e-dlg-overlay {
    background-color: var(--xm-overlay) !important;
    opacity: 1 !important;
}

.e-dialog.e-popup {
    border: 1px solid var(--xm-border-soft);
    border-radius: 12px;
    background: var(--xm-surface);
    color: var(--xm-text);
    box-shadow: var(--xm-dialog-shadow);
    overflow: hidden;
}

    .e-dialog.e-popup .e-dlg-header-content {
        padding: 16px 20px 6px 20px;
        border-bottom: none;
        border-radius: 12px 12px 0 0;
        background: transparent;
    }

    .e-dialog.e-popup .e-dlg-header,
    .e-dialog.e-popup .e-dlg-header * {
        font-size: 15px;
        font-weight: 600;
        color: var(--xm-text);
    }

    .e-dialog.e-popup .e-dlg-content {
        padding: 8px 20px 12px 20px;
        background: transparent;
        color: var(--xm-text);
        font-size: 13px;
    }

    .e-dialog.e-popup .e-footer-content {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        gap: 8px;
        padding: 10px 20px 16px 20px;
        border-top: none;
        border-radius: 0 0 12px 12px;
        background: transparent;
    }

    /*
        the close cross: a quiet square that lights on hover, not a round grey button.
        The theme draws it as a zero-width button (width 0, padding 4px 11px) nudged up 5px, with a 16px glyph in a
        10px box. Sized to 28px on top of that, the square and the cross no longer lined up: the square sat 5px high
        and the cross off to one side. So the offsets are undone and the cross is centred in the square.
    */
    .e-dialog.e-popup .e-dlg-header-content .e-btn.e-dlg-closeicon-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        position: relative;
        bottom: 0;
        left: 0;
        width: 28px;
        min-width: 28px;
        height: 28px;
        margin: -4px -6px 0 8px;
        padding: 0;
        border: none;
        border-radius: 6px;
        background: transparent;
        box-shadow: none;
        line-height: 1;
    }

        .e-dialog.e-popup .e-dlg-header-content .e-btn.e-dlg-closeicon-btn:hover {
            background: var(--xm-surface-hover);
        }

        .e-dialog.e-popup .e-dlg-header-content .e-btn.e-dlg-closeicon-btn:focus-visible {
            background: var(--xm-surface-hover);
            outline: 2px solid var(--xm-accent);
            outline-offset: 0;
        }

        .e-dialog.e-popup .e-dlg-header-content .e-btn.e-dlg-closeicon-btn .e-btn-icon {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 16px;
            height: 16px;
            margin: 0;
            font-size: 14px;
            line-height: 1;
            color: var(--xm-text-muted);
        }

        .e-dialog.e-popup .e-dlg-header-content .e-btn.e-dlg-closeicon-btn:hover .e-btn-icon {
            color: var(--xm-text);
        }

        /* the theme's click ripple, drawn where the pointer was: it read as a second, stray highlight */
        .e-dialog.e-popup .e-dlg-closeicon-btn .e-ripple-element {
            display: none;
        }

    /* ---- the buttons, as the command bar's */
    .e-dialog.e-popup .e-footer-content .e-btn {
        order: 1;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        height: 32px;
        min-width: 0;
        margin: 0;
        padding: 0 14px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 8px;
        background: var(--xm-surface);
        color: var(--xm-text);
        box-shadow: none;
        font-size: 13px;
        font-weight: 500;
        line-height: 1;
        text-transform: none;
        letter-spacing: normal;
    }

        .e-dialog.e-popup .e-footer-content .e-btn:hover:not(:disabled) {
            background: var(--xm-surface-hover);
            border-color: var(--xm-border-soft);
            color: var(--xm-text);
        }

        .e-dialog.e-popup .e-footer-content .e-btn:focus,
        .e-dialog.e-popup .e-footer-content .e-btn:focus-visible {
            outline: 2px solid color-mix(in srgb, var(--xm-accent) 55%, transparent);
            outline-offset: 1px;
        }

        .e-dialog.e-popup .e-footer-content .e-btn:disabled {
            opacity: .5;
        }

        /* the main action: filled, and last. ok-button is what several dialogs called theirs. */
        .e-dialog.e-popup .e-footer-content .e-btn.e-primary,
        .e-dialog.e-popup .e-footer-content .e-btn.ok-button {
            order: 2;
            border-color: var(--xm-accent);
            background: var(--xm-accent);
            color: #fff;
        }

            .e-dialog.e-popup .e-footer-content .e-btn.e-primary:hover:not(:disabled),
            .e-dialog.e-popup .e-footer-content .e-btn.ok-button:hover:not(:disabled) {
                border-color: var(--xm-accent-hover);
                background: var(--xm-accent-hover);
                color: #fff;
            }

        /* A destructive action: red, so the colour warns before the words do. A message box is told apart by its
           own body (Helper/AppDialog.cs renders .xm-confirm.is-danger), not by a class on the dialog, which
           Syncfusion's utility dialogs do not reliably carry. Only with a Cancel beside it: an error or an alert
           has one button, which only closes. */
        .e-dialog.e-popup .e-footer-content .e-btn.e-danger,
        .e-dialog.e-popup:has(.xm-confirm.is-danger):has(.e-footer-content .e-btn:not(.e-primary)) .e-footer-content .e-btn.e-primary {
            order: 2;
            border-color: var(--xm-danger);
            background: var(--xm-danger);
            color: #fff;
        }

            .e-dialog.e-popup .e-footer-content .e-btn.e-danger:hover:not(:disabled),
            .e-dialog.e-popup:has(.xm-confirm.is-danger):has(.e-footer-content .e-btn:not(.e-primary)) .e-footer-content .e-btn.e-primary:hover:not(:disabled) {
                border-color: var(--xm-danger-hover);
                background: var(--xm-danger-hover);
                color: #fff;
            }

/* ================================================== message boxes (Helper/AppDialog.cs)
   Left-aligned: a small mark beside the text when the tone means something (a warning, a delete, an error),
   none on an ordinary question. They used to be a centred stack under a 38px logo or icon circle. */
.xm-confirm-dialog .e-dlg-content {
    padding-top: 4px;
}

.xm-confirm {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    text-align: left;
}

.xm-confirm-mark {
    width: 28px;
    height: 28px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--xm-surface-hover);
}

    .xm-confirm-mark .e-icons {
        font-size: 14px;
        color: var(--xm-text-muted);
    }

    .xm-confirm-mark img {
        width: 20px;
        height: 20px;
        object-fit: contain;
    }

    .xm-confirm.is-info .xm-confirm-mark .e-icons {
        color: var(--xm-accent);
    }

    .xm-confirm.is-success .xm-confirm-mark {
        background: color-mix(in srgb, var(--xm-status-success) 14%, transparent);
    }

        .xm-confirm.is-success .xm-confirm-mark .e-icons {
            color: var(--xm-status-success);
        }

    .xm-confirm.is-warning .xm-confirm-mark {
        background: var(--xm-warning-bg);
    }

        .xm-confirm.is-warning .xm-confirm-mark .e-icons {
            color: var(--xm-warning-text);
        }

    .xm-confirm.is-danger .xm-confirm-mark {
        background: color-mix(in srgb, var(--xm-danger) 12%, transparent);
    }

        .xm-confirm.is-danger .xm-confirm-mark .e-icons {
            color: var(--xm-danger);
        }

.xm-confirm-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 4px;
}

    /* with no mark, the text starts at the top edge */
    .xm-confirm > .xm-confirm-text:first-child {
        padding-top: 0;
    }

.xm-confirm-question {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--xm-text);
}

/* The facts the answer rests on: label left, value right. Rows, not a filled block. */
.xm-confirm-facts {
    margin: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 5px 14px;
    padding: 8px 0;
    border-top: 1px solid var(--xm-border-soft);
    border-bottom: 1px solid var(--xm-border-soft);
}

    .xm-confirm-facts dt {
        font-size: 12px;
        color: var(--xm-text-muted);
        white-space: nowrap;
    }

    .xm-confirm-facts dd {
        margin: 0;
        min-width: 0;
        font-size: 12px;
        font-weight: 600;
        overflow-wrap: anywhere;
    }

.xm-confirm-warning {
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--xm-text-muted);
}

/* An error's own words, folded under Show details. */
.xm-confirm-more summary {
    width: fit-content;
    font-size: 12px;
    color: var(--xm-accent-text);
    cursor: pointer;
}

.xm-confirm-more[open] summary {
    margin-bottom: 8px;
}

.xm-confirm-detail {
    max-height: 190px;
    margin: 0;
    padding: 9px 11px;
    overflow: auto;
    border: 1px solid var(--xm-border-soft);
    border-radius: 8px;
    background: var(--xm-surface-alt);
    color: var(--xm-text);
    font-family: 'Cascadia Mono', 'Consolas', monospace;
    font-size: 11.5px;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    user-select: text;
}


/* ================================================== document type
   The panes that show a document rather than the app's own chrome. Size follows the user's setting for all
   of them; the monospace family applies only where raw text is shown, since the trees read better in the
   interface font. Set by js/font.js from the signed-in user's settings. */
.xm-doc-text {
    font-family: var(--xm-doc-font);
    font-size: var(--xm-doc-size);
    line-height: 1.5;
}

/* Map tree rows. These carried the size in an inline style, which no stylesheet could override. */
.treenode-text.is-node {
    font-size: var(--xm-doc-size);
}

.treenode-text.is-detail {
    /* The trailing detail on a node reads as secondary, as it did when it was 10px against the node's 12px. */
    font-size: calc(var(--xm-doc-size) - 2px);
}


/* A pane that shows part of a document rather than the app's own chrome — the properties, validation and
   search panes under the editor trees. Syncfusion's grid sizes its own cells from site.css, and it takes
   no CssClass in this version, so the wrapper is what carries the setting down to them. */
.xm-doc-pane .e-grid .e-rowcell,
.xm-doc-pane .e-grid .e-headercelldiv,
.xm-doc-pane .e-grid .e-headertext {
    font-size: var(--xm-doc-size);
}

/* Rows have to grow with the type or the text crops at the larger sizes. The multiplier is chosen so that
   the default 12px still lands on the 22px these rows have today, rather than quietly retightening them. */
.xm-doc-pane .e-grid .e-rowcell {
    line-height: calc(var(--xm-doc-size) * 1.8);
}

/* ================================================== editor workspace
   Pages/ShowMap.razor (and the schema viewer): Controls/EditorPane, EditorSection, EditorStatusBar.
   Sizes are CSS variables that wwwroot/js/panes.js sets on the data-panes container while dividers are dragged. */
.xe-shell {
    position: relative;
    flex: 1;
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding-top: 8px;
    box-sizing: border-box;
}

.xe-work {
    flex: 1;
    min-height: 0;
    display: flex;
}

.xe-side {
    flex-shrink: 0;
    min-width: 0;
    display: flex;
}

    .xe-side.is-collapsed {
        width: 38px !important;
    }

    /*
        The test dock keeps the width it was dragged to while there is room for it, and gives way when there is not
        (a narrower window, a wider map pane): it used to keep its width regardless, and then ran past the window's
        right edge, taking the result, its own buttons and the sample's menu out of view.
    */
    .xe-side[data-tab="test"]:not(.is-collapsed) {
        flex-shrink: 1;
        min-width: 460px;
    }

.xe-center {
    flex: 1;
    min-width: 240px;
    display: flex;
}

/* ---- a pane */
.xe-pane {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    background: var(--xm-surface);
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    overflow: hidden;
}

.xe-pane-inner {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.xe-pane-head {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 8px 0 14px;
    border-bottom: 1px solid var(--xm-border-soft);
}

.xe-pane-title {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--xm-text);
    white-space: nowrap;
}

.xe-pane-sub {
    min-width: 0;
    font-size: 12px;
    color: var(--xm-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.xe-pane-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.xe-grow {
    flex: 1;
}

.xe-mono {
    font-family: var(--xm-doc-font);
}

.xe-icon-btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--xm-text-muted);
    font-size: 12px;
    cursor: pointer;
}

    .xe-icon-btn:hover,
    .xe-icon-btn:focus-visible {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

/* folded to a strip */
.xe-pane.is-collapsed {
    flex: 1;
}

.xe-pane-strip {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border: none;
    background: transparent;
    color: var(--xm-text-muted);
    cursor: pointer;
}

    .xe-pane-strip:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

.xe-pane-strip-title {
    writing-mode: vertical-rl;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .3px;
}

/* ---- content that fills a pane: something that scrolls, and optionally a section under it */
.xe-fill {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.xe-scroll {
    flex: 1;
    min-height: 0;
    overflow: auto;
}

.xe-section {
    position: relative;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-top: 1px solid var(--xm-border-soft);
}

.xe-section-head {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border: none;
    background: var(--xm-surface-alt);
    color: var(--xm-text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    cursor: pointer;
    text-align: left;
}

    .xe-section-head:hover {
        color: var(--xm-text);
    }

.xe-section-chev {
    font-size: 10px;
}

.xe-count {
    padding: 0 6px;
    border-radius: 999px;
    background: var(--xm-surface);
    letter-spacing: 0;
}

    .xe-count.is-error {
        background: color-mix(in srgb, var(--xm-danger) 14%, transparent);
        color: var(--xm-danger);
    }

    /* yellow like the validation's warning dots; the number in the theme's warning text colour, to stay readable */
    .xe-count.is-warning {
        background: color-mix(in srgb, #eab308 22%, transparent);
        color: var(--xm-warning-text);
    }

.xe-section-body {
    flex: 1;
    min-height: 0;
    overflow: auto;
}

/* ---- dividers: a hairline gap with a grip, a wide target to grab */
.xe-split,
.xe-split-h {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: none;
}

.xe-split {
    width: 8px;
    cursor: col-resize;
}

.xe-split-h {
    height: 8px;
    cursor: row-resize;
}

.xe-section > .xe-split-h {
    position: absolute;
    left: 0;
    right: 0;
    top: -5px;
    z-index: 2;
}

.xe-split > span,
.xe-split-h > span {
    border-radius: 2px;
    background: var(--xm-border);
    opacity: .55;
    transition: opacity .12s, background .12s;
}

.xe-split > span {
    width: 3px;
    height: 32px;
}

.xe-split-h > span {
    width: 32px;
    height: 3px;
}

.xe-split:hover > span,
.xe-split-h:hover > span,
.xe-split.is-dragging > span,
.xe-split-h.is-dragging > span {
    opacity: 1;
    background: var(--xm-accent);
}

.xe-gap {
    width: 8px;
    flex-shrink: 0;
}

/* ---- test: sample and result, stacked in the right-hand column or side by side full screen */
/* A grid, not flex: a percentage height on a flex child is not always resolvable, and the sample then grew to its
   content and pushed the result out of view. The divider sets the first track in px; until then the two share. */
.xe-test {
    flex: 1;
    min-height: 0;
    min-width: 0;
    display: grid;
    /* the sample's dragged width (--xe-sample-w, set by ShowMap), but never so wide that the result has no room */
    grid-template-columns: max(0px, min(var(--xe-sample-w, calc(50% - 4px)), calc(100% - 208px))) 8px minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
}

    .xe-test.is-stacked {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: var(--xe-sample-h, minmax(0, 1fr)) 8px minmax(0, 1fr);
    }

.xe-test-part {
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.xe-test-head {
    flex-shrink: 0;
    padding: 6px 12px 4px 12px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

/* The sample or result above, its validation below in a section that folds. */
.xe-stack {
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

    .xe-stack > .xe-stack-main {
        flex: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

        .xe-stack > .xe-stack-main > * {
            flex: 1;
            min-height: 0;
        }

.xe-test-body {
    position: relative;
    flex: 1;
    min-height: 0;
}

/* Fills the body with a definite size, so a child that is 100% high (the sample's and the result's own splitter,
   content over validation) is as high as the pane, not as high as its content. */
.xe-abs {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
}

    .xe-abs > * {
        flex: 1;
        min-height: 0;
    }

.xe-run {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--xm-text-muted);
}

.xe-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--xm-border);
    vertical-align: 1px;
    margin-right: 5px;
}

.xe-run .xe-dot {
    margin-right: 0;
}

.xe-dot.is-ok { background: var(--xm-status-success); }
.xe-dot.is-bad { background: var(--xm-error-text); }
.xe-dot.is-warn { background: var(--xm-warning-text); }
.xe-dot.is-open { background: var(--xm-kind-question); }

/* ---- status bar */
.xe-status {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 16px;
    height: 28px;
    margin-top: 8px;
    padding: 0 4px;
    font-size: 12px;
    color: var(--xm-text-muted);
    white-space: nowrap;
    overflow: hidden;
}

.xe-status-strong {
    color: var(--xm-text);
    font-weight: 500;
}

.xe-status-bad {
    color: var(--xm-error-text);
}

/* The open-questions count: a button that turns on that filter of the map tree. */
.xe-status-open {
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    color: var(--xm-kind-question);
    cursor: pointer;
}

    .xe-status-open:hover {
        text-decoration: underline;
    }

/* ================================================== tree rows (Controls/TreeNodeRow.razor)
   Both the map tree and the schema trees. The row's classes are also what the pane filters hide rows by. */
.srctrgtree .treeviewdiv {
    display: block;
    width: 100%;
}

.xn {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-width: 0;
    padding: 0 10px 0 2px;
    box-sizing: border-box;
    font-family: var(--xm-doc-font);
    font-size: var(--xm-doc-size);
    line-height: 1.7;
    color: var(--xm-text);
    border-radius: 4px;
}

.xn-glyph {
    flex: none;
    display: inline-flex;
    color: var(--xm-text-muted);
}

    .xn-glyph.is-record,
    .xn-glyph.is-element {
        color: var(--xm-accent);
    }

    .xn-glyph.is-array,
    .xn-glyph.is-loop,
    .xn-glyph.is-recursive {
        color: var(--xm-kind-loop);
    }

    .xn-glyph.is-link { color: var(--xm-kind-link); }
    .xn-glyph.is-function { color: var(--xm-kind-function); }
    .xn-glyph.is-constant,
    .xn-glyph.is-variable { color: var(--xm-kind-constant); }
    .xn-glyph.is-question { color: var(--xm-kind-question); }
    .xn-glyph.is-attribute { color: var(--xm-kind-source); }

.xn-name {
    white-space: nowrap;
}

.xn-content {
    min-width: 0;
    max-width: 18em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--xm-code-string);
    font-size: .92em;
}

.xn-grow {
    flex: 1;
    min-width: 10px;
}

.xn-chip {
    flex: none;
    padding: 0 7px;
    border-radius: 999px;
    font-family: 'Segoe UI', system-ui, sans-serif;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 17px;
}

    .xn-chip.is-link { color: var(--xm-kind-link); background: var(--xm-kind-link-bg); }
    .xn-chip.is-function { color: var(--xm-kind-function); background: var(--xm-kind-function-bg); }
    .xn-chip.is-constant,
    .xn-chip.is-record { color: var(--xm-kind-constant); background: var(--xm-kind-constant-bg); }
    .xn-chip.is-loop { color: var(--xm-kind-loop); background: var(--xm-kind-loop-bg); }
    .xn-chip.is-if { color: var(--xm-kind-if); background: var(--xm-kind-if-bg); }
    .xn-chip.is-question { color: var(--xm-kind-question); background: var(--xm-kind-question-bg); }

/* The open questions inside a branch, on the branch's row while it is folded. */
.xn-open-mark {
    flex: none;
    padding: 0 6px;
    border: 1px solid var(--xm-kind-question);
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 15px;
    color: var(--xm-kind-question);
}

.srctrgtree li.e-list-item[aria-expanded="true"] > .e-text-content .xn-open-mark {
    display: none;
}

.xn-card {
    flex: none;
    min-width: 28px;
    text-align: right;
    font-size: 11px;
    color: var(--xm-text-muted);
}

.xn-used-mark {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: 11px;
    color: var(--xm-accent-text);
}

.xn-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    box-sizing: border-box;
}

    .xn-dot.is-problem { background: var(--xm-error-text); }
    .xn-dot.is-problem-below { border: 1.5px solid var(--xm-error-text); }
    .xn-dot.is-open { background: var(--xm-kind-question); }
    .xn-dot.is-open-below { border: 1.5px solid var(--xm-kind-question); }
    .xn-dot.is-reference { background: var(--xm-status-success); }
    .xn-dot.is-unmapped { border: 1.5px solid var(--xm-border); }
    .xn-dot.is-none { visibility: hidden; }

.xn.xn-unmapped .xn-name {
    color: var(--xm-text-muted);
    font-style: italic;
}

/* The source fields the selected map node reads. */
.xn.is-read {
    background: var(--xm-kind-source-bg);
    box-shadow: inset 3px 0 0 var(--xm-highlight);
}

    .xn.is-read .xn-name {
        font-weight: 600;
    }

/* ---- the tree around the rows: hover, the selected row, indent guides */
.srctrgtree .e-list-item > .e-fullrow {
    border: none;
}

.srctrgtree .e-list-item.e-hover > .e-fullrow {
    background: var(--xm-surface-hover);
}

.srctrgtree .e-list-item.e-active > .e-fullrow {
    background: var(--xm-selection);
    box-shadow: inset 3px 0 0 var(--xm-accent);
}

.srctrgtree .e-list-item.e-active > .e-text-content .e-list-text,
.srctrgtree .e-list-item.e-active > .e-text-content .xn {
    color: var(--xm-text);
}

    .srctrgtree .e-list-item.e-active > .e-text-content .xn-name {
        font-weight: 600;
    }

/* A hairline down the side of every open branch, so depth can be followed by eye. */
.srctrgtree .e-list-item > .e-ul {
    background-image: linear-gradient(var(--xm-border-soft), var(--xm-border-soft));
    background-size: 1px 100%;
    background-repeat: no-repeat;
    background-position: 12px 0;
}

/* ---- drag and drop: where it will land, and the node being carried */
.srctrgtree .e-sibling {
    border-top: 2px solid var(--xm-accent) !important;
}

.srctrgtree .e-list-item.e-drop-in > .e-fullrow {
    background: color-mix(in srgb, var(--xm-accent) 14%, transparent);
    box-shadow: inset 0 0 0 1px var(--xm-accent);
}

.e-drag-item.srctrgtree,
.e-drag-item {
    border: 1px solid var(--xm-border-soft) !important;
    border-radius: 8px !important;
    background: var(--xm-surface) !important;
    color: var(--xm-text) !important;
    box-shadow: 0 6px 20px var(--xm-shadow) !important;
    font-family: var(--xm-doc-font);
}

/* ---- pane filters: rows are hidden, not removed, and a branch stays when anything below it matches */
/* The selected row, and the branch it is in, always stay: mapping a field under "Not mapped" must not make the
   node just made (and selected) disappear from under the pointer. */
.xe-filter-map-problems .srctrgtree li.e-list-item:not(:has(.xn-problem, .xn-problem-below)):not(.e-active):not(:has(.e-active)),
.xe-filter-map-open .srctrgtree li.e-list-item:not(:has(.xn-open, .xn-open-below)):not(.e-active):not(:has(.e-active)),
.xe-filter-map-unmapped .srctrgtree li.e-list-item:not(:has(.xn-unmapped, .xn-unmapped-below)):not(.e-active):not(:has(.e-active)),
.xe-filter-src-used .srctrgtree li.e-list-item:not(:has(.xn-used, .xn-used-below)):not(.e-active):not(:has(.e-active)),
.xe-filter-src-unused .srctrgtree li.e-list-item:not(:has(.xn-unused, .xn-group)):not(.e-active):not(:has(.e-active)) {
    display: none;
}

/* ---- the chips that set those filters, in a pane's toolbar row */
.xe-pane-tools {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    padding: 7px 10px 7px 14px;
    border-bottom: 1px solid var(--xm-border-soft);
}

.xe-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    padding: 0 10px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 999px;
    background: transparent;
    color: var(--xm-text-muted);
    font-size: 12px;
    cursor: pointer;
}

    .xe-chip:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

    .xe-chip.is-on {
        border-color: var(--xm-accent);
        background: var(--xm-selection);
        color: var(--xm-accent-text);
        font-weight: 500;
    }

.xe-chip-count {
    opacity: .75;
    font-size: 11px;
}

.xe-chips {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

/* ================================================== inspector (Controls/NodeInspector.razor) */
.xi {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 12px 16px 18px 16px;
    color: var(--xm-text);
    /* the full height of the pane, so the foot (field facts, lineage) can sit at its bottom */
    box-sizing: border-box;
    min-height: 100%;
}

    /* the inspector's blocks keep their own height; the pane scrolls when they do not fit */
    .xi > * {
        flex-shrink: 0;
    }

/* pushed to the bottom of the pane while the editors stay at the top; follows them when they fill it */
.xi-foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

    .xi-foot > .xi-lineage {
        margin-top: 0;
    }

/* The inspector in one typeface: the document font the paths and the node's name are set in (the reader's own
   choice, see Controls/UserSettingsDialog), for the labels, links, pickers and inputs as well. Mixed with the
   interface font, a row read as two different kinds of thing. */
.xi,
.xi button,
.xi input,
.xi textarea,
.xi select,
.xi .e-input,
.xi .e-control,
.xi .e-list-text,
.xi .e-ddl .e-input-value,
.xi .e-checkbox-wrapper .e-label {
    font-family: var(--xm-doc-font);
}

.xi-empty {
    margin: 40px auto;
    max-width: 380px;
    text-align: center;
    color: var(--xm-text-muted);
    font-size: 13px;
    line-height: 1.55;
}

.xi-empty-title {
    margin-bottom: 6px;
    color: var(--xm-text);
    font-size: 14px;
    font-weight: 600;
}

.xi-empty p {
    margin: 0 0 4px 0;
}

.xi-crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    font-family: var(--xm-doc-font);
    font-size: 12px;
    color: var(--xm-text-muted);
}

.xi-crumb {
    padding: 2px 5px;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--xm-text-muted);
    font: inherit;
    cursor: pointer;
}

    .xi-crumb:hover:not(:disabled) {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

    .xi-crumb.is-last {
        color: var(--xm-text);
        font-weight: 600;
        cursor: default;
    }

.xi-crumb-sep {
    color: var(--xm-border);
}

.xi-copy {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 9px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text-muted);
    font-size: 12px;
    cursor: pointer;
}

    .xi-copy:hover {
        color: var(--xm-text);
        background: var(--xm-surface-hover);
    }

.xi-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    /* pinned to the top of the pane while the editors scroll under it */
    position: sticky;
    top: 0;
    z-index: 3;
    margin: -12px -16px 0 -16px;
    padding: 12px 16px 10px 16px;
    border-bottom: 1px solid var(--xm-border-soft);
    background: var(--xm-surface);
}

.xi-name {
    font-family: var(--xm-doc-font);
    font-size: 19px;
    font-weight: 500;
}

.xi-meta {
    padding: 1px 9px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 999px;
    color: var(--xm-text-muted);
    font-size: 12px;
}

.xi-problems {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px;
    border: 1px solid var(--xm-error-border);
    border-radius: 8px;
    background: var(--xm-error-bg);
    font-size: 13px;
}

.xi-problem {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: var(--xm-text);
}

    .xi-problem .e-icons {
        margin-top: 2px;
        color: var(--xm-error-text);
        font-size: 13px;
    }

/* A Question* node: a to-do, not an error. */
.xi-open {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--xm-warning-text);
    border-radius: 8px;
    background: var(--xm-warning-bg);
    color: var(--xm-text);
    font-size: 13px;
}

    .xi-open .e-icons {
        margin-top: 2px;
        color: var(--xm-warning-text);
        font-size: 13px;
    }

.xi-hint {
    margin: 0;
    padding: 10px 12px;
    border: 1px dashed var(--xm-border);
    border-radius: 8px;
    color: var(--xm-text-muted);
    font-size: 13px;
}

/* ---- the node's editors (TrgComponent), on the pane's own surface: sections, not cards */
.xi-body {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    gap: 16px;
    min-width: 0;
}

/* No scrolling of its own: a section that scrolled sideways cut its last rows off under its scrollbar (the value
   trees size themselves after they draw). A wide function tree scrolls the whole inspector pane instead. */
.xi-sec {
    flex-shrink: 0;
    min-width: 0;
}

    .xi-sec:empty {
        display: none;
    }

.xi-sec-title {
    margin: 0 0 6px 0;
    color: var(--xm-text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
}

/* a section's title with an action at its end (the design note's Remove) */
.xi-sec-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

    .xi-sec-head .xi-sec-title {
        margin: 0;
    }

.xi-sec-remove {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 7px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--xm-text-muted);
    font-size: 11.5px;
    cursor: pointer;
}

    .xi-sec-remove .e-icons {
        font-size: 11px;
    }

    .xi-sec-remove:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-danger);
    }

    .xi-sec-remove:focus-visible {
        outline: 2px solid var(--xm-accent);
        outline-offset: 1px;
    }

.xi-label {
    flex: none;
    color: var(--xm-text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
}

/* where the value comes from: a labelled switch, the node's first decision */
.xi-source-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
}

.xi-seg {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 8px;
    background: var(--xm-surface-alt);
}

.xi-seg-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 10px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--xm-text-muted);
    font-size: 12px;
    white-space: nowrap;
    cursor: pointer;
}

    .xi-seg-btn:hover:not(.is-on) {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

    .xi-seg-btn.is-on {
        background: var(--xm-surface);
        color: var(--xm-text);
        font-weight: 600;
        box-shadow: 0 1px 2px var(--xm-shadow), 0 0 0 1px var(--xm-border-soft);
    }

    .xi-seg-btn:focus-visible {
        outline: 2px solid color-mix(in srgb, var(--xm-accent) 55%, transparent);
        outline-offset: 1px;
    }

    /* icons only (user setting): a square button around the icon */
    .xi-seg-btn.is-icon {
        padding: 0 7px;
    }

.xi-seg-icon {
    width: 13px;
    height: 13px;
    opacity: .75;
}

.xi-seg-btn.is-on .xi-seg-icon {
    opacity: 1;
}

/* what the node does not have yet: a quiet row of links */
.xi-adds {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
}

.xi-add {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 0;
    border: none;
    background: transparent;
    color: var(--xm-accent-text);
    font-size: 12.5px;
    cursor: pointer;
}

    .xi-add .e-icons {
        font-size: 11px;
    }

    .xi-add:hover {
        text-decoration: underline;
    }

/* the node's options, as switches */
.xi-options {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 16px;
    padding-top: 12px;
    border-top: 1px solid var(--xm-border-soft);
}

.xi-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    cursor: pointer;
    user-select: none;
}

    .xi-toggle input {
        position: absolute;
        opacity: 0;
        width: 1px;
        height: 1px;
    }

.xi-toggle-track {
    position: relative;
    width: 30px;
    height: 17px;
    flex: none;
    border-radius: 999px;
    background: var(--xm-border);
    transition: background .15s ease;
}

    .xi-toggle-track::after {
        content: "";
        position: absolute;
        top: 2px;
        left: 2px;
        width: 13px;
        height: 13px;
        border-radius: 50%;
        background: #fff;
        box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
        transition: transform .15s ease;
    }

.xi-toggle input:checked + .xi-toggle-track {
    background: var(--xm-accent);
}

    .xi-toggle input:checked + .xi-toggle-track::after {
        transform: translateX(13px);
    }

.xi-toggle input:focus-visible + .xi-toggle-track {
    outline: 2px solid color-mix(in srgb, var(--xm-accent) 55%, transparent);
    outline-offset: 2px;
}

.xi-facts {
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    overflow: hidden;
}

    .xi-facts > summary {
        padding: 8px 12px;
        background: var(--xm-surface-alt);
        color: var(--xm-text-muted);
        font-size: 11px;
        font-weight: 600;
        letter-spacing: .5px;
        text-transform: uppercase;
        cursor: pointer;
    }

.xi-kv {
    display: grid;
    grid-template-columns: minmax(90px, max-content) minmax(0, 1fr);
    margin: 0;
    font-size: 13px;
}

    .xi-kv dt,
    .xi-kv dd {
        margin: 0;
        padding: 6px 12px;
        border-top: 1px solid var(--xm-border-soft);
    }

    .xi-kv dt {
        color: var(--xm-text-muted);
    }

    .xi-kv dd {
        font-family: var(--xm-doc-font);
        font-size: 12.5px;
        overflow-wrap: anywhere;
    }

/* ================================================== search panel (Controls/SearchPanel.razor) */
.xs-backdrop {
    position: fixed;
    inset: 0;
    z-index: 8000;
    background: color-mix(in srgb, var(--xm-text) 18%, transparent);
}

.xs {
    position: fixed;
    top: 88px;
    left: 50%;
    z-index: 8001;
    width: min(680px, calc(100vw - 32px));
    max-height: calc(100vh - 140px);
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    border: 1px solid var(--xm-border-soft);
    border-radius: 12px;
    background: var(--xm-surface);
    color: var(--xm-text);
    box-shadow: 0 24px 60px var(--xm-shadow);
    overflow: hidden;
}

.xs-input-row {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--xm-border-soft);
}

.xs-input-icon {
    color: var(--xm-text-muted);
    font-size: 15px;
}

.xs-input {
    flex: 1;
    min-width: 0;
    border: none;
    outline: none;
    background: transparent;
    color: var(--xm-text);
    font-size: 15px;
}

.xs-esc {
    padding: 2px 7px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 5px;
    background: var(--xm-surface-alt);
    color: var(--xm-text-muted);
    font-size: 11px;
    cursor: pointer;
}

.xs-scopes {
    flex-shrink: 0;
    display: flex;
    gap: 6px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--xm-border-soft);
}

.xs-results {
    flex: 1;
    min-height: 60px;
    overflow: auto;
    padding: 4px 0 8px 0;
}

.xs-group {
    padding: 10px 16px 4px 16px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

.xs-hit {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 16px;
    border: none;
    background: transparent;
    color: var(--xm-text);
    text-align: left;
    cursor: pointer;
}

    .xs-hit.is-active {
        background: var(--xm-selection);
        box-shadow: inset 3px 0 0 var(--xm-accent);
    }

.xs-hit-name {
    flex: none;
    font-family: var(--xm-doc-font);
    font-size: 13px;
    font-weight: 500;
}

.xs-hit-path {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    direction: rtl; /* a long path keeps its end, where the name is, in view */
    text-align: right;
    font-family: var(--xm-doc-font);
    font-size: 11.5px;
    color: var(--xm-text-muted);
}

.xs-empty {
    padding: 18px 16px;
    color: var(--xm-text-muted);
    font-size: 13px;
}

.xs-foot {
    flex-shrink: 0;
    display: flex;
    gap: 16px;
    padding: 8px 16px;
    border-top: 1px solid var(--xm-border-soft);
    background: var(--xm-surface-alt);
    color: var(--xm-text-muted);
    font-size: 11px;
}

/* the button that opens it, in the editors' pane title bars and ribbons */
.xs-open {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 28px;
    padding: 0 10px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 7px;
    background: var(--xm-surface-alt);
    color: var(--xm-text-muted);
    font-size: 12px;
    cursor: pointer;
}

    .xs-open:hover {
        color: var(--xm-text);
        background: var(--xm-surface-hover);
    }

.xs-kbd {
    padding: 0 5px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 4px;
    background: var(--xm-surface);
    font-size: 10.5px;
}

/* the schema's own documentation for an element, in the schema inspector */
.xi-doc {
    margin: 0;
    padding: 10px 12px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 8px;
    background: var(--xm-surface-alt);
    color: var(--xm-text);
    font-size: 13px;
    line-height: 1.55;
    white-space: pre-wrap;
}

/* ================================================== validation badges in the test pane's title bar */
.xv-badges {
    display: inline-flex;
    gap: 6px;
}

.xv-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    padding: 0 9px;
    border: none;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}

    .xv-badge .e-icons {
        font-size: 11px;
    }

    .xv-badge.is-ok {
        background: color-mix(in srgb, var(--xm-status-success) 16%, transparent);
        color: var(--xm-text);
    }

        .xv-badge.is-ok .e-icons { color: var(--xm-status-success); }

    .xv-badge.is-warning {
        background: var(--xm-kind-if-bg);
        color: var(--xm-kind-if);
    }

    .xv-badge.is-error {
        background: var(--xm-error-bg);
        color: var(--xm-error-text);
    }

/* ================================================== narrow windows: the panes become tabs
   Below 1280px there is no room for three or four panes side by side. The tab strip appears, only the chosen pane
   is shown at full width, and the dividers go. Wide screens never see any of it. */
.xe-tabs {
    display: none;
}

@media (max-width: 1279px) {
    .xe-tabs {
        flex-shrink: 0;
        display: flex;
        gap: 2px;
        margin-bottom: 8px;
        border-bottom: 1px solid var(--xm-border-soft);
    }

    .xe-work > .xe-split,
    .xe-work > .xe-gap {
        display: none;
    }

    .xe-work > [data-tab]:not(.is-tab-on) {
        display: none;
    }

    .xe-work > [data-tab].is-tab-on {
        flex: 1;
        width: auto !important;
    }
}

.xe-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 36px;
    padding: 0 14px;
    border: none;
    background: transparent;
    color: var(--xm-text-muted);
    font-size: 13px;
    cursor: pointer;
}

    .xe-tab:hover {
        color: var(--xm-text);
    }

    .xe-tab.is-on {
        color: var(--xm-text);
        font-weight: 600;
        box-shadow: inset 0 -2px 0 var(--xm-accent);
    }

/* ================================================== command bar (Controls/MapRibbonComponent, SchemaRibbonComponent)
   One slim row where the ribbon was: the document on the left, its commands on the right. */
.xc-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 50px;
    padding: 6px 16px;
    border-bottom: 1px solid var(--xm-border-soft);
    background: var(--xm-surface);
    color: var(--xm-text);
    box-sizing: border-box;
}

.xc-back,
.xc-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--xm-text-muted);
    cursor: pointer;
}

    .xc-back:hover,
    .xc-icon:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

.xc-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 8px;
    min-width: 0;
}

.xc-name {
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
}

.xc-chip {
    padding: 1px 8px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 999px;
    color: var(--xm-text-muted);
    font-size: 12px;
    white-space: nowrap;
}

    .xc-chip.is-accent {
        border-color: transparent;
        background: var(--xm-kind-link-bg);
        color: var(--xm-kind-link);
        font-weight: 600;
        font-size: 11px;
    }

.xc-unsaved {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--xm-unsaved-dot);
    font-size: 12px;
    font-weight: 600;
}

    .xc-unsaved::before {
        content: "";
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: var(--xm-unsaved-dot);
    }

.xc-sub {
    color: var(--xm-text-muted);
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.xc-actions {
    flex: none;
    display: flex;
    align-items: center;
    gap: 6px;
}

.xc-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 8px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
}

    .xc-btn:hover:not(:disabled),
    .xc-btn.is-open {
        background: var(--xm-surface-hover);
    }

    .xc-btn:disabled {
        opacity: .5;
        cursor: default;
    }

    .xc-btn .e-icons {
        font-size: 13px;
    }

    .xc-btn.is-primary {
        border-color: var(--xm-accent);
        background: var(--xm-accent);
        color: #fff;
        font-weight: 500;
    }

        .xc-btn.is-primary:hover {
            background: var(--xm-accent-hover);
        }

        /* Unsaved: the button you need to press says so, without taking any width of its own. */
        .xc-btn.is-primary.is-unsaved {
            box-shadow: 0 0 0 2px color-mix(in srgb, var(--xm-unsaved-dot) 55%, transparent);
        }

.xc-caret {
    font-size: 10px !important;
    opacity: .7;
}

/* ---- the menus */
.xc-menu-wrap {
    position: relative;
    display: inline-flex;
}

.xc-backdrop {
    position: fixed;
    inset: 0;
    z-index: 8400;
}

.xc-pop {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 8500;
    display: flex;
    flex-direction: column;
    min-width: 230px;
    max-height: min(560px, calc(100vh - 140px));
    overflow: auto;
    padding: 6px 0;
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    background: var(--xm-surface);
    box-shadow: 0 12px 32px var(--xm-shadow);
}

    .xc-pop.is-left {
        right: auto;
        left: 0;
    }

    /* opened where it was clicked (CommandMenu AtPointer): fixed, so no scrolling box around it can cut it off */
    .xc-pop.is-at-pointer {
        position: fixed;
        right: auto;
        min-width: 190px;
    }

.xc-head {
    padding: 8px 14px 4px 14px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

    .xc-head:first-child {
        padding-top: 4px;
    }

.xc-sep {
    height: 1px;
    margin: 5px 0;
    background: var(--xm-border-soft);
}

.xc-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 14px;
    border: none;
    background: transparent;
    color: var(--xm-text);
    font-size: 13px;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

    .xc-item:hover:not(:disabled) {
        background: var(--xm-surface-hover);
    }

    .xc-item:disabled {
        opacity: .5;
        cursor: default;
    }

    .xc-item .e-icons {
        width: 14px;
        font-size: 13px;
        color: var(--xm-text-muted);
    }

    /* an icon the font has not, drawn: as wide and as muted as the font's */
    .xc-item .xc-icon-svg {
        flex: none;
        width: 14px;
        height: 14px;
        fill: none;
        stroke: var(--xm-text-muted);
        stroke-width: 1.8;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

/* a menu row that opens in place onto child rows (the New menu's Schema ▸ XML, JSON, CSV) */
.xc-parent .xc-parent-caret {
    margin-left: auto;
    width: auto;
    font-size: 10px;
    transition: transform .15s ease;
}

.xc-parent[aria-expanded="true"] .xc-parent-caret {
    transform: rotate(90deg);
}

.xc-item.xc-child {
    padding-left: 38px;
}

/* A row with a flyout beside the menu (NewMenu's Schema): the caret points at it, and the row stays lit while it is open. */
.xc-flyout-parent[aria-expanded="true"] .xc-parent-caret {
    transform: none;
}

.xc-flyout-parent.is-open {
    background: var(--xm-surface-hover);
}

/* The flyout: fixed where its row is on screen, so the menu's scrolling cannot cut it off. */
.xc-pop.xc-flyout {
    position: fixed;
    right: auto;
    max-height: none;
    z-index: 8600;
}

/* a menu row that is a setting: a check when on, the same room when off */
.xc-blank::before {
    content: "";
}

/* the sample's and the result's heading carries its menu */
.xe-test-head {
    display: flex;
    align-items: center;
    padding: 2px 6px 0 12px;
}

/* an empty document pane: says what would be there */
.xe-empty-note {
    padding: 24px 16px;
    color: var(--xm-text-muted);
    font-size: 13px;
    text-align: center;
}

/* the map editor while it opens: over the whole editor until the first sample is settled (Pages/ShowMap.razor) */
.xe-startup {
    position: absolute;
    inset: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: color-mix(in srgb, var(--xm-surface) 78%, transparent);
    backdrop-filter: blur(1px);
    color: var(--xm-text-muted);
    font-size: 13px;
}

/* ================================================== context menus (Controls/ContextMenuComponent.razor)
   Right-click menus drawn like the ⋯ menus (.xc-pop / .xc-item): a soft card, 13px sentence-case rows with an icon
   column, a hover tint, a hairline between groups. Syncfusion's own theme drew them as a flat grey list. */
.e-contextmenu-wrapper ul.e-contextmenu,
.e-contextmenu-container ul.e-contextmenu {
    min-width: 210px;
    padding: 6px 0;
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    background: var(--xm-surface);
    box-shadow: 0 12px 32px var(--xm-shadow);
    font-family: inherit;
}

    .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item,
    .e-contextmenu-container ul.e-contextmenu .e-menu-item {
        display: flex;
        align-items: center;
        height: auto;
        min-height: 32px;
        padding: 0 14px;
        line-height: normal;
        background: transparent;
        color: var(--xm-text);
        font-size: 13px;
    }

        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-focused,
        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-selected,
        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item:hover,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-focused,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-selected,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-disabled,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-disabled {
            opacity: .5;
        }

        /* Items a menu hides for this node (Delete on a source field, Map on a mapped node) stay hidden: the
           display above would otherwise beat Syncfusion's own rule for them. */
        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-menu-hide,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-menu-hide {
            display: none;
        }

        /* an item with a sub-menu: room for the arrow at the end */
        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-menu-caret-icon,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-menu-caret-icon {
            padding-right: 32px;
        }

        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item .e-caret,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item .e-caret {
            right: 10px;
            color: var(--xm-text-muted);
            font-size: 11px;
        }

        .e-contextmenu-wrapper ul.e-contextmenu .e-menu-item.e-separator,
        .e-contextmenu-container ul.e-contextmenu .e-menu-item.e-separator {
            min-height: 0;
            height: 1px;
            margin: 5px 0;
            padding: 0;
            background: var(--xm-border-soft);
        }

/* Sub-menus (Paste's list of copies): Syncfusion draws them as their own list, which the rules above, written
   for the menu itself, did not reach; it kept the theme's heavy grey box. The same card and rows here. */
.e-contextmenu-wrapper ul:not(.e-contextmenu),
.e-contextmenu-container ul:not(.e-contextmenu) {
    min-width: 260px;
    max-width: 460px;
    max-height: 60vh;
    padding: 6px 0;
    overflow-y: auto;
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    background: var(--xm-surface);
    box-shadow: 0 12px 32px var(--xm-shadow);
    font-family: inherit;
}

    .e-contextmenu-wrapper ul:not(.e-contextmenu) .e-menu-item,
    .e-contextmenu-container ul:not(.e-contextmenu) .e-menu-item {
        display: flex;
        align-items: center;
        height: auto;
        min-height: 32px;
        padding: 6px 14px;
        line-height: normal;
        background: transparent;
        color: var(--xm-text);
        font-size: 13px;
    }

        .e-contextmenu-wrapper ul:not(.e-contextmenu) .e-menu-item.e-focused,
        .e-contextmenu-wrapper ul:not(.e-contextmenu) .e-menu-item.e-selected,
        .e-contextmenu-wrapper ul:not(.e-contextmenu) .e-menu-item:hover,
        .e-contextmenu-container ul:not(.e-contextmenu) .e-menu-item.e-focused,
        .e-contextmenu-container ul:not(.e-contextmenu) .e-menu-item.e-selected,
        .e-contextmenu-container ul:not(.e-contextmenu) .e-menu-item:hover {
            background: var(--xm-surface-hover);
            color: var(--xm-text);
        }

/* a copy in the Paste list: its name, and what it uses and when it was copied under it */
.xm-paste {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
    white-space: normal;
}

.xm-paste-top {
    display: flex;
    align-items: baseline;
    gap: 12px;
}

.xm-paste-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    color: var(--xm-text);
    font-size: 13px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* when it was copied: set apart from the name, and written like the detail under it */
.xm-paste-time {
    flex: none;
    margin-left: auto;
    padding-left: 14px;
    color: var(--xm-text-muted);
    font-family: var(--xm-doc-font);
    font-size: 11.5px;
    line-height: 1.4;
}

/* what it uses: up to two lines, then cut; the whole list is in its tooltip */
.xm-paste-detail {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    color: var(--xm-text-muted);
    font-family: var(--xm-doc-font);
    font-size: 11.5px;
    line-height: 1.4;
    overflow-wrap: anywhere;
}

/* the value tree's icons (images/svg) in a menu's icon column; dark theme lightens them as it does the <img> ones */
.xm-ctx-svg {
    display: inline-block;
    width: 15px;
    height: 15px;
    background: center / contain no-repeat;
}

    .xm-ctx-svg.is-condition { background-image: url("../images/svg/question.svg"); }
    .xm-ctx-svg.is-function { background-image: url("../images/svg/function.svg"); }
    .xm-ctx-svg.is-path { background-image: url("../images/svg/link.svg"); }
    .xm-ctx-svg.is-constant { background-image: url("../images/svg/constant.svg"); }
    .xm-ctx-svg.is-variable { background-image: url("../images/svg/variable.svg"); }

[data-theme="dark"] .xm-ctx-svg {
    filter: invert(0.9);
}

.xm-ctx-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    white-space: nowrap;
}

/* the label takes the row's remaining width, so a long one (a copy in Paste) wraps inside the menu's width */
.xm-ctx-text {
    flex: 1;
    min-width: 0;
}

.xm-ctx-icon {
    flex: none;
    width: 14px;
    font-size: 13px;
    text-align: center;
    color: var(--xm-text-muted);
}

/* ================================================== quick picker (Controls/TypePicker.razor)
   A map function, a condition, or an object to insert: a card beside the click, in the menus' style. */
/* Opened from inside a modal dialog, a picker has to be in the dialog's content (GitPromoteComponent): a modal
   Syncfusion dialog is lifted into its own layer, which no z-index outside it reaches. */
.tp-backdrop {
    position: fixed;
    inset: 0;
    z-index: 8900;
}

.tp {
    position: fixed;
    z-index: 9000;
    display: flex;
    flex-direction: column;
    width: 380px;
    max-width: calc(100vw - 16px);
    max-height: min(460px, calc(100vh - 16px));
    border: 1px solid var(--xm-border-soft);
    border-radius: 12px;
    background: var(--xm-surface);
    color: var(--xm-text);
    box-shadow: var(--xm-dialog-shadow, 0 16px 40px rgba(15, 23, 42, .14));
    overflow: hidden;
    animation: tp-in .12s ease-out;
}

@keyframes tp-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

.tp.is-above {
    animation-name: tp-in-above;
}

@keyframes tp-in-above {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

.tp-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 14px 6px 14px;
}

.tp-title {
    font-size: 13.5px;
    font-weight: 600;
}

.tp-sub {
    font-size: 12px;
    color: var(--xm-text-muted);
}

.tp-search {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 12px 8px 12px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--xm-control-border);
    border-radius: 8px;
    background: var(--xm-surface);
}

    .tp-search:focus-within {
        border-color: var(--xm-accent);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--xm-accent) 18%, transparent);
    }

    .tp-search .e-icons {
        font-size: 12px;
        color: var(--xm-text-muted);
    }

    .tp-search input {
        flex: 1;
        min-width: 0;
        border: none;
        outline: none;
        background: transparent;
        color: var(--xm-text);
        font-size: 13px;
    }

.tp-list {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: 0 6px 6px 6px;
}

.tp-group {
    padding: 10px 8px 4px 8px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

.tp-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 6px 8px;
    border: none;
    border-radius: 7px;
    background: transparent;
    color: var(--xm-text);
    text-align: left;
    cursor: pointer;
}

    .tp-item:hover {
        background: var(--xm-surface-hover);
    }

    .tp-item.is-active {
        background: var(--xm-selection);
        box-shadow: inset 2px 0 0 var(--xm-accent);
    }

.tp-icon {
    width: 14px;
    height: 14px;
    flex: none;
}

.tp-text {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.tp-name {
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

    .tp-name mark {
        padding: 0;
        border-radius: 2px;
        background: color-mix(in srgb, var(--xm-highlight) 35%, transparent);
        color: inherit;
        font-weight: 600;
    }

.tp-item.is-current .tp-name {
    font-weight: 600;
}

.tp-detail {
    font-size: 11.5px;
    color: var(--xm-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tp-check {
    flex: none;
    font-size: 12px;
    color: var(--xm-accent-text);
}

.tp-empty {
    padding: 22px 10px;
    text-align: center;
    font-size: 12.5px;
    color: var(--xm-text-muted);
}

.tp-foot {
    display: flex;
    gap: 14px;
    padding: 7px 14px;
    border-top: 1px solid var(--xm-border-soft);
    font-size: 11px;
    color: var(--xm-text-muted);
}

    .tp-foot kbd {
        display: inline-block;
        min-width: 16px;
        margin-right: 3px;
        padding: 0 4px;
        border: 1px solid var(--xm-border-soft);
        border-radius: 4px;
        background: var(--xm-surface-alt);
        font-family: inherit;
        font-size: 10.5px;
        text-align: center;
    }

/* ================================================== value editors: the value-type picker and a set condition
   (SrcBtnGroupComponent, IfFunctionComponent): a soft pill with the icon and the name, a menu or picker behind it */
/* the picker's button: the type's icon and name, quiet until hovered */
.xs-type-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 8px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-size: 12px;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
}

    .xs-type-btn:hover,
    .xs-type-btn.is-open {
        background: var(--xm-surface-hover);
    }

    .xs-type-btn .xc-caret {
        font-size: 9px !important;
    }

.xs-type-icon {
    width: 13px;
    height: 13px;
    flex: none;
}

.xs-type-name {
    flex: 1;
}

.xs-type-check {
    margin-left: 12px;
    font-size: 12px;
    color: var(--xm-accent-text);
}

.xs-cond {
    font-weight: 500;
}

/* ==========================================================================================================
   List editors: a parameter that holds several values (Controls/SrcComponents: CollectionComponent,
   DictionaryComponent, NamespaceManagerComponent). In the row, the values as chips that open the editor; the
   editor is the Metadata dialog's layout: a text box per value, a remove button, and Add. The columns are set per
   editor with --xle-cols on .xle-list.
   ========================================================================================================== */

/* ---- in the row */
.xle-trigger {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
    min-height: 26px;
    padding: 2px 6px;
    border: 1px solid var(--xm-border-soft);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-size: 12px;
    text-align: left;
    vertical-align: middle;
    cursor: pointer;
}

    .xle-trigger:hover {
        background: var(--xm-surface-hover);
    }

    .xle-trigger:focus-visible {
        outline: 2px solid var(--xm-accent);
        outline-offset: 1px;
    }

.xle-chip {
    max-width: 160px;
    padding: 1px 7px;
    overflow: hidden;
    border-radius: 999px;
    background: color-mix(in srgb, var(--xm-accent) 10%, transparent);
    color: var(--xm-accent-text);
    font-family: var(--xm-doc-font);
    text-overflow: ellipsis;
    white-space: nowrap;
}

    .xle-chip .xle-arrow {
        margin: 0 3px;
        color: var(--xm-text-muted);
    }

.xle-more {
    color: var(--xm-text-muted);
    font-size: 11.5px;
}

.xle-none {
    color: var(--xm-text-muted);
    font-style: italic;
}

.xle-edit {
    margin-left: 2px;
    font-size: 11px !important;
    color: var(--xm-text-muted);
}

/* ---- the editor */
.xle {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 4px 2px 8px 2px;
    color: var(--xm-text);
}

.xle-lead {
    margin: 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--xm-text-muted);
}

.xle-list {
    --xle-cols: 22px 1fr 32px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 52vh;
    overflow-y: auto;
    padding-right: 2px;
}

.xle-head,
.xle-row {
    display: grid;
    grid-template-columns: var(--xle-cols);
    gap: 8px;
    align-items: center;
}

.xle-head {
    padding: 0 2px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

.xle-index {
    font-size: 11px;
    text-align: right;
    color: var(--xm-text-muted);
    font-variant-numeric: tabular-nums;
}

.xle-arrow-col {
    text-align: center;
    color: var(--xm-text-muted);
}

.xle-input {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    height: 32px;
    padding: 0 9px;
    border: 1px solid var(--xm-control-border);
    border-radius: 7px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-family: var(--xm-doc-font);
    font-size: 12.5px;
    outline: none;
}

    .xle-input:focus {
        border-color: var(--xm-accent);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--xm-accent) 18%, transparent);
    }

    .xle-input.is-warn {
        border-color: var(--xm-warning-text);
    }

    .xle-input.is-bad {
        border-color: var(--xm-danger);
    }

.xle-note {
    margin-top: -2px;
    padding-left: 2px;
    font-size: 11.5px;
    color: var(--xm-warning-text);
}

    .xle-note.is-bad {
        color: var(--xm-danger);
    }

    .xle-note.is-indented {
        padding-left: 30px;
    }

.xle-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid transparent;
    border-radius: 7px;
    background: transparent;
    color: var(--xm-text-muted);
    cursor: pointer;
}

    .xle-remove:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-danger);
    }

.xle-add {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 11px;
    border: 1px dashed var(--xm-control-border);
    border-radius: 8px;
    background: transparent;
    color: var(--xm-text);
    font-size: 12.5px;
    cursor: pointer;
}

    .xle-add.is-indented {
        margin-left: 30px;
    }

    .xle-add:hover {
        background: var(--xm-surface-hover);
        border-style: solid;
    }

.xle-empty {
    padding: 18px 12px;
    border: 1px dashed var(--xm-border-soft);
    border-radius: 10px;
    text-align: center;
    color: var(--xm-text-muted);
}

.xle-empty-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--xm-text);
}

.xle-empty p {
    margin: 3px 0 0 0;
    font-size: 12px;
}

@media (max-width: 720px) {
    .xle-dialog.e-dialog {
        width: 94vw !important;
    }
}

/* ==========================================================================================================
   Inline value editors in the inspector's value tree (Controls/SrcComponents): plain inputs, the "null" toggle,
   the true/false switch, and the picker buttons (formats, time zones, enum members, variables). They replace
   Syncfusion text boxes, checkboxes, combo boxes and drop-down lists, and share one height, border and focus ring.
   ========================================================================================================== */

.xv-row {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    max-width: 100%;
    vertical-align: middle;
}

.xv-input {
    width: 220px;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    height: 28px;
    padding: 0 8px;
    border: 1px solid var(--xm-control-border);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-family: var(--xm-doc-font);
    font-size: 12.5px;
    outline: none;
    vertical-align: middle;
}

    .xv-input:focus {
        border-color: var(--xm-accent);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--xm-accent) 18%, transparent);
    }

    .xv-input::placeholder {
        color: var(--xm-text-muted);
        font-style: italic;
    }

    .xv-input:disabled {
        background: var(--xm-surface-hover);
        cursor: default;
    }

    .xv-input.is-char {
        width: 36px;
        padding: 0;
        text-align: center;
    }

    .xv-input.is-int {
        width: 110px;
        font-variant-numeric: tabular-nums;
    }

    .xv-input.is-bad {
        border-color: var(--xm-danger);
    }

textarea.xv-input {
    display: block;
    width: 100%;
    height: auto;
    min-height: 88px;
    padding: 6px 8px;
    line-height: 1.45;
    resize: vertical;
}

.xv-hint {
    font-size: 11.5px;
    color: var(--xm-text-muted);
}

    .xv-hint.is-bad {
        color: var(--xm-danger);
    }

/* ---- "null": a chip beside the value, pressed when the value is null rather than empty */
.xv-null {
    display: inline-flex;
    align-items: center;
    height: 22px;
    padding: 0 8px;
    border: 1px dashed var(--xm-control-border);
    border-radius: 999px;
    background: transparent;
    color: var(--xm-text-muted);
    font-family: var(--xm-doc-font);
    font-size: 11.5px;
    cursor: pointer;
}

    .xv-null:hover {
        background: var(--xm-surface-hover);
        color: var(--xm-text);
    }

    .xv-null.is-on {
        border-style: solid;
        border-color: color-mix(in srgb, var(--xm-accent) 55%, transparent);
        background: color-mix(in srgb, var(--xm-accent) 12%, transparent);
        color: var(--xm-accent-text);
    }

    .xv-null:focus-visible {
        outline: 2px solid var(--xm-accent);
        outline-offset: 1px;
    }

/* ---- true / false: the inspector's toggle switch with its value beside it */
.xv-bool {
    font-family: var(--xm-doc-font);
    font-size: 12.5px;
}

    .xv-bool .xv-bool-text {
        min-width: 32px;
        color: var(--xm-text);
    }

/* ---- a picker's button: the value, what it means, and a caret */
.xv-pick {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    min-width: 0;
    height: 28px;
    padding: 0 8px;
    border: 1px solid var(--xm-control-border);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-size: 12.5px;
    text-align: left;
    vertical-align: middle;
    cursor: pointer;
}

    .xv-pick:hover {
        background: var(--xm-surface-hover);
    }

    .xv-pick:focus-visible {
        outline: 2px solid var(--xm-accent);
        outline-offset: 1px;
    }

    .xv-pick:disabled {
        background: var(--xm-surface-hover);
        color: var(--xm-text-muted);
        cursor: default;
    }

.xv-pick-value {
    font-family: var(--xm-doc-font);
    white-space: nowrap;
}

    .xv-pick-value.is-empty {
        color: var(--xm-text-muted);
        font-family: inherit;
        font-style: italic;
    }

.xv-pick-detail {
    min-width: 0;
    overflow: hidden;
    color: var(--xm-text-muted);
    font-size: 11.5px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xv-pick .xc-caret {
    flex: none;
    margin-left: auto;
    font-size: 9px !important;
    color: var(--xm-text-muted);
}

/* ---- the value picker's own bits (Controls/ValuePicker.razor, on the TypePicker card) */
.tp-item.is-custom .tp-name {
    font-family: var(--xm-doc-font);
}

.tp-mono {
    font-family: var(--xm-doc-font);
}

/* The maps page's New menu, at the end of its command bar. */
.xm-bar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ---- the flat file builder's type menu (Controls/FlatFileTypeSelect.razor): a select's look, a menu with a submenu */
.ct-wrap {
    position: relative;
    display: block;
    min-width: 0;
}

.ct-button {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    height: 28px;
    box-sizing: border-box;
    padding: 0 7px;
    border: 1px solid var(--xm-control-border);
    border-radius: 6px;
    background: var(--xm-surface);
    color: var(--xm-text);
    font-size: 12.5px;
    text-align: left;
    cursor: pointer;
}

    .ct-button:hover,
    .ct-button.is-open {
        border-color: var(--xm-accent);
    }

.ct-current {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ct-caret {
    flex: none;
    font-size: 10px;
    color: var(--xm-text-muted);
}

.ct-backdrop {
    position: fixed;
    inset: 0;
    z-index: 8600;
}

.ct-menu {
    position: fixed;
    z-index: 8601;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: 5px 0;
    border: 1px solid var(--xm-border-soft);
    border-radius: 10px;
    background: var(--xm-surface);
    box-shadow: 0 12px 32px var(--xm-shadow);
    outline: none;
}

.ct-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 14px;
    border: none;
    background: transparent;
    color: var(--xm-text);
    font-size: 13px;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

    .ct-item:hover,
    .ct-item.is-open {
        background: var(--xm-surface-hover);
    }

    .ct-item.is-on {
        color: var(--xm-accent);
        font-weight: 600;
    }

.ct-note {
    margin-left: auto;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--xm-text-muted);
}

.ct-parent .ct-note {
    margin-left: 0;
}

.ct-sub-caret {
    margin-left: auto;
    font-size: 10px;
    color: var(--xm-text-muted);
}

.ct-sep {
    height: 1px;
    margin: 5px 0;
    background: var(--xm-border-soft);
}

.ct-head {
    padding: 8px 14px 3px 14px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--xm-text-muted);
}

    .ct-head:first-child {
        padding-top: 3px;
    }
