/* The workbench: the shell, the app bar, the two panes and the status bar, one section
   per part of the page. Only the shell pages (the workbench and /not-found) load this. */

/* ==== Shell ================================================================= */

:root {
    --cv-statusbar-h: 1.5rem;
}

.cv-shell {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--cv-bg);
    color: var(--cv-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.875rem;
}

/* Below tablet width the two panes cannot sit side by side, so swap them for a notice. */
.cv-too-small {
    display: none;
}

@media (max-width: 921.58px) {
    .cv-shell {
        display: none;
    }

    .cv-too-small {
        position: fixed;
        inset: 0;
        display: grid;
        place-items: center;
        padding: 2rem;
        background: var(--cv-bg);
        color: var(--cv-text);
        font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
        text-align: center;
    }

    .cv-too-small-inner {
        max-width: 26rem;
    }

    .cv-too-small-mark {
        width: 2.25rem;
        height: 2.25rem;
        margin-bottom: 1rem;
        fill: none;
        stroke: var(--cv-accent);
        stroke-width: 1.6;
    }

    .cv-too-small h1 {
        font-size: 1.125rem;
        font-weight: 600;
        letter-spacing: -0.01em;
        margin-bottom: 0.5rem;
    }

    .cv-too-small p {
        color: var(--cv-muted);
        font-size: 0.9375rem;
        line-height: 1.5;
        margin: 0;
    }
}

/* ==== App bar =============================================================== */

.appbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: none;
    height: 2.75rem;
    padding: 0 0.625rem;
    background: var(--cv-chrome);
    border-bottom: 1px solid var(--cv-border);
}

.brand {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    flex: none;
    padding-right: 0.25rem;
}

.brand-mark {
    width: 1.25rem;
    height: 1.25rem;
    fill: none;
    stroke: var(--cv-muted);
    stroke-width: 1.6;
}

.brand-mark-flex {
    stroke: var(--cv-accent);
}

.brand-name {
    color: var(--cv-text);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.brand-name-accent {
    color: var(--cv-accent);
}

.appbar-spacer {
    flex: 1;
}

@media (max-width: 1228.78px) {
    .appbar {
        gap: 0.5rem;
    }
}

/* ==== Theme switch ========================================================== */

.theme-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 999px;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.theme-btn:hover:not(:disabled) {
    background: var(--cv-chrome-hover);
    color: var(--cv-text);
}

.theme-btn:disabled {
    cursor: default;
    opacity: 0.6;
}

/* The label is the first thing to go when the chrome tightens - the glyph on its
   own still says which way the switch will move. */
@media (max-width: 1228.78px) {
    .theme-btn-label {
        display: none;
    }
}

/* ==== Panes ================================================================= */

.pane {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    background: var(--cv-pane);
}

/* Each pane carries its own hue, used only for the hairline under the header and
   the focus rule - enough to tell the panes apart without colouring the text
   itself, which is where the user is actually reading. */
.pane-tables {
    --pane-hue: var(--cv-hue-tables);
}

.pane-query {
    --pane-hue: var(--cv-hue-query);
}

.pane-results {
    --pane-hue: var(--cv-hue-results);
}

.pane-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    padding: 0.3125rem 0.5rem 0.3125rem 0.625rem;
    background: var(--cv-pane-alt);
    border-bottom: 1px solid var(--cv-border-soft);
    box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--pane-hue) 35%, transparent);
}

.pane-title {
    margin: 0;
    color: var(--cv-text);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

.pane-meta {
    color: var(--cv-muted);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pane-head-spacer {
    flex: 1;
    min-width: 0.5rem;
}

.pane-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex: none;
}

.pane-editor {
    flex: 1;
    min-height: 0;
    min-width: 0;
    padding: 0.5rem 0.75rem;
    border: 0;
    outline: 0;
    resize: none;
    background: transparent;
    color: var(--cv-text);
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.8125rem;
    line-height: 1.55;
    tab-size: 8;
    white-space: pre;
    overflow: auto;
}

.pane-editor::placeholder {
    color: var(--cv-faint);
}

.pane-editor:focus-visible {
    box-shadow: inset 2px 0 0 var(--pane-hue);
}

.pane-footer {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    flex-wrap: wrap;
    padding: 0.375rem 0.625rem;
    background: var(--cv-pane-alt);
    border-top: 1px solid var(--cv-border-soft);
    color: var(--cv-muted);
    font-size: 0.75rem;
}

/* ==== Workbench ============================================================= */

/* Pane sizes are bare `fr` values so a drag just moves budget between neighbours;
   js/panes.js rewrites these custom properties during a drag. They must stay free
   of any `minmax()` floor - with a floor in the track, grid subtracts the floors
   before distributing the remainder, so sizes stop being proportional to the
   custom properties and the arithmetic in panes.js no longer holds. The minimum
   pane size is clamped in JS instead.

   The starting proportions are `var()` fallbacks rather than declarations on these
   elements, because a remembered layout is applied to <html> before first paint
   (see the inline script in the page head) and a declaration here would shadow what it inherits. */
.cv {
    position: relative;
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: var(--cv-size-tables, 1fr) auto var(--cv-size-main, 4.2fr);
    background: var(--cv-bg);
}

/* The query over the results, split by a row handle. */
.cv-main {
    display: grid;
    grid-template-rows: var(--cv-size-query, 2fr) auto var(--cv-size-results, 3fr);
    min-width: 0;
    min-height: 0;
}

/* One handle style for both axes: a gutter in the shell colour, hairlined on both
   sides, with a short grip in the middle. Which axis a handle serves is decided by
   its box - see panes.js - so the media query below only restyles it, it never has
   to tell the script anything. */
.cv-split {
    position: relative;
    display: grid;
    place-items: center;
    background: var(--cv-bg);
    touch-action: none;
}

.cv-split::after {
    content: "";
    display: block;
    border-radius: 999px;
    background: var(--cv-faint);
    opacity: 0.5;
}

/* A column handle, between side-by-side panes. A pane split top-to-bottom wants the
   same rules turned through 90 degrees - height, border-block, row-resize - which is
   what SetFlex does for its result pane. */
.cv > .cv-split {
    width: 9px;
    border-inline: 1px solid var(--cv-border);
    cursor: col-resize;
}

.cv > .cv-split::after {
    width: 3px;
    height: 2rem;
}

.cv-main > .cv-split {
    height: 9px;
    border-block: 1px solid var(--cv-border);
    cursor: row-resize;
}

.cv-main > .cv-split::after {
    width: 2rem;
    height: 3px;
}

.cv-split:hover,
.cv-split:focus-visible {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent-dim);
    outline: none;
}

.cv-split:hover::after,
.cv-split:focus-visible::after,
.cv-split.is-dragging::after {
    background: var(--cv-accent);
    opacity: 1;
}

.cv-split.is-dragging {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent);
}

/* Bigger grab target on touch devices; the gutter keeps its weight because the
   extra width is padding in the shell colour. */
@media (pointer: coarse) {
    .cv > .cv-split {
        width: 17px;
    }

    .cv-main > .cv-split {
        height: 17px;
    }
}

/* Small ghost buttons in the pane header bars and beside the pills. */
.pane-btn {
    padding: 0.1875rem 0.4375rem;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.75rem;
    white-space: nowrap;
    cursor: pointer;
}

.pane-btn:hover:not(:disabled) {
    background: var(--cv-chrome-hover);
    border-color: var(--cv-border);
    color: var(--cv-text);
}

.pane-btn:disabled {
    cursor: default;
    opacity: 0.55;
}

/* Result shaping: pressed pills rather than one-shot buttons, because these stay
   on across a recalculation. */
.pill {
    padding: 0.1875rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 999px;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.75rem;
    white-space: nowrap;
    cursor: pointer;
}

.pill:hover {
    border-color: var(--cv-accent-dim);
    color: var(--cv-text);
}

.pill.is-on {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent-dim);
    color: var(--cv-accent);
}

.opt {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    color: var(--cv-muted);
    font-size: 0.75rem;
    cursor: pointer;
    user-select: none;
}

.opt[hidden] {
    display: none;
}

.opt input {
    width: 0.875rem;
    height: 0.875rem;
    margin: 0;
    accent-color: var(--cv-accent);
}

.statusbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: none;
    box-sizing: border-box;
    /* Fixed, so the privacy sheet can sit exactly on top of it. */
    height: var(--cv-statusbar-h);
    padding: 0 0.75rem;
    background: var(--cv-chrome);
    border-top: 1px solid var(--cv-border);
    color: var(--cv-muted);
    font-size: 0.6875rem;
}

.statusbar-item {
    font-variant-numeric: tabular-nums;
}

.statusbar-spacer {
    flex: 1;
}

.statusbar-note {
    color: var(--cv-faint);
    white-space: nowrap;
}

/* Something the user asked for did not happen. Muted rather than red: nothing on
   screen is wrong, there is just another way to get at it. */
.statusbar-warn {
    min-width: 0;
    overflow: hidden;
    color: var(--cv-text);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The privacy notice. Faint, like the summary, because it is a standing control rather
   than anything about the comparison - but it stays at every width, which the summary
   does not. The chevron points up to open the sheet and down once it is open. */
.statusbar-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: none;
    padding: 0;
    border: 0;
    background: none;
    color: var(--cv-faint);
    font: inherit;
    white-space: nowrap;
    cursor: pointer;
}

.statusbar-link:hover,
.statusbar-link:focus-visible,
.statusbar:has(+ .privacy-sheet:popover-open) .statusbar-link {
    color: var(--cv-text);
}

.statusbar-chevron {
    width: 0.625rem;
    height: 0.625rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 0.2s ease;
}

.statusbar:has(+ .privacy-sheet:popover-open) .statusbar-chevron {
    transform: rotate(180deg);
}

/* ==== Privacy sheet ========================================================= */

/* Slides up out of the status bar, on the right under the button that opened it. A
   popover, so it lives in the top layer and needs no z-index; the UA's centring and
   border are undone. */
.privacy-sheet {
    position: fixed;
    inset: auto 0.75rem var(--cv-statusbar-h) auto;
    box-sizing: border-box;
    width: min(26rem, calc(100vw - 1.5rem));
    max-height: calc(100vh - var(--cv-statusbar-h) - 3.5rem);
    margin: 0;
    padding: 0.875rem 1rem 0.75rem;
    overflow: auto;
    background: var(--cv-pane);
    border: 1px solid var(--cv-border);
    border-bottom: 0;
    border-radius: 0.5rem 0.5rem 0 0;
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.22);
    color: var(--cv-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.8125rem;
    line-height: 1.5;

    transform: translateY(100%);
    opacity: 0;
    transition:
        transform 0.22s ease,
        opacity 0.22s ease,
        overlay 0.22s allow-discrete,
        display 0.22s allow-discrete;
}

.privacy-sheet:popover-open {
    transform: none;
    opacity: 1;
}

@starting-style {
    .privacy-sheet:popover-open {
        transform: translateY(100%);
        opacity: 0;
    }
}

/* Clear, so the workbench stays readable behind it - it is a note, not a dialog. */
.privacy-sheet::backdrop {
    background: transparent;
}

.privacy-sheet-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.privacy-sheet-title {
    flex: 1;
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.privacy-sheet-close {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 0.25rem;
    background: none;
    color: var(--cv-muted);
    cursor: pointer;
}

.privacy-sheet-close:hover,
.privacy-sheet-close:focus-visible {
    border-color: var(--cv-border);
    background: var(--cv-chrome-hover);
    color: var(--cv-text);
}

.privacy-sheet-close svg {
    width: 0.75rem;
    height: 0.75rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.privacy-sheet-list {
    margin: 0;
    padding-left: 1.125rem;
    color: var(--cv-muted);
}

.privacy-sheet-list li + li {
    margin-top: 0.4375rem;
}

.privacy-sheet-list strong {
    color: var(--cv-text);
    font-weight: 600;
}

.privacy-sheet-foot {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin-top: 0.75rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--cv-border-soft);
    font-size: 0.75rem;
}

.privacy-sheet-foot a {
    color: var(--cv-accent);
    text-decoration: none;
}

.privacy-sheet-foot a:hover,
.privacy-sheet-foot a:focus-visible {
    text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
    .privacy-sheet,
    .statusbar-chevron {
        transition: none;
    }
}

/* ==== Not found ============================================================= */

.missing {
    flex: 1;
    display: grid;
    place-items: center;
    padding: 2rem;
    text-align: center;
}

.missing h1 {
    margin: 0 0 0.5rem;
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.missing p {
    margin: 0 0 1rem;
    color: var(--cv-muted);
}

.missing a {
    color: var(--cv-accent);
}

/* ==== App bar actions and the engine light ================================== */

.appbar-group {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex: none;
    padding-left: 0.5rem;
    border-left: 1px solid var(--cv-border-soft);
}

.bar-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    padding: 0.25rem 0.5rem;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.75rem;
    white-space: nowrap;
    cursor: pointer;
}

.bar-btn:hover:not(:disabled),
.bar-btn:focus-visible {
    background: var(--cv-chrome-hover);
    border-color: var(--cv-border);
    color: var(--cv-text);
    outline: none;
}

.bar-btn svg {
    width: 0.875rem;
    height: 0.875rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.engine {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex: none;
    color: var(--cv-muted);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.engine-dot {
    width: 0.4375rem;
    height: 0.4375rem;
    border-radius: 50%;
    background: var(--cv-faint);
}

.engine[data-state="loading"] .engine-dot,
.engine[data-state="busy"] .engine-dot {
    background: var(--cv-accent);
    animation: cv-pulse 1s ease-in-out infinite alternate;
}

.engine[data-state="ready"] .engine-dot {
    background: var(--cv-ok);
}

.engine[data-state="failed"] .engine-dot {
    background: var(--cv-danger);
}

.engine[data-state="failed"] {
    color: var(--cv-danger);
}

@keyframes cv-pulse {
    from { opacity: 0.35; }
    to { opacity: 1; }
}

@media (max-width: 1228.78px) {
    .bar-btn-label,
    .engine-label {
        display: none;
    }
}

/* ==== Tabs, segments, buttons and fields ===================================== */

.tabs {
    display: flex;
    gap: 0.125rem;
    flex: none;
}

.tab {
    padding: 0.1875rem 0.5rem;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
}

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

.tab.is-on {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent-dim);
    color: var(--cv-accent);
}

.tab:focus-visible,
.seg-btn:focus-visible,
.btn:focus-visible,
.pane-btn:focus-visible,
.link-btn:focus-visible,
.icon-btn:focus-visible {
    outline: 2px solid var(--cv-accent-dim);
    outline-offset: 1px;
}

.seg {
    display: inline-flex;
    flex: none;
    border: 1px solid var(--cv-border);
    border-radius: 999px;
    overflow: hidden;
}

.seg-btn {
    padding: 0.1875rem 0.625rem;
    border: 0;
    background: transparent;
    color: var(--cv-muted);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.seg-btn + .seg-btn {
    border-left: 1px solid var(--cv-border);
}

.seg-btn:hover {
    color: var(--cv-text);
}

.seg-btn.is-on {
    background: var(--cv-accent-wash);
    color: var(--cv-accent);
}

.btn {
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    background: var(--cv-chrome-2);
    color: var(--cv-text);
    font: inherit;
    font-size: 0.75rem;
    white-space: nowrap;
    cursor: pointer;
}

.btn:hover:not(:disabled) {
    background: var(--cv-chrome-hover);
}

.btn-primary {
    background: var(--cv-accent);
    border-color: var(--cv-accent);
    color: var(--cv-accent-ink);
    font-weight: 600;
}

.btn-primary:hover:not(:disabled) {
    background: var(--cv-accent-bright);
}

.btn:disabled {
    cursor: default;
    opacity: 0.5;
}

.link-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--cv-accent);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.link-btn:hover {
    text-decoration: underline;
}

.link-danger {
    color: var(--cv-danger);
}

.icon-btn {
    display: grid;
    place-items: center;
    flex: none;
    width: 1.375rem;
    height: 1.375rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 4px;
    background: none;
    color: var(--cv-muted);
    cursor: pointer;
}

.icon-btn:hover {
    border-color: var(--cv-border);
    background: var(--cv-chrome-hover);
    color: var(--cv-text);
}

.icon-btn svg {
    width: 0.625rem;
    height: 0.625rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 0.15s ease;
}

.icon-btn[aria-expanded="true"] svg {
    transform: rotate(90deg);
}

.field {
    min-width: 0;
    padding: 0.1875rem 0.375rem;
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    background: var(--cv-pane);
    color: var(--cv-text);
    font: inherit;
    font-size: 0.75rem;
}

.field:focus-visible {
    border-color: var(--cv-accent-dim);
    outline: 2px solid var(--cv-accent-wash);
}

.field:disabled {
    opacity: 0.55;
}

.field-sm {
    width: 7rem;
}

.field-num {
    width: 5rem;
}

.field-wide {
    flex: 1;
    max-width: 32rem;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
}

.field-search {
    width: 12rem;
}

.hint {
    color: var(--cv-faint);
    font-size: 0.75rem;
}

.opt code,
.hint code {
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
}

/* ==== Tables list =========================================================== */

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

.tables-empty {
    margin: 0;
    padding: 0.75rem;
    color: var(--cv-muted);
    font-size: 0.75rem;
    line-height: 1.5;
}

.tables-empty[hidden] {
    display: none;
}

.tables-list {
    margin: 0;
    padding: 0.25rem 0;
    list-style: none;
}

.table-item.is-current .table-open {
    background: var(--cv-accent-wash);
    box-shadow: inset 2px 0 0 var(--cv-accent);
}

.table-row {
    display: flex;
    align-items: center;
    gap: 0.125rem;
    padding-right: 0.375rem;
}

.table-open {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    flex: 1;
    min-width: 0;
    padding: 0.3125rem 0.625rem;
    border: 0;
    background: none;
    color: var(--cv-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.table-open:hover {
    background: var(--cv-chrome-hover);
}

.table-name {
    max-width: 100%;
    overflow: hidden;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.8125rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.table-meta {
    color: var(--cv-muted);
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
}

.table-detail {
    padding: 0.125rem 0.625rem 0.5rem 1rem;
    font-size: 0.75rem;
}

.table-detail[hidden] {
    display: none;
}

.table-file {
    margin: 0 0 0.25rem;
    color: var(--cv-faint);
    overflow-wrap: anywhere;
}

.table-columns {
    margin: 0 0 0.375rem;
    padding: 0;
    list-style: none;
}

.table-columns li {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.0625rem 0;
}

.table-columns .col-name {
    overflow: hidden;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.table-columns .col-type {
    flex: none;
    color: var(--cv-faint);
    font-size: 0.6875rem;
}

.table-actions {
    display: flex;
    gap: 0.75rem;
}

.import-opts {
    flex: none;
    border-top: 1px solid var(--cv-border-soft);
    background: var(--cv-pane-alt);
    font-size: 0.75rem;
}

.import-opts summary {
    padding: 0.375rem 0.625rem;
    color: var(--cv-muted);
    cursor: pointer;
}

.import-opts summary:hover {
    color: var(--cv-text);
}

.import-grid {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 0.375rem 0.5rem;
    padding: 0 0.625rem;
    color: var(--cv-muted);
}

.import-note {
    margin: 0.5rem 0.625rem 0.625rem;
    color: var(--cv-faint);
    line-height: 1.4;
}

/* ==== Query modes =========================================================== */

.mode {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.mode[hidden] {
    display: none;
}

.sql-editor {
    tab-size: 4;
}

.form {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: 0.5rem 0.75rem;
    font-size: 0.75rem;
}

.form-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.375rem 0.5rem;
    padding: 0.25rem 0;
}

.form-row[hidden] {
    display: none;
}

.form-row-top {
    align-items: flex-start;
}

.form-label {
    flex: none;
    width: 6.5rem;
    color: var(--cv-muted);
}

.form-row-top > .form-label {
    padding-top: 0.25rem;
}

.form-label-inline {
    width: auto;
    margin-left: 0.5rem;
}

.stack {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    flex: 1;
    gap: 0.375rem;
    min-width: 0;
}

.inline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

/* A wrapping row of checkable column names. */
.checks {
    display: flex;
    flex-wrap: wrap;
    flex: 1;
    gap: 0.25rem;
    min-width: 0;
    max-height: 5.5rem;
    overflow: auto;
}

.checks:empty::before {
    content: attr(data-empty);
    color: var(--cv-faint);
}

.check {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 999px;
    color: var(--cv-muted);
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.6875rem;
    cursor: pointer;
    user-select: none;
}

.check input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.check:has(input:checked) {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent-dim);
    color: var(--cv-accent);
}

.check:has(input:focus-visible) {
    outline: 2px solid var(--cv-accent-dim);
    outline-offset: 1px;
}

.check:has(input:disabled) {
    opacity: 0.4;
    cursor: default;
}

.rows-list {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rows-list:empty {
    display: none;
}

.rows-item {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.sql-preview {
    flex: 1;
    min-width: 0;
    margin: 0;
    padding: 0.375rem 0.5rem;
    border: 1px solid var(--cv-border-soft);
    border-radius: 4px;
    background: var(--cv-pane-alt);
    color: var(--cv-text);
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.75rem;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.sql-preview.is-empty {
    color: var(--cv-faint);
}

.impact {
    color: var(--cv-muted);
}

.impact.is-warning {
    color: var(--cv-danger);
}

/* ==== Results =============================================================== */

.view {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.view[hidden] {
    display: none;
}

.error {
    flex: none;
    max-height: 40%;
    overflow: auto;
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--cv-border-soft);
    background: var(--cv-danger-wash);
    color: var(--cv-danger);
    font-size: 0.75rem;
}

.error[hidden] {
    display: none;
}

.error-text {
    margin: 0.25rem 0 0;
    color: var(--cv-text);
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    white-space: pre-wrap;
}

.placeholder {
    margin: 0;
    padding: 1rem;
    color: var(--cv-faint);
    font-size: 0.8125rem;
}

.placeholder[hidden] {
    display: none;
}

.welcome {
    display: grid;
    place-content: center;
    justify-items: center;
    flex: 1;
    gap: 0.5rem;
    padding: 2rem;
    text-align: center;
}

.welcome[hidden] {
    display: none;
}

.welcome-mark {
    width: 2.5rem;
    height: 2.5rem;
    fill: none;
    stroke: var(--cv-muted);
    stroke-width: 1.4;
}

.welcome-mark-flex {
    stroke: var(--cv-accent);
}

.welcome-title {
    margin: 0;
    font-size: 1.0625rem;
    font-weight: 600;
}

.welcome-text {
    max-width: 30rem;
    margin: 0;
    color: var(--cv-muted);
    font-size: 0.8125rem;
    line-height: 1.5;
}

.welcome-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.welcome-note {
    margin: 0;
    color: var(--cv-faint);
    font-size: 0.75rem;
}

/* ==== The grid ============================================================== */

/* One scroller. Inside it, a sizer as tall as every row and as wide as every column, so
   the scrollbars are the real ones; the header sticks to its top, and only the rows in
   view (and a few either side) exist, positioned absolutely by js/grid.js. */
.grid {
    --row-h: 1.5rem;
    position: relative;
    flex: 1;
    min-height: 0;
    overflow: auto;
    outline: none;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.grid[hidden] {
    display: none;
}

.grid-sizer {
    position: relative;
}

.grid-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    width: max-content;
    min-width: 100%;
    background: var(--cv-pane-alt);
    border-bottom: 1px solid var(--cv-border);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
}

.grid-body {
    position: relative;
}

.grid-gutter {
    position: sticky;
    left: 0;
    z-index: 1;
    flex: none;
    box-sizing: border-box;
    padding: 0 0.375rem;
    overflow: hidden;
    background: var(--cv-pane-alt);
    border-right: 1px solid var(--cv-border-soft);
    color: var(--cv-faint);
    text-align: right;
}

.grid-head .grid-gutter {
    z-index: 3;
}

.grid-th {
    position: relative;
    flex: none;
    box-sizing: border-box;
    padding: 0.25rem 0.5rem 0.1875rem;
    border-right: 1px solid var(--cv-border-soft);
    cursor: pointer;
    user-select: none;
}

.grid-th:hover {
    background: var(--cv-chrome-hover);
}

.grid-th-name {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    overflow: hidden;
    color: var(--cv-text);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.grid-th-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

.grid-th-sort {
    flex: none;
    color: var(--cv-accent);
    font-size: 0.625rem;
}

.grid-th-type {
    overflow: hidden;
    color: var(--cv-faint);
    font-size: 0.625rem;
    letter-spacing: 0.04em;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}

.grid-th-filter {
    display: block;
    box-sizing: border-box;
    width: 100%;
    margin-top: 0.1875rem;
    padding: 0.0625rem 0.25rem;
    border: 1px solid var(--cv-border);
    border-radius: 3px;
    background: var(--cv-pane);
    color: var(--cv-text);
    font: inherit;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.6875rem;
}

.grid-th-filter[hidden] {
    display: none;
}

.grid-th-filter.is-set {
    border-color: var(--cv-accent-dim);
}

.grid-th-filter:focus-visible {
    border-color: var(--cv-accent);
    outline: none;
}

.grid-resize {
    position: absolute;
    top: 0;
    right: -4px;
    bottom: 0;
    z-index: 1;
    width: 8px;
    cursor: col-resize;
}

.grid-resize:hover,
.grid-resize.is-dragging {
    background: linear-gradient(to right, transparent 3px, var(--cv-accent) 3px, var(--cv-accent) 5px, transparent 5px);
}

.grid-row {
    position: absolute;
    left: 0;
    display: flex;
    height: var(--row-h);
    line-height: var(--row-h);
}

.grid-row.is-alt {
    background: var(--cv-row-alt);
}

.grid-row:hover {
    background: var(--cv-row-hover);
}

.grid-row .grid-gutter {
    font-size: 0.6875rem;
}

.grid-cell {
    flex: none;
    box-sizing: border-box;
    padding: 0 0.5rem;
    overflow: hidden;
    border-right: 1px solid var(--cv-border-soft);
    color: var(--cv-text);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.grid-cell.is-num {
    text-align: right;
}

.grid-cell.is-null {
    color: var(--cv-null);
    font-style: italic;
}

.grid-row.is-loading .grid-cell {
    color: var(--cv-faint);
}

.grid-none {
    position: sticky;
    left: 0;
    margin: 0;
    padding: 1rem;
    color: var(--cv-faint);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.8125rem;
}

.grid-none[hidden] {
    display: none;
}

/* ==== Profile =============================================================== */

.profile {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(16rem, 2fr);
    flex: 1;
    min-height: 0;
}

.profile:not(:has(.profile-detail:not([hidden]))) {
    grid-template-columns: minmax(0, 1fr);
}

.profile-table-wrap {
    min-height: 0;
    overflow: auto;
}

.profile-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.profile-table th {
    position: sticky;
    top: 0;
    padding: 0.3125rem 0.625rem;
    background: var(--cv-pane-alt);
    border-bottom: 1px solid var(--cv-border);
    color: var(--cv-muted);
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}

.profile-table td {
    max-width: 14rem;
    padding: 0.25rem 0.625rem;
    overflow: hidden;
    border-bottom: 1px solid var(--cv-border-soft);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.profile-table .num {
    text-align: right;
}

.profile-table tbody tr {
    cursor: pointer;
}

.profile-table tbody tr:hover {
    background: var(--cv-row-hover);
}

.profile-table tbody tr.is-current {
    background: var(--cv-accent-wash);
    box-shadow: inset 2px 0 0 var(--cv-accent);
}

.profile-table .mono {
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
}

.profile-table .faint {
    color: var(--cv-faint);
}

.bar-cell {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.375rem;
}

.bar-cell-bar {
    width: 2.5rem;
    height: 0.3125rem;
    border-radius: 999px;
    background: var(--cv-border-soft);
    overflow: hidden;
}

.bar-cell-fill {
    display: block;
    height: 100%;
    background: var(--cv-accent);
}

.profile-detail {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0.625rem 0.75rem;
    border-left: 1px solid var(--cv-border-soft);
    overflow: auto;
}

.profile-detail[hidden] {
    display: none;
}

.profile-detail-title {
    margin: 0;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.875rem;
}

.profile-detail-sub {
    margin: 0.125rem 0 0.5rem;
    color: var(--cv-muted);
    font-size: 0.75rem;
}

.profile-chart {
    width: 100%;
    min-height: 12rem;
    flex: 1;
}

/* ==== Charts ================================================================ */

.chart-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    flex: none;
    gap: 0.5rem 0.75rem;
    padding: 0.4375rem 0.75rem;
    border-bottom: 1px solid var(--cv-border-soft);
}

.chart-area {
    position: relative;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.chart {
    display: block;
    width: 100%;
    height: 100%;
}

.chart[hidden] {
    display: none;
}

.chart text,
.profile-chart text {
    fill: var(--cv-muted);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.6875rem;
}

.chart .axis,
.profile-chart .axis {
    stroke: var(--cv-border);
    stroke-width: 1;
}

.chart .gridline {
    stroke: var(--cv-border-soft);
    stroke-width: 1;
}

.chart .bar,
.profile-chart .bar {
    fill: var(--cv-accent);
}

.chart .bar:hover,
.profile-chart .bar:hover {
    fill: var(--cv-accent-bright);
}

.chart .line {
    fill: none;
    stroke: var(--cv-accent);
    stroke-width: 2;
    stroke-linejoin: round;
}

.chart .dot {
    fill: var(--cv-accent);
}

.chart .slice {
    stroke: var(--cv-pane);
    stroke-width: 1.5;
}

.chart .legend-label {
    fill: var(--cv-text);
}

.series-1 { fill: var(--cv-series-1); }
.series-2 { fill: var(--cv-series-2); }
.series-3 { fill: var(--cv-series-3); }
.series-4 { fill: var(--cv-series-4); }
.series-5 { fill: var(--cv-series-5); }
.series-6 { fill: var(--cv-series-6); }
.series-7 { fill: var(--cv-series-7); }
.series-8 { fill: var(--cv-series-8); }
.series-9 { fill: var(--cv-series-9); }

/* ==== Menus and help ======================================================== */

/* Popovers placed under the button that opened them by js/workbench.js. */
.menu {
    position: fixed;
    inset: auto;
    box-sizing: border-box;
    min-width: 14rem;
    max-width: min(22rem, calc(100vw - 1rem));
    max-height: min(28rem, calc(100vh - 4rem));
    margin: 0;
    padding: 0.375rem;
    overflow: auto;
    background: var(--cv-pane);
    border: 1px solid var(--cv-border);
    border-radius: 0.375rem;
    box-shadow: var(--cv-pop-shadow);
    color: var(--cv-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.8125rem;
}

.menu::backdrop {
    background: transparent;
}

.menu-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-right: 0.375rem;
}

.menu-title {
    margin: 0;
    padding: 0.25rem 0.5rem 0.375rem;
    color: var(--cv-muted);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.menu-item {
    display: block;
    width: 100%;
    padding: 0.3125rem 0.5rem;
    border: 0;
    border-radius: 4px;
    background: none;
    color: var(--cv-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.menu-item:hover,
.menu-item:focus-visible {
    background: var(--cv-accent-wash);
    color: var(--cv-accent);
    outline: none;
}

.menu-note {
    margin: 0.375rem 0.5rem 0.25rem;
    color: var(--cv-faint);
    font-size: 0.6875rem;
    line-height: 1.4;
}

.menu-checks {
    display: flex;
    flex-direction: column;
}

.menu-checks label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.75rem;
    cursor: pointer;
}

.menu-checks label:hover {
    background: var(--cv-chrome-hover);
}

.menu-checks input {
    accent-color: var(--cv-accent);
}

.help {
    position: fixed;
    inset: 3.25rem 0.75rem auto auto;
    box-sizing: border-box;
    width: min(30rem, calc(100vw - 1.5rem));
    max-height: calc(100vh - 5rem);
    margin: 0;
    padding: 0.75rem 1rem 1rem;
    overflow: auto;
    background: var(--cv-pane);
    border: 1px solid var(--cv-border);
    border-radius: 0.5rem;
    box-shadow: var(--cv-pop-shadow);
    color: var(--cv-text);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 0.8125rem;
    line-height: 1.5;
}

.help::backdrop {
    background: transparent;
}

.help-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.help h2 {
    margin: 0;
    font-size: 0.9375rem;
}

.help h3 {
    margin: 0.875rem 0 0.25rem;
    color: var(--cv-accent);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.help p,
.help ul {
    margin: 0;
    color: var(--cv-muted);
}

.help ul {
    padding-left: 1.125rem;
}

.help li + li {
    margin-top: 0.25rem;
}

.help strong {
    color: var(--cv-text);
}

.help code,
.help kbd {
    padding: 0 0.1875rem;
    border-radius: 3px;
    background: var(--cv-chrome-2);
    color: var(--cv-text);
    font-family: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', ui-monospace, monospace;
    font-size: 0.75rem;
}

/* ==== Dropping files ======================================================== */

.drop {
    position: fixed;
    inset: 0;
    z-index: 10;
    display: grid;
    place-items: center;
    padding: 2rem;
    background: color-mix(in srgb, var(--cv-bg) 70%, transparent);
    pointer-events: none;
}

.drop[hidden] {
    display: none;
}

.drop-inner {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border: 2px dashed var(--cv-accent);
    border-radius: 0.75rem;
    background: var(--cv-accent-wash);
    color: var(--cv-accent);
    font-family: 'Inter', 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, sans-serif;
    font-size: 1.125rem;
    font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
    .engine-dot {
        animation: none !important;
    }
}

.pane-btn.is-on {
    background: var(--cv-accent-wash);
    border-color: var(--cv-accent-dim);
    color: var(--cv-accent);
}

/* The results header carries the tabs, the counts, the search and three buttons; under
   the 1024px breakpoint the search box gives up the room. */
@media (max-width: 1228.78px) {
    .field-search {
        width: 7rem;
    }

    .pane-results .pane-meta {
        overflow: hidden;
        text-overflow: ellipsis;
        min-width: 0;
    }
}
