/*
 * ProdQuery Guard — base application theme
 * Extracted from base.html. Loaded once via <link> so the browser caches it
 * and Django no longer re-parses ~630 lines of CSS on every render.
 */
/* ============================================================================
   DESIGN TOKENS — the single source of truth for the console's visual language.
   Two tiers: raw *primitive* ramps resolve into *semantic aliases*; component
   CSS below references ONLY the semantic aliases (and the back-compat names at
   the bottom), never a raw hex. Full reference: docs/07-ui-design-guidelines.md
   and the living style guide at /_styleguide/ (DEBUG/staff only).
   ========================================================================== */
:root {
    /* ---- PRIMITIVES · neutral (slate) ---- */
    --slate-50: #f8fafc;
    --slate-100: #f1f5f9;
    --slate-200: #e2e8f0;
    --slate-300: #cbd5e1;
    --slate-400: #94a3b8;
    --slate-500: #64748b;
    --slate-600: #475569;
    --slate-700: #334155;
    --slate-800: #1e293b;
    --slate-900: #0f172a;

    /* ---- PRIMITIVES · brand (indigo) ---- */
    --indigo-50: #eef2ff;
    --indigo-300: #a5b4fc;
    --indigo-400: #818cf8;
    --indigo-500: #4f46e5;
    --indigo-600: #4338ca;
    --indigo-700: #3730a3;

    /* ---- PRIMITIVES · status ramps (light stop / solid / hover / dark text) ---- */
    --green-50: #ecfdf5;  --green-200: #a7f3d0; --green-400: #34d399; --green-500: #10b981; --green-600: #059669; --green-700: #047857; --green-800: #065f46;
    --amber-50: #fffbeb;  --amber-200: #fde68a; --amber-400: #fbbf24; --amber-500: #f59e0b; --amber-600: #d97706; --amber-700: #b45309; --amber-800: #92400e;
    --red-50:   #fef2f2;  --red-200:   #fecaca; --red-400:   #f87171; --red-500:   #ef4444; --red-600:   #dc2626; --red-800:   #991b1b;
    --blue-50:  #eff6ff;  --blue-200:  #bfdbfe; --blue-400:  #60a5fa; --blue-500:  #3b82f6; --blue-600:  #2563eb; --blue-800:  #1e40af;

    /* ---- SEMANTIC · surface & border ---- */
    --bg-page: var(--slate-50);
    --bg-surface: #ffffff;
    --bg-subtle: var(--slate-100);
    --border: var(--slate-200);
    --border-strong: var(--slate-300);

    /* ---- SEMANTIC · text ---- */
    --text: var(--slate-800);
    --text-muted: var(--slate-500);
    --text-subtle: var(--slate-400);
    --text-on-accent: #ffffff;

    /* ---- SEMANTIC · brand accent ---- */
    --accent: var(--indigo-500);
    --accent-hover: var(--indigo-600);
    --accent-active: var(--indigo-700);
    --accent-soft-bg: var(--indigo-50);
    --accent-tint: rgba(79, 70, 229, 0.04);        /* faint row hover */
    --accent-tint-strong: rgba(79, 70, 229, 0.15); /* search-match highlight */
    --focus-ring: rgba(79, 70, 229, 0.25);
    --focus-border: var(--indigo-300);

    /* ---- SEMANTIC · status (each: solid / hover / soft-bg / line / text) ---- */
    --ok-solid: var(--green-500);  --ok-hover: var(--green-600);  --ok-soft: var(--green-50);  --ok-line: var(--green-200);  --ok-text: var(--green-800);
    --warn-solid: var(--amber-500); --warn-hover: var(--amber-600); --warn-soft: var(--amber-50); --warn-line: var(--amber-200); --warn-text: var(--amber-800);
    --dgr-solid: var(--red-500);   --dgr-hover: var(--red-600);   --dgr-soft: var(--red-50);   --dgr-line: var(--red-200);   --dgr-text: var(--red-800);
    --info-solid: var(--blue-500); --info-hover: var(--blue-600); --info-soft: var(--blue-50); --info-line: var(--blue-200); --info-text: var(--blue-800);

    /* ---- TYPE ---- */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
    --fs-eyebrow: 0.7rem;  /* uppercase micro-label */
    --fs-xs: 0.75rem;
    --fs-sm: 0.8rem;
    --fs-base: 0.875rem;   /* body default */
    --fs-md: 1rem;
    --fs-lg: 1.125rem;
    --fs-xl: 1.375rem;     /* page title */
    --fs-2xl: 1.75rem;     /* stat value */
    --fw-regular: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    /* ---- SPACE · 4px base ---- */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-7: 2rem;
    --space-8: 3rem;

    /* ---- RADIUS ---- */
    --r-xs: 4px;
    --r-sm: 6px;
    --r-md: 8px;
    --r-lg: 12px;
    --r-pill: 999px;

    /* ---- ELEVATION ---- */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 20px -5px rgb(0 0 0 / 0.18);

    /* ---- MOTION ---- */
    --transition: all 0.2s ease;
    --transition-fast: all 0.15s ease;

    /* ---- Z-INDEX layers (see .content-head / .sidebar / flyouts) ---- */
    --z-content-head: 1020;
    --z-scrim: 1025;
    --z-sidebar: 1030;
    --z-flyout: 1040;

    /* ---- SIDEBAR (the one place the palette inverts to dark) ---- */
    --side-w: 232px;
    --rail-w: 64px;
    --side-bg: linear-gradient(180deg, #1e293b 0%, #263449 55%, #334155 100%);
    --side-fg: var(--slate-300);
    --side-fg-dim: var(--slate-400);
    --side-active-bg: rgba(99, 91, 255, 0.22);
    --side-hover-bg: rgba(255, 255, 255, 0.07);
    --side-line: rgba(255, 255, 255, 0.09);
    --side-menu-bg: var(--slate-900);
    --side-cur: var(--side-w);

    /* Map Bootstrap's palette onto the brand palette so utility classes
       (badges, links, text-* and bg-* utilities, active states) render
       on-brand. */
    --bs-primary: #4f46e5;
    --bs-primary-rgb: 79, 70, 229;
    --bs-success: #10b981;
    --bs-success-rgb: 16, 185, 129;
    --bs-info: #3b82f6;
    --bs-info-rgb: 59, 130, 246;
    --bs-warning: #f59e0b;
    --bs-warning-rgb: 245, 158, 11;
    --bs-danger: #ef4444;
    --bs-danger-rgb: 239, 68, 68;
    --bs-link-color: #4f46e5;
    --bs-link-color-rgb: 79, 70, 229;
    --bs-link-hover-color: #4338ca;
    --bs-link-hover-color-rgb: 67, 56, 202;

    /* Code syntax palette (GitHub light). Single source of truth shared by the
       highlight.js viewer (partials/_code_highlight.html) and the CodeMirror
       editors so read-only views and editors render in one identical theme. */
    --code-fg: #24292e;
    --code-keyword: #6f42c1;
    --code-string: #032f62;
    --code-number: #b31d28;
    --code-attr: #005cc5;
    --code-comment: #6a737d;
    --code-bullet: #735c0f;
    --code-add-fg: #22863a;
    --code-add-bg: #e6ffed;
    --code-del-fg: #b31d28;
    --code-del-bg: #ffeef0;

    /* ---- BACK-COMPAT ALIASES ----
       Older component CSS (and templates) reference these names. They now
       resolve to the semantic tokens above, so the whole app inherits the
       system with zero visual change. Prefer the semantic names in new code. */
    --primary: var(--accent);
    --primary-hover: var(--accent-hover);
    --success: var(--ok-solid);
    --warning: var(--warn-solid);
    --danger: var(--dgr-solid);
    --info: var(--info-solid);
    --dark: var(--text);
    --muted: var(--text-muted);
    --light-bg: var(--bg-page);
    --card-bg: var(--bg-surface);
    --border-color: var(--border);
    --radius: var(--r-lg);
    --radius-sm: var(--r-md);
}

/* Brand alignment for Bootstrap components that compile literal colours
   (buttons, active states, focus ring) rather than reading --bs-* vars. */
.btn-primary {
    --bs-btn-bg: var(--accent);
    --bs-btn-border-color: var(--accent);
    --bs-btn-hover-bg: var(--accent-hover);
    --bs-btn-hover-border-color: var(--accent-hover);
    --bs-btn-active-bg: var(--accent-hover);
    --bs-btn-active-border-color: var(--accent-active);
    --bs-btn-disabled-bg: var(--accent);
    --bs-btn-disabled-border-color: var(--accent);
}

.btn-outline-primary {
    --bs-btn-color: var(--accent);
    --bs-btn-border-color: var(--accent);
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--accent);
    --bs-btn-active-bg: var(--accent);
    --bs-btn-active-border-color: var(--accent);
}

.btn-success {
    --bs-btn-bg: var(--ok-solid);
    --bs-btn-border-color: var(--ok-solid);
    --bs-btn-hover-bg: var(--ok-hover);
    --bs-btn-hover-border-color: var(--ok-hover);
    --bs-btn-active-bg: var(--ok-hover);
    --bs-btn-active-border-color: var(--green-700);
}

.btn-warning {
    --bs-btn-bg: var(--warn-solid);
    --bs-btn-border-color: var(--warn-solid);
    --bs-btn-hover-bg: var(--warn-hover);
    --bs-btn-hover-border-color: var(--warn-hover);
    --bs-btn-active-bg: var(--warn-hover);
    --bs-btn-active-border-color: var(--amber-700);
}

.btn-outline-danger {
    --bs-btn-color: var(--dgr-solid);
    --bs-btn-border-color: var(--dgr-solid);
    --bs-btn-hover-bg: var(--dgr-solid);
    --bs-btn-hover-border-color: var(--dgr-solid);
    --bs-btn-active-bg: var(--dgr-solid);
    --bs-btn-active-border-color: var(--dgr-solid);
}

.list-group-item.active {
    background-color: var(--accent);
    border-color: var(--accent);
}

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

/* text-bg-* utilities compile literal colours in BS5.3 — recolour to brand. */
.text-bg-primary {
    background-color: var(--accent) !important;
}

.text-bg-info {
    background-color: var(--info-solid) !important;
    color: #fff !important;
}

.text-bg-success {
    background-color: var(--ok-solid) !important;
}

.text-bg-danger {
    background-color: var(--dgr-solid) !important;
}

.text-bg-warning {
    background-color: var(--warn-solid) !important;
}

.text-bg-dark {
    background-color: var(--text) !important;
}

.text-bg-secondary {
    background-color: var(--text-muted) !important;
}

/* The ONE focus ring for the app: indigo-300 border + a soft indigo halo.
   Used by inputs, selects and btn-check pickers so focus reads identically
   everywhere (was previously defined twice, with different rings). */
.form-control:focus,
.form-select:focus,
.btn-check:focus-visible+.btn {
    border-color: var(--focus-border);
    box-shadow: 0 0 0 0.25rem var(--focus-ring);
}

/* Eyebrow / field label — the uppercase micro-label above a value or
   field. ONE definition for this type scale (was also duplicated, with a
   hardcoded grey, in query_result.html). Use the class, not inline styles. */
.field-label {
    display: block;
    text-transform: uppercase;
    font-size: .7rem;
    letter-spacing: .05em;
    color: var(--muted);
    margin-bottom: .25rem;
}

/* Choice control — the ONE pattern for btn-check pickers (segmented chips
   AND radio cards). One language everywhere: white default, neutral grey
   hover, indigo (brand) selected. Apply `.choice` to the <label> paired
   with a `.btn-check` input (label also keeps Bootstrap `.btn` for sizing). */
.btn-check+.choice {
    border: 1px solid var(--border);
    background-color: var(--bg-surface);
    color: var(--text);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn-check+.choice:hover {
    /* neutral grey = "pointing at" */
    background-color: var(--bg-subtle);
    border-color: var(--border-strong);
    color: var(--text);
}

.btn-check:checked+.choice {
    /* indigo = "selected" (brand accent) */
    background-color: var(--accent-soft-bg); /* fallback for no color-mix */
    background-color: color-mix(in srgb, var(--accent) 10%, #fff);
    border-color: var(--accent);
    color: var(--accent-hover);
    box-shadow: inset 0 0 0 1px var(--accent);
}

.btn-check:checked+.choice .text-body-secondary {
    color: var(--muted) !important;
}

/* Outline focus ring stays visible even when checked (the inset box-shadow
   above would otherwise mask the default focus ring at equal specificity). */
.btn-check:focus-visible+.choice {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

* {
    box-sizing: border-box;
}

html {
    height: 100%;
}

body {
    min-height: 100vh;
    background-color: var(--light-bg);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 0.875rem;
    color: var(--dark);
    line-height: 1.6;
}

/* ==================================================================
   Left Sidebar Navigation
   Two-level menu: modules (Prod Query, k8s GitOps) each hold a
   sub-menu. Collapses to a 64px icon rail; becomes an off-canvas
   drawer below the lg breakpoint. Sidebar tokens (--side-*) live in the
   design-token layer at the top of this file.
   ================================================================== */
.nav-collapsed { --side-cur: var(--rail-w); }

.app-shell {
    display: grid;
    grid-template-columns: var(--side-cur) 1fr;
    min-height: 100vh;
    transition: grid-template-columns 0.22s ease;
}

.sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--side-bg);
    color: var(--side-fg);
    box-shadow: var(--shadow-md);
    z-index: 1030;
    overflow: hidden;
}

/* Brand */
.side-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 60px;
    padding: 0 0.5rem 0 1rem;
    border-bottom: 1px solid var(--side-line);
    flex: none;
}
.brand-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 1;
    min-width: 0;
    color: #fff;
    text-decoration: none;
    font-weight: 700;
    letter-spacing: -0.02em;
    overflow: hidden;
}
.brand-mark {
    width: 30px;
    height: 30px;
    flex: none;
    border-radius: 9px;
    display: grid;
    place-items: center;
    font-size: 1rem;
    background: linear-gradient(135deg, var(--primary), #7c73ff);
    box-shadow: 0 2px 6px rgb(79 70 229 / 0.5);
}
.brand-text {
    font-size: 0.98rem;
    white-space: nowrap;
}
.collapse-btn {
    flex: none;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--side-fg-dim);
    cursor: pointer;
    display: grid;
    place-items: center;
    font-size: 1rem;
    transition: var(--transition);
}
.collapse-btn:hover { background: var(--side-hover-bg); color: #fff; }
.collapse-btn i { transition: transform 0.22s ease; display: block; }
.nav-collapsed .collapse-btn i { transform: rotate(180deg); }

/* Nav scroll region */
.side-nav {
    flex: 1;
    padding: 0.6rem 0.5rem;
    overflow-y: auto;
    overflow-x: hidden;
}

/* Module (top-level menu) */
.module { position: relative; }
.module + .module {
    margin-top: 0.4rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--side-line);
}
.module-head {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.1rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    color: var(--side-fg-dim);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    transition: var(--transition);
}
.module-head:hover { color: #fff; background: var(--side-hover-bg); }
.mod-ic { font-size: 1.05rem; color: var(--side-fg); }
.mod-name {
    flex: 1;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
}
.mod-caret {
    font-size: 0.72rem;
    opacity: 0.8;
    transition: transform 0.2s ease;
}
.module.expanded .mod-caret { transform: rotate(180deg); }
.mod-badge {
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.2em 0.48em;
    border-radius: 999px;
    background: var(--warning);
    color: #3d2b00;
}

/* Sub-menu (sub-level) */
.submenu {
    position: relative;
    padding-left: 0.95rem;
    overflow: hidden;
}
.submenu::before {
    content: "";
    position: absolute;
    left: 1.05rem;
    top: 0.15rem;
    bottom: 0.15rem;
    width: 1px;
    background: var(--side-line);
}
.module:not(.expanded) .submenu { display: none; }

.nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0.75rem;
    margin: 2px 0;
    border-radius: var(--radius-sm);
    color: var(--side-fg);
    text-decoration: none;
    font-weight: 500;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}
.nav-item i { font-size: 1.05rem; flex: none; }
.nav-item:hover { background: var(--side-hover-bg); color: #fff; }
.nav-item.active {
    background: var(--side-active-bg);
    color: #fff;
    font-weight: 600;
}
.submenu .nav-item.active::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    bottom: 6px;
    width: 3px;
    border-radius: 3px;
    background: var(--primary);
}
.lbl { flex: 1; min-width: 0; overflow: hidden; }
.nav-badge {
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.22em 0.5em;
    border-radius: 999px;
    background: var(--secondary, #64748b);
    color: #fff;
}
.nav-badge.danger { background: var(--danger); }

/* Account (pinned footer) */
.side-account {
    flex: none;
    border-top: 1px solid var(--side-line);
    padding: 0.5rem;
}
.account-trigger {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    color: var(--side-fg);
    text-decoration: none;
    text-align: left;
    cursor: pointer;
    transition: var(--transition);
}
.account-trigger:hover { background: var(--side-hover-bg); }
.account-trigger::after { display: none; } /* suppress Bootstrap caret */
.avatar {
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 1.15rem;
    color: #fff;
    background: linear-gradient(135deg, #475569, #64748b);
}
.account-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    overflow: hidden;
}
.account-name {
    color: #fff;
    font-weight: 600;
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.role-badge {
    align-self: flex-start;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.1em 0.45em;
    border-radius: 4px;
    background: rgba(16, 185, 129, 0.2);
    color: #6ee7b7;
    white-space: nowrap;
}
.account-trigger .caret {
    flex: none;
    font-size: 0.8rem;
    color: var(--side-fg-dim);
    transition: transform 0.2s ease;
}
.account-trigger[aria-expanded="true"] .caret { transform: rotate(180deg); }
.account-menu {
    min-width: 190px;
    background: var(--side-menu-bg);
    border: 1px solid var(--side-line);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    padding: 0.35rem;
}
.account-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.6rem;
    border-radius: 6px;
    color: var(--side-fg);
    font-weight: 500;
}
.account-menu .dropdown-item:hover,
.account-menu .dropdown-item:focus { background: var(--side-hover-bg); color: #fff; }
.account-menu .dropdown-item.text-danger:hover { background: rgba(239, 68, 68, 0.16); color: #fca5a5 !important; }
.account-menu .dropdown-divider { border-color: var(--side-line); margin: 0.3rem 0.2rem; }

/* ---------- Collapsed rail (desktop only) ----------
   Scoped to >=992px so it never fights the mobile drawer, which is
   always full-width regardless of the persisted collapse preference. */
@media (min-width: 992px) {
    .nav-collapsed .sidebar { overflow: visible; }
    .nav-collapsed .brand-text,
    .nav-collapsed .mod-name,
    .nav-collapsed .mod-caret,
    .nav-collapsed .account-meta,
    .nav-collapsed .account-trigger .caret { display: none; }
    /* Rail is only 64px wide — stack the logo and the expand toggle
       vertically so they never overlap. */
    .nav-collapsed .side-brand {
        flex-direction: column;
        height: auto;
        gap: 0.35rem;
        padding: 0.5rem 0;
        justify-content: center;
    }
    .nav-collapsed .collapse-btn { position: static; width: 30px; height: 24px; }
    .nav-collapsed .brand-link { flex: none; justify-content: center; }
    .nav-collapsed .side-nav { overflow: visible; padding: 0.6rem 0.4rem; }
    .nav-collapsed .module-head { justify-content: center; padding: 0.65rem 0; }
    .nav-collapsed .mod-badge {
        position: absolute;
        top: 3px;
        right: 11px;
        width: 9px;
        height: 9px;
        padding: 0;
        font-size: 0;
        border: 2px solid #22304a;
        border-radius: 50%;
    }
    .nav-collapsed .account-trigger { justify-content: center; padding: 0.5rem 0; }

    /* sub-menu becomes a hover flyout on the rail */
    .nav-collapsed .submenu {
        display: none;
        position: absolute;
        left: 100%;
        top: -4px;
        margin-left: 10px;
        width: 212px;
        padding: 1.9rem 0.4rem 0.4rem;
        background: var(--side-menu-bg);
        border: 1px solid var(--side-line);
        border-radius: var(--radius-sm);
        box-shadow: var(--shadow-md);
        overflow: visible;
        z-index: 1040;
    }
    .nav-collapsed .submenu::before {
        content: attr(data-title);
        position: absolute;
        left: 0.6rem;
        top: 0.55rem;
        width: auto;
        height: auto;
        background: none;
        font-size: 0.66rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        color: var(--side-fg-dim);
    }
    .nav-collapsed .submenu::after { /* invisible bridge keeps hover alive across the gap */
        content: "";
        position: absolute;
        right: 100%;
        top: 0;
        bottom: 0;
        width: 14px;
    }
    .nav-collapsed .module:hover .submenu,
    .nav-collapsed .module:focus-within .submenu { display: block; }
    .nav-collapsed .submenu .lbl { display: inline; }
    .nav-collapsed .submenu .nav-item { justify-content: flex-start; padding: 0.45rem 0.55rem; }
}

/* ---------- Main column ---------- */
.main-col {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.content-head {
    display: none; /* desktop: sidebar carries everything */
    align-items: center;
    gap: 0.75rem;
    height: 56px;
    padding: 0 1rem;
    background: var(--card-bg);
    border-bottom: 1px solid var(--border-color);
    position: sticky;
    top: 0;
    z-index: 1020;
}
.hamburger {
    width: 38px;
    height: 38px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--dark);
    cursor: pointer;
    display: grid;
    place-items: center;
    font-size: 1.25rem;
}
.hamburger:hover { background: var(--light-bg); }
.content-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--dark);
    text-decoration: none;
    font-weight: 700;
    letter-spacing: -0.02em;
}
.content-brand i { color: var(--primary); }

/* ---------- Mobile drawer ---------- */
.nav-scrim {
    display: none;
    position: fixed;
    inset: 0;
    background: rgb(15 23 42 / 0.5);
    z-index: 1025;
}
@media (max-width: 991.98px) {
    .app-shell { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed;
        left: 0;
        top: 0;
        width: var(--side-w);
        transform: translateX(-100%);
        transition: transform 0.25s ease;
    }
    .nav-open .sidebar { transform: translateX(0); }
    .nav-open .nav-scrim { display: block; }
    .collapse-btn { display: none; }
    .content-head { display: flex; }
}

/* Cards */
.card {
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    margin-bottom: 1.25rem;
    background: var(--card-bg);
    transition: var(--transition);
}

.card:hover {
    box-shadow: var(--shadow);
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--border-color);
    font-weight: 600;
    padding: 1rem 1.25rem;
    font-size: 0.875rem;
}

.card-body {
    padding: 1.25rem;
}

/* Buttons */
.btn {
    border-radius: var(--radius-sm);
    font-weight: 500;
    font-size: 0.8rem;
    padding: 0.5rem 1rem;
    transition: var(--transition);
    border: none;
}

.btn:hover {
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(0);
}

.btn-primary {
    background: var(--primary);
    color: white;
}

.btn-primary:hover {
    background: var(--primary-hover);
}

.btn-success {
    background: var(--success);
}

.btn-danger {
    background: var(--danger);
}

.btn-outline-primary {
    border: 1.5px solid var(--primary);
    color: var(--primary);
    background: transparent;
}

.btn-outline-primary:hover {
    background: var(--primary);
    color: white;
}

.btn-outline-secondary {
    border: 1.5px solid var(--border-color);
    color: var(--muted);
    background: transparent;
}

.btn-outline-secondary:hover {
    background: var(--light-bg);
    border-color: var(--muted);
    color: var(--dark);
}

.btn-sm {
    font-size: 0.75rem;
    padding: 0.375rem 0.75rem;
}

/* Badges */
.badge {
    padding: 0.35rem 0.65rem;
    font-weight: 500;
    font-size: 0.7rem;
    border-radius: 6px;
    letter-spacing: 0.01em;
}

.badge.bg-warning {
    background: linear-gradient(135deg, var(--amber-400) 0%, var(--amber-500) 100%) !important;
}

.badge.bg-success {
    background: linear-gradient(135deg, var(--green-400) 0%, var(--green-500) 100%) !important;
}

.badge.bg-danger {
    background: linear-gradient(135deg, var(--red-400) 0%, var(--red-500) 100%) !important;
}

.badge.bg-info {
    background: linear-gradient(135deg, var(--blue-400) 0%, var(--blue-500) 100%) !important;
}

.badge.bg-secondary {
    background: var(--text-muted) !important;
}

.badge.bg-primary {
    background: linear-gradient(135deg, var(--indigo-400) 0%, var(--indigo-500) 100%) !important;
}

/* Tables */
.table {
    margin-bottom: 0;
    font-size: 0.8rem;
}

.table thead th {
    border-bottom: 2px solid var(--border-color);
    font-weight: 600;
    color: var(--muted);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.875rem 1rem;
    background: var(--light-bg);
}

.table tbody tr {
    transition: var(--transition);
}

.table tbody tr:hover {
    background: var(--bg-subtle);
}

.table tbody td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: middle;
}

.table-hover tbody tr:hover {
    background: var(--accent-tint);
}

/* Alerts */
.alert {
    border: none;
    border-radius: var(--radius-sm);
    border-left: 4px solid;
    font-size: 0.8rem;
    padding: 0.875rem 1rem;
}

.alert-success {
    background: var(--ok-soft);
    border-left-color: var(--ok-solid);
    color: var(--ok-text);
}

.alert-danger {
    background: var(--dgr-soft);
    border-left-color: var(--dgr-solid);
    color: var(--dgr-text);
}

.alert-warning {
    background: var(--warn-soft);
    border-left-color: var(--warn-solid);
    color: var(--warn-text);
}

.alert-info {
    background: var(--info-soft);
    border-left-color: var(--info-solid);
    color: var(--info-text);
}

/* Forms */
.form-control,
.form-select {
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: 0.8rem;
    padding: 0.625rem 0.875rem;
    transition: var(--transition);
}

.form-select {
    padding-right: 2.25rem;
}

/* Focus ring is defined once, near the top (.form-control:focus …). */

.form-label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--dark);
    margin-bottom: 0.375rem;
}

.form-control-sm,
.form-select-sm {
    font-size: 0.75rem;
    padding: 0.5rem 0.75rem;
}

.form-select-sm {
    padding-right: 2rem;
}

/* Page Header */
.page-header {
    margin-bottom: 1.5rem;
}

.page-header h1 {
    font-size: 1.375rem;
    font-weight: 700;
    color: var(--dark);
    margin: 0;
    letter-spacing: -0.02em;
}

.page-header h1 i {
    color: var(--primary);
    opacity: 0.8;
}

/* Stat Cards */
.stat-card {
    transition: var(--transition);
    border: 1px solid var(--border-color);
}

.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.stat-card .display-6 {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--dark);
}

/* Main content - flex-grow to push footer down */
main {
    flex: 1;
}

/* Footer */
footer {
    margin-top: auto;
    border-top: 1px solid var(--border-color);
    background: var(--card-bg);
}

footer small {
    color: var(--muted);
    font-size: 0.75rem;
}

/* Typography */
h5 {
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

h6 {
    font-size: 0.8125rem;
    font-weight: 600;
}

.fs-4 {
    font-size: 1.25rem !important;
    font-weight: 700;
}

.fs-5 {
    font-size: 1rem !important;
}

small,
.small {
    font-size: 0.75rem;
}

.text-muted {
    color: var(--muted) !important;
}

/* Dropdown */
.dropdown-menu {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    padding: 0.375rem;
}

.dropdown-item {
    border-radius: 6px;
    font-size: 0.8rem;
    padding: 0.5rem 0.75rem;
}

.dropdown-item:hover {
    background: var(--light-bg);
}

/* Pagination */
.pagination {
    gap: 0.25rem;
}

.page-link {
    border-radius: 6px;
    font-size: 0.8rem;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--border-color);
    color: var(--dark);
}

.page-link:hover {
    background: var(--light-bg);
}

.page-item.active .page-link {
    background: var(--primary);
    border-color: var(--primary);
}

/* Spinner */
.spinner-border-sm {
    width: 0.875rem;
    height: 0.875rem;
    border-width: 0.15em;
}

/* Link styling */
a {
    color: var(--primary);
    text-decoration: none;
    transition: var(--transition);
}

a:hover {
    color: var(--primary-hover);
}

/* ── Tom Select (searchable selects) ──────────────────────────────
   The bootstrap5 theme is designed so the WRAPPER carries the
   Bootstrap .form-select look and the inner .ts-control is borderless
   / transparent. Tom Select copies the form-select(-sm) classes onto
   the wrapper <div>, so this app's .form-select rules + Bootstrap's
   caret/white-fill already style it — border, radius, background and
   caret come for free. We only size the control to match; no
   !important fighting needed. (The original code set the wrapper's
   `background-image: none`, which is what removed the caret.) */

/* Control: mirror .form-select padding/typography. Border, background
   and caret live on the wrapper via the .form-select class. */
.ts-wrapper.form-select .ts-control {
    min-height: 0;
    color: var(--dark);
    font-size: 0.8rem;
    line-height: 1.5;
    padding: 0.625rem 2.25rem 0.625rem 0.875rem;
}

.ts-wrapper.form-select .ts-control>input {
    color: var(--dark);
    line-height: 1.5;
}

/* On click a single select shows its search input in-flow. The theme's
   `flex-wrap: wrap` + the input's default `min-width: 7rem` push that input
   onto a second row in narrow filters, so the box jumps taller. Keep it on
   one row and let the input shrink — no height change, no jerk. */
.ts-wrapper.form-select.single .ts-control {
    flex-wrap: nowrap;
}

.ts-wrapper.form-select.single .ts-control>input {
    min-width: 0;
}

/* A long selected value ellipsis-truncates inside the box instead of hard
   clipping at the caret. The control's align-items:center still centers it. */
.ts-wrapper.form-select.single .ts-control>.item {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Small filter variant: match .form-select-sm. The theme's `.has-items`
   rule (same specificity) zeroes padding-bottom and bumps the font to
   .875rem; this rule loads later, so it wins — no !important. */
.ts-wrapper.form-select-sm {
    min-width: 170px;
}

/* Width modifier for selects with longer labels (e.g. database names). The
   dropdown panel matches the control width, so a wider control = less
   option truncation. Tom Select copies the select's classes to the wrapper,
   so adding `searchable-wide` to the <select> reaches this rule. */
.ts-wrapper.form-select-sm.searchable-wide {
    min-width: 320px;
}

.ts-wrapper.form-select-sm .ts-control,
.ts-wrapper.form-select-sm.has-items .ts-control {
    font-size: 0.75rem;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    padding-left: 0.75rem;
}

/* Focus: ring on the wrapper (which holds the border). Tom Select adds
   the .focus class; matches native .form-select:focus. */
.ts-wrapper.form-select.focus {
    border-color: var(--focus-border);
    box-shadow: 0 0 0 0.25rem var(--focus-ring);
}

/* Dropdown panel + options. The panel grows to fit the widest option (so a
   long database name shows in full) rather than being clamped to the control
   width — but never narrower than the control, nor wide enough to run off
   screen. This makes truncation rare and needs no hover tooltip. */
.ts-dropdown {
    width: auto;
    min-width: 100%;
    max-width: min(560px, 92vw);
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    font-size: 0.8rem;
}

/* Database filters (.searchable-wide): dropdown is at least as wide as the
   box (via the base min-width:100%) and grows to fit long names up to 760px. */
.ts-wrapper.searchable-wide .ts-dropdown {
    max-width: min(760px, 95vw);
}

/* Each option on a single line. With the auto-width panel above it usually
   shows in full; the ellipsis only engages past the max-width cap. */
.ts-dropdown .option {
    padding: 0.375rem 0.875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ts-dropdown .active {
    background: var(--light-bg);
    color: var(--dark);
}

/* Search-match highlight, tuned to the app's indigo palette. */
.ts-dropdown .highlight {
    background: var(--accent-tint-strong);
    border-radius: 2px;
}

/* Show ~14 rows before the dropdown scrolls (default is ~7). */
.ts-dropdown .ts-dropdown-content {
    max-height: 400px;
}

/* Scrollbar */
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

::-webkit-scrollbar-track {
    background: var(--light-bg);
}

::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--text-subtle);
}

/* ---------------------------------------------------------------------------
   CodeMirror token colours → shared --code-* palette.
   CodeMirror's own stylesheet loads after app.css with .cm-s-default .cm-*
   (specificity 0,2,0), so these overrides use the compound .CodeMirror.cm-s-default
   prefix (0,3,0) to win without !important. Keeps editors visually identical to
   the highlight.js read-only viewer.
   --------------------------------------------------------------------------- */
.CodeMirror.cm-s-default { color: var(--code-fg); }

.CodeMirror.cm-s-default .cm-keyword,
.CodeMirror.cm-s-default .cm-meta,
.CodeMirror.cm-s-default .cm-type { color: var(--code-keyword); }

.CodeMirror.cm-s-default .cm-string,
.CodeMirror.cm-s-default .cm-string-2 { color: var(--code-string); }

.CodeMirror.cm-s-default .cm-number,
.CodeMirror.cm-s-default .cm-atom,
.CodeMirror.cm-s-default .cm-builtin { color: var(--code-number); }

.CodeMirror.cm-s-default .cm-attribute,
.CodeMirror.cm-s-default .cm-property { color: var(--code-attr); }

.CodeMirror.cm-s-default .cm-comment { color: var(--code-comment); font-style: italic; }

.CodeMirror.cm-s-default .cm-variable,
.CodeMirror.cm-s-default .cm-variable-2,
.CodeMirror.cm-s-default .cm-def,
.CodeMirror.cm-s-default .cm-operator,
.CodeMirror.cm-s-default .cm-bracket { color: var(--code-fg); }

/* YAML keys tokenise as `atom` in CodeMirror but as `attr` (blue) in the viewer.
   Scope to the gitops YAML editor so its keys match the viewer, while SQL/JSON
   literals (also `atom`) stay on the default number/literal colour. */
.yaml-ed .CodeMirror.cm-s-default .cm-atom { color: var(--code-attr); }