/* ── Tron Theme Tokens ─────────────────────────── */
:root, [data-bs-theme="dark"] {
    --sidebar-width: 250px;

    /* Surfaces */
    --bg-dark: #04080e;
    --bg-card: #08131e;
    --bg-sidebar: #050c14;
    --bg-topbar: #061019;
    --grid-line: rgba(45, 226, 255, .045);

    /* Circuit colors */
    --accent: #2de2ff;
    --accent-dim: rgba(45, 226, 255, .14);
    --accent-line: rgba(45, 226, 255, .30);
    --yellow: #ffcf2d;
    --yellow-dim: rgba(255, 207, 45, .14);
    --red: #ff2e4d;
    --red-dim: rgba(255, 46, 77, .14);
    --green: #00e6a0;
    --orange: #ff9d2e;

    /* Typography
       --font-hero is the TRON face, reserved for the brand wordmark and page
       h1s. It is a display face with no weight range and near-unicase
       proportions (lowercase draws taller than the caps), so it is unreadable
       at UI sizes — never point chrome or body copy at it.
       --font-display carries the letterspaced uppercase chrome (nav, panel
       headers, labels, metric values). It was Orbitron, whose wide caps and
       small x-height turned to mush below ~0.8rem, which is most of where it
       is used. Exo 2 keeps the technical tone at a normal width. */
    --font-hero: 'TRON', 'Exo 2', 'Segoe UI', system-ui, sans-serif;
    --font-display: 'Exo 2', 'Segoe UI', system-ui, sans-serif;
    --font-body: 'Exo 2', 'Segoe UI', system-ui, sans-serif;
    --font-mono: 'Share Tech Mono', 'Cascadia Code', 'Fira Code', monospace;

    /* Bootstrap re-map — recolors every text-*, bg-*, border-* utility */
    --bs-info-rgb: 45, 226, 255;
    --bs-primary-rgb: 45, 226, 255;
    --bs-danger-rgb: 255, 46, 77;
    --bs-warning-rgb: 255, 207, 45;
    --bs-success-rgb: 0, 230, 160;
    --bs-secondary-rgb: 92, 130, 156;
    --bs-dark-rgb: 8, 19, 30;
    --bs-link-color-rgb: 45, 226, 255;
    --bs-link-hover-color-rgb: 160, 244, 255;
    --bs-body-bg: #04080e;
    --bs-body-color: #cfe9f5;
    --bs-emphasis-color: #eafaff;
    --bs-border-color: rgba(45, 226, 255, .18);
    --bs-border-color-translucent: rgba(45, 226, 255, .14);
    --bs-body-font-family: var(--font-body);
    --bs-body-font-size: 1rem;
    --bs-heading-color: #eafaff;
}

/* ── Base ──────────────────────────────────────── */
html, body {
    height: 100%;
    margin: 0;
    background: var(--bg-dark);
    color: #cfe9f5;
    font-family: var(--font-body);
    font-size: 1rem;
    /* No extra tracking: the .01em here was propping up Rajdhani, which is
       condensed. Exo 2 is normal width and reads tighter without it. */
    /* Stop iOS/Android from re-flowing text after an orientation change. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* Light grid + horizon glow behind everything */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        radial-gradient(1200px 600px at 50% -10%, rgba(45, 226, 255, .10), transparent 70%),
        radial-gradient(900px 500px at 100% 110%, rgba(255, 207, 45, .05), transparent 70%),
        repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 48px),
        repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 48px);
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: .06em;
    color: #eafaff;
    text-shadow: 0 0 14px rgba(45, 226, 255, .30);
}

/* Hero headers only. TRON has a single weight, so font-weight is pinned to 400
   to stop the browser synthesising a smeared faux-bold over it. */
h1, .h1, .hero-title {
    font-family: var(--font-hero);
    font-weight: 400 !important;
    letter-spacing: .06em;
}

a {
    text-decoration: none;
}
a:hover {
    text-shadow: 0 0 10px rgba(45, 226, 255, .55);
}

code, pre, kbd, samp, .font-monospace {
    font-family: var(--font-mono);
}

/* Correlation IDs, URLs and headers are long unbroken strings — let them wrap
   instead of pushing the page sideways on a phone. */
code {
    word-break: break-word;
}

/* Glow for the semantic text utilities used across the views */
.text-info { text-shadow: 0 0 12px rgba(45, 226, 255, .55); }
.text-primary { text-shadow: 0 0 12px rgba(45, 226, 255, .55); }
.text-danger { text-shadow: 0 0 12px rgba(255, 46, 77, .55); }
.text-warning { text-shadow: 0 0 12px rgba(255, 207, 45, .55); }
.text-success { text-shadow: 0 0 12px rgba(0, 230, 160, .45); }
.text-white { color: #eafaff !important; }
.text-white-50 { color: rgba(150, 205, 228, .62) !important; }
.text-dark { color: #04080e !important; }

hr, .border-secondary {
    border-color: var(--accent-line) !important;
    opacity: 1;
}

/* ── Sidebar ──────────────────────────────────── */
.sidebar {
    width: var(--sidebar-width);
    height: 100vh;
    background: linear-gradient(180deg, var(--bg-sidebar), #030810);
    border-right: 1px solid var(--accent-line);
    box-shadow: 1px 0 18px rgba(45, 226, 255, .12);
    position: sticky;
    top: 0;
    align-self: flex-start;
    overflow: hidden;
}

/* Grouped into sections the nav list is taller than a short viewport, so it
   scrolls on its own and the brand/user footer stays pinned. flex-wrap and
   min-height are both load-bearing: Bootstrap's .nav wraps, so without them an
   over-tall list breaks into a second column beside the sidebar instead of
   scrolling. */
.sidebar > .nav {
    flex-wrap: nowrap;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--accent-line) transparent;
}

.sidebar .nav-link {
    border-radius: 2px;
    border-left: 2px solid transparent;
    font-family: var(--font-display);
    font-size: .78rem;
    font-weight: 500;
    letter-spacing: .07em;
    text-transform: uppercase;
    transition: background .15s, color .15s, box-shadow .15s;
}

.sidebar .nav-link.active {
    background: linear-gradient(90deg, var(--accent-dim), transparent) !important;
    border-left-color: var(--accent);
    color: var(--accent) !important;
    box-shadow: inset 0 0 22px rgba(45, 226, 255, .12), -1px 0 12px rgba(45, 226, 255, .35);
    text-shadow: 0 0 12px rgba(45, 226, 255, .6);
}

.sidebar .nav-link:hover:not(.active) {
    background: rgba(45, 226, 255, .06);
    border-left-color: rgba(45, 226, 255, .5);
    color: var(--accent) !important;
}

/* Group heading between runs of nav links. Collapsed, the label is hidden by
   .sidebar-label and the rule is all that survives — which is what we want:
   the groups still read as groups when the sidebar is icons-only. */
.sidebar .nav-section {
    margin: .85rem 0 .3rem;
    padding: 0 0 .3rem .5rem;
    border-bottom: 1px solid var(--accent-line);
    font-family: var(--font-display);
    font-size: .62rem;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: rgba(45, 226, 255, .55);
}

/* Brand wordmark. Both !importants are load-bearing, because the Bootstrap
   utilities they override (.fw-semibold, .fs-5) are themselves !important:
   TRON ships only a 400 weight, so without the first the browser synthesises
   a faux-bold and smears it; and TRON runs about 1.04em per character, so at
   .fs-5 the wordmark rendered 228px wide and pushed the 250px sidebar into
   horizontal overflow. It is near-unicase and chunky, so it still reads as a
   logo at the smaller size. */
.sidebar .fs-5.fw-semibold {
    font-family: var(--font-hero);
    font-weight: 400 !important;
    font-size: .95rem !important;
    letter-spacing: .04em;
    white-space: nowrap;
    text-shadow: 0 0 16px rgba(45, 226, 255, .55);
}

/* ── Top Bar ──────────────────────────────────── */
.top-bar {
    background: var(--bg-topbar);
    border-bottom: 1px solid var(--accent-line);
    box-shadow: 0 1px 18px rgba(45, 226, 255, .10);
    min-height: 50px;
}
.top-bar h5 {
    font-family: var(--font-display);
    font-size: .95rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--accent) !important;
}

/* ── Main Content ─────────────────────────────── */
.main-content {
    min-height: 100vh;
    min-height: 100dvh; /* mobile browser chrome shrinks the visual viewport */
    /* Transparent so the grid and horizon glow on <body> show through. */
    background: transparent;
    /* Without this a wide table can stretch the flex item past the viewport. */
    min-width: 0;
}

/* ── Metric Grid ──────────────────────────────── */
/* minmax(0, 1fr) rather than 1fr: plain `1fr` floors each column at its
   min-content width, so long counts push the last card past the viewport. */
.metric-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: .75rem;
}
/* Four cards plus the 250px sidebar stop fitting below ~1200px. */
@media (max-width: 1199.98px) {
    .metric-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 991.98px) {
    .metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Keep two-up on phones — one card per row turns the dashboard into a
   scroll marathon before any real data is visible. */
@media (max-width: 360px) {
    .metric-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── Metric Cards ─────────────────────────────── */
.metric-card {
    background: linear-gradient(160deg, rgba(45, 226, 255, .05), transparent 55%), var(--bg-card);
    border: 1px solid var(--accent-line);
    border-radius: 3px;
    padding: 1.25rem;
    box-shadow: inset 0 0 26px rgba(45, 226, 255, .05);
    transition: transform .15s, box-shadow .15s, border-color .15s;
}
.metric-card:hover {
    transform: translateY(-2px);
    border-color: var(--accent);
    box-shadow: 0 0 28px rgba(45, 226, 255, .22), inset 0 0 30px rgba(45, 226, 255, .08);
}
/* Let the text column shrink inside the flex row instead of overflowing. */
.metric-card > div:last-child {
    min-width: 0;
}
.metric-card .metric-value,
.metric-card .metric-label {
    overflow-wrap: anywhere;
}
.metric-card .metric-value {
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: .04em;
    text-shadow: 0 0 18px currentColor;
}
/* Denser variant used on pages with a four-card summary row. */
.metric-card .metric-value.metric-value-sm {
    font-size: 1.5rem;
}
.metric-card .metric-label {
    font-family: var(--font-display);
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .16em;
    color: rgba(150, 205, 228, .62);
    opacity: 1;
}
.metric-card .metric-icon {
    width: 48px;
    height: 48px;
    border-radius: 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    border: 1px solid currentColor;
    box-shadow: 0 0 16px -2px currentColor, inset 0 0 16px -6px currentColor;
}
.metric-card-link {
    display: block;
    text-decoration: none;
    color: inherit;
}
.metric-card-link .metric-card:hover {
    border-color: var(--accent);
}

/* ── Panel / Data Card ────────────────────────── */
.panel {
    background: var(--bg-card);
    border: 1px solid var(--accent-line);
    border-radius: 3px;
    overflow: hidden;
    box-shadow: 0 0 24px rgba(0, 0, 0, .5), inset 0 0 40px rgba(45, 226, 255, .03);
}
.panel-header {
    position: relative;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--accent-line);
    background: linear-gradient(90deg, rgba(45, 226, 255, .07), transparent);
    font-family: var(--font-display);
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #eafaff;
}
/* Glowing rail under every panel header */
.panel-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, var(--accent), transparent 65%);
    box-shadow: 0 0 10px rgba(45, 226, 255, .6);
}
.panel-body {
    padding: 1.25rem;
}

/* ── Tables ───────────────────────────────────── */
.table-dark-custom {
    --bs-table-bg: transparent;
    --bs-table-color: #cfe9f5;
    --bs-table-striped-bg: rgba(45, 226, 255, .03);
    --bs-table-striped-color: #cfe9f5;
    --bs-table-hover-bg: rgba(45, 226, 255, .09);
    --bs-table-hover-color: #eafaff;
    font-size: .9rem;
}
.table-dark-custom th {
    border-bottom-color: var(--accent-line);
    font-family: var(--font-display);
    font-weight: 600;
    text-transform: uppercase;
    font-size: .68rem;
    letter-spacing: .12em;
    color: var(--accent);
    text-shadow: 0 0 10px rgba(45, 226, 255, .35);
    background: rgba(45, 226, 255, .04);
}
.table-dark-custom th a {
    color: inherit;
}
.table-dark-custom td {
    border-bottom-color: rgba(45, 226, 255, .07);
    vertical-align: middle;
}

/* ── Truncating table cells ───────────────────── */
/* Fixed pixel widths overflow a phone; these shrink with the viewport. */
.cell-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 300px;
}
.cell-truncate-sm { max-width: 220px; }
.cell-truncate-lg { max-width: 350px; }
@media (max-width: 991.98px) {
    .cell-truncate,
    .cell-truncate-sm,
    .cell-truncate-lg { max-width: 220px; }
}
@media (max-width: 767.98px) {
    .cell-truncate,
    .cell-truncate-sm,
    .cell-truncate-lg { max-width: 42vw; }
}

/* ── Severity Badges ──────────────────────────── */
.badge {
    border-radius: 2px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .66rem;
    letter-spacing: .10em;
    text-transform: uppercase;
    border: 1px solid rgba(255, 255, 255, .18);
}
.badge.bg-info,
.badge.bg-primary { box-shadow: 0 0 12px rgba(45, 226, 255, .45); border-color: var(--accent); }
.badge.bg-danger { box-shadow: 0 0 12px rgba(255, 46, 77, .45); border-color: var(--red); }
.badge.bg-warning { box-shadow: 0 0 12px rgba(255, 207, 45, .45); border-color: var(--yellow); color: #04080e; }
.badge.bg-success { box-shadow: 0 0 12px rgba(0, 230, 160, .40); border-color: var(--green); color: #04080e; }
.badge.bg-secondary { border-color: rgba(92, 130, 156, .6); }

.badge-critical { background: var(--red); color: #fff; border-color: var(--red); box-shadow: 0 0 14px rgba(255, 46, 77, .6); }
.badge-error { background: rgba(255, 46, 77, .22); color: #ff8b9d; border-color: var(--red); box-shadow: 0 0 10px rgba(255, 46, 77, .35); }
.badge-warning { background: var(--yellow); color: #04080e; border-color: var(--yellow); box-shadow: 0 0 14px rgba(255, 207, 45, .55); }
.badge-info { background: var(--accent); color: #04080e; border-color: var(--accent); box-shadow: 0 0 14px rgba(45, 226, 255, .55); }
.badge-debug { background: rgba(92, 130, 156, .22); color: #9fc4d8; border-color: rgba(92, 130, 156, .6); }

/* ── Buttons ──────────────────────────────────── */
.btn {
    --bs-btn-border-radius: 2px;
    font-family: var(--font-display);
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    transition: box-shadow .15s, background .15s, color .15s;
}
.btn-sm { font-size: .68rem; }
.btn-lg { font-size: .9rem; }

.btn-info, .btn-primary {
    --bs-btn-color: #04080e;
    --bs-btn-bg: var(--accent);
    --bs-btn-border-color: var(--accent);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: #6aecff;
    --bs-btn-hover-border-color: #6aecff;
    --bs-btn-active-bg: #6aecff;
    --bs-btn-active-border-color: #6aecff;
}
.btn-info:hover, .btn-primary:hover { box-shadow: 0 0 20px rgba(45, 226, 255, .6); }

.btn-outline-info, .btn-outline-secondary {
    --bs-btn-color: var(--accent);
    --bs-btn-border-color: var(--accent-line);
    --bs-btn-bg: rgba(45, 226, 255, .04);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--accent);
    --bs-btn-active-color: #04080e;
    --bs-btn-active-bg: var(--accent);
    --bs-btn-active-border-color: var(--accent);
}
.btn-outline-info:hover, .btn-outline-secondary:hover { box-shadow: 0 0 18px rgba(45, 226, 255, .5); }

.btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--red);
    --bs-btn-border-color: var(--red);
    --bs-btn-hover-bg: #ff5871;
    --bs-btn-hover-border-color: #ff5871;
}
.btn-outline-danger {
    --bs-btn-color: var(--red);
    --bs-btn-border-color: rgba(255, 46, 77, .45);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: var(--red);
    --bs-btn-hover-border-color: var(--red);
    --bs-btn-active-bg: var(--red);
    --bs-btn-active-border-color: var(--red);
}
.btn-danger:hover, .btn-outline-danger:hover { box-shadow: 0 0 20px rgba(255, 46, 77, .55); }

.btn-warning {
    --bs-btn-color: #04080e;
    --bs-btn-bg: var(--yellow);
    --bs-btn-border-color: var(--yellow);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: #ffdd66;
    --bs-btn-hover-border-color: #ffdd66;
}
.btn-outline-warning {
    --bs-btn-color: var(--yellow);
    --bs-btn-border-color: rgba(255, 207, 45, .45);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: var(--yellow);
    --bs-btn-hover-border-color: var(--yellow);
    --bs-btn-active-color: #04080e;
    --bs-btn-active-bg: var(--yellow);
    --bs-btn-active-border-color: var(--yellow);
}
.btn-warning:hover, .btn-outline-warning:hover { box-shadow: 0 0 20px rgba(255, 207, 45, .55); }

.btn-outline-success {
    --bs-btn-color: var(--green);
    --bs-btn-border-color: rgba(0, 230, 160, .45);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: var(--green);
    --bs-btn-hover-border-color: var(--green);
    --bs-btn-active-color: #04080e;
    --bs-btn-active-bg: var(--green);
    --bs-btn-active-border-color: var(--green);
}
.btn-outline-success:hover { box-shadow: 0 0 20px rgba(0, 230, 160, .45); }

.btn-dark {
    --bs-btn-color: var(--accent);
    --bs-btn-bg: #08131e;
    --bs-btn-border-color: var(--accent-line);
    --bs-btn-hover-color: #04080e;
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--accent);
}
.btn-link {
    --bs-btn-color: var(--accent);
    --bs-btn-hover-color: #a0f4ff;
    text-transform: none;
    letter-spacing: normal;
}
.btn:focus-visible, .btn.focus {
    box-shadow: 0 0 0 3px var(--accent-dim);
}

/* ── Alerts ───────────────────────────────────── */
.alert {
    --bs-alert-border-radius: 2px;
    border-width: 1px;
    border-left-width: 3px;
}
.alert-danger {
    --bs-alert-color: #ff8b9d;
    --bs-alert-bg: rgba(255, 46, 77, .10);
    --bs-alert-border-color: var(--red);
    box-shadow: inset 0 0 30px rgba(255, 46, 77, .07), -3px 0 14px -6px var(--red);
}
.alert-warning {
    --bs-alert-color: #ffdf7d;
    --bs-alert-bg: rgba(255, 207, 45, .10);
    --bs-alert-border-color: var(--yellow);
    box-shadow: inset 0 0 30px rgba(255, 207, 45, .07), -3px 0 14px -6px var(--yellow);
}
.alert-success {
    --bs-alert-color: #7dffd6;
    --bs-alert-bg: rgba(0, 230, 160, .10);
    --bs-alert-border-color: var(--green);
    box-shadow: inset 0 0 30px rgba(0, 230, 160, .07), -3px 0 14px -6px var(--green);
}
.alert-info, .alert-primary {
    --bs-alert-color: #a0f4ff;
    --bs-alert-bg: rgba(45, 226, 255, .10);
    --bs-alert-border-color: var(--accent);
    box-shadow: inset 0 0 30px rgba(45, 226, 255, .07), -3px 0 14px -6px var(--accent);
}
/* Muted slate for explanatory footnotes and "nothing is switched on" states.
   Deliberately quieter than .alert-info: these carry context, not a signal, and
   accent-glowing every one of them would flatten the page's priority order. */
.alert-secondary, .alert-dark {
    --bs-alert-color: rgba(180, 214, 232, .85);
    --bs-alert-bg: rgba(92, 130, 156, .10);
    --bs-alert-border-color: rgba(92, 130, 156, .55);
    box-shadow: inset 0 0 30px rgba(92, 130, 156, .06), -3px 0 14px -6px rgba(92, 130, 156, .8);
}
.alert-secondary code, .alert-dark code {
    color: #9fe8ff;
}
.btn-close {
    filter: invert(85%) sepia(40%) saturate(900%) hue-rotate(150deg);
}

/* ── Status Dot ───────────────────────────────── */
.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}
.status-dot.green { background: var(--green); box-shadow: 0 0 10px var(--green); }
.status-dot.red { background: var(--red); box-shadow: 0 0 10px var(--red); }
.status-dot.yellow { background: var(--yellow); box-shadow: 0 0 10px var(--yellow); }
.status-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1.25rem;
    padding: .85rem 1.25rem;
    border-top: 1px solid var(--accent-line);
    color: rgba(150, 205, 228, .70);
    font-size: .8rem;
    letter-spacing: .04em;
}
.status-legend-item {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}

/* ── Login Page ───────────────────────────────── */
.login-page {
    min-height: 100vh;
    min-height: 100dvh;
    background:
        radial-gradient(800px 500px at 50% 0%, rgba(45, 226, 255, .16), transparent 70%),
        radial-gradient(700px 400px at 50% 100%, rgba(255, 207, 45, .07), transparent 70%),
        linear-gradient(180deg, #04080e 0%, #061420 55%, #030810 100%);
    display: flex;
    align-items: center;
    justify-content: center;
}
.login-card {
    position: relative;
    background: var(--bg-card);
    border: 1px solid var(--accent);
    border-radius: 3px;
    padding: 2.5rem;
    width: 100%;
    max-width: 400px;
    box-shadow: 0 0 40px rgba(45, 226, 255, .25), 0 20px 60px rgba(0, 0, 0, .6), inset 0 0 60px rgba(45, 226, 255, .05);
}
/* Brand wordmark on the login card. Sized well below Bootstrap's h3 because
   TRON is roughly 1.04em per character — at h3 it wrapped mid-wordmark. */
.login-card .hero-title {
    font-size: 1.3rem;
    letter-spacing: .04em;
    white-space: nowrap;
}
/* Light ribbon across the top of the card */
.login-card::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 12%;
    right: 12%;
    height: 2px;
    background: var(--accent);
    box-shadow: 0 0 16px var(--accent);
}
.login-card .form-control {
    background: rgba(45, 226, 255, .04);
    border: 1px solid var(--accent-line);
    color: #eafaff;
    padding: .75rem 1rem;
    border-radius: 2px;
}
.login-card .form-control:focus {
    background: rgba(45, 226, 255, .08);
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-dim), 0 0 18px rgba(45, 226, 255, .35);
    color: #eafaff;
}
.login-card .btn-primary {
    background: var(--accent);
    border: 1px solid var(--accent);
    color: #04080e;
    font-weight: 700;
    padding: .75rem;
    border-radius: 2px;
    box-shadow: 0 0 22px rgba(45, 226, 255, .45);
    transition: box-shadow .15s, background .15s;
}
.login-card .btn-primary:hover {
    background: #6aecff;
    color: #04080e;
    box-shadow: 0 0 34px rgba(45, 226, 255, .7);
}

/* ── Stack trace toggle ───────────────────────── */
.stack-toggle {
    cursor: pointer;
    color: var(--accent);
    font-size: .8rem;
    text-shadow: 0 0 10px rgba(45, 226, 255, .45);
}
.stack-trace-content {
    max-height: 200px;
    overflow-y: auto;
    /* Long unbroken frames/URLs would otherwise widen the whole row. */
    overflow-x: auto;
    overflow-wrap: anywhere;
    font-family: var(--font-mono);
    font-size: .8rem;
    white-space: pre-wrap;
    color: #9fe8ff;
    background: rgba(0, 0, 0, .45);
    border: 1px solid rgba(45, 226, 255, .12);
    border-radius: 2px;
    padding: .75rem;
    margin-top: .5rem;
}

/* The detail page shows the whole exception; nothing is worth scrolling in a
   200px box when the page itself can scroll. */
.stack-trace-full {
    max-height: none;
    margin-top: 0;
}

/* ── Exception detail ─────────────────────────── */
.detail-label {
    font-family: var(--font-display);
    font-size: .66rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(150, 205, 228, .65);
    margin-bottom: .15rem;
}

/* Message cells that open the full exception. Reads as normal table text
   until hovered, so the lists stay scannable. */
a.exception-link {
    color: inherit;
    text-decoration: none;
    display: block;
}
a.exception-link:hover,
a.exception-link:focus-visible {
    color: var(--accent);
    text-decoration: underline;
}

/* ── Trace waterfall ──────────────────────────── */
/* Each bar is positioned and sized by its real start and duration, so the
   track needs to read as a recessed rail with the span glowing on top of it. */
.waterfall-row {
    display: flex;
    align-items: center;
    gap: .5rem;
}
.waterfall-label {
    width: 24rem;
    flex: 0 0 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .82rem;
}
.waterfall-track {
    position: relative;
    flex: 1 1 auto;
    height: 1.25rem;
    background: rgba(0, 0, 0, .45);
    border: 1px solid rgba(45, 226, 255, .12);
    border-radius: 2px;
    overflow: hidden;
}
/* Faint tick rail so a bar's offset stays readable without axis labels. */
.waterfall-track::before {
    content: "";
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(90deg, rgba(45, 226, 255, .07) 0 1px, transparent 1px 10%);
    pointer-events: none;
}
.waterfall-bar {
    position: absolute;
    top: 0;
    height: 100%;
    border-radius: 1px;
    background: linear-gradient(180deg, #6aecff, var(--accent));
    box-shadow: 0 0 12px rgba(45, 226, 255, .55);
}
/* A span with no recorded end time, drawn to the end of the window. */
.waterfall-bar.is-open {
    background: repeating-linear-gradient(45deg, var(--yellow) 0 6px, rgba(255, 207, 45, .45) 6px 12px);
    box-shadow: 0 0 12px rgba(255, 207, 45, .5);
}
.waterfall-duration {
    width: 6rem;
    flex: 0 0 auto;
    text-align: right;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: .78rem;
}
@media (max-width: 767.98px) {
    /* The label column would leave no room for the bar on a phone. */
    .waterfall-label { width: 40vw; }
    .waterfall-duration { width: 4.5rem; font-size: .7rem; }
}

/* ── Forms ────────────────────────────────────── */
.form-label {
    font-family: var(--font-display);
    font-size: .68rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(150, 205, 228, .75);
}

.form-control,
.form-select {
    background-color: rgba(45, 226, 255, .04);
    border: 1px solid var(--accent-line);
    border-radius: 2px;
    color: #eafaff;
}

.form-control:focus,
.form-select:focus {
    background-color: rgba(45, 226, 255, .07);
    border-color: var(--accent);
    color: #eafaff;
    box-shadow: 0 0 0 3px var(--accent-dim), 0 0 16px rgba(45, 226, 255, .25);
}

.form-control.bg-transparent,
.form-select.bg-transparent {
    background-color: rgba(45, 226, 255, .04) !important;
    color: #eafaff !important;
}

.form-control::placeholder {
    color: rgba(150, 205, 228, .5);
    opacity: 1;
}

.form-select {
    color-scheme: dark;
}

.form-select option,
.form-select optgroup {
    background-color: var(--bg-card);
    color: #eafaff;
}

.form-select option:checked {
    background-color: var(--accent-dim);
    color: var(--accent);
}

.input-group-text {
    background-color: rgba(45, 226, 255, .06);
    border-color: var(--accent-line);
    color: var(--accent);
}

.form-check-input:checked {
    background-color: var(--accent);
    border-color: var(--accent);
    box-shadow: 0 0 10px rgba(45, 226, 255, .5);
}

/* ── Pagination ───────────────────────────────── */
/* Bootstrap derives these from its compiled $primary, so the --bs-*-rgb
   remap above does not reach them. */
.pagination {
    --bs-pagination-bg: rgba(45, 226, 255, .04);
    --bs-pagination-color: var(--accent);
    --bs-pagination-border-color: var(--accent-line);
    --bs-pagination-border-radius: 2px;
    --bs-pagination-hover-bg: rgba(45, 226, 255, .14);
    --bs-pagination-hover-color: #a0f4ff;
    --bs-pagination-hover-border-color: var(--accent);
    --bs-pagination-focus-bg: rgba(45, 226, 255, .14);
    --bs-pagination-focus-color: #a0f4ff;
    --bs-pagination-active-bg: var(--accent);
    --bs-pagination-active-color: #04080e;
    --bs-pagination-active-border-color: var(--accent);
    --bs-pagination-disabled-bg: transparent;
    --bs-pagination-disabled-color: rgba(150, 205, 228, .35);
    --bs-pagination-disabled-border-color: rgba(45, 226, 255, .10);
    font-family: var(--font-display);
    font-size: .72rem;
}
.pagination .active > .page-link {
    box-shadow: 0 0 14px rgba(45, 226, 255, .5);
}

/* ── Dropdowns & Modals ───────────────────────── */
.dropdown-menu {
    --bs-dropdown-bg: #08131e;
    --bs-dropdown-border-color: var(--accent-line);
    --bs-dropdown-border-radius: 2px;
    --bs-dropdown-link-color: #cfe9f5;
    --bs-dropdown-link-hover-bg: rgba(45, 226, 255, .12);
    --bs-dropdown-link-hover-color: var(--accent);
    --bs-dropdown-link-active-bg: var(--accent-dim);
    --bs-dropdown-link-active-color: var(--accent);
    box-shadow: 0 0 24px rgba(45, 226, 255, .18);
}

.modal-content {
    background: var(--bg-card);
    border: 1px solid var(--accent);
    border-radius: 3px;
    box-shadow: 0 0 44px rgba(45, 226, 255, .22);
}
.modal-header, .modal-footer {
    border-color: var(--accent-line);
}
.modal-title {
    font-family: var(--font-display);
    letter-spacing: .1em;
    text-transform: uppercase;
    font-size: 1rem;
}

/* ── Scrollbar ────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(45, 226, 255, .25); border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }

/* ── Chart container ──────────────────────────── */
.chart-container {
    position: relative;
    height: 250px;
}
/* Taller fixed chart (bubble/scatter) that still needs to shrink on a phone. */
.chart-tall {
    height: 420px;
}
/* Height driven by row count — the view supplies both values. */
.chart-dynamic {
    height: var(--chart-h, 250px);
}

/* ── Sidebar pin/collapse (desktop) ──────────── */
@media (min-width: 768px) {
    .sidebar {
        transition: width .2s ease;
    }
    .sidebar.collapsed {
        width: 64px;
        padding-left: .5rem !important;
        padding-right: .5rem !important;
    }
    .sidebar.collapsed .sidebar-label {
        display: none;
    }
    .sidebar.collapsed .nav-link {
        text-align: center;
        padding: .5rem;
        justify-content: center;
    }
    .sidebar.collapsed .nav-link i {
        margin-right: 0 !important;
        font-size: 1.15rem;
    }
    .sidebar.collapsed hr {
        margin: .5rem 0;
    }
    .sidebar.collapsed .nav-section {
        margin: .45rem .25rem;
        padding: 0;
    }
    /* A scrollbar in a 64px rail costs more than it tells you; wheel still works. */
    .sidebar.collapsed > .nav {
        scrollbar-width: none;
    }
    .sidebar.collapsed > .nav::-webkit-scrollbar {
        display: none;
    }
    .sidebar.collapsed .dropdown-toggle::after {
        display: none;
    }
    .sidebar.collapsed #sidebarPin {
        margin: 0 auto;
    }
}

/* ── Pin button ──────────────────────────────── */
#sidebarPin {
    transition: transform .15s;
}
#sidebarPin:hover {
    color: var(--accent) !important;
    text-shadow: 0 0 12px rgba(45, 226, 255, .6);
}
.sidebar:not(.collapsed) #pinIcon {
    transform: rotate(-45deg);
}

/* ── Mobile top bar ──────────────────────────── */
.mobile-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 50px;
    background: var(--bg-topbar);
    border-bottom: 1px solid var(--accent-line);
    box-shadow: 0 1px 16px rgba(45, 226, 255, .12);
    z-index: 1040;
}
/* Same wordmark, mobile bar. See the sidebar rule above for why !important. */
.mobile-topbar .fw-semibold {
    font-family: var(--font-hero);
    font-weight: 400 !important;
    font-size: .95rem;
    letter-spacing: .04em;
    white-space: nowrap;
}

/* ── Sidebar overlay ─────────────────────────── */
.sidebar-overlay {
    position: fixed;
    inset: 0;
    background: rgba(2, 8, 14, .7);
    z-index: 1049;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
}
.sidebar-overlay.open {
    opacity: 1;
    pointer-events: auto;
}

/* ── Responsive sidebar ─────────────────────── */
@media (max-width: 767.98px) {
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 1050;
        transform: translateX(-100%);
        transition: transform .25s ease;
        width: 260px;
        overflow-y: auto;
    }
    /* The whole drawer scrolls on mobile, so the nav list must not scroll too —
       and must not shrink either, or its links spill over the pinned footer. */
    .sidebar > .nav {
        overflow: visible;
        flex-shrink: 0;
        min-height: auto;
    }
    .sidebar.open {
        transform: translateX(0);
    }
    .main-content {
        margin-top: 50px;
        width: 100%;
    }
    .top-bar {
        display: none !important;
    }
}

/* ── Responsive metric cards ─────────────────── */
@media (max-width: 767.98px) {
    .metric-card {
        padding: .85rem;
    }
    .metric-card .metric-value {
        font-size: 1.4rem;
    }
    /* Two of these sit side by side on a phone — keep long counts on one line. */
    .metric-card .metric-value.metric-value-sm {
        font-size: 1.15rem;
    }
    .metric-card .metric-icon {
        width: 38px;
        height: 38px;
        font-size: 1rem;
    }
    .metric-card .metric-label {
        font-size: .7rem;
    }
}

/* ── Responsive tables ───────────────────────── */
@media (max-width: 767.98px) {
    .table-dark-custom,
    .table-dark {
        font-size: .8rem;
    }
    .table-dark-custom th,
    .table-dark-custom td,
    .table-dark th,
    .table-dark td {
        padding: .4rem .5rem;
    }
    /* Hide secondary columns on small screens. Anything hidden here is still
       reachable through the row's expandable detail panel or a drill-down. */
    .d-mobile-none {
        display: none !important;
    }
    /* Header widths sized for a desktop table force horizontal scroll. */
    .table-responsive th[style*="width"] {
        width: auto !important;
    }
}

/* ── Stacked tables (forms in cells) ─────────── */
/* Side-scrolling a table whose cells contain text inputs is unusable on a
   phone, so those tables become one card per row instead. */
@media (max-width: 767.98px) {
    .table-stack-mobile thead {
        display: none;
    }
    .table-stack-mobile,
    .table-stack-mobile tbody,
    .table-stack-mobile tr,
    .table-stack-mobile td {
        display: block;
        width: 100%;
    }
    .table-stack-mobile tr {
        padding: .85rem 1rem;
        border-bottom: 1px solid rgba(45, 226, 255, .12);
    }
    .table-stack-mobile td {
        border: 0 !important;
        padding: .35rem 0 !important;
        text-align: left !important;
    }
    .table-stack-mobile td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: .25rem;
        font-family: var(--font-display);
        font-size: .65rem;
        text-transform: uppercase;
        letter-spacing: .12em;
        color: rgba(150, 205, 228, .62);
    }
    .table-stack-mobile .form-check.d-flex {
        justify-content: flex-start !important;
    }
}

/* ── Pagination ──────────────────────────────── */
@media (max-width: 767.98px) {
    .pagination {
        flex-wrap: wrap;
        justify-content: center;
        gap: .2rem;
    }
    .page-link {
        min-width: 38px;
        min-height: 38px;
        display: flex;
        align-items: center;
        justify-content: center;
    }
}

/* ── Touch targets ───────────────────────────── */
@media (max-width: 767.98px) {
    /* A 14px icon is not a tappable target — pad it out to 40px square. */
    .stack-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        min-height: 40px;
        margin: -.4rem;
    }
    .btn-sm {
        min-height: 34px;
    }
    .table-dark-custom .btn-sm {
        padding-left: .5rem;
        padding-right: .5rem;
    }
}

/* ── Responsive panels ───────────────────────── */
@media (max-width: 767.98px) {
    .panel {
        border-radius: 2px;
    }
    .panel-header {
        padding: .75rem 1rem;
        font-size: .78rem;
    }
    /* Headers pair a title with counts/actions; let them stack rather than
       squash the title to one word per line. */
    .panel-header.d-flex {
        flex-wrap: wrap;
        gap: .5rem;
    }
    .panel-body {
        padding: .75rem;
    }
}

/* ── Responsive filter forms ─────────────────── */
@media (max-width: 767.98px) {
    /* Must stay at 16px: iOS Safari zooms the whole page when a focused
       input renders below 16px, and never zooms back out. The input-group
       selectors are needed to outrank Bootstrap's `.input-group-sm > .form-control`. */
    .form-control, .form-select,
    .form-control-sm, .form-select-sm,
    .input-group-sm > .form-control,
    .input-group-sm > .form-select,
    .input-group-sm > .form-control-sm,
    .input-group-sm > .form-select-sm {
        font-size: 16px;
        padding: .45rem .6rem;
    }
    .form-label {
        margin-bottom: .2rem;
    }
    /* Filter buttons go full width so they are easy to hit. */
    .filter-actions .btn {
        flex: 1 1 auto;
    }
    /* Switches and checkboxes need a bigger hit area. */
    .form-check-input {
        width: 1.25rem;
        height: 1.25rem;
        margin-top: .1rem;
    }
    .form-switch .form-check-input {
        width: 2.25rem;
    }
}

/* ── Responsive chart ────────────────────────── */
@media (max-width: 767.98px) {
    .chart-container {
        height: 200px;
    }
    .chart-tall {
        height: 300px;
    }
    .chart-dynamic {
        height: var(--chart-h-sm, var(--chart-h, 250px));
    }
}

/* ── Responsive login ────────────────────────── */
@media (max-width: 575.98px) {
    .login-page {
        padding: 1rem;
    }
    .login-card {
        padding: 1.5rem;
    }
}
/* The wordmark is nowrap, so on the narrowest phones it has to shrink rather
   than break — at 1.3rem it clears the card's inner width by only ~13px at
   320px, and less below that. */
@media (max-width: 360px) {
    .login-card .hero-title {
        font-size: 1.05rem;
    }
}

/* ── Reduced motion ──────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .metric-card, .btn, .sidebar, .sidebar .nav-link, #sidebarPin, .sidebar-overlay {
        transition: none;
    }
}

/* ── Application health ────────────────────────
   The heartbeat strip on an application card, and the per-instance table that
   drops out of a row on the Applications page. The nested table sits inside a
   cell of the outer one, so it has to shed the outer table's row hover and
   borders or the two read as one confusing grid. */
.app-health {
    border-top: 1px solid var(--accent-line);
}

.instance-row > td {
    border-top: 0;
    background: rgba(45, 226, 255, .04);
}

.instance-table {
    font-size: .78rem;
    background: transparent;
}

.instance-table > thead > tr > th {
    font-size: .68rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: rgba(150, 205, 228, .70);
    border-bottom: 1px solid var(--accent-line);
    background: transparent;
}

.instance-table > tbody > tr > td {
    border-bottom: 1px solid rgba(45, 226, 255, .08);
    background: transparent;
}

.instance-table > tbody > tr:last-child > td {
    border-bottom: 0;
}
