/*
 * VITALS.AI stylesheet.
 *
 * Light theme, violet accent, white sidebar with collapsible sections and a user
 * block pinned at the foot. Top-level sections (Operations, Monitoring, Admin)
 * live in the sidebar with their features nested beneath, so everything stays
 * visible as the feature set grows.
 *
 * Dense but airy: the reader is an SRE or FDE examining a cluster they may not
 * know, so scannable data beats decoration.
 *
 * No framework, no build step: one file served from the JAR.
 */

:root {
    /* Surfaces */
    --bg:            #ffffff;
    --bg-page:       #f7f9f9;
    --bg-sidebar:    #fcfdfd;
    --bg-subtle:     #f1f5f4;
    --bg-hover:      #eaf2f1;
    --bg-inset:      #f9fbfb;

    /* Card surface: mostly opaque so it stays crisp under the new layered shadows,
       while still letting a hint of the ambient wash tint through. One token, so
       every card/tile/panel shares the exact same surface. */
    --surface:       color-mix(in srgb, var(--bg) 94%, transparent);

    /* Lines */
    --border:        #e4eaea;
    --border-strong: #d2dada;

    /* Text: warm-neutral ink rather than pure black.
       Secondary tones darkened for more contrast ("brighter"/crisper) — the dim
       and faint greys drove the washed-out look. Revert to #5a6465 / #8a9394 to
       restore the softer original. */
    --text:          #141a1a;
    --text-dim:      #454f50;
    --text-faint:    #6d7778;

    /*
      Ambient wash behind the whole app. Keeps large light surfaces from reading
      as flat paper, without tinting content.
    */
    --wash:
        radial-gradient(1200px 620px at 78% -12%, rgba(62, 156, 147, 0.10) 0%, transparent 62%),
        radial-gradient(880px 520px at 4% 108%, rgba(201, 162, 39, 0.07) 0%, transparent 60%);

    --shadow-color: rgba(20, 32, 32, 0.06);
    --scrim: rgba(255, 255, 255, 0.72);

    /*
      Brand gradient: teal to sage to gold. Emphasis in the wordmark comes from
      weight contrast rather than colour, so the gradient is reserved for the
      mark, the active nav tile, and accent details.
    */
    --grad-start:    #3E9C93;
    --grad-mid:      #8FA97A;
    --grad-end:      #C9A227;
    --brand-gradient: linear-gradient(120deg,
                        var(--grad-start) 0%,
                        var(--grad-mid) 48%,
                        var(--grad-end) 100%);

    /* Accent: the teal end of the gradient carries interactive state */
    --accent:        #2f8b83;
    --accent-hover:  #257771;
    --accent-soft:   #eaf4f2;
    --accent-line:   #c9e2de;
    --gold:          #C9A227;

    /* Status */
    --ok:            #2f8b6b;
    --ok-soft:       #eaf5f0;
    --warn:          #a2731a;
    --warn-soft:     #fbf4e4;
    --error:         #c4362b;
    --error-soft:    #fbedeb;
    --info:          #2f7392;
    --info-soft:     #eaf2f6;

    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    --radius:     10px;
    --radius-sm:  7px;
    --sidebar-w:  236px;
    --topbar-h:   52px;

    /*
      Layered, soft shadows. A near-transparent ambient layer plus a tighter
      contact layer reads as depth on paper rather than a hard 1px line — the
      difference between "boxed" enterprise UI and a modern floating surface.
      Every card, table and panel inherits these, so lifting them here lifts the
      whole app at once.
    */
    --shadow-sm: 0 1px 2px rgba(20, 32, 32, 0.04), 0 1px 3px rgba(20, 32, 32, 0.05);
    --shadow:    0 2px 4px rgba(20, 32, 32, 0.05), 0 4px 12px rgba(20, 32, 32, 0.06);
    --shadow-md: 0 4px 10px rgba(20, 32, 32, 0.07), 0 10px 28px rgba(20, 32, 32, 0.08);
}

/*
  Dark theme.
  Deep blue-black rather than neutral grey, with a teal glow from the top edge.
  Surfaces sit only slightly above the background and rely on hairline borders,
  which keeps dense tables readable without heavy contrast steps.
*/
[data-theme="dark"] {
    --bg:            #101820;
    --bg-page:       #0a1016;
    --bg-sidebar:    #0c131a;
    --bg-subtle:     #16202a;
    --bg-hover:      #182430;
    --bg-inset:      #0e161d;

    /* Slightly lifted above the page on dark, for a subtle elevation cue. */
    --surface:       #131d27;

    --border:        #1e2a35;
    --border-strong: #2b3a47;

    /* Secondary tones lifted for more contrast; revert to #9aa8b0 / #6b7a84. */
    --text:          #f2f6f7;
    --text-dim:      #b3c0c7;
    --text-faint:    #85939c;

    --wash:
        radial-gradient(1300px 680px at 74% -16%, rgba(62, 156, 147, 0.20) 0%, transparent 60%),
        radial-gradient(900px 520px at 2% 106%, rgba(201, 162, 39, 0.08) 0%, transparent 58%);

    --shadow-color: rgba(0, 0, 0, 0.4);
    --scrim: rgba(10, 16, 22, 0.72);

    /* On dark, depth comes from deeper ambient shadow rather than contact lines. */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.22);
    --shadow:    0 2px 6px rgba(0, 0, 0, 0.34), 0 6px 16px rgba(0, 0, 0, 0.30);
    --shadow-md: 0 6px 16px rgba(0, 0, 0, 0.40), 0 14px 34px rgba(0, 0, 0, 0.38);

    /* Teal reads brighter on dark, so interactive accents shift up a step */
    --accent:        #4db6aa;
    --accent-hover:  #63c6ba;
    --accent-soft:   rgba(77, 182, 170, 0.14);
    --accent-line:   rgba(77, 182, 170, 0.34);

    --ok:            #4cb98b;
    --ok-soft:       rgba(76, 185, 139, 0.14);
    --warn:          #d3a24a;
    --warn-soft:     rgba(211, 162, 74, 0.14);
    --error:         #e0685c;
    --error-soft:    rgba(224, 104, 92, 0.14);
    --info:          #5aa7c7;
    --info-soft:     rgba(90, 167, 199, 0.14);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.5;
    background: var(--bg-page);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/*
  The ambient wash sits behind everything as a fixed layer, so it does not scroll
  with content and does not repaint on every htmx swap.
*/
body::before {
    content: '';
    position: fixed;
    inset: 0;
    background: var(--wash);
    pointer-events: none;
    /*
      Negative, so the wash sits behind page content without each container needing
      to be lifted above it. An earlier version used z-index:0 here and raised
      individual elements instead, which left anything unraised — and any child using
      a negative z-index — painting underneath the wash.
    */
    z-index: -1;
}

code {
    font-family: var(--mono);
    font-size: 0.86em;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 5px;
    color: var(--text-dim);
}

/* ================= App frame ================= */

.app {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    height: 100vh;
    overflow: hidden;
    transition: grid-template-columns 0.16s ease;
}

.app.sidebar-collapsed { grid-template-columns: 0 1fr; }

/* ================= Sidebar ================= */

.sidebar {
    /* Slightly translucent so the ambient wash reads through the chrome */
    background: color-mix(in srgb, var(--bg-sidebar) 88%, transparent);
    backdrop-filter: blur(10px);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/*
  Collapsing narrows the grid column to zero and clips the contents. The sidebar
  must stay a grid item: removing it with display:none shifts main into the
  zero-width first column and blanks the whole page.
*/
.app.sidebar-collapsed .sidebar {
    border-right: none;
    visibility: hidden;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 9px;
    height: var(--topbar-h);
    padding: 0 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    text-decoration: none;
    color: var(--text);
    transition: background 0.12s;
}

.sidebar-brand:hover { background: var(--bg-subtle); }

.brand-logo { width: 24px; height: 24px; flex-shrink: 0; }

/*
  Wordmark: heavy stem, light suffix, single ink colour. The contrast is carried
  by weight rather than colour, which reads as more considered than a two-tone
  treatment and survives being placed on any background.
*/
.brand-name {
    font-weight: 750;
    font-size: 14.5px;
    letter-spacing: 0.2px;
    white-space: nowrap;
    color: var(--text);
}

.brand-name .suffix {
    font-weight: 400;
    letter-spacing: 0.1px;
}

.nav {
    flex: 1;
    overflow-y: auto;
    padding: 8px 0 14px;
}

.nav::-webkit-scrollbar { width: 10px; }
.nav::-webkit-scrollbar-track { background: transparent; }
.nav::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: 5px;
    border: 3px solid var(--bg-sidebar);
}
.nav::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }

/* ---- Section: a top-level heading in the sidebar ---- */

.nav-section { margin-bottom: 1px; }

.section-head {
    display: flex;
    align-items: center;
    gap: 7px;
    width: 100%;
    padding: 8px 14px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: 11px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-faint);
    text-align: left;
    border-radius: var(--radius-sm);
    transition: color 0.12s, background 0.12s;
}

.section-head:hover { color: var(--text-dim); background: var(--bg-subtle); }

/* Icon sprite host: present in the DOM but never rendered */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/*
  Icons are single-weight thin strokes in muted grey, so the sidebar reads as a
  calm list. Colour is spent only on the selected item.
*/
.section-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
    color: var(--text-faint);
    transition: color 0.12s;
}

.section-head:hover .section-icon { color: var(--text-dim); }

.chevron {
    font-size: 8px;
    width: 8px;
    display: inline-block;
    transition: transform 0.16s ease;
    color: var(--text-faint);
    flex-shrink: 0;
}

.nav-section.collapsed .chevron { transform: rotate(-90deg); }

.section-label { flex: 1; }

.section-count {
    font-family: var(--mono);
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--text-faint);
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 9px;
    padding: 0 5px;
    min-width: 17px;
    text-align: center;
}

.section-items {
    list-style: none;
    margin: 0;
    padding: 0 8px 6px;
}

.nav-section.collapsed .section-items,
.nav-section.collapsed .section-empty { display: none; }

/* ---- Feature: nested under its section ---- */

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 6px 10px 6px 12px;
    margin-bottom: 2px;
    /* Buttons do not inherit these, so they are set explicitly */
    background: none;
    border: none;
    font-family: inherit;
    text-align: left;
    color: var(--text-dim);
    text-decoration: none;
    font-size: 13.5px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
}

.nav-item:focus-visible,
.user-menu-item:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.nav-item:hover { background: var(--bg-subtle); color: var(--text); }

/* Selected: dark ink and weight, matching the wordmark's logic */
.nav-item.selected {
    background: var(--bg-subtle);
    color: var(--text);
    font-weight: 600;
}

/* Item icon: a bordered tile that fills with the brand gradient when selected */
.item-icon {
    width: 26px;
    height: 26px;
    border-radius: 7px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    background: var(--bg);
    color: var(--text-faint);
    transition: background 0.14s, color 0.14s, border-color 0.14s;
}

.item-icon svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.nav-item:hover .item-icon { border-color: var(--border-strong); color: var(--text-dim); }

.nav-item.selected .item-icon {
    background: var(--brand-gradient);
    border-color: transparent;
    color: #fff;
}

.nav-item .label { flex: 1; min-width: 0; }

/* Capability-gated: shown so its absence is explained, but inert */
.nav-item.disabled {
    color: var(--text-faint);
    cursor: not-allowed;
    align-items: flex-start;
}

.nav-item.disabled:hover { background: none; }
.nav-item.disabled .item-icon { opacity: 0.55; }

.nav-item .reason {
    display: block;
    font-family: var(--mono);
    font-size: 9.5px;
    font-style: normal;
    color: var(--text-faint);
    margin-top: 1px;
}

.section-empty {
    margin: 0;
    padding: 2px 14px 8px 20px;
    font-size: 12px;
    color: var(--text-faint);
    font-style: italic;
}

/* ---- User block, pinned at the foot ---- */

.sidebar-foot {
    position: relative;
    flex-shrink: 0;
    border-top: 1px solid var(--border);
    padding: 8px 10px;
}

/* The whole block is the menu trigger */
.user-trigger {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 6px 8px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    color: var(--text);
    transition: background 0.12s;
}

.user-trigger:hover { background: var(--bg-subtle); }

.trigger-caret {
    color: var(--text-faint);
    flex-shrink: 0;
    transition: transform 0.16s ease;
}

.user-trigger[aria-expanded="true"] .trigger-caret { transform: rotate(180deg); }

.avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--brand-gradient);
    color: #fff;
    font-size: 11.5px;
    font-weight: 650;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    text-transform: uppercase;
}

.avatar-lg { width: 36px; height: 36px; font-size: 13px; }

.user-meta { flex: 1; min-width: 0; }

.user-name {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.user-role {
    display: block;
    font-size: 10.5px;
    color: var(--text-faint);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- User menu ---- */

.user-menu {
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: calc(100% - 2px);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 8px 28px var(--shadow-color);
    padding: 6px;
    z-index: 40;
}

.user-menu[hidden] { display: none; }

.user-menu-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 10px 12px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
}

.user-menu-head .user-name { font-size: 13.5px; }
.user-menu-head .user-role { font-size: 11.5px; }

.user-menu-items { display: flex; flex-direction: column; }

.user-menu-form { margin: 0; display: flex; }

.user-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-size: 13px;
    font-family: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
}

.user-menu-item:hover { background: var(--bg-subtle); color: var(--text); }
.user-menu-item .chrome-icon { color: var(--text-faint); flex-shrink: 0; }
.user-menu-item:hover .chrome-icon { color: var(--accent); }

/* ================= Main ================= */

.main {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
}

.topbar {
    display: flex;
    align-items: center;
    gap: 14px;
    height: var(--topbar-h);
    padding: 0 20px;
    background: var(--scrim);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.crumb {
    display: flex;
    align-items: baseline;
    gap: 7px;
    font-size: 13px;
    min-width: 0;
    flex: 1;
}

.crumb-section { color: var(--text-faint); }

.crumb-section:not(:empty)::after {
    content: '›';
    margin-left: 7px;
    color: var(--text-faint);
    font-size: 14px;
}

.crumb-item { color: var(--text); font-weight: 600; }

.topbar-right { display: flex; align-items: center; gap: 9px; }

.chip {
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: 0.3px;
    padding: 3px 9px;
    border-radius: 11px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

/* Demo data must never be mistaken for a real cluster reading */
.chip-demo {
    background: var(--warn-soft);
    color: var(--warn);
    border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}

.chip-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.chip-cluster {
    background: var(--bg-subtle);
    color: var(--text-dim);
    border: 1px solid var(--border);
    font-family: var(--mono);
    font-weight: 500;
}

.btn-icon {
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    cursor: pointer;
    font-size: 14px;
    width: 30px;
    height: 28px;
    line-height: 1;
    padding: 0;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.btn-icon:hover {
    color: var(--accent);
    border-color: var(--accent-line);
    background: var(--accent-soft);
}

.btn-icon.spinning { animation: spin 0.6s linear; }

/* Brief confirmation flash after Copy/Export. */
.btn-icon.flash-ok {
    color: var(--ok);
    border-color: var(--ok);
    background: var(--ok-soft);
}
.btn-icon.flash-error {
    color: var(--error);
    border-color: var(--error);
    background: var(--error-soft);
}

.toggle-glyph { font-size: 13px; line-height: 1; }

.btn-icon { display: inline-flex; align-items: center; justify-content: center; }

.chrome-icon {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Only the glyph for the theme being offered is shown */
.theme-icon-dark  { display: none; }
[data-theme="dark"] .theme-icon-light { display: none; }
[data-theme="dark"] .theme-icon-dark  { display: inline; }

@keyframes spin { to { transform: rotate(360deg); } }

.content {
    flex: 1;
    overflow-y: auto;
    padding: 22px 24px 44px;
    min-width: 0;
    /* Positioning context for the panel loading overlay. */
    position: relative;
}

/* ================= Banners ================= */

.banner {
    padding: 9px 20px;
    font-size: 12.5px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.banner-warn {
    background: var(--warn-soft);
    border-bottom-color: color-mix(in srgb, var(--warn) 30%, transparent);
    color: var(--warn);
}

.banner code { background: color-mix(in srgb, var(--bg) 60%, transparent); border-color: transparent; color: inherit; }

/* ================= Loading ================= */

/*
 * Full-panel loading overlay. Covers the emptied panel while the next view
 * loads, so the previous view is never left visible mid-fetch. vitals.js toggles
 * the [hidden] attribute; the bar animates on its own while shown.
 */
.panel-loader {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 40px;
    background: var(--bg);
    z-index: 5;
}

.panel-loader[hidden] { display: none; }

/*
 * Inline variant, injected into a sub-panel such as the Cluster Insight output.
 * Flows in place rather than covering the whole content area, and needs no
 * positioning context on its parent.
 */
.panel-loader-inline {
    position: static;
    inset: auto;
    min-height: 180px;
    background: transparent;
}

.panel-loader-bar {
    position: relative;
    width: min(280px, 60%);
    height: 4px;
    border-radius: 999px;
    background: var(--bg-subtle);
    overflow: hidden;
}

.panel-loader-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 40%;
    border-radius: 999px;
    background: var(--brand-gradient);
    /* Indeterminate: signals work without implying a known duration. */
    animation: panel-loader-slide 1.1s ease-in-out infinite;
}

@keyframes panel-loader-slide {
    0%   { left: -40%; }
    100% { left: 100%; }
}

.panel-loader-text {
    color: var(--text-faint);
    font-size: 12.5px;
}

/*
 * Respect reduced-motion: replace the sliding bar with a static full bar that
 * gently pulses, so there is still a signal without the horizontal motion.
 */
@media (prefers-reduced-motion: reduce) {
    .panel-loader-fill {
        left: 0;
        width: 100%;
        animation: panel-loader-pulse 1.4s ease-in-out infinite;
    }
    @keyframes panel-loader-pulse {
        0%, 100% { opacity: 0.35; }
        50%      { opacity: 0.8; }
    }
}

.placeholder { color: var(--text-faint); font-size: 13px; }

/* ================= Donuts (Cluster Overview) ================= */

.donut-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.donut-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 14px 16px 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.donut-head {
    align-self: flex-start;
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
}

.donut { display: flex; flex-direction: column; align-items: center; gap: 6px; }

.donut-svg { width: 104px; height: 104px; }

.donut-track {
    fill: none;
    stroke: var(--bg-inset);
    stroke-width: 10;
}

.donut-arc {
    fill: none;
    stroke-width: 10;
    stroke-linecap: round;
    transition: stroke-dasharray 0.4s ease;
}
.donut-arc.ok    { stroke: var(--ok); }
.donut-arc.warn  { stroke: var(--warn); }
.donut-arc.error { stroke: var(--error); }
.donut-arc.na    { stroke: var(--border); }

.donut-pct {
    fill: var(--text);
    font-size: 20px;
    font-weight: 650;
    text-anchor: middle;
    dominant-baseline: middle;
    font-family: var(--font);
}

.donut-sub { font-size: 11.5px; color: var(--text-faint); text-align: center; }

/* ================= Overview tile grid ================= */

.tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
}

.tile-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 12px 14px 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.tile-card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md, var(--shadow-sm));
    transform: translateY(-2px);
}
.tile-card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.tile-head {
    align-self: flex-start;
    font-size: 10px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
}

.tile-ring { display: flex; flex-direction: column; align-items: center; gap: 4px; }
/* Larger ring so long count ratios (e.g. 1980/2040 on big clusters) fit inside. */
.tile-svg { width: 104px; height: 104px; }
.tile-ring-figure {
    fill: var(--text);
    font-size: 19px;
    font-weight: 650;
    text-anchor: middle;
    dominant-baseline: middle;
    font-family: var(--font);
}

/* Long ring figures (e.g. big ratios like 1980/2040) shrink to stay inside the
   ring, since SVG text does not reflow. Keeps every tile the same size. The viewBox
   is fixed at 100 units, so these sizes are in viewBox units and scale with the ring. */
.tile-ring-figure.figure-sm  { font-size: 15px; }
.tile-ring-figure.figure-xs  { font-size: 12px; }
.tile-ring-figure.figure-xxs { font-size: 9.5px; }

.tile-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 0 2px;
}
.tile-figure {
    font-size: 30px;
    font-weight: 680;
    letter-spacing: -0.5px;
    color: var(--text);
    line-height: 1.05;
}
.tile-figure.ok    { color: var(--ok); }
.tile-figure.warn  { color: var(--warn); }
.tile-figure.error { color: var(--error); }
.tile-figure.na    { color: var(--text-faint); }
.tile-unit {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-dim);
}
.tile-sub {
    font-size: 10.5px;
    color: var(--text-faint);
    text-align: center;
}

/* Count tiles on the Network hub: a large number rather than a health ring,
   since networking objects have no meaningful "healthy percentage". */
.count-grid {
    display: grid;
    /* Fixed-width tracks packed from the left, so a hub with two tiles shows two
       normal-sized cards rather than stretching each to fill half the row. auto-fill
       (not auto-fit) keeps empty tracks from collapsing the sizing. */
    grid-template-columns: repeat(auto-fill, minmax(220px, 240px));
    gap: 14px;
    margin-bottom: 18px;
}
.count-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 16px 18px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.count-card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md, var(--shadow-sm));
    transform: translateY(-2px);
}
.count-card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.count-head {
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
}
.count-value {
    font-size: 30px;
    font-weight: 680;
    letter-spacing: -0.5px;
    color: var(--text);
    line-height: 1.1;
}
.count-value.ok   { color: var(--ok); }
.count-value.warn { color: var(--warn); }
.count-value.na   { color: var(--text-faint); }
.count-sub { font-size: 11.5px; color: var(--text-faint); }

/* A non-clickable count tile (e.g. Secrets, which is never read): no pointer, no
   lift, and dimmed so it reads as informational rather than actionable. */
.count-card-static {
    cursor: default;
    opacity: 0.72;
}
.count-card-static:hover {
    border-color: var(--border);
    box-shadow: var(--shadow-sm);
    transform: none;
}

/* Clickable tiles on the Workloads hub: reset the button chrome, then add a
   pointer affordance and a lift on hover so the whole card reads as a link. */
.donut-card-link {
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
    width: 100%;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.donut-card-link:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md, var(--shadow-sm));
    transform: translateY(-2px);
}
.donut-card-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ================= Module views ================= */

.module-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
}

.module-head h2 {
    margin: 0;
    font-size: 20px;
    font-weight: 650;
    letter-spacing: -0.3px;
}

.module-sub {
    margin: 2px 0 0;
    font-size: 13px;
    color: var(--text-faint);
}

.module-meta {
    font-size: 11.5px;
    color: var(--text-faint);
    font-family: var(--mono);
    text-align: right;
    white-space: nowrap;
    padding-top: 4px;
}

/* ---- Stat cards ---- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 13px 15px;
    box-shadow: var(--shadow-sm);
}

.stat-label {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-faint);
    font-weight: 600;
    margin-bottom: 5px;
}

.stat-value {
    font-size: 22px;
    font-weight: 650;
    font-family: var(--mono);
    line-height: 1.15;
    letter-spacing: -0.5px;
}

.stat-sub { font-size: 11px; color: var(--text-faint); margin-top: 3px; }

.stat-value.ok    { color: var(--ok); }
.stat-value.warn  { color: var(--warn); }
.stat-value.error { color: var(--error); }

/* ---- Stat card with a leading icon chip (modern KPI-card pattern) ----
   A soft-tinted rounded icon square on the left, metric on the right. The chip
   tint follows the metric's status, so an all-clear card reads teal/green and a
   problem card reads amber/red — the colour carries meaning, not decoration. */
.stat-ic {
    display: flex;
    align-items: center;
    gap: 13px;
    transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.stat-ic:hover {
    box-shadow: var(--shadow);
    border-color: var(--border-strong);
    transform: translateY(-1px);
}
.stat-chip {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-soft);
    color: var(--accent);
}
.stat-chip svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.stat-chip.ok    { background: var(--ok-soft);    color: var(--ok); }
.stat-chip.warn  { background: var(--warn-soft);  color: var(--warn); }
.stat-chip.error { background: var(--error-soft); color: var(--error); }
.stat-chip.info  { background: var(--info-soft);  color: var(--info); }
.stat-ic .stat-body { min-width: 0; }
.stat-ic .stat-label { margin-bottom: 2px; }
.stat-ic .stat-value { font-size: 21px; }

/* ---- Tables ---- */

.table-wrap {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 18px;
    box-shadow: var(--shadow-sm);
    transition: box-shadow 0.16s ease;
}
.table-wrap:hover { box-shadow: var(--shadow); }

.table-title {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 15px;
    font-size: 12px;
    font-weight: 650;
    color: var(--text);
    background: var(--bg-inset);
    border-bottom: 1px solid var(--border);
}

/*
  Scroll in both directions and cap the height. Columns already scrolled
  horizontally; capping the height means a long table scrolls vertically inside
  its own box instead of pushing the header off the top of the page. A short
  table never reaches the cap, so it shows no vertical scrollbar — the behaviour
  only kicks in for the large tables that need it, with no per-table markup.

  The cap is viewport-relative so it adapts to screen size, less the room the
  page chrome and surrounding cards take.
*/
.table-scroll {
    overflow: auto;
    max-height: 70vh;
    /*
      Reserve the scrollbar gutter at all times. Without this, a table tall enough
      to scroll gains a vertical scrollbar that narrows the body's content box but
      not the sticky header row (which is painted across the full width), so the
      header cells drift a few pixels right of the columns beneath them. A stable
      gutter gives header and body the same available width, keeping them aligned
      whether or not the scrollbar is present.
    */
    scrollbar-gutter: stable;
}

table.data {
    width: 100%;
    /*
      border-collapse: separate, not collapse. A collapsed table computes column
      widths for sticky <th> independently of the body cells, so the pinned header
      row drifts out of line with the columns beneath it. With separate borders the
      header and body share one column layout and stay aligned. Spacing is zeroed so
      the visual is unchanged; row dividers are drawn per-cell below.
    */
    border-collapse: separate;
    border-spacing: 0;
    font-size: 14px;
}

/*
  Sticky header row: stays pinned to the top of .table-scroll while the body
  scrolls under it. A header cell inherits the alignment of its column via the
  align-* helpers below, so a right-aligned numeric column gets a right-aligned
  header and the two line up.
*/
table.data th {
    text-align: left;
    padding: 7px 16px;
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
    /* A subtle translucent header that stays legible when it sticks over content. */
    background: color-mix(in srgb, var(--bg-inset) 88%, var(--bg));
    backdrop-filter: saturate(1.1) blur(2px);
    border-bottom: 1px solid var(--border-strong);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 3;
}

table.data td {
    padding: 6px 16px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

table.data tbody tr:last-child td { border-bottom: none; }
/* A soft accent-tinted hover reads more alive than a flat grey; the transition
   keeps it from flickering as the pointer sweeps a dense table. */
table.data tbody tr {
    transition: background 0.12s ease;
}
table.data tbody tr:hover {
    background: color-mix(in srgb, var(--accent) 5%, var(--bg));
}

td.num, th.num { text-align: right; font-family: var(--mono); }

/* Left-aligned numeric column: mono figures that read better sitting under their
   header on a wide table (small integer counts, not magnitudes to compare). */
td.num-left, th.num-left { text-align: left; font-family: var(--mono); }
table.data th.num-left { text-align: left; }
/* Header cells for numeric columns must right-align to line up with their
   right-aligned values. Scoped with table.data to outrank `table.data th`
   (which sets left) regardless of source order. */
table.data th.num { text-align: right; }
td.mono   { font-family: var(--mono); font-size: 13px; }
td.dim    { color: var(--text-faint); }
td.nowrap { white-space: nowrap; }

/* ---- Status pills ---- */

.pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 650;
    line-height: 1.5;
    white-space: nowrap;
    border: 1px solid transparent;
}
/* A tiny leading dot gives each status pill a modern "signal" glyph without an icon.
   Excludes .pill-sm, which is used as a bare colour swatch (no text) in some views. */
.pill:not(.pill-sm).pill-ok::before,
.pill:not(.pill-sm).pill-warn::before,
.pill:not(.pill-sm).pill-error::before,
.pill:not(.pill-sm).pill-info::before,
.pill:not(.pill-sm).pill-neutral::before {
    content: '';
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

.pill-ok      { background: var(--ok-soft);    color: var(--ok);        border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.pill-warn    { background: var(--warn-soft);  color: var(--warn);      border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.pill-error   { background: var(--error-soft); color: var(--error);     border-color: color-mix(in srgb, var(--error) 30%, transparent); }
.pill-neutral { background: var(--bg-subtle);  color: var(--text-dim);  border-color: var(--border); }
.pill-info    { background: var(--info-soft);  color: var(--info);      border-color: color-mix(in srgb, var(--info) 30%, transparent); }

/* ---- States ---- */

.state-empty, .state-error {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 34px 26px;
    text-align: center;
    box-shadow: var(--shadow-sm);
}

.state-error { border-color: color-mix(in srgb, var(--error) 30%, transparent); }

.state-icon {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    color: var(--text-faint);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
    margin: 0 auto 12px;
}

.state-title  { font-weight: 650; margin: 0 0 5px; font-size: 14.5px; }
.state-reason { color: var(--text-dim); margin: 0 0 6px; font-size: 13px; }
.state-help   {
    color: var(--text-faint);
    margin: 0 auto;
    font-size: 12.5px;
    max-width: 48ch;
}

/*
 * Explanatory note at the foot of a view.
 *
 * Distinct from .state-help, which centres a short line inside an empty-state card.
 * These notes are prose that runs the full width of the page, so no max-width and no
 * auto margin: constraining them only adds lines.
 */
.page-note {
    color: var(--text-faint);
    font-size: 12.5px;
    line-height: 1.55;
    text-align: left;
    margin: 18px 0 0;
    max-width: none;
}

/* Same note placed inside a card, where the card supplies no padding of its own. */
.page-note.inset {
    margin: 0;
    padding: 12px 14px;
}

/* Partial failures shown alongside successful data (R16.1) */
.error-list {
    background: var(--error-soft);
    border: 1px solid color-mix(in srgb, var(--error) 30%, transparent);
    border-radius: var(--radius);
    padding: 11px 14px;
    margin-bottom: 16px;
    font-size: 12.5px;
}

.error-list-title { font-weight: 650; color: var(--error); margin-bottom: 3px; }
.error-list ul { margin: 0; padding-left: 18px; color: var(--text-dim); }

.notice {
    border-radius: var(--radius);
    padding: 11px 14px;
    margin-bottom: 16px;
    font-size: 12.5px;
}

.notice-warn { background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent); }

/* An absent optional capability is information, not a fault, so it is not styled as one. */
.notice-info {
    background: var(--info-soft);
    border: 1px solid color-mix(in srgb, var(--info) 30%, transparent);
    color: var(--text-dim);
    line-height: 1.55;
}
.notice-title { font-weight: 650; color: var(--warn); margin-bottom: 3px; }
.notice p { margin: 0; color: var(--text-dim); }

.truncated-note { font-size: 12px; color: var(--warn); margin-bottom: 10px; }

/* ================= Login ================= */

.login-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 24px;
}

/* Two columns: brand statement on the left, form on the right */
.login-split {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 60px;
    width: 100%;
    max-width: 980px;
}

/* ---- Left column ---- */

.login-pitch { padding-left: 6px; }

/* Gradient pill, the loudest use of the brand colours */
.badge-pill {
    display: inline-block;
    background: var(--brand-gradient);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.4px;
    padding: 5px 15px;
    border-radius: 999px;
    margin-bottom: 18px;
}

/*
  Large, light-weight wordmark with the gradient carried by the letters. Falls
  back to the teal end where background-clip:text is unsupported.
*/
/*
  Gradient-filled text. The transparent fill is applied only inside @supports, so a
  browser that cannot clip a background to text keeps solid teal letters rather than
  rendering them invisible.
*/
.pitch-word {
    margin: 0;
    font-size: 62px;
    font-weight: 300;
    letter-spacing: -1.6px;
    line-height: 1.05;
    color: var(--grad-start);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
    .pitch-word {
        background: var(--brand-gradient);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
    }
}

.pitch-sub {
    margin: 10px 0 0;
    font-size: 16.5px;
    color: var(--text-dim);
}

.pitch-points {
    margin: 26px 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.pitch-points li {
    position: relative;
    padding-left: 20px;
    font-size: 13.5px;
    color: var(--text-faint);
}

.pitch-points li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 7px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand-gradient);
}

/* ---- Right column ---- */

.login-panel { display: flex; flex-direction: column; align-items: center; }

/*
  The glow is a sibling behind the card rather than a negative-z-index child: a
  negative child escapes the card's stacking context and can paint over unrelated
  content. isolation:isolate keeps this contained.
*/
.login-card {
    position: relative;
    isolation: isolate;
    width: 100%;
    max-width: 372px;
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    backdrop-filter: blur(12px);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 32px 30px 26px;
    box-shadow: 0 10px 34px var(--shadow-color);
}

/* Gradient glow bleeding out from behind the card */
.login-card::before {
    content: '';
    position: absolute;
    inset: -20px;
    border-radius: 26px;
    background: var(--brand-gradient);
    opacity: 0.15;
    filter: blur(26px);
    z-index: -1;
    pointer-events: none;
}

.card-title {
    margin: 0 0 4px;
    font-size: 20px;
    font-weight: 650;
    letter-spacing: -0.2px;
}

.card-sub { margin: 0 0 20px; font-size: 13px; color: var(--text-faint); }

/* Full-width gradient button, matching the reference */
.btn-gradient {
    margin-top: 22px;
    padding: 11px;
    background: var(--brand-gradient);
    border: none;
    border-radius: var(--radius-sm);
    color: #fff;
    font-size: 14px;
    font-weight: 650;
    font-family: inherit;
    cursor: pointer;
    transition: filter 0.14s, transform 0.06s;
}

.btn-gradient:hover  { filter: brightness(1.07) saturate(1.05); }
.btn-gradient:active { transform: translateY(1px); }

/* ---- SSO, not yet wired ---- */

.sso-block { margin-top: 22px; }

.divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
    color: var(--text-faint);
    font-size: 11.5px;
}

.divider::before, .divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
}

.btn-outline {
    width: 100%;
    padding: 10px;
    background: transparent;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-size: 13.5px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}

.btn-outline:disabled { opacity: 0.5; cursor: not-allowed; }

.sso-note {
    margin: 8px 0 0;
    font-size: 11.5px;
    color: var(--text-faint);
    text-align: center;
}

.login-form { display: flex; flex-direction: column; }

.login-form label {
    font-size: 11.5px;
    font-weight: 650;
    color: var(--text-dim);
    margin-top: 12px;
    margin-bottom: 5px;
}

.login-form input {
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 9px 11px;
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
}

.login-form input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.btn-primary {
    margin-top: 20px;
    padding: 10px;
    background: var(--accent);
    border: none;
    border-radius: var(--radius-sm);
    color: #fff;
    font-size: 14px;
    font-weight: 650;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.12s;
}
.btn-primary:hover { background: var(--accent-hover); }

.alert {
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    margin-bottom: 12px;
}

/* Borders derived from the status colour so both themes work from one rule */
.alert-error {
    background: var(--error-soft);
    border: 1px solid color-mix(in srgb, var(--error) 32%, transparent);
    color: var(--error);
}
.alert-info {
    background: var(--info-soft);
    border: 1px solid color-mix(in srgb, var(--info) 32%, transparent);
    color: var(--info);
}

.login-hint {
    margin-top: 18px;
    padding: 9px 11px;
    background: var(--warn-soft);
    border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent);
    border-radius: var(--radius-sm);
    font-size: 12px;
    color: var(--warn);
    text-align: center;
}

.login-hint code { background: color-mix(in srgb, var(--bg) 60%, transparent); border-color: transparent; color: inherit; }

.login-footer {
    margin: 20px 0 0;
    text-align: center;
    font-size: 11.5px;
    color: var(--text-faint);
    letter-spacing: 0.4px;
    font-weight: 700;
}

.login-footer .suffix { font-weight: 400; }

.login-footer span:last-child {
    font-family: var(--mono);
    font-weight: 400;
    margin-left: 6px;
    letter-spacing: 0;
}

/* Single column below the split's comfortable width */
@media (max-width: 860px) {
    .login-split { grid-template-columns: 1fr; gap: 34px; max-width: 400px; }
    .login-pitch { text-align: center; padding-left: 0; }
    .pitch-word  { font-size: 46px; }
    .pitch-points { display: none; }
}

/* ================= Utility ================= */

.btn-sm {
    padding: 4px 10px;
    font-size: 12px;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    cursor: pointer;
    font-family: inherit;
}
.btn-sm:hover { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }

.bar {
    height: 6px;
    background: color-mix(in srgb, var(--text-faint) 14%, transparent);
    border: none;
    border-radius: 999px;
    overflow: hidden;
    min-width: 54px;
    display: inline-block;
    vertical-align: middle;
}

/* Rounded, softly shaded fill — a subtle top-light gradient reads as a modern meter
   rather than a flat block. Colour still comes from the threshold class. */
.bar-fill {
    height: 100%;
    display: block;
    border-radius: 999px;
    background: var(--accent);
    background-image: linear-gradient(180deg, rgba(255,255,255,0.25), rgba(255,255,255,0));
    transition: width 0.3s ease;
}
.bar-fill.ok    { background-color: var(--ok); }
.bar-fill.warn  { background-color: var(--warn); }
.bar-fill.error { background-color: var(--error); }

/* ================= Toolbar and inputs ================= */

.toolbar {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

/*
  Reusable per-table filter bar (fragments/filters.html). It sits inside the
  padding-less .table-wrap, between the title and the table, so it needs its own
  horizontal padding to line up with the title rather than hugging the border.
*/
.table-wrap > .filter-bar {
    padding: 12px 15px 4px;
    margin-bottom: 0;
}
.filter-bar .input { min-width: 200px; }
.filter-bar select.input { min-width: 150px; }

/* The client-side filter hides non-matching items with the hidden attribute. A card/list
   item styled with its own `display` would otherwise ignore it, so enforce hiding for any
   filterable item. Table rows do not need this; card/list views (data-filter-item) do. */
[data-filter-item][hidden] { display: none !important; }

/* Replace the native <select> arrow with the same chevron the combobox uses, so the
   two controls match. Light theme stroke is --text-dim (#454f50); the dark theme
   overrides the image below with its lighter stroke. */
select.input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 30px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23454f50' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-size: 12px 12px;
}
[data-theme="dark"] select.input {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23b3c0c7' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.field { display: flex; flex-direction: column; gap: 5px; }

.field-label {
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
}

.input {
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 7px 10px;
    color: var(--text);
    font-size: 13px;
    font-family: inherit;
    min-width: 180px;
}

.input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ================= Searchable multi-select combobox ================= */

.combo { position: relative; }

.combo-control { position: relative; display: flex; align-items: center; }

.combo-input {
    min-width: 220px;
    width: 100%;
    padding-right: 58px;   /* room for the summary + caret */
}

/* When options are selected the count sits over the input's right side. */
.combo-summary {
    position: absolute;
    right: 26px;
    font-size: 11.5px;
    color: var(--text-dim);
    pointer-events: none;
}

/* Uses the exact same SVG chevron as the native <select>, so the two controls
   match pixel-for-pixel. The text glyph from the markup is hidden; the arrow is
   drawn as a 12px background image, with a dark-theme colour override below. */
.combo-caret {
    position: absolute;
    right: 9px;
    width: 12px;
    height: 12px;
    font-size: 0;                 /* hide the ▾ text glyph */
    color: transparent;
    pointer-events: none;
    transition: transform 0.12s ease;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23454f50' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px 12px;
}
[data-theme="dark"] .combo-caret {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23b3c0c7' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.combo.combo-open .combo-caret { transform: rotate(180deg); }

/*
  Fixed positioning so the menu escapes the .table-wrap's overflow:hidden clip
  (the filter bar sits inside that clipped box). vitals.js sets top/left/width to
  align it under the control when opening, and keeps it in sync on scroll/resize.
*/
.combo-menu {
    display: none;
    position: fixed;
    z-index: 200;
    min-width: 240px;
    max-height: 320px;
    overflow-y: auto;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md, 0 6px 20px rgba(0,0,0,0.18));
    padding: 4px;
}
.combo.combo-open .combo-menu { display: block; }

.combo-option {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 9px;
    font-size: 13px;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.combo-option:hover { background: var(--bg-subtle); }
.combo-option input { flex-shrink: 0; }
.combo-option[hidden] { display: none; }

/* ================= Usage cells ================= */

/*
  Numbers on top, proportion bar underneath. Both matter: the numbers for capacity
  planning, the bar for spotting a workload near its limit at a glance.
*/
.usage-cell {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 150px;
}

.usage-text { font-size: 12px; white-space: nowrap; }

.usage-cell .bar { width: 100%; min-width: 0; }

.filter-empty {
    margin: 0;
    padding: 16px;
    text-align: center;
    color: var(--text-faint);
    font-size: 13px;
}

/* ================= Drill-down modal ================= */

.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 20px;
    background: color-mix(in srgb, var(--text) 34%, transparent);
    backdrop-filter: blur(3px);
}

.modal-overlay[hidden] { display: none; }

/* Prevents the page scrolling behind an open modal */
body.modal-open { overflow: hidden; }

.modal {
    width: 100%;
    max-width: 780px;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 16px 48px var(--shadow-color);
    overflow: hidden;
}

.modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-inset);
    flex-shrink: 0;
}

.modal-title {
    margin: 0;
    font-size: 16px;
    font-weight: 650;
    letter-spacing: -0.2px;
}

.modal-sub { margin: 3px 0 0; font-size: 12px; color: var(--text-faint); }

.modal-close {
    background: none;
    border: none;
    color: var(--text-faint);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
    border-radius: 4px;
    flex-shrink: 0;
}

.modal-close:hover { color: var(--text); background: var(--bg-subtle); }

.modal-body { overflow-y: auto; padding: 16px 18px 18px; }

.modal-body .table-scroll {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: auto;
}

/*
  The insight line, which is the reason the modal exists: the table is evidence, this
  is the reading of it.
*/
.insight {
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.5;
    margin-bottom: 14px;
    border: 1px solid transparent;
}

.insight-ok    { background: var(--ok-soft);    color: var(--ok);
                 border-color: color-mix(in srgb, var(--ok) 26%, transparent); }
.insight-warn  { background: var(--warn-soft);  color: var(--warn);
                 border-color: color-mix(in srgb, var(--warn) 26%, transparent); }
.insight-error { background: var(--error-soft); color: var(--error);
                 border-color: color-mix(in srgb, var(--error) 26%, transparent); }

/* ---- Drillable cells ---- */

/*
  Cells are buttons but must not look like a wall of buttons: the affordance is a
  subtle hover, and the pill inside carries the meaning.
*/
.cell-btn {
    display: block;
    width: 100%;
    padding: 3px 5px;
    margin: -3px -5px;
    background: none;
    border: none;
    border-radius: 5px;
    font-family: inherit;
    font-size: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
    transition: background 0.1s;
}

.cell-btn:hover { background: var(--bg-subtle); }

.cell-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}

.cell-btn.dim { color: var(--text-faint); }

table.drillable td { padding-top: 6px; padding-bottom: 6px; }

/* ================= Readiness score ================= */

/*
  The go/no-go verdict. Sized to be the first thing read, because "should we ship" is the
  question being asked and a number does not answer it.
*/
.verdict {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 18px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    margin-bottom: 18px;
}

.verdict-ok    { background: var(--ok-soft);
                 border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.verdict-warn  { background: var(--warn-soft);
                 border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.verdict-error { background: var(--error-soft);
                 border-color: color-mix(in srgb, var(--error) 34%, transparent); }

.verdict-mark {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 700;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--bg) 60%, transparent);
}

.verdict-ok .verdict-mark    { color: var(--ok); }
.verdict-warn .verdict-mark  { color: var(--warn); }
.verdict-error .verdict-mark { color: var(--error); }

.verdict-body { min-width: 0; }

.verdict-label {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -0.2px;
    margin-bottom: 3px;
}

.verdict-ok .verdict-label    { color: var(--ok); }
.verdict-warn .verdict-label  { color: var(--warn); }
.verdict-error .verdict-label { color: var(--error); }

.verdict-summary {
    margin: 0;
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.55;
    max-width: 90ch;
}

.score-row {
    display: grid;
    grid-template-columns: 190px 1fr;
    gap: 12px;
    margin-bottom: 22px;
    align-items: stretch;
}

.score-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.score-caption {
    font-size: 10px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-faint);
    margin-bottom: 4px;
}

.score-value {
    font-size: 46px;
    font-weight: 700;
    font-family: var(--mono);
    line-height: 1;
    letter-spacing: -2px;
}

/* The "/100" reads as a unit, not part of the figure, so keep it small and dim. */
.score-max {
    font-size: 18px;
    font-weight: 500;
    color: var(--text-faint);
    letter-spacing: 0;
    margin-left: 2px;
}

.score-ok    { color: var(--ok); }
.score-info  { color: var(--info); }
.score-warn  { color: var(--warn); }
.score-error { color: var(--error); }

.score-label {
    font-size: 13px;
    font-weight: 650;
    margin-top: 6px;
}

.score-sub { font-size: 11px; color: var(--text-faint); margin-top: 2px; }

.score-stats { margin-bottom: 0; }

/* ---- Findings ---- */

.finding-list { padding: 4px; }

.finding {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}

.finding:last-child { border-bottom: none; }

.finding-head {
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.finding-subject { font-size: 12.5px; font-weight: 600; }

.finding-detail { font-size: 13px; }

/* Which rule produced this, pushed right so it does not compete with the finding */
.finding-check {
    margin-left: auto;
    font-size: 10.5px;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.finding-impact {
    margin: 0 0 6px;
    font-size: 12.5px;
    color: var(--text-dim);
    line-height: 1.55;
}

.finding-remedy {
    margin: 0;
    font-size: 12.5px;
    color: var(--text);
    line-height: 1.55;
}

.remedy-label {
    display: inline-block;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid var(--accent-line);
    border-radius: 4px;
    padding: 1px 6px;
    margin-right: 7px;
    vertical-align: 1px;
}

/* Workload Doctor: the "View crash log" button, pushed to the right of the head. */
.doctor-log-btn { margin-left: 8px; }

/* Readiness findings: the "Inspect" deep-link sits at the right of the finding head,
   just after the check label, so every finding is one click from the page that
   proves it and lets the reader act. */
.finding-inspect {
    margin-left: 12px;
    font-size: 11.5px;
    font-weight: 600;
    flex-shrink: 0;
}

/* Restart Leaderboard: inline severity legend beside a table title, and the dot
   separating a row's two actions. */
.legend-inline {
    margin-left: 12px;
    font-size: 11px;
    font-weight: 400;
    color: var(--text-dim);
    text-transform: none;
    letter-spacing: 0;
}

.legend-inline .pill { margin: 0 3px 0 9px; }
.legend-inline .pill:first-child { margin-left: 0; }

.row-action-sep { color: var(--text-faint); margin: 0 5px; }

/* A table row flagged as the highest-severity finding (e.g. an active blast radius). */
table.data tbody tr.row-error td { background: var(--error-soft, rgba(220,60,60,0.06)); }

/* ---- Help ---- */

.help-section { margin: 0 0 22px; max-width: 92ch; }
.help-section h3 { margin: 0 0 8px; font-size: 14px; }

.help-text {
    margin: 0 0 8px;
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.6;
}

.help-list {
    margin: 0;
    padding-left: 18px;
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.6;
}

.help-list li { margin-bottom: 6px; }
.help-list strong { color: var(--text); font-weight: 600; }

/* ---- Cluster Snapshot ---- */

/* Actions sit at the top-right of the module head, beside the title. */
.module-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-shrink: 0;
}

.snapshot-wrap {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: auto;
    max-height: 64vh;
}

.snapshot-md {
    margin: 0;
    padding: 16px 18px;
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.6;
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--bg-inset);
}

/* ---- Change Timeline ---- */

.timeline {
    margin-top: 6px;
    position: relative;
    padding-left: 6px;
}

/* The filter bar sits above the thread, not on it: cancel the left padding and give
   it breathing room so it does not align to the marker column. */
.timeline > .filter-bar {
    margin: 0 0 12px -6px;
}

/* The client-side filter hides non-matching entries with the hidden attribute. A class
   that sets `display` would otherwise override the attribute's default display:none, so
   filtered-out timeline entries must be explicitly hidden. */
.tl-entry[hidden] { display: none; }

.tl-entry {
    display: grid;
    grid-template-columns: 14px 1fr;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
}

.tl-entry:last-child { border-bottom: none; }

/* The marker dot and the thread it sits on. */
.tl-marker {
    position: relative;
    width: 10px;
    height: 10px;
    margin-top: 4px;
    border-radius: 50%;
    background: var(--text-faint);
    flex-shrink: 0;
}

.tl-marker.tl-warn { background: var(--warn); }
.tl-marker.tl-info { background: var(--accent); }
.tl-marker.tl-neutral { background: var(--text-faint); }

/* A connecting line down the column, so the entries read as one thread. Drawn only
   when another entry follows (:has), so the filter bar, the empty-state message, or a
   hidden trailing entry never leaves a dangling connector below the last one. */
.tl-entry:has(~ .tl-entry) .tl-marker::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 14px;
    transform: translateX(-50%);
    width: 1px;
    height: calc(100% + 18px);
    background: var(--border);
}

.tl-head {
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
}

.tl-reason { font-size: 12.5px; font-weight: 600; }
.tl-object { font-size: 12px; color: var(--text-dim); }
.tl-count  { font-size: 10px; }
.tl-age    { margin-left: auto; font-size: 11.5px; }

.tl-message {
    margin: 3px 0 0;
    font-size: 12.5px;
    color: var(--text-dim);
    line-height: 1.5;
}

/* Explanatory line above the log tail in the Doctor modal. */
.log-note {
    margin: 0 0 10px;
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.5;
}

/* Constrain the log tail so a long trace scrolls inside the modal, not the page. */
.modal-body .log-body { max-height: 52vh; overflow: auto; }

.modal-actions {
    margin-top: 12px;
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/*
  Hanging indent for any remedy line that carries a label (Fix / Next).
  Without this, a wrapped remedy sentence returns to the far-left margin under the
  label pill rather than under the sentence — so a fragment like "the node." reads
  as a stray line. Making the paragraph a flex row puts the label in its own column
  and lets the text wrap as a block beside it. Applies wherever the pattern is used
  (Readiness findings, Workload Doctor next steps); the label-less .finding-remedy on
  the Overview card is untouched because it has no .remedy-label child.
*/
.finding-remedy:has(> .remedy-label) {
    display: flex;
    align-items: baseline;
    gap: 7px;
}

/* The flex gap handles spacing now, so the label's block-layout margin is dropped. */
.finding-remedy:has(> .remedy-label) .remedy-label { margin-right: 0; }

/* Everything after the label shares one wrapping column, so wraps hang correctly. */
.finding-remedy:has(> .remedy-label) > :not(.remedy-label) { flex: 1; }

.next-step { margin-bottom: 4px; }

/* Workload Doctor: the correlated evidence behind a verdict, one fact per row. */
.signal-list {
    margin: 2px 0 10px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.signal-row {
    display: flex;
    align-items: baseline;
    gap: 9px;
}

.signal-detail {
    font-size: 12.5px;
    color: var(--text-dim);
    line-height: 1.5;
    max-width: 92ch;
}

/* A compact pill for the signal "kind" label, narrower than a table pill. */
.pill-sm {
    font-size: 9.5px;
    padding: 0 6px;
    min-width: 58px;
    text-align: center;
    flex-shrink: 0;
}

/* In the grouped tables the impact sits under the detail rather than beside it */
.finding-impact-inline {
    display: block;
    font-size: 11.5px;
    color: var(--text-faint);
    margin-top: 3px;
    line-height: 1.5;
}

.category-note {
    margin-left: auto;
    font-size: 11px;
    font-weight: 400;
    color: var(--text-faint);
    text-transform: none;
    letter-spacing: 0;
}

@media (max-width: 720px) {
    .score-row { grid-template-columns: 1fr; }
}

/* ================= Connectivity matrix ================= */

/*
  Sized to content rather than stretched to the container: with `width:100%` the row-header
  column absorbed all the slack and pushed the cells into a cramped strip on the right.
*/
table.matrix {
    border-collapse: separate;
    border-spacing: 0;
    width: auto;
    min-width: 0;
}

.matrix-corner {
    font-size: 9.5px !important;
    color: var(--text-faint);
    white-space: nowrap;
    position: sticky;
    /* Pinned on both axes: the corner must stay put whether the matrix scrolls
       sideways (many columns) or down (many rows), so it sits above every other
       sticky element. */
    left: 0;
    top: 0;
    background: var(--bg-inset);
    z-index: 5;
    /* Bounded, so the header cannot claim the space the cells need */
    width: 1%;
}

/*
  Column headers are rotated fully vertical (reading bottom-to-top). A 45/60-degree
  slant drifted each label away from its column, so a header no longer sat above the
  cells it names. At 90 degrees the label is centred on its own 34px column and lines
  up with the marks beneath it.
*/
.matrix-head {
    height: 120px;
    padding: 0 !important;
    vertical-align: bottom;
    white-space: nowrap;
    width: 34px;
    max-width: 34px;
    /* Pin the rotated column headers to the top so they stay visible when a tall
       matrix scrolls down, matching the sticky behaviour of data tables. */
    position: sticky;
    top: 0;
    background: var(--bg-inset);
    z-index: 3;
}

.matrix-head span {
    /*
      Vertical label using writing-mode, which lays the text out bottom-to-top
      within the cell reliably — unlike a rotated flex box, which rendered outside
      the 34px cell and appeared blank. mixed orientation keeps the glyphs upright
      but stacked; the 180deg rotate makes it read bottom-to-top so it sits under
      the column rather than over it.
    */
    display: inline-block;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    text-orientation: mixed;
    white-space: nowrap;
    max-height: 112px;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 10.5px;
    font-family: var(--mono);
    text-transform: none;
    letter-spacing: 0;
}

/* The row header stays visible while the matrix scrolls sideways */
.matrix-row-head {
    position: sticky;
    left: 0;
    background: var(--bg);
    font-size: 12px;
    white-space: nowrap;
    z-index: 1;
    border-right: 1px solid var(--border);
    /* Shrink to the longest namespace name; the cells take the rest */
    width: 1%;
    padding-right: 18px !important;
}

table.matrix tbody tr:hover .matrix-row-head { background: var(--bg-inset); }

.matrix-cell {
    text-align: center;
    padding: 4px !important;
    width: 34px;
}

.matrix-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 700;
    cursor: default;
    border: 1px solid transparent;
}

.mark-allowed    { background: var(--ok-soft);    color: var(--ok);
                   border-color: color-mix(in srgb, var(--ok) 26%, transparent); }
.mark-open       { background: var(--bg-subtle);  color: var(--text-faint);
                   border-color: var(--border); }
.mark-denied     { background: var(--bg-subtle);  color: var(--text-faint); }
.mark-referenced { background: var(--accent-soft); color: var(--accent);
                   border-color: var(--accent-line); }
/* A configured link that policy blocks: the one cell that demands attention */
.mark-conflict   { background: var(--error-soft); color: var(--error);
                   border-color: color-mix(in srgb, var(--error) 40%, transparent); }
.mark-self       { background: none; color: var(--border-strong); }
.mark-unknown    { background: var(--bg-subtle);  color: var(--text-faint); }

.matrix-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    padding: 12px 14px;
    border-top: 1px solid var(--border);
    font-size: 11.5px;
    color: var(--text-dim);
}

.matrix-legend span { display: inline-flex; align-items: center; gap: 6px; }

.matrix-legend .matrix-mark { width: 18px; height: 18px; font-size: 10.5px; }

/* ================= Diagnostic console ================= */

.target-fields { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }

.console-layout {
    display: grid;
    grid-template-columns: 290px 1fr;
    gap: 16px;
    align-items: start;
}

.console-library {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.library-scroll { max-height: 62vh; overflow-y: auto; padding: 6px; }

.command-group { margin-bottom: 8px; }

.command-group-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    color: var(--text-faint);
    padding: 7px 9px 4px;
}

.command-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    padding: 6px 9px;
    margin-bottom: 1px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-family: inherit;
    font-size: 12.5px;
    text-align: left;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
}

.command-item:hover { background: var(--bg-subtle); color: var(--text); }

.command-item.active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}

.command-item:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.command-label { flex: 1; min-width: 0; }

/* Marks inspections that need a pod or container selected first */
.command-scope {
    font-size: 9.5px;
    font-family: var(--mono);
    color: var(--text-faint);
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0 5px;
    flex-shrink: 0;
}

.console-output { min-width: 0; }

.console-result {
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    overflow: hidden;
    background: var(--surface);
}

.console-result .log-body { border: none; border-radius: 0; max-height: 56vh; }

.console-result .table-scroll { max-height: 56vh; overflow: auto; }

.console-empty {
    padding: 22px;
    text-align: center;
    color: var(--text-faint);
    font-size: 13px;
}

@media (max-width: 1100px) {
    .console-layout { grid-template-columns: 1fr; }
    .library-scroll { max-height: 34vh; }
}

/* ================= Log browser ================= */

.log-layout {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 16px;
    align-items: start;
}

.log-pods {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.pod-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 62vh;
    overflow-y: auto;
}

.pod-entry {
    padding: 10px 13px;
    border-bottom: 1px solid var(--border);
}

.pod-entry:last-child { border-bottom: none; }

.pod-head {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 7px;
    flex-wrap: wrap;
}

.pod-name {
    font-size: 12px;
    word-break: break-all;
    flex: 1;
    min-width: 0;
}

.pod-restarts {
    font-size: 10.5px;
    color: var(--warn);
    font-weight: 600;
}

.pod-containers { display: flex; gap: 5px; flex-wrap: wrap; }

.container-chip {
    padding: 3px 9px;
    font-size: 11.5px;
    font-family: var(--mono);
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: 11px;
    color: var(--text-dim);
    cursor: pointer;
}

.container-chip:hover {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--accent);
}

.log-output { min-width: 0; }

.log-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 13px;
    background: var(--bg-inset);
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
    font-size: 12.5px;
    flex-wrap: wrap;
}

.log-target { font-weight: 600; }

.log-actions { display: flex; align-items: center; gap: 10px; font-size: 11.5px; }

/* Inline line-count selector in the log header */
.log-lines {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.log-lines .field-label { margin: 0; }

.input-sm {
    padding: 3px 8px;
    font-size: 11.5px;
    height: auto;
    width: auto;
    min-width: 64px;
}

/*
  Log output is a dark surface in both themes: log text is monospaced, dense and
  read for long stretches, and light-on-dark is easier for that than the reverse.
*/
.log-body {
    margin: 0;
    padding: 13px;
    background: #0d1117;
    color: #d5dde5;
    border: 1px solid var(--border);
    border-radius: 0 0 var(--radius) var(--radius);
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.55;
    max-height: 62vh;
    overflow: auto;
    white-space: pre;
    tab-size: 4;
}

@media (max-width: 1100px) {
    .log-layout { grid-template-columns: 1fr; }
    .pod-list { max-height: 30vh; }
}

@media (max-width: 900px) {
    :root { --sidebar-w: 208px; }
    .content { padding: 16px 14px 30px; }
}

/* ============================================================
   Home page
   ============================================================ */

/*
 * Screen-reader-only text.
 *
 * Deliberately not the classic `position: absolute` recipe. Absolute positioning resolves
 * against the nearest positioned ancestor, and the shell has none between here and the
 * document, so such an element is measured against the document rather than the scrolling
 * panel. Placed far down a long view it extends the document height and raises a second,
 * browser-level scrollbar beside the panel's own.
 *
 * Clipping to a zero-size box keeps the text in the accessibility tree while occupying no
 * space and, being still in flow, it cannot escape its container.
 */
.sr-only {
    display: inline-block;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Overview sits above the sections and has no collapsible heading of its own */
.nav-section-flat { margin-bottom: 4px; }
.nav-item-home .label { font-weight: 600; }

/* ---- Verdict banner ---- */

.verdict {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 18px;
    align-items: center;
    background: var(--bg);
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: var(--radius);
    padding: 18px 20px;
    margin-bottom: 22px;
    box-shadow: var(--shadow-sm);
}

.verdict-ok    { border-left-color: var(--ok);    background: var(--ok-soft); }
.verdict-warn  { border-left-color: var(--warn);  background: var(--warn-soft); }
.verdict-error { border-left-color: var(--error); background: var(--error-soft); }

.verdict-mark {
    width: 40px; height: 40px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; font-weight: 600;
    background: var(--bg);
    border: 1px solid var(--border);
}

.verdict-ok    .verdict-mark { color: var(--ok); }
.verdict-warn  .verdict-mark { color: var(--warn); }
.verdict-error .verdict-mark { color: var(--error); }

.verdict-body h3 {
    margin: 0 0 4px;
    font-size: 15.5px;
    font-weight: 650;
}

.verdict-body p {
    margin: 0;
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.5;
    max-width: 92ch;
}

.verdict-counts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.count-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 4px 11px;
    font-size: 12px;
    color: var(--text-dim);
    cursor: pointer;
    font-family: inherit;
    transition: border-color .12s, background .12s;
}

.count-chip:hover { border-color: var(--accent); background: var(--bg-hover); }
.count-chip strong { font-size: 13.5px; font-weight: 650; color: var(--text); }
.count-error strong { color: var(--error); }
.count-warn  strong { color: var(--warn); }

/* Score is secondary to the verdict, so it is quieter and set to one side */
.verdict-score {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 18px;
    cursor: pointer;
    font-family: inherit;
    transition: border-color .12s;
}

.verdict-score:hover { border-color: var(--accent); }

.score-figure {
    font-size: 30px;
    font-weight: 300;
    line-height: 1.05;
    letter-spacing: -0.5px;
}

.score-figure.ok    { color: var(--ok); }
.score-figure.info  { color: var(--info); }
.score-figure.warn  { color: var(--warn); }
.score-figure.error { color: var(--error); }

.score-of    { font-size: 11px; color: var(--text-faint); }
.score-grade { font-size: 11.5px; color: var(--text-dim); font-weight: 600; }

/* ---- Section blocks ---- */

.home-block { margin-bottom: 26px; }

.home-block-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.home-block-head h3 {
    margin: 0;
    font-size: 13px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-dim);
}

.home-block-meta { font-size: 12.5px; color: var(--text-faint); }
.ok-text    { color: var(--ok);    font-weight: 650; }
.error-text { color: var(--error); font-weight: 650; }

.link-btn {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-size: 12.5px;
    color: var(--accent);
    cursor: pointer;
    white-space: nowrap;
}

.link-btn:hover { color: var(--accent-hover); text-decoration: underline; }

/* ---- Finding cards ---- */

.finding-cards {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(390px, 1fr));
    gap: 12px;
}

.finding-card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 13px 15px;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.finding-card-top {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.finding-subject {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text);
}

.finding-area {
    font-size: 11px;
    color: var(--text-faint);
    margin-left: auto;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.finding-detail {
    margin: 0;
    font-size: 13px;
    color: var(--text);
    line-height: 1.45;
}

/* The consequence, set apart so it is not skimmed past as more description */
.finding-impact {
    margin: 0;
    font-size: 12.5px;
    color: var(--text-dim);
    line-height: 1.5;
    border-left: 2px solid var(--border-strong);
    padding-left: 10px;
}

.finding-card-foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    margin-top: auto;
    padding-top: 4px;
}

.finding-remedy {
    font-size: 12px;
    color: var(--accent);
    line-height: 1.45;
}

/* ---- Ring charts ---- */

.chart-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 14px;
}

.chart-card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 15px 17px;
    box-shadow: var(--shadow-sm);
}

.chart-card-head h4 {
    margin: 0 0 2px;
    font-size: 13.5px;
    font-weight: 650;
}

.chart-card-head p {
    margin: 0 0 14px;
    font-size: 11.5px;
    color: var(--text-faint);
}

.chart-body {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
}

.donut-wrap {
    position: relative;
    width: 132px;
    height: 132px;
    flex: 0 0 auto;
}

.donut { width: 100%; height: 100%; }

.donut-track {
    fill: none;
    stroke: var(--bg-subtle);
    stroke-width: 13;
}

.donut-slice {
    fill: none;
    stroke-width: 13;
    stroke-linecap: butt;
    transition: stroke-width .12s;
}

.donut-slice:hover { stroke-width: 15.5; }

/* Centre figure is the number a reader takes away, so it sits inside the hole */
.donut-centre {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.donut-figure {
    font-size: 21px;
    font-weight: 300;
    letter-spacing: -0.4px;
    line-height: 1.1;
}

.donut-unit { font-size: 10.5px; color: var(--text-faint); }

.chart-legend {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1 1 170px;
    min-width: 0;
    font-size: 12px;
}

.chart-legend li {
    display: grid;
    grid-template-columns: 9px 1fr auto auto;
    gap: 8px;
    align-items: center;
    padding: 2.5px 0;
}

.legend-swatch {
    width: 9px; height: 9px;
    border-radius: 2px;
    display: inline-block;
}

.legend-label {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.legend-value   { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.legend-percent {
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
    min-width: 32px;
    text-align: right;
}

/* ---- Workload block grid ---- */

.grid-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 12px;
    font-size: 11.5px;
    color: var(--text-faint);
}

.grid-legend span { display: inline-flex; align-items: center; gap: 5px; }

.swatch {
    width: 10px; height: 10px;
    border-radius: 2px;
    display: inline-block;
    border: 1px solid transparent;
}

.swatch-ok      { background: var(--ok); }
.swatch-warn    { background: var(--warn); }
.swatch-error   { background: var(--error); }
.swatch-neutral { background: var(--border-strong); }
.swatch-restart {
    background: var(--ok);
    border-color: var(--warn);
    box-shadow: inset 0 0 0 1.5px var(--warn);
}

.ns-grid {
    display: grid;
    grid-template-columns: 190px 1fr;
    gap: 12px;
    align-items: start;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
}

.ns-grid:last-of-type { border-bottom: none; }

.ns-grid-label {
    font-size: 12.5px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    padding-top: 2px;
}

.ns-grid-label em {
    display: block;
    font-style: normal;
    font-size: 11px;
    color: var(--error);
    margin-top: 1px;
}

.ns-grid-blocks {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.wl-block {
    width: 17px;
    height: 17px;
    border-radius: 3px;
    border: 1px solid transparent;
    padding: 0;
    cursor: pointer;
    transition: transform .1s, outline-color .1s;
    outline: 2px solid transparent;
    outline-offset: 1px;
}

.wl-block:hover {
    transform: scale(1.22);
    outline-color: var(--accent);
}

.wl-ok      { background: var(--ok); }
.wl-warn    { background: var(--warn); }
.wl-error   { background: var(--error); }
.wl-neutral { background: var(--border-strong); }

/*
 * Restarting is orthogonal to status: a workload can be fully ready and still be
 * crash-looping. Shown as an inset ring so it overlays any base colour.
 */
.wl-restart { box-shadow: inset 0 0 0 2px var(--warn); }

@media (max-width: 820px) {
    .verdict { grid-template-columns: auto 1fr; }
    .verdict-score { grid-column: 2; justify-self: start; }
    .ns-grid { grid-template-columns: 1fr; }
}

/* ================= Dependency graph (Blast Radius) ================= */

.graph-wrap {
    padding: 10px 14px 4px;
    display: flex;
    justify-content: center;
}

/* Cap the drawing so it does not dominate the page on wide screens. */
.dep-graph {
    width: 100%;
    max-width: 560px;
    height: auto;
}

.dep-edge {
    stroke: var(--border-strong);
    stroke-width: 1.5;
    opacity: 0.55;
}

/* Arrowhead marker fill matches the edge colour so direction reads without shouting. */
.dep-arrowhead {
    fill: var(--border-strong);
    opacity: 0.75;
}

.dep-node {
    stroke: var(--bg);
    stroke-width: 2;
}
.dep-node.dep-ok      { fill: var(--ok); }
.dep-node.dep-warn    { fill: var(--warn); }
.dep-node.dep-error   { fill: var(--error); }
.dep-node.dep-neutral { fill: var(--text-faint); }

.dep-label {
    font-size: 20px;
    fill: var(--text-dim);
    font-family: var(--mono, monospace);
}

/* ================= Page help panel (modal) ================= */

.help-lead {
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.5;
    color: var(--text);
    margin: 0 0 12px;
}

.help-text {
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--text-dim);
    margin: 0 0 12px;
}
.help-text:last-child { margin-bottom: 0; }

/* Inline risk badge next to an image tag (e.g. :latest). Compact so it sits on the row. */
.tag-risk {
    margin-left: 6px;
    font-size: 10px;
    vertical-align: middle;
}

/* Extra separation before the probe-risk table so it doesn't crowd the note above it. */
.probe-risk-table { margin-top: 26px; }

/* Sub-section heading within a merged page (e.g. Right-sizing inside Waste Sweep). */
.section-heading {
    margin: 30px 0 12px;
    font-size: 15px;
    font-weight: 650;
    color: var(--text);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}

/* ===== On Fire Now (incident triage) ===================================== */

/* Situation card: the severity donut + legend on the left, scope verdict on the right.
   Reuses .chart-card so it matches the Overview's resource-distribution panels exactly. */
.fire-situation {
    display: grid;
    grid-template-columns: minmax(260px, 340px) 1fr;
    gap: 24px;
    align-items: center;
}
.fire-situation-chart {
    display: flex;
    align-items: center;
    gap: 22px;
}
.fire-legend { align-self: center; }
.fire-legend li { grid-template-columns: 9px 1fr auto; }

/* Scope verdict: a tinted panel that reads as the headline takeaway. */
.fire-situation-scope {
    border-left: 3px solid var(--border-strong);
    padding: 4px 0 4px 16px;
}
.fire-situation-scope.scope-error { border-left-color: var(--error); }
.fire-situation-scope.scope-warn  { border-left-color: var(--warn); }
.fire-situation-scope.scope-ok    { border-left-color: var(--ok); }
.fire-scope-text {
    margin: 2px 0 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.45;
}

@media (max-width: 760px) {
    .fire-situation { grid-template-columns: 1fr; gap: 16px; }
    .fire-situation-scope { border-left: none; border-top: 3px solid var(--border-strong); padding: 12px 0 0; }
}

/* Incident cards, stacked worst-first — matched to the Overview finding cards. */
.incident-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 18px;
}
.incident {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 14px 16px 14px 18px;
    background: var(--bg);
    display: flex;
    flex-direction: column;
    gap: 9px;
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
/* A slim severity rail on the left edge, drawn with a border so it hugs the radius. */
.incident-error { border-left: 3px solid var(--error); }
.incident-warn  { border-left: 3px solid var(--warn); }
.incident:hover { box-shadow: var(--shadow); border-color: var(--border-strong); }

.incident-head {
    display: flex;
    align-items: center;
    gap: 9px;
}
.incident-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
}
.incident-dot.dot-error { background: var(--error); }
.incident-dot.dot-warn  { background: var(--warn); }
.incident-title {
    font-weight: 650;
    font-size: 14px;
    margin: 0;
    flex: 1 1 auto;
    color: var(--text);
}
/* A quiet, tinted badge rather than a loud pill. */
.incident-badge {
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 2px 8px;
    border-radius: 999px;
}
.incident-badge.badge-error { color: var(--error); background: var(--error-soft); }
.incident-badge.badge-warn  { color: var(--warn);  background: var(--warn-soft); }

.incident-cause {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-dim);
}

/* Small uppercase eyebrow label above the evidence and action blocks. */
.incident-eyebrow {
    display: block;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 650;
    color: var(--text-faint);
    margin-bottom: 5px;
}

/* Evidence: a light left-rule, not a heavy filled slab. */
.incident-evidence {
    border-left: 2px solid var(--border-strong);
    padding-left: 11px;
}
.incident-evidence ul {
    margin: 0;
    padding-left: 15px;
}
.incident-evidence li {
    font-family: var(--mono, monospace);
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.65;
}
.incident-foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin-top: 1px;
    padding-top: 11px;
    border-top: 1px solid var(--border);
}
.incident-action {
    flex: 1 1 auto;
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
}
.incident-action > span:last-child { color: var(--text); }

/* The call-to-action: subtle outline button, filling with accent on hover. */
.incident-cta {
    flex: 0 0 auto;
    background: var(--accent-soft);
    color: var(--accent);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 7px 13px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.14s ease, color 0.14s ease;
}
.incident-cta:hover { background: var(--accent); color: #fff; }

@media (max-width: 720px) {
    .incident-foot { flex-direction: column; align-items: stretch; }
}
