:root {
    --bg-canvas: #f8fafc;
    --bg-surface: #ffffff;
    --bg-sidebar: #0f172a;
    --bg-sidebar-hover: rgba(255, 255, 255, 0.06);
    --bg-sidebar-active: rgba(99, 102, 241, 0.16);
    --border-subtle: #e2e8f0;
    --border-emphasis: #cbd5e1;
    --text-primary: #0f172a;
    --text-secondary: #475569;
    --text-muted: #94a3b8;
    --text-on-dark: #cbd5e1;
    --text-on-dark-active: #ffffff;
    --accent: #6366f1;
    --accent-soft: #eef2ff;
    --success: #10b981;
    --danger: #ef4444;
    --shadow-sm: 0 1px 2px 0 rgba(15, 23, 42, 0.04);
    --shadow-md: 0 4px 12px -2px rgba(15, 23, 42, 0.06), 0 2px 4px -2px rgba(15, 23, 42, 0.04);
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --topbar-height: 56px;
    --sidebar-width: 216px;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    height: 100vh;        /* fallback for older browsers */
    height: 100dvh;       /* iOS Safari: stay correct as the address bar resizes */
    overflow: hidden;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    background-color: var(--bg-canvas);
    color: var(--text-primary);
    font-size: 14px;
    line-height: 1.5;
}

.app {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
}

/* ─── Top bar ─────────────────────────────────────────────────── */

.topbar {
    display: flex;
    align-items: center;
    gap: 24px;
    height: var(--topbar-height);
    padding: 0 20px;
    background-color: var(--bg-surface);
    border-bottom: 1px solid var(--border-subtle);
    flex-shrink: 0;

    /* PWA / iOS standalone: when launched from the homescreen, the OS no
       longer reserves the status-bar strip, so the topbar would slide under
       the notch / camera island. env(safe-area-inset-top) is zero in a
       regular browser tab (requires viewport-fit=cover in the <meta
       viewport>, which App.razor now sets) and ~44–60px in standalone mode
       on iPhone X+. We add it to padding *and* grow the height by the same
       amount so the original 56px content area stays unchanged. */
    padding-top: env(safe-area-inset-top);
    height: calc(var(--topbar-height) + env(safe-area-inset-top));
}

.sidebar-toggle {
    /* Reset the topbar's 24px gap on the right side so the hamburger sits
       closer to the brand than the search box does to it. */
    margin-right: -16px;
    font-size: 18px;
}

@media (min-width: 768px) {
    /* Desktop semantics: the persisted preference hides the sidebar entirely.
       Below 768px the sidebar becomes an overlay drawer controlled by the
       transient `sidebar-open` class instead — see the mobile block below. */
    html.sidebar-collapsed .sidebar {
        display: none;
    }
}

html.sidebar-collapsed .brand {
    min-width: 0;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: calc(var(--sidebar-width) - 20px);
}

.brand-mark {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: conic-gradient(from 220deg at 50% 50%, #6366f1, #8b5cf6, #ec4899, #6366f1);
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.85), 0 0 0 1px rgba(15, 23, 42, 0.05);
}

.brand-name {
    font-weight: 600;
    font-size: 15px;
    letter-spacing: -0.01em;
    color: var(--text-primary);
}

.brand-env {
    font-size: 11px;
    font-weight: 500;
    color: var(--accent);
    background-color: var(--accent-soft);
    padding: 2px 8px;
    border-radius: 999px;
    text-transform: lowercase;
    letter-spacing: 0.02em;
}

.topbar-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
}

.icon-btn {
    position: relative;
    width: 34px;
    height: 34px;
    border: none;
    background: transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    font-size: 16px;
    transition: background-color 120ms ease, color 120ms ease;
}

.icon-btn:hover {
    background-color: var(--bg-canvas);
    color: var(--text-primary);
}

.badge-dot {
    position: absolute;
    top: 8px;
    right: 9px;
    width: 7px;
    height: 7px;
    background-color: var(--danger);
    border-radius: 50%;
    border: 2px solid var(--bg-surface);
}

.topbar-divider {
    width: 1px;
    height: 24px;
    background-color: var(--border-subtle);
    margin: 0 8px;
}

.user-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 4px 4px;
    border: none;
    background: transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 13.5px;
    transition: background-color 120ms ease;
}

.user-chip:hover {
    background-color: var(--bg-canvas);
}

.user-chip i {
    color: var(--text-muted);
    font-size: 11px;
}

.avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.user-name {
    font-weight: 500;
}

/* ─── Shell (sidebar + content) ───────────────────────────────── */

.shell {
    display: flex;
    flex: 1;
    overflow: hidden;
}

.sidebar {
    width: var(--sidebar-width);
    background-color: var(--bg-sidebar);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    overflow-y: auto;
}

.nav-menu {
    display: flex;
    flex-direction: column;
    padding: 12px 10px;
    gap: 1px;
    flex: 1;
}

.nav-item a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    border-radius: var(--radius-md);
    color: var(--text-on-dark);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 500;
    transition: background-color 120ms ease, color 120ms ease;
}

.nav-item a i {
    font-size: 16px;
    width: 18px;
    text-align: center;
    color: var(--text-muted);
    transition: color 120ms ease;
}

.nav-item a:hover {
    background-color: var(--bg-sidebar-hover);
    color: var(--text-on-dark-active);
}

.nav-item a:hover i {
    color: var(--text-on-dark);
}

.nav-item a.active {
    background-color: var(--bg-sidebar-active);
    color: var(--text-on-dark-active);
    position: relative;
}

.nav-item a.active::before {
    content: '';
    position: absolute;
    left: -10px;
    top: 8px;
    bottom: 8px;
    width: 3px;
    background-color: var(--accent);
    border-radius: 0 2px 2px 0;
}

.nav-item a.active i {
    color: var(--accent);
}

.sidebar-badge {
    margin-left: auto;
    padding: 1px 8px;
    background-color: rgba(255, 255, 255, 0.10);
    color: var(--text-on-dark-active);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.6;
}

.nav-item a:hover .sidebar-badge {
    background-color: rgba(255, 255, 255, 0.16);
}

.nav-item a.active .sidebar-badge {
    background-color: rgba(99, 102, 241, 0.32);
    color: #ffffff;
}

.sidebar-footer {
    padding: 14px 22px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.status {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11.5px;
    color: var(--text-on-dark);
    font-weight: 500;
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--success);
    box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.18);
}

.version {
    font-size: 11px;
    color: var(--text-muted);
    margin-left: 16px;
}

/* ─── Content ─────────────────────────────────────────────────── */

.content {
    flex: 1;
    overflow-y: auto;
    padding: 32px 40px;
    background-color: var(--bg-canvas);
}

.content h1 {
    margin: 0 0 8px 0;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--text-primary);
}

.content h1::after {
    content: '';
    display: block;
    width: 36px;
    height: 3px;
    background-color: var(--accent);
    border-radius: 2px;
    margin-top: 14px;
}

/* ─── Sidebar backdrop (mobile drawer dismiss target) ─────────── */

/* Plain <button> reset — only visible/active when html has `sidebar-open`,
   and only on narrow viewports (the rule below). The button gives us free
   accessible "tap outside to close" behaviour without an extra JS listener. */
.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: var(--topbar-height) 0 0 0;
    background: rgba(15, 23, 42, 0.45);
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    z-index: 50;
}

/* ─── Mobile shell (≤768px) ───────────────────────────────────── */

@media (max-width: 767.98px) {
    /* Topbar slims down: drop the env pill, the user-name (avatar stays),
       and the visual divider between actions and identity. */
    .topbar {
        gap: 8px;
        padding: 0 12px;
    }

    .brand {
        min-width: 0;
        flex-shrink: 1;
    }

    .brand-env,
    .user-name,
    .topbar-divider {
        display: none;
    }

    /* Sidebar becomes an off-canvas drawer. Fixed-position so it floats over
       content rather than reflowing it, full-height under the topbar, and
       slid out of view by default. `sidebar-open` brings it on screen.
       The top offset matches .topbar's standalone-mode height (base + safe
       area) so the drawer hugs the topbar's bottom edge on iPhone X+ in
       installed-PWA mode. The bottom inset keeps the last nav item clear of
       the iOS home indicator. */
    .sidebar {
        position: fixed;
        top: calc(var(--topbar-height) + env(safe-area-inset-top));
        bottom: 0;
        left: 0;
        z-index: 60;
        transform: translateX(-100%);
        transition: transform 180ms ease;
        box-shadow: 4px 0 16px -4px rgba(15, 23, 42, 0.18);
        padding-bottom: env(safe-area-inset-bottom);
    }

    html.sidebar-open .sidebar {
        transform: translateX(0);
    }

    html.sidebar-open .sidebar-backdrop {
        display: block;
    }

    /* Content gets the full row since the sidebar is now an overlay. Tighter
       padding so 375px phones don't waste 80px of horizontal space on gutters.
       The safe-area-inset-bottom keeps content clear of the iOS home indicator
       when running as an installed PWA. */
    .content {
        padding: 20px 16px;
        padding-bottom: calc(20px + env(safe-area-inset-bottom));
    }

    /* Any wide table inside the content area scrolls horizontally on its own
       rather than expanding the viewport. Setting `display: block` on the
       table makes it a scroll container; the browser wraps the descendants
       in an anonymous table box so column alignment is preserved. */
    .data-table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* ─── Auth ────────────────────────────────────────────────────── */

.sign-in-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    border-radius: var(--radius-md);
    background-color: var(--accent);
    color: #ffffff;
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
    transition: background-color 120ms ease, box-shadow 120ms ease;
}

.sign-in-btn:hover {
    background-color: #4f46e5;
    box-shadow: 0 1px 2px 0 rgba(79, 70, 229, 0.4);
}

.sign-in-btn i {
    font-size: 14px;
}

.user-chip {
    text-decoration: none;
}

.logout-form {
    display: contents;
}

/* ─── Bootstrap overrides (Sphere theme) ──────────────────────── */

.content hr {
    border: 0;
    border-top: 1px solid var(--border-subtle);
    margin: 18px 0;
}

/* Forms */

.form-control {
    width: 100%;
    padding: 9px 12px;
    background-color: var(--bg-surface);
    color: var(--text-primary);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.form-control:focus {
    outline: none;
    border-color: var(--accent);
    background-color: var(--bg-surface);
    color: var(--text-primary);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.14);
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--bg-canvas);
    color: var(--text-muted);
    cursor: not-allowed;
}

.form-control::placeholder {
    color: var(--text-muted);
}

.form-label {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
}

/* Replace Bootstrap's floating-label pattern with a stacked label-then-input */
.form-floating {
    position: static;
    display: flex;
    flex-direction: column-reverse;
    margin-bottom: 14px;
}

.form-floating > .form-control,
.form-floating > .form-control:focus,
.form-floating > .form-control:not(:placeholder-shown) {
    height: auto;
    min-height: auto;
    padding: 9px 12px;
}

.form-floating > label,
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label {
    position: static;
    transform: none;
    height: auto;
    padding: 0 0 6px 0;
    margin: 0;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
    pointer-events: auto;
    background: transparent;
    opacity: 1;
    z-index: auto;
}

/* Checkboxes */

.form-check-input {
    width: 16px;
    height: 16px;
    margin: 0;
    border: 1px solid var(--border-emphasis);
    border-radius: 4px;
    background-color: var(--bg-surface);
    cursor: pointer;
    accent-color: var(--accent);
}

.form-check-input:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.18);
    border-color: var(--accent);
}

.checkbox label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    cursor: pointer;
    font-size: 13.5px;
    color: var(--text-secondary);
}

/* Buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 18px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.4;
    cursor: pointer;
    text-decoration: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

.btn:focus,
.btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.22);
}

.btn-lg {
    padding: 11px 22px;
    font-size: 14px;
}

.btn-primary {
    background-color: var(--accent);
    color: #ffffff;
    border-color: var(--accent);
}

.btn-primary:hover {
    background-color: #4f46e5;
    border-color: #4f46e5;
    color: #ffffff;
}

.btn-danger {
    background-color: var(--danger);
    color: #ffffff;
    border-color: var(--danger);
}

.btn-danger:hover {
    background-color: #dc2626;
    border-color: #dc2626;
    color: #ffffff;
}

.btn-link {
    background-color: transparent;
    color: var(--accent);
    padding: 0;
    border: none;
}

.btn-link:hover {
    text-decoration: underline;
    color: #4f46e5;
}

/* Alerts */

.alert {
    padding: 12px 16px;
    margin: 0 0 16px 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: 13.5px;
    line-height: 1.55;
}

.alert-success {
    background-color: #f0fdf4;
    color: #14532d;
    border-color: #bbf7d0;
}

.alert-danger {
    background-color: #fef2f2;
    color: #7f1d1d;
    border-color: #fecaca;
}

.alert-warning {
    background-color: #fffbeb;
    color: #78350f;
    border-color: #fde68a;
}

.alert-info {
    background-color: var(--accent-soft);
    color: #312e81;
    border-color: #c7d2fe;
}

/* Nav pills (ManageNavMenu) */

.nav-pills {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.nav-pills .nav-item {
    margin: 0;
}

.nav-pills .nav-link {
    display: block;
    padding: 7px 12px;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 500;
    transition: background-color 120ms ease, color 120ms ease;
}

.nav-pills .nav-link:hover {
    background-color: var(--bg-canvas);
    color: var(--text-primary);
}

.nav-pills .nav-link.active {
    background-color: var(--accent-soft);
    color: var(--accent);
}

/* Validation / status text */

.text-danger {
    display: inline-block;
    color: var(--danger);
    font-size: 12.5px;
    font-weight: 500;
}

.text-success {
    color: var(--success);
}

.text-info {
    color: var(--accent);
}

.font-weight-bold {
    font-weight: 600;
}

/* Anonymous auth page shell (no sidebar / no topbar) */

.auth-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
    background:
        radial-gradient(circle at 20% 18%, rgba(99, 102, 241, 0.10), transparent 42%),
        radial-gradient(circle at 82% 84%, rgba(139, 92, 246, 0.07), transparent 42%),
        var(--bg-canvas);
}

.auth-page-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 28px;
}

.auth-page-brand .brand-mark {
    width: 28px;
    height: 28px;
}

.auth-page-brand .brand-name {
    font-size: 20px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.015em;
}

.auth-page-body {
    width: 100%;
    display: flex;
    justify-content: center;
}

.auth-page-body .auth-card {
    margin: 0;
}

.auth-page-footer {
    margin-top: 28px;
    color: var(--text-muted);
    font-size: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.auth-page-footer .status-dot {
    width: 6px;
    height: 6px;
    box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.18);
}

/* Auth card — Login and other anonymous auth pages */

.auth-card {
    max-width: 420px;
    margin: 8px auto 32px auto;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 32px 32px 28px 32px;
    box-shadow: var(--shadow-md);
}

.auth-card .auth-title {
    margin: 0 0 6px 0;
    font-size: 22px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.015em;
}

.auth-card .auth-title::after {
    display: none;
}

.auth-card .auth-subtitle {
    margin: 0 0 22px 0;
    font-size: 13.5px;
    color: var(--text-secondary);
}

.auth-card hr {
    margin: 0 0 18px 0;
}

/* Manage shell — two-column nav + content */

.manage-shell {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 32px;
    margin-top: 22px;
}

.manage-shell .manage-sidebar {
    border-right: 1px solid var(--border-subtle);
    padding-right: 16px;
}

.manage-shell .manage-content {
    min-width: 0;
}

@media (max-width: 720px) {
    .manage-shell {
        grid-template-columns: 1fr;
    }

    .manage-shell .manage-sidebar {
        border-right: none;
        border-bottom: 1px solid var(--border-subtle);
        padding-right: 0;
        padding-bottom: 16px;
    }
}

/* ─── Tabs ────────────────────────────────────────────────────── */

.tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border-subtle);
    margin: 18px 0 22px 0;
}

.tabs .tab {
    padding: 8px 14px;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 500;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 120ms ease, border-color 120ms ease;
}

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

.tabs .tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* ─── Data table ─────────────────────────────────────────────── */

.data-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    font-size: 13.5px;
}

.data-table th,
.data-table td {
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: middle;
}

.data-table th {
    font-weight: 600;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    background-color: var(--bg-canvas);
}

.data-table th.sortable {
    cursor: pointer;
    user-select: none;
    transition: color 100ms ease, background-color 100ms ease;
}

.data-table th.sortable:hover {
    color: var(--text-secondary);
    background-color: rgba(15, 23, 42, 0.03);
}

.data-table th.sortable.is-sorted {
    color: var(--text-primary);
}

.data-table th .sort-indicator {
    margin-left: 4px;
    color: var(--accent);
    font-size: 10.5px;
    vertical-align: middle;
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

.data-table tbody tr:hover {
    background-color: rgba(99, 102, 241, 0.04);
}

.data-table .cell-strong {
    font-weight: 600;
    color: var(--text-primary);
}

.data-table .cell-link {
    font-weight: 600;
    color: var(--text-primary);
    text-decoration: none;
}

.data-table .cell-link:hover {
    color: var(--accent);
    text-decoration: underline;
}

.data-table .cell-muted {
    color: var(--text-muted);
}

.data-table .project-input {
    padding: 5px 8px;
    font-size: 13px;
    background-color: transparent;
    border-color: transparent;
}

.data-table .project-input:hover {
    border-color: var(--border-subtle);
    background-color: var(--bg-surface);
}

.data-table .project-input:focus {
    border-color: var(--accent);
    background-color: var(--bg-surface);
}

.row-actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
}

.icon-btn-danger:hover {
    color: var(--danger);
    background-color: #fef2f2;
}

/* Row action menu (three-dot popover) */

.row-menu-wrapper {
    position: relative;
    display: flex;
    justify-content: flex-end;
}

/* Name cells in row grids (Active, Endpoints, Policies, Prompts) are
   buttons styled as links — clicking opens the same drill-down view as
   the kebab menu's primary action. Gives mobile users a real tap target
   without forcing them to hit the small three-dots button. */
.row-name-link {
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: var(--link, #1d4e5f);
    text-align: left;
    cursor: pointer;
    text-decoration: none;
}
.row-name-link:hover,
.row-name-link:focus-visible {
    text-decoration: underline;
    outline: none;
}
.row-name-link:focus-visible {
    outline: 2px solid var(--focus-ring, #2563eb);
    outline-offset: 2px;
    border-radius: 2px;
}

.row-menu-trigger {
    width: 30px;
    height: 30px;
    font-size: 15px;
}

.row-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 100;
    min-width: 180px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 10px 20px -6px rgba(15, 23, 42, 0.18), 0 4px 8px -4px rgba(15, 23, 42, 0.10);
    padding: 4px;
}

.row-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 10px;
    background-color: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: 13px;
    color: var(--text-primary);
    transition: background-color 80ms ease, color 80ms ease;
}

.row-menu-item:hover {
    background-color: var(--bg-canvas);
}

.row-menu-item i {
    width: 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: 14px;
    transition: color 80ms ease;
}

.row-menu-item:hover i {
    color: var(--text-secondary);
}

.row-menu-item-danger {
    color: var(--danger);
}

.row-menu-item-danger i {
    color: var(--danger);
}

.row-menu-item-danger:hover {
    background-color: #fef2f2;
    color: var(--danger);
}

.row-menu-item-danger:hover i {
    color: var(--danger);
}

.row-menu-separator {
    height: 1px;
    background-color: var(--border-subtle);
    margin: 4px 2px;
}

.menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 90;
    background-color: transparent;
}

/* Entry-point chips */

.entry-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.entry-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    font-size: 12px;
    line-height: 1.5;
}

.entry-chip .entry-name {
    font-weight: 600;
    color: var(--text-primary);
}

.entry-chip .entry-type {
    color: var(--text-secondary);
    font-style: italic;
}

.entry-chip .entry-type-json {
    color: var(--success);
    font-style: normal;
    font-weight: 500;
}

/* ─── Switch (toggle) ─────────────────────────────────────────── */

.switch {
    position: relative;
    display: inline-block;
    width: 34px;
    height: 20px;
    cursor: pointer;
    vertical-align: middle;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}

.switch-slider {
    position: absolute;
    inset: 0;
    background-color: var(--border-emphasis);
    border-radius: 999px;
    transition: background-color 120ms ease;
}

.switch-slider::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background-color: #ffffff;
    border-radius: 50%;
    transition: transform 120ms ease;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

.switch input:checked + .switch-slider {
    background-color: var(--accent);
}

.switch input:checked + .switch-slider::before {
    transform: translateX(14px);
}

.switch input:focus-visible + .switch-slider {
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.22);
}

/* ─── Page toolbar / state (shared across data pages) ─────────── */

.page-toolbar {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-bottom: 14px;
}

/* ─── Form rows used inside modal-body forms (Scheduler new-job dialog, etc.) ── */

.form-row {
    margin-bottom: 14px;
}

.form-row > label {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
}

.form-row--inline {
    display: grid;
    grid-template-columns: max-content 1fr 1fr;
    align-items: center;
    column-gap: 10px;
}

.form-row--inline > label {
    margin-bottom: 0;
}

.form-help {
    display: block;
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--text-muted);
}

.form-help code {
    font-size: 11px;
    color: var(--text-secondary);
}

.form-control--mono {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12.5px;
    line-height: 1.5;
}

/* Segmented control — two-or-three button toggle, used for Start/Message + Once/Cron in the
   scheduler new-job dialog. Sits on top of regular .btn-style buttons that get type="button". */
/* Flux Keys editor — form-tab rows. Each row is a Type pill + Name input
   (outputs only) + delete button, laid out on a single line. Skeleton-only;
   the per-type field forms are added in later slices. */
.fluxkeys-section-title {
    margin: 0.25rem 0 0.5rem;
    font-size: 0.95rem;
}

.fluxkeys-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0;
}

.fluxkeys-row--add {
    margin-top: 0.25rem;
}

.fluxkeys-kind {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: var(--radius-sm);
    background: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    font-size: 0.8125rem;
    color: var(--text-secondary);
    min-width: 5.5em;
    justify-content: center;
}

/* Per-row "card" wrapping a Type + (optional) Name header and a body with
   type-specific fields. Each card represents one OutputClients entry or one
   Services slot in the FluxConfig JSON the dialog produces. */
.fluxkeys-card {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    background: var(--bg-surface);
}

.fluxkeys-card-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.fluxkeys-card-spacer {
    flex: 1 1 auto;
}

.fluxkeys-card-body {
    margin-top: 0.5rem;
    padding-left: 0.75rem;
    border-left: 2px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.fluxkeys-field-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.fluxkeys-field-label {
    flex: 0 0 8.5em;
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin: 0;
}

.fluxkeys-field-row .form-control {
    flex: 1 1 auto;
}

.fluxkeys-cycle-amount {
    flex: 0 0 6em;
}

.fluxkeys-cycle-unit {
    flex: 0 0 8em;
}

.fluxkeys-stub {
    font-size: 0.85rem;
    font-style: italic;
}

.fluxkeys-inline-check {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    flex: 1 1 auto;
    font-size: 0.85rem;
}

/* Sub-block for HTTP input's PollChannels list — one channel per nested
   card. Keeps the inner cards visually distinct from the parent. */
.fluxkeys-subsection {
    margin-top: 0.25rem;
}

.fluxkeys-subsection-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}

.fluxkeys-channel {
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 0.4rem 0.6rem;
    margin-bottom: 0.4rem;
    background: var(--bg-canvas);
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

/* Slice 3 — validation indicators. Cards/channels with at least one error get
   a tinted border + background; per-field errors render as a small red
   line below the input. The dialog also shows a roll-up summary at the top. */
.fluxkeys-card--error {
    border-color: var(--danger, #dc3545);
    background: rgba(220, 53, 69, 0.04);
}

.fluxkeys-channel--error {
    border-color: var(--danger, #dc3545);
    background: rgba(220, 53, 69, 0.04);
}

.fluxkeys-field-error {
    display: block;
    color: var(--danger, #dc3545);
    font-size: 0.8rem;
    margin-top: -0.15rem;
}

.fluxkeys-field-error--indent {
    margin-left: calc(8.5em + 0.5rem);
}

.fluxkeys-name-wrap {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.fluxkeys-name-wrap .form-control {
    width: 100%;
}

.fluxkeys-issues {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.fluxkeys-issues-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
}

.fluxkeys-issues-list {
    margin: 0;
    padding-left: 1.6rem;
    font-size: 0.85rem;
}

.seg-group {
    display: inline-flex;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background-color: var(--bg-canvas);
    padding: 2px;
    gap: 2px;
}

.seg-btn {
    appearance: none;
    background: transparent;
    border: none;
    padding: 6px 14px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
    border-radius: calc(var(--radius-md) - 2px);
    cursor: pointer;
    transition: background-color 100ms ease, color 100ms ease;
    font-family: inherit;
}

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

.seg-btn.is-active {
    background-color: var(--bg-surface);
    color: var(--text-primary);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
}

/* Modal footer used by Scheduler dialogs — right-aligned button row. */
.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 22px;
    border-top: 1px solid var(--border-subtle);
    flex-shrink: 0;
}

/* ─── Policy editor (Development → Policies card) ────────────────────────── */

.policy-editor-shell {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 14px;
    height: calc(100vh - var(--topbar-height) - 220px);
    min-height: 480px;
}

.policy-editor-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    overflow: hidden;
}

.policy-editor-list .form-control {
    flex-shrink: 0;
}

.policy-list {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    flex: 1;
    min-height: 0;
}

.policy-list-item {
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color 100ms ease;
}

.policy-list-item:hover {
    background-color: var(--bg-canvas);
}

.policy-list-item.is-selected {
    background-color: var(--accent-soft);
}

.policy-list-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.policy-list-item.is-selected .policy-list-name {
    color: var(--accent);
}

.policy-list-meta {
    font-size: 11.5px;
    color: var(--text-muted);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.policy-editor-main {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px;
    overflow: hidden;
    min-width: 0;
}

.policy-editor-header {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    flex-wrap: wrap;
}

.policy-editor-fields {
    display: grid;
    grid-template-columns: 1fr 1fr 100px;
    gap: 10px;
    flex: 1 1 460px;
    min-width: 0;
}

.policy-editor-fields .form-row {
    margin-bottom: 0;
}

.policy-editor-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.policy-editor-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.policy-editor-dirty-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--accent);
    font-weight: 500;
}

.policy-editor-dirty-indicator i {
    font-size: 18px;
    line-height: 0;
}

.policy-editor-mount {
    flex: 1;
    min-height: 320px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

@media (max-width: 960px) {
    .policy-editor-shell {
        grid-template-columns: 1fr;
        height: auto;
    }

    .policy-editor-list {
        max-height: 240px;
    }
}

/* ─── Connector Maker page ────────────────────────────────────────────────── */

/* Anchored to the visible viewport. No `min-height` floor — on short viewports
   the shell compresses with the editor rather than overflowing `.content`'s
   scroll area (which would clip Monaco's bottom row + scrollbar handle). The
   260px subtraction covers .content's 32px top + 32px bottom padding, the
   page <h1> + .page-intro stack (~120px), and a small breathing-room margin. */
.connector-maker-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
    height: calc(100vh - var(--topbar-height) - 260px);
    min-height: 360px;
}

.connector-maker-main {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px;
    overflow: hidden;
    /* Flex children default to `min-height: auto` which refuses to shrink past
       intrinsic content size — that's what was letting `min-height: 320px` on
       .connector-maker-mount escape this container. Force shrinkability. */
    min-height: 0;
    min-width: 0;
    flex: 1;
}

.connector-maker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.connector-maker-meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-muted);
    min-width: 0;
    flex-wrap: wrap;
}

.connector-maker-runtime-label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
    margin: 0;
}

.connector-maker-runtime-select {
    width: auto;
    min-width: 180px;
    padding-top: 4px;
    padding-bottom: 4px;
    font-size: 13px;
}

.connector-maker-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-canvas);
    color: var(--text-muted);
    text-align: center;
    padding: 24px;
}

.connector-maker-placeholder i {
    font-size: 32px;
    display: block;
    margin-bottom: 8px;
    color: var(--border-strong);
}

.connector-maker-placeholder p {
    margin: 0;
    font-size: 14px;
}

.connector-maker-placeholder-hint {
    margin-top: 6px !important;
    font-size: 12.5px;
    max-width: 420px;
}

.form-required {
    color: var(--danger, #d62a2a);
    font-weight: 600;
}

.connector-maker-filename {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.connector-maker-meta-sep {
    color: var(--border-subtle);
}

.connector-maker-meta-hint {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
}

.connector-maker-dirty {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    color: var(--accent);
    font-weight: 500;
}

.connector-maker-dirty i {
    font-size: 18px;
    line-height: 0;
}

.connector-maker-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.connector-maker-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.connector-maker-hint {
    margin: 0;
    padding: 8px 10px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    color: var(--text-muted);
    line-height: 1.5;
}

.connector-maker-hint code {
    font-size: 12px;
    background-color: var(--bg-surface);
    padding: 1px 4px;
    border-radius: 3px;
}

.connector-maker-mount {
    flex: 1;
    /* Smaller usability floor than the previous 320px so the mount actually
       fits inside the shell on viewports where min-height kicks in. */
    min-height: 220px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

/* ─── KPI page ─────────────────────────────────────────────────────────────── */

.kpi-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.kpi-config-card {
    display: flex;
    flex-direction: column;
    gap: 18px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 18px 20px;
}

.kpi-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Pair Aggregation + Chart on a single row to save vertical space. Wraps on narrow screens. */
.kpi-section-row {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    align-items: flex-start;
}

.kpi-section-row > .kpi-section {
    flex: 1 1 auto;
    min-width: 0;
}

.kpi-section-subrow {
    margin-top: 8px;
}

.kpi-section h3 {
    margin: 0 0 2px 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.kpi-chip-tray {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 36px;
    padding: 6px 8px;
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-sm);
    background-color: var(--bg-canvas);
}

.kpi-chip-tray.is-empty {
    border-style: dashed;
}

.kpi-chip-empty {
    color: var(--text-muted);
    font-size: 12.5px;
    align-self: center;
}

.kpi-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 4px 3px 10px;
    background-color: var(--accent-soft);
    color: var(--accent);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
}

.kpi-chip-text {
    padding-block: 4px;
}

.kpi-chip-remove {
    appearance: none;
    border: none;
    background: transparent;
    color: inherit;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0.7;
    transition: background-color 100ms ease, opacity 100ms ease;
}

.kpi-chip-remove:hover {
    background-color: rgba(99, 102, 241, 0.16);
    opacity: 1;
}

.kpi-chip-picker {
    position: relative;
}

.kpi-chip-search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: 13px;
    pointer-events: none;
}

.kpi-chip-input {
    width: 100%;
    height: 34px;
    padding: 0 12px 0 32px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background-color: var(--bg-canvas);
    font-family: inherit;
    font-size: 13px;
    color: var(--text-primary);
    transition: border-color 120ms ease, background-color 120ms ease;
}

.kpi-chip-input:focus {
    outline: none;
    border-color: var(--accent);
    background-color: var(--bg-surface);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);
}

.kpi-chip-suggestions {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 100;
    list-style: none;
    margin: 0;
    padding: 4px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px -6px rgba(15, 23, 42, 0.15);
    max-height: 240px;
    overflow-y: auto;
}

.kpi-chip-suggestions li {
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary);
}

.kpi-chip-suggestions li:hover {
    background-color: var(--bg-canvas);
}

.kpi-chip-suggestion-empty {
    color: var(--text-muted);
    cursor: default !important;
    font-style: italic;
}

.kpi-chip-suggestion-empty:hover {
    background-color: transparent !important;
}

.kpi-presets {
    flex-wrap: wrap;
}

.kpi-window-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 10px;
}

.kpi-window-grid .form-row {
    margin-bottom: 0;
}

.kpi-config-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

.kpi-config-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.kpi-last-gen {
    font-size: 12px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
}

.kpi-chart-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 20px;
}

.kpi-chart-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.kpi-chart-header h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}

.kpi-chart-meta {
    font-size: 12px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
}

@media (max-width: 720px) {
    .kpi-window-grid {
        grid-template-columns: 1fr;
    }
}

/* ─── Tabs (Realms page) ─────────────────────────────────────────────────── */

.tab-nav {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--border-subtle);
    margin: 18px 0 18px 0;
    overflow-x: auto;
}

.tab-button {
    appearance: none;
    background: transparent;
    border: none;
    padding: 10px 16px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 100ms ease, border-color 100ms ease, background-color 100ms ease;
    font-family: inherit;
    white-space: nowrap;
}

.tab-button:hover {
    color: var(--text-primary);
    background-color: var(--bg-surface);
}

.tab-button.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.tab-button i {
    font-size: 14px;
}

.tab-content {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ─── Realms tab — small extras on top of the existing data-table styling ─ */

.cell-inline-icon {
    color: var(--text-muted);
    margin-right: 6px;
}

.cell-meta {
    margin-left: 10px;
    font-size: 12px;
    color: var(--accent);
    font-weight: 500;
}

/* ─── Realm detail page (/realms/{name}) ─────────────────────────────────── */

.page-breadcrumb {
    margin-bottom: 6px;
}

.breadcrumb-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 13px;
    text-decoration: none;
}

.breadcrumb-link:hover {
    color: var(--accent);
}

.page-title-icon {
    margin-right: 10px;
    color: var(--text-muted);
    font-size: 0.85em;
}

.realm-detail-shell {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.realm-detail-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.realm-detail-picker {
    flex: 1 1 320px;
    min-width: 240px;
    max-width: 480px;
}

.realm-detail-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.realm-detail-section-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.realm-detail-section-title > i {
    color: var(--text-muted);
}

.realm-detail-section-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    padding: 0 7px;
    height: 18px;
    border-radius: 9px;
    background-color: var(--bg-canvas);
    color: var(--text-muted);
    font-size: 11.5px;
    font-weight: 600;
}

.realm-detail-section-hint {
    margin: 0;
    font-size: 12.5px;
    color: var(--text-muted);
    line-height: 1.5;
}

.realm-detail-meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text-muted);
}

.realm-detail-meta code {
    color: var(--text-primary);
    background-color: var(--bg-canvas);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 12px;
}

.realm-detail-meta-sep {
    color: var(--border-subtle);
}

.realm-detail-meta-hint {
    color: var(--text-muted);
}

.realm-detail-redis-pre {
    margin: 0;
    padding: 14px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow-x: auto;
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--text-primary);
    white-space: pre;
}

/* ─── Types tab (master-detail) ──────────────────────────────────────────── */

.types-shell {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 14px;
    min-height: 560px;
}

.types-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    min-height: 0;
}

.types-list-toolbar {
    display: flex;
    gap: 6px;
    align-items: center;
}

.types-list-toolbar .form-control {
    flex: 1;
}

.types-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.types-list-items {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    flex: 1;
    max-height: 640px;
}

.types-list-item {
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 100ms ease, border-color 100ms ease;
    margin-bottom: 4px;
}

.types-list-item:hover {
    background-color: var(--bg-canvas);
}

.types-list-item.is-selected {
    background-color: var(--accent-soft);
    border-color: rgba(99, 102, 241, 0.25);
}

.types-list-name {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.types-list-item.is-selected .types-list-name {
    color: var(--accent);
}

.types-list-meta {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
}

.types-list-meta .dot {
    margin: 0 4px;
    opacity: 0.6;
}

/* Lambdas / Registry list items get a row of small pills for input/output type. */
.types-list-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
}

.types-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.types-list-version {
    margin-left: 6px;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--text-muted);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
}

.types-detail-version {
    margin-left: 8px;
    font-size: 13px;
    color: var(--text-muted);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
}

/* Readout grids for Lambdas / Registry detail panes. */
.types-readout-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px 18px;
}

.types-readout-grid .types-readout-full {
    grid-column: 1 / -1;
}

.types-readout-label {
    font-size: 11.5px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 4px;
}

.types-readout-value {
    font-size: 13px;
    color: var(--text-primary);
    word-break: break-word;
}

.types-readout-value--mono {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    color: var(--text-secondary);
}

/* Package upload row in the Lambdas detail view. */
.types-package-controls {
    margin-top: 12px;
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

.types-package-controls .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ─── Schema Validator page ──────────────────────────────────────────────── */

.schema-validator-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.schema-validator-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 14px;
    padding: 14px 16px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}

.schema-validator-picker {
    flex: 1 1 320px;
    min-width: 280px;
    margin-bottom: 0;
}

.schema-validator-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-left: auto;
}

.schema-validator-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.schema-validator-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.schema-validator-panel {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    min-width: 0;
}

.schema-validator-panel-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.schema-validator-panel-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.schema-validator-panel-meta {
    font-size: 11.5px;
    color: var(--text-muted);
}

.schema-validator-mount {
    height: 460px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.schema-validator-results {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.schema-validator-results-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.schema-validator-results-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.schema-validator-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.01em;
    border: 1px solid transparent;
}

.schema-validator-status--neutral {
    background-color: var(--accent-soft);
    color: var(--accent);
    border-color: rgba(99, 102, 241, 0.25);
}

.schema-validator-status--success {
    background-color: rgba(16, 185, 129, 0.12);
    color: #047857;
    border-color: rgba(16, 185, 129, 0.30);
}

.schema-validator-status--error {
    background-color: rgba(239, 68, 68, 0.12);
    color: #b91c1c;
    border-color: rgba(239, 68, 68, 0.30);
}

.schema-validator-empty {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
    font-style: italic;
}

.schema-validator-result-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 320px;
    overflow-y: auto;
}

.schema-validator-result-line {
    padding: 6px 10px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    color: var(--text-primary);
    word-break: break-word;
    white-space: pre-wrap;
    line-height: 1.5;
}

/* Dark mode tweaks: keep the status pill colours readable. */
html.dark .schema-validator-status--success {
    color: #6ee7b7;
}

html.dark .schema-validator-status--error {
    color: #fca5a5;
}

@media (max-width: 1024px) {
    .schema-validator-grid {
        grid-template-columns: 1fr;
    }

    .schema-validator-actions {
        margin-left: 0;
    }
}

.types-detail {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 18px 22px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

.types-empty-pane {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 6px;
    padding: 48px 16px;
}

.types-empty-pane i {
    font-size: 36px;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.types-empty-pane h3 {
    margin: 0;
    font-size: 15px;
    color: var(--text-primary);
}

.types-empty-pane p {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

.types-detail-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.types-detail-title h3 {
    margin: 0 0 4px 0;
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
}

.types-detail-meta {
    font-size: 12px;
    color: var(--text-muted);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
}

.types-detail-meta .dot {
    margin: 0 4px;
    opacity: 0.6;
}

.types-detail-actions {
    display: flex;
    gap: 6px;
    align-items: center;
}

.types-detail-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.types-form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 14px;
}

.types-form-grid .form-row--full {
    grid-column: 1 / -1;
}

.form-help-inline {
    margin-left: 8px;
    font-size: 11.5px;
    color: var(--text-muted);
    font-weight: 400;
}

.types-readout {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.types-readout-card {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    background-color: var(--bg-canvas);
}

.types-readout-card h4 {
    margin: 0 0 8px 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.types-readout-card-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 8px;
}

.types-readout-card-header h4 {
    margin: 0;
}

.types-readout-meta {
    font-size: 11.5px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
}

.types-description {
    margin: 0;
    color: var(--text-primary);
    white-space: pre-wrap;
    line-height: 1.55;
    font-size: 13px;
}

.types-empty-inline {
    margin: 0;
    color: var(--text-muted);
    font-style: italic;
    font-size: 13px;
}

/* Placeholder card used by the Lambdas / Registry tabs */
.placeholder-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 48px 32px;
    background-color: var(--bg-surface);
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
}

.placeholder-card .placeholder-icon {
    font-size: 36px;
    color: var(--text-muted);
    margin-bottom: 4px;
}

.placeholder-card h3 {
    margin: 0;
    font-size: 15px;
    color: var(--text-primary);
    font-weight: 600;
}

.placeholder-card p {
    margin: 0;
    font-size: 13px;
    line-height: 1.55;
    max-width: 540px;
}

.placeholder-card .placeholder-status {
    margin-top: 8px;
    color: var(--text-muted);
    font-size: 12px;
    font-style: italic;
}

@media (max-width: 960px) {
    .types-shell {
        grid-template-columns: 1fr;
    }

    .types-list-items {
        max-height: 280px;
    }

    .types-form-grid {
        grid-template-columns: 1fr;
    }
}

.page-toolbar .form-control {
    max-width: 340px;
}

.page-toolbar .btn-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.page-loading,
.page-count {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 12.5px;
    font-feature-settings: 'tnum';
}

.page-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--text-muted);
    background-color: var(--bg-surface);
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-md);
    font-size: 13.5px;
}

/* ─── Data table — id / center / indicator-dot ────────────────── */

.data-table .cell-id {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    color: var(--text-secondary);
    max-width: 18em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.data-table .cell-center {
    text-align: center;
}

.indicator-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    vertical-align: middle;
}

.indicator-dot-active {
    background-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.18);
}

.indicator-dot-idle {
    background-color: var(--border-emphasis);
}

/* Green "online" dot — used in RealmsTab's Details dialog to flag the
   Hades nodes that answered the ping. Same 8px shape as the other
   indicator-dot variants; pulls from --success so light/dark themes
   carry the right green automatically. */
.indicator-dot-online {
    background-color: var(--success);
    box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.18);
}

/* Active-Hades node list inside the Details modal — strip the default
   bullet so the indicator-dot is the only marker, and lay rows out as
   "dot + identity" with a comfortable gap. */
.details-node-list {
    list-style: none;
    padding: 0;
    margin: 8px 0 0;
}

.details-node-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 0;
}

/* Flux node realm — small label sat next to the IP code so an operator
   can see which realm each pod belongs to at a glance. Subdued type so
   the IP (the operationally relevant field) keeps visual priority. */
.flux-node-realm {
    display: inline-block;
    min-width: 90px;
    padding: 1px 8px;
    border-radius: var(--radius-sm, 4px);
    background-color: var(--bg-surface, rgba(99, 102, 241, 0.08));
    border: 1px solid var(--border-subtle, rgba(0, 0, 0, 0.08));
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary, inherit);
    line-height: 1.4;
}

.flux-node-realm-empty {
    color: var(--text-muted, #888);
    font-style: italic;
}

/* ─── Bulk delete toolbar / search banner ─────────────────────── */

.bulk-toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 14px;
    padding: 8px 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}

.bulk-toolbar .bulk-label {
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-right: 2px;
}

.bulk-toolbar .form-control {
    max-width: none;
}

.bulk-toolbar .bulk-flow-select {
    flex: 1 1 220px;
    min-width: 180px;
}

.bulk-toolbar .bulk-date-range {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}

.bulk-toolbar .bulk-date {
    flex: 0 0 auto;
    width: 175px;
    font-feature-settings: 'tnum';
}

.bulk-toolbar .bulk-sep {
    color: var(--text-muted);
    font-size: 13px;
}

.bulk-toolbar .bulk-delete-btn {
    flex: 0 0 auto;
}

.bulk-error {
    margin: -6px 0 14px 0;
    padding: 6px 12px;
    color: var(--danger);
    font-size: 12.5px;
    background-color: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: var(--radius-md);
}

.search-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    margin-bottom: 12px;
    background-color: var(--accent-soft);
    border: 1px solid #c7d2fe;
    border-radius: var(--radius-md);
    font-size: 13px;
    color: #312e81;
}

.search-banner i {
    color: var(--accent);
    font-size: 14px;
}

/* ─── Generic modal dialog (Show, Dependencies, …) ────────────── */

.modal-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
}

.modal-dialog {
    background-color: var(--bg-surface);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 48px -12px rgba(15, 23, 42, 0.25);
    width: 100%;
    max-width: 680px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    /* Bootstrap 5.3's .modal-dialog sets pointer-events: none (its design assumes a
       .modal-content child re-enables them). Sphere uses .modal-dialog directly, so
       re-enable here or the overlay swallows every click and closes the dialog. */
    pointer-events: auto;
    position: relative;
}

.modal-dialog--wide {
    max-width: 960px;
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 22px;
    border-bottom: 1px solid var(--border-subtle);
    flex-shrink: 0;
}

.modal-header h3 {
    margin: 0;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.modal-header .modal-subtitle {
    font-weight: 500;
    color: var(--text-secondary);
    margin-left: 4px;
}

.modal-close {
    background: transparent;
    border: none;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    transition: background-color 100ms ease, color 100ms ease;
}

.modal-close:hover {
    background-color: var(--bg-canvas);
    color: var(--text-primary);
}

.modal-body {
    padding: 18px 22px;
    overflow-y: auto;
}

.modal-hint {
    margin: 0 0 14px 0;
    font-size: 12.5px;
    color: var(--text-muted);
}

.policy-code {
    margin: 0;
    padding: 16px 18px;
    background-color: #0f172a;
    color: #e2e8f0;
    border-radius: var(--radius-md);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12.5px;
    line-height: 1.55;
    overflow: auto;
    max-height: calc(85vh - 140px);
    white-space: pre;
    tab-size: 4;
}

.policy-code code {
    color: inherit;
    background: transparent;
    font: inherit;
}

/* ─── Inline page banner (e.g. cache refresh result) ──────────── */

.page-banner {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.alert-close {
    background: transparent;
    border: none;
    color: inherit;
    opacity: 0.55;
    cursor: pointer;
    padding: 0;
    line-height: 1;
    font-size: 12px;
    transition: opacity 100ms ease;
}

.alert-close:hover {
    opacity: 1;
}

/* ─── Confirm dialog ──────────────────────────────────────────── */

.confirm-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
}

.confirm-dialog {
    background-color: var(--bg-surface);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 48px -12px rgba(15, 23, 42, 0.25);
    padding: 24px 28px 20px 28px;
    max-width: 440px;
    width: 100%;
    /* See note on .modal-dialog — same Bootstrap pointer-events conflict applies here. */
    pointer-events: auto;
    position: relative;
}

.confirm-dialog h3 {
    margin: 0 0 8px 0;
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
}

.confirm-dialog p {
    margin: 0 0 18px 0;
    color: var(--text-secondary);
    font-size: 13.5px;
    line-height: 1.55;
}

.confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 4px;
}

/* Extra detail paragraphs + lists used by the Endpoints "delete flow"
   confirm dialog when there are orphan/kept dataweaves to display. The
   default .confirm-dialog max-width (440px) is too tight when these are
   present; widen it via the modifier below. */
.confirm-dialog--wide {
    max-width: 580px;
}

.confirm-detail {
    margin: 0 0 6px 0 !important;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.5;
}

.confirm-detail--muted {
    color: var(--text-muted);
    font-size: 12.5px;
}

.confirm-list {
    margin: 0 0 14px 0;
    padding-left: 20px;
    font-size: 12.5px;
    color: var(--text-primary);
    line-height: 1.7;
    max-height: 160px;
    overflow: auto;
}

.confirm-list--muted {
    color: var(--text-muted);
}

.confirm-list code {
    font-size: 11.5px;
}

/* ─── Page intro paragraph ────────────────────────────────────── */

.page-intro {
    margin: -2px 0 20px 0;
    color: var(--text-secondary);
    font-size: 13.5px;
    line-height: 1.55;
    max-width: 720px;
}

/* ─── App-card dashboard tiles (Architecture, future Apps page) ─ */

.app-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 16px;
    margin-top: 22px;
}

.app-card {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 20px 22px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    position: relative;
    transition:
        border-color 160ms ease,
        transform 160ms ease,
        box-shadow 160ms ease,
        background-color 160ms ease;
}

.app-card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.app-card-icon {
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background-color: var(--accent-soft);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    transition: background-color 160ms ease, color 160ms ease;
}

.app-card:hover .app-card-icon {
    background-color: var(--accent);
    color: #ffffff;
}

.app-card-content {
    flex: 1 1 auto;
    min-width: 0;
}

.app-card-category {
    display: block;
    margin-bottom: 4px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.app-card-title {
    margin: 0 0 6px 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

.app-card-title::after {
    display: none;
}

.app-card-description {
    margin: 0;
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.5;
}

.app-card-action {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 16px;
    transition: color 160ms ease, transform 160ms ease;
}

.app-card:hover .app-card-action {
    color: var(--accent);
    transform: translateX(3px);
}

/* ─── Inbox (Tasks) ───────────────────────────────────────────── */

.unread-pill {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    background-color: var(--accent-soft);
    color: var(--accent);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
}

.inbox-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 6px;
}

.inbox-row {
    display: flex;
    gap: 10px;
    align-items: stretch;
    width: 100%;
    padding: 12px 14px;
    /* Recessed at rest — sits visibly inside the list surface (which is
       --bg-surface). The border defines each card so adjacent rows don't
       blur into a single column. */
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    text-align: left;
    cursor: pointer;
    font: inherit;
    color: inherit;
    transition: background-color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
}

.inbox-row:hover {
    /* Hover lifts the row: matches the list surface + subtle elevation +
       slightly stronger border, so the hovered row reads as raised rather
       than just tinted. */
    background-color: var(--bg-surface);
    border-color: var(--text-muted);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.inbox-row:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--bg-surface), 0 0 0 4px var(--accent);
}

.inbox-row-indicator {
    flex: 0 0 auto;
    width: 4px;
    border-radius: 2px;
    background-color: transparent;
    align-self: stretch;
}

.inbox-row--unread .inbox-row-indicator {
    background-color: var(--accent);
}

.inbox-row-main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.inbox-row-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 12.5px;
    color: var(--text-secondary);
}

.inbox-row-from {
    font-weight: 500;
    color: var(--text-primary);
}

.inbox-row-time {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.inbox-row-subject {
    font-size: 14px;
    color: var(--text-primary);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.inbox-row--unread .inbox-row-subject {
    font-weight: 700;
}

.inbox-row-bottom {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 12.5px;
    color: var(--text-muted);
}

.inbox-row-preview {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.inbox-row-flow {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
}

.inbox-row-flow i {
    font-size: 12px;
    color: var(--accent);
}

/* Detail view */

.inbox-detail {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.inbox-detail-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    border-bottom: 1px solid var(--border-subtle);
    background-color: var(--bg-canvas);
}

.inbox-detail-source {
    font-size: 12px;
    color: var(--text-muted);
}

.inbox-detail-body {
    padding: 24px 28px;
}

.inbox-detail-subject {
    margin: 0 0 12px 0;
    font-size: 20px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

.inbox-detail-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    margin-bottom: 18px;
    font-size: 13px;
    color: var(--text-secondary);
}

.inbox-detail-meta-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-right: 4px;
}

.inbox-detail-text {
    margin-bottom: 24px;
    padding: 16px 18px;
    background-color: var(--bg-canvas);
    border-left: 3px solid var(--border-emphasis);
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    color: var(--text-primary);
    white-space: pre-wrap;
    line-height: 1.55;
}

/* Schema form */

.schema-form {
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 20px 22px;
}

.schema-form-title {
    margin: 0 0 16px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.schema-form-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}

.schema-form-field label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
}

.schema-form-required {
    color: var(--danger);
    margin-left: 3px;
    font-weight: 600;
}

.schema-form-switch {
    align-self: flex-start;
}

.schema-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--border-subtle);
}

/* ─── Tabs as <button> elements (Home tabs are state-based, not URL-based) ── */

.tabs button.tab {
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text-secondary);
    padding: 8px 14px;
    margin-bottom: -1px;
    transition: color 120ms ease, border-color 120ms ease;
}

.tabs button.tab:hover {
    color: var(--text-primary);
}

.tabs button.tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* ─── Home: friendly empty-state placeholders for stub tabs ──── */

.home-tab-empty {
    text-align: center;
    padding: 56px 24px;
    max-width: 560px;
    margin: 24px auto;
}

.home-tab-empty .home-tab-empty-icon {
    width: 56px;
    height: 56px;
    margin: 0 auto 18px auto;
    border-radius: 50%;
    background-color: var(--accent-soft);
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
}

.home-tab-empty h3 {
    margin: 0 0 8px 0;
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
}

.home-tab-empty p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 13.5px;
    line-height: 1.55;
}

/* ─── Home: User Info tab ─────────────────────────────────────── */

.user-info-tab {
    margin-top: 18px;
}

.user-info-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 20px 24px;
}

.user-info-header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding-bottom: 16px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border-subtle);
}

.user-info-avatar {
    width: 44px;
    height: 44px;
    font-size: 16px;
}

.user-info-identity h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}

.user-info-meta {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--text-muted);
}

.user-info-claims h4 {
    margin: 0 0 12px 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* ─── Home: Console tab ───────────────────────────────────────── */

.console-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    margin: 18px 0 12px 0;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}

.console-toolbar-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin-right: 2px;
}

.console-toolbar .console-select {
    flex: 0 0 auto;
    max-width: none;
    width: 12em;
}

.console-channel {
    flex: 0 0 auto;
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    padding: 4px 10px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    color: var(--text-secondary);
}

.console-toolbar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

.console-mode-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-secondary);
    cursor: pointer;
    margin: 0 6px;
}

.console-mode-toggle input {
    margin: 0;
}

.console-status {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text-secondary);
    margin-bottom: 8px;
}

.console-status code {
    font-size: 11.5px;
    color: var(--accent);
    background: transparent;
}

.console-output {
    background-color: #0b1220;
    color: #34d399;
    border: 1px solid #1e293b;
    border-radius: var(--radius-md);
    padding: 14px 16px;
    /* Grow the console until it nearly reaches the bottom of the viewport. The
       subtracted value approximates the chrome above (app header + page intro +
       tab strip + console toolbar + status row + alert banner) plus a small
       trailing gutter so the page doesn't scroll. */
    height: calc(100vh - 320px);
    min-height: 320px;
    overflow-y: auto;
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    line-height: 1.55;
}

.console-output--amber {
    color: #f59e0b;
}

/* Standalone pop-out at /webconsole — uses BlankLayout, so there's no Sphere
   chrome above to reserve viewport height for. Reclaim that height for the
   live output and add a comfortable gutter. */
.webconsole-shell {
    padding: 16px 20px;
    height: 100vh;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.webconsole-shell .console-output {
    /* Fit-to-viewport minus toolbar (~50px) + status row (~28px) + paddings. */
    height: calc(100vh - 140px);
    min-height: 240px;
    flex: 1 1 auto;
}

.console-output-empty {
    color: #64748b;
    font-style: italic;
}

.console-line {
    display: flex;
    gap: 10px;
    padding: 2px 0;
    border-bottom: 1px solid rgba(148, 163, 184, 0.06);
    white-space: pre-wrap;
    word-break: break-word;
}

.console-line:last-child {
    border-bottom: none;
}

.console-line-time {
    flex: 0 0 auto;
    color: rgba(148, 163, 184, 0.65);
    font-variant-numeric: tabular-nums;
}

.console-line-channel {
    flex: 0 0 auto;
    color: #818cf8;
    font-weight: 500;
}

.console-line-text {
    flex: 1 1 auto;
    color: inherit;
}

/* ─── Dark mode ────────────────────────────────────────────────────────────
   Activated when <html class="dark"> is set (App.razor head script handles this
   before first paint, gated by localStorage and a path check for /workflow-editor).
   Most components route through the variables below, so flipping them does the
   heavy lifting. A few hardcoded selectors (alerts, native form controls) need
   explicit overrides at the bottom of this block.
   ─────────────────────────────────────────────────────────────────────────── */

html.dark {
    --bg-canvas: #0b1220;
    --bg-surface: #131c2f;
    --bg-sidebar: #0a0f1c;
    --bg-sidebar-hover: rgba(255, 255, 255, 0.05);
    --bg-sidebar-active: rgba(99, 102, 241, 0.22);
    --border-subtle: #1e293b;
    --border-emphasis: #334155;
    --text-primary: #e2e8f0;
    --text-secondary: #94a3b8;
    --text-muted: #64748b;
    --text-on-dark: #cbd5e1;
    --text-on-dark-active: #ffffff;
    --accent: #818cf8;
    --accent-soft: rgba(129, 140, 248, 0.18);
    --success: #34d399;
    --danger: #f87171;
    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.35);
    --shadow-md: 0 4px 12px -2px rgba(0, 0, 0, 0.45), 0 2px 4px -2px rgba(0, 0, 0, 0.30);
}

html.dark body,
html.dark .home-shell,
html.dark .auth-shell,
html.dark .manage-shell {
    color-scheme: dark;
}

/* Alerts — Sphere's light versions are pastel; dark versions are tinted-on-dark. */
html.dark .alert-success {
    background-color: rgba(16, 185, 129, 0.12);
    color: #6ee7b7;
    border-color: rgba(16, 185, 129, 0.30);
}
html.dark .alert-danger {
    background-color: rgba(239, 68, 68, 0.12);
    color: #fca5a5;
    border-color: rgba(239, 68, 68, 0.30);
}
html.dark .alert-warning {
    background-color: rgba(245, 158, 11, 0.12);
    color: #fcd34d;
    border-color: rgba(245, 158, 11, 0.30);
}
html.dark .alert-info {
    background-color: rgba(129, 140, 248, 0.12);
    color: #a5b4fc;
    border-color: rgba(129, 140, 248, 0.30);
}

/* Native form controls — make the browser pick dark chrome (scrollbars, datetime pickers). */
html.dark .form-control,
html.dark select.form-control,
html.dark input.form-control,
html.dark textarea.form-control {
    color-scheme: dark;
    background-color: var(--bg-canvas);
    color: var(--text-primary);
    border-color: var(--border-subtle);
}
html.dark .form-control:focus {
    background-color: var(--bg-surface);
}
html.dark .form-control::placeholder {
    color: var(--text-muted);
}

/* Data table row hover: the light-mode value sits on a near-white surface and
   reads gray; on dark it'd disappear into the surface, so use a pale highlight. */
html.dark .data-table tbody tr:hover {
    background-color: rgba(255, 255, 255, 0.03);
}

/* KPI chip suggestion list — its boxshadow needs more contrast on dark. */
html.dark .kpi-chip-suggestions {
    box-shadow: 0 8px 24px -6px rgba(0, 0, 0, 0.6);
}

/* Theme toggle icon swap. Only one of the two <i> elements inside .theme-toggle
   shows at a time, driven by html.dark. */
.theme-icon-dark { display: none; }
html.dark .theme-icon-light { display: none; }
html.dark .theme-icon-dark { display: inline; }

/* ─── Flow Launcher page ─────────────────────────────────────────────────── */

.flow-launcher-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.flow-launcher-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 14px;
    padding: 14px 16px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}

.flow-launcher-toolbar-field {
    flex: 1 1 280px;
    min-width: 240px;
    margin-bottom: 0;
}

.flow-launcher-grid {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    gap: 14px;
}

.flow-launcher-panel {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    min-width: 0;
}

.flow-launcher-panel-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.flow-launcher-panel-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.flow-launcher-panel-meta {
    font-size: 11.5px;
    color: var(--text-muted);
}

.flow-launcher-panel-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.flow-launcher-panel-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.flow-launcher-mount {
    height: 460px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.flow-launcher-launch-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 18px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    flex-wrap: wrap;
}

.flow-launcher-launch-copy {
    color: var(--text-secondary);
    font-size: 13px;
    flex: 1;
    min-width: 240px;
}

.flow-launcher-url {
    background-color: var(--bg-canvas);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 11.5px;
    color: var(--text-primary);
    word-break: break-all;
}

.flow-launcher-launch-card .btn-lg {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.flow-launcher-output {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.flow-launcher-output-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.flow-launcher-output-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.flow-launcher-output-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.flow-launcher-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-secondary);
    cursor: pointer;
}

.flow-launcher-toggle input[type="checkbox"] {
    margin: 0;
    cursor: pointer;
}

.flow-launcher-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.01em;
    border: 1px solid transparent;
    white-space: nowrap;
}

.flow-launcher-status--neutral {
    background-color: var(--accent-soft);
    color: var(--accent);
    border-color: rgba(99, 102, 241, 0.25);
}

.flow-launcher-status--success {
    background-color: rgba(16, 185, 129, 0.12);
    color: #047857;
    border-color: rgba(16, 185, 129, 0.30);
}

.flow-launcher-status--warning {
    background-color: rgba(245, 158, 11, 0.12);
    color: #92400e;
    border-color: rgba(245, 158, 11, 0.30);
}

.flow-launcher-status--error {
    background-color: rgba(239, 68, 68, 0.12);
    color: #b91c1c;
    border-color: rgba(239, 68, 68, 0.30);
}

html.dark .flow-launcher-status--success { color: #6ee7b7; }
html.dark .flow-launcher-status--warning { color: #fcd34d; }
html.dark .flow-launcher-status--error   { color: #fca5a5; }

@media (max-width: 1024px) {
    .flow-launcher-grid {
        grid-template-columns: 1fr;
    }
}

/* ─── Dataweave Editor ───────────────────────────────────────────────────── */

/* Same master-detail shell as the Policy Editor, but the main pane fits both
   the Monaco editor and the test-runner panel below it — so the shell goes
   auto-height (vs the Policy Editor's locked 100vh-ish) and the page scrolls. */
.dataweave-editor-shell {
    height: auto;
    min-height: 0;
}

.dataweave-editor-shell .policy-editor-list {
    /* Sticky list rail so it stays visible while the right pane scrolls. */
    position: sticky;
    top: 0;
    max-height: calc(100vh - var(--topbar-height) - 64px);
    align-self: flex-start;
}

.dataweave-editor-shell .policy-editor-main {
    overflow: visible;
}

.dataweave-editor-fields {
    grid-template-columns: 1fr;
}

.dataweave-editor-mount {
    /* Override the Policy Editor's flex:1 so the editor + test panel coexist. */
    flex: none;
    height: 460px;
    min-height: 320px;
}

.dataweave-test-panel {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px 16px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
}

.dataweave-test-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.dataweave-test-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}

.dataweave-test-subtitle {
    display: block;
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
}

.dataweave-test-subtitle code {
    background-color: var(--bg-surface);
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    color: var(--text-primary);
}

.dataweave-test-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.dataweave-test-controls .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.dataweave-test-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.dataweave-test-grid .form-row {
    margin-bottom: 0;
    min-width: 0;
}

.dataweave-test-textarea {
    resize: vertical;
    min-height: 180px;
}

.dataweave-test-actions {
    display: flex;
    justify-content: flex-start;
}

.dataweave-test-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.dataweave-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.01em;
    border: 1px solid transparent;
    white-space: nowrap;
}

.dataweave-status--neutral {
    background-color: var(--accent-soft);
    color: var(--accent);
    border-color: rgba(99, 102, 241, 0.25);
}

.dataweave-status--success {
    background-color: rgba(16, 185, 129, 0.12);
    color: #047857;
    border-color: rgba(16, 185, 129, 0.30);
}

.dataweave-status--warning {
    background-color: rgba(245, 158, 11, 0.12);
    color: #92400e;
    border-color: rgba(245, 158, 11, 0.30);
}

.dataweave-status--error {
    background-color: rgba(239, 68, 68, 0.12);
    color: #b91c1c;
    border-color: rgba(239, 68, 68, 0.30);
}

html.dark .dataweave-status--success { color: #6ee7b7; }
html.dark .dataweave-status--warning { color: #fcd34d; }
html.dark .dataweave-status--error   { color: #fca5a5; }

@media (max-width: 1024px) {
    .dataweave-test-grid {
        grid-template-columns: 1fr;
    }
}

/* ─── Types reference dialog (Dataweave editor) ──────────────────────────── */

/* Two-pane layout: scrollable name list on the left, definition preview on
   the right. Sized to fill the .modal-dialog--wide max-width minus padding,
   capped against the dialog's max-height so the inner Monaco mount always
   has a deterministic height instead of stretching the modal off-screen. */
.types-dialog-grid {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 14px;
    min-height: 460px;
    height: 60vh;
}

.types-dialog-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 10px;
    overflow: hidden;
    min-height: 0;
}

.types-dialog-list .policy-list {
    overflow-y: auto;
    flex: 1;
    min-height: 0;
    margin: 0;
}

.types-dialog-detail {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
    min-height: 0;
}

.types-dialog-detail-header h4 {
    margin: 0 0 4px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}

.types-dialog-desc {
    margin: 0 0 6px 0;
    font-size: 12.5px;
    color: var(--text-secondary);
}

.types-dialog-labels {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.types-dialog-label {
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 9999px;
    background-color: var(--accent-soft);
    color: var(--accent);
}

.types-dialog-preview {
    flex: 1;
    min-height: 240px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.types-dialog-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-muted);
    text-align: center;
}

.types-dialog-empty i {
    font-size: 28px;
}

@media (max-width: 860px) {
    .types-dialog-grid {
        grid-template-columns: 1fr;
        height: auto;
    }
    .types-dialog-list {
        max-height: 240px;
    }
}

/* ─── Forms Designer ─────────────────────────────────────────────────────── */

.forms-designer-fields {
    grid-template-columns: 2fr 1fr 1fr;
}

.forms-designer-tabs {
    margin: 0 0 12px 0;
}

/* Schema / Form editors are always in the DOM so Monaco doesn't remount on tab
   switches; we just hide the non-active pane via display:none. */
.forms-designer-pane { display: none; }
.forms-designer-pane.is-visible { display: block; }

.forms-designer-preview {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.forms-designer-preview-form,
.forms-designer-preview-model {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    min-width: 0;
}

.forms-designer-preview-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}
.forms-designer-preview-header h3 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-primary);
}
.forms-designer-preview-meta {
    font-size: 11.5px;
    color: var(--text-muted);
}
.forms-designer-preview-mount { min-height: 320px; }

.forms-designer-preview-model-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}
.forms-designer-preview-model-toggle {
    padding: 2px 6px;
    font-size: 12px;
    line-height: 1;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* Editable variant — same monospace dark slab as .policy-code so toggling
   between view/edit doesn't shift the layout, but rendered as a textarea so
   the user can actually type into the model. */
textarea.forms-designer-preview-model-edit {
    width: 100%;
    min-height: 320px;
    max-height: calc(85vh - 140px);
    border: none;
    resize: vertical;
    white-space: pre;
    overflow: auto;
}
textarea.forms-designer-preview-model-edit:focus {
    outline: 2px solid var(--accent, #3b82f6);
    outline-offset: -2px;
}

/* Vanilla preview renderer classes (emitted by js/forms-preview.js). */
.forms-preview-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.forms-preview-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.forms-preview-label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-secondary);
}
.forms-preview-label--inline {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.forms-preview-checkbox { margin-right: 4px; }
.forms-preview-input { font-family: inherit; font-size: 13px; }
.forms-preview-help { font-size: 11.5px; color: var(--text-muted); }
.forms-preview-fieldset {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.forms-preview-legend {
    padding: 0 6px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Author-supplied `style` on a uischema entry becomes one or more CSS classes
   on the field's wrapper. The set below covers the common "layout" cases the
   Forms Designer is likely to emit; bespoke values pass through verbatim so
   app-level CSS (or Bootstrap utilities) can extend it. */
.forms-preview-fieldset.row,
.forms-preview-fieldset.forms-preview-row {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
}
.forms-preview-fieldset.row > .forms-preview-field,
.forms-preview-fieldset.forms-preview-row > .forms-preview-field {
    flex: 1 1 200px;
}
.forms-preview-field.inline {
    flex-direction: row;
    align-items: center;
    gap: 10px;
}
.forms-preview-field.inline > .forms-preview-label { flex: 0 0 auto; }
.forms-preview-field.inline > .forms-preview-input { flex: 1 1 auto; }
.forms-preview-field.half  { flex-basis: calc(50% - 12px); }
.forms-preview-field.third { flex-basis: calc(33.333% - 12px); }
.forms-preview-field.quarter { flex-basis: calc(25% - 12px); }

/* Read-only field treatment. Applied by the renderer when the uischema entry
   carries `readonly: true`. Controls inside are also `disabled` (set by
   lockdownReadonly in forms-preview.js); the CSS adds a visual hint so the
   author can spot read-only fields at a glance even when the input itself
   doesn't change shape much (e.g. a select). */
.forms-preview-field.is-readonly > .forms-preview-label {
    color: var(--text-muted);
}
.forms-preview-field.is-readonly > .forms-preview-label::after {
    content: ' · read-only';
    font-style: italic;
    font-size: 0.85em;
    opacity: 0.7;
    font-weight: normal;
}

/* Inline validation marker — applied by SphereFormsPreview.validate when a
   field fails its schema constraint. Red ring on whatever input element
   the field hosts (text/select/textarea), plus a small error message
   `<p class="forms-preview-field-error">` appended to the wrapper. */
.forms-preview-field.is-invalid > .forms-preview-input,
.forms-preview-field.is-invalid > select.forms-preview-input,
.forms-preview-field.is-invalid > textarea.forms-preview-input,
.forms-preview-field.is-invalid input.forms-preview-input,
.forms-preview-field.is-invalid select.forms-preview-input,
.forms-preview-field.is-invalid textarea.forms-preview-input {
    border-color: var(--danger, #ef4444);
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.12);
}
.forms-preview-field.is-invalid > .forms-preview-label {
    color: var(--danger, #ef4444);
}
.forms-preview-field-error {
    color: var(--danger, #ef4444);
    font-size: 0.85em;
    margin: 4px 0 0 0;
}

.forms-preview-field--missing {
    border: 1px dashed var(--accent-warn, #d98c2b);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    background: rgba(217, 140, 43, 0.06);
}
.forms-preview-field--missing .forms-preview-help { color: var(--accent-warn, #d98c2b); }

/* Widget-specific styling: each block targets the structures emitted by the
   builders in forms-preview.js. Selectors are scoped under .forms-preview-*
   classes so this can't bleed into the rest of the app. */

/* Image widget (string with type: "image" on the form-layout entry).
   Display-only; the entry's `style` classes land directly on the <img>, so
   `style: "w-50"` etc. size it. Default keeps it contained. */
.forms-preview-image {
    display: block;
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-sm);
}

/* Template widget (string with type: "template" on the form-layout entry).
   Author-supplied HTML rendered via innerHTML — wrapper exists only so the
   entry's `style` classes have somewhere to land. No intrinsic styling. */
.forms-preview-template {
    display: block;
}

/* Array-of-images widgets (string[] arrays with type: "images_list" or
   "images_table" on the form-layout entry). Both render display-only with
   uniform square tiles so mixed-resolution / sparse models still present
   cleanly. Authors size the outer wrapper via the entry's `style` classes. */
.forms-preview-images-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.forms-preview-images-table {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 0.5rem;
}

.forms-preview-images-item {
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--surface-muted, #f3f3f3);
}

.forms-preview-images-list > .forms-preview-images-item {
    width: 200px;
    aspect-ratio: 1 / 1;
}

.forms-preview-images-table > .forms-preview-images-item {
    width: 100%;
    aspect-ratio: 1 / 1;
}

/* Object-array iteration via `subForms`. The outer wrapper stacks each item
   block below the previous; each per-item <fieldset> groups the array
   element's rendered child entries. Authors size/space the outer wrapper via
   the entry's `style` classes. */
.forms-preview-items {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.forms-preview-items-title {
    font-size: 1rem;
    margin: 0;
}

.forms-preview-item {
    border: 1px solid var(--border-muted, #e5e7eb);
    border-radius: var(--radius-sm);
    padding: 0.75rem 1rem;
}

.forms-preview-item-legend {
    padding: 0 0.4rem;
    font-size: 0.875rem;
    color: var(--text-muted, #6b7280);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
}

/* Container that holds the item cards for a subForms array. Sits between the
   title/description block and the + Add button; gets rebuilt in place on add/
   remove without re-mounting the surrounding wrap. */
.forms-preview-items-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* + Add button at the bottom of a subForms list. Always visible — even when
   the array is empty, this is how the user adds the first item. */
.forms-preview-add-item {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    font-size: 0.875rem;
    border: 1px dashed var(--border-muted, #e5e7eb);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text, #1a1d24);
    text-decoration: none;
}
.forms-preview-add-item:hover {
    background: var(--bg-muted, #f3f4f6);
    border-style: solid;
}

/* Per-item × remove button — sits in the legend row, right-aligned. */
.forms-preview-remove-item {
    padding: 0.1rem 0.35rem;
    font-size: 0.75rem;
    line-height: 1;
    border: none;
    background: transparent;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
}
.forms-preview-remove-item:hover {
    color: var(--danger, #dc2626);
}

/* Toggleable wrapper. The entry-level `toggleable: true` flag (any property
   type) wraps the field in a switch row + a content area that's hidden when
   the switch is off. Soph parity: model value is preserved across toggling. */
.forms-preview-toggleable {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.forms-preview-toggleable-row {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.875rem;
    color: var(--text-secondary, var(--text-primary));
}

.forms-preview-toggleable-text {
    user-select: none;
}

.forms-preview-toggleable-content {
    display: block;
}

/* Monospace text inputs — markdown / code / html / json textareas. */
.forms-preview-input--mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    line-height: 1.45;
}

/* Radio list (string enum, type: "radio"). */
.forms-preview-radio-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.forms-preview-radio-row {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    cursor: pointer;
}

/* Range slider (number, type: "range"). */
.forms-preview-range {
    display: flex;
    align-items: center;
    gap: 10px;
}
.forms-preview-range-input { flex: 1 1 auto; }
.forms-preview-range-value {
    min-width: 3em;
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
    font-size: 12.5px;
}

/* Toggle switch (boolean, type: "toggle"). Pure CSS — the underlying control
   is still a checkbox so form-handling stays uniform. */
.forms-preview-switch {
    position: relative;
    display: inline-block;
    width: 36px;
    height: 20px;
    flex: 0 0 auto;
}
.forms-preview-switch input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    z-index: 1;
}
.forms-preview-switch-track {
    position: absolute;
    inset: 0;
    background: var(--border-strong, #cbd5e1);
    border-radius: 999px;
    transition: background 0.15s ease;
}
.forms-preview-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: #ffffff;
    border-radius: 999px;
    transition: transform 0.15s ease;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.forms-preview-switch input[type="checkbox"]:checked ~ .forms-preview-switch-track {
    background: var(--accent, #3b82f6);
}
.forms-preview-switch input[type="checkbox"]:checked ~ .forms-preview-switch-track .forms-preview-switch-thumb {
    transform: translateX(16px);
}

/* Tags input (array, type: "tags"). */
.forms-preview-tags {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.forms-preview-tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-height: 0;
}
.forms-preview-tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 8px;
    background: var(--bg-canvas, #f1f5f9);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    font-size: 12px;
}
.forms-preview-tag-remove {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    padding: 0 4px;
    cursor: pointer;
}
.forms-preview-tag-remove:hover { color: var(--accent-danger, #dc2626); }
.forms-preview-tag-input { font-size: 13px; }

/* Primitive-item array widget (default for string[] / integer[] / number[]
   / boolean[] / enum[]). Stacked list of values, each with a remove
   button; a single input + "Add" button below. Replaces the legacy
   "raw JSON textarea" default — the textarea is now reached only for
   array shapes whose items aren't a primitive (or have no `items` at
   all). */
.forms-preview-primarr {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.forms-preview-primarr-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.forms-preview-primarr-empty {
    color: var(--text-muted);
    font-size: 12px;
    font-style: italic;
    padding: 4px 0;
}
.forms-preview-primarr-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 10px;
    background: var(--bg-canvas, #f1f5f9);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    font-size: 13px;
}
.forms-preview-primarr-value {
    flex: 1 1 auto;
    word-break: break-word;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.forms-preview-primarr-remove {
    flex: 0 0 auto;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 1;
    padding: 0 4px;
    cursor: pointer;
}
.forms-preview-primarr-remove:hover { color: var(--accent-danger, #dc2626); }
.forms-preview-primarr-add-row {
    display: flex;
    gap: 6px;
    align-items: stretch;
}
.forms-preview-primarr-add-row > .forms-preview-input {
    flex: 1 1 auto;
}
.forms-preview-primarr-add {
    flex: 0 0 auto;
    padding: 4px 12px;
    border: 1px solid var(--accent);
    background: var(--accent-soft, #eef2ff);
    color: var(--accent);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
}
.forms-preview-primarr-add:hover {
    background: var(--accent);
    color: white;
}

/* Google Maps widget placeholder (string, type: "googlemaps"). */
.forms-preview-googlemaps {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Map widget wrap — positions the refresh button as a top-right overlay
   on the map area. Used by the OSM/Leaflet `map` widget in forms-preview.js
   so the user can re-run geocoding after editing the paired text input
   (typical shape in BluePrinter Startup + task inbox forms). */
.forms-preview-map-wrap {
    position: relative;
    width: 100%;
}
.forms-preview-map-refresh {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 401;            /* above Leaflet panes (which top out at 400) */
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--border-emphasis);
    background: white;
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.forms-preview-map-refresh:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.forms-preview-map-refresh:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* ============================================================
   SearchableSelect (Sphere/Components/Shared/SearchableSelect.razor)
   Generic single-select with substring filter. Reuses .form-control
   tokens for the trigger so callers can drop it in where a <select>
   sat without changing surrounding layout.
   ============================================================ */
.sphere-searchable-select {
    position: relative;
    display: block;
    width: 100%;
}
.sphere-searchable-select-trigger {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 34px;
    padding: 4px 8px 4px 10px;
    background: var(--bg-elevated, #ffffff);
    border: 1px solid var(--border-strong, #cbd5e1);
    border-radius: var(--radius-sm);
    color: var(--text-primary, inherit);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    gap: 8px;
}
.sphere-searchable-select.is-open .sphere-searchable-select-trigger {
    border-color: var(--accent, #3b82f6);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
.sphere-searchable-select.is-disabled .sphere-searchable-select-trigger {
    opacity: 0.55;
    cursor: not-allowed;
}
.sphere-searchable-select-value {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.sphere-searchable-select-value-main { overflow: hidden; text-overflow: ellipsis; }
.sphere-searchable-select-value-sub {
    font-size: 11px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
}
.sphere-searchable-select-placeholder {
    flex: 1 1 auto;
    color: var(--text-muted, #94a3b8);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sphere-searchable-select-actions {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
}
.sphere-searchable-select-clear {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0 4px;
    font-size: 14px;
    line-height: 1;
    border-radius: 4px;
}
.sphere-searchable-select-clear:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--text-primary);
}
.sphere-searchable-select-chevron {
    color: var(--text-muted);
    font-size: 13px;
    transition: transform 0.15s ease;
}
.sphere-searchable-select.is-open .sphere-searchable-select-chevron {
    transform: rotate(180deg);
}

.sphere-searchable-select-backdrop {
    position: fixed;
    inset: 0;
    background: transparent;
    z-index: 1000;
}
.sphere-searchable-select-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 1001;
    background: var(--bg-elevated, #ffffff);
    border: 1px solid var(--border-strong, #cbd5e1);
    border-radius: var(--radius-sm);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
    max-height: 320px;
    overflow: hidden;
}
.sphere-searchable-select-search {
    margin: 6px 6px 4px 6px;
    width: calc(100% - 12px);
    font-size: 13px;
}
.sphere-searchable-select-list {
    list-style: none;
    margin: 0;
    padding: 2px 0 4px 0;
    overflow-y: auto;
    flex: 1 1 auto;
}
.sphere-searchable-select-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary, inherit);
}
.sphere-searchable-select-item:hover {
    background: var(--bg-canvas, #f1f5f9);
}
.sphere-searchable-select-item.is-selected {
    background: rgba(59, 130, 246, 0.10);
    color: var(--accent, #3b82f6);
}
.sphere-searchable-select-item-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sphere-searchable-select-item-sub {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--text-muted);
}
.sphere-searchable-select-item-tick {
    flex: 0 0 auto;
    color: var(--accent, #3b82f6);
}
.sphere-searchable-select-empty {
    padding: 10px 12px;
    color: var(--text-muted);
    font-size: 12.5px;
    text-align: center;
}
.forms-preview-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--text-muted);
    background-color: var(--bg-canvas);
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.5;
}

.forms-designer-deploy {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 18px 22px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.forms-designer-deploy-header h3 {
    margin: 0 0 4px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
.forms-designer-deploy-meta {
    display: block;
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}
.forms-designer-deploy-meta code {
    background-color: var(--bg-canvas);
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 11.5px;
    color: var(--text-primary);
}
.forms-designer-deploy-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
.forms-designer-deploy-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.forms-designer-deploy-hint {
    color: var(--text-muted);
    font-size: 12.5px;
    font-style: italic;
}

@media (max-width: 1024px) {
    .forms-designer-fields { grid-template-columns: 1fr; }
    .forms-designer-preview { grid-template-columns: 1fr; }
}

/* Schema-tab toolbar above the Monaco mount — hosts the "Add property" trigger. */
.forms-designer-schema-toolbar {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}

.forms-designer-schema-toolbar .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Schema-tab "Load from type" row — label + SearchableSelect + Load button +
   inline hint. The SearchableSelect needs a bounded width or it consumes the
   whole row; flex on the .typesel wrapper lets it size proportionally. */
.forms-designer-schema-toolbar-label {
    font-size: 0.875rem;
    color: var(--text-muted, #6b7280);
    white-space: nowrap;
}
.forms-designer-schema-toolbar-typesel {
    flex: 0 1 280px;
    min-width: 200px;
}

.forms-designer-schema-toolbar-hint {
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1.4;
    flex: 1;
    min-width: 240px;
}

.forms-designer-schema-toolbar-hint code {
    background-color: var(--bg-canvas);
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 11.5px;
    color: var(--text-primary);
}

/* Help dialog (Widget types reference). Compact two-column tables, grouped by
   the underlying JSON Schema type. */
.forms-designer-help-btn {
    flex: 0 0 auto;
}
.forms-designer-help-group {
    margin: 16px 0 6px;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}
.forms-designer-help-group:first-of-type { margin-top: 8px; }
.forms-designer-help-group code {
    background-color: var(--bg-canvas);
    padding: 0 4px;
    border-radius: var(--radius-sm);
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 11px;
    text-transform: none;
    letter-spacing: 0;
}
.forms-designer-help-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12.5px;
    line-height: 1.45;
}
.forms-designer-help-table th,
.forms-designer-help-table td {
    text-align: left;
    vertical-align: top;
    padding: 4px 8px;
    border-bottom: 1px solid var(--border-subtle);
}
.forms-designer-help-table th {
    font-weight: 500;
    width: 14em;
    color: var(--text-secondary);
}
.forms-designer-help-table th code {
    font-family: ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;
    font-size: 12px;
    color: var(--text-primary);
}
.forms-designer-help-table tr:last-child th,
.forms-designer-help-table tr:last-child td {
    border-bottom: none;
}
.forms-designer-help-foot {
    margin-top: 16px;
    padding-top: 10px;
    border-top: 1px solid var(--border-subtle);
}

/* Property type picker grid inside the Add Property modal. Three columns on the
   wide modal; collapses to two on narrow screens. */
.property-type-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}

.property-type-btn {
    appearance: none;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 12px 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    color: var(--text-secondary);
    font-size: 12px;
    font-weight: 500;
    font-family: inherit;
    transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
}

.property-type-btn:hover {
    background-color: var(--bg-surface);
    color: var(--text-primary);
}

.property-type-btn.is-active {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

.property-type-btn i {
    font-size: 18px;
}

.forms-builder-inline-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-primary);
    cursor: pointer;
    user-select: none;
}

.forms-builder-inline-check input[type="checkbox"] {
    margin: 0;
}

@media (max-width: 720px) {
    .property-type-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ─── BluePrinter ─────────────────────────────────────────────────────────── */

.blueprinter-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* Page-level blueprint switcher. Lives above .blueprinter-header so the
   user can hop between saved blueprints from any tab. Capped at a sane
   width so it doesn't span the whole monitor on a wide screen — feels
   like an inline switcher rather than a full toolbar. */
.blueprinter-loadbar {
    display: flex;
    align-items: stretch;
    gap: 8px;
    max-width: 560px;
}
.blueprinter-loadbar > .sphere-searchable-select {
    flex: 1 1 auto;
    min-width: 0;
}
.blueprinter-loadbar > .btn {
    flex: 0 0 auto;
}

.blueprinter-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.blueprinter-name-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 auto;
    min-width: 280px;
}

.blueprinter-name-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.blueprinter-name-input {
    max-width: 460px;
    font-weight: 500;
}

.blueprinter-dirty {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: 12px;
    color: var(--accent);
    font-weight: 500;
}

.blueprinter-dirty i {
    font-size: 22px;
    line-height: 0;
}

.blueprinter-header-actions {
    display: flex;
    gap: 8px;
}

/* Tab count badges */
.tab-button .tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
}

.tab-button.is-active .tab-count {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

/* Generic icon-only button used by row actions in the BluePrinter view. */
.btn-icon {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 100ms ease, color 100ms ease, border-color 100ms ease;
}

.btn-icon:hover:not(:disabled) {
    background-color: var(--bg-surface);
    color: var(--text-primary);
    border-color: var(--border-subtle);
}

.btn-icon:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.btn-icon-danger:hover:not(:disabled) {
    color: var(--danger);
}

/* Common section block — light card, padded, used across most tabs. */
.bp-section {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.bp-section-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.bp-section-hint {
    color: var(--text-muted);
    font-size: 13px;
    margin: 0;
}

/* Inline add row: input(s) on the left, primary button on the right. */
.bp-inline-add {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

.bp-inline-add .form-control {
    min-width: 200px;
    flex: 0 1 auto;
}

/* Activity list */
.bp-activity-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bp-activity-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    transition: border-color 100ms ease, box-shadow 100ms ease;
}

.bp-activity-card.is-expanded {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.bp-activity-summary {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
}

.bp-activity-seq {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 600;
    min-width: 28px;
    text-align: right;
    font-feature-settings: 'tnum';
}

.bp-activity-toggle {
    appearance: none;
    background: transparent;
    border: none;
    text-align: left;
    cursor: pointer;
    flex: 1 1 auto;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    display: flex;
    flex-direction: column;
    gap: 4px;
    color: var(--text-primary);
    font-family: inherit;
}

.bp-activity-toggle:hover {
    background-color: rgba(99, 102, 241, 0.05);
}

.bp-activity-name {
    font-weight: 500;
    font-size: 14px;
}

/* Enum values editor — used in two places:
   1. Below the Variables-tab inline-add row when newVarType == "Enum"
      (collecting values before the new variable is added).
   2. Expanded inside the variables <table> as a colspan=3 row when an
      existing Enum variable's pencil-edit button is toggled.
   The shared shell keeps the visual identical in both contexts. */
.bp-enum-editor {
    margin: 6px 0 14px;
    padding: 12px 14px;
    background: var(--bs-tertiary-bg, #f6f7f9);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 8px;
}
.bp-enum-editor-label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 8px;
    color: var(--bs-secondary-color, #6c757d);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.bp-enum-editor .bp-token-list {
    margin-bottom: 8px;
}
.bp-enum-edit-row > td {
    background: var(--bs-tertiary-bg, #f6f7f9);
    padding: 6px 8px 12px;
}

/* Activity-level Variables sub-section inside an expanded activity card.
   Sits below the Description editor; renders the currently-attached
   variables as removable pill-tokens, and a picker + Attach button
   under that. Disabled state covers "no blueprint-level variables
   defined yet" — the user is steered to the Variables tab. */
.bp-activity-vars {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px dashed var(--bs-border-color, #dee2e6);
}
.bp-activity-vars-header {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    margin: 0 0 10px;
    color: var(--bs-body-color, #1d1d1f);
}
.bp-section-hint--inline {
    margin: 4px 0 10px;
    font-size: 0.85rem;
    opacity: 0.7;
}

/* Form preview that lives under the variable-tags row inside an expanded
   Activity card. Renders what the recipient will see at run-time, using
   the same BluePrintFormBuilder + SphereFormsPreview path as the Startup
   modal. Detach a tag above → ReconcileActivityFormsAsync re-mounts this
   without the removed field. */
.bp-activity-form-preview {
    margin-top: 18px;
    padding: 12px 14px 14px;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--radius-md, 8px);
    background: var(--bs-tertiary-bg, #f6f7f9);
}
.bp-activity-form-preview-header {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 600;
    margin: 0 0 10px;
    color: var(--text-secondary, #475569);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.bp-activity-form-preview-header > i {
    font-size: 0.95rem;
    opacity: 0.7;
}
.bp-activity-form-host {
    min-height: 60px;
}

/* Activity status icons — Soph parity. Each conditional flag (human/aeon,
   notify, review, has variables) shows as a small Bootstrap-icon glyph
   in front of the activity's pill row. Colour palette ports Soph's
   Radzen/Material icon colours one-to-one for visual continuity. */
.bp-activity-icons {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: 8px;
    font-size: 0.95rem;
    flex-shrink: 0;
}
.bp-icon { line-height: 1; }
.bp-icon-human  { color: #1f8a3a; }   /* darkgreen — Soph parity */
.bp-icon-aeon   { color: #6b7280; }   /* gray — Soph parity */
.bp-icon-review { color: #cc6600; }   /* darkorange — Soph parity */
.bp-icon-notify { color: #f59e0b; }   /* orange — Soph parity */
.bp-icon-vars   { color: #663399; }   /* rebeccapurple — Soph parity */

.bp-activity-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.bp-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 9999px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 500;
    text-transform: lowercase;
    font-feature-settings: 'tnum';
}
/* Variant for pills that carry long content (URLs, paths) — caps the
   visible width and ellipsizes. Hover title still shows the full string. */
.bp-pill.bp-pill--truncate {
    max-width: 28ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-transform: none;
}

.bp-pill-human {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

.bp-pill-system {
    background-color: #ecfeff;
    border-color: #06b6d4;
    color: #0e7490;
}

/* Startup activity row marker — paired with the gentle green tint on the
   card itself. Positional only (Activities[0]); nothing else depends on it. */
.bp-pill-startup {
    background-color: #ecfdf5;
    border-color: #10b981;
    color: #047857;
    text-transform: none;
}

.bp-activity-card--startup {
    background-color: #f0fdf4;
    border-left: 3px solid #10b981;
}

.bp-activity-card--startup.is-expanded {
    background-color: #ecfdf5;
}

/* Startup-form modal — slightly wider than the default modal-dialog so the
   inline form has room to breathe. */
.bp-startup-modal {
    max-width: 720px;
    width: 90%;
}

.bp-startup-description {
    border-left: 3px solid var(--border-subtle);
    padding: 0.25rem 0.75rem;
    margin-bottom: 0.75rem;
    color: var(--text-secondary);
}

.bp-pill-risk-low {
    background-color: #f0fdf4;
    border-color: #22c55e;
    color: #15803d;
}

.bp-pill-risk-medium {
    background-color: #fffbeb;
    border-color: #f59e0b;
    color: #b45309;
}

.bp-pill-risk-high {
    background-color: #fef2f2;
    border-color: #ef4444;
    color: #b91c1c;
}

html.dark .bp-pill {
    background-color: rgba(255, 255, 255, 0.04);
}

html.dark .bp-pill-system {
    background-color: rgba(6, 182, 212, 0.15);
    color: #67e8f9;
}

html.dark .bp-pill-risk-low {
    background-color: rgba(34, 197, 94, 0.15);
    color: #86efac;
}

html.dark .bp-pill-risk-medium {
    background-color: rgba(245, 158, 11, 0.15);
    color: #fcd34d;
}

html.dark .bp-pill-risk-high {
    background-color: rgba(239, 68, 68, 0.15);
    color: #fca5a5;
}

.bp-activity-rowactions {
    display: flex;
    gap: 4px;
    align-items: center;
}

.bp-activity-body {
    border-top: 1px solid var(--border-subtle);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.bp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px;
}

.bp-grid .form-row--inline {
    align-items: center;
    gap: 14px;
}

.bp-quill-wrap {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bp-quill-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.bp-quill-mount {
    min-height: 200px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-md);
}

.bp-quill-mount .ql-toolbar {
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
    border-color: var(--border-subtle);
}

.bp-quill-mount .ql-container {
    border-bottom-left-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
    border-color: var(--border-subtle);
    font-family: inherit;
    font-size: 14px;
    min-height: 160px;
}

html.dark .bp-quill-mount .ql-toolbar,
html.dark .bp-quill-mount .ql-container {
    background-color: var(--bg-surface);
    color: var(--text-primary);
}

html.dark .bp-quill-mount .ql-stroke {
    stroke: var(--text-secondary);
}

html.dark .bp-quill-mount .ql-fill {
    fill: var(--text-secondary);
}

html.dark .bp-quill-mount .ql-picker {
    color: var(--text-secondary);
}

/* Token list (Participants & Components) */
.bp-token-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.bp-token {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 4px 4px 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 9999px;
    font-size: 13px;
    color: var(--text-primary);
}

.bp-token-protected {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    padding-right: 12px;
}

.bp-token-icon {
    color: var(--text-muted);
    font-size: 13px;
}

.bp-token-remove {
    appearance: none;
    background: transparent;
    border: none;
    width: 22px;
    height: 22px;
    border-radius: 9999px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.bp-token-remove:hover {
    background-color: var(--bg-canvas);
    color: var(--danger);
}

/* Per-activity-variable flag buttons (read-only, toggleable). Inside a
   `.bp-token` chip — same dimensions as .bp-token-remove so the chip stays
   compact. Default ("off") is muted; "is-on" flips to the accent colour so
   the author can see at a glance which variables in an activity are
   read-only or toggleable. */
.bp-token-flag {
    appearance: none;
    background: transparent;
    border: none;
    width: 22px;
    height: 22px;
    border-radius: 9999px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
}
.bp-token-flag:hover {
    background-color: var(--bg-canvas);
    color: var(--text-secondary);
}
.bp-token-flag.is-on {
    color: var(--accent);
    background-color: var(--accent-soft);
}
.bp-token-flag.is-on:hover {
    color: var(--accent);
    background-color: var(--accent-soft);
    filter: brightness(0.95);
}

/* Manage tab (labelled "Share" in the UI; enum kept as Manage to avoid
   churn — see BluePrinterView TabLabel mapping). */
.bp-raw summary {
    cursor: pointer;
    font-size: 13px;
    color: var(--text-secondary);
    padding: 6px 0;
}

/* Share tab — recipient picker above the read-only JSON view. */
.bp-share-recipient {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 18px;
    max-width: 600px;
}
.bp-share-recipient > .btn {
    flex: 0 0 auto;
}
.bp-share-recipient-label {
    font-weight: 600;
    font-size: 0.9rem;
    flex: 0 0 auto;
    color: var(--text-primary);
}
.bp-share-recipient > .sphere-searchable-select {
    flex: 1 1 auto;
    min-width: 0;
}

.bp-share-json {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.bp-share-json-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.bp-share-json-header > label {
    font-weight: 600;
    font-size: 0.9rem;
    margin: 0;
    color: var(--text-primary);
}
.bp-share-copy {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border: 1px solid var(--border-subtle);
    background: var(--bg-surface);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    font-size: 0.85em;
    cursor: pointer;
}
.bp-share-copy:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.bp-share-copy > i {
    font-size: 0.95em;
}

.bp-raw-text {
    width: 100%;
    margin-top: 6px;
}

/* Run tab */
.bp-run-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
}

.bp-run-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Subheading for the per-`$xxx` participant-assignments block on the Run
   tab. Mirrors .bp-activity-vars-header's visual weight. */
.bp-section-subheader {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    margin: 16px 0 10px;
    color: var(--bs-body-color, #1d1d1f);
}

/* Per-`$xxx` placeholder → username dropdown column on the Run tab.
   Single column so the placeholder names line up vertically; SearchableSelect
   handles its own width. */
.bp-run-bindings {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    margin-bottom: 12px;
}

.bp-run-log {
    border-top: 1px solid var(--border-subtle);
    padding-top: 12px;
}

.bp-run-log-header {
    font-size: 13px;
    color: var(--text-muted);
    margin: 0 0 8px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.bp-run-log ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.bp-run-log li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-primary);
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    background-color: var(--bg-surface);
}

.bp-run-log li.is-ok i {
    color: var(--success, #22c55e);
}

.bp-run-log li.is-error i {
    color: var(--danger);
}

/* Instances tab */
.bp-progression-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 12px;
}

/* /tasks → Activity tab. Forces the same `.bp-progression` cards into a
   single vertical column ordered latest-first (BluePrinter's Instances
   tab uses the grid above instead — multi-column on wide screens). */
.tasks-activity-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.bp-progression {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.bp-progression-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.bp-progression-name {
    font-weight: 600;
    color: var(--text-primary);
}

.bp-progression-id {
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
}

.bp-progression-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 12px;
    color: var(--text-secondary);
}

.bp-progression-meta span i {
    margin-right: 4px;
    color: var(--text-muted);
}

.bp-progression-bar {
    height: 6px;
    background-color: var(--bg-canvas);
    border-radius: 3px;
    overflow: hidden;
}

.bp-progression-fill {
    height: 100%;
    background-color: var(--accent);
    transition: width 200ms ease;
}

.bp-progression-pct {
    font-size: 12px;
    color: var(--text-muted);
    text-align: right;
    font-feature-settings: 'tnum';
    font-weight: 500;
}

/* Risk colour. Applies to the span wrapper so both the icon and the word
   pick up the same colour via inheritance — the .bp-progression-meta rule
   above would otherwise force the icon to var(--text-muted). */
.bp-risk             { font-weight: 500; text-transform: capitalize; }
.bp-risk i           { color: inherit; }
.bp-risk-controlled  { color: #0ea5e9; }  /* sky-500 — mitigated */
.bp-risk-low         { color: #16a34a; }  /* green-600 — safe */
.bp-risk-medium      { color: #d97706; }  /* amber-600 — caution */
.bp-risk-high        { color: #dc2626; }  /* red-600 — danger */

/* ─── Statistics tab ──────────────────────────────────────────────────────── */

.stats-tab {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.stats-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 16px;
}

.stats-toolbar-banner {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
}

.stats-banner-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.stats-banner-value {
    font-size: 28px;
    font-weight: 700;
    color: var(--text-primary);
    font-feature-settings: 'tnum';
    line-height: 1;
}

.stats-banner-sub {
    display: inline-flex;
    gap: 6px;
}

.stats-banner-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 600;
    font-feature-settings: 'tnum';
    border: 1px solid var(--border-subtle);
}

.stats-banner-pill-ok {
    background-color: #f0fdf4;
    border-color: #22c55e;
    color: #15803d;
}

.stats-banner-pill-err {
    background-color: #fef2f2;
    border-color: #ef4444;
    color: #b91c1c;
}

html.dark .stats-banner-pill-ok {
    background-color: rgba(34, 197, 94, 0.12);
    color: #86efac;
}

html.dark .stats-banner-pill-err {
    background-color: rgba(239, 68, 68, 0.12);
    color: #fca5a5;
}

.stats-toolbar-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.stats-name-filter {
    width: 200px;
}

.stats-topn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-secondary);
}

.stats-topn-select {
    width: 5.5em;
}

.stats-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-secondary);
    user-select: none;
    cursor: pointer;
}

.stats-toggle input {
    margin: 0;
}

.stats-spin {
    animation: stats-spin-anim 0.9s linear infinite;
}

@keyframes stats-spin-anim {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.stats-chart-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.stats-chart-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.stats-chart-header h3 {
    margin: 0;
    font-size: 14px;
    color: var(--text-primary);
    font-weight: 600;
}

.stats-chart-meta {
    font-size: 12px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
    flex: 1 1 auto;
}

.stats-view-toggle {
    margin-left: auto;
}

.stats-threshold {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

.stats-threshold-mode {
    width: 7em;
}

.stats-threshold-value {
    width: 7em;
    font-feature-settings: 'tnum';
}

.stats-chart-empty {
    padding: 36px 12px;
    text-align: center;
}

.stats-donut-pair {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 12px;
}

.stats-donut h4 {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    margin: 0 0 6px;
    text-align: center;
}

.stats-empty {
    text-align: center;
    padding: 48px 16px;
    color: var(--text-secondary);
}

.stats-empty i {
    font-size: 32px;
    color: var(--text-muted);
    margin-bottom: 8px;
    display: block;
}

.stats-empty-hint {
    font-size: 12px;
    color: var(--text-muted);
}

.stats-foot {
    font-size: 12px;
    color: var(--text-muted);
    text-align: right;
}

/* ─── Tags tab ────────────────────────────────────────────────────────────── */

.tags-tab {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.tags-toolbar {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.tags-filter-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.tags-filter-input {
    width: 260px;
}

.tags-mode-toggle {
    margin-left: 6px;
}

.tags-active-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tags-result-toolbar {
    display: flex;
    justify-content: flex-end;
    color: var(--text-muted);
    font-size: 12px;
    font-feature-settings: 'tnum';
}

.tags-table {
    width: 100%;
}

.tags-table td {
    vertical-align: middle;
}

.tags-empty {
    padding: 36px 12px;
    text-align: center;
}

.tags-empty i {
    font-size: 28px;
    color: var(--text-muted);
    margin-bottom: 6px;
    display: block;
}

/* Context badges */
.tags-ctx {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    text-transform: lowercase;
    padding: 2px 8px;
    border-radius: 9999px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    letter-spacing: 0.02em;
}

.tags-ctx-petrinet,
.tags-ctx-flow {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

.tags-ctx-policy {
    background-color: #fef3c7;
    border-color: #f59e0b;
    color: #b45309;
}

.tags-ctx-dataweave {
    background-color: #ecfeff;
    border-color: #06b6d4;
    color: #0e7490;
}

.tags-ctx-type {
    background-color: #f3e8ff;
    border-color: #a855f7;
    color: #7e22ce;
}

.tags-ctx-form {
    background-color: #f0fdf4;
    border-color: #22c55e;
    color: #15803d;
}

.tags-ctx-scheduler {
    background-color: #fdf2f8;
    border-color: #ec4899;
    color: #be185d;
}

.tags-ctx-secret {
    background-color: #fef2f2;
    border-color: #ef4444;
    color: #b91c1c;
}

.tags-ctx-lambda {
    background-color: #fff7ed;
    border-color: #f97316;
    color: #c2410c;
}

html.dark .tags-ctx { background-color: rgba(255, 255, 255, 0.05); }
html.dark .tags-ctx-policy    { background-color: rgba(245, 158, 11, 0.18); color: #fcd34d; }
html.dark .tags-ctx-dataweave { background-color: rgba(6, 182, 212, 0.18); color: #67e8f9; }
html.dark .tags-ctx-type      { background-color: rgba(168, 85, 247, 0.18); color: #d8b4fe; }
html.dark .tags-ctx-form      { background-color: rgba(34, 197, 94, 0.18); color: #86efac; }
html.dark .tags-ctx-scheduler { background-color: rgba(236, 72, 153, 0.18); color: #f9a8d4; }
html.dark .tags-ctx-secret    { background-color: rgba(239, 68, 68, 0.18); color: #fca5a5; }
html.dark .tags-ctx-lambda    { background-color: rgba(249, 115, 22, 0.18); color: #fdba74; }

.tags-name-link {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
    /* Reset native <button> chrome so the same class can style both <a> (route
       fallback) and <button> (dialog trigger) consistently. */
    background: transparent;
    border: 0;
    padding: 0;
    font: inherit;
    cursor: pointer;
    text-align: left;
}

.tags-name-link:hover {
    text-decoration: underline;
}

.tags-name {
    color: var(--text-primary);
    font-weight: 500;
}

/* Tag chips inside a row */
.tags-pill-list {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.tags-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 10px;
    border-radius: 9999px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    font-size: 12px;
}

.tags-pill-remove {
    appearance: none;
    background: transparent;
    border: none;
    width: 18px;
    height: 18px;
    border-radius: 9999px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
}

.tags-pill-remove:hover {
    background-color: var(--bg-surface);
    color: var(--danger);
}

/* Per-row add-tag input */
.tags-add-row {
    display: flex;
    gap: 6px;
}

.tags-add-input {
    flex: 1 1 auto;
    min-width: 0;
}

/* ─── Replay ──────────────────────────────────────────────────────────────── */

.replay-shell {
    display: grid;
    grid-template-columns: 360px 1fr;
    gap: 14px;
    min-height: calc(100vh - 280px);
}

.replay-list {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
}

.replay-list-toolbar {
    display: flex;
    gap: 6px;
    align-items: center;
}

.replay-list-toolbar .form-control {
    flex: 1 1 auto;
}

.replay-breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
    padding: 4px 4px 8px;
    border-bottom: 1px solid var(--border-subtle);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.replay-breadcrumb-name {
    color: var(--text-primary);
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
}

.replay-back {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 0 4px;
    line-height: 0;
}

.replay-back:hover {
    color: var(--accent);
}

.replay-flow-list,
.replay-instance-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    min-height: 0;
}

.replay-flow-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--text-primary);
    transition: background-color 100ms ease, color 100ms ease;
}

.replay-flow-item:hover {
    background-color: var(--accent-soft);
    color: var(--accent);
}

.replay-flow-item i {
    color: var(--text-muted);
    font-size: 14px;
}

.replay-flow-item:hover i {
    color: var(--accent);
}

.replay-flow-name {
    font-size: 14px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.replay-instance-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 100ms ease, border-color 100ms ease;
}

.replay-instance-item:hover {
    background-color: var(--bg-canvas);
}

.replay-instance-item.is-selected {
    background-color: var(--accent-soft);
    border-color: var(--accent);
}

.replay-instance-id {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
}

.replay-instance-item.is-selected .replay-instance-id {
    color: var(--accent);
}

.replay-instance-times {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 11px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
}

.replay-instance-times i {
    margin-right: 3px;
}

.replay-instance-duration {
    color: var(--accent);
    font-weight: 500;
}

/* Right pane */
.replay-main {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    min-width: 0;
}

.replay-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.replay-header h3 {
    margin: 0 0 4px;
    font-size: 16px;
    color: var(--text-primary);
}

.replay-instance-code {
    display: block;
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    margin-bottom: 6px;
    word-break: break-all;
}

.replay-header-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 12px;
    color: var(--text-secondary);
    font-feature-settings: 'tnum';
}

.replay-header-meta i {
    color: var(--text-muted);
    margin-right: 4px;
}

.replay-header-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Monaco mount */
.replay-mount {
    flex: 1 1 auto;
    min-height: 520px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.replay-mount-empty {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    color: var(--text-muted);
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 60px 24px;
    min-height: 520px;
}

.replay-mount-empty i {
    font-size: 36px;
    color: var(--text-muted);
}

/* Responsive: stack the master/detail at narrow viewports */
@media (max-width: 960px) {
    .replay-shell {
        grid-template-columns: 1fr;
    }
    .replay-list {
        max-height: 320px;
    }
}

/* ─── Active instance detail (/active/{id}) ───────────────────────────────── */

.instance-detail-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.instance-detail-back {
    align-self: flex-start;
}

.instance-detail-header {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 18px;
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.instance-detail-flow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}

.instance-detail-flow i {
    color: var(--accent);
}

.instance-detail-version {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 500;
    margin-left: 2px;
}

.instance-detail-id {
    display: block;
    margin: 6px 0 8px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    word-break: break-all;
}

.instance-detail-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    font-size: 12px;
    color: var(--text-secondary);
    font-feature-settings: 'tnum';
}

.instance-detail-meta i {
    color: var(--text-muted);
    margin-right: 4px;
}

.instance-detail-sub-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 9999px;
    background-color: #fffbeb;
    border: 1px solid #f59e0b;
    color: #b45309;
    font-weight: 600;
}

html.dark .instance-detail-sub-pill {
    background-color: rgba(245, 158, 11, 0.15);
    color: #fcd34d;
}

.instance-detail-sub-pill i {
    color: inherit;
    margin-right: 4px;
}

.instance-detail-header-actions {
    display: flex;
    gap: 8px;
    align-items: flex-start;
}

/* Tab content */
.instance-tab-pane {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.instance-tab-pane.is-hidden {
    display: none;
}

.instance-tab-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.instance-monaco-mount {
    min-height: 520px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Markings — petrinet outline host */
.instance-petri-host {
    background: #ffffff;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 8px;
    min-height: 300px;
    overflow: auto;
}

.instance-petri-host svg {
    background-color: #ffffff !important;
    max-width: 100%;
    height: auto;
}

/* gojs-based read-only workflow canvas (WorkflowViewer.razor). Sized via inline
   `Style="height: …px"`; this rule just supplies the chrome. */
.petrinet-viewer-host,
.configurator-petri-host {
    background: #ffffff;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
    width: 100%;
}

.petrinet-viewer-empty {
    margin-top: 8px;
    padding: 12px;
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--surface-subtle, #f9fafb);
    color: var(--text-muted, #6b7280);
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
}

.petrinet-viewer-empty i {
    font-size: 18px;
    opacity: 0.7;
}

.petrinet-viewer-empty p { margin: 0; }

/* Markings — side-by-side row: tokens on the left, read-only WorkflowViewer on
   the right. Mirrors .configurator-workflow-row. Below ~1100px we collapse to a
   stack (tokens above the viewer) — see the @media block at the bottom of this
   block. */
.instance-markings-row {
    display: grid;
    grid-template-columns: minmax(260px, 360px) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

/* The left column caps at the viewer height (520px) so a long token list
   scrolls inside its own pane instead of stretching the whole row. */
.instance-markings-row__tokens {
    max-height: 520px;
    overflow-y: auto;
}

@media (max-width: 1100px) {
    .instance-markings-row {
        grid-template-columns: 1fr;
    }
    .instance-markings-row__tokens {
        max-height: none;
        overflow-y: visible;
    }
}

/* Markings — token grid */
.instance-tokens {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.instance-tokens-header {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.instance-tokens-count {
    color: var(--accent);
    font-weight: 700;
}

.instance-tokens-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 10px;
}

.instance-token-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.instance-token-card header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.instance-token-place {
    font-weight: 600;
    color: var(--accent);
}

.instance-token-id {
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    word-break: break-all;
}

.instance-token-payload {
    margin: 0;
    padding: 8px 10px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    font-size: 11px;
    color: var(--text-primary);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    max-height: 220px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.instance-tokens-empty {
    text-align: center;
    padding: 24px 12px;
}

/* Send tab */
.instance-send-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 12px;
    align-items: flex-end;
}

.instance-send-target {
    display: inline-block;
    padding: 8px 12px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    word-break: break-all;
}

.instance-send-label {
    margin: 8px 0 -4px;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.instance-send-payload {
    min-height: 180px;
}

.instance-send-actions {
    display: flex;
    justify-content: flex-end;
}

.instance-send-response {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
}

.instance-send-response header {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    margin-bottom: 6px;
}

.instance-send-response pre {
    margin: 0;
    font-size: 12px;
    color: var(--text-primary);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    max-height: 320px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* ─── Endpoint Documentation (/endpoint-docs/{process}/{version}) ─────────── */

.endpoint-doc-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.endpoint-doc-back {
    align-self: flex-start;
}

.endpoint-doc-header {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 18px;
}

.endpoint-doc-flow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}

.endpoint-doc-flow i {
    color: var(--accent);
}

.endpoint-doc-version {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 500;
    margin-left: 4px;
}

.endpoint-doc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-secondary);
    font-feature-settings: 'tnum';
}

.endpoint-doc-meta i {
    color: var(--text-muted);
    margin-right: 4px;
}

.endpoint-doc-description {
    margin: 10px 0 0;
    color: var(--text-primary);
    line-height: 1.5;
}

/* Master-detail layout for the Transitions/Places tabs */
.doc-master-detail {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 14px;
    min-height: 520px;
}

.doc-list {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
}

.doc-list-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    min-height: 0;
}

.doc-list-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 100ms ease, border-color 100ms ease;
}

.doc-list-item:hover {
    background-color: var(--bg-canvas);
}

.doc-list-item.is-selected {
    background-color: var(--accent-soft);
    border-color: var(--accent);
}

.doc-list-item-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.doc-list-item.is-selected .doc-list-item-name {
    color: var(--accent);
}

.doc-list-item-meta {
    font-size: 11px;
    color: var(--text-muted);
}

.doc-detail {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}

.doc-detail-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    flex-wrap: wrap;
}

.doc-detail-header h3 {
    margin: 0;
    font-size: 16px;
    color: var(--text-primary);
}

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

.doc-fieldset {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.doc-fieldset h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.doc-fieldset-empty {
    text-align: left;
    padding: 12px 0;
    color: var(--text-muted);
    font-size: 13px;
}

/* Key/value tables in the detail pane */
.doc-kv-table {
    width: 100%;
    border-collapse: collapse;
}

.doc-kv-table th {
    text-align: left;
    font-weight: 600;
    color: var(--text-secondary);
    width: 9em;
    padding: 6px 10px 6px 0;
    vertical-align: top;
    font-size: 13px;
}

.doc-kv-table td {
    padding: 6px 0;
    color: var(--text-primary);
    font-size: 13px;
    word-break: break-word;
    vertical-align: top;
}

.doc-kv-table tr + tr th,
.doc-kv-table tr + tr td {
    border-top: 1px solid var(--border-subtle);
}

.doc-kv-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    color: var(--text-primary);
    background-color: var(--bg-canvas);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
}

.doc-kv-hint {
    font-size: 11px;
    color: var(--text-muted);
    margin-left: 6px;
}

.doc-kv-empty {
    color: var(--text-muted);
}

.doc-uri {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    color: var(--text-primary);
    background-color: var(--bg-canvas);
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    word-break: break-all;
    display: inline-block;
}

.doc-pill {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 9999px;
    font-size: 11px;
    font-weight: 600;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
}

.doc-pill-override {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

.doc-pill-audit {
    background-color: #f0fdf4;
    border-color: #22c55e;
    color: #15803d;
}

html.dark .doc-pill-audit {
    background-color: rgba(34, 197, 94, 0.18);
    color: #86efac;
}

.doc-pill-audit i {
    margin-right: 4px;
}

.doc-policy-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.doc-policy-list .btn {
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
}

.doc-policy-code {
    margin: 0;
    padding: 12px;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    color: var(--text-primary);
    max-height: 60vh;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.doc-kpi-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

.doc-kpi-table th {
    text-align: left;
    padding: 6px 10px;
    background-color: var(--bg-canvas);
    color: var(--text-secondary);
    font-weight: 600;
    border-bottom: 1px solid var(--border-subtle);
}

.doc-kpi-table td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: top;
}

.doc-kpi-table code {
    display: block;
    white-space: pre-wrap;
    word-break: break-word;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    color: var(--text-primary);
}

/* Responsive: stack master/detail at narrow viewports */
@media (max-width: 960px) {
    .doc-master-detail {
        grid-template-columns: 1fr;
    }
    .doc-list {
        max-height: 280px;
    }
}

/* ─── Shared compact toggle (originally Assistant; reused by DebuggerView) ── */

.assistant-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-secondary);
    user-select: none;
    cursor: pointer;
}

.assistant-toggle input {
    margin: 0;
}

/* ─── Simulator (/simulator) ──────────────────────────────────────────────── */

.simulator-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.simulator-model-picker {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

.simulator-model-picker select {
    width: 18em;
}

.simulator-scenario {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 14px;
    min-height: 480px;
}

.simulator-list-card,
.simulator-editor-card {
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
}

.simulator-list-card > header,
.simulator-editor-card > header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.simulator-list-card h4,
.simulator-editor-card h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.simulator-list-card > header span,
.simulator-editor-card > header span {
    font-size: 12px;
    color: var(--text-secondary);
}

.simulator-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    min-height: 0;
}

.simulator-list-item {
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 13px;
    transition: background-color 100ms ease, border-color 100ms ease;
}

.simulator-list-item:hover {
    background-color: var(--bg-surface);
}

.simulator-list-item.is-selected {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 500;
}

.simulator-list-item-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 6px 6px 10px;
}

.simulator-list-name {
    appearance: none;
    background: transparent;
    border: none;
    text-align: left;
    flex: 1 1 auto;
    cursor: pointer;
    color: inherit;
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: inherit;
    font-size: 13px;
}

.simulator-list-name:hover {
    color: var(--accent);
}

.simulator-list-empty {
    padding: 12px;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
}

/* Risk pills inside the configured list */
.simulator-risk {
    margin-left: auto;
    display: inline-block;
    padding: 1px 8px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 600;
    text-transform: lowercase;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
}

.simulator-risk-controlled { background-color: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.simulator-risk-low        { background-color: #f0fdf4; border-color: #22c55e; color: #15803d; }
.simulator-risk-medium     { background-color: #fffbeb; border-color: #f59e0b; color: #b45309; }
.simulator-risk-high       { background-color: #fef2f2; border-color: #ef4444; color: #b91c1c; }
html.dark .simulator-risk-low      { background-color: rgba(34, 197, 94, 0.18); color: #86efac; }
html.dark .simulator-risk-medium   { background-color: rgba(245, 158, 11, 0.18); color: #fcd34d; }
html.dark .simulator-risk-high     { background-color: rgba(239, 68, 68, 0.18); color: #fca5a5; }

.simulator-pair {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.simulator-pair-label {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.simulator-pair-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.simulator-editor-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* Run controls + warning text */
.simulator-warn {
    color: var(--danger);
}

.simulator-run-controls {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

.simulator-runs {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-secondary);
}

.simulator-runs-input {
    width: 6em;
}

/* Report summary */
.simulator-report-summary {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.simulator-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px;
}

.simulator-stat {
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.simulator-stat-label {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.simulator-stat-value {
    font-size: 22px;
    font-weight: 700;
    color: var(--text-primary);
    font-feature-settings: 'tnum';
    line-height: 1.1;
}

.simulator-stat-sub {
    font-size: 11px;
    color: var(--text-secondary);
    font-feature-settings: 'tnum';
}

.simulator-report-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 12px;
}

.simulator-report-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.simulator-report-card h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

@media (max-width: 1100px) {
    .simulator-scenario {
        grid-template-columns: 1fr;
    }
    .simulator-list-card {
        max-height: 280px;
    }
}

/* ─── Debugger (/debugger + /debugger/{ref}) ──────────────────────────────── */

.debugger-list-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.debugger-list-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 16px;
    flex-wrap: wrap;
}

.debugger-list-filter {
    flex: 1 1 320px;
    max-width: 440px;
}

.debugger-list-table {
    width: 100%;
}

/* Per-story view */
.debugger-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.debugger-back {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.debugger-orb-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: #b45309;
    background-color: #fffbeb;
    border: 1px solid #f59e0b;
    padding: 4px 10px;
    border-radius: 9999px;
}

html.dark .debugger-orb-pill {
    background-color: rgba(245, 158, 11, 0.15);
    color: #fcd34d;
}

.debugger-tab-pane {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.debugger-tab-pane.is-hidden { display: none; }

.debugger-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.debugger-story-grid {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 14px;
    min-height: 480px;
}

.debugger-actions-list,
.debugger-action-editor {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
}

.debugger-actions-list > header,
.debugger-action-editor > header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.debugger-actions-list h4,
.debugger-action-editor h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 6px;
}

.debugger-action-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.debugger-action-seq {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 600;
    font-feature-settings: 'tnum';
    min-width: 1.8em;
}

.debugger-action-label {
    color: var(--text-secondary);
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.debugger-action-type {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    letter-spacing: 0.04em;
}

.debugger-action-type-start     { background-color: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.debugger-action-type-session   { background-color: #ecfeff; border-color: #06b6d4; color: #0e7490; }
.debugger-action-type-token     { background-color: #f0fdf4; border-color: #22c55e; color: #15803d; }
.debugger-action-type-fire      { background-color: #fff7ed; border-color: #f97316; color: #c2410c; }
.debugger-action-type-mock      { background-color: #f3e8ff; border-color: #a855f7; color: #7e22ce; }
.debugger-action-type-break     { background-color: #fffbeb; border-color: #f59e0b; color: #b45309; }
.debugger-action-type-delete    { background-color: #fef2f2; border-color: #ef4444; color: #b91c1c; }

html.dark .debugger-action-type-session  { background-color: rgba(6, 182, 212, 0.18); color: #67e8f9; }
html.dark .debugger-action-type-token    { background-color: rgba(34, 197, 94, 0.18); color: #86efac; }
html.dark .debugger-action-type-fire     { background-color: rgba(249, 115, 22, 0.18); color: #fdba74; }
html.dark .debugger-action-type-mock     { background-color: rgba(168, 85, 247, 0.18); color: #d8b4fe; }
html.dark .debugger-action-type-break    { background-color: rgba(245, 158, 11, 0.18); color: #fcd34d; }
html.dark .debugger-action-type-delete   { background-color: rgba(239, 68, 68, 0.18); color: #fca5a5; }

.debugger-action-buttons {
    display: flex;
    gap: 4px;
    padding-top: 6px;
    border-top: 1px solid var(--border-subtle);
}

.debugger-add-row {
    display: flex;
    gap: 6px;
}

.debugger-action-data {
    min-height: 200px;
    font-size: 12px;
}

/* Debugger tab */
.debugger-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.debugger-output-tabs {
    margin-top: 4px;
}

.debugger-output-pane {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    min-height: 200px;
}

.debugger-output-pane.is-hidden { display: none; }

.debugger-output-pre {
    margin: 0;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    color: var(--text-primary);
    max-height: 480px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Manage tab */
.debugger-manage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: 14px;
}

.debugger-redis-key {
    display: inline-block;
    margin-top: 6px;
    padding: 4px 10px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 11px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    word-break: break-all;
}

@media (max-width: 1100px) {
    .debugger-story-grid {
        grid-template-columns: 1fr;
    }
    .debugger-actions-list {
        max-height: 320px;
    }
}

/* ─── Apps (/apps) ────────────────────────────────────────────────────────── */

.apps-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.apps-tab-pane {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.apps-tab-pane.is-hidden { display: none; }

.apps-orb-pill {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: #b45309;
    background-color: #fffbeb;
    border: 1px solid #f59e0b;
    padding: 4px 10px;
    border-radius: 9999px;
}

html.dark .apps-orb-pill {
    background-color: rgba(245, 158, 11, 0.15);
    color: #fcd34d;
}

.apps-name-input {
    max-width: 32em;
}

.apps-edit-grid {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 14px;
    min-height: 480px;
}

.apps-list-card,
.apps-slide-editor {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
}

.apps-list-card > header,
.apps-slide-editor > header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.apps-list-card h4,
.apps-slide-editor h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.apps-add-btn {
    margin-left: auto;
}

/* Submit-type pills */
.apps-submit-pill {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    letter-spacing: 0.04em;
}

.apps-submit-pill-local   { background-color: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.apps-submit-pill-start   { background-color: #f0fdf4; border-color: #22c55e; color: #15803d; }
.apps-submit-pill-message { background-color: #fff7ed; border-color: #f97316; color: #c2410c; }

html.dark .apps-submit-pill-start   { background-color: rgba(34, 197, 94, 0.18); color: #86efac; }
html.dark .apps-submit-pill-message { background-color: rgba(249, 115, 22, 0.18); color: #fdba74; }

.apps-raw-actions {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

/* Run tab */
.apps-run-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    flex-wrap: wrap;
}

.apps-run-header h3 {
    margin: 0;
    font-size: 16px;
    color: var(--text-primary);
}

.apps-run-step {
    font-size: 14px;
    color: var(--text-secondary);
    margin-left: 6px;
}

.apps-run-progress {
    font-size: 12px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
}

.apps-form-host {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.apps-run-actions {
    display: flex;
    justify-content: flex-end;
}

.apps-run-summary {
    background-color: var(--bg-surface);
    border: 1px solid var(--accent);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.apps-run-summary h4 {
    margin: 0;
    font-size: 14px;
    color: var(--accent);
    font-weight: 600;
}

.apps-result-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.apps-result-card header {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.apps-result-title {
    font-weight: 600;
    color: var(--text-primary);
}

.apps-result-uri {
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    word-break: break-all;
}

.apps-result-pre {
    margin: 0;
    padding: 8px 10px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 12px;
    color: var(--text-primary);
    max-height: 320px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Block that hosts the SphereResponseViewer Monaco editor inside the Orb
   response card. Fixed height keeps the result card from inflating when
   Monaco hands back a long value; Monaco's own scroll takes over. */
.apps-response-value-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 4px;
}

.apps-response-value-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.apps-response-value-mount {
    height: 280px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

@media (max-width: 1100px) {
    .apps-edit-grid {
        grid-template-columns: 1fr;
    }
    .apps-list-card {
        max-height: 320px;
    }
}

/* Split layout for the App Builder Run tab while the scene is still in
   progress. Form on the left, accumulating compact result cards on the right.
   The aside is only rendered once runResults.Count > 0, so the very first
   slide gets the full width until something has been captured. After
   runEnded the page reverts to the existing single-column finished view
   without these styles applying. */
.apps-run-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 18px;
    align-items: start;
}

.apps-run-main {
    /* min-width:0 lets the form/host shrink inside the grid track instead of
       pushing the side column off-screen on long URLs / wide previews. */
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.apps-run-side {
    display: flex;
    flex-direction: column;
    gap: 8px;
    /* Cap the side column's height so it scrolls independently of the form
       host. Roughly matches the visible viewport minus the page header/tab
       chrome — operators see the latest captures without the form
       disappearing off-screen. */
    max-height: 70vh;
    overflow-y: auto;
    padding-right: 4px;
}

.apps-run-side-header {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 8px;
    background-color: var(--bg-canvas);
    border-bottom: 1px solid var(--border-subtle);
}

.apps-run-side-title {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.apps-run-side-count {
    font-size: 12px;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.apps-result-card--compact {
    padding: 8px 10px;
    gap: 4px;
}

.apps-result-card--compact header {
    gap: 6px;
}

.apps-result-card--compact .apps-result-title {
    font-size: 12px;
}

.apps-result-card--compact .apps-result-uri {
    font-size: 10px;
}

.apps-result-card--compact .apps-result-pre {
    max-height: 120px;
    font-size: 11px;
    padding: 6px 8px;
}

@media (max-width: 1100px) {
    .apps-run-grid {
        grid-template-columns: 1fr;
    }
    .apps-run-side {
        max-height: 360px;
    }
}

/* ─── Apps launchpad (/apps) ──────────────────────────────────────────────── */

.apps-launch-toolbar {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    flex-wrap: wrap;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 16px;
    margin-bottom: 14px;
}

.apps-launch-namespace {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 14em;
}

.apps-launch-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.apps-launch-search {
    flex: 1 1 240px;
    max-width: 30em;
}

.apps-launch-builder {
    margin-left: auto;
}

/* The launchpad cards re-use `.app-card-grid` / `.app-card`. We render them as <button>
   so the click triggers an in-page state change; these overrides make the button behave
   visually identical to the <a>-based AppCard used elsewhere. */
.apps-launch-card {
    appearance: none;
    background-color: var(--bg-surface);
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    color: inherit;
    width: 100%;
}

.apps-launch-card-mock {
    opacity: 0.78;
    border-style: dashed;
}

.apps-launch-card-mock-pill {
    display: inline-block;
    margin-left: 6px;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 1px 6px;
    border-radius: 9999px;
    background-color: var(--accent-soft);
    border: 1px solid var(--accent);
    color: var(--accent);
    vertical-align: middle;
}

.apps-launch-card-flow {
    font-feature-settings: 'tnum';
}

.apps-launch-card-version {
    color: var(--text-muted);
    font-size: 11px;
}

/* Trash button overlaid in the top-right corner of an apps-launch-card.
   AuthorizeView around the rendered element gates visibility to Admin /
   SuperAdmin, and the outer card is now a <div role="button"> so this real
   <button> can sit inside without HTML5 nesting violations. */
.apps-launch-card-delete {
    position: absolute;
    top: 8px;
    right: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background-color: transparent;
    color: var(--text-muted);
    font-size: 14px;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.apps-launch-card-delete:hover {
    background-color: var(--danger-soft, rgba(220, 53, 69, 0.1));
    color: var(--danger, #dc3545);
    border-color: var(--danger, #dc3545);
}

.apps-launch-card-delete:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Edit button — sits to the left of the trash, same square footprint,
   primary-accent hover instead of danger so the two affordances are
   visually distinct. Gated to SuperAdmin via AuthorizeView; if the trash
   is hidden (non-Admin), the edit slot is too so the corner stays clean. */
.apps-launch-card-edit {
    position: absolute;
    top: 8px;
    right: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background-color: transparent;
    color: var(--text-muted);
    font-size: 14px;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.apps-launch-card-edit:hover {
    background-color: var(--accent-soft, rgba(59, 130, 246, 0.1));
    color: var(--accent, #3b82f6);
    border-color: var(--accent, #3b82f6);
}

.apps-launch-card-edit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Inline launch panel — shown in place of the grid once a card is clicked. */
.apps-launch-panel {
    display: flex;
    flex-direction: column;
    gap: 14px;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 18px;
}

.apps-launch-panel-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.apps-launch-panel-title {
    margin: 4px 0 6px;
    font-size: 18px;
    color: var(--text-primary);
}

.apps-launch-panel-description {
    margin: 0 0 6px;
    color: var(--text-secondary);
}

.apps-launch-panel-route {
    display: inline-block;
    padding: 2px 10px;
    background-color: var(--bg-canvas);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 11px;
    color: var(--text-muted);
    word-break: break-all;
}

.apps-launch-actions {
    display: flex;
    justify-content: flex-end;
}

/* ─── AI Admin (/ai) ──────────────────────────────────────────────────────── */

.ai-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.ai-tab {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.ai-tab-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.ai-tab-toolbar h3 {
    margin: 0;
    font-size: 16px;
    color: var(--text-primary);
}

.ai-tab-meta {
    font-size: 12px;
    color: var(--text-muted);
    font-feature-settings: 'tnum';
    flex: 1 1 auto;
}

/* Service-type pills mirror the action-type pill palette pattern. */
.ai-service-pill {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    letter-spacing: 0.04em;
}

.ai-service-pill-openai { background-color: #ecfdf5; border-color: #10b981; color: #047857; }
.ai-service-pill-gemini { background-color: #eff6ff; border-color: #3b82f6; color: #1d4ed8; }
.ai-service-pill-claude { background-color: #fef3c7; border-color: #f59e0b; color: #b45309; }

html.dark .ai-service-pill-openai { background-color: rgba(16, 185, 129, 0.18); color: #6ee7b7; }
html.dark .ai-service-pill-gemini { background-color: rgba(59, 130, 246, 0.18); color: #93c5fd; }
html.dark .ai-service-pill-claude { background-color: rgba(245, 158, 11, 0.18); color: #fcd34d; }

.ai-secret {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
    font-size: 11.5px;
    color: var(--text-secondary);
}

.ai-reveal {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    user-select: none;
}

.ai-reveal input {
    margin: 0;
}

/* System prompts sections */
.ai-prompts-section {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ai-prompts-section header {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.ai-prompts-section h4 {
    margin: 0;
    font-size: 14px;
    color: var(--text-primary);
}

.ai-prompts-actions {
    display: flex;
    gap: 8px;
    margin-left: auto;
}

.ai-prompts-textarea {
    min-height: 200px;
    font-size: 12.5px;
    line-height: 1.5;
}

/* ─── Configurator (/configurator) ────────────────────────────────────────── */

.configurator-shell {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.configurator-tab-pane {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.configurator-tab-pane.is-hidden { display: none; }

.configurator-picker {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px 16px;
}

.configurator-picker-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.configurator-picker-select {
    width: 22em;
}

.configurator-loaded {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--accent);
}

/* Inline anchor-style button used inside data-table cells (e.g. the
   Operations type pair). Reads like a hyperlink but is a real <button> so
   the click handler can pop a Blazor dialog without leaving the page. */
.link-button {
    appearance: none;
    background: transparent;
    border: none;
    padding: 0;
    margin: 0;
    color: var(--accent);
    cursor: pointer;
    font: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.link-button:hover {
    text-decoration: none;
    color: var(--accent-strong, var(--accent));
}

.overview-type-arrow {
    margin: 0 6px;
    color: var(--text-muted);
}

/* Compact 22×22 icon button placed next to a dataweave name in the
   Transitions card. Slightly tighter than .icon-btn to keep the row scan-able. */
.overview-dw-icon {
    margin-left: 4px;
    padding: 2px 4px;
    font-size: 12px;
}

/* ─── Weave dialog ─────────────────────────────────────────────────────────
   Compact visual-mapping dialog. Layout from top to bottom:
     header  → fixed 44px
     toolbar → type pickers row (~52px)
     body    → 3-column grid (from-tree | Monaco | to-tree), fills remainder
     toolbar → weave/constant/undo row (~40px)
     summary → wrap of mapping chips (auto, capped)
     footer  → save/close
   Sized at 1040×640 so the editor has breathing room without overwhelming
   the underlying Configurator. Min/max keep it usable on narrower viewports. */

.weave-dialog {
    max-width: min(1040px, 95vw);
    width: 95vw;
    max-height: 90vh;
    height: 640px;
}

.weave-dialog-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0; /* let the workspace claim leftover height */
}

.weave-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.weave-type-row {
    gap: 12px;
}

.weave-type-cell {
    flex: 1 1 220px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.weave-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.weave-arrow {
    align-self: flex-end;
    margin-bottom: 8px;
    color: var(--text-muted);
    font-size: 16px;
}

.weave-workspace {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr) 220px;
    gap: 10px;
    flex: 1 1 auto;
    min-height: 0;
}

.weave-tree-pane,
.weave-editor-pane {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.weave-tree-pane > header,
.weave-editor-pane > header {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border-subtle);
    background-color: var(--bg-canvas);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    min-height: 24px;
}

.weave-selected {
    color: var(--accent);
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    font-size: 10.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 60%;
}

.weave-dirty {
    color: var(--accent);
    font-size: 10.5px;
    text-transform: none;
    letter-spacing: 0;
}

.weave-tree {
    list-style: none;
    margin: 0;
    padding: 4px 0;
    overflow: auto;
    flex: 1 1 auto;
    font-size: 12.5px;
}

.weave-tree-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px 3px 6px;
    cursor: pointer;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.weave-tree-item:hover {
    background-color: var(--bg-canvas);
}

.weave-tree-item.is-selected {
    background-color: var(--accent);
    color: white;
}

.weave-tree-item i {
    opacity: 0.7;
    font-size: 11px;
}

.weave-tree-item.is-selected i {
    opacity: 0.95;
}

.weave-empty {
    padding: 12px;
    text-align: center;
    color: var(--text-muted);
    font-size: 12px;
}

.weave-editor-mount {
    flex: 1 1 auto;
    min-height: 0;
}

.weave-actions-row {
    padding: 4px 0;
    border-top: 1px dashed var(--border-subtle);
    border-bottom: 1px dashed var(--border-subtle);
}

.weave-divider {
    width: 1px;
    background-color: var(--border-subtle);
    align-self: stretch;
}

.weave-spacer {
    flex: 1 1 auto;
}

.weave-constant-input {
    width: 160px;
}

.weave-mappings {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 64px;
    overflow: auto;
}

.weave-mapping-chip {
    background-color: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 2px 8px;
    font-size: 11.5px;
    color: var(--text-primary);
}

.weave-error {
    margin: 0;
}

.weave-footer {
    justify-content: flex-end;
}

@media (max-width: 900px) {
    .weave-workspace {
        grid-template-columns: 1fr;
        grid-auto-rows: minmax(160px, auto);
    }
    .weave-dialog {
        height: auto;
        max-height: 95vh;
    }
}

/* Inline call-to-action inside the deploy banner (e.g. "Open dataweave
   editor"). Sits between the multi-line message and the close button —
   page-banner uses `align-items: flex-start`, so nudge it down a hair so
   it aligns with the first message line. */
.configurator-banner-link {
    align-self: flex-start;
    white-space: nowrap;
    padding: 0;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    text-decoration: underline;
}

.configurator-banner-link:hover {
    text-decoration: none;
}

.configurator-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.configurator-card > header h3 {
    margin: 0;
    font-size: 14px;
    color: var(--text-primary);
}

.configurator-card > header p {
    margin: 2px 0 0;
    font-size: 12px;
    color: var(--text-muted);
}

.configurator-general {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 14px;
}

.configurator-card-actions,
.configurator-card-wide {
    grid-column: 1 / -1;
}

.configurator-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.configurator-version-row {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
}

.configurator-version-row .form-control {
    flex: 1 1 8em;
    min-width: 8em;
}

.configurator-overview,
.configurator-workflow,
.configurator-operations,
.configurator-exceptions {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.configurator-node-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 14px;
}

/* Workflow tab: places&transitions card on the left, gojs viewer on the right.
   At narrow viewports the row collapses (see the @media block below) so the
   stack falls back to "places&transitions on top, viewer below". */
.configurator-workflow-row {
    display: grid;
    grid-template-columns: minmax(220px, 320px) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

/* The left card matches the viewer's 520px height; long place/transition lists
   scroll inside the card instead of stretching the whole row. */
.configurator-workflow-row__nodes {
    max-height: 520px;
    overflow-y: auto;
}

/* When places&transitions sits in the narrow left column, stack the two
   sub-columns vertically (Places above Transitions). The default 2-col grid
   would be too cramped at ~280px wide. */
.configurator-node-grid--stacked {
    grid-template-columns: minmax(0, 1fr);
}

.configurator-node-col h4 {
    margin: 0 0 8px;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.configurator-node-chip {
    padding: 2px;
}

.configurator-node-btn {
    appearance: none;
    background: transparent;
    border: none;
    color: inherit;
    cursor: pointer;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.configurator-node-btn:hover {
    color: var(--accent);
}

.configurator-add-actions {
    display: flex;
    justify-content: flex-end;
}

.configurator-exceptions-grid {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 14px;
    min-height: 480px;
}

.configurator-rules-list,
.configurator-rule-editor {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
}

.configurator-rules-list > header,
.configurator-rule-editor > header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.configurator-rules-list h4,
.configurator-rule-editor h4 {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.configurator-exception-data {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
}

.configurator-exception-data legend {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    padding: 0 4px;
}

.configurator-exception-data label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-secondary);
}

.configurator-strategy-saved {
    font-size: 11px;
    align-self: flex-end;
}

.configurator-panel-subhead {
    margin: 14px 0 8px;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

/* TransitionDetailPanel: Properties + Secrets sit side by side inside the
   modal, each in its own lightly-bordered card to make the boundary obvious
   without the heavyweight `.configurator-card` chrome (which is meant for
   page-level sections, not inside a dialog). */
.transition-detail-pair {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

.transition-detail-card {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background-color: var(--bg-surface);
    padding: 12px 14px 14px;
}

/* The h4 inside each card carries its own top margin from
   `.configurator-panel-subhead`; zero it out so the card padding sets the
   spacing instead. */
.transition-detail-card > .configurator-panel-subhead:first-child {
    margin-top: 0;
}

@media (max-width: 1100px) {
    .configurator-general,
    .configurator-node-grid {
        grid-template-columns: 1fr;
    }
    .configurator-exceptions-grid {
        grid-template-columns: 1fr;
    }
    .configurator-rules-list {
        max-height: 320px;
    }
    /* Below ~1100px the side-by-side row is too cramped — fall back to
       "places&transitions on top, viewer below". Lift the height cap on the
       nodes card now that it has the full width to work with. */
    .configurator-workflow-row {
        grid-template-columns: 1fr;
    }
    .configurator-workflow-row__nodes {
        max-height: none;
        overflow-y: visible;
    }
    /* Same call inside the Transition modal: side-by-side Properties / Secrets
       cards become too tight, so stack them. */
    .transition-detail-pair {
        grid-template-columns: 1fr;
    }
}

/* ─── Maintenance page ────────────────────────────────────────────────────
   Admin → Maintenance: five cleanup tabs (Types, Models, Policies, Forms,
   KPI). The first three are per-row deletion lists with a trash button;
   Forms and KPI are bulk-delete cards centred on a count + a confirm. */

.maintenance-tab {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-top: 12px;
}

.maintenance-toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.maintenance-toolbar-info { flex: 1; min-width: 0; }

.maintenance-toolbar-info h3 {
    margin: 0 0 4px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}

.maintenance-toolbar-info p {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* Per-row table — used by Types, Models, Policies. */
.maintenance-table {
    width: 100%;
    border-collapse: collapse;
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.maintenance-table thead th {
    text-align: left;
    padding: 10px 14px;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    background-color: var(--bg-elevated, var(--bg-surface));
    border-bottom: 1px solid var(--border-subtle);
    font-weight: 600;
}

.maintenance-table tbody td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-subtle);
    font-size: 13px;
    color: var(--text-primary);
    vertical-align: middle;
}

.maintenance-table tbody tr:last-child td { border-bottom: none; }

.maintenance-table tbody tr:hover {
    background-color: var(--bg-hover, rgba(0, 0, 0, 0.02));
}

.maintenance-col-action {
    width: 56px;
    text-align: right;
}

.maintenance-col-desc {
    color: var(--text-muted);
    max-width: 480px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Small trash button used inline in the maintenance tables. */
.btn-sm {
    padding: 4px 8px;
    font-size: 12px;
    line-height: 1;
    border-radius: var(--radius-sm);
}

.btn-danger-outline {
    background-color: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border-subtle);
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-danger-outline:hover {
    background-color: var(--danger-soft, rgba(220, 53, 69, 0.1));
    color: var(--danger, #dc3545);
    border-color: var(--danger, #dc3545);
}

.btn-danger-outline:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Bulk-delete card — Forms and KPI share this shape. */
.maintenance-bulk-card {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.maintenance-kpi-controls {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
}

.maintenance-kpi-date {
    max-width: 200px;
}

.maintenance-bulk-stats {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 24px;
    row-gap: 6px;
    margin: 0;
    font-size: 13px;
}

.maintenance-bulk-stats dt {
    color: var(--text-muted);
    font-weight: 500;
}

.maintenance-bulk-stats dd {
    margin: 0;
    color: var(--text-primary);
}

.maintenance-bulk-stats-count {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.maintenance-bulk-actions {
    display: flex;
    justify-content: flex-end;
    padding-top: 4px;
    border-top: 1px solid var(--border-subtle);
}

/* Empty-state icon — used in every tab when nothing's cleanable. */
.maintenance-empty-icon {
    font-size: 20px;
    color: var(--success, #28a745);
    margin-right: 8px;
    vertical-align: middle;
}

@media (max-width: 720px) {
    .maintenance-toolbar { flex-direction: column; align-items: stretch; }
    .maintenance-table { font-size: 12px; }
    .maintenance-col-desc { max-width: none; }
    .maintenance-bulk-stats { grid-template-columns: 1fr; row-gap: 2px; }
    .maintenance-bulk-stats dt { padding-top: 8px; }
}

/* ─── Elicit form page ──────────────────────────────────────────────────── */
/* /tasks page — top-level tab nav. The labels keep the visual weight of the
   previous `<h1>Tasks</h1>` heading, with a subtle underline on the active
   tab and a muted, hover-able treatment on the inactive one so the user can
   tell they're tabs without screaming "tabs!" at them. */

.tasks-tabnav {
    display: flex;
    gap: 6px;
    align-items: flex-end;
    /* Sit on top of the border so the active tab visually "merges" into
       the content area below (classic browser-tab affordance). */
    border-bottom: 2px solid var(--border-emphasis);
    margin-bottom: 1rem;
    padding: 0 0 0 0.25rem;
}
.tasks-tab {
    /* h1-class typography so the active tab matches the previous heading. */
    font-size: 2rem;
    font-weight: 600;
    line-height: 1.1;
    color: var(--text-secondary);
    background: var(--bg-canvas);
    border: 2px solid var(--border-subtle);
    border-bottom: none;
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
    padding: 0.4rem 1.25rem 0.55rem 1.25rem;
    /* Active tab "sits on" the nav's bottom border by pulling itself down
       2px, so its bottom edge overlaps the line. Inactive tabs stay above
       the line and look detached. */
    margin: 0 0 -2px 0;
    cursor: pointer;
    transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}
.tasks-tab:hover:not(.is-active) {
    color: var(--text-primary);
    background: var(--bg-surface);
    border-color: var(--border-emphasis);
}
.tasks-tab.is-active {
    color: var(--text-primary);
    background: var(--bg-surface);
    border-color: var(--border-emphasis);
    /* Cover the nav's bottom border across the width of this tab — makes
       the tab look like it merges into the content below. */
    box-shadow: 0 2px 0 0 var(--bg-surface);
}
.tasks-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.tasks-tabcontent {
    /* Sits below the merged tab/border line so .tasks-tab.is-active's
       box-shadow has a `--bg-surface` background to "punch through" into.
       The pages inside (Inbox, Processes) bring their own backgrounds. */
}

/* Mobile: shrink the tab typography + padding so 3 tabs fit on a phone.
   Same 720px breakpoint the Processes pane uses for its single-column
   stack — keeps the responsive thresholds consistent across /tasks. */
@media (max-width: 720px) {
    .tasks-tabnav {
        gap: 2px;
        padding: 0;
    }
    .tasks-tab {
        font-size: 1rem;
        font-weight: 600;
        padding: 0.35rem 0.7rem 0.45rem 0.7rem;
        border-width: 1px;
        border-top-left-radius: var(--radius-sm);
        border-top-right-radius: var(--radius-sm);
        /* Pull the bottom edge down 1px to match the now-thinner border. */
        margin: 0 0 -1px 0;
        min-width: 0;
    }
    .tasks-tabnav {
        border-bottom-width: 1px;
    }
}

/* Processes tab — two-pane list + detail. Same shape as Types or Realms. */
.processes-shell {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 1rem;
    min-height: 60vh;
}
.processes-list {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    overflow: auto;
    max-height: 75vh;
}
.processes-list ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.processes-list-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 100%;
    text-align: left;
    padding: 10px 12px;
    border: none;
    border-bottom: 1px solid var(--border-subtle);
    background: transparent;
    cursor: pointer;
    color: var(--text-primary);
    transition: background 0.1s ease;
}
.processes-list-item:hover {
    background: var(--accent-soft);
}
.processes-list-item.is-selected {
    background: var(--accent-soft);
    border-left: 3px solid var(--accent);
    padding-left: 9px;
}
.processes-list-name { font-weight: 600; }
.processes-list-version { color: var(--text-secondary); font-size: 0.8rem; }
.processes-list-description {
    color: var(--text-secondary);
    font-size: 0.8rem;
    margin-top: 2px;
}
.processes-list-input {
    color: var(--text-muted);
    font-size: 0.75rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.processes-detail {
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    overflow: auto;
}
.processes-detail-header { margin-bottom: 1rem; }
.processes-detail-header h3 { margin: 0 0 0.25rem 0; }
.processes-detail-description { color: var(--text-secondary); margin: 0.25rem 0; }
.processes-detail-meta { color: var(--text-muted); font-size: 0.85rem; }
.processes-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-subtle);
}
.processes-response {
    margin-top: 1rem;
    background: var(--bg-canvas);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.75rem;
}
.processes-response pre {
    margin: 0.5rem 0 0 0;
    max-height: 240px;
    overflow: auto;
    font-size: 0.8rem;
}

/* Mobile-only "back to list" button — desktop layout already has both panels
   visible side-by-side, so the back-button only exists when the layout
   stacks vertically (the @media block below). */
.processes-back-mobile { display: none; }

/* Mobile layout: single column. Showing both panels at once on a narrow
   screen squeezes the detail off the viewport (the bug being fixed here).
   Instead, swap to a focused single-panel view — list when nothing is
   selected, detail when something is. `.has-selection` on the shell is the
   toggle, set by Processes.razor when `selected != null`. */
@media (max-width: 720px) {
    .processes-shell {
        grid-template-columns: 1fr;
        min-height: auto;
    }
    .processes-list {
        max-height: 70vh;
    }
    .processes-shell.has-selection .processes-list {
        display: none;
    }
    .processes-shell:not(.has-selection) .processes-detail {
        display: none;
    }
    .processes-back-mobile {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        margin-bottom: 0.75rem;
        background: transparent;
        border: 1px solid var(--border-subtle);
        color: var(--text-secondary);
        padding: 4px 10px;
        border-radius: var(--radius-sm);
        font-size: 0.9em;
        cursor: pointer;
    }
    .processes-back-mobile:hover {
        background: var(--accent-soft);
        border-color: var(--accent);
        color: var(--accent);
    }
}

/* /elicit/{uuid} — hosted form page backing CircleMCP's request_user_input.
   Two surfaces: the active form (`.elicit-form`) and the terminal states
   (`.elicit-terminal`) shown when the form is submitted / cancelled /
   expired / forbidden.

   The global `html, body { overflow: hidden }` rule above is intentional
   for the main Sphere shell (sidebar + topbar + internal scroll panes),
   but it traps tall elicit forms — the page won't scroll when content
   exceeds the viewport. `:has()` re-enables page-level scroll only when
   an elicit surface is present, leaving the rest of the app unaffected. */

html:has(.elicit-form),
html:has(.elicit-terminal),
body:has(.elicit-form),
body:has(.elicit-terminal) {
    height: auto;
    min-height: 100dvh;
    overflow: auto;
}

.elicit-form {
    max-width: 720px;
    margin: 24px auto;
    padding: 24px;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.elicit-form-header {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--bs-border-color);
}
.elicit-form-title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 600;
}
.elicit-form-meta {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    font-size: 0.875rem;
    color: var(--bs-secondary-color);
}
.elicit-form-meta i { margin-right: 4px; }
.elicit-form-description {
    margin-bottom: 16px;
    padding: 12px 16px;
    background: var(--bs-tertiary-bg);
    border-radius: 8px;
    white-space: pre-wrap;
}
.elicit-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--bs-border-color);
}

.elicit-terminal {
    max-width: 480px;
    margin: 64px auto;
    padding: 32px;
    text-align: center;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.elicit-terminal h2 {
    margin: 16px 0 8px;
    font-size: 1.25rem;
    font-weight: 600;
}
.elicit-terminal p {
    margin: 0;
    color: var(--bs-secondary-color);
    line-height: 1.6;
}
.elicit-terminal-icon {
    font-size: 3rem;
    color: var(--bs-secondary-color);
    display: inline-block;
}
.elicit-terminal-icon-ok {
    color: var(--bs-success, #198754);
}
