/*
 * ScanMe design system.
 *
 * Everything here used to live in a <style> block in includes/header.php plus
 * 819 more lines spread across 32 pages. That produced two card systems, two
 * grey scales and 59 distinct colour literals for what is really about a dozen
 * decisions, and it meant a change to the shell had to be repeated everywhere
 * or drift.
 *
 * Two things it fixes beyond tidiness:
 *
 *   - the application had no media query at all, so below about 1000px the
 *     fixed 250px sidebar sat on top of content that had been pushed off the
 *     right of the screen. It was unusable on a phone or a narrow window.
 *   - colours are tokens, so the interface follows the operating system's
 *     light or dark setting instead of being white regardless.
 *
 * Layered under Bootstrap: tokens first, then the shell, then components.
 */

/* ----------------------------------------------------------------- tokens */

:root {
    color-scheme: light dark;

    /* Brand. Kept from the previous stylesheet so nothing shifts hue. */
    --primary-color: #2563eb;
    --primary-hover: #1d4ed8;
    --secondary-color: #64748b;
    --success-color: #10b981;
    --danger-color: #ef4444;
    --warning-color: #f59e0b;

    /* Surfaces and text. Two surface levels: the page, and things raised off
       it. A third is used only for hover and table stripes. */
    --surface: #ffffff;
    --surface-2: #f8fafc;
    --surface-3: #f1f5f9;
    --border: #e2e8f0;
    --border-strong: #cbd5e1;

    --text: #0f172a;
    --text-muted: #64748b;
    --text-faint: #94a3b8;

    /* One severity language for the whole product. A finding, a patch and an
       agent state all mean the same thing by "critical", so they should not be
       three different reds chosen page by page. */
    --sev-critical: #b91c1c;
    --sev-critical-bg: #fef2f2;
    --sev-high: #ea580c;
    --sev-high-bg: #fff7ed;
    --sev-medium: #ca8a04;
    --sev-medium-bg: #fefce8;
    --sev-low: #0891b2;
    --sev-low-bg: #ecfeff;
    --sev-info: #64748b;
    --sev-info-bg: #f8fafc;

    /* Text for running text, Display for headings: the pairing the family was
       drawn as. The fallbacks are the system faces, so the shape of the page is
       right before either webfont arrives and stays right if they never do. */
    --font-sans: 'Red Hat Text', -apple-system, BlinkMacSystemFont, 'Segoe UI',
                 Roboto, Oxygen, Ubuntu, sans-serif;
    --font-display: 'Red Hat Display', var(--font-sans);
    --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
                 'Liberation Mono', monospace;

    --radius: 10px;
    --radius-sm: 7px;
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06);
    --shadow: 0 1px 3px rgba(15, 23, 42, .08), 0 1px 2px rgba(15, 23, 42, .04);
    --shadow-lg: 0 10px 24px rgba(15, 23, 42, .10);

    --sidebar-width: 250px;
    --topbar-height: 56px;
}

/*
 * Dark mode follows the operating system unless the user has chosen. The
 * explicit choice is stamped on <html> as data-bs-theme, which is also what
 * Bootstrap 5.3 reads, so one attribute drives both.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) {
        --surface: #0f172a;
        --surface-2: #1e293b;
        --surface-3: #334155;
        --border: #334155;
        --border-strong: #475569;

        --text: #f1f5f9;
        --text-muted: #94a3b8;
        --text-faint: #64748b;

        --sev-critical: #f87171;
        --sev-critical-bg: #3f1414;
        --sev-high: #fb923c;
        --sev-high-bg: #3d2410;
        --sev-medium: #fbbf24;
        --sev-medium-bg: #3a2f0b;
        --sev-low: #22d3ee;
        --sev-low-bg: #0c2b33;
        --sev-info: #94a3b8;
        --sev-info-bg: #1e293b;

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
        --shadow: 0 1px 3px rgba(0, 0, 0, .5);
        --shadow-lg: 0 10px 24px rgba(0, 0, 0, .6);
    }
}

:root[data-bs-theme="dark"] {
    --surface: #0f172a;
    --surface-2: #1e293b;
    --surface-3: #334155;
    --border: #334155;
    --border-strong: #475569;

    --text: #f1f5f9;
    --text-muted: #94a3b8;
    --text-faint: #64748b;

    --sev-critical: #f87171;
    --sev-critical-bg: #3f1414;
    --sev-high: #fb923c;
    --sev-high-bg: #3d2410;
    --sev-medium: #fbbf24;
    --sev-medium-bg: #3a2f0b;
    --sev-low: #22d3ee;
    --sev-low-bg: #0c2b33;
    --sev-info: #94a3b8;
    --sev-info-bg: #1e293b;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 1px 3px rgba(0, 0, 0, .5);
    --shadow-lg: 0 10px 24px rgba(0, 0, 0, .6);
}

/* ------------------------------------------------------------------ base */

body {
    background-color: var(--surface-2);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: .9375rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--text);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -.01em;
}
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }
hr { border-color: var(--border); opacity: 1; }
a { color: var(--primary-color); }
a:hover { color: var(--primary-hover); }

/* Visible keyboard focus. Bootstrap's default is easy to lose against the
   pale surfaces used here. */
:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Screen-reader-only text that becomes visible when focused, for skip links. */
.visually-hidden-focusable:not(:focus):not(:focus-within) {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

/* ----------------------------------------------------------------- shell */

.sidebar {
    min-height: 100vh;
    background: var(--surface);
    border-right: 1px solid var(--border);
    position: fixed;
    top: 0;
    left: 0;
    width: var(--sidebar-width);
    padding-top: 20px;
    overflow-y: auto;
    z-index: 1040;
    transition: transform .2s ease;
}

/* Two element names for one thing: pages built on includes/header.php use
   .main-content, the fifteen older ones use <main>. Both are the page body
   beside the sidebar, so both are laid out here rather than in each page. */
.main-content,
body > main {
    margin-left: var(--sidebar-width);
    padding: 24px;
    background: var(--surface-2);
    min-height: 100vh;
}

/* The mobile bar. Hidden on desktop, where the sidebar is always present. */
.topbar {
    display: none;
    position: sticky;
    top: 0;
    z-index: 1030;
    height: var(--topbar-height);
    align-items: center;
    gap: .75rem;
    padding: 0 1rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, .5);
    z-index: 1035;
}

/*
 * Below 992px the sidebar slides away and is opened by the topbar button.
 * This is the media query the application never had.
 */
@media (max-width: 991.98px) {
    .sidebar {
        transform: translateX(-100%);
        box-shadow: var(--shadow-lg);
    }
    body.sidebar-open .sidebar { transform: translateX(0); }
    body.sidebar-open .sidebar-backdrop { display: block; }

    .main-content,
    body > main {
        margin-left: 0;
        padding: 16px;
    }
    .topbar { display: flex; }
}

/* Tables are the one thing that cannot reflow, so they scroll in place rather
   than forcing the whole page sideways. */
@media (max-width: 767.98px) {
    .table-responsive-always { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .stat-value { font-size: 2rem; }
    .main-content, body > main { padding: 12px; }
}

@media print {
    /* Paper is white whatever the screen was set to, so the tokens are pinned
       back to their light values rather than printing a dark page. */
    :root, :root[data-bs-theme="dark"] {
        --surface: #fff;
        --surface-2: #fff;
        --surface-3: #f1f5f9;
        --border: #cbd5e1;
        --text: #000;
        --text-muted: #333;
    }
    .sidebar, .topbar, .sidebar-backdrop, .no-print { display: none !important; }
    .main-content, body > main { margin-left: 0; padding: 0; }
    body { background: #fff; color: #000; }
    .card { box-shadow: none; }
}

/* --------------------------------------------------------------- sidebar */

.navbar-brand {
    font-weight: 600;
    color: var(--text) !important;
    display: flex;
    align-items: center;
    gap: .5rem;
}
.navbar-brand i { color: var(--primary-color); }

.sidebar .nav-link {
    color: var(--text-muted);
    padding: .55rem 1rem;
    border-radius: var(--radius-sm);
    margin: 2px 10px;
    font-size: .9rem;
    display: flex;
    align-items: center;
    gap: .6rem;
    transition: background-color .15s, color .15s;
}

.sidebar .nav-link:hover {
    background-color: var(--surface-3);
    color: var(--text);
}

/* The current page reads as selected rather than merely hovered. */
.sidebar .nav-link.active {
    background-color: var(--primary-color);
    color: #fff;
    font-weight: 500;
}
.sidebar .nav-link.active i { color: #fff; }

.sidebar-category { margin-top: .5rem; }

/*
 * A real <button>, so the section can be opened from the keyboard. It was a
 * <div> with a click handler, which nothing but a mouse could reach.
 */
.sidebar-category-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: calc(100% - 20px);
    margin: 0 10px;
    padding: .5rem 1rem;
    background: none;
    border: 0;
    color: var(--text-faint);
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    cursor: pointer;
    user-select: none;
    border-radius: var(--radius-sm);
    transition: background-color .15s, color .15s;
}
.sidebar-category-header:hover { background: var(--surface-3); color: var(--text-muted); }
.sidebar-category-header .bi-chevron-down { transition: transform .2s; font-size: .7rem; }
.sidebar-category-header.collapsed .bi-chevron-down { transform: rotate(-90deg); }
.sidebar-category-content { padding-left: .35rem; }

/* -------------------------------------------------------------- surfaces */

.card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

.card-header {
    background-color: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 14px 20px;
    font-weight: 600;
    color: var(--text);
}

.stat-card,
.stat-card-modern {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    box-shadow: var(--shadow-sm);
    height: 100%;
}

.stat-card h3,
.stat-value {
    font-size: 2rem;
    margin: 8px 0;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text);
}

.stat-card p,
.stat-label {
    color: var(--text-muted);
    margin: 0;
    font-size: .8125rem;
}

/*
 * Page heading. Pages titled themselves a dozen different ways, so the eye had
 * to relearn where it was on every screen.
 */
.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}
.page-header h1,
.page-header h2 { margin: 0; }
.page-header .page-subtitle {
    color: var(--text-muted);
    margin: .25rem 0 0;
    font-size: .875rem;
}

/* ------------------------------------------------------------- controls */

.btn-primary {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
}
.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--primary-hover);
    border-color: var(--primary-hover);
}

.form-control, .form-select {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--text);
}
.form-control:focus, .form-select:focus {
    background-color: var(--surface);
    color: var(--text);
    border-color: var(--primary-color);
    box-shadow: 0 0 0 .2rem rgba(37, 99, 235, .15);
}
.form-control::placeholder { color: var(--text-faint); }

/* ---------------------------------------------------------------- tables */

.table {
    --bs-table-bg: var(--surface);
    --bs-table-color: var(--text);
    --bs-table-border-color: var(--border);
    --bs-table-striped-bg: var(--surface-2);
    --bs-table-striped-color: var(--text);
    --bs-table-hover-bg: var(--surface-3);
    --bs-table-hover-color: var(--text);
}

.table > thead {
    background: var(--surface-2);
}
.table > thead th {
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

/* Numbers line up when they share a width, which matters on pages that are
   mostly counts. */
.tabular { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- severity */

.sev {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}
.sev::before {
    content: '';
    width: .45rem;
    height: .45rem;
    border-radius: 50%;
    background: currentColor;
}
.sev-critical { color: var(--sev-critical); background: var(--sev-critical-bg); }
.sev-high     { color: var(--sev-high);     background: var(--sev-high-bg); }
.sev-medium   { color: var(--sev-medium);   background: var(--sev-medium-bg); }
.sev-low      { color: var(--sev-low);      background: var(--sev-low-bg); }
.sev-info     { color: var(--sev-info);     background: var(--sev-info-bg); }

/* ---------------------------------------------------------- empty states */

/*
 * "No pending patches found" was rendered as a bare sentence, which reads the
 * same whether nothing needs doing or nothing was looked at. An empty state
 * should say which.
 */
.empty-state {
    text-align: center;
    padding: 3rem 1.5rem;
    color: var(--text-muted);
}
.empty-state .bi {
    font-size: 2.5rem;
    color: var(--text-faint);
    display: block;
    margin-bottom: .75rem;
}
.empty-state h3 {
    font-size: 1.05rem;
    color: var(--text);
    margin-bottom: .35rem;
}
.empty-state p { margin: 0 auto; max-width: 42ch; font-size: .875rem; }

/* --------------------------------------------------------------- badges */

.badge { font-weight: 600; }

.alert { border-radius: var(--radius); border-width: 1px; }

/* DataTables controls inherit the theme rather than staying light. */
.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
    background-color: var(--surface);
    color: var(--text);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: .25rem .5rem;
}
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter { color: var(--text-muted); font-size: .875rem; }

/* Respect a reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

/*
 * Chart containers.
 *
 * Chart.js sizes a responsive canvas to its parent when maintainAspectRatio is
 * false. If that parent's own height comes from its contents, the two define
 * each other and the canvas grows on every layout pass without settling, which
 * looks exactly like a chart that never finishes loading. A definite height
 * here is what breaks the cycle.
 */
.chart-canvas {
    position: relative;
    width: 100%;
}

@media (max-width: 575.98px) {
    /* Charts get shorter on a phone rather than eating the whole screen. */
    .chart-canvas { height: 220px !important; }
}

/* =========================================================================
   Refinement layer.
 *
 * The system below was still Bootstrap's defaults wearing this product's
 * colours. This is the part that makes it look considered: a typographic
 * scale instead of whatever size each heading happened to be, one spacing
 * rhythm, shadows that suggest a surface rather than draw a box, and tables
 * that read as data rather than as a grid.
 *
 * It also takes ownership of the components each page had been redefining.
 * .severity-critical was written out in seven files, .stat-card in nine, and
 * they had drifted: four different reds, three different corner radii, badges
 * that were pills on one page and rectangles on another.
 * ========================================================================= */

:root {
    /* One rhythm. Everything below is a multiple of these. */
    --space-1: .25rem;
    --space-2: .5rem;
    --space-3: .75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;

    /* Softer, layered elevation. A single hard shadow reads as a box; two
       offsets read as a surface lifted off the page. */
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 1px rgba(15, 23, 42, .03);
    --shadow:    0 1px 3px rgba(15, 23, 42, .05), 0 4px 12px rgba(15, 23, 42, .04);
    --shadow-lg: 0 2px 6px rgba(15, 23, 42, .06), 0 12px 32px rgba(15, 23, 42, .08);

    --radius-sm: 8px;
    --radius:    12px;
    --radius-lg: 16px;
}

:root[data-bs-theme="dark"] {
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow:    0 1px 3px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, .5), 0 12px 32px rgba(0, 0, 0, .45);
}
@media (prefers-color-scheme: dark) {
    :root:not([data-bs-theme="light"]) {
        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
        --shadow:    0 1px 3px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);
        --shadow-lg: 0 2px 6px rgba(0, 0, 0, .5), 0 12px 32px rgba(0, 0, 0, .45);
    }
}

/* ------------------------------------------------------------- typography */

body {
    font-size: .9375rem;
    line-height: 1.6;
    letter-spacing: -.005em;
}

h1, .h1 { font-size: 1.75rem; line-height: 1.25; letter-spacing: -.02em; }
h2, .h2 { font-size: 1.375rem; line-height: 1.3; letter-spacing: -.018em; }
h3, .h3 { font-size: 1.125rem; line-height: 1.35; letter-spacing: -.012em; }
h4, .h4 { font-size: 1rem; letter-spacing: -.01em; }
h5, .h5 { font-size: .9375rem; }
h6, .h6 { font-size: .875rem; }

/* Numbers that change should not make the layout twitch. */
.stat-value, .stat-card h3, .tabular, td.num, .table td.num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

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

/* ------------------------------------------------------------- page header */

.page-header { margin-bottom: var(--space-5); }
.page-header h1,
.page-header h2 { margin: 0; }
.page-header .page-subtitle {
    color: var(--text-muted);
    margin: var(--space-1) 0 0;
    font-size: .875rem;
}

/* Bare <h2> at the top of a page, which is how most pages title themselves. */
.main-content > .container-fluid > h2,
body > main > .container-fluid > h2 {
    margin-bottom: var(--space-5);
}

/* ----------------------------------------------------------------- cards */

.card,
.stat-card,
.stat-card-modern,
.chart-card,
.patch-card,
.group-card,
.pricing-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--border);
    padding: var(--space-4) var(--space-5);
    font-weight: 600;
    font-size: .9375rem;
    letter-spacing: -.01em;
}
.card-header h5,
.card-header h6 { font-size: .9375rem; margin: 0; font-weight: 600; }

.card-body { padding: var(--space-5); }

/* Coloured card headers were solid blocks of brand colour. Keeping the hue as
   a tint rather than a fill lets the content stay the loudest thing on screen. */
.card-header.bg-primary,
.card-header.bg-success,
.card-header.bg-warning,
.card-header.bg-danger,
.card-header.bg-info {
    background: var(--surface-2) !important;
    color: var(--text) !important;
    border-bottom: 1px solid var(--border);
}

/* ------------------------------------------------------------ stat cards */

.stat-card,
.stat-card-modern {
    padding: var(--space-5);
    height: 100%;
    /* Several pages added a 4px coloured left edge. It fought the severity
       colours elsewhere on the same screen, so it goes. */
    border-left-width: 1px;
}

.stat-card p,
.stat-label {
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    margin: 0 0 var(--space-2);
}

.stat-card h3,
.stat-value {
    font-size: 1.875rem;
    font-weight: 650;
    line-height: 1.1;
    letter-spacing: -.02em;
    margin: 0;
    color: var(--text);
}

.stat-card small,
.stat-delta {
    display: inline-block;
    margin-top: var(--space-2);
    font-size: .8125rem;
    color: var(--text-muted);
}

/* A hover that lifts the card by 4px and doubles its shadow is a lot of
   movement for something that is not clickable. */
.stat-card-modern:hover { transform: none; box-shadow: var(--shadow); }

/* --------------------------------------------------------------- tables */

.table {
    --bs-table-bg: transparent;
    margin-bottom: 0;
}

.table > thead th {
    background: transparent;
    color: var(--text-faint);
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.table > tbody td {
    padding: var(--space-4);
    border-bottom: 1px solid var(--border);
    border-top: 0;
    vertical-align: middle;
}

/* The last row's rule doubles up with the card edge. */
.table > tbody tr:last-child td { border-bottom: 0; }

.table-hover > tbody > tr:hover > * {
    background-color: var(--surface-2);
    --bs-table-accent-bg: var(--surface-2);
}

/* A table inside a card should meet its edges, not float in padding. */
.card-body > .table-responsive,
.card-body > .table { margin: calc(var(--space-5) * -1); width: auto; }
.card-body > .table-responsive > .table { margin: 0; }
.card-body > .table-responsive > .table > thead th:first-child,
.card-body > .table-responsive > .table > tbody td:first-child { padding-left: var(--space-5); }
.card-body > .table-responsive > .table > thead th:last-child,
.card-body > .table-responsive > .table > tbody td:last-child { padding-right: var(--space-5); }

/* ------------------------------------------------------------- severity */

/*
 * One severity language. These class names are used across seven pages as
 * <span class="severity-critical">CRITICAL</span>, where each page defined its
 * own solid-colour rectangle. A tinted pill with a coloured dot carries the
 * same information without four saturated blocks competing on one row.
 */
.sev,
.severity-critical, .severity-high, .severity-medium, .severity-low,
.severity-info, .severity-unknown, .severity-badge {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .125rem .5rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    text-transform: capitalize;
}

.sev::before,
.severity-critical::before, .severity-high::before, .severity-medium::before,
.severity-low::before, .severity-info::before, .severity-unknown::before {
    content: '';
    width: .375rem;
    height: .375rem;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.sev-critical, .severity-critical { color: var(--sev-critical); background: var(--sev-critical-bg); }
.sev-high,     .severity-high     { color: var(--sev-high);     background: var(--sev-high-bg); }
.sev-medium,   .severity-medium   { color: var(--sev-medium);   background: var(--sev-medium-bg); }
.sev-low,      .severity-low      { color: var(--sev-low);      background: var(--sev-low-bg); }
.sev-info,     .severity-info,
.severity-unknown                 { color: var(--sev-info);     background: var(--sev-info-bg); }

/* --------------------------------------------------------- status badges */

/*
 * Deployment target states. status-badge-not_applicable had no styling at all,
 * so a new outcome rendered as unstyled text next to styled siblings.
 */
.badge { font-weight: 600; font-size: .75rem; padding: .3em .6em; border-radius: 999px; }

.status-badge-success, .status-badge-completed, .status-badge-installed {
    color: var(--success-color); background: color-mix(in srgb, var(--success-color) 12%, transparent);
}
.status-badge-failed {
    color: var(--sev-critical); background: var(--sev-critical-bg);
}
.status-badge-in_progress, .status-badge-installing {
    color: var(--primary-color); background: color-mix(in srgb, var(--primary-color) 12%, transparent);
}
.status-badge-pending, .status-badge-scheduled {
    color: var(--text-muted); background: var(--surface-3);
}
.status-badge-not_applicable {
    color: var(--sev-low); background: var(--sev-low-bg);
}

/* ---------------------------------------------------------------- links */

.cve-link {
    color: var(--primary-color);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}
.cve-link:hover { text-decoration: underline; }

/* -------------------------------------------------------------- controls */

.btn {
    border-radius: var(--radius-sm);
    font-weight: 500;
    font-size: .875rem;
    padding: .4375rem .875rem;
}
.btn-sm { padding: .25rem .625rem; font-size: .8125rem; border-radius: 6px; }
.btn-lg { padding: .625rem 1.25rem; font-size: .9375rem; }

.btn-outline-secondary {
    border-color: var(--border-strong);
    color: var(--text-muted);
}
.btn-outline-secondary:hover {
    background: var(--surface-3);
    border-color: var(--border-strong);
    color: var(--text);
}

.form-control, .form-select {
    border-radius: var(--radius-sm);
    padding: .4375rem .75rem;
    font-size: .875rem;
}
.form-label { font-size: .875rem; font-weight: 500; margin-bottom: var(--space-2); }

.alert { border-radius: var(--radius); padding: var(--space-4) var(--space-5); font-size: .875rem; }

.pagination { --bs-pagination-border-radius: var(--radius-sm); }
.page-link { border-color: var(--border); color: var(--text-muted); font-size: .875rem; }
.page-item.active .page-link { background: var(--primary-color); border-color: var(--primary-color); }

/* ---------------------------------------------------------- patch cards */

.patch-card {
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s, background-color .15s;
}
.patch-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }
.patch-card.selected {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 5%, var(--surface));
    box-shadow: 0 0 0 1px var(--primary-color);
}

/* ------------------------------------------------------------- sidebar */

.sidebar { padding-top: var(--space-5); }
.sidebar .navbar-brand { font-size: 1.0625rem; padding: 0 var(--space-2) var(--space-5); }
.sidebar .nav-link { font-size: .875rem; padding: .5rem .75rem; margin: 1px var(--space-2); }
.sidebar-category-header { font-size: .6875rem; margin-top: var(--space-3); }

/* --------------------------------------------------------------- charts */

.chart-card { padding: var(--space-5); }
.chart-card .card-header {
    padding: 0 0 var(--space-4);
    border: 0;
    font-size: .9375rem;
}
.chart-card .card-body { padding: 0; }

/* Bootstrap declares its own font stack on form controls, buttons and tables,
   and the browser gives form elements a UA font regardless of what body says,
   so the family is set on them explicitly. Anything that inherits normally is
   left alone. */
body, .btn, .form-control, .form-select, .form-label, .table,
.card, .alert, .badge, .nav-link, .page-link, .dropdown-menu,
input, select, textarea, button, optgroup {
    font-family: var(--font-sans);
}

/*
 * Which face goes where.
 *
 * Display is for the things the eye lands on: headings, the big numbers on a
 * stat card, the product name. Everything that is read rather than scanned is
 * Text, which is drawn for it and holds up at 13px in a table where Display
 * starts to feel tight.
 *
 * With a proper text face carrying the body, the weights can come back down:
 * 400 reads correctly now rather than needing help.
 */
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
.stat-value, .stat-card h3, .navbar-brand, .page-header h1, .page-header h2 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -.02em;
}

body { font-weight: 400; }
.table > thead th { font-weight: 600; }
.btn { font-weight: 500; }

/* Card headers are labels rather than headlines; Text keeps them quiet. */
.card-header, .card-header h5, .card-header h6 {
    font-family: var(--font-sans);
    font-weight: 600;
    letter-spacing: -.005em;
}

code, pre, kbd, samp, .font-mono { font-family: var(--font-mono); }

/*
 * Filter cards.
 *
 * The severity cards on the findings page look like figures but behave like
 * filters, and the only sign that one was active was a Bootstrap border colour
 * that differed per card, so it read as decoration. One selected state, and a
 * cursor that says the card is a control.
 */
.filter-card {
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s, background-color .15s;
}
.filter-card:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow);
}
.filter-card.is-selected {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 5%, var(--surface));
    box-shadow: inset 0 0 0 1px var(--primary-color);
}
a:has(> .filter-card) { display: block; }

/* Plan price on the billing page. It carried an inline 3rem and a hardcoded
   near-black, which stayed black in dark mode. */
.plan-price {
    font-family: var(--font-display);
    font-size: 2.75rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    color: var(--text);
    margin: 1rem 0 .25rem;
}
.plan-price-unit { font-size: 1.25rem; color: var(--text-muted); font-weight: 500; }
.plan-price-equiv { font-size: .8125rem; color: var(--text-muted); font-weight: 400; }
