/* ============================================
   Network Optimizer - Main Stylesheet
   Modern, dark-mode friendly design
   ============================================ */

/* CSS Variables for theming - Ozark Connect Brand Colors */
:root {
    color-scheme: dark;

    /* Typography - Two font families only */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace;

    /* Brand Colors - Ozark Connect Blue + Orange */
    --primary-color: #0550B5;
    --primary-hover: #2E79C4;
    --accent-color: #E56B11;
    --accent-hover: #F08530;

    /* Signal quality - five grades, used by .signal-* and the dashboard gauges */
    --signal-excellent: #10b981;
    --signal-good: #22c55e;
    --signal-fair: #eab308;
    --signal-weak: #f97316;
    --signal-poor: #ef4444;

    /* Status Colors - refined for dark backgrounds */
    --success-color: #24bc70;
    --warning-color: #e79613;
    --danger-color: #ee6368;
    --info-color: #4797ff;
    --good-color: #3b82f6;
    /* What "look here" is drawn in: the nav-to-card ring and a card held called out. Its own name
       rather than borrowing a score color, so changing either cannot move the other. */
    --highlight-color: var(--primary-color);

    /* Purple/Violet - WiFi 6E, sponsorship */
    --purple-color: #a855f7;
    --purple-light: #c084fc;

    /* WiFi band palette - canonical across WiFi Optimizer, audit views, 3D map.
     * Use these instead of hardcoding #fbbf24 / #3b82f6 / #a855f7 inline. */
    --band-24-color: #fbbf24;
    --band-5-color:  #3b82f6;
    --band-6-color:  #a855f7;

    /* Dark Mode Backgrounds - neutral dark, Linear/Vercel inspired */
    --bg-primary: #0f0f11;
    --bg-inset: #131315;
    --bg-secondary: #161618;
    --bg-tertiary: #232326;
    --bg-elevated: #2c2c30;
    --bg-card: #161618;
    --bg-hover: #232326;
    --bg-hover-subtle: #1c1c1f;
    /* Hovering a row that is already expanded. One step above --bg-hover so the row still answers
       the mouse, without climbing to --bg-elevated and reading as a different surface. */
    --bg-row-expanded-hover: #27272b;
    --surface: #161618;
    --surface-secondary: #1c1c1f;

    /* Text Colors - neutral, no blue tint */
    --text-primary: #ededef;
    --text-secondary: #a0a0a8;
    --text-muted: #5c5c66;
    --text-dark: #171717;

    /* Blue accent variants for text/links */
    --primary-light: #60a5fa;
    --primary-lighter: #93c5fd;

    /* Map toolbar buttons */
    --btn-map-bg: var(--bg-elevated);
    --btn-map-hover: #35353a;

    /* Borders & Effects */
    --border-color: #232326;
    --border-radius: 4px;
    --border-radius-lg: 6px;
    --shadow: none;
    --shadow-lg: rgba(0, 0, 0, 0.4) 0px 4px 12px 0px;
    --focus-ring: 0 0 0 1px var(--primary-color);

    /* Layout */
    --sidebar-width: 260px;
    --topbar-height: 56px;
}

/* Global Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html, body {
    height: 100%;
    font-family: var(--font-sans);
    background: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    scroll-behavior: smooth;
}

/* Anchor Links - Ubiquiti Blue primary, Orange for hover emphasis */
a {
    color: var(--primary-color);
    text-decoration: none;
    transition: color 0.15s ease-out;
}

.page-description a,
.page-description a:visited {
    color: var(--primary-color);
}

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

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

.leaflet-container a.map-popup-link {
    color: var(--primary-hover);
}

.leaflet-container a.map-popup-link:hover {
    color: var(--accent-color);
    text-decoration: underline;
}

/* App Container Layout */
.app-container {
    display: flex;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

/* Sidebar */
.sidebar {
    width: var(--sidebar-width);
    background: var(--bg-secondary);
    border-right: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.sidebar-header {
    display: block;
    padding: 16px;
    border-bottom: 1px solid var(--border-color);
    text-align: center;
    text-decoration: none;
    color: inherit;
}

.sidebar-header:hover {
    text-decoration: none;
}

.sidebar-logo {
    max-width: 180px;
    height: auto;
}

.app-title {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--accent-color);
    margin: 0;
}

.app-subtitle {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin: 0.25rem 0 0 0;
}

/* Navigation Menu */
.nav-menu {
    flex: 1;
    padding: 1rem 0;
    display: flex;
    flex-direction: column;
}

.nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.nav-item {
    margin: 0.25rem 0;
}

.nav-link {
    display: flex;
    align-items: center;
    padding: 10px 16px 10px 11px;
    color: var(--text-secondary);
    text-decoration: none;
    transition: background-color 0.15s ease-out, color 0.15s ease-out;
    border-left: 2px solid transparent;
}

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

.agent-install .agent-flavor-note {
    margin-left: 0.4rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
}

.nav-link.active {
    background: var(--bg-tertiary);
    color: var(--accent-color);
    border-left-color: var(--accent-color);
}

.nav-icon {
    font-size: 1.25rem;
    margin-right: 0.75rem;
    width: 1.5rem;
    text-align: center;
    flex-shrink: 0;
}

.nav-icon-img {
    width: 2.5rem;
    height: 1.875rem;
    margin-right: 0.5rem;
    object-fit: contain;
    object-position: right;
    flex-shrink: 0;
}

.nav-text {
    font-weight: 500;
}

.card-title-icon {
    width: 1.75rem;
    height: 1.4rem;
    object-fit: contain;
    vertical-align: middle;
    margin-right: 0.45rem;
}

.nav-sub-item {
    padding-left: 1rem;
}

.nav-sub-icon {
    width: 1.5rem;
    margin-right: 0.5rem;
    text-align: right;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.nav-footer {
    margin-top: auto;
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--border-color);
}

.license-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--success-color);
    font-size: 0.875rem;
}

.license-icon {
    font-size: 1rem;
}

/* Main Content Area */
.main-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Top Bar */
.top-bar {
    height: var(--topbar-height);
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    padding: 0 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.status-indicators {
    display: flex;
    gap: 2rem;
}

.status-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.status-item.status-connected .status-icon {
    color: var(--success-color);
}

.status-icon {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.confirm-inline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.confirm-text {
    font-size: 0.875rem;
    color: var(--text-muted);
}

.timestamp {
    font-size: 0.875rem;
    color: var(--text-muted);
}

/* Page Content */
.page-content {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
}

.content {
    max-width: 1400px;
    margin: 0 auto;
}

/* Page Header */
.page-header {
    margin-bottom: 24px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 12px;
}

.page-header h1 {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    margin-bottom: 4px;
    display: flex;
    align-items: center;
}

/* Back button (PageBackButton). A tall strip down the header's left edge, with the title and
   description pushed over to make room; where the content column leaves a gutter, a square
   beside the title instead. */
:where(.page-header, .page-header > div):has(> .page-back-btn) {
    position: relative;
    padding-left: 44px;
}

.page-back-btn {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 32px;
    /* The title plus two lines of description; a longer description runs on past it */
    max-height: 88px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}

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

.page-back-btn svg {
    width: 18px;
    height: 18px;
}

.page-back-float {
    display: none;
}

/* Sidebar + the 1400px column + a gutter wide enough to hold the button. Here MainLayout's copy
   takes over: a zero-height sticky strip atop the column, so the button floats in the gutter
   while the page scrolls. It shows only on pages that carry a PageBackButton. */
@media (min-width: 1780px) {
    :where(.page-header, .page-header > div):has(> .page-back-btn) {
        padding-left: 0;
    }

    .page-header .page-back-btn {
        display: none;
    }

    .content:has(.page-header .page-back-btn) > .page-back-float {
        display: block;
        position: sticky;
        top: 0;
        height: 0;
        z-index: 10;
    }

    /* Centered on the title plus the description's first line (0 to 64.8px) */
    .page-back-float .page-back-btn {
        top: 14px;
        left: auto;
        right: calc(100% + 16px);
        bottom: auto;
        width: 36px;
        height: 36px;
        max-height: none;
    }
}

.page-header-suffix {
    margin-left: 0.75rem;
    font-size: 1.1rem;
    font-weight: 400;
    color: var(--text-muted);
}

h1:focus {
    outline: none;
}

.page-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.page-header-icon-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    color: var(--text-secondary);
    transition: color 0.15s ease, background 0.15s ease;
}

.page-header-icon-link:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
}

.page-header-icon-link svg {
    width: 20px;
    height: 20px;
}

.page-description {
    color: var(--text-secondary);
    font-size: 0.875rem;
    width: 100%;
}

.poll-error {
    font-size: 0.8rem;
    color: var(--danger-color);
}

.page-description-footnote {
    margin-top: 0.75rem;
    margin-left: 0.5rem;
}

.unstyled-link {
    color: inherit;
    text-decoration: none;
}

/* Cards */
.card {
    background: var(--bg-card);
    border: none;
    border-radius: var(--border-radius-lg);
    margin-bottom: 1rem;
    overflow: hidden;
}

.settings-container > .card,
.audit-container > .card {
    margin-bottom: 1.5rem;
}

.settings-tabbed > .card,
.settings-tabbed > .alert {
    display: none;
}

.settings-tabbed.active-connection > .settings-tab-connection,
.settings-tabbed.active-monitoring > .settings-tab-monitoring,
.settings-tabbed.active-aptelemetry > .settings-tab-aptelemetry,
.settings-tabbed.active-speedtests > .settings-tab-speedtests,
.settings-tabbed.active-security > .settings-tab-security,
.settings-tabbed.active-application > .settings-tab-application,
.settings-tabbed.active-identity > .settings-tab-identity,
.settings-tabbed.active-auditlog > .settings-tab-auditlog,
.settings-tabbed.active-multisite > .settings-tab-multisite {
    display: block;
}

.wan-live-chart-card {
    margin-bottom: 0;
    overflow: visible;
}
.wan-live-chart-card > .card-body {
    position: relative;
    padding: 0 0 0.3rem;
    margin-right: -0.75rem;
    overflow: visible;
}
.wan-live-chart-card .apexcharts-canvas {
    min-height: 0;
}
.wan-chart-seekable {
    position: relative;
}
.wan-chart-seekable.wan-chart-seek-hot {
    cursor: crosshair;
}
.wan-chart-mode-cluster {
    position: absolute;
    top: 0.5rem;
    right: 3.5rem;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.wan-chart-mode-cluster.is-comparing {
    right: 2.25rem;
}
@media (max-width: 768px) {
    .wan-chart-mode-cluster,
    .wan-chart-mode-cluster.is-comparing {
        right: 0;
    }
}
.wan-chart-mode-cluster .lan-flow-map-mode {
    cursor: pointer;
}
.dashboard-grid .lv-panel > .wan-live-chart-card {
    margin: -0.5rem;
}

.card-header {
    padding: 12px 16px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.card-header.history-card-header {
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
}

.header-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.monitoring-chart-header {
    min-height: 59px;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.monitoring-chart-header .chart-header-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-left: auto;
    justify-content: flex-end;
}

.isp-health-toolbar .wan-selector {
    margin-right: auto;
}

.monitoring-chart-header.chart-header-stacked .card-title {
    flex-basis: 100%;
}

@media (max-width: 768px) {
    .monitoring-chart-header.chart-header-stacked .wan-selector,
    .monitoring-chart-header .chart-header-controls {
        margin-left: 0;
        flex: 1 1 100%;
        justify-content: flex-start;
    }
}

.time-window-controls {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

@media (max-width: 768px) {
    .time-window-controls .time-btn[data-shift] {
        padding: 0.5rem;
    }
}

.wan-selector .wan-filter-reset {
    position: static;
    margin-left: 0.15rem;
}

.stats-name-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.stats-name-head .wan-filter-reset {
    position: static;
    padding: 0 0.15rem;
}

@media (max-width: 768px) {
    .monitoring-chart-header:has(.time-range-selector):has(.settings-link) {
        position: relative;
        padding-right: 2.75rem;
    }

    .monitoring-chart-header:has(.time-range-selector):has(.settings-link) .card-title {
        line-height: 24px;
    }

    .monitoring-chart-header:has(.time-range-selector):has(.settings-link) .settings-link {
        position: absolute;
        top: 4px;
        right: 0;
        margin: 0;
    }

}

.card-header-collapsible {
    cursor: pointer;
    user-select: none;
    transition: background 0.15s ease;
}

.card-header-collapsible:hover {
    background: var(--bg-tertiary);
}

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

.settings-title-link {
    display: inline-flex;
    align-items: center;
    color: var(--text-muted);
    transition: color 0.15s ease;
}

.settings-title-link:hover {
    color: var(--primary-color);
}

.speedtest-liveview-link {
    gap: 4px;
}

.card-header-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-left: auto;
}

.collapse-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    transition: transform 0.2s ease;
}

.collapse-chevron.expanded {
    transform: rotate(90deg);
}

.card-title-group {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.card-icon {
    width: 32px;
    height: 32px;
}

.card-title {
    font-size: 1.125rem;
    font-weight: 500;
    margin: 0;
}

.card-title-suffix {
    margin-left: 0.4rem;
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--text-muted);
}

@media (max-width: 412px) {
    .card-title {
        font-size: 1rem;
    }
}

@media (max-width: 382px) {
    .card-title {
        font-size: 0.95rem;
    }
}

.card-action {
    color: var(--accent-color);
    text-decoration: none;
    font-size: 0.875rem;
    font-weight: 500;
    transition: color 0.15s ease-out;
}

.card-action:hover {
    color: var(--accent-hover);
}

/* Clickable card title links */
.card-title-link {
    color: inherit;
    text-decoration: none;
    transition: color 0.15s ease;
}

.card-title-link:hover {
    color: var(--primary-color);
}

.card-title-link:hover .card-title {
    color: var(--primary-color);
}

.card-body {
    padding: 16px;
}

/* Info section text (How it Works, etc.) */
.info-section {
    font-size: 0.8125rem;
    line-height: 1.6;
}

.info-section p,
.info-section ol,
.info-section ul,
.info-section li {
    font-size: 0.8125rem;
}

.info-section ol,
.info-section ul {
    padding-left: 1.5rem;
    margin: 0.75rem 0;
}

.info-section li {
    margin-bottom: 0.5rem;
}

.card-span-2 {
    grid-column: span 2;
}

.card-full-width {
    width: 100%;
    margin-bottom: 1.5rem;
}

@media (max-width: 768px) {
    .card-full-width > .card-body {
        padding: 0;
    }

    .settings-container > .card,
    .audit-container > .card {
        margin-bottom: 1rem;
    }

    .dashboard-grid .lv-panel > .wan-live-chart-card {
        padding: 0;
        margin-left: 0;
        margin-right: 0;
    }

    .wan-live-chart-card > .card-body {
        margin-right: 0;
        padding-bottom: 0.2rem;
    }

    .card.wan-live-chart-card {
        padding: 0;
    }
}

/* Clickable card */
.clickable-card {
    cursor: pointer;
    transition: background 0.15s ease;
}

.clickable-card:hover {
    background: #1c1c1f;
}
.clickable-stat-card {
    cursor: pointer;
    transition: opacity 0.15s ease;
}
.clickable-stat-card:hover {
    opacity: 0.8;
}

/* Speed Test Stats (Dashboard panel) */
.speed-test-stats {
    display: flex;
    gap: 2rem;
    justify-content: center;
    margin-bottom: 1rem;
}

.speed-stat {
    text-align: center;
}

.speed-stat-value {
    font-size: 2rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1;
}

.speed-stat-unit {
    font-size: 0.875rem;
    color: var(--text-muted);
    margin-left: 0.25rem;
}

.speed-stat-label {
    display: block;
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-top: 0.25rem;
}

.speed-test-meta {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: var(--text-muted);
    border-top: 1px solid var(--border-color);
    padding-top: 0.75rem;
}

/* Speed Test List (Dashboard - multiple results) */
.speed-test-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.speed-test-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--border-color);
}

.speed-test-row:first-child {
    padding-top: 0;
}

.speed-test-row:last-child {
    border-bottom: none;
}

/* The Tailscale mark before a client name in speed test lists */
.client-tailscale-icon {
    margin-right: calc(0.3rem + 2px);
    vertical-align: middle;
    /* The mark's solid dots sit low in its box (its top row is faded), so a centered box reads low. */
    position: relative;
    top: -1.5px;
}

/* A client's UniFi Network icon (ClientIcon) */
.client-icon {
    display: inline-block;
    flex-shrink: 0;
    object-fit: contain;
    vertical-align: middle;
}

/* Before a client name in a table cell or a heading. vertical-align: middle centers on the
   x-height, which reads low beside capitalized names; 1.5px up matches the Tailscale mark. */
.client-icon-inline {
    margin-right: 0.4rem;
    position: relative;
    top: -1.5px;
}

/* The Tailscale mark in a speed test result row: padded to the 22px width of a client icon so names line up. */
.result-tailscale-icon {
    box-sizing: content-box;
    padding: 0 3px;
    margin-right: 0.4rem;
}

.speed-test-row .speed-test-device {
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 33%;
}

.speed-test-speeds {
    display: flex;
    gap: 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.875rem;
}

.speed-down {
    color: var(--speed-download-color);  /* blue - From Device */
}

.speed-up {
    color: var(--speed-upload-color);  /* green - To Device */
}

.speed-test-row .speed-test-time {
    font-size: 0.75rem;
    color: var(--text-muted);
    white-space: nowrap;
    margin-left: auto;
}

/* Stats Row */
.stats-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 16px;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 88px;
}

.stat-card.stat-success {
    border-left: 2px solid var(--success-color);
}

.stat-card.stat-warning {
    border-left: 2px solid var(--warning-color);
}

.stat-card.stat-danger {
    border-left: 2px solid var(--danger-color);
}

/* Clickable stat cards */
a.stat-card-link,
a.stat-card-link:link,
a.stat-card-link:visited {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

a.stat-card-link:hover {
    transform: translateY(-1px);
    background: var(--bg-hover);
}

a.stat-card-link:active {
    transform: translateY(0);
}

.stat-icon {
    width: 3rem;
    height: 3rem;
    font-size: 2.5rem;
    line-height: 1;
    opacity: 0.8;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.stat-icon svg {
    width: 3rem;
    height: 3rem;
}

.stat-icon-img {
    width: 3rem;
    height: 3rem;
    object-fit: contain;
    opacity: 0.9;
    flex-shrink: 0;
}

.stat-icon-img.stat-icon-sm {
    width: 2.5rem;
    height: 2.5rem;
}

.stat-content {
    flex: 1;
}

.stat-value {
    font-size: 2rem;
    font-weight: 600;
    line-height: 1;
    margin-bottom: 0.25rem;
}

.stat-value-text {
    font-size: 1.5rem;
    font-weight: 600;
}

.stat-value.cleanest-channels {
    font-size: 1.25rem;
}

.stat-label {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

/* Monitoring Stat Cards (shared between Monitoring page and Dashboard Live View) */
.monitoring-stat-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.monitoring-stat-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: 0.75rem 1rem;
    flex: 1 1 120px;
    min-width: 100px;
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.monitoring-stat-pair {
    display: flex;
    gap: 0.75rem;
    flex: 2 1 250px;
}
.monitoring-stat-pair .monitoring-stat-card {
    flex: 1 1 0;
    min-width: 0;
}
.monitoring-stat-card .stat-value {
    font-variant-numeric: tabular-nums;
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.2;
}
.monitoring-stat-card .stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}
.monitoring-stat-card .stat-value .stat-unit {
    margin-left: 0.25rem;
}
.monitoring-stat-card .stat-danger {
    color: var(--danger-color);
}
@media (min-width: 769px) and (max-width: 1200px) {
    .monitoring-stat-card {
        min-height: 99px;
    }
    .monitoring-stat-pair .monitoring-stat-card,
    .monitoring-stat-card.stat-card-no-minheight {
        min-height: auto;
    }
}
@media (max-width: 1024px) {
    .monitoring-stat-rate {
        min-height: 99px;
    }
}
@media (max-width: 768px) {
    .monitoring-stat-cards {
        gap: 0.5rem;
    }
    .monitoring-stat-card {
        flex: 1 1 80px;
        min-width: 70px;
        padding: 0.5rem 0.5rem;
    }
    .monitoring-stat-card .stat-value {
        font-size: 1rem;
    }
    .monitoring-stat-card .stat-value .stat-unit {
        font-size: 0.7em;
        margin-left: 0.15rem;
    }
    .monitoring-stat-pair {
        gap: 0.5rem;
        flex-basis: 170px;
    }
}

/* Responsive label helpers */
.mobile-label { display: none; }
.desktop-label { display: inline; }

@media (max-width: 768px) {
    .mobile-label { display: inline; }
    .desktop-label { display: none; }
}

/* Content Grid */
.content-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
}

/* Main dashboard cards - fixed height to prevent flash during load */
.content-grid > .card:first-child {
    min-height: 37vh;
}

/* Card stacking - two cards in one grid cell */
.card-stack {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.card-stack > .card:last-child {
    flex: 1;
}

.card-stack-even > .card {
    flex: 1;
}

/* Dashboard Grid */
.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px 16px;
}

.dashboard-grid .card,
.dashboard-grid .stats-row {
    margin-bottom: 0;
}

/* Dashboard card wrapper - stretch inner cards to match row height */
.dashboard-card-wrapper {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.dashboard-card-wrapper > .card,
.dashboard-card-wrapper > .card-stack {
    flex: 1;
}

.dashboard-grid .card-stack {
    gap: 16px;
}

/* Keeps the Active Alerts card's size when its last alert is dismissed */
#active-alerts .card-body {
    min-height: 180px;
}

@media (max-width: 768px) {
    #active-alerts .card-body {
        min-height: 172px;
    }
}

.dashboard-card-wrapper.card-span-2 {
    grid-column: span 2;
}

.dashboard-card-wrapper.card-span-2 > .card-stack {
    flex-direction: row;
}

.dashboard-card-wrapper.card-span-2 > .card-stack > .card {
    flex: 1;
    min-width: 0;
}

.dashboard-card-hidden {
    opacity: 0.4;
}

.add-card-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    border: 2px dashed var(--border-color);
    background: transparent;
    cursor: pointer;
    color: var(--text-muted);
    transition: border-color 0.15s, color 0.15s;
}

.add-card-placeholder:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.edit-bottom-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 4px 0;
}

.dashboard-card-editing {
    position: relative;
}

/* Card edit toolbar */
.card-edit-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
    border: 1px dashed var(--border-color);
    border-bottom: none;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.card-edit-toolbar + .card,
.card-edit-toolbar + .card-stack,
.card-edit-toolbar + .stats-row {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.card-edit-label {
    font-weight: 500;
    color: var(--text-primary);
}

.card-edit-actions {
    display: flex;
    align-items: center;
    gap: 4px;
}

.card-edit-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.card-edit-btn:hover:not(:disabled) {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.card-edit-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.card-edit-btn-toggle {
    margin-left: 4px;
}

/* Stat item editing */
.stat-item-wrapper {
    position: relative;
    display: contents;
}

.stat-item-editing {
    display: block;
    position: relative;
}

.stat-edit-actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    position: absolute;
    top: -2px;
    left: 50%;
    transform: translate(-50%, -100%);
    z-index: 5;
    padding: 2px 6px;
    background: var(--bg-tertiary);
    border-radius: 4px;
    border: 1px solid var(--border-color);
    white-space: nowrap;
}

.stat-edit-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 18px;
    border: none;
    border-radius: 3px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.stat-edit-btn:hover:not(:disabled) {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.stat-edit-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.stat-edit-btn-remove:hover {
    color: var(--danger-color);
}

/* Add stat button area */
.stat-add-wrapper {
    display: flex;
    align-items: stretch;
}

.stat-add-dropdown {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    background: var(--bg-card);
    border: 1px dashed var(--border-color);
    border-radius: var(--border-radius-lg);
    min-width: 160px;
}

.stat-add-btn {
    padding: 6px 10px;
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    color: var(--text-secondary);
    font-size: 0.8rem;
    cursor: pointer;
    text-align: left;
    transition: background 0.15s, color 0.15s;
}

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

/* Stats row editing mode */
.stats-row-editing {
    border: 1px dashed var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 30px 8px 8px;
    background: rgba(255, 255, 255, 0.02);
}

/* Hidden cards divider in edit mode */
.hidden-cards-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.hidden-cards-divider::before,
.hidden-cards-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border-color);
}

.dashboard-card-stacked {
    opacity: 0.5;
}

.stacked-in-label {
    font-weight: 400;
    color: var(--text-muted);
    font-style: italic;
}

/* Edit mode toast notification */
.edit-toast {
    padding: 10px 16px;
    background: rgba(71, 151, 255, 0.12);
    border: 1px solid rgba(71, 151, 255, 0.3);
    border-radius: var(--border-radius-lg);
    color: var(--info-color);
    font-size: 0.85rem;
    margin-bottom: 16px;
    animation: toast-fade-in 0.2s ease;
}

@keyframes toast-fade-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Stacked child toolbar (shown between cards in a stack during edit mode) */
.stacked-child-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 10px;
    background: var(--bg-tertiary);
    border-top: 1px dashed var(--border-color);
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.stacked-child-toolbar .card-edit-label {
    font-weight: 500;
    color: var(--text-primary);
}

/* Stack-add bar below cards in edit mode */
.stack-add-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 6px;
    border: 1px dashed var(--border-color);
    border-top: none;
    border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
    background: rgba(255, 255, 255, 0.02);
}

.stack-add-bar .stat-add-btn {
    font-size: 0.75rem;
    padding: 4px 8px;
}

/* Wi-Fi Optimizer card */
.wifi-issues-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    justify-content: flex-start;
}

.wifi-issue-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    font-size: 0.85rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.wifi-issue-row:last-child {
    border-bottom: none;
}

.wifi-issue-severity {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 3px;
    white-space: nowrap;
    flex-shrink: 0;
}

.wifi-severity-critical {
    background: rgba(239, 68, 68, 0.15);
    color: #ef4444;
}

.wifi-severity-warning {
    background: rgba(234, 179, 8, 0.15);
    color: #eab308;
}

.wifi-severity-info {
    background: rgba(71, 151, 255, 0.15);
    color: #4797ff;
}

.wifi-issue-title {
    flex: 1;
    color: var(--text-primary);
}

.wifi-issue-entity {
    color: var(--text-muted);
    font-size: 0.8rem;
    white-space: nowrap;
}

.wifi-issue-icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    background: transparent;
    padding: 0;
}

.wifi-issue-icon svg {
    display: block;
}

.wifi-issue-group {
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.wifi-issue-group:last-child {
    border-bottom: none;
}

.wifi-issue-group-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    font-size: 0.85rem;
    cursor: pointer;
    user-select: none;
}

.wifi-issue-group-header:hover {
    background: var(--bg-hover);
    border-radius: 4px;
}

.group-count-badge {
    font-size: 0.7rem;
    font-weight: 600;
    min-width: 1.25rem;
    height: 1.25rem;
    line-height: 1.25rem;
    text-align: center;
    border-radius: 9999px;
    flex-shrink: 0;
    padding-top: 0.02rem;
}

.wifi-issue-chevron {
    color: var(--text-muted);
    font-size: 0.65rem;
    margin-left: auto;
}

.dashboard-grid .wifi-issue-group-header {
    gap: 0.75rem;
}

.dashboard-grid .wifi-issue-row {
    flex-wrap: wrap;
}

.dashboard-grid .wifi-issue-entity {
    white-space: normal;
}

@media (max-width: 768px) {
    .dashboard-grid .wifi-issue-group-header {
        gap: 8px;
    }
}

.dashboard-grid .wifi-issue-item {
    display: block;
    padding: 6px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    background: none;
    border-left: none;
    border-radius: 0;
    gap: 0;
}

.dashboard-grid .wifi-issue-item:last-child {
    border-bottom: none;
}

.dashboard-grid .wifi-issue-item .wifi-issue-row {
    padding: 0;
    border-bottom: none;
}

.wifi-issue-description {
    font-size: 0.8rem;
    color: var(--text-secondary);
    padding-left: 0.5rem;
    margin-top: 2px;
    line-height: 1.3;
}

.wifi-issue-nested {
    padding: 6px 0 6px 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.03);
}

.wifi-issue-nested:last-child {
    border-bottom: none;
}

.wifi-issue-nested-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.device-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 12px;
}

/* Device Card */
.device-card {
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    padding: 12px;
    border-left: 2px solid var(--border-color);
}

.device-card.device-online {
    border-left-color: var(--success-color);
}

.device-card.device-offline {
    border-left-color: var(--danger-color);
}

.device-card.device-provisioning {
    border-left-color: var(--warning-color);
}

.device-card.device-error {
    border-left-color: var(--danger-color);
}

.device-header,
.ap-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.75rem;
}

.device-header {
    margin-left: -0.2rem;
}

.ap-header {
    margin-left: -0.3rem;
}

.device-icon {
    font-size: 1.5rem;
}

.device-info {
    flex: 1;
}

.device-name {
    font-size: 0.85rem;
    font-weight: 600;
    margin: 0;
}

.device-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.125rem;
}

.device-type {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.device-status {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
}

.status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--text-muted);
}

.status-dot.online {
    background: var(--success-color);
}

.status-dot.offline {
    background: var(--text-muted);
}

.status-dot.provisioning {
    background: #fbbf24;
    animation: pulse-yellow 2s infinite;
}

.status-dot.error {
    background: var(--danger-color);
}

.device-body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.device-detail {
    display: flex;
    justify-content: space-between;
    font-size: 0.8125rem;
}

.detail-label {
    color: var(--text-secondary);
}

.detail-value {
    color: var(--text-primary);
    font-weight: 500;
}

/* Security Score Gauge */
.security-score-gauge {
    text-align: center;
    padding: 0 1rem 1rem;
}

.gauge-container {
    max-width: 300px;
    margin: -0.5rem auto 0;
}

.gauge-svg {
    width: 100%;
    height: auto;
}

.gauge-rating {
    margin-top: 0.5rem;
}

.rating-badge {
    display: inline-block;
    padding: 0.5rem 1.5rem;
    border-radius: 2rem;
    font-weight: 600;
    font-size: 0.875rem;
}

.rating-badge.rating-excellent {
    background: var(--success-color);
    color: white;
}

.rating-badge.rating-good {
    background: var(--primary-color);
    color: white;
}

.rating-badge.rating-fair {
    background: var(--warning-color);
    color: white;
}

.rating-badge.rating-poor {
    background: var(--danger-color);
    color: white;
}

.rating-badge.rating-none {
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}

.security-summary {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.summary-item {
    display: flex;
    justify-content: space-between;
    font-size: 0.875rem;
}

.summary-label {
    color: var(--text-secondary);
}

.summary-value {
    font-weight: 600;
    min-height: 1.25rem;
    display: inline-flex;
    align-items: center;
}

.summary-value.critical {
    color: var(--danger-color);
}

.summary-value.warning,
.summary-value.recommended {
    color: var(--warning-color);
}

/* SQM Status Panel */
.sqm-status-panel {
    /* Styles handled in component */
}

.sqm-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.cellular-stats-panel .sqm-header {
    margin-bottom: 0;
}

.cellular-stats-panel .sqm-actions {
    margin-top: 0.5rem;
}

.sqm-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.status-indicator {
    width: 12px;
    min-width: 12px;
    height: 12px;
    border-radius: 50%;
}

.status-indicator.status-active {
    background: var(--success-color);
}

.status-indicator.status-inactive {
    background: var(--text-muted);
}

.status-indicator.status-danger {
    background: var(--danger-color);
}

.status-indicator.status-warning {
    background: var(--warning-color);
}

.learning-badge {
    background: var(--info-color);
    color: white;
    padding: 0.25rem 0.75rem;
    border-radius: var(--border-radius-lg);
    font-size: 0.75rem;
    font-weight: 600;
}

.metric-icon {
    font-size: 1.5rem;
}

.metric-content {
    flex: 1;
}

.metric-value {
    font-size: 1.3rem;
    font-weight: 600;
    line-height: 1;
    margin-bottom: 0.25rem;
}

.metric-value .unit {
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--text-secondary);
}

.metric-label {
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-bottom: 0.25rem;
}

.metric-baseline {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.metric-baseline.latency-good {
    color: var(--success-color);
}

.metric-baseline.latency-fair {
    color: var(--warning-color);
}

.metric-baseline.latency-poor {
    color: var(--danger-color);
}

@media (max-width: 768px) {
    .metric-value {
        font-size: 1.2rem;
    }
}

/* Shared stats panel styles (ONT, Cable Modem, Cellular) */

.signal-quality-section {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: 8px;
}

.ont-rx-gauge {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    flex: 1;
}

.ont-rx-gauge .rx-power-value {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.2;
}

.ont-rx-gauge .rx-power-label {
    font-size: 0.85rem;
    color: var(--text-muted);
}

.modem-nav {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.signal-hero {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-left: 0.6rem;
}

/* Scoped: Client Performance declares its own .signal-gauge for a dBm readout, and this
   rule must never size that box. */
.signal-with-model .signal-gauge {
    width: 14px;
    height: 52px;
    border-radius: 7px;
    position: relative;
    flex: none;
    overflow: hidden;
}

.signal-gauge .gauge-shade {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    background: var(--bg-card);
    opacity: 0.8;
}

.signal-gauge .gauge-shade-low {
    top: auto;
    bottom: 0;
}

.signal-with-model .ont-rx-gauge {
    align-items: flex-start;
    flex: initial;
}

.cm-model {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.25rem;
    text-align: right;
    margin-right: 0.4rem;
    min-width: 0;
}

.cm-model-name {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.cm-model-number {
    font-size: 0.75rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

/* Signal hero sparklines (SignalSparkline.razor). signal-spark.js sets the --spark-* geometry
   to the hero's gauge or bar stack, and the data-spark-* attributes; at rest the last 24 hours
   sit faintly behind the text. On hover the model fades, the gauge and its value slide right
   together, and the chart comes up to full strength on the gauge's own scale, ending level with
   the gauge's reading. Pointing at the model itself keeps it (and its tooltip) in place. */
.signal-spark-host {
    position: relative;
    isolation: isolate;
}

/* A halo in the card's own background behind the text: a line crossing the letters breaks up
   their shapes, which reads as faded text even at full color. --spark-halo is the host's background. */
.signal-spark-host {
    --spark-halo: var(--bg-tertiary);
}

.monitoring-stat-card.signal-spark-host {
    --spark-halo: var(--bg-card);
}

/* Muted labels a shade brighter where a chart sits behind them, so the eye still finds them.
   Context selectors outrank the component style blocks (ClientDashboard-style, loaded after
   app.css) that set these labels to --text-muted. */
.signal-spark-host .ont-rx-gauge .rx-power-label,
.signal-spark-host .signal-quality-text .quality-label,
.signal-spark-host .cm-model .cm-model-number,
.monitoring-stat-card.signal-spark-host .stat-label,
.metric-box.signal-spark-host .metric-row .metric-label,
.signal-spark-host .signal-spark .signal-spark-span {
    color: color-mix(in srgb, var(--text-muted) 55%, var(--text-secondary));
}

.signal-spark-host > :not(.signal-spark) {
    position: relative;
    z-index: 1;
    /* Stacked: one soft shadow is mostly transparent and leaves the line showing through. */
    text-shadow:
        0 0 1px var(--spark-halo), 0 0 1px var(--spark-halo), 0 0 2px var(--spark-halo),
        0 0 2px var(--spark-halo), 0 0 3px var(--spark-halo), 0 0 3px var(--spark-halo),
        0 0 4px var(--spark-halo), 0 0 6px var(--spark-halo);
}

.signal-spark,
.signal-spark-host > .signal-spark-wash {
    position: absolute;
    z-index: 0;
    top: var(--spark-top, 0);
    left: var(--spark-left, 0);
    width: var(--spark-width, 0);
    height: var(--spark-height, 0);
    pointer-events: none;
    opacity: 0;
}

.signal-spark-host > .signal-spark-wash {
    z-index: 2;
    text-shadow: none;
}

[data-spark-ready] > .signal-spark,
[data-spark-ready] > .signal-spark-wash {
    opacity: 0.28;
}

.signal-spark-svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.signal-spark-line {
    fill: none;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.signal-spark-area {
    opacity: 0.32;
}

.signal-spark-level {
    position: absolute;
    left: 0;
    height: 0;
    border-top: 1px dashed color-mix(in srgb, var(--text-secondary) 45%, transparent);
    transform: translateY(-0.5px) scaleX(0);
    transform-origin: left center;
    opacity: 0;
}

/* The held end of the line, thickening into the gauge's lit window, fill, or first bar. Its
   shape (clip-path) and fill come from SignalSparkline; it covers the line's last stretch. */
/* right: -2px runs it under the first bar's 2px corner radius; on a gauge the overlap is the
   gauge's own gradient, so it does not show. It reaches 16px past the chart top and bottom
   (SparklinePath.TaperPad), since a reading at a scale end thickens past the chart's box; the
   fill is sized to the chart itself, so a gauge gradient stays on the gauge's scale. */
.signal-spark-taper {
    position: absolute;
    top: -16px;
    bottom: -16px;
    right: -2px;
    background: var(--taper-fill) no-repeat 0 16px / 100% calc(100% - 32px);
    opacity: 0;
    transform: scaleY(0.1);
}

.signal-spark-dot {
    position: absolute;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 2px var(--bg-tertiary), 0 0 12px currentColor;
    transform: translate(-50%, -50%) scale(0.4);
    opacity: 0;
}

.signal-spark-dot::after {
    content: "";
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 1.5px solid currentColor;
    opacity: 0;
}


/* Square in the box's bottom-left corner: the chart starts on the box's left padding, and
   --spark-floor is the gap from the chart down to the box's bottom. */
.signal-spark-span {
    position: absolute;
    left: 0;
    bottom: calc(0.75rem - var(--spark-floor, 0px));
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
    color: var(--text-muted);
    opacity: 0;
    transform: translateY(3px);
}

/* The 5G NR / LTE boxes: the chart covers the rows, which step aside on hover for it and a
   live RSRP readout in the box's top right. */
.signal-spark-host > .spark-box-readout {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    font-family: monospace;
    font-size: 0.85rem;
    font-weight: 600;
    opacity: 0;
    transform: translateX(8px);
    pointer-events: none;
}

.spark-box-readout-label {
    font-family: var(--font-sans);
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--text-muted);
}

.metric-box .signal-spark-span {
    display: none;
}

/* Live View's gateway tiles (StatTileSparkline): the chart takes the lower strip of the tile. On
   hover the label steps aside and the value lifts clear of the line. */
.signal-spark-host > .stat-spark-area {
    position: absolute;
    left: 0.1rem;
    right: 0.3rem;
    bottom: 0.55rem;
    height: 42%;
    pointer-events: none;
}

/* Narrow tiles give the line nearly every pixel: from the left edge, with a hair on the right
   so the end dot clears the border. */
@media (max-width: 768px) {
    .signal-spark-host > .stat-spark-area {
        left: 0;
        right: 0.2rem;
    }
}

/* On a tile the span caption sits in the tile's upper-left corner, out of the chart strip:
   --spark-top/--spark-left place the strip within the tile, so subtracting them lands on the tile. */
.monitoring-stat-card.signal-spark-host .signal-spark-span {
    top: calc(0.5rem - var(--spark-top, 0px));
    bottom: auto;
    left: calc(0.6rem - var(--spark-left, 0px));
}

@media (hover: hover) and (pointer: fine) {
    .monitoring-stat-card.signal-spark-host[data-spark-roomy]:hover .stat-label {
        opacity: 0;
        transform: translateY(6px);
    }

    .monitoring-stat-card.signal-spark-host[data-spark-roomy]:hover .stat-value {
        transform: translateY(-9px);
    }
}

@media (prefers-reduced-motion: no-preference) {
    .monitoring-stat-card.signal-spark-host .stat-label,
    .monitoring-stat-card.signal-spark-host .stat-value {
        transition: opacity 0.25s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
    }
}

@media (hover: hover) and (pointer: fine) {
    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) > .signal-spark,
    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) > .signal-spark-wash {
        opacity: 1;
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) [data-spark-value] {
        transform: translateX(var(--spark-shift, 0));
    }

    /* Only while the chart is forward does its end thicken into the gauge. */
    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-taper {
        opacity: 1;
        transform: none;
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) [data-spark-anchor="root"] {
        transform: translateY(var(--spark-lift, 0));
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) [data-spark-model] {
        opacity: 0;
        transform: translateX(14px) scale(0.96);
        filter: blur(6px);
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-svg {
        filter: drop-shadow(0 0 6px color-mix(in srgb, var(--spark-glow, var(--signal-good)) 45%, transparent));
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-level {
        opacity: 1;
        transform: translateY(-0.5px) scaleX(1);
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-dot {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1);
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-span {
        opacity: 1;
        transform: none;
    }

    .signal-spark-host[data-spark-roomy]:hover [data-spark-fill] {
        opacity: 0;
        transform: translateY(4px);
        filter: blur(4px);
    }

    .signal-spark-host[data-spark-roomy]:hover > .spark-box-readout {
        opacity: 1;
        transform: none;
    }
}

.signal-spark.signal-excellent { --spark-glow: var(--signal-excellent); }
.signal-spark.signal-good { --spark-glow: var(--signal-good); }
.signal-spark.signal-fair { --spark-glow: var(--signal-fair); }
.signal-spark.signal-weak { --spark-glow: var(--signal-weak); }
.signal-spark.signal-poor { --spark-glow: var(--signal-poor); }

/* Motion only where it is welcome; without it the same states swap in place. */
@media (prefers-reduced-motion: no-preference) {
    [data-spark-ready] > .signal-spark,
    [data-spark-ready] > .signal-spark-wash {
        transition: opacity 0.45s ease;
    }

    .signal-spark-host [data-spark-fill] {
        transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), filter 0.3s ease;
    }

    .signal-spark-host > .spark-box-readout {
        transition: opacity 0.2s ease, transform 0.2s ease;
    }

    .signal-spark-host:hover > .spark-box-readout {
        transition: opacity 0.35s ease 0.15s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.15s;
    }

    [data-spark-ready] .signal-spark-svg {
        animation: signal-spark-reveal 1.2s cubic-bezier(0.65, 0, 0.35, 1) backwards;
        transition: filter 0.45s ease;
    }

    /* Out: the taper collapses first. In: it swells while the gauge slides in (0.62s) and is
       full before the gauge lands, so the two arrive together. */
    .signal-spark-taper {
        transition: opacity 0.15s ease, transform 0.2s ease;
    }

    .signal-spark-host:hover:not(:has([data-spark-model]:hover)) .signal-spark-taper {
        transition: opacity 0.15s ease 0.12s, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.12s;
    }

    /* Cellular: the bars rise or drop as they slide, landing with their root on the line's end. */
    .signal-spark-host [data-spark-anchor="root"] {
        transition: transform 0.62s cubic-bezier(0.22, 1, 0.36, 1);
    }

    .signal-spark-host [data-spark-value] {
        transition: transform 0.62s cubic-bezier(0.22, 1, 0.36, 1);
        will-change: transform;
    }

    /* Out: the model waits for the value to clear its spot. In: it leaves at once. */
    .signal-spark-host [data-spark-model] {
        transition: opacity 0.34s ease 0.18s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.14s, filter 0.34s ease 0.18s;
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) [data-spark-model] {
        transition: opacity 0.2s ease, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), filter 0.2s ease;
    }

    .signal-spark-level {
        transition: transform 0.2s ease, opacity 0.2s ease;
    }

    .signal-spark-host:hover:not(:has([data-spark-model]:hover)) .signal-spark-level {
        transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.12s, opacity 0.3s ease 0.12s;
    }

    .signal-spark-dot {
        transition: transform 0.3s ease, opacity 0.2s ease;
    }

    .signal-spark-host:hover:not(:has([data-spark-model]:hover)) .signal-spark-dot {
        transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.42s, opacity 0.25s ease 0.42s;
    }

    .signal-spark-host[data-spark-roomy]:hover:not(:has([data-spark-model]:hover)) .signal-spark-dot::after {
        animation: signal-spark-ping 2s cubic-bezier(0, 0, 0.2, 1) 0.9s infinite;
    }

    .signal-spark-span {
        transition: opacity 0.2s ease, transform 0.2s ease;
    }

    .signal-spark-host:hover:not(:has([data-spark-model]:hover)) .signal-spark-span {
        transition: opacity 0.35s ease 0.3s, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.3s;
    }
}

/* Overdrawn vertically so the stroke and glow at the box edges are never cut mid-reveal;
   the fill mode is backwards, so no clip is left on the chart once it has drawn. */
@keyframes signal-spark-reveal {
    from { clip-path: inset(-50% 100% -50% -10%); }
    to { clip-path: inset(-50% -10% -50% -10%); }
}

@keyframes signal-spark-ping {
    0% { transform: scale(0.5); opacity: 0.7; }
    75%, 100% { transform: scale(1.9); opacity: 0; }
}

/* Channel Spectrum (CM Stats): the latest poll's channels by frequency. Axis and grid colors
   match the ApexCharts charts above it. Grade classes are cmsp-* because .grade-* is global. */
.cm-spectrum-card {
    margin-bottom: 1rem;
}

.cm-spectrum-header {
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
}

.cm-spectrum-asof {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.cm-spectrum-asof.not-window {
    color: var(--text-secondary);
}

.cm-spectrum-asof.stale {
    color: var(--warning-color);
}

.cm-spectrum-panels {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 1.5rem;
    padding: 0.75rem 1rem 1rem;
}

.cm-spectrum-panel {
    min-width: 0;
}

.cm-spectrum-panel-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.6rem;
    margin-bottom: 0.5rem;
}

.cm-spectrum-panel-title {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-primary);
}

.cm-spectrum-count {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.cm-spectrum-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.9rem;
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.cm-spectrum-fact-value {
    color: var(--text-primary);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.cm-spectrum-plot {
    width: 100%;
    min-height: 150px;
}

.cm-spectrum-svg {
    display: block;
    overflow: visible;
}

.cm-spectrum-grid {
    stroke: #374151;
    stroke-dasharray: 3;
}

.cm-spectrum-grid.zero {
    stroke: #4b5563;
    stroke-dasharray: none;
}

.cm-spectrum-axis {
    stroke: #374151;
}

.cm-spectrum-divider {
    stroke: #374151;
    stroke-dasharray: 2 3;
}

.cm-spectrum-tick,
.cm-spectrum-lane-label,
.cm-spectrum-limit-label {
    fill: #9ca3af;
    font-family: var(--font-sans);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.cm-spectrum-lane-label {
    fill: var(--text-muted);
    font-size: 9px;
    letter-spacing: 0.04em;
}

.cm-spectrum-limit-label {
    fill: var(--danger-color);
    font-size: 10px;
}

.cm-spectrum-limit {
    stroke: var(--danger-color);
    stroke-dasharray: 4 3;
    opacity: 0.8;
}

.cm-spectrum-range {
    fill: color-mix(in srgb, var(--success-color) 7%, transparent);
}

.cm-spectrum-empty {
    fill: var(--text-muted);
    font-size: 12px;
}

.cm-spectrum-bar {
    opacity: 0.88;
    stroke-width: 0;
    transition: opacity 0.12s;
}

.cm-spectrum-bar.cmsp-excellent { fill: var(--signal-excellent); stroke: var(--signal-excellent); }
.cm-spectrum-bar.cmsp-good { fill: var(--signal-good); stroke: var(--signal-good); }
.cm-spectrum-bar.cmsp-fair { fill: var(--signal-fair); stroke: var(--signal-fair); }
.cm-spectrum-bar.cmsp-poor { fill: var(--signal-poor); stroke: var(--signal-poor); }
.cm-spectrum-bar.cmsp-none { fill: var(--text-muted); stroke: var(--text-muted); }

/* OFDM spans many subcarriers, so it reads as a lighter block rather than one more bar. */
.cm-spectrum-bar.ofdm {
    fill-opacity: 0.45;
    stroke-width: 1.5;
}

.cm-spectrum-bar.unlocked {
    fill: none;
    stroke: var(--text-muted);
    stroke-width: 1;
    stroke-dasharray: 2 2;
}

.cm-spectrum-fec {
    fill: var(--danger-color);
}

.cm-spectrum-hit {
    fill: transparent;
    cursor: pointer;
}

.cm-spectrum-channel:hover .cm-spectrum-hit {
    fill: rgba(255, 255, 255, 0.04);
}

.cm-spectrum-channel:hover .cm-spectrum-bar {
    opacity: 1;
}

.cm-spectrum-channel:hover .cm-spectrum-bar:not(.unlocked):not(.ofdm) {
    stroke: var(--text-primary);
    stroke-width: 1;
}

.cm-spectrum-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.8rem;
    margin-top: 0.4rem;
    font-size: 0.72rem;
    color: var(--text-secondary);
}

.cm-spectrum-key-label {
    color: var(--text-muted);
}

.cm-spectrum-key {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}

.cm-spectrum-swatch {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 2px;
}

.cm-spectrum-swatch.cmsp-excellent { background: var(--signal-excellent); }
.cm-spectrum-swatch.cmsp-good { background: var(--signal-good); }
.cm-spectrum-swatch.cmsp-fair { background: var(--signal-fair); }
.cm-spectrum-swatch.cmsp-poor { background: var(--signal-poor); }

.cm-spectrum-swatch.range {
    background: color-mix(in srgb, var(--success-color) 18%, transparent);
    border: 1px solid color-mix(in srgb, var(--success-color) 35%, transparent);
}

.cm-spectrum-swatch.fec {
    height: 6px;
    background: var(--danger-color);
}

.cm-spectrum-swatch.unlocked {
    border: 1px dashed var(--text-muted);
}

.cm-spectrum-panel-empty {
    padding: 2.5rem 0;
    text-align: center;
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.tippy-box .cm-spectrum-tip-title {
    margin-bottom: 0.3rem;
    font-weight: 600;
    color: var(--text-primary);
}

@media (max-width: 900px) {
    .cm-spectrum-panels {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.25rem;
    }
}

@media (max-width: 768px) {
    .cm-spectrum-card {
        margin-bottom: 0.5rem;
    }

    .cm-spectrum-panels {
        padding: 0.75rem 0.75rem 0.9rem;
    }

    .cm-spectrum-facts {
        width: 100%;
        margin-left: 0;
    }
}

.signal-centered {
    position: relative;
    justify-content: center;
}
.signal-centered .ont-rx-gauge {
    flex: initial;
}
.signal-centered .modem-nav {
    position: absolute;
    right: 0.75rem;
    margin-left: 0;
}
@media (max-width: 768px) {
    .signal-centered,
    .signal-with-model {
        flex-wrap: wrap;
    }
    .signal-with-model .modem-nav {
        margin-left: 0;
    }
    .signal-with-model .cm-model {
        margin-left: auto;
        margin-right: 0.25rem;
    }
    .signal-hero {
        gap: 0.8rem;
        margin-left: 0.15rem;
    }
    .signal-centered .modem-nav {
        position: static;
        margin-left: 0;
    }
}

.nav-btn {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    width: 28px;
    height: 28px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1.2rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.nav-btn:hover:not(:disabled) {
    background: var(--accent-color, #3b82f6);
}

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

.modem-counter {
    font-size: 0.8rem;
    color: var(--text-muted, #888);
    min-width: 30px;
    text-align: center;
}

.cellular-metrics {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

.metric-box {
    background: var(--bg-tertiary);
    border-radius: 8px;
    padding: 0.75rem;
}

.metric-header {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--accent-color, #3b82f6);
    margin-bottom: 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.metric-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.85rem;
    padding: 2px 0;
    gap: 0.5rem;
    max-width: 250px;
    margin: 0 auto;
}

@media (max-width: 1500px) {
    .metric-value.ont-err-counts {
        font-size: 1.1rem;
    }
}

@media (max-width: 768px) {
    .cellular-metrics {
        grid-template-columns: 1fr;
    }
    .metric-row {
        font-size: 1rem;
    }
    .metric-value.ont-err-counts {
        font-size: 1rem;
    }
}

.learning-progress {
    background: var(--bg-primary);
    padding: 1rem;
    border-radius: var(--border-radius);
    margin-bottom: 1rem;
}

.sqm-actions {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1.25rem;
}

/* Alerts List */
.alerts-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.alert-item {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    background: var(--bg-primary);
    border-radius: var(--border-radius);
    border-left: 4px solid var(--border-color);
}

.alert-item.alert-item-critical {
    border-left-color: var(--danger-color);
}

.alert-item.alert-item-warning,
.alert-item.alert-item-recommended {
    border-left-color: var(--warning-color);
}

.alert-item.alert-item-info {
    border-left-color: var(--info-color);
}

.alert-icon {
    flex-shrink: 0;
    display: flex;
    align-items: flex-start;
    padding-top: 0.125rem;
    width: 24px;
    min-height: 24px;
}

.alert-item.alert-item-critical .alert-icon {
    color: var(--danger-color);
}

.alert-item.alert-item-warning .alert-icon,
.alert-item.alert-item-recommended .alert-icon {
    color: var(--warning-color);
}

.alert-item.alert-item-info .alert-icon {
    color: var(--info-color);
}

.alert-content {
    flex: 1;
}

.alert-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.alert-title {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
}

.alert-time {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.alert-message {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin: 0 0 0.5rem 0;
}

.linkified-url {
    overflow-wrap: anywhere;
}

.alert-source {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.alert-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: flex-end;
}

@media (min-width: 769px) {
    .alert-actions .btn {
        min-width: 6.75rem;
    }
}

/* Offers a poll's findings without moving the list underneath the reader. */
.alert-pending-pill {
    display: block;
    margin: 0 auto 1rem;
}

.no-alerts {
    text-align: center;
    padding: 2rem;
    color: var(--text-secondary);
}

.no-alerts-icon {
    font-size: 2.5rem;
    font-weight: bold;
    margin-bottom: 0.5rem;
    color: var(--success-color);
}

.no-alerts .no-alerts-icon {
    margin-bottom: 0;
}

.no-alerts p {
    font-size: 0.8125rem;
}

/* Agent Status Table */
.agent-status-table {
    /* Styles for table */
}

/* Table responsive wrapper - enables horizontal scroll on mobile */
.table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.detail-table {
    margin-bottom: 0.25rem;
}

/* The first column of each metric group. Same highlight the nav jump tints a row with, held on
   and far weaker: this one is read against, not glanced at. */
.data-table th.stats-lead,
.data-table td.stats-lead {
    background-color: color-mix(in srgb, var(--highlight-color) 10%, transparent);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 500px; /* Ensures table doesn't compress too much */
}

.latency-target-paused td:not(:last-child) {
    opacity: 0.55;
}

.data-table thead {
    background: var(--bg-primary);
}

.data-table th {
    padding: 0.75rem 1rem;
    text-align: left;
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-color);
}

.data-table td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.8125rem;
}

.data-table .col-time {
    width: 125px;
    white-space: nowrap;
}

.data-table tr:not(.history-details-row):hover {
    background: var(--bg-hover-subtle);
}

.data-table code {
    background: var(--bg-primary);
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
}

/* Inline code inside running text (TextWithCode): the table look, wherever the text lands. */
code.text-code {
    background: var(--bg-primary);
    color: var(--text-primary);
    padding: 0.0625rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125em;
}

/* Text truncation utilities for table cells */
.text-truncate-200 { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-truncate-300 { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-truncate-400 { max-width: 400px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* TC Monitor Configuration */
.section-description {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin-bottom: 1.5rem;
    line-height: 1.5;
}

.wan-interfaces-section {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border-color);
}

.wan-interfaces-section h4 {
    margin-bottom: 1rem;
    font-size: 0.9375rem;
    color: var(--text-primary);
}

.config-output {
    margin-top: 1.5rem;
}

.config-output h4 {
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
}

.config-block {
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: 1rem;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    line-height: 1.5;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-all;
    margin-bottom: 0.75rem;
}

.agent-name {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.agent-icon {
    font-size: 1.25rem;
}

/* Status Badges */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background-color: var(--bg-elevated);
    padding: 0.25rem 0.75rem;
    border-radius: var(--border-radius-lg);
    font-size: 0.75rem;
    font-weight: 600;
}

.status-badge.status-active,
.status-badge.status-connected {
    background: rgba(36, 188, 112, 0.2);
    color: var(--success-color);
}

.status-badge.status-inactive,
.status-badge.status-disconnected {
    background: rgba(100, 116, 139, 0.2);
    color: var(--text-muted);
}

.status-badge.status-error {
    background: rgba(239, 68, 68, 0.2);
    color: var(--danger-color);
}

.status-badge.status-provisioning,
.status-badge.status-warning {
    background: rgba(231, 150, 19, 0.2);
    color: var(--warning-color);
    font-weight: 600;
}

.status-badge.status-info {
    background: rgba(71, 151, 255, 0.2);
    color: var(--info-color);
}

.status-badge.badge-muted {
    color: var(--text-muted);
}

.status-badge.badge-agent {
    background: rgba(100, 116, 139, 0.2);
    color: var(--text-secondary);
}

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

.card-header-badges .issue-type-chevron {
    margin-left: 0.25rem;
}

/* Buttons - Three colors only: primary (blue), secondary (grey), danger (red) */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 36px;
    min-width: 6rem;
    padding: 0 20px;
    border: none;
    border-radius: var(--border-radius);
    /* Form controls carry an explicit UA font, which beats inheritance - without this every
       <button class="btn"> renders in the browser's default while <a class="btn"> uses ours. */
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.15s ease-out, color 0.15s ease-out;
    text-decoration: none;
    white-space: nowrap;
    box-sizing: border-box;
    line-height: normal;
    vertical-align: middle;
}

/* Ensure anchor buttons match button elements */
a.btn {
    line-height: 36px;
}

.btn-sm {
    height: 28px;
    padding: 0 12px;
    font-size: 0.8125rem;
}

a.btn-sm {
    line-height: 28px;
}

.investigate-actions {
    width: fit-content;
    max-width: 100%;
}

.investigate-actions-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    align-items: center;
}

.investigate-result {
    display: block;
    margin-top: 0.75rem;
    text-align: center;
}

@media (max-width: 768px) {
    .loss-nav-arrow {
        min-width: 4rem;
    }

    .investigate-btn {
        font-size: 0.8rem;
    }
}

.btn-group-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Monitoring Interfaces row actions: keep the action buttons on one line by overriding the
   global .btn min-width and tightening spacing. The table-responsive wrapper provides
   horizontal scroll on very narrow screens. */
.mi-row-actions {
    flex-wrap: nowrap;
    gap: 0.375rem;
}

.mi-row-actions .btn {
    min-width: 0;
    padding: 0 12px;
}

/* Busy buttons: both states occupy the same grid cell, so the button is sized by its widest
   state and never resizes mid-action. Do not collapse to an @if - swapping the label for a
   spinner changes the width, which shifts the toolbar wherever .btn min-width is relaxed. */
.btn-state-stack {
    display: grid;
    align-items: center;
    justify-items: center;
}

.btn-state-stack > * {
    grid-area: 1 / 1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.btn-state-stack > .is-hidden {
    visibility: hidden;
}

.btn-lg {
    height: 44px;
    padding: 0 24px;
    font-size: 0.9375rem;
    border-radius: var(--border-radius-lg);
}

a.btn-lg {
    line-height: 44px;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Primary - Blue */
.btn-primary {
    background: var(--primary-color);
    color: white !important;
}

.btn-primary:hover:not(:disabled) {
    background: var(--primary-hover);
    color: white !important;
}

.btn-primary:visited {
    color: white !important;
}

/* Secondary - Grey (alias: btn-secondary, btn-ghost) */
.btn-secondary,
.btn-ghost {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.btn-secondary:hover:not(:disabled),
.btn-ghost:hover:not(:disabled) {
    background: var(--bg-elevated);
}

/* An auth option with nothing configured. Dimmed rather than hidden, because which options are and
   are not in play is the thing you come to these cards to read.

   Qualified with .form-label deliberately: on its own this loses to .form-label's own colour, which
   is declared later in the file at equal specificity. */
.form-label.form-label-unused {
    color: var(--text-muted);
}

.ssh-key-row .form-help,
#ssh-key .form-help {
    margin-top: 0.5rem;
}

/* Wraps the value only, not the label - the label stays aligned with every other field header in the
   card. Bordered only once a key is stored: it states that key auth is in play for the section, so it
   should read as a statement rather than as another line of help text. */
.ssh-key-row-set {
    margin-top: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--info-color);
    border-radius: var(--border-radius);
}

.ssh-key-row-set .form-help {
    margin-top: 0;
}

#ssh-key .ssh-key-upload .form-group {
    margin-bottom: 1rem;
}

/* The Private key field opens the upload form, so it needs clearing from the buttons above it. */
#ssh-key .ssh-key-upload .form-group:first-child {
    margin-top: 1rem;
}

#ssh-key .ssh-key-public {
    margin-bottom: 1.25rem;
}

/* The actions follow a setup-guide, which carries no bottom margin of its own. */
#ssh-key .action-buttons {
    margin-top: 1.5rem;
    gap: 1rem;
}

/* This one sits inside help text rather than beside a button, so it sizes to sit with the sentence. */
#ssh-key .form-help .btn-link {
    font-size: 0.8rem;
}

/* A button that reads as a link, for the lesser of two adjacent actions. */
.btn-link {
    background: none;
    border: none;
    padding: 0;
    font-size: 0.9rem;
    color: var(--primary-hover);
    text-decoration: underline;
    cursor: pointer;
}

.btn-link:hover:not(:disabled) {
    color: var(--text-primary);
}

/* Tertiary - Elevated grey (for dismiss/subtle actions on tertiary backgrounds) */
.btn-tertiary {
    background: var(--bg-elevated);
    color: var(--text-secondary);
}

.btn-tertiary:hover:not(:disabled) {
    background: var(--btn-map-hover);
    color: var(--text-primary);
}

/* Same lift as tertiary, for a button sitting ON an elevated surface rather than one that is
   lower priority. Keeps full-strength text: the elevated background is doing the separating, and
   toning the label down as well makes it read as de-emphasised when it is not. */
.btn-contrast {
    background: var(--bg-elevated);
    color: var(--text-primary);
}

.btn-contrast:hover:not(:disabled) {
    background: var(--btn-map-hover);
}

/* Danger - Red (for destructive actions) */
.btn-danger {
    background: var(--danger-color);
    color: white !important;
}

.btn-danger:hover:not(:disabled) {
    background: #dc5559;
    color: white !important;
}

.btn-danger:visited {
    color: white !important;
}

/* Legacy aliases - map to three main colors */
.btn-success,
.btn-accent,
.btn-gradient {
    background: var(--primary-color);
    color: white !important;
}

.btn-success:hover:not(:disabled),
.btn-accent:hover:not(:disabled),
.btn-gradient:hover:not(:disabled) {
    background: var(--primary-hover);
    color: white !important;
}

.btn-warning {
    background: var(--warning-color);
    color: #1a1a1a;
}

.btn-warning:hover:not(:disabled) {
    background: #c47e10;
}

/* Outline variant - primary only */
.btn-outline-primary {
    background: transparent;
    border: 1px solid var(--primary-color);
    color: var(--primary-color);
}

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

/* Test button with progress indicator */
.test-button {
    position: relative;
    overflow: hidden;
    min-width: 7.5rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
}

.test-button .test-progress {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    background: rgba(0, 0, 0, 0.2);
}

.test-button .test-progress .progress-bar {
    height: 100%;
    background: rgba(255, 255, 255, 0.25);
    transition: width 0.25s ease-out;
}

.test-button .test-phase {
    position: relative;
    z-index: 1;
    white-space: nowrap;
}

.btn-sm.test-button {
    min-width: 6.5rem;
}

.action-buttons {
    display: flex;
    gap: 0.5rem;
    flex-wrap: nowrap;
    align-items: center;
}

@media (max-width: 768px) {
    .action-buttons {
        flex-wrap: wrap;
        justify-content: center;
    }

    .site-switcher ~ .logout-btn span,
    .site-switcher ~ .account-btn span {
        display: none;
    }
}

.action-buttons .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Action button spacing in tables */

/* Data Management Section */
.data-actions {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.action-item {
    padding: 1rem 0;
    border-bottom: 1px solid var(--border-color);
}

.action-item:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.action-item:first-child {
    padding-top: 0;
}

.action-item h4 {
    margin: 0 0 0.5rem 0;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--text-primary);
}

.action-item p {
    margin: 0 0 1rem 0;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.action-item.danger-zone h4 {
    color: var(--danger-color);
}

.card.danger-zone {
    border-left: 4px solid var(--danger-color);
}

.card.danger-zone .card-title {
    color: var(--danger-color);
}

.card.card-accent {
    border-left: 4px solid var(--primary-hover);
}

.card.card-accent .card-title {
    color: var(--primary-hover);
}

/* Forms */
.form-group {
    margin-bottom: 1.5rem;
}

.form-label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    font-size: 0.875rem;
    color: var(--text-primary);
}

.form-control {
    width: 100%;
    padding: 0.625rem 0.875rem;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    font-size: 0.875rem;
}

.form-control:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(5, 89, 201, 0.2);
}

select.form-control {
    padding-right: 2.5rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
    appearance: none;
    -webkit-appearance: none;
}

/* iOS Safari gives native date/time inputs an intrinsic min-width that ignores width: 100% and overflows the card. */
input[type="time"].form-control,
input[type="date"].form-control,
input[type="datetime-local"].form-control {
    -webkit-appearance: none;
    appearance: none;
    min-width: 0;
}

input.form-control::-webkit-date-and-time-value {
    text-align: left;
}

.form-help {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.input-row {
    display: flex;
    gap: 0.75rem;
}

.threshold-fields {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
}

.threshold-fields .form-group {
    flex: 1;
    min-width: 180px;
    margin-bottom: 0;
}

.sfp-ddm-toggle {
    margin-top: 0.25rem;
}

/* Long enough to need a measure; the threshold fields above wrap at 180px, so this may not. */
.sfp-ddm-help {
    max-width: 68ch;
}

.input-with-button {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.input-with-button .form-control {
    flex: 1;
    min-width: 0;
}

.input-with-button .btn {
    flex-shrink: 0;
    white-space: nowrap;
}

/* Password field with the show/hide eye inside it, on the right (PasswordInput). */
.password-field {
    position: relative;
}

.password-field .form-control {
    padding-right: 2.75rem;
}

/* Edge draws its own reveal eye; one is enough. */
.password-field .form-control::-ms-reveal {
    display: none;
}

.password-toggle {
    position: absolute;
    top: 50%;
    right: 0.5rem;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    background: none;
    border: none;
    border-radius: var(--border-radius);
    color: var(--text-secondary);
    cursor: pointer;
}

.password-toggle:hover,
.password-toggle:focus-visible {
    color: var(--text-primary);
}

.password-toggle svg {
    width: 1.25rem;
    height: 1.25rem;
}

/* The eye offers to show; once shown, the slashed eye offers to hide. */
.password-toggle .password-eye-slash,
.password-toggle[aria-pressed="true"] .password-eye {
    display: none;
}

.password-toggle[aria-pressed="true"] .password-eye-slash {
    display: block;
}

.checkbox-label,
.radio-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    cursor: pointer;
}

.checkbox-group,
.radio-group {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.auth-method-toggle {
    display: flex;
    gap: 1.5rem;
}

/* Progress Bar */
.progress-bar {
    width: 100%;
    height: 8px;
    background: var(--bg-primary);
    border-radius: var(--border-radius-lg);
    overflow: hidden;
    margin-top: 1rem;
}

.progress-fill {
    height: 100%;
    background: var(--primary-color);
    transition: width 0.3s ease;
}

.progress-text {
    margin-top: 0.5rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
    text-align: center;
}

/* Spinner */
.spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Empty States */
.empty-icon {
    font-size: 4rem;
    margin-bottom: 1rem;
    opacity: 0.5;
}

.empty-icon svg {
    width: 3rem;
    height: 3rem;
    color: var(--text-secondary);
}

.account-credential-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.account-credential-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.625rem 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
}

.account-credential-info {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.account-credential-item .btn {
    flex: 0 0 auto;
}

.account-credential-name {
    font-weight: 500;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.account-credential-meta {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.account-passkey-name {
    max-width: 260px;
    margin-bottom: 1rem;
}

.account-recovery-intro {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.5;
}

.account-recovery-codes {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.375rem;
}

.account-recovery-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 1rem;
}

.account-recovery-codes code {
    font-size: 0.95rem;
    letter-spacing: 0.05em;
}

.account-empty-note {
    margin-bottom: 0.5rem;
}

/* A posted action button that sits in a row with circuit buttons. */
.account-inline-form {
    display: inline;
}

.account-note {
    margin: 0 0 0.75rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

.account-qr {
    display: inline-block;
    margin-bottom: 0.5rem;
    padding: 0.75rem;
    background: #ffffff;
    border-radius: var(--border-radius-lg);
    line-height: 0;
}

.account-qr img {
    display: block;
}

.account-key-row {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    max-width: 26rem;
    margin-bottom: 1rem;
}

.account-key-input {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.04em;
}

.code-copy-block {
    position: relative;
}

.code-copy-block pre {
    background: var(--bg-primary);
    padding: 0.75rem;
    padding-right: 3rem;
    border-radius: 6px;
    overflow-x: auto;
    max-width: 100%;
    font-size: 0.8125rem;
}

.code-copy-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 1;
    /* The pre this sits over is an async-scrolled composited layer on iOS, which paints across an
       unpromoted sibling whatever the paint order says. Never drop the transform: on a phone the
       button then renders invisible - present, hit-testable, and not drawn. */
    will-change: transform;
    transform: translateZ(0);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    background: var(--bg-elevated);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

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

.code-copy-btn svg {
    width: 0.95rem;
    height: 0.95rem;
}

.account-copy-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.5rem;
    padding: 0;
    background: var(--bg-elevated);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: all 0.2s;
}

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

.account-copy-btn svg {
    width: 1rem;
    height: 1rem;
}

.account-verify-code {
    max-width: 340px;
    margin-bottom: 1rem;
}

.empty-state h3 {
    margin-bottom: 0.5rem;
    color: var(--text-primary);
}

.empty-state p {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
    font-size: 0.8125rem;
}

.client-picker-row {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    text-align: left;
}

.client-picker-row select {
    max-width: 320px;
}

/* Alerts/Messages */
.alert {
    padding: 1rem;
    border-radius: var(--border-radius);
    margin-top: 1rem;
    margin-bottom: 1rem;
    font-size: 0.875rem;
}


.alert-success {
    background: rgba(36, 188, 112, 0.1);
    border: 1px solid var(--success-color);
    color: var(--success-color);
}

.alert-warning {
    background: rgba(245, 158, 11, 0.1);
    border: 1px solid var(--warning-color);
    color: var(--warning-color);
}

.alert.speedtest-invalid-alert {
    margin: 0 1rem 1rem;
}

.alert-warning a {
    color: #fbbf24;
    text-decoration: underline;
}

.alert-warning a:hover {
    color: #fcd34d;
}

.alert-danger {
    background: rgba(239, 68, 68, 0.1);
    border: 1px solid var(--danger-color);
    color: var(--danger-color);
}

.alert-info {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
}

/* Dark inline code (for use in alerts) */
.code-dark {
    background: rgba(0, 0, 0, 0.3);
    padding: 0.15rem 0.4rem;
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
}

/* Alert with progress bar */
.alert-progress {
    position: relative;
    overflow: hidden;
    background: var(--bg-tertiary);
}

.alert-progress .alert-progress-bar {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    background: linear-gradient(90deg, rgba(5, 89, 201, 0.4) 0%, rgba(5, 89, 201, 0.25) 100%);
    transition: width 0.25s ease-out;
    border-right: 2px solid rgba(5, 89, 201, 0.6);
}

.alert-progress .alert-progress-text {
    position: relative;
    z-index: 1;
}

/* Alert as clickable link */
.alert-link {
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.1s ease;
}

.alert-link:hover {
    background: rgba(36, 188, 112, 0.25);
    transform: translateY(-1px);
}

.alert-link:active {
    transform: translateY(0);
}

.alert-link-hint {
    font-size: 0.8rem;
    opacity: 0.8;
    margin-left: 1rem;
}

/* Badges */
.badge {
    display: inline-block;
    padding: 0.25rem 0.625rem;
    border-radius: 0.25rem;
    font-size: 0.75rem;
    font-weight: 600;
}

.badge-pdf {
    background: var(--danger-color);
    color: white;
}

.badge-markdown {
    background: var(--info-color);
    color: white;
}

.badge-html {
    background: var(--warning-color);
    color: white;
}

.badge-premium {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

/* Tabs */
.filter-tabs {
    display: flex;
    gap: 0.5rem;
}

.tab {
    padding: 0.5rem 1rem;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: all 0.15s ease-out;
}

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

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

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

.tab.tab-muted.active {
    color: var(--text-secondary);
    border-bottom-color: var(--text-secondary);
}

/* Issue Styling */
.issues-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.issue-item {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    background: var(--bg-primary);
    border-radius: var(--border-radius);
    border-left: 4px solid var(--border-color);
}

.issue-item.issue-critical {
    border-left-color: var(--danger-color);
}

.issue-item.issue-warning,
.issue-item.issue-recommended {
    border-left-color: var(--warning-color);
}

.issue-item.issue-info,
.issue-item.info {
    border-left-color: var(--info-color);
}

/* Simplified severity classes (without issue- prefix) */
.issue-item.critical {
    border-left-color: var(--danger-color);
}

.issue-item.warning {
    border-left-color: var(--warning-color);
}

.issue-icon {
    flex-shrink: 0;
    display: flex;
    align-items: flex-start;
    margin-top: 22px;
    width: 24px;
    min-height: 24px;
}

.issue-item.issue-critical .issue-icon {
    color: var(--danger-color);
}

.issue-item.issue-warning .issue-icon,
.issue-item.issue-recommended .issue-icon {
    color: var(--warning-color);
}

.issue-item.issue-info .issue-icon,
.issue-item.info .issue-icon {
    color: var(--info-color);
}

/* Simplified severity classes for icons */
.issue-item.critical .issue-icon {
    color: var(--danger-color);
}

.issue-item.warning .issue-icon {
    color: var(--warning-color);
}

.issue-body,
.issue-content {
    flex: 1;
    min-width: 0;
}

.issue-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    min-height: 28px;
}

.issue-severity {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    border-radius: 0.25rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
}

.issue-critical .issue-severity {
    background: rgba(239, 68, 68, 0.15);
    color: var(--danger-color);
}

.issue-warning .issue-severity,
.issue-recommended .issue-severity {
    background: rgba(245, 158, 11, 0.15);
    color: var(--warning-color);
}

.issue-info .issue-severity {
    background: rgba(6, 182, 212, 0.15);
    color: var(--info-color);
}

.issue-category {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.issue-action {
    margin-left: auto;
    font-size: 0.75rem;
    padding: 0.25rem 0.5rem;
    opacity: 0.7;
}

.issue-action:hover {
    opacity: 1;
}

/* Only the first action pushes right; the ones after it sit beside it. */
.issue-action + .issue-action {
    margin-left: 0;
}

.issue-action.btn-primary {
    opacity: 1;
}

.issue-settings-icon {
    width: 20px;
    height: 20px;
    margin-left: 0.5rem;
    background: transparent;
    text-decoration: none;
}

.issue-settings-icon svg {
    width: 14px;
    height: 14px;
}

.issue-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.offline-badge {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    background: var(--text-muted);
    color: var(--bg-primary);
}

.issue-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

.issue-recommendation {
    margin-top: 0.75rem;
    margin-bottom: 0.25rem;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.issue-recommendation strong {
    color: var(--text-primary);
}

.issue-recommendation a.issue-action-link,
.issue-type-recommendation a.issue-action-link {
    display: flex;
    width: fit-content;
    margin-top: 0.5rem;
    text-decoration: none;
}

.issue-investigate {
    margin-top: 0.5rem;
    font-size: 0.875rem;
}

.issue-recommendation a,
.issue-type-recommendation a,
.issue-description a,
.issue-type-description a,
.issue-item-description a {
    color: var(--primary-hover);
    text-decoration: none;
}

.issue-recommendation a:hover,
.issue-type-recommendation a:hover,
.issue-description a:hover,
.issue-type-description a:hover,
.issue-item-description a:hover {
    color: var(--accent-color);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.no-issues {
    text-align: center;
    padding: 2rem;
    color: var(--text-muted);
    font-size: 0.8125rem;
}

.issue-item.issue-dismissed {
    opacity: 0.6;
    border-left-color: var(--text-muted);
}

.issue-item.issue-dismissed .issue-icon {
    color: var(--text-muted);
}

/* Collapsible Issue Type Groups */
.issue-type-group {
    margin-bottom: 0.5rem;
}

.issue-type-header {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1rem;
    background: var(--bg-primary);
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: background 0.15s ease;
    font-weight: 500;
    color: var(--text-primary);
    border-left: 4px solid var(--border-color);
}

.issue-type-header:hover {
    background: var(--bg-hover);
}

.issue-type-header.expanded {
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

.issue-type-group .expand-wrapper .expand-content {
    border-left: 4px solid var(--border-color);
}

.issue-type-group .expand-wrapper.expanded .expand-content {
    background: var(--bg-primary);
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

.issue-type-group.issue-critical .expand-wrapper .expand-content {
    border-left-color: var(--danger-color);
}

.issue-type-group.issue-recommended .expand-wrapper .expand-content {
    border-left-color: var(--warning-color);
}

.issue-type-group.issue-info .expand-wrapper .expand-content {
    border-left-color: var(--info-color);
}

/* Issue type group severity colors - uses same classes as issue-item */
.issue-type-group.issue-critical .issue-type-header {
    border-left-color: var(--danger-color);
}

.issue-type-group.issue-recommended .issue-type-header {
    border-left-color: var(--warning-color);
}

.issue-type-group.issue-info .issue-type-header {
    border-left-color: var(--info-color);
}

.issue-type-icon {
    display: flex;
    align-items: flex-start;
    margin: auto 0;
    width: 24px;
    min-height: 24px;
    flex-shrink: 0;
}

.issue-type-icon svg {
    width: 24px;
    height: 24px;
}

.issue-type-group.issue-critical .issue-type-icon {
    color: var(--danger-color);
}

.issue-type-group.issue-recommended .issue-type-icon {
    color: var(--warning-color);
}

.issue-type-group.issue-info .issue-type-icon {
    color: var(--info-color);
}

.issue-type-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.issue-type-body .issue-title {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.issue-type-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    font-size: 0.75rem;
    color: var(--text-muted);
    flex-shrink: 0;
    margin-left: auto;
}

.issue-type-header .issue-type-chevron {
    width: 2rem;
}

.issue-type-name {
    font-weight: 500;
    flex: 1;
}

.issue-type-count {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-weight: normal;
    margin-right: 0.5rem;
}

.issue-type-description {
    padding: 0.75rem 1rem 0.5rem 3.5rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.issue-type-items-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem 1rem 0.75rem 3.5rem;
}

.issue-type-item .issue-context {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    padding: 0.75rem;
    font-size: 0.875rem;
    margin: 0;
}

.issue-type-item .issue-context .context-item {
    display: inline-flex;
    gap: 0.25rem;
}

.issue-type-item .issue-context .context-item strong {
    color: var(--text-muted);
}

.issue-type-item .issue-action {
    margin-left: auto;
    background: var(--bg-secondary);
}

.issue-type-item .issue-item-description {
    flex: 1;
    color: var(--text-secondary);
}

.issue-type-recommendation {
    padding: 0.75rem 1rem 1.25rem 3.5rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

/* Footer */
.app-footer {
    padding: 1.5rem 2rem;
    text-align: center;
    font-size: 0.75rem;
    color: var(--text-muted);
    border-top: 1px solid var(--border-color);
}

.app-footer a {
    color: var(--text-muted);
    text-decoration: none;
}

.app-footer a:hover {
    color: var(--text-secondary);
    text-decoration: underline;
}

/* Hamburger Menu Button - hidden on desktop */
.hamburger-btn {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    margin-right: 0.5rem;
}

.hamburger-btn span {
    display: block;
    width: 24px;
    height: 3px;
    background: var(--text-primary);
    border-radius: 2px;
    margin: 5px 0;
    transition: transform 0.3s ease, opacity 0.3s ease;
}

/* Mobile logo - hidden on desktop */
.mobile-logo {
    display: none;
}

/* Sidebar Overlay - hidden on desktop */
.sidebar-overlay {
    display: none;
}

/* Hidden on desktop, shown only in mobile media query below */
.pull-to-refresh {
    display: none;
}

/* Responsive Design */
@media (max-width: 1024px) {
    /* Lock the viewport so only .main-content scrolls - iOS can otherwise scroll
       the body (esp. on return from background), swallowing touch gestures.
       overflow:hidden only (no position:fixed, which disturbs the dynamic-viewport
       behavior the sticky top-bar hide rides on). Scoped to the app shell so the
       login page can still scroll. */
    html:has(.app-container),
    body:has(.app-container) {
        overflow: hidden;
    }

    .content-grid {
        grid-template-columns: 1fr;
    }

    .dashboard-grid {
        grid-template-columns: 1fr;
    }

    .dashboard-card-wrapper.card-span-2 {
        grid-column: span 1;
    }

    /* Show hamburger button */
    .hamburger-btn {
        display: block;
    }

    /* Show mobile logo next to hamburger */
    .mobile-logo {
        display: block;
        height: 60px;
        margin: -0.5rem 0;
        max-height: 20vw;
    }

    .mobile-logo img {
        height: 100%;
        width: auto;
    }

    /* Off-canvas sidebar */
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        height: 100dvh;
        width: 280px;
        transform: translateX(-100%);
        transition: transform 0.3s ease;
        z-index: 1000;
        overflow-y: auto;
    }

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

    /* Overlay when sidebar is open */
    .sidebar-overlay {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 999;
    }

    .sidebar-overlay.visible {
        display: block;
    }

    /* Main content takes full width */
    .main-content {
        width: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        overscroll-behavior-y: contain;
    }

    .page-content {
        overflow-y: visible;
        flex: none;
    }

    /* Top bar adjustments */
    .top-bar {
        position: sticky;
        top: 0;
        z-index: 100;
        height: auto;
        padding: 0.75rem 1rem;
        gap: 0.5rem;
        /* Base transition governs the reveal (returning to this state) - slower */
        transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
    }

    /* Slide up by exactly the bar's own height (translateY %) so the full
       transition is spent moving one bar-height - a gradual slide, not the
       instant snap that top:-100% produced (that % resolves against the tall
       scroll container, so the bar cleared the screen in a few ms).
       Transition here governs the hide (entering this state) - kept quicker. */
    .top-bar.top-bar-hidden {
        position: sticky;
        top: 0;
        transform: translateY(-100%);
        transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        pointer-events: none;
    }

    .top-bar.top-bar-hidden.top-bar-collapsed {
        position: absolute;
        left: 0;
        right: 0;
    }

    .top-bar.top-bar-hidden .site-switcher-menu,
    .top-bar.top-bar-hidden .site-switcher-backdrop {
        pointer-events: auto;
    }

    .app-footer {
        padding: 0.5rem 1rem;
        font-size: 0.6rem;
        opacity: 0;
        transition: opacity 0.3s ease;
    }

    .app-footer.footer-visible {
        opacity: 1;
    }

    /* Client dashboard identity bar: shift below top bar when it's visible */
    .identity-bar.below-topbar {
        top: 70px;
    }

    .status-indicators {
        display: none;
    }

    .header-actions {
        flex: 1;
        justify-content: flex-end;
    }

    .timestamp {
        font-size: 0.75rem;
    }

    /* Pull-to-refresh indicator */
    .pull-to-refresh {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 40px;
        transform: translateY(-40px);
        opacity: 0;
        z-index: 1000;
        pointer-events: none;
        transition: none;
    }

    .pull-to-refresh.ptr-refreshing {
        transition: transform 0.2s ease;
    }

    .ptr-spinner {
        width: 32px;
        height: 32px;
        color: var(--primary-color);
        transition: color 0.15s ease;
    }

    .pull-to-refresh.ptr-ready .ptr-spinner {
        color: var(--success-color);
    }

    .pull-to-refresh.ptr-refreshing .ptr-spinner {
        animation: ptr-spin 0.6s linear infinite;
        color: var(--success-color);
    }

    @keyframes ptr-spin {
        from { transform: rotate(0deg) scale(1.4); }
        to { transform: rotate(360deg) scale(1.4); }
    }
}

@media (max-width: 768px) {
    /* Client dashboard identity bar: smooth collapse name/meta when scrolled down */
    .identity-bar .identity-name,
    .identity-bar .identity-name-cell,
    .identity-bar .identity-meta {
        max-height: 60px;
        opacity: 1;
        overflow: hidden;
        transition: max-height 0.3s ease, opacity 0.2s ease, margin 0.3s ease;
    }

    .identity-bar.identity-collapsed:has(.signal-gauge) {
        padding-top: 0;
    }

    .identity-bar.identity-collapsed:has(.signal-gauge) .identity-name,
    .identity-bar.identity-collapsed:has(.signal-gauge) .identity-name-cell,
    .identity-bar.identity-collapsed:has(.signal-gauge) .identity-meta {
        max-height: 0;
        opacity: 0;
        margin: 0;
    }

    .identity-bar.identity-collapsed {
        border-radius: 0;
        margin-left: -16px;
        margin-right: -16px;
        padding-left: 16px;
        padding-right: 16px;
    }

    /* Content adjustments */
    .stats-row {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }

    .content-grid {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }

    .dashboard-grid {
        display: flex;
        flex-direction: column;
        gap: 14px 8px;
    }

    .dashboard-grid .card-stack {
        gap: 14px;
    }

    .device-grid {
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .page-content {
        padding: 1rem;
    }

    .content {
        padding: 0;
    }

    /* Card adjustments for mobile */
    .card {
        padding: 1rem;
        margin-bottom: 0.5rem;
    }

    .card-stack {
        gap: 0.5rem;
    }

    .dashboard-card-wrapper.card-span-2 > .card-stack {
        flex-direction: column;
    }

    .card-header {
        padding: 0 0 0.75rem;
        flex-wrap: wrap;
        gap: 0.5rem;
        position: relative;
    }

    .card-header .issue-type-chevron,
    .data-table .issue-type-chevron {
        position: static;
        transform: none;
    }

    .card-header-collapsible .card-header-right {
        width: 100%;
        justify-content: space-between;
    }

    .card-header-collapsible > .card-title,
    .card-header-collapsible > .card-title-group {
        flex: 1 1 0;
    }

    .card-header-collapsible > .time-range-selector {
        order: 1;
        flex-basis: 100%;
    }

    /* Filter tabs mobile - wrap below title, compact sizing */
    .filter-tabs {
        width: 100%;
        gap: 0.25rem;
        justify-content: flex-start;
    }

    .filter-tabs .tab {
        padding: 0.35rem 0.5rem;
        font-size: 0.8rem;
    }

    .card-body {
        padding: 1rem 0 0.4rem;
    }

    /* Footer adjustments */
    .app-footer {
        padding: 0.75rem;
        font-size: 0.7rem;
    }

    /* Alert items - icon inline with title on mobile */
    .alert-item {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: 0.5rem;
        row-gap: 0.25rem;
    }

    .alert-icon {
        grid-column: 1;
        grid-row: 1;
        align-self: start;
        padding-top: 0.15rem;
    }

    .alert-content {
        display: contents;
    }

    .alert-header {
        grid-column: 2;
        grid-row: 1;
        display: flex;
        flex-wrap: wrap;
        gap: 0.25rem 0.5rem;
        align-items: center;
    }

    .alert-title {
        font-size: 0.9rem;
    }

    .alert-time {
        font-size: 0.7rem;
        margin-left: auto;
    }

    .alert-message {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    .alert-source {
        grid-column: 1 / -1;
        grid-row: 3;
    }

    .alert-actions {
        grid-column: 1 / -1;
        grid-row: 4;
        display: flex;
        flex-direction: row;
        gap: 0.5rem;
        margin-top: 0.5rem;
    }

    /* Issue items - icon inline with title on mobile */
    .issue-item {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: 0.5rem;
        row-gap: 0.25rem;
    }

    .issue-icon {
        grid-column: 1;
        grid-row: 2;
        align-self: start;
        margin-top: 0;
        padding-top: 0.05rem;
    }

    .issue-body,
    .issue-content {
        display: contents;
    }

    .issue-meta {
        grid-column: 1 / -1;
        grid-row: 1;
    }

    .issue-header {
        grid-column: 1 / -1;
        grid-row: 1;
        flex-wrap: wrap;
        gap: 0.25rem 0.5rem;
        min-height: 0;
    }

    .issue-severity {
        font-size: 0.6rem;
    }

    .issue-category {
        font-size: 0.65rem;
    }

    .issue-title {
        grid-column: 2;
        grid-row: 2;
        font-size: 0.9rem;
        margin-top: 0.125rem;
    }

    .issue-description {
        grid-column: 1 / -1;
        grid-row: 3;
        font-size: 0.8rem;
    }

    .issue-entity,
    .issue-recommendation {
        grid-column: 1 / -1;
    }

    .issue-context {
        grid-column: 1 / -1;
        grid-row: 4;
    }

    .issue-fix-error {
        grid-column: 1 / -1;
    }

    .issue-recommendation {
        grid-column: 1 / -1;
        grid-row: 5;
        font-size: 0.8rem;
    }

    .issue-action {
        margin-left: auto;
    }

    /* Collapsible group header - match single item layout */
    .issue-type-header {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: 0.5rem;
        row-gap: 0.25rem;
        position: relative;
        padding-right: 2rem;
    }

    .issue-type-icon {
        grid-column: 1;
        grid-row: 2;
        align-self: start;
        padding-top: 0.05rem;
        margin: 0;
    }

    .issue-type-body {
        display: contents;
    }

    .issue-type-body .issue-header {
        grid-column: 1 / -1;
        grid-row: 1;
        flex-wrap: wrap;
        gap: 0.25rem 0.5rem;
    }

    .issue-type-body .issue-title {
        grid-column: 2;
        grid-row: 2;
        font-size: 0.9rem;
        margin-top: 0.125rem;
    }

    .issue-type-chevron {
        position: absolute;
        right: 0.5rem;
        top: 50%;
        transform: translateY(-50%);
    }

    /* Expanded items - full width context */
    .issue-type-description {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    .issue-type-items-list {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    .issue-type-recommendation {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    .issue-type-item .issue-context {
        flex-direction: column;
        align-items: stretch;
        gap: 0.25rem;
    }

    .issue-type-item .issue-context .context-item {
        width: 100%;
    }

    .issue-type-item .issue-action {
        margin-top: 0.5rem;
    }
}

/* Network Purpose Override */
.purpose-cell-inner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    position: relative;
}

.purpose-select {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    padding: 0.375rem 0.5rem;
    font-size: 0.875rem;
    line-height: 1.4;
    cursor: pointer;
    width: 140px;
    min-width: 140px;
}

.purpose-select:focus {
    outline: none;
    border-color: var(--primary-color);
}

.purpose-saved {
    color: var(--success-color);
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
    animation: purposeFadeIn 0.2s ease-out;
    position: absolute;
    left: calc(140px + 0.5rem);
}

@keyframes purposeFadeIn {
    from { opacity: 0; transform: translateX(-4px); }
    to { opacity: 1; transform: translateX(0); }
}

.purpose-rerun-banner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    margin-bottom: 1rem;
    background: rgba(71, 151, 255, 0.08);
    border: 1px solid rgba(71, 151, 255, 0.25);
    border-radius: 6px;
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.purpose-rerun-banner .purpose-rerun-icon {
    color: var(--info-color);
    flex-shrink: 0;
    display: flex;
}

.purpose-rerun-banner span:nth-child(2) {
    flex: 1;
}

/* Utility Classes */
.text-center {
    text-align: center;
}

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

.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }

.hidden-placeholder {
    visibility: hidden;
}

@media (max-width: 768px) {
    .hidden-placeholder,
    .action-buttons .btn.hidden-placeholder {
        display: none;
    }
}

.d-flex {
    display: flex;
}

.gap-1 {
    gap: 0.5rem;
}

.gap-2 {
    gap: 1rem;
}

/* Connection Banner */
.connection-banner {
    background: linear-gradient(135deg, var(--warning-color) 0%, #d97706 100%);
    border-radius: var(--border-radius);
    padding: 1rem 1.5rem;
    margin-bottom: 1.5rem;
}

.banner-content {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.scan-gap-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.75rem 1rem;
    border-radius: var(--border-radius);
    margin-bottom: 1rem;
    font-size: 0.85rem;
}

.scan-gap-banner .scan-gap-text {
    flex: 1;
    min-width: 12rem;
}

.scan-gap-banner .btn {
    flex-shrink: 0;
}

.scan-error-banner {
    margin-bottom: 1rem;
    font-size: 0.85rem;
}

@media (max-width: 768px) {
    .scan-gap-banner .btn {
        width: 100%;
    }
}

.banner-icon {
    font-size: 1.5rem;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.banner-icon-info {
    background: var(--info-color);
    color: var(--text-primary);
    font-size: 1rem;
    font-weight: 600;
    width: 24px;
    height: 24px;
}

.banner-icon-warning {
    background: var(--warning-color);
    color: var(--text-primary);
    font-size: 1rem;
    font-weight: 600;
    width: 24px;
    height: 24px;
}

/* SNMP Devices table: device name + type badge */
.snmp-device-type {
    margin-left: 0.5rem;
}

@media (max-width: 768px) {
    .snmp-device-name {
        display: block;
    }
    .snmp-device-type {
        margin-left: 0;
        margin-top: 0.25rem;
    }
}

.snmp-row-chevron {
    font-size: 0.7rem;
    color: var(--text-muted);
    transition: color 0.15s;
}

tr:hover .snmp-row-chevron {
    color: var(--text-secondary);
}

.snmp-row-expanded {
    background: var(--bg-tertiary);
}

.data-table tr.snmp-row-expanded:hover {
    background: var(--bg-row-expanded-hover);
}

.data-table .snmp-detail-row > td {
    padding: 0;
    border-top: none;
}

.snmp-detail-panel {
    padding: 1rem 1.25rem 1.25rem;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border-color);
}

.snmp-detail-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
}

.snmp-detail-header h4 {
    margin: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
}

.snmp-oid-table {
    font-size: 0.85rem;
}

.snmp-oid-code {
    font-size: 0.8rem;
    padding: 0.15rem 0.4rem;
    background: var(--bg-tertiary);
    border-radius: 3px;
    color: var(--text-secondary);
    word-break: break-all;
}

.snmp-add-oid-form {
    margin-top: 0.75rem;
    padding: 1rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
    border: 1px solid var(--border-color);
}

.snmp-add-oid-form .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.snmp-add-oid-form .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

.snmp-add-oid-form .form-group > .checkbox-label,
.snmp-add-oid-form .form-group > .radio-group {
    padding: 0.625rem 0;
}

.snmp-add-oid-form textarea.form-control {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    resize: vertical;
}

.snmp-test-result {
    margin-top: 0.35rem;
    font-size: 0.8rem;
    padding: 0.3rem 0.5rem;
    border-radius: 4px;
}

.snmp-test-success {
    background: rgba(36, 188, 112, 0.1);
    color: var(--success-color);
}

.snmp-test-error {
    background: rgba(238, 99, 104, 0.1);
    color: var(--danger-color);
}

.snmp-save-error {
    font-size: 0.8rem;
    color: var(--danger-color);
}

@media (max-width: 768px) {
    .snmp-detail-panel {
        padding: 0.75rem;
    }

    .snmp-add-oid-form .form-row {
        flex-direction: column;
        gap: 0;
    }

    .snmp-add-oid-form .form-row > .form-group {
        flex: 0 0 auto;
    }

    .snmp-detail-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }
}

.banner-text {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.banner-text strong {
    font-size: 1rem;
    color: white;
}

.banner-text span {
    font-size: 0.875rem;
    color: rgba(255, 255, 255, 0.9);
}

.banner-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.multi-wan-hint {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.multi-wan-hint-body {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: 1;
}

.multi-wan-hint p {
    flex: 1;
    margin: 0;
}

@media (max-width: 768px) {
    .multi-wan-hint {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .multi-wan-hint .btn {
        align-self: flex-end;
    }
}

.connection-banner .btn-secondary {
    background: white;
    color: var(--warning-color) !important;
    border: none;
}

.connection-banner .btn-secondary:hover {
    background: rgba(255, 255, 255, 0.9);
}

.connection-banner.module-update-banner {
    background: var(--bg-tertiary);
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.module-update-banner .banner-icon {
    background: rgba(231, 150, 19, 0.15);
    color: var(--warning-color);
}

.module-update-banner .btn {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary);
    border: 1px solid rgba(255, 255, 255, 0.18);
}

.module-update-banner .btn:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: var(--text-secondary);
}

@media (max-width: 768px) {
    .connection-banner .banner-content {
        flex-wrap: wrap;
        justify-content: center;
    }

    .connection-banner .banner-content .banner-text {
        flex-basis: calc(100% - 3.5rem);
    }

    .alert .banner-content {
        flex-wrap: wrap;
    }

    .alert .banner-content .banner-text {
        flex-basis: calc(100% - 3.5rem);
    }

    .alert .banner-content .banner-actions {
        flex-basis: 100%;
        display: flex;
        gap: 0.5rem;
        justify-content: flex-end;
    }
}

/* PWA Install Banner */
.pwa-banner {
    background: linear-gradient(135deg, rgba(71, 151, 255, 0.12) 0%, rgba(71, 151, 255, 0.05) 100%);
    border: 1px solid rgba(71, 151, 255, 0.3);
}

.pwa-banner .banner-text strong {
    color: var(--info-color);
}

.pwa-banner .banner-text span {
    color: var(--text-secondary);
}

.pwa-banner .btn-pwa-action {
    background: rgba(71, 151, 255, 0.15);
    color: var(--info-color);
    border: none;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    white-space: nowrap;
    text-decoration: none;
}

.pwa-banner .btn-pwa-action:hover {
    background: rgba(71, 151, 255, 0.3);
    color: white;
}

.pwa-banner .btn-pwa-dismiss {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-muted);
    border: none;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    white-space: nowrap;
}

.pwa-banner .btn-pwa-dismiss:hover {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-secondary);
}

/* Sponsorship Banner */
.sponsorship-banner {
    background: linear-gradient(135deg, rgba(168, 85, 247, 0.15) 0%, rgba(168, 85, 247, 0.08) 100%);
    border: 1px solid var(--purple-color);
    border-radius: var(--border-radius);
    padding: 1rem 1.5rem;
    margin-bottom: 1.5rem;
    position: relative;
    overflow: hidden;
}

.sponsorship-banner .banner-corgi {
    position: absolute;
    right: 400px;
    top: 50%;
    height: 80px;
    opacity: 0.5;
    pointer-events: none;
    object-fit: contain;
    transform: translateY(-50%);
}

.sponsorship-banner .banner-icon {
    background: var(--purple-color);
    color: white;
}

.sponsorship-banner .banner-text strong {
    color: var(--purple-light);
    width: 85%;
}

.sponsorship-banner .banner-text span {
    color: var(--text-primary);
}

.sponsorship-banner .banner-text a {
    color: var(--purple-light);
    text-decoration: underline;
}

.sponsorship-banner .banner-text a:hover {
    color: white;
}

.sponsorship-banner .banner-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
    flex-wrap: wrap;
    align-items: center;
}

.sponsorship-banner .banner-actions-secondary {
    display: flex;
    gap: 0.5rem;
}

.sponsorship-banner .btn-dismiss,
.sponsorship-banner .btn-sponsor {
    background: rgba(168, 85, 247, 0.15);
    color: var(--purple-light);
    border: none;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    white-space: nowrap;
}

.sponsorship-banner .btn-cta {
    background: var(--purple-color);
    color: white;
    border: none;
    padding: 0.45rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: background 0.15s;
    white-space: nowrap;
}

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

.sponsorship-banner .btn-dismiss:hover,
.sponsorship-banner .btn-sponsor:hover {
    background: rgba(168, 85, 247, 0.3);
    color: white;
}

@media (max-width: 1575px) {
    .sponsorship-banner .banner-text strong {
        width: 79%;
    }
}

@media (max-width: 1353px) {
    .sponsorship-banner .banner-content {
        flex-wrap: wrap;
    }

    .sponsorship-banner .banner-text strong {
        width: 88%;
    }

    .sponsorship-banner .banner-actions {
        width: 100%;
        justify-content: flex-end;
        margin-top: 0.5rem;
    }

    .sponsorship-banner .banner-corgi {
        left: auto;
        right: 0.5rem;
        top: auto;
        bottom: 0;
    }
}

@media (max-width: 930px) {
    .sponsorship-banner .banner-icon {
        display: none;
    }
}

@media (max-width: 900px) {
    .sponsorship-banner .banner-corgi {
        left: auto;
        right: 0.5rem;
        top: auto;
        bottom: 0;
    }
}

@media (max-width: 768px) {
    .sponsorship-banner {
        padding: 1rem;
    }

    .sponsorship-banner .banner-separator {
        display: none;
    }

    .sponsorship-banner .banner-text strong {
        font-size: 0.95rem;
    }

    .sponsorship-banner .banner-commercial {
        display: block;
        margin-top: 0.25rem;
        font-size: 0.8rem;
    }
}

@media (max-width: 575px) {
    .sponsorship-banner .banner-text strong {
        width: auto;
    }
}

@media (max-width: 460px) {
    .sponsorship-banner .banner-actions {
        flex-direction: column;
        align-items: flex-end;
    }

    .sponsorship-banner .banner-corgi {
        left: 10px;
        right: auto;
        top: auto;
        bottom: 1.3rem;
        transform: none;
    }
}

/* Sponsorship Modal */
.sponsor-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    backdrop-filter: blur(2px);
}

.sponsor-modal {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 2rem;
    max-width: 540px;
    width: 90%;
    position: relative;
    overflow: hidden;
}

.sponsor-modal .modal-corgi {
    position: absolute;
    right: 1.5rem;
    bottom: 1.5rem;
    height: 200px;
    opacity: 0.25;
    pointer-events: none;
    object-fit: contain;
}

.sponsor-modal h3 {
    color: var(--text-primary);
    margin: 0 0 0.25rem 0;
    font-size: 1.2rem;
}

.sponsor-modal-subtitle {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin: 0 0 1.5rem 0;
}

.sponsor-modal-close {
    position: absolute;
    top: 0.75rem;
    right: 1rem;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.5rem;
    cursor: pointer;
    line-height: 1;
    padding: 0.25rem;
}

.sponsor-modal-close:hover {
    color: var(--text-primary);
}

.sponsor-modal-options {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: clamp(min(300px, 100%), 80%, 100%);
}

.sponsor-option {
    display: block;
    padding: 1rem 1.25rem;
    border-radius: var(--border-radius);
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
}

.sponsor-option-kofi {
    background: rgba(255, 94, 91, 0.08);
    border: 1px solid rgba(255, 94, 91, 0.3);
}

.sponsor-option-kofi:hover {
    background: rgba(255, 94, 91, 0.15);
    border-color: rgba(255, 94, 91, 0.5);
}

.sponsor-option-github {
    background: rgba(168, 85, 247, 0.08);
    border: 1px solid rgba(168, 85, 247, 0.3);
}

.sponsor-option-github:hover {
    background: rgba(168, 85, 247, 0.15);
    border-color: rgba(168, 85, 247, 0.5);
}

.sponsor-option-name {
    display: block;
    font-weight: 600;
    font-size: 1rem;
    margin-bottom: 0.25rem;
}

.sponsor-option-kofi .sponsor-option-name {
    color: #ff5e5b;
}

.sponsor-option-github .sponsor-option-name {
    color: var(--purple-light);
}

.sponsor-option-desc {
    display: block;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    line-height: 1.4;
}

@media (max-width: 768px) {
    .sponsor-modal {
        padding: 1.5rem;
        margin: 1rem;
        max-width: 480px;
    }
}

/* Loading State */
.loading-state {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 2rem;
    color: var(--text-secondary);
    min-height: 150px;
}

.loading-container {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--text-secondary);
}

/* Empty State */
.empty-state {
    text-align: center;
    padding: 3rem 2rem;
    color: var(--text-secondary);
    font-size: 0.92rem;
}

/* For an empty state inside a card that is already one of several on a page, where the full-page
   version's 3rem reads as a hole rather than breathing room. Both classes so it beats .empty-state
   on specificity rather than on source order. */
.empty-state.empty-state-small {
    padding: 1.5rem;
}

.empty-state.empty-state-small .empty-icon {
    font-size: 2rem;
}

.empty-state .empty-icon {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.5;
}

.empty-state .empty-icon-img {
    margin-bottom: 0;
}

.empty-state .empty-icon-img img {
    width: 100px;
    height: 100px;
    opacity: 0.5;
}

.empty-state h3 {
    color: var(--text-primary);
    margin-bottom: 0.5rem;
}

.empty-state p {
    margin-bottom: 1.5rem;
    font-size: 0.8125rem;
}

/* Status indicators for disconnected state */
.status-disconnected {
    color: var(--text-muted);
}

.status-disconnected .status-icon {
    color: var(--text-muted);
}

/* SQM unavailable state */
.sqm-unavailable {
    padding: 1rem;
    text-align: center;
}

.sqm-unavailable .status-message {
    color: var(--text-secondary);
    margin: 1rem 0;
    font-size: 0.8125rem;
}

/* SQM not deployed state */
.sqm-not-deployed {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    text-align: center;
}

.not-deployed-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.not-deployed-icon {
    width: 48px;
    height: 48px;
    opacity: 0.6;
}

.not-deployed-text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.not-deployed-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.not-deployed-message {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.status-not-configured {
    color: var(--text-muted);
}

.status-unavailable {
    color: var(--warning-color);
}

/* TC Interfaces Grid */
.tc-interfaces-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1rem;
    margin: 1rem 0;
}

.tc-interface-card {
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    padding: 1rem;
    text-align: center;
    border: 1px solid var(--border-color);
}

.tc-interface-card.inactive {
    opacity: 0.6;
}

.interface-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

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

.interface-status {
    font-size: 0.75rem;
    padding: 0.125rem 0.5rem;
    border-radius: var(--border-radius);
    background: var(--bg-secondary);
}

.interface-status.status-active {
    background: rgba(36, 188, 112, 0.2);
    color: var(--success-color);
}

.interface-status.status-not_found {
    background: rgba(239, 68, 68, 0.2);
    color: var(--danger-color);
}

.interface-rate {
    margin: 0.75rem 0 0.25rem;
}

.interface-rate .rate-value {
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--accent-color);
}

.interface-rate .rate-unit {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin-left: 0.25rem;
}

@media (max-width: 768px) {
    .interface-header {
        flex-direction: column;
        gap: 0.5rem;
    }
}

.interface-details {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    color: var(--text-muted);
    font-size: 0.75rem;
}

.rate-raw {
    color: var(--text-secondary);
}

.tc-timestamp {
    color: var(--text-muted);
}

/* Spinner small */
.spinner-sm {
    display: inline-block;
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    border: 2px solid var(--text-muted);
    border-top-color: transparent;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.btn .spinner-sm {
    border-color: rgba(255, 255, 255, 0.4);
    border-top-color: white;
}

.status-offline {
    color: var(--danger-color);
}

/* Accent Highlight Box (Ozark Connect style) */
.highlight-box {
    background: rgba(249, 115, 22, 0.1);
    border-left: 4px solid var(--accent-color);
    padding: 1rem 1.25rem;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    margin: 1rem 0;
}

.highlight-box p {
    color: var(--accent-color);
    font-weight: 500;
    margin: 0;
}

/* Accent Links */
.link-accent {
    color: var(--accent-color);
    text-decoration: none;
    transition: color 0.15s ease-out;
}

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

/* Primary Links (for light elements on dark bg) */
.link-primary {
    color: var(--primary-color);
    text-decoration: none;
    transition: color 0.15s ease-out;
}

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

/* Accent Text */
.text-accent {
    color: var(--accent-color);
}

.text-primary-brand {
    color: var(--primary-color);
}

/* Stat Value Accent (for prominent numbers) */
.stat-value-accent {
    color: var(--accent-color);
}

/* Audit Issue Context Styles */
.issue-context {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin: 0.75rem 0;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.875rem;
}

.issue-context .context-item {
    display: inline-flex;
    gap: 0.25rem;
}

.issue-context .context-item strong {
    color: var(--text-muted);
}

/* ============================================
   Ozark Connect Gradient & Accent Styles
   ============================================ */

/* Gradient Backgrounds */
.bg-gradient-primary {
    background: linear-gradient(135deg, var(--primary-color) 0%, #0466e0 100%);
}

.bg-gradient-hero {
    background: linear-gradient(135deg, rgba(5, 89, 201, 0.1) 0%, transparent 100%);
}

/* Info Box (Blue - Ozark Connect style) */
.info-box {
    background: rgba(5, 89, 201, 0.08);
    border-left: 4px solid var(--primary-color);
    padding: 1rem 1.25rem;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    margin: 1rem 0;
}

.info-box p {
    color: var(--text-primary);
    margin: 0;
}

.info-box strong {
    color: var(--primary-color);
}

/* Callout Box (Orange highlight - Ozark Connect style) */
.callout-box {
    background: rgba(249, 115, 22, 0.08);
    border-left: 4px solid var(--accent-color);
    padding: 1rem 1.25rem;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    margin: 1rem 0;
}

.callout-box p {
    color: var(--text-primary);
    margin: 0;
}

.callout-box strong {
    color: var(--accent-color);
}

/* Feature Badge (Ozark Connect style) */
.feature-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--bg-tertiary);
    padding: 0.5rem 1rem;
    border-radius: 2rem;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-primary);
}

.feature-badge .badge-icon {
    color: var(--primary-color);
}

/* Card with gradient header */
.card-gradient-header {
    background: linear-gradient(135deg, var(--primary-color) 0%, #0466e0 100%);
    color: white;
    padding: 1.5rem;
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

.card-gradient-header h3 {
    color: white;
    margin: 0;
}

/* ============================================
   Speed Test Results Component
   ============================================ */

/* Color variables for speed test */
:root {
    --speed-upload-color: var(--success-color);    /* green - To Device */
    --speed-download-color: var(--primary-hover);  /* blue - From Device */
}

.speed-results {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    margin: 1rem 0;
    position: relative;
}

.speed-results > .detail-actions {
    position: absolute;
    right: 1.25rem;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.speed-result {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1.25rem;
    background: var(--bg-card);
    border-radius: var(--border-radius);
    min-width: 180px;
}

#latest-result .speed-result {
    background: var(--bg-tertiary);
}

#latest-result .tooltip-icon {
    background: var(--bg-secondary);
}

.speed-result.upload {
    border-left: 4px solid var(--speed-upload-color);
}

.speed-result.upload .speed-icon,
.speed-result.upload .speed-value {
    color: var(--speed-upload-color);
}

.speed-result.download {
    border-left: 4px solid var(--speed-download-color);
}

.speed-result.download .speed-icon,
.speed-result.download .speed-value {
    color: var(--speed-download-color);
}

.speed-icon {
    font-size: 1.5rem;
    font-weight: bold;
    place-content: center;
    display: flex;
}

.speed-details,
.speed-info {
    display: flex;
    flex-direction: column;
}

.speed-label {
    font-size: 0.75rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.2rem;
}

.speed-value {
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 0.8;
}

.speed-value.speed-down {
    color: var(--speed-download-color);
}

.speed-value.speed-up {
    color: var(--speed-upload-color);
}

.speed-details .speed-value {
    font-size: 1.25rem;
}

.speed-unit {
    font-size: 0.875rem;
    font-weight: normal;
    color: var(--text-secondary);
    vertical-align: baseline;
}

.speed-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.375rem;
}

.retransmits-info {
    text-align: center;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
    font-size: 0.8rem;
}

.test-timestamp {
    text-align: center;
    color: var(--text-muted);
    margin-top: 0.5rem;
}

.test-details {
    display: flex;
    gap: 1rem 2rem;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    color: var(--text-secondary);
    font-size: 0.875rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
    text-align: center;
}

.test-details code {
    background: var(--bg-primary);
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
}

.btn-action-icon {
    background: none;
    border: none;
    padding: 0.25rem;
    cursor: pointer;
    color: var(--text-muted);
    opacity: 0.6;
    transition: opacity 0.15s, color 0.15s;
    display: flex;
    align-items: center;
}

.btn-action-icon:hover {
    opacity: 1;
    color: var(--primary-color);
}

.btn-action-danger:hover {
    color: var(--danger-color);
}

.btn-action-icon:disabled {
    cursor: wait;
    opacity: 0.4;
}

.btn-action-label {
    background: none;
    border: none;
    padding: 0.25rem 0.375rem;
    cursor: pointer;
    color: var(--text-muted);
    opacity: 0.6;
    transition: opacity 0.15s, color 0.15s;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
}

.btn-action-label:hover {
    opacity: 1;
    color: var(--primary-color);
}

.detail-actions .wan-reassign-overlay {
    position: fixed;
    inset: 0;
    z-index: 99;
}

.wan-reassign-select {
    position: relative;
    z-index: 100;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    padding: 0.25rem 0.5rem;
    font-size: 0.8rem;
    cursor: pointer;
}

.wan-reassign-select:focus {
    outline: none;
    border-color: var(--primary-color);
}

.wan-reassign-select option {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.detail-actions .wan-saved-indicator {
    font-size: 0.7rem;
    color: var(--success-color);
    opacity: 0.8;
}

.detail-actions .spinner-sm {
    width: 14px;
    height: 14px;
    border: 2px solid var(--border-color);
    border-top-color: var(--text-muted);
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
}

/* Speed test result notes */
.result-notes {
    flex: 1;
    position: relative;
    min-width: 150px;
}

.notes-input {
    width: 100%;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--border-radius);
    padding: 0.25rem 0.5rem;
    font-family: inherit;
    font-size: 0.8125rem;
    color: var(--text-primary);
    resize: none;
    min-height: 2.5rem;
    transition: border-color 0.15s, background-color 0.15s;
}

.notes-input:focus {
    outline: none;
    border-color: var(--primary-color);
    background: rgba(255, 255, 255, 0.08);
}

.notes-input::placeholder {
    color: var(--text-muted);
    opacity: 0.75;
}

.notes-status {
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.notes-status.saving {
    color: var(--text-muted);
}

.notes-status.saved {
    color: var(--success-color);
}

.show-mobile {
    display: none !important;
}

.btn-label-compact {
    display: none;
}

.col-actions {
    width: 1%;
    white-space: nowrap;
}

@media (max-width: 768px) {
    .col-actions {
        width: auto;
        white-space: normal;
    }

    .speed-results {
        flex-direction: column;
        align-items: center;
        gap: 1rem;
    }

    .test-details {
        gap: 0.5rem 1rem;
    }

    .test-details > span {
        min-width: 34%;
        text-align: center;
    }

    .speed-results > .detail-actions {
        position: static;
        transform: none;
        width: 100%;
        justify-content: center;
    }

    .hide-mobile {
        display: none !important;
    }

    .show-mobile {
        display: table-cell !important;
    }

    .btn-label-full {
        display: none;
    }

    .btn-label-compact {
        display: inline;
    }

    .host-truncate {
        display: inline-block;
        max-width: 125px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        vertical-align: bottom;
    }

    .speedtest-container .data-table,
    .client-speedtest-container .data-table {
        min-width: 350px;
    }

    .table-responsive {
        padding: 0;
    }

    [class*="badge-vpn-"] {
        margin-bottom: 0.25rem;
    }

    .data-table th,
    .data-table td {
        padding: 0.75rem 0.4rem;
    }

    .data-table .col-time {
        width: auto;
    }

    td .btn {
        margin: 0 auto;
    }

    td .btn + .btn {
        margin: 0 auto;
    }
}

/* Path Analysis - Redesigned */
.path-analysis {
    margin-top: 1.25rem;
    padding: 1rem 1rem 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.875rem;
}

.history-details .test-details {
    position: relative;
    border-top: 1px solid var(--bg-card);
    padding-left: 1rem;
    padding-right: 1rem;
}

.history-details .path-analysis {
    margin-top: 0rem;
    padding-bottom: 0.25rem;
}

.path-analysis .path-summary {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.path-analysis .path-max-speed {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.75rem 1rem;
    background: var(--bg-card);
    border-radius: 6px;
    min-width: 80px;
}

.path-analysis .path-max-speed .speed-value {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.25rem;
}

/* Directional speed colors for asymmetric links (matching speed-results) */
.path-analysis .path-max-speed .speed-from {
    color: var(--speed-download-color);  /* blue - From Device (↓) */
}

.path-analysis .path-max-speed .speed-to {
    color: var(--speed-upload-color);    /* green - To Device (↑) */
}

.path-analysis .path-max-speed .speed-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    margin-bottom: 0;
}

.path-analysis .efficiency-grades {
    display: flex;
    gap: 0.5rem;
}

.path-analysis .grade-badge {
    padding: 0.35rem 0.6rem;
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: help;
}

.grade-excellent { background: rgba(36, 188, 112, 0.2); color: var(--success-color); }
.grade-good { background: rgba(59, 130, 246, 0.2); color: #3b82f6; }
.grade-fair { background: rgba(234, 179, 8, 0.2); color: #eab308; }
.grade-poor { background: rgba(249, 115, 22, 0.2); color: #f97316; }
.grade-critical { background: rgba(239, 68, 68, 0.2); color: #ef4444; }

/* Path Visualization */
.path-analysis .path-visualization {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
    padding: 0.75rem;
    background: var(--bg-card);
    border-radius: 6px;
    row-gap: 0.75rem;
}

.path-analysis .path-hop {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.6rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    white-space: nowrap;
    min-height: 41px;
    z-index: 1;
}

.path-analysis .path-hop .hop-icon {
    font-size: 0.9rem;
    cursor: default;
}

.path-analysis .path-hop .hop-name {
    color: var(--text-primary);
    font-weight: 500;
    cursor: default;
}

.path-analysis .path-hop[data-tooltip] {
    cursor: pointer;
}
.path-analysis .path-hop[data-tooltip] .hop-icon,
.path-analysis .path-hop[data-tooltip] .hop-name {
    cursor: pointer;
}

.path-analysis .path-hop.bottleneck {
    border: 1px solid var(--warning-color);
}

.path-analysis .path-connector {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 0.2rem;
    margin-top: 1rem;
    gap: 0.1rem;
}

.path-analysis .path-connector .connector-line {
    width: calc(100% + 23px);
    height: 2px;
    background: #3b82f6;
    position: relative;
    z-index: 0;
}

.path-analysis .path-connector .connector-line::after {
    content: '';
    position: absolute;
    right: 0;
    top: -3px;
    border: 4px solid transparent;
    border-left-color: #3b82f6;
}

.path-analysis .path-connector .connector-speed {
    font-size: 0.6rem;
    color: var(--primary-lighter);
    white-space: nowrap;
    cursor: default;
}

.path-analysis .path-connector .connector-speed-spacer {
    display: none;
}

.path-analysis .path-connector.bottleneck .connector-line {
    background: var(--warning-color);
}

.path-analysis .path-connector.bottleneck .connector-line::after {
    border-left-color: var(--warning-color);
}

.path-analysis .path-connector.bottleneck .connector-speed {
    color: var(--warning-color);
    font-weight: 500;
}

/* Wireless link indicator - shows wifi icon above the connector line */
.path-analysis .path-connector.wireless {
    position: relative;
}

.path-analysis .path-connector[data-tooltip] {
    cursor: pointer;
}
.path-analysis .path-connector[data-tooltip] .connector-speed {
    cursor: pointer;
}

.path-analysis .path-connector .wireless-icon {
    position: absolute;
    top: -1.05rem;
    left: 50%;
    transform: translateX(-50%);
    line-height: 1;
    cursor: pointer;
}

/* Mini signal strength bars on wireless connectors */
.mini-signal-bars {
    display: flex;
    align-items: flex-end;
    gap: 0.1rem;
    height: 14px;
}
.mini-signal-bars .bar {
    width: 3px;
    border-radius: 1px;
    background: rgba(255,255,255,0.15);
}
.mini-signal-bars .bar:nth-child(1) { height: 20%; }
.mini-signal-bars .bar:nth-child(2) { height: 40%; }
.mini-signal-bars .bar:nth-child(3) { height: 60%; }
.mini-signal-bars .bar:nth-child(4) { height: 80%; }
.mini-signal-bars .bar:nth-child(5) { height: 100%; }
.mini-signal-bars.signal-excellent .bar.active { background: #10b981; }
.mini-signal-bars.signal-good .bar.active { background: #22c55e; }
.mini-signal-bars.signal-fair .bar.active { background: #eab308; }
.mini-signal-bars.signal-weak .bar.active { background: #f97316; }
.mini-signal-bars.signal-poor .bar.active { background: #ef4444; }

/* Path row - base styling (always flex) */
.path-analysis .path-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0;
}

/* Switchback layout - snake pattern for multi-row traces */
.path-analysis .path-visualization.path-switchback {
    flex-wrap: nowrap;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-bottom: 1rem;
}

.path-analysis .path-switchback .path-row {
    padding: 0.5rem 0;
    position: relative;
    width: 100%;
}

/* First row aligns left with margin */
.path-analysis .path-switchback .path-row:not(.reversed) {
    justify-content: flex-start;
    margin-left: 0.75rem;
}

/* Reversed rows start from right, turn exits on left */
.path-analysis .path-switchback .path-row.reversed {
    justify-content: flex-end;
    align-self: flex-end;
    margin-right: 0.75rem;
}

/* Left-pointing arrows for reversed rows */
.path-analysis .path-connector.arrow-left .connector-line::after {
    right: auto;
    left: 0;
    border-left-color: transparent;
    border-right-color: #3b82f6;
}

.path-analysis .path-connector.arrow-left.bottleneck .connector-line::after {
    border-right-color: var(--warning-color);
}

/* Turn connector - L-shaped corner going down then across */
.path-analysis .path-connector.path-turn {
    position: relative;
    flex-grow: 0.7;
    margin-left: -2px;
}

/* Extend the connector line to the edge for turn connectors */
.path-analysis .path-connector.path-turn .connector-line {
    width: calc(101% + 18px);
    min-width: 3rem;
}

.path-analysis .path-connector.path-turn .turn-corner {
    position: absolute;
    width: 2px;
    background: #3b82f6;
    right: -8px;
    top: 0;
    height: calc(100% + 2.55rem);
}

/* Horizontal part of the L at the bottom - extends left to meet next row */
.path-analysis .path-connector.path-turn .turn-corner::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 4.25rem;
    height: 2px;
    background: #3b82f6;
}

/* Turn from left side (reversed rows going to next row) - mirrored */
.path-analysis .path-connector.path-turn.turn-left {
    flex-grow: 0.7;
    margin-left: 0;
    margin-right: -2px;
}

.path-analysis .path-connector.path-turn.turn-left .connector-line {
    width: calc(101% + 18px);
}

/* Arrow on turn-left: positioned on left end, pointing left (into the turn) */
.path-analysis .path-connector.path-turn.turn-left .connector-line::after {
    right: auto;
    left: 0;
    border-left-color: transparent;
    border-right-color: #3b82f6;
}

.path-analysis .path-connector.path-turn.turn-left.bottleneck .connector-line::after {
    border-right-color: var(--warning-color);
}

.path-analysis .path-connector.path-turn.turn-left .turn-corner {
    right: auto;
    left: -8px;
}

.path-analysis .path-connector.path-turn.turn-left .turn-corner::after {
    right: auto;
    left: 0;
}

.path-analysis .path-connector.path-turn.bottleneck .turn-corner,
.path-analysis .path-connector.path-turn.bottleneck .turn-corner::after {
    background: var(--warning-color);
}

/* Mobile adjustments */
@media (max-width: 768px) {
    /* Wrap path-summary (grades + notes) on mobile */
    .path-analysis .path-summary {
        flex-wrap: wrap;
        justify-content: center;
    }

    .path-analysis .path-summary .result-notes {
        flex-basis: 100%;
        min-width: 0;
    }

    .path-analysis .path-max-speed {
        padding: 0.75rem 0.5rem;
    }

    .path-analysis .path-max-speed .speed-value {
        font-size: 1rem;
    }

    .path-analysis .grade-badge {
        padding: 0.35rem 0.4rem;
    }

    /* Mobile: simple vertical stack layout */
    .path-analysis .path-visualization {
        flex-direction: column;
        align-items: center;
    }

    .path-analysis .path-visualization.path-switchback {
        align-items: center;
    }

    .path-analysis .path-switchback .path-row {
        flex-direction: column;
        align-items: center;
        justify-content: center !important;
        align-self: center !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
        width: auto;
    }

    /* Undo server-side reversal on mobile - reverse back to normal order */
    .path-analysis .path-switchback .path-row.reversed {
        flex-direction: column-reverse;
        padding-top: 0;
    }

    .path-analysis .path-row {
        flex-direction: column;
        align-items: center;
    }

    /* Vertical connectors on mobile */
    .path-analysis .path-connector {
        transform: rotate(90deg);
        margin: 0.25rem 0;
    }

    /* Fixed width for connector lines on mobile */
    .path-analysis .path-connector .connector-line,
    .path-analysis .path-connector.path-turn .connector-line,
    .path-analysis .path-connector.path-turn.turn-left .connector-line {
        width: 43px;
        min-width: 0;
    }

    /* Reset arrow direction on mobile - all arrows point same way (down after rotation) */
    .path-analysis .path-connector.arrow-left .connector-line::after {
        right: 0;
        left: auto;
        border-right-color: transparent;
        border-left-color: #3b82f6;
    }

    .path-analysis .path-connector.arrow-left.bottleneck .connector-line::after {
        border-right-color: transparent;
        border-left-color: var(--warning-color);
    }

    /* Reset turn-left arrow direction on mobile - all arrows point same way (down after rotation) */
    .path-analysis .path-connector.path-turn.turn-left .connector-line::after {
        right: 0;
        left: auto;
        border-right-color: transparent;
        border-left-color: #3b82f6;
    }

    .path-analysis .path-connector.path-turn.turn-left.bottleneck .connector-line::after {
        border-left-color: var(--warning-color);
    }

    /* Remove top padding on subsequent rows */
    .path-analysis .path-switchback .path-row + .path-row {
        padding-top: 0;
    }

    /* Hide turn connectors on mobile - not needed for vertical layout */
    .path-analysis .path-connector.path-turn .turn-corner {
        display: none;
    }

    /* Position speed badges beside connector on mobile */
    .path-analysis .path-connector .connector-speed {
        transform: rotate(-90deg);
        position: absolute;
        top: 28px;
        width: 60px;
        text-align: end;
    }

    /* Spacer holds vertical space for the absolute-positioned speed label */
    .path-analysis .path-connector .connector-speed-spacer {
        display: block;
        visibility: hidden;
        font-size: 0.6rem;
    }

    /* Reset turn connector margins on mobile */
    .path-analysis .path-connector.path-turn {
        margin-left: 0;
    }

    .path-analysis .path-connector.path-turn.turn-left {
        margin-right: 0;
    }

    /* Counter-rotate wireless icon to stay upright when connector is rotated */
    .path-analysis .path-connector .wireless-icon {
        top: -1.2rem;
        left: 43%;
        transform: translateX(-50%) rotate(-90deg);
    }

}

/* Wi-Fi tooltip styling */
.wifi-tooltip-header {
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
    color: var(--text-primary);
}

.wifi-tooltip-row {
    font-size: 0.8rem;
    color: var(--text-secondary);
    margin-bottom: 0.2rem;
}

.wifi-tooltip-signal {
    color: var(--primary-light);
}

.wifi-tooltip-speed {
    color: #4ade80;
    font-weight: 500;
}

.wifi-tooltip-divider {
    height: 1px;
    background: rgba(148, 163, 184, 0.2);
    margin: 0.4rem 0;
}

.wifi-tooltip-link {
    font-size: 0.8rem;
    margin-bottom: 0.15rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.wifi-tooltip-mlo-link + .wifi-tooltip-mlo-link {
    margin-top: 0.35rem;
}

.wifi-tooltip-link-signal {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
    padding-left: 0.25rem;
}

/* The dBm reading is the payload of a signal line; only the SNR/channel context stays muted */
.wifi-tooltip-signal-value {
    color: var(--text-secondary);
}

.wifi-tooltip-ch {
    color: var(--text-secondary);
}

.wifi-tooltip-link-speed {
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-bottom: 0.15rem;
    padding-left: 0.25rem;
}

.wifi-speed-rx {
    color: var(--speed-download-color);
}

.wifi-speed-tx {
    color: var(--speed-upload-color);
}

.wifi-tooltip-bottleneck {
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    color: var(--warning-color);
    font-size: 0.75rem;
    font-weight: 500;
}

.wifi-band-badge {
    display: inline-block;
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 600;
}

.wifi-band-badge.wifi-band-ng {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.wifi-band-badge.wifi-band-na {
    background: rgba(59, 130, 246, 0.2);
    color: var(--primary-light);
}

.wifi-band-badge.wifi-band-6e {
    background: rgba(168, 85, 247, 0.2);
    color: var(--purple-light);
}

/* Device tooltip styling (path visualization) */
.device-tooltip-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    margin-bottom: 0.15rem;
    color: var(--text-secondary);
}

.device-tooltip-row:last-child {
    margin-bottom: 0;
}

.device-tooltip-label {
    color: var(--text-secondary);
    font-weight: 500;
}

.wifi-tooltip-client-link {
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    color: var(--primary-light);
    font-size: 0.75rem;
}

.device-tooltip-link {
    color: var(--primary-light);
    font-size: 0.75rem;
    margin-top: 0.25rem;
}

/* Client name links to Wi-Fi Optimizer */
a.client-link {
    color: var(--primary-hover);
    text-decoration: none;
}

a.client-link:visited {
    color: var(--primary-hover);
}

a.client-link:hover {
    color: var(--accent-color);
    text-decoration: underline;
}

/* Clickable hop (wireless client linking to Wi-Fi Optimizer) */
a.path-hop.hop-clickable {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}
a.path-hop.hop-clickable .hop-icon,
a.path-hop.hop-clickable .hop-name {
    cursor: pointer;
}

a.path-hop.hop-clickable:hover {
    border-color: var(--primary-light);
    background: rgba(59, 130, 246, 0.15);
}

/* VPN hop icons (Teleport, Tailscale, generic VPN) */
.vpn-icon {
    color: currentColor;
    vertical-align: middle;
    display: inline-block;
}

.vpn-shield-icon {
    width: 24px;
    height: 24px;
    object-fit: contain;
}

.path-analysis .path-hop.hop-teleport {
    background: rgba(168, 85, 247, 0.15);
    border-color: rgba(168, 85, 247, 0.3);
}

.path-analysis .path-hop.hop-teleport .hop-icon {
    color: var(--purple-light);
}

.path-analysis .path-hop.hop-tailscale {
    background: rgba(59, 130, 246, 0.15);
    border-color: rgba(59, 130, 246, 0.3);
}

.path-analysis .path-hop.hop-tailscale .hop-icon {
    color: var(--primary-light);
}

.path-analysis .path-hop.hop-wan {
    background: rgba(125, 211, 252, 0.15);
    border-color: rgba(125, 211, 252, 0.3);
}

.path-analysis .path-hop.hop-wan .hop-icon {
    color: #7dd3fc;
}

.path-analysis .path-hop.hop-vpn {
    background: rgba(20, 184, 166, 0.15);
    border-color: rgba(20, 184, 166, 0.3);
}

.path-analysis .path-hop.hop-vpn .hop-icon {
    color: #2dd4bf;
}

/* Warnings and badges */
.path-analysis .bottleneck-warning {
    padding: 0.5rem 0.75rem;
    background: rgba(234, 179, 8, 0.1);
    border-left: 3px solid var(--warning-color);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    font-size: 0.8rem;
    color: var(--warning-color);
    margin-bottom: 0.5rem;
    white-space: normal;
}

.path-analysis .routing-badge {
    display: inline-block;
    padding: 0.3rem 0.6rem;
    background: rgba(59, 130, 246, 0.2);
    border: 1px solid rgba(59, 130, 246, 0.4);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--primary-lighter);
    margin-bottom: 0.5rem;
}

.path-analysis .path-error {
    padding: 0.75rem;
    background: rgba(239, 68, 68, 0.1);
    border-radius: var(--border-radius);
    color: var(--text-muted);
    font-size: 0.85rem;
    margin-bottom: 0.75rem;
}

/* Notes section */
.path-analysis .path-notes {
    border-top: 1px solid var(--border-color);
    white-space: normal;
}

.path-analysis .note {
    font-size: 0.8rem;
    color: var(--text-secondary);
    padding: 0.25rem 0;
}

.path-analysis .note::before {
    content: '';
    display: inline-block;
    width: 18px;
    height: 18px;
    margin-right: 0.35rem;
    vertical-align: -4px;
    background: currentColor;
    -webkit-mask: var(--note-icon) center/contain no-repeat;
    mask: var(--note-icon) center/contain no-repeat;
}

/* Info circle icon for insights */
.path-analysis .note.insight {
    --note-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E");
}

/* Trending up arrow for recommendations */
.path-analysis .note.recommendation {
    color: var(--primary-lighter);
    --note-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='23 6 13.5 15.5 8.5 10.5 1 18'/%3E%3Cpolyline points='17 6 23 6 23 12'/%3E%3C/svg%3E");
}

.test-error {
    padding: 1rem;
    background: rgba(239, 68, 68, 0.1);
    border-radius: var(--border-radius);
    color: var(--danger-color);
    font-size: 0.9rem;
}

.no-results {
    padding: 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* History Table Expandable Rows */
.history-row-clickable {
    cursor: pointer;
    transition: background 0.15s ease;
}

.history-row-clickable:hover {
    background: var(--bg-hover);
}

.history-row-expanded {
    background: var(--bg-hover);
}

.data-table tr.history-row-expanded:hover {
    background: var(--bg-row-expanded-hover);
}

.history-details-row {
    background: var(--bg-hover);
}

.expand-chevron {
    width: 2rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.75rem;
}

.history-details-row {
    background: var(--bg-tertiary);
}

/* Direct child only. As a descendant selector this zeroed the padding of every cell in any table
   rendered inside a details row - and the !important meant nothing could win it back. */
.history-details-row > td {
    padding: 0 !important;
}

.history-details-row .expand-wrapper.expanded {
    border-top: 1px solid var(--border-color);
}

.history-details {
    padding: 2px 0 0;
    margin-bottom: 0.5rem;
}

/* ============================================
   Pagination Component
   ============================================ */

.pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1rem;
    margin-top: 1rem;
}

.pagination-info {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

/* Sits inside the history card rather than between sections, so it needs the room underneath. */
.history-pagination {
    margin-bottom: 1rem;
}

.pag-arrow {
    position: relative;
    top: -1px;
}

/* ============================================
   Result Summary (compact link to full result)
   ============================================ */

/* Expandable result box - unified container for summary + details */
.result-box {
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    margin: 1rem 0 0;
    cursor: pointer;
    transition: background 0.15s ease-out;
}

.result-box:hover {
    background: var(--bg-hover);
}

.result-box-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
}

.result-box-right {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.result-box-details {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.25s ease-out;
}

.result-box.expanded .result-box-details {
    grid-template-rows: 1fr;
}

.result-box-details-inner {
    overflow: hidden;
    padding: 0 1rem;
}

.result-box.expanded .result-box-details-inner {
    padding: 0 1rem 1rem;
}

/* Legacy result-summary for any remaining uses */
.result-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    text-decoration: none;
    color: var(--text-primary);
    transition: background 0.15s ease-out;
    margin: 1rem 0 0;
}

.result-summary:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.result-speeds {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    font-weight: 600;
}

.result-speed {
    font-size: 1.25rem;
}

.result-unit {
    font-size: 0.875rem;
    font-weight: normal;
    color: var(--text-secondary);
}

.result-time {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.result-summary {
    cursor: pointer;
}

.result-expand-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-left: 1rem;
}

/* Expandable details animation wrapper */
.expand-wrapper {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.25s ease-out;
}

.expand-wrapper.expanded {
    grid-template-rows: 1fr;
}

.expand-wrapper > .expand-content {
    overflow: hidden;
}

.result-expanded-details {
    padding: 1rem 0;
}

/* Form section header */
.form-section-header h5 {
    color: var(--text-primary);
}

.form-section-header .form-help {
    margin-bottom: 1rem;
    color: var(--text-muted);
}

.form-section-header a {
    color: var(--primary-color);
}

/* ============================================
   Blazor Reconnection Dialog (Dark Theme)
   ============================================ */
.components-reconnect-dialog {
    background-color: var(--bg-secondary) !important;
    color: var(--text-primary) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: var(--border-radius) !important;
    padding: 2rem !important;
    box-shadow: var(--shadow-lg) !important;
}

.components-reconnect-dialog p {
    color: var(--text-primary) !important;
    font-size: 1rem !important;
    font-weight: 500 !important;
}

.components-reconnect-dialog button {
    background: var(--primary-color) !important;
    color: white !important;
    border: none !important;
    border-radius: var(--border-radius) !important;
    padding: 0.625rem 1.25rem !important;
    font-weight: 600 !important;
    cursor: pointer !important;
}

.components-reconnect-dialog button:hover {
    background: var(--primary-hover) !important;
}

/* Blazor error UI */
#blazor-error-ui {
    background: var(--danger-color) !important;
    color: white !important;
    padding: 1rem;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10000;
    display: none;
}

#blazor-error-ui * {
    color: white !important;
}

#blazor-error-ui.show {
    display: block;
}

/* ============================================
   Audit Page Styles
   ============================================ */

/* Audit Controls Layout */
.audit-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1rem;
    padding-top: 1rem;
}

.audit-controls .btn {
    margin-right: 0.5rem;
}

/* Audit Options (Checkboxes) */
.audit-options {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-top: 1rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-color);
    width: 100%;
}

.audit-options .checkbox-label {
    gap: 0.625rem;
}

/* Settings - Automatic Blocking: divided sections like .audit-options, one target per block */
.automatic-blocking .ab-section,
.trusted-sources .ab-section,
.wan-flood .ab-section {
    border-top: 1px solid var(--border-color);
    padding-top: 1.25rem;
}

.automatic-blocking .ab-section-title,
.trusted-sources .ab-section-title,
.wan-flood .ab-section-title {
    font-size: 1rem;
    margin: 0 0 1rem;
}

/* WAN Flood Protection's Advanced: the guide's border-top already divides; its first section adds none. */
.wan-flood .setup-guide-content {
    padding-top: 1.25rem;
}

.wan-flood .setup-guide-content > .ab-section:first-child {
    border-top: none;
    padding-top: 0;
}

/* The guide's content is muted; section titles keep the card's own heading color. */
.wan-flood .setup-guide-content .ab-section-title {
    color: var(--text-primary);
}

.wan-flood .setup-guide {
    margin-bottom: 1.5rem;
}

.automatic-blocking .ab-section > .form-help,
.trusted-sources .ab-section > .form-help {
    margin: 0 0 1rem;
}

.automatic-blocking .ab-setup-hidden .form-help {
    margin: 0 0 0.5rem;
}

/* The form row above already ends in a 1.5rem margin; the guide sits on it and keeps one below. */
.automatic-blocking .setup-guide {
    margin: 0 0 1.5rem;
}

/* An option that belongs to the target above it: indented to its checkbox text. */
.automatic-blocking .ab-suboption {
    margin-left: 1.625rem;
}

/* The card's Save, set off from the last target's own buttons like a section. */
.automatic-blocking .ab-save,
.wan-flood .ab-save {
    border-top: 1px solid var(--border-color);
    padding-top: 1.25rem;
}

/* WAF card headers (Threat Intelligence Overview and the WAF page): paranoia beside the mode badge */
.waf-card-mode {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.waf-meta {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.automatic-blocking .ab-list {
    margin-bottom: 1rem;
}

/* Public Block Lists: the profile picker sits on the right of the section title */
.automatic-blocking .ab-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.automatic-blocking .ab-section-header .ab-section-title {
    margin: 0;
}

.automatic-blocking .ab-profile {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.automatic-blocking .ab-profile .form-control {
    width: auto;
}

.automatic-blocking .ab-saved {
    color: var(--success-color);
    font-size: 0.875rem;
    font-weight: 600;
}

.automatic-blocking .ab-token {
    margin-top: 0.5rem;
}

/* A form's bottom button row sits on the right on desktop (centered on mobile, as everywhere): every
   Settings card's last row, and any other form's row marked .form-footer. */
@media (min-width: 769px) {
    .settings-container > .card > .card-body > .action-buttons:not(:has(~ .action-buttons)),
    .action-buttons.form-footer {
        justify-content: flex-end;
    }
}

/* Settings - Monitoring: the auto-discovered modems heading shares its row with Scan for Modems */
.modem-discovery-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.modem-discovery-header h4 {
    margin: 0;
}

.modem-scan-result {
    color: var(--success-color);
    font-size: 0.875rem;
    font-weight: 600;
}

/* Its primary button, floated while the row is scrolled out of view (settings-section-save.js) */
.settings-floating-save {
    position: fixed;
    z-index: 900;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}

.settings-floating-save[hidden] {
    display: none;
}

/* How the floating Save went: a check, a cross, or a warning mark beside it */
.settings-floating-result {
    position: fixed;
    z-index: 900;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg-secondary);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}

.settings-floating-result[hidden] {
    display: none;
}

.settings-floating-result.is-success {
    color: var(--success-color);
}

.settings-floating-result.is-error {
    color: var(--danger-color);
}

.settings-floating-result.is-warning {
    color: var(--warning-color);
}

/* Threat Intelligence - Protection Setup checklist: one row per step, its action on the right */
.protection-setup .card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.protection-setup-count {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.protection-steps {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}

.protection-step {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.875rem;
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--border-color);
}

.protection-step:last-child {
    border-bottom: none;
}

.protection-step::before {
    content: "";
    flex: 0 0 auto;
    width: 0.875rem;
    height: 0.875rem;
    border-radius: 50%;
    border: 2px solid var(--text-muted);
}

.protection-step.is-done::before {
    border-color: var(--success-color);
    background: var(--success-color);
}

.protection-step.is-optional::before {
    border-style: dashed;
}

.protection-step-text {
    flex: 1 1 auto;
    min-width: 0;
}

.protection-step.is-done .protection-step-text {
    color: var(--text-secondary);
}

.protection-step .btn {
    flex: 0 0 auto;
}

.protection-optional {
    margin: 0 0 1rem;
}

.protection-hide {
    display: flex;
    justify-content: flex-end;
}

.protection-setup-done,
.wan-flood-status .wan-flood-summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .protection-step {
        flex-wrap: wrap;
    }

    .protection-step-text {
        flex-basis: calc(100% - 2.25rem);
    }

    .protection-step .btn {
        margin-left: 1.875rem;
    }
}
/* Settings - Trusted Sources: one block per site, its addresses in a table under it */
.trusted-sources .trusted-site {
    margin-bottom: 1.5rem;
}

.trusted-sources .trusted-site > .checkbox-label {
    margin-bottom: 0.5rem;
}

.trusted-sources .ab-status {
    color: var(--text-secondary);
}

/* Three short columns fit a phone; no sideways scroll like wider tables. */
.data-table.trusted-addresses {
    min-width: 0;
}

.data-table.trusted-addresses td {
    white-space: normal;
}

.data-table.trusted-addresses code {
    word-break: break-all;
}

.trusted-addresses .trusted-action {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

.trusted-addresses tr.trusted-stale td {
    color: var(--text-secondary);
}

.trusted-matrix .trusted-matrix-cell {
    text-align: center;
}

.trusted-matrix .table-responsive {
    margin-top: 0.5rem;
}

.automatic-blocking .ab-target {
    margin-bottom: 1.5rem;
}

.automatic-blocking .ab-status {
    color: var(--text-secondary);
}

.automatic-blocking .ab-status.is-ok {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--success-color);
}

.automatic-blocking .ab-check {
    flex: 0 0 auto;
}

.automatic-blocking .ab-status.is-warning {
    color: var(--warning-color);
}

.automatic-blocking .form-row,
.wan-flood .form-row,
.blocking-exception-form .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.automatic-blocking .form-row > .form-group,
.wan-flood .form-row > .form-group,
.blocking-exception-form .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

/* Blocking exceptions: the form keeps the form-group rhythm, so the panel's flex gap is off */
.site-config-panel.blocking-exception-form {
    gap: 0;
}

.blocking-exception-form > .section-description,
.blocking-exception-form > .alert {
    margin: 0 0 1rem;
}

.blocking-exceptions > .ab-status,
.blocking-exceptions > .form-error {
    margin-bottom: 1rem;
}

.blocking-exceptions-table .exc-arrow {
    margin: 0 0.35rem;
    color: var(--text-secondary);
}

.blocking-exceptions-table .exc-any {
    color: var(--text-secondary);
}

.blocking-exceptions-table .exc-detail {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.blocking-exceptions-table .exc-actions,
.drilldown-row-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

/* Stands in for Allow on a row an exception covers; the size of a .btn-sm so the row keeps its height. */
.exception-covered {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 28px;
    color: var(--success-color);
}

.exception-covered:hover {
    color: var(--text-primary);
}

/* Public Block List Drops: the Port column folds under the address on a phone, and the three columns
   left fit without the table's usual minimum width, so Allow stays in view. */
.public-list-drops .drop-port {
    display: none;
}

.data-table.public-list-drops-table {
    min-width: 0;
}

@media (max-width: 768px) {
    .public-list-drops .ip-client-name {
        display: block;
        margin-left: 0;
    }

    .public-list-drops .drop-port {
        display: block;
        margin-top: 0.15rem;
        font-size: 0.8rem;
        color: var(--text-secondary);
    }
}

/* Threat Intelligence header row: page tabs on the left, filters and time range on the right.
   Shared by the main page and the WAF page, so it lives here rather than in either page. */
.threat-header-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1rem;
    min-height: 34px;
}

.threat-header-bar > .wifi-view-tabs-wrapper {
    flex: 1 1 auto;
    min-width: 200px;
}

.threat-header-bar > div:last-child {
    margin-left: auto;
}

.threat-header-bar .wifi-tabs-scroll-btn {
    border-bottom: none;
    margin-top: 0.35rem;
}

.threat-controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

@media (max-width: 768px) {
    .threat-header-bar {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 0.5rem;
    }

    .threat-header-bar > div:last-child {
        margin-left: unset;
        justify-content: space-between;
    }

    .threat-time-preset {
        padding: 0.35rem 0.5rem;
        font-size: 0.75rem;
    }
}

/* Threat Intelligence stat tiles and paired tables: shared by the main page and the WAF page, so
   they live here rather than in either page's style block. */
.threat-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}

.threat-summary-grid .card {
    margin-bottom: 1.5rem;
}

.threat-summary-grid-compact .card {
    margin-bottom: 0.75rem;
}

.threat-stat-card {
    text-align: center;
    padding: 1.25rem 1rem;
}

.threat-stat-value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.3;
}

.threat-stat-label {
    font-size: 0.85rem;
    color: var(--text-muted);
}

.waf-stats {
    grid-template-columns: repeat(3, 1fr);
}

.threat-two-chart-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

@media (max-width: 768px) {
    .threat-summary-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .threat-two-chart-row {
        grid-template-columns: 1fr;
        margin-bottom: 1rem;
    }
}

/* The tiles' own 0.75rem margin plus this is the 1.5rem rhythm to the link. */
.waf-card-link {
    margin-top: 0.75rem;
}

/* Settings - Multi-Site: a site's Automatic Blocking in its Configuration panel */
.site-blocking .site-blocking-mode {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.site-blocking .site-blocking-mode .form-label {
    margin-bottom: 0;
}

.site-blocking .site-blocking-mode .form-control {
    width: auto;
}

/* The status line is its own row, not the toggle's help. */
.site-blocking .form-help {
    margin: 0.5rem 0;
}

/* Threat Intelligence - block one address from its details */
.ip-block-control {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.ip-block-control .ip-block-duration {
    width: auto;
    padding: 0.25rem 0.5rem;
    height: 28px;
}

.ip-block-control .ip-block-until,
.ip-block-control .ip-block-message {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.ip-block-message.is-ok {
    color: var(--success-color);
}

.ip-block-message.is-error {
    color: var(--danger-color);
}

/* Threat Intelligence - Blocked Sources */
/* WAN Flood Protection's status line keeps the connection table on its right edge; on a phone it wraps below. */
.wan-flood-status .wan-flood-summary {
    flex-wrap: wrap;
}

.wan-flood-status .wan-flood-summary .waf-meta {
    margin-left: auto;
}

@media (max-width: 768px) {
    .wan-flood-status .wan-flood-summary .waf-meta {
        flex-basis: 100%;
        margin-left: calc(8px + 0.5rem);
    }

    /* Two short columns are left on a phone (hide-mobile), so the tables fit without scrolling sideways. */
    .wan-flood-status .data-table {
        min-width: 0;
    }
}

.blocked-sources .blocked-sources-subtitle,
.wan-flood-status .wan-flood-subtitle {
    font-size: 0.95rem;
    margin: 1.5rem 0 0.75rem;
}

.blocked-sources .blocked-sources-dry,
.blocked-sources .blocked-sources-strikes {
    margin-left: 0.5rem;
}

.blocked-sources .blocked-sources-strikes {
    color: var(--warning-color);
    font-size: 0.8rem;
}

.blocked-sources .blocked-sources-skew {
    margin-left: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 400;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    cursor: help;
}

@media (max-width: 768px) {
    .automatic-blocking .form-row,
    .wan-flood .form-row,
    .blocking-exception-form .form-row {
        flex-direction: column;
        gap: 0;
    }

    .automatic-blocking .form-row > .form-group,
    .wan-flood .form-row > .form-group,
    .blocking-exception-form .form-row > .form-group {
        flex: 0 0 auto;
    }
}

@media (max-width: 768px) {
    .audit-controls,
    .gateway-actions {
        justify-content: center;
        padding-top: 0;
    }

    .audit-controls .btn,
    .gateway-actions .btn {
        margin-right: 0;
    }

    .audit-options,
    .diagnostics-options {
        justify-content: center;
        margin-top: 0.5rem;
    }
}

/* Audit Results Summary */
.results-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3rem;
    place-content: center;
}

@media (max-width: 768px) {
    .results-summary {
        gap: 1rem;
    }
}

.summary-score {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.score-circle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 130px;
    height: 130px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    border: 4px solid var(--border-color);
}

.score-circle.score-excellent {
    border-color: var(--success-color);
    background: rgba(36, 188, 112, 0.1);
}

.score-circle.score-good {
    border-color: var(--primary-color);
    background: rgba(5, 89, 201, 0.1);
}

.score-circle.score-fair {
    border-color: var(--warning-color);
    background: rgba(245, 158, 11, 0.1);
}

.score-circle.score-poor {
    border-color: var(--danger-color);
    background: rgba(239, 68, 68, 0.1);
}

.score-value {
    font-size: 2.5rem;
    font-weight: 600;
    color: var(--text-primary);
}

.score-max {
    font-size: 1rem;
    color: var(--text-muted);
    margin-left: 0.125rem;
}

.score-label {
    font-size: 0.875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
}

.score-excellent .score-label,
.summary-score:has(.score-excellent) .score-label {
    color: var(--success-color);
}

.score-good .score-label,
.summary-score:has(.score-good) .score-label {
    color: var(--primary-color);
}

.score-fair .score-label,
.summary-score:has(.score-fair) .score-label {
    color: var(--warning-color);
}

.score-poor .score-label,
.summary-score:has(.score-poor) .score-label {
    color: var(--danger-color);
}

/* Issue Counts */
.issue-counts {
    display: flex;
    gap: 2rem;
}

.issue-count {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 1rem 1.5rem;
    background: var(--bg-tertiary);
    border: 1px solid transparent;
    border-radius: var(--border-radius);
    min-width: 80px;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: border-color 0.15s ease;
}

.issue-count:hover,
.issue-count:focus-visible {
    border-color: var(--text-muted);
    outline: none;
}

.issue-count .count {
    font-size: 2rem;
    font-weight: 600;
    line-height: 1;
}

.issue-count .label {
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.issue-count.critical .count {
    color: var(--danger-color);
}

.issue-count.warning .count,
.issue-count.recommended .count {
    color: var(--warning-color);
}

.issue-count.info .count {
    color: var(--info-color);
}

/* Compact issue count for card headers */
/* Wi-Fi Optimizer - Health Issues card, Acknowledged tab */
.acknowledged-note {
    margin: 0 0 0.75rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* Inside Security Audit's issues list the list's own gap spaces it; no margin on top of that. */
.issues-list .acknowledged-note {
    margin-bottom: 0;
}

.issue-count-sm {
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem;
    font-weight: 500;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    color: var(--text-muted);
}

/* Audit Timestamp */
.audit-timestamp {
    font-size: 0.875rem;
    color: var(--text-muted);
}

/* ============================================
   Audit Detail Sections
   ============================================ */

/* Switch section */
.switch-section {
    margin-bottom: 2rem;
}

.switch-section:last-child {
    margin-bottom: 0;
}

.switch-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.switch-model {
    font-weight: 400;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.switch-note {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-style: italic;
    margin-top: 0.5rem;
}

/* AP section */
.ap-section {
    margin-bottom: 1.5rem;
}

.ap-section:last-child {
    margin-bottom: 0;
}

.ap-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.client-count {
    font-weight: 400;
    color: var(--text-muted);
    font-size: 0.875rem;
}

/* Port table - fixed column widths */
.port-table {
    table-layout: fixed;
}

.port-table th,
.port-table td {
    font-size: 0.8rem;
    padding: 0.4rem 0.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Switch port table columns: Port, Name, Link, PoE, Port Sec, Forward, Native VLAN, Status */
.port-table th:nth-child(1),
.port-table td:nth-child(1) { width: 5%; }   /* Port */
.port-table th:nth-child(2),
.port-table td:nth-child(2) { width: 18%; }  /* Name */
.port-table th:nth-child(3),
.port-table td:nth-child(3) { width: 8%; }   /* Link */
.port-table th:nth-child(4),
.port-table td:nth-child(4) { width: 6%; }   /* PoE */
.port-table th:nth-child(5),
.port-table td:nth-child(5) { width: 9%; }   /* Port Sec */
.port-table th:nth-child(6),
.port-table td:nth-child(6) { width: 10%; }  /* Forward */
.port-table th:nth-child(7),
.port-table td:nth-child(7) { width: 28%; }  /* Native VLAN */
.port-table th:nth-child(8),
.port-table td:nth-child(8) { width: 16%; }  /* Status */

/* Wireless client table - fixed column widths */
.wireless-client-table {
    table-layout: fixed;
}

.wireless-client-table th,
.wireless-client-table td {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Wireless client columns: Client, Type, Network, Status */
.wireless-client-table th:nth-child(1),
.wireless-client-table td:nth-child(1) { width: 35%; }  /* Client */
.wireless-client-table th:nth-child(2),
.wireless-client-table td:nth-child(2) { width: 20%; }  /* Type */
.wireless-client-table th:nth-child(3),
.wireless-client-table td:nth-child(3) { width: 25%; }  /* Network */
.wireless-client-table th:nth-child(4),
.wireless-client-table td:nth-child(4) { width: 20%; }  /* Status */

/* Offline client table - fixed column widths */
.offline-client-table {
    table-layout: fixed;
}

.offline-client-table th,
.offline-client-table td {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Offline client columns: Client, Type, Network, Last Seen, Status */
.offline-client-table th:nth-child(1),
.offline-client-table td:nth-child(1) { width: 30%; }  /* Client */
.offline-client-table th:nth-child(2),
.offline-client-table td:nth-child(2) { width: 18%; }  /* Type */
.offline-client-table th:nth-child(3),
.offline-client-table td:nth-child(3) { width: 22%; }  /* Network */
.offline-client-table th:nth-child(4),
.offline-client-table td:nth-child(4) { width: 13%; }  /* Last Seen */
.offline-client-table th:nth-child(5),
.offline-client-table td:nth-child(5) { width: 17%; }  /* Status */

/* Status classes */
.status-success {
    color: var(--success-color);
    font-weight: 500;
}

.status-warning {
    color: var(--warning-color);
    font-weight: 500;
}

.status-danger {
    color: var(--danger-color);
    font-weight: 500;
}

.status-neutral {
    color: var(--text-muted);
    font-weight: 500;
}

.row-warning {
    background-color: rgba(231, 150, 19, 0.1);
}

.row-warning td {
    border-color: rgba(231, 150, 19, 0.2);
}

.row-critical {
    background-color: rgba(218, 68, 68, 0.1);
}

.row-critical td {
    border-color: rgba(218, 68, 68, 0.2);
}

/* Hardening list */
.hardening-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.hardening-list li {
    padding: 0.5rem 0;
    padding-left: 1.5rem;
    position: relative;
    border-bottom: 1px solid var(--border-color);
}

.hardening-list li:last-child {
    border-bottom: none;
}

.hardening-list li::before {
    content: "✓";
    position: absolute;
    left: 0;
    color: var(--success-color);
    font-weight: bold;
}

/* DNS Security summary */
.dns-summary {
    margin-top: 1rem;
    padding: 0.75rem 1rem;
    border-radius: var(--border-radius);
    font-size: 0.9rem;
}

.dns-protected {
    background-color: rgba(36, 188, 112, 0.1);
    border: 1px solid rgba(36, 188, 112, 0.3);
    color: var(--success-color);
}

.dns-partial {
    background-color: rgba(231, 150, 19, 0.1);
    border: 1px solid rgba(231, 150, 19, 0.3);
    color: var(--warning-color);
}

/* ============================================
   Tooltip Icon Component (using Tippy.js)
   Interactive popovers with link support
   ============================================ */
.tooltip-wrapper {
    display: inline-flex;
    align-items: center;
}

.tooltip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    margin-left: 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--bg-tertiary);
    border-radius: 50%;
    cursor: pointer;
    vertical-align: middle;
    transition: all 0.15s ease-out;
    user-select: none;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
}

.tooltip-icon:hover {
    color: var(--text-primary);
    background: var(--primary-color);
}

/* Smaller tooltip icon for table cells and inline use */
.tooltip-icon-sm {
    width: 14px;
    height: 14px;
    font-size: 10px;
    margin-left: 3px;
    vertical-align: text-top;
}

/* In a heading, text-top rides above the capitals: center on them instead (-0.17em is measured on Inter at 18-19px). */
h2 > .tooltip-icon-sm,
h3 > .tooltip-icon-sm {
    vertical-align: middle;
    position: relative;
    top: -0.17em;
}

/* For icons sitting on an inner tertiary surface, where the default tertiary fill disappears. */
.tooltip-icon-contrast {
    background: var(--bg-elevated);
}

/* Hidden content element (Tippy reads innerHTML from this) */
.tooltip-content {
    display: none;
}

/* Tippy.js custom theme to match app styling */
.tippy-box[data-theme~='custom'] {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.5;
    box-shadow: var(--shadow-lg);
}

.tippy-box[data-theme~='custom'] .tippy-content {
    padding: 10px 14px;
}

.tippy-box[data-theme~='custom'] .tippy-arrow {
    color: var(--border-color);
}

/* The X on a tooltip that stays up (addTipClose in App.razor); the content keeps clear of it. */
.tippy-box[data-theme~='custom']:has(> .tip-close) .tippy-content {
    padding-right: 1.6rem;
}

.tippy-box[data-theme~='custom'] .tip-close {
    position: absolute;
    /* Above .tippy-content, which Tippy's own CSS lifts to z-index 1 and would take the click. */
    z-index: 2;
    top: 3px;
    right: 4px;
    width: 16px;
    height: 16px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 16px;
    cursor: pointer;
}

.tippy-box[data-theme~='custom'] .tip-close:hover {
    color: var(--text-primary);
}

/* Links inside Tippy tooltips */
.tippy-box[data-theme~='custom'] a {
    color: var(--primary-hover);
    text-decoration: none;
}

/* Two or more links on one card line (Live Traffic's destination card: Threats, Trace). */
.tippy-box[data-theme~='custom'] .tip-links { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.tippy-box[data-theme~='custom'] .tip-link-icon {
    margin-left: 0.15em;
    vertical-align: -1px;
}

/* Copy beside an address or domain on a Live Traffic hover card. */
.tippy-box[data-theme~='custom'] .tip-copy {
    display: inline-flex;
    align-items: center;
    margin-left: 0.3em;
    padding: 0 2px;
    border: 0;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    vertical-align: -1px;
}

.tippy-box[data-theme~='custom'] .tip-copy:hover {
    color: var(--text-primary);
}

.tippy-box[data-theme~='custom'] .tip-copy.is-copied {
    color: var(--success-color);
}

.tippy-box[data-theme~='custom'] a:hover {
    color: var(--accent-color);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.tippy-box[data-theme~='custom'] strong {
    color: var(--text-primary);
    font-weight: 600;
}

/* Alert with tooltip (SSH troubleshooting, etc.) */
.alert-with-tooltip {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.alert-with-tooltip .alert-text {
    flex: 1;
}

.alert-with-tooltip .tooltip-wrapper {
    flex-shrink: 0;
    margin-left: auto;
}

.alert-with-tooltip .tooltip-icon {
    width: 22px;
    height: 22px;
    font-size: 14px;
    margin-left: 0;
}

.alert-danger.alert-with-tooltip .tooltip-icon {
    background: var(--bg-secondary);
}

/* Wide tooltip content for detailed help */
.tippy-box[data-theme~='custom'].tooltip-wide {
    max-width: 360px;
}

/* ApexCharts sets pointer-events: none on every annotation label. The marks normally bind their
   tooltip to the label's background box instead (see hitTarget in chart-event-marks.js), so this
   only carries the fallback where that box is absent. Listed per container on purpose: ISP Health,
   latency and the WAN live chart draw annotations too and must keep the library's behaviour, so a
   card earns the unlock by being added here. The id also wins on specificity without !important. */
#device-health-charts-container .apexcharts-xaxis-annotation-label.chart-event-mark,
#sfp-charts-container .apexcharts-xaxis-annotation-label.chart-event-mark,
#ont-charts-container .apexcharts-xaxis-annotation-label.chart-event-mark {
    pointer-events: auto;
}

/* Chart event mark tooltips. Scoped to the tooltip rather than the chart card because Tippy
   renders the popper on document.body, outside the container entirely. Rows themselves reuse
   .device-tooltip-row / .device-tooltip-label, so a mark reads like the speed test and Wi-Fi
   tooltips do. */
.tippy-box[data-theme~='custom'] .chart-mark-title {
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
    color: var(--text-primary);
}

/* Semi-bold on the mark tooltips only. The shared .device-tooltip-label stays at its own weight
   so the speed test and Wi-Fi tooltips are untouched. */
.tippy-box[data-theme~='custom'] .chart-mark-row .device-tooltip-label {
    font-weight: 600;
}

/* Detail is prose rather than a value, so it wraps under its label instead of being squeezed
   into the value column beside it. */
.tippy-box[data-theme~='custom'] .chart-mark-detail {
    display: block;
    margin-top: 0.3rem;
}

/* A fold names every event it covers, so the list scrolls rather than truncating. */
.tippy-box[data-theme~='custom'] .chart-mark-list {
    max-height: 12rem;
    overflow-y: auto;
    margin-top: 0.35rem;
    border-top: 1px solid var(--border-color);
    padding-top: 0.35rem;
}

.tippy-box[data-theme~='custom'] .chart-mark-item {
    display: flex;
    gap: 0.5rem;
    font-size: 0.8rem;
    padding: 0.15rem 0;
}

.tippy-box[data-theme~='custom'] .chart-mark-item-time {
    color: var(--text-muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.tippy-box[data-theme~='custom'] .chart-mark-item-body {
    display: flex;
    flex-direction: column;
}

.tippy-box[data-theme~='custom'] .chart-mark-item-title {
    color: var(--text-primary);
}

.tippy-box[data-theme~='custom'] .chart-mark-item-where {
    color: var(--text-secondary);
}

/* A mark that opens something: the single tooltip's link row, or a row in a fold's list. */
.tippy-box[data-theme~='custom'] .chart-mark-action {
    margin-top: 0.4rem;
    color: var(--primary-hover);
    font-size: 0.8rem;
    cursor: pointer;
}

.tippy-box[data-theme~='custom'] .chart-mark-action:hover {
    color: var(--accent-color);
}

.tippy-box[data-theme~='custom'] .chart-mark-item-action {
    cursor: pointer;
    border-radius: var(--border-radius);
}

.tippy-box[data-theme~='custom'] .chart-mark-item-action:hover {
    background: var(--bg-hover);
}

/* ============================================
   Login Page Styles
   ============================================ */

.auth-layout {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-primary) 50%, var(--bg-secondary) 100%);
    padding: 1rem;
}

.login-container {
    width: 100%;
    max-width: 420px;
}

.login-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 2.5rem;
    box-shadow: var(--shadow-lg);
}

.login-header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.login-logo {
    width: 140px;
    height: auto;
    margin-bottom: 0.75rem;
}

.login-header h1 {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0;
}

.login-subtitle {
    color: var(--text-muted);
    font-size: 0.875rem;
    margin: 0.25rem 0 0 0;
}

.login-card .form-group {
    margin-bottom: 1.5rem;
}

.login-card .form-label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.login-card .form-control {
    width: 100%;
    padding: 0.75rem 1rem;
    font-size: 1rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    transition: border-color 0.15s ease-out, box-shadow 0.15s ease-out;
}

.login-card .form-control:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: var(--focus-ring);
}

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

.login-btn {
    width: 100%;
    padding: 0.875rem 1.5rem;
    /* Form controls do not inherit the page font, so the passkey <button> rendered in the browser's
       system UI font while the provider <a> next to it used ours. Same size and weight either way,
       which is why it read as a mismatch rather than an obvious one. */
    font-family: inherit;
    font-size: 1rem;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.login-alt-signin {
    margin-top: 1.25rem;
}

.login-footer {
    text-align: center;
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* The sign-in-method buttons follow .login-divider, which is already a rule. */
.login-footer-undivided {
    padding-top: 0;
    border-top: none;
}

/* The row gap is the label-to-tooltip spacing; the rules add their own margin on top of it so the
   line can breathe without the tooltip drifting away from the words it belongs to. */
/* Marks a card as the one being pointed at - a deep link's target, or the thing a page is asking
   the user to act on. .card carries no border, so this is a ring rather than a border-color: the
   same 3px primary halo the focus state uses, which is why it reads as deliberate rather than as a
   hairline stuck to the edge. */


/* The guidance sits at the top of the card body, where .alert's own top margin doubles the padding
   already there. */
.card-highlight .card-body > .alert:first-child {
    margin-top: 0;
}

.login-divider {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-top: 1.5rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.login-divider::before,
.login-divider::after {
    content: "";
    flex: 1;
    min-width: 0;
    height: 1px;
    background: var(--border-color);
}

.login-divider::before {
    margin-right: 0.375rem;
}

.login-divider::after {
    margin-left: 0.375rem;
}

.login-divider .tooltip-icon {
    margin-left: 0;
}

.login-divider-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
    cursor: pointer;
}

/* The provider buttons are anchors, so the global a:hover recoloured their text blue on hover while
   the passkey <button> beside them kept the button colour. They are buttons here, not links. */
.login-footer a.btn:hover {
    color: var(--text-primary);
}

.login-footer .text-muted {
    color: var(--text-muted);
    font-size: 0.8125rem;
}

/* Logout Button in Header */
.header-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.error-page-icon {
    display: flex;
    justify-content: center;
    margin-bottom: 1rem;
    color: var(--text-secondary);
    opacity: 0.6;
}

.error-page-icon svg {
    width: 3rem;
    height: 3rem;
}

.error-page-title {
    margin: 0 0 0.75rem;
    font-size: 1.25rem;
    text-align: center;
    color: var(--text-primary);
}

.error-page-body {
    margin: 0 0 1.25rem;
    font-size: 0.875rem;
    line-height: 1.5;
    text-align: center;
    color: var(--text-secondary);
}

.login-back {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-bottom: 0.75rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
    text-decoration: none;
}

.login-back:hover {
    color: var(--text-primary);
}

.login-back svg {
    width: 14px;
    height: 14px;
}

/* Both class and element qualified so it beats .login-card .form-group outright, rather than
   depending on which rule happens to come later in the file. */
.login-card .form-group.login-username-group {
    margin-bottom: 1rem;
}

.remember-device {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 1rem;
    font-size: 0.9rem;
}

.logout-form {
    display: inline-flex;
}

.nav-item-logout {
    display: none;
}

.nav-logout-btn {
    width: 100%;
    background: none;
    border: none;
    border-left: 2px solid transparent;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.nav-logout-icon {
    width: 2.5rem;
    margin-right: 0.5rem;
    display: flex;
    justify-content: flex-end;
    flex-shrink: 0;
}

.nav-logout-icon svg {
    width: 1.25rem;
    height: 1.25rem;
}

@media (max-width: 768px) {
    .nav-item-logout {
        display: block;
    }

    .logout-form {
        display: none;
    }
}

.logout-btn,
.account-btn {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    font-size: 0.8125rem;
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.2s;
}

.logout-btn:hover {
    background: var(--bg-hover);
    border-color: var(--danger-color);
    color: var(--danger-color);
}

.account-btn:hover {
    background: var(--bg-hover);
    border-color: var(--primary-hover);
    color: var(--primary-hover);
}

.logout-btn svg,
.account-btn svg {
    width: 14px;
    height: 14px;
}

/* ============================================
   Device Icons
   ============================================ */

/* Device icon image */
.device-icon {
    object-fit: contain;
    vertical-align: middle;
    flex-shrink: 0;
}

/* Size variants */
.device-icon-sm {
    width: 16px;
    height: 16px;
}

.device-icon-md {
    width: 28px;
    height: 28px;
}

.device-icon-lg {
    width: 34px;
    height: 34px;
}

.device-icon-xl {
    width: 48px;
    height: 48px;
}

/* Fallback emoji display */
.device-icon-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
}

.device-icon-fallback.device-icon-sm {
    font-size: 14px;
}

.device-icon-fallback.device-icon-md {
    font-size: 18px;
}

.device-icon-fallback.device-icon-lg {
    font-size: 24px;
}

.device-icon-fallback.device-icon-xl {
    font-size: 36px;
}

/* Device icon with name wrapper */
.device-with-icon {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* Table icon cell */
.icon-cell {
    width: 32px;
    padding-right: 0 !important;
    text-align: center;
}

.icon-cell .device-icon {
    display: block;
    margin: 0 -0.5rem 0 auto;
}

@media (max-width: 768px) {
    .icon-cell .device-icon {
        margin: 0 auto;
    }
}

/* ============================================
   MOBILE OVERRIDES (must come after base styles)
   ============================================ */
@media (max-width: 768px) {
    /* Issue counts - reduce gap and padding on mobile */
    .issue-counts {
        flex-wrap: wrap;
        gap: 0.5rem;
    }

    .issue-count {
        padding: 1rem 1rem;
        min-width: 70px;
    }

    /* Audit timestamp - hide label, reduce font size */
    .audit-timestamp {
        font-size: 0.75rem;
    }

    .audit-timestamp .timestamp-label {
        display: none;
    }
}

@media (max-width: 412px) {
    .issue-count {
        padding: 0.75rem 0.75rem;
    }
}

/* ============================================
   SETUP GUIDE - Collapsible help sections
   ============================================ */

.setup-guide {
    margin-top: 1.5rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
}

.setup-guide summary {
    padding: 0.75rem 1rem;
    cursor: pointer;
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--text-secondary);
    user-select: none;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.setup-guide summary::-webkit-details-marker {
    display: none;
}

.setup-guide summary::before {
    content: "▶";
    font-size: 0.7rem;
    transition: transform 0.2s ease;
}

.setup-guide[open] summary::before {
    transform: rotate(90deg);
}

.setup-guide summary:hover {
    color: var(--text-primary);
    background: var(--bg-elevated);
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
}

.setup-guide:not([open]) summary:hover {
    border-radius: var(--border-radius-lg);
}

.setup-guide-content {
    padding: 0 1rem 1rem 1rem;
    border-top: 1px solid var(--border-color);
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.6;
}

.setup-guide-content h4 {
    color: var(--text-primary);
    margin: 1rem 0 0.5rem 0;
    font-size: 0.95rem;
}

.setup-guide-content h4:first-child {
    margin-top: 0;
}

.setup-guide-content p {
    margin: 0.5rem 0;
}

.setup-guide-content a,
.setup-guide-content a:visited {
    color: var(--primary-color);
}

.setup-guide-content a:hover {
    color: var(--primary-hover);
}

.add-form {
    margin-top: 1.25rem;
}

.add-form summary {
    cursor: pointer;
    font-weight: 500;
    font-size: 0.875rem;
    margin-bottom: 0.25rem;
}

/* A help line under the summary title, visible while the form is collapsed. */
.add-form-summary-help {
    font-weight: 400;
    margin-bottom: 0.5rem;
}

.add-form[open] .add-form-summary-help {
    margin-bottom: 0.75rem;
}

.add-form-content {
    padding-top: 0.25rem;
}

.add-form-content-spaced {
    padding-top: 0.75rem;
}

.setup-guide-content ol,
.setup-guide-content ul {
    margin: 0.5rem 0;
    padding-left: 1.5rem;
}

.setup-guide-content li {
    margin: 0.35rem 0;
}

.setup-guide-content ul ul {
    margin-top: 0.25rem;
}

.setup-guide-content code {
    background: var(--bg-tertiary);
    padding: 0.15rem 0.4rem;
    border-radius: var(--border-radius);
    font-size: 0.85em;
}

.gateway-diag-raw {
    background: var(--bg-primary);
    padding: 0.75rem;
    border-radius: var(--border-radius);
    overflow-x: auto;
    max-width: 100%;
    margin: 0.35rem 0 1rem;
    font-size: 0.8125rem;
}

/* Audit page table minimum widths for mobile */
@media (max-width: 768px) {
    .port-table {
        min-width: 800px;
    }

    .wireless-client-table,
    .offline-client-table {
        min-width: 700px;
    }
}

/* Nav icon SVG (inline SVG icons) */
.nav-icon-svg {
    width: 1.5rem;
    height: 1.5rem;
    margin-right: 0.75rem;
    flex-shrink: 0;
    opacity: 0.8;
}

.nav-link:hover .nav-icon-svg,
.nav-link.active .nav-icon-svg {
    opacity: 1;
}

/* ================================
   UPnP Inspector Page
   ================================ */

.upnp-container {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.upnp-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
}

.upnp-controls .control-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.upnp-controls .filter-label {
    color: var(--text-muted);
    font-size: 0.875rem;
}

.upnp-controls .filter-select {
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-primary);
    padding: 0.4rem 0.75rem;
    font-size: 0.875rem;
}

/* Summary Cards */
.summary-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1rem;
}

.summary-card {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}

.summary-card .summary-value {
    font-size: 2rem;
    font-weight: 600;
    color: var(--text-primary);
}

.summary-card .summary-label {
    font-size: 0.875rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.summary-card.summary-warning .summary-value {
    color: #fbbf24;
}

.summary-card.summary-muted {
    opacity: 0.6;
}

.summary-card.summary-muted .summary-value {
    color: var(--text-muted);
}

/* UPnP Device Groups */
.upnp-device-group {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    margin-bottom: 0.75rem;
    overflow: hidden;
}

.upnp-device-group.has-expiring {
    border-color: rgba(251, 191, 36, 0.4);
}

.upnp-device-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.875rem 1rem;
    cursor: pointer;
    transition: background 0.15s;
}

.upnp-device-header:hover {
    background: var(--bg-hover);
}

.upnp-device-header .device-info {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.upnp-device-header .device-ip {
    font-weight: 600;
    font-family: ui-monospace, monospace;
    color: var(--text-primary);
}

.upnp-device-header .device-count {
    font-size: 0.875rem;
    color: var(--text-muted);
}

.upnp-device-header .expand-chevron {
    color: var(--text-muted);
    font-size: 0.75rem;
}

/* UPnP Rules List */
.upnp-rules-list {
    padding: 0 1rem 1rem 1rem;
}

.upnp-rule-item {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    gap: 1rem;
    align-items: center;
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--border-color);
}

.upnp-rule-item:last-child {
    border-bottom: none;
}

/* Status Indicator */
.rule-status {
    width: 24px;
    display: flex;
    justify-content: center;
}

.rule-status .status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--success-color);
}

.rule-status.status-active .status-dot {
    background: var(--success-color);
}

.rule-status.status-expiring .status-dot {
    background: #fbbf24;
    animation: pulse-yellow 2s infinite;
}

.rule-status.status-stale .status-dot {
    background: var(--text-secondary);
}

.rule-status.status-disabled .status-dot {
    background: var(--danger-color);
}

@keyframes pulse-yellow {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* Rule Details */
.rule-details {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
}

.rule-details .rule-main {
    width: 220px;
    flex-shrink: 0;
}

.rule-details .rule-name {
    font-weight: 500;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rule-details .rule-ports {
    display: flex;
    gap: 0.5rem;
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin-top: 0.125rem;
}

.rule-protocol {
    background: rgba(59, 130, 246, 0.2);
    color: var(--primary-light);
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    font-size: 0.75rem;
    font-weight: 500;
}

.rule-protocol.protocol-udp {
    background: rgba(168, 85, 247, 0.2);
    color: var(--purple-light);
}

.rule-protocol.protocol-both {
    background: rgba(249, 115, 22, 0.2);
    color: var(--accent-hover);
}

.rule-details .rule-port-mapping {
    font-family: ui-monospace, monospace;
}

.rule-ports code {
    background: var(--bg-primary);
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
}

/* Lease Time */
.rule-lease {
    text-align: right;
    min-width: 70px;
}

.rule-lease .lease-time {
    font-size: 0.875rem;
    color: var(--text-muted);
    font-family: ui-monospace, monospace;
}

.rule-lease .lease-time.expiring {
    color: #fbbf24;
    font-weight: 500;
}

/* Traffic Info */
.rule-traffic {
    text-align: right;
    min-width: 120px;
}

.rule-traffic .traffic-info {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.rule-traffic .traffic-info.no-traffic {
    color: var(--text-muted);
    opacity: 0.6;
}

/* Note Input */
.rule-note {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 380px;
    flex-shrink: 0;
}

.rule-note .note-input {
    width: 320px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--border-radius);
    padding: 0.25rem 0.5rem;
    font-size: 0.8125rem;
    color: var(--text-primary);
    transition: border-color 0.15s, background-color 0.15s;
}

.rule-note .note-input::placeholder {
    color: var(--text-muted);
    opacity: 0.5;
}

.rule-note .note-input:focus {
    outline: none;
    border-color: var(--primary-color);
    background: rgba(255, 255, 255, 0.08);
}

.rule-note .note-status {
    font-size: 0.6875rem;
    white-space: nowrap;
}

.rule-note .note-status.saving {
    color: var(--text-muted);
}

.rule-note .note-status.saved {
    color: #4ade80;
}

@media (max-width: 768px) {
    .rule-note .note-input {
        width: 90%;
    }
}

/* Badges */
.badge {
    display: inline-block;
    padding: 0.2rem 0.5rem;
    border-radius: var(--border-radius);
    font-size: 0.75rem;
    font-weight: 500;
}

.badge-active {
    background: rgba(36, 188, 112, 0.2);
    color: var(--success-color);
}

.badge-idle {
    background: rgba(100, 116, 139, 0.2);
    color: var(--text-muted);
}

.badge-disabled {
    background: rgba(239, 68, 68, 0.2);
    color: #f87171;
}

/* Row disabled state */
.row-disabled {
    opacity: 0.5;
}

/* Expand/collapse animation using CSS grid for true auto-height */
.expand-wrapper {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.2s ease-in;
}

.expand-wrapper.expanded {
    grid-template-rows: 1fr;
    transition: grid-template-rows 0.3s ease-out;
}

.expand-wrapper > .expand-content {
    overflow: hidden;
}

/* Mobile responsive */
@media (max-width: 768px) {
    .upnp-controls {
        flex-direction: column;
        align-items: stretch;
    }

    .upnp-controls .control-group {
        justify-content: space-between;
    }

    .summary-cards {
        grid-template-columns: repeat(2, 1fr);
    }

    .upnp-rule-item {
        grid-template-columns: auto 1fr;
        grid-template-rows: auto auto;
        gap: 0.5rem;
    }

    .rule-details {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }

    .rule-note {
        width: 100%;
    }

    .rule-lease,
    .rule-traffic {
        grid-column: 2;
        text-align: left;
        min-width: unset;
    }

    .rule-lease {
        display: inline;
    }

    .rule-traffic {
        display: inline;
        margin-left: 1rem;
    }
}

/* ============================================
   Diagnostics Page Styles
   ============================================ */

.diagnostics-container {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.diagnostics-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1rem;
    padding-top: 1rem;
}

.diagnostics-options {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-top: 1rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-color);
    width: 100%;
}

.diagnostics-options .checkbox-label {
    gap: 0.625rem;
}

.empty-section-text {
    color: var(--text-muted);
    margin: 0;
    font-size: 0.875rem;
    font-style: italic;
}

/* Diagnostics Summary Stats */
.diagnostics-summary {
    display: flex;
    justify-content: center;
}

.summary-stats {
    display: flex;
    gap: 2rem;
    flex-wrap: wrap;
    justify-content: center;
}

.stat-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 1rem 1.5rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    min-width: 100px;
}

.stat-item .stat-value {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1;
    color: var(--text-primary);
}

.stat-item .stat-label {
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.stat-item.has-warnings .stat-value {
    color: var(--warning-color);
}

.stat-item.has-info .stat-value {
    color: var(--info-color);
}

/* Diagnostics Issues List */
.issues-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* Issue item variants for diagnostics severity levels */
.issue-item.severity-warning {
    border-left-color: var(--warning-color);
}

.issue-item.severity-info {
    border-left-color: var(--info-color);
}

.issue-item.severity-unknown {
    border-left-color: var(--text-muted);
}

.issue-item.severity-low {
    border-left-color: var(--info-color);
}

.issue-item.severity-medium {
    border-left-color: var(--warning-color);
}

.issue-item.severity-high {
    border-left-color: var(--danger-color);
}

/* Severity Badge */
.severity-badge {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    border-radius: 0.25rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
}

.severity-badge.warning,
.severity-badge.medium {
    background: rgba(245, 158, 11, 0.15);
    color: var(--warning-color);
}

.severity-badge.info,
.severity-badge.low {
    background: rgba(6, 182, 212, 0.15);
    color: var(--info-color);
}

.severity-badge.high {
    background: rgba(239, 68, 68, 0.15);
    color: var(--danger-color);
}

.severity-badge.unknown {
    background: rgba(148, 163, 184, 0.15);
    color: var(--text-muted);
}

/* Issue Details Grid */
.issue-details {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin: 0.5rem 0;
}

.detail-row {
    display: flex;
    gap: 0.5rem;
    font-size: 0.875rem;
}

.detail-label {
    color: var(--text-muted);
    flex-shrink: 0;
}

.detail-value {
    color: var(--text-secondary);
}

/* Issue Count Badge (card header) */
.issue-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 24px;
    padding: 0 0.5rem;
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.issue-count-badge.has-warnings {
    background: rgba(231, 150, 19, 0.15);
    color: var(--warning-color);
}

.issue-count-badge.has-info {
    background: rgba(71, 151, 255, 0.15);
    color: var(--info-color);
}

.card-header-collapsible.header-warning {
    border-left: 3px solid var(--warning-color);
}

.card-header-collapsible.header-info {
    border-left: 3px solid var(--info-color);
}

/* No Issues Success State */
.no-issues {
    text-align: center;
    padding: 3rem 2rem;
}

.no-issues .success-icon {
    display: block;
    font-size: 3rem;
    color: var(--success-color);
    margin-bottom: 1rem;
}

.no-issues h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.5rem;
}

.no-issues p {
    color: var(--text-muted);
    font-size: 0.875rem;
}

/* Responsive adjustments for diagnostics */
@media (max-width: 768px) {
    .diagnostics-controls {
        justify-content: center;
        padding-top: 0;
    }

    .summary-stats {
        gap: 0.75rem;
    }

    .stat-item {
        min-width: 80px;
        padding: 0.75rem 1rem;
    }

    .stat-item .stat-value {
        font-size: 1.5rem;
    }

    .detail-row {
        flex-direction: column;
        gap: 0.125rem;
    }
}

/* ================================
   Wi-Fi Optimizer Page
   ================================ */

.wifi-content-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.25rem 1.25rem;
    margin-bottom: 0.25rem;
}

/* Override main dashboard min-height for WiFi overview cards */
.wifi-content-grid > .card:nth-child(-n+4) {
    min-height: auto;
}

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

@media (max-width: 768px) {
    .wifi-content-grid {
        display: flex;
        flex-direction: column;
        gap: 16px;
        margin-bottom: 16px;
    }
}

/* Stat icon SVG */
.stat-icon-svg {
    width: 3rem;
    height: 3rem;
    opacity: 0.8;
    color: var(--primary-color);
    flex-shrink: 0;
}

.stat-icon-svg.stat-icon-sm {
    width: 2.5rem;
    height: 2.5rem;
}

/* Health score icon in stat card */
.wifi-health-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--bg-secondary);
    border: 2px solid var(--border-color);
}

.wifi-health-icon .health-score-num {
    font-size: 1.25rem;
    font-weight: 600;
}

.wifi-health-icon.score-excellent {
    border-color: var(--success-color);
    color: var(--success-color);
}

.wifi-health-icon.score-good {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.wifi-health-icon.score-fair {
    border-color: var(--warning-color);
    color: var(--warning-color);
}

.wifi-health-icon.score-poor {
    border-color: var(--danger-color);
    color: var(--danger-color);
}

/* Score label colors and font for stat card */
.stat-value.score-excellent,
.stat-value.score-good,
.stat-value.score-fair,
.stat-value.score-poor {
    font-size: 1.6rem;
}
.stat-value.score-excellent { color: var(--success-color); }
.stat-value.score-good { color: var(--primary-color); }
.stat-value.score-fair { color: var(--warning-color); }
.stat-value.score-poor { color: var(--danger-color); }

@media (max-width: 450px) {
    .stat-value.score-excellent,
    .stat-value.score-good,
    .stat-value.score-fair,
    .stat-value.score-poor {
        font-size: 5.3vw;
    }
}

/* Health Score Display */
.health-score-display {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.health-score-main {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto auto;
    align-items: center;
    justify-content: center;
    column-gap: 1rem;
    row-gap: 0;
}

.health-score-main .score-circle {
    grid-column: 1;
    grid-row: 1 / 3;
    width: 120px;
    height: 120px;
}

.health-score-main .score-label {
    grid-column: 2;
    grid-row: 1;
    margin-top: 0;
    align-self: end;
}

.health-score-main .health-score-timestamp {
    grid-column: 2;
    grid-row: 2;
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0;
    align-self: start;
}

.health-score-main .score-value.score-perfect {
    font-size: 2rem;
}

/* Health Dimensions */
.health-dimensions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.dimension-row {
    display: grid;
    grid-template-columns: 140px 1fr 40px;
    gap: 1rem;
    align-items: center;
}

.dimension-label {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.dimension-bar-container {
    height: 8px;
    background: var(--bg-tertiary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
}

.dimension-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.dimension-bar.bar-excellent { background: #22c55e; }
.dimension-bar.bar-good { background: #84cc16; }
.dimension-bar.bar-fair { background: #fbbf24; }
.dimension-bar.bar-poor { background: #ef4444; }

.dimension-score {
    font-size: 0.875rem;
    font-weight: 600;
    text-align: right;
    color: var(--text-primary);
}

/* Band Distribution */
.band-distribution {
    display: flex;
    justify-content: center;
    gap: 3rem;
    padding: 0.5rem 0;
}

.band-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
}

.band-item.clickable {
    cursor: pointer;
    border-radius: 8px;
    transition: background-color 0.15s ease;
}

.band-item.clickable:hover {
    background-color: var(--bg-hover);
}

.band-bar-container {
    width: 60px;
    height: 96px;
    background: var(--bg-tertiary);
    border-radius: 6px 6px 0 0;
    overflow: hidden;
    display: flex;
    align-items: flex-end;
}

.band-bar {
    width: 100%;
    border-radius: 6px 6px 0 0;
    transition: height 0.3s ease;
    min-height: 4px;
}

.band-bar.band-2ghz { background: #fbbf24; }
.band-bar.band-5ghz { background: #3b82f6; }
.band-bar.band-6ghz { background: #a855f7; }

.band-value {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.band-label {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.band-stats {
    display: flex;
    justify-content: center;
    gap: 2rem;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

/* Overview: Client Band Distribution + Channel Optimization stacked in one grid cell */
.wifi-overview-stack {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.channel-rec-card .card-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.channel-rec-summary {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.875rem;
    padding-bottom: 0.5rem;
    text-align: center;
}

.channel-rec-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.95rem;
    color: var(--text-secondary);
}

.channel-rec-status.optimal {
    color: var(--success-color);
}

.channel-rec-count {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1;
    color: var(--accent-color);
}

.channel-rec-bands {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
}

.channel-rec-summary .btn-recommend {
    width: 100%;
    max-width: 260px;
    height: 38px;
}

@media (max-width: 768px) {
    .wifi-overview-stack {
        gap: 16px;
    }
}

.band-stat {
    display: flex;
    gap: 0.5rem;
}

.band-stat-label {
    color: var(--text-muted);
    font-size: 0.875rem;
}

.band-stat-value {
    font-weight: 600;
    font-size: 0.875rem;
}

/* Satisfaction/Signal colors */
.satisfaction-excellent, .signal-excellent { color: #22c55e; }
.satisfaction-good, .signal-good { color: #84cc16; }
.satisfaction-fair, .signal-fair { color: #fbbf24; }
.satisfaction-poor, .signal-poor { color: #ef4444; }

/* WiFi Health Issues List */
.wifi-issues-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.wifi-issue-item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 1rem;
    align-items: center;
    padding: 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    border-left: 4px solid var(--border-color);
}

.wifi-issue-item.issue-critical {
    border-left-color: #ef4444;
}

.wifi-issue-item.issue-warning {
    border-left-color: #fbbf24;
}

.wifi-issue-item.issue-info {
    border-left-color: #3b82f6;
}

.wifi-issue-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.wifi-issue-badge {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    padding: 0.2rem 0.5rem;
    border-radius: var(--border-radius);
    background: var(--bg-primary);
}

.wifi-issue-item.issue-critical .wifi-issue-badge {
    color: #ef4444;
    background: rgba(239, 68, 68, 0.15);
}

.wifi-issue-item.issue-warning .wifi-issue-badge {
    color: #fbbf24;
    background: rgba(251, 191, 36, 0.15);
}

.wifi-issue-item.issue-info .wifi-issue-badge {
    color: #3b82f6;
    background: rgba(59, 130, 246, 0.15);
}

.wifi-issue-dimension {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.wifi-issue-impact {
    font-size: 0.75rem;
    color: #ef4444;
    font-weight: 500;
}

.wifi-issue-title {
    font-weight: 600;
    color: var(--text-primary);
}

.wifi-issue-content {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.wifi-issue-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.wifi-issue-entity {
    font-size: 0.8rem;
    color: var(--text-muted);
}

.wifi-issue-action {
    font-size: 0.8rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-secondary);
    border-radius: 6px;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* WiFi Issues List Responsive */
@media (max-width: 900px) {
    .wifi-issue-item {
        grid-template-columns: 1fr;
        gap: 0.5rem;
    }

    .wifi-issue-meta {
        flex-wrap: wrap;
    }

    .wifi-issue-action {
        justify-self: start;
    }
}

/* Success State */
.success-state {
    color: #22c55e;
    padding-top: 2rem;
    padding-bottom: 2rem;
}

.success-state svg {
    opacity: 0.6;
}

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

/* Access Points List */
.ap-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}

.ap-card {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
}

.ap-card.ap-offline {
    opacity: 0.5;
}

.ap-status {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: auto;
    margin-top: -1.3rem;
}

.ap-status-text {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.optimize-mesh-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
    align-self: flex-end;
    margin-bottom: 0.25rem;
}

.optimize-mesh-icon {
    font-size: 0.95rem;
    line-height: 1;
}

.wifi-toast {
    position: fixed;
    bottom: 5rem;
    right: 3rem;
    z-index: 1080;
    max-width: 22rem;
    background: rgba(22, 22, 24, 0.8);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.wifi-toast-note {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .wifi-toast {
        right: auto;
        left: 50%;
        bottom: 1rem;
        width: 80vw;
        max-width: 80vw;
        transform: translateX(-50%);
    }
}

.ap-header-text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

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

.ap-model {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.ap-stats {
    display: flex;
    gap: 1.5rem;
    margin-bottom: 0.5rem;
    margin-left: 0.25rem;
}

.ap-stats-mesh .ap-stat {
    justify-content: flex-end;
}

/* MLO mesh cards and parents with stacked children: the multi-row block reads top-down,
   so the client stat aligns top like non-mesh cards, the row tightens to make width for
   the grid, and the mesh block hugs the right edge as one unit (the grid keeps columns aligned). */
.ap-stats-mlo {
    gap: 1.25rem;
}

.ap-stats-mlo .ap-stat {
    justify-content: flex-start;
}

.ap-stats-mlo .ap-mesh-info {
    align-items: flex-end;
}

.ap-stat {
    display: flex;
    flex-direction: column;
}

.roaming-stat-value,
.channel-stat-value,
.load-stat-value,
.power-stat-value,
.airtime-stat-value {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.33;
}

.ap-stat-value {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.ap-stat-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
}

.ap-mesh-info {
    display: flex;
    flex-direction: column;
    margin-left: auto;
}

.ap-mesh-info-with-action {
    margin-top: -1.75rem;
}

/* A parent's mesh children, paged: the pager sits bottom right, clear of a Re-pair Uplink
   button above, and every page shares one grid cell so the card holds the tallest page's height. */
.ap-mesh-children {
    display: flex;
    flex-direction: column;
    margin-left: auto;
    min-width: 0;
    touch-action: pan-y;
}

.mesh-child-nav {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    align-self: flex-end;
    margin-top: 0.35rem;
}

.mesh-child-pages {
    display: grid;
}

.mesh-child-page {
    grid-area: 1 / 1;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.mesh-child-page:not(.active) {
    visibility: hidden;
}

.mesh-child-page .ap-mesh-info {
    margin-left: 0;
}

.mesh-signal {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}

.mesh-signal-value {
    font-size: 1.25rem;
    font-weight: 600;
}

.mesh-rates {
    display: flex;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

/* MLO mesh backhaul: link rows share a 3-column grid (badge / signal / rates) so the
   columns align across rows; each row div flattens into it via display: contents. */
.mesh-mlo-links {
    display: grid;
    grid-template-columns: auto auto auto;
    column-gap: 0.5rem;
    row-gap: 0.3rem;
    align-items: baseline;
    justify-content: start;
}

.mesh-mlo-link {
    display: contents;
}

.mesh-mlo-links .band-badge {
    min-width: 54px;
    text-align: center;
}

.mesh-mlo-signal {
    font-size: 0.875rem;
    white-space: nowrap;
}

.mesh-rate {
    white-space: nowrap;
}

.ap-mesh-info .ap-stat-label {
    text-transform: none;
    margin-top: 0.2rem;
}

.lock-icon {
    font-size: 0.75rem;
    cursor: default;
    margin-left: 0.35rem;
}

/* ApLockIcon: a round AP in the muted text color, the lock badge in amber on the card background. */
.ap-lock-icon {
    color: var(--text-secondary);
    vertical-align: middle;
    position: relative;
    top: -1.5px;
    flex-shrink: 0;
}

.ap-lock-icon-badge {
    fill: var(--bg-card);
}

/* The AP's LED ring, in Ubiquiti blue */
.ap-lock-icon-led {
    stroke: var(--primary-color);
}

.ap-lock-icon-lock {
    stroke: var(--warning-color);
}

.ap-lock-icon-lock-body {
    fill: var(--warning-color);
}

.mesh-unit {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-muted);
}

.ap-radios {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--border-color);
    /* Sink to the card bottom so radio lists align across a row when a taller
       MLO mesh card stretches its siblings. */
    margin-top: auto;
}

.ap-radio {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
}

.radio-band {
    font-weight: 600;
    padding: 0.125rem 0.5rem;
    border-radius: var(--border-radius);
    font-size: 0.7rem;
    width: 60px;
    text-align: center;
    flex-shrink: 0;
}

.radio-band.band-2ghz {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.radio-band.band-5ghz {
    background: rgba(59, 130, 246, 0.2);
    color: #3b82f6;
}

.radio-band.band-6ghz {
    background: rgba(168, 85, 247, 0.2);
    color: #a855f7;
}

.radio-disabled {
    opacity: 0.5;
}

.radio-channel {
    color: var(--text-secondary);
    width: 45px;
    flex-shrink: 0;
}

.radio-eirp {
    color: var(--text-muted);
    font-size: 0.75rem;
    width: 47px;
    flex-shrink: 0;
}

.radio-util {
    font-weight: 500;
    width: 54px;
    flex-shrink: 0;
}

.radio-util.util-low { color: #22c55e; }
.radio-util.util-medium { color: #fbbf24; }
.radio-util.util-high { color: #ef4444; }

.radio-clients {
    color: var(--text-muted);
    width: 60px;
    margin-left: auto;
}

/* Clickable elements in AP cards */
.ap-card .clickable {
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.15s ease;
}

.ap-card .clickable:hover {
    background-color: var(--bg-hover);
}

.ap-stat.clickable:hover {
    background-color: var(--bg-hover);
    border-radius: 6px;
    padding: 0 4px;
    margin: 0 -4px;
}

/* Client Timeline AP & Band Filters */
.client-filter-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.client-filter-group .ap-filter-select {
    min-width: 120px;
    max-width: 200px;
    height: 34px;
    font-size: 0.875rem;
    padding: 0 0.75rem;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-primary);
}

.client-timeline-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 1 30%;
    margin-left: auto;
    justify-content: flex-end;
}

.band-pill-selector {
    display: flex;
    gap: 0.25rem;
    background: var(--bg-primary);
    border-radius: 6px;
    padding: 0.25rem;
}

.band-pill {
    padding: 0.35rem 0.5rem;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.band-pill:hover {
    color: var(--text-secondary);
}

.band-pill.active {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.band-pill-2ghz.active {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.band-pill-5ghz.active {
    background: rgba(59, 130, 246, 0.2);
    color: #3b82f6;
}

.band-pill-6ghz.active {
    background: rgba(168, 85, 247, 0.2);
    color: #a855f7;
}

@media (max-width: 420px) {
    .band-pill {
        font-size: 0.7rem;
        padding: 0.35rem 0.4rem;
    }
}

/* Mobile responsive */
@media (max-width: 768px) {
    .radio-eirp {
        display: none;
    }

    .radio-band {
        width: auto;
    }

    .radio-channel,
    .radio-util {
        width: auto;
    }

    .client-filter-group .ap-filter-select {
        max-width: 130px;
    }

    .dimension-row {
        grid-template-columns: 100px 1fr 35px;
        gap: 0.5rem;
    }

    .dimension-label {
        font-size: 0.75rem;
    }

    .band-distribution {
        gap: 1.5rem;
    }

    .band-bar-container {
        width: 50px;
        height: 100px;
    }

    .band-stats {
        flex-direction: column;
        gap: 0.5rem;
        align-items: center;
    }

    .ap-list {
        grid-template-columns: 1fr;
    }

    .health-score-main .score-circle {
        width: 100px;
        height: 100px;
    }

    .health-score-main .score-value {
        font-size: 2rem;
    }

    .health-score-main .score-value.score-perfect {
        font-size: 1.75rem;
    }
}

/* ================================
   Metrics Component
   ================================ */

.metrics-container {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.metrics-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 1rem;
}

.metrics-title h3 {
    margin: 0;
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.metrics-subtitle {
    font-size: 0.875rem;
    color: var(--text-muted);
}

.metrics-controls {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Pill selector - used for toggle buttons (time ranges, status filters, etc.) */
.pill-selector,
.time-refresh-group {
    display: flex;
    align-items: center;
    gap: 1rem;
}

@media (max-width: 768px) {
    .time-refresh-group {
        width: 100%;
        justify-content: space-around;
    }

    .time-range-selector {
        max-width: 400px;
    }
}

.stat-value-stacked {
    display: grid;
    grid-template-columns: 2.6rem 5.2rem;
    justify-content: center;
    align-items: center;
    column-gap: 0.6rem;
    row-gap: 0.1rem;
    font-size: 0.95rem;
    line-height: 1.35;
    font-variant-numeric: tabular-nums;
}

.stat-stack-row {
    display: contents;
}

.stat-stack-wan {
    color: var(--text-muted);
    font-size: 0.7rem;
    text-align: right;
}

.stat-stack-value {
    text-align: left;
    font-size: 1rem;
}

.wan-pill-token {
    color: var(--text-muted);
    margin-left: 0.3rem;
}

@media (max-width: 768px) {
    .wan-pill-token {
        display: none;
    }

    .stat-stack-wan {
        font-size: 0.65rem;
    }

    .stat-stack-value {
        font-size: 0.78rem;
    }
}

.time-btn.active .wan-pill-token {
    color: var(--text-secondary);
}

.wan-selector-standalone {
    width: max-content;
    max-width: 100%;
}

@media (max-width: 768px) {
    .wan-selector-standalone {
        width: auto;
    }
}

.wan-all-btn {
    flex: 0.4;
}

.time-range-selector.wan-selector-on-page {
    background: var(--bg-tertiary);
}

.time-range-selector {
    display: flex;
    gap: 0.25rem;
    background: var(--bg-primary);
    border-radius: 6px;
    padding: 0.25rem;
}

.custom-range-popover {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 50;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 1rem;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    min-width: 240px;
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.custom-range-popover.open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.custom-range-input {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 0.85rem;
    width: 100%;
    color-scheme: dark;
}

.custom-range-input:focus {
    outline: none;
    border-color: var(--primary-color);
}

.custom-range-label {
    font-size: 0.75rem;
    margin-left: 0.25rem;
}

.custom-range-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.custom-range-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
}

.custom-range-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.custom-range-field label {
    display: block;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.custom-range-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

.custom-range-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.custom-range-clear {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 14px;
    height: 14px;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    background: var(--danger-color);
    color: #fff;
    border-radius: 50%;
    cursor: pointer;
    opacity: 0.85;
}

.custom-range-clear:hover {
    opacity: 1;
}

/* Use secondary background when inside nested cards */
.card .card .pill-selector,
.card .card .time-range-selector,
.card .card .band-tab,
.card .card .btn-secondary,
.card .card .btn-ghost {
    background: var(--bg-secondary);
}

.card .card .btn-secondary:hover:not(:disabled),
.card .card .btn-ghost:hover:not(:disabled) {
    background: var(--bg-elevated);
}

.card .card .data-table .btn-secondary,
.card .card .data-table .btn-ghost {
    background: var(--bg-tertiary);
}

.pill-btn,
.time-btn {
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    font-weight: 500;
    background: transparent;
    border: none;
    border-radius: var(--border-radius);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s ease;
}

.pill-btn:hover,
.time-btn:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.pill-btn.active,
.time-btn.active {
    background: var(--primary-color);
    color: white;
}

.time-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.time-btn:disabled:hover {
    background: transparent;
    color: var(--text-secondary);
}

.time-btn.active:disabled {
    opacity: 0.4;
}

.metrics-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 0.75rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
}

.filter-group {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.filter-group.metrics-filter-right {
    margin-left: auto;
}

.metrics-filters .band-tabs,
.env-controls .band-tabs {
    margin-bottom: 0;
}

/* Band filter label colors */
.filter-checkbox .checkbox-label.band-2ghz { color: #fbbf24; }
.filter-checkbox .checkbox-label.band-5ghz { color: #3b82f6; }
.filter-checkbox .checkbox-label.band-6ghz { color: #a855f7; }

.filter-label {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-weight: 500;
}

.ap-filter-select {
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    padding: 0.25rem 0.5rem;
    font-size: 0.8rem;
    min-width: 120px;
}

.ap-filter-select:focus {
    outline: none;
    border-color: var(--primary-color);
}

.ap-filter-select option {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.filter-checkbox {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    cursor: pointer;
}

.filter-checkbox input {
    cursor: pointer;
}

.filter-checkbox .checkbox-label {
    font-size: 0.8rem;
    font-weight: 500;
}

.filter-checkbox .checkbox-label.airtime { color: #2ba89a; }
.filter-checkbox .checkbox-label.interference { color: #a78bfa; }
.filter-checkbox .checkbox-label.retries { color: #ef5858; }

.filter-checkboxes {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.metrics-loading,
.metrics-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-muted);
    gap: 1rem;
}

.band-charts-wrapper {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    flex: 1;
    min-height: 50vh;
}

@media (max-width: 768px) {
    .band-charts-wrapper {
        min-height: 70vh;
    }
}

.band-chart-container {
    flex: 1;
    min-height: 0;
    position: relative;
    padding-bottom: 2.2rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    overflow: hidden;
}

.band-chart-container > div:last-child {
    position: absolute;
    top: 2rem;
    left: 0;
    right: 0;
    bottom: 0;
}

.band-chart-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border-color);
}

.band-chart-header .band-count {
    font-size: 0.75rem;
    color: #6b7280;
}

.band-chart-header .band-label {
    font-size: 0.875rem;
    font-weight: 600;
    padding: 0.25rem 0.5rem;
    border-radius: var(--border-radius);
}

.band-chart-header .band-label.band-2ghz {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.band-chart-header .band-label.band-5ghz {
    background: rgba(59, 130, 246, 0.2);
    color: #3b82f6;
}

.band-chart-header .band-label.band-6ghz {
    background: rgba(168, 85, 247, 0.2);
    color: #a855f7;
}

.band-chart-header .channel-info {
    font-size: 0.75rem;
    color: var(--text-secondary);
    font-weight: 500;
}

/* ApexCharts dark theme overrides */
.apexcharts-canvas {
    background: transparent !important;
}

/* ApexCharts dark theme overrides annotation label fill - needs double class
   specificity to beat .apexcharts-text rule below */
.apexcharts-text.apexcharts-xaxis-annotation-label:not(.wan-chart-tick-label) {
    fill: var(--text-primary) !important;
}

/* Hide hover dots and tooltip markers for transparent (hidden) series */
.apexcharts-tooltip-marker[style*="rgba(0"],
.apexcharts-tooltip-marker[style*="transparent"] {
    display: none !important;
}
.apexcharts-marker[fill="rgba(0,0,0,0)"],
.apexcharts-marker[fill="transparent"] {
    opacity: 0 !important;
}

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

.apexcharts-gridline {
    stroke: var(--border-color) !important;
}

.apexcharts-tooltip {
    background: var(--bg-secondary) !important;
    border: 1px solid var(--border-color) !important;
    color: var(--text-primary) !important;
}

.apexcharts-tooltip-title {
    background: var(--bg-primary) !important;
    border-bottom: 1px solid var(--border-color) !important;
}

/* Legend dots carry apexcharts-marker too; without the exclusion they vanish with the hover dots. */
.netopt-own-hover-dots .apexcharts-marker:not(.apexcharts-legend-marker) {
    display: none;
}

/* Marks a synced tooltip as trimmed - the rest are on the chart under the pointer. Sits at the
   right end of the last row, so the mark costs no height of its own. */
.netopt-tooltip-more {
    margin-left: auto;
    padding-left: 10px;
    color: var(--text-muted);
    font-family: Helvetica, Arial, sans-serif;
    font-size: 12px;
}

@media (max-width: 768px) {
    .metrics-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .metrics-controls {
        width: 100%;
        justify-content: space-between;
    }

    .time-range-selector {
        flex: 1;
    }

    .time-btn {
        flex: 1;
        padding: 0.5rem 0.25rem;
    }

    .wan-all-btn {
        flex: 0.4;
    }

    .wan-selector.wan-selector-many .time-btn {
        font-size: 0.7rem;
        padding: 0.5rem 0.15rem;
    }

    .filter-group {
        flex-wrap: wrap;
    }
}

/* ================================
   Client Timeline Component
   ================================ */

.client-timeline-container {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.client-timeline-title {
    margin: 0;
    margin-right: auto;
    font-size: 1.25rem;
    font-weight: 600;
    width: 100%;
}

@media (max-width: 1700px) {
    .client-timeline-title {
        width: auto;
    }

    .client-timeline-actions {
        margin-left: 0;
    }
}

.client-timeline-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

@media (max-width: 1700px) {
    .client-timeline-controls {
        justify-content: flex-end;
    }
}

.client-timeline-controls .pill-selector {
    gap: 0.25rem;
}

.client-timeline-controls .pill-btn {
    padding: 0.35rem 0.5rem;
}

.client-selector {
    min-width: 250px;
}

.client-selector .form-select {
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-primary);
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    width: 100%;
}

.client-selector .form-select option {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.client-timeline-loading,
.client-timeline-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-muted);
    gap: 1rem;
}

/* Sortable column headers */
.data-table th.sortable,
.results-table th.sortable {
    cursor: pointer;
    user-select: none;
    position: relative;
    padding-right: 1.5rem;
}

.data-table th.sortable:hover,
.results-table th.sortable:hover {
    background: rgba(255, 255, 255, 0.05);
}

/* The glyph is an SVG chevron drawn through a mask, so it takes the color it is given:
   muted at rest, the app blue on the active column. */
.data-table th.sortable::after,
.results-table th.sortable::after {
    content: '';
    position: absolute;
    right: 0.5rem;
    top: 50%;
    width: 10px;
    height: 12px;
    transform: translateY(-50%);
    background-color: var(--text-muted);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 4 5 1 8 4M2 8 5 11 8 8' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 4 5 1 8 4M2 8 5 11 8 8' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

.data-table th.sortable.sort-asc::after,
.results-table th.sortable.sort-asc::after {
    background-color: var(--primary-color);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 7.5 5 4.5 8 7.5' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 7.5 5 4.5 8 7.5' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.data-table th.sortable.sort-desc::after,
.results-table th.sortable.sort-desc::after {
    background-color: var(--primary-color);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 4.5 5 7.5 8 4.5' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2 4.5 5 7.5 8 4.5' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Client selector combo (View All + filterable select) */
.client-selector-combo {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.client-timeline-controls .view-all-btn {
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: 0.8rem;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.15s ease;
}

.client-timeline-controls .view-all-btn:hover {
    background: var(--bg-tertiary);
    border-color: var(--primary-color);
}

/* Filterable select dropdown */
.filterable-select {
    position: relative;
    min-width: 400px;
    max-width: 400px;
}

/* The click-outside overlay is a sibling inside this control, so while the list is open it covers
   the search box. Without this, every click on the box hits the overlay and closes the list.
   Raising the control itself does not work: the overlay rises with it. */
.filterable-select.open .filterable-select-input {
    position: relative;
    z-index: 1001;
}


.filterable-select-input {
    width: 100%;
    height: 34px;
    cursor: pointer;
    padding: 0 2.5rem 0 0.75rem;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 0.875rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
}

.filterable-select.open .filterable-select-input {
    cursor: text;
}

.filterable-select-input::placeholder {
    color: var(--text-muted);
}

.filterable-select-display {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    width: 100%;
    height: 34px;
    padding: 0 2.5rem 0 0.75rem;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
}

.filterable-select-display:hover,
.filterable-select-display:focus-visible {
    border-color: var(--primary-color);
}

.filterable-select-display:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);
}

.filterable-select-display .option-text {
    flex: 1;
    font-size: 0.8rem;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filterable-select-display .option-mac {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-family: monospace;
}

/* Overlay for click-outside-to-close */
.filterable-select-clear {
    position: absolute;
    right: 2rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1002;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    width: 1.25rem;
    height: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
}

.filterable-select-clear:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.filterable-select-overlay {
    position: fixed;
    inset: 0;
    z-index: 999;
}

.filterable-select-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 2px;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    max-height: 300px;
    overflow-y: auto;
    z-index: 1000;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.filterable-select-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    transition: background 0.1s ease;
}

.filterable-select-option.is-active {
    background: rgba(59, 130, 246, 0.15);
}

.filterable-select-option.offline {
    opacity: 0.7;
}

.filterable-select-option[data-selected="true"] {
    background: rgba(59, 130, 246, 0.26);
    box-shadow: inset 2px 0 0 var(--primary-color);
}

.filterable-select-option[data-selected="true"].is-active {
    background: rgba(59, 130, 246, 0.4);
}

.filterable-select-option .option-text {
    flex: 1;
    font-size: 0.8rem;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filterable-select-option .option-mac {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-family: monospace;
}

.filterable-select-empty {
    padding: 0.75rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.875rem;
}

/* Client list table */
.client-list-section {
    margin-top: 1rem;
}

.client-list-section .table-responsive {
    overflow-x: auto;
}

.client-list-section .data-table tbody tr {
    cursor: pointer;
}

.client-list-section .data-table tbody tr:hover {
    background: rgba(59, 130, 246, 0.1);
}

/* Pagination (shared with SpectrumAnalysis) */
.client-list-section .pagination-controls {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 0 0;
    border-top: 1px solid var(--border-color);
    margin-top: 1rem;
}

.client-list-section .pagination-info {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.client-list-section .pagination-buttons {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.client-list-section .page-btn {
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    color: var(--text-primary);
    cursor: pointer;
    transition: all 0.15s ease;
}

.client-list-section .page-btn:hover:not(:disabled) {
    background: var(--bg-tertiary);
    border-color: var(--primary-color);
}

.client-list-section .page-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.client-list-section .page-indicator {
    font-size: 0.85rem;
    color: var(--text-secondary);
    padding: 0 0.5rem;
}

.client-list-section .data-table td:first-child {
    text-align: center;
}

.client-offline {
    opacity: 0.7;
}

.client-info-banner {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.client-info-main {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Client Stats: the Status column holds only a dot, so it takes no more than its header. */
.client-list-section .col-status {
    width: 1%;
    white-space: nowrap;
}

/* The client's icon and name, kept together and closer than the banner's field gap. */
.client-info-identity {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.client-info-main .client-name {
    font-size: 1.1rem;
}

.client-info-main .client-name-link {
    text-decoration: none;
    color: var(--text-primary);
    transition: color 0.15s;
}

.client-info-main .client-name-link:hover {
    color: var(--primary-color);
}

.client-info-main .client-perf-link {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    margin-left: auto;
    padding: 0.25rem 0.625rem;
    border-radius: 6px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.8rem;
    font-weight: 500;
    transition: background 0.15s, color 0.15s;
}

.client-info-main .client-perf-link:hover {
    background: var(--primary-color);
    color: var(--text-primary);
}

.client-info-main .client-dashboard-link {
    display: none;
    color: var(--text-muted);
    transition: color 0.15s;
}

.client-info-main .client-dashboard-link:hover {
    color: var(--primary-color);
}

@media (max-width: 768px) {
    .client-info-main {
        flex-wrap: wrap;
        row-gap: 0.25rem;
    }

    .client-info-main .client-name {
        flex-basis: 100%;
    }

    .client-info-main .client-perf-link {
        display: none;
    }

    .client-info-main .client-dashboard-link {
        display: inline-flex;
    }
}

.client-name {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
}

.client-mac,
.client-ip {
    font-size: 0.875rem;
    color: var(--text-muted);
    font-family: monospace;
}

.client-info-details {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}

.info-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.info-label {
    font-size: 0.8rem;
    color: var(--text-muted);
}

.info-value {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-primary);
}

.band-badge {
    padding: 0.125rem 0.5rem;
    border-radius: var(--border-radius);
    font-size: 0.75rem;
}

.client-timeline-chart-section {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    overflow: hidden;
}

.chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
}

.chart-title {
    font-weight: 600;
    font-size: 0.9rem;
}

.chart-filters {
    display: flex;
    gap: 1rem;
}

.chart-empty {
    padding: 2rem;
    text-align: center;
    color: var(--text-muted);
}

.filter-checkbox .checkbox-label.signal { color: #3b82f6; }

.events-section {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
}

.events-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
}

.events-title {
    font-weight: 600;
    font-size: 0.9rem;
}

.events-count {
    font-size: 0.8rem;
    color: var(--text-muted);
}

.events-empty {
    padding: 2rem;
    text-align: center;
    color: var(--text-muted);
}

.events-empty p {
    margin: 0;
    font-size: 0.8125rem;
}

.events-list {
    max-height: 300px;
    overflow-y: auto;
}

.event-item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-color);
}

.event-item:last-child {
    border-bottom: none;
}

.event-icon {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.8rem;
    flex-shrink: 0;
    background: var(--bg-primary);
    color: var(--text-muted);
}

.event-connect .event-icon {
    background: rgba(34, 197, 94, 0.2);
    color: #22c55e;
}

.event-disconnect .event-icon {
    background: rgba(239, 68, 68, 0.2);
    color: #ef4444;
}

.event-roam .event-icon {
    background: rgba(59, 130, 246, 0.2);
    color: #3b82f6;
}

.event-warning .event-icon {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.event-success .event-icon {
    background: rgba(34, 197, 94, 0.2);
    color: #22c55e;
}

.event-content {
    flex: 1;
    min-width: 0;
}

.event-title {
    font-weight: 500;
    font-size: 0.875rem;
    color: var(--text-primary);
}

.event-details {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-top: 0.125rem;
}

.event-time {
    font-size: 0.75rem;
    color: var(--text-muted);
    white-space: nowrap;
}

/* ============================================
   Generic View Tabs (reusable across pages)
   ============================================ */
.view-tabs {
    display: flex;
    gap: 0.4rem;
    border-bottom: 1px solid var(--border-color);
    padding-bottom: 0;
    margin-bottom: 1.5rem;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.view-tabs::-webkit-scrollbar {
    display: none;
}

.view-tab {
    padding: 0.5rem 0.68rem;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-size: 0.9rem;
    cursor: pointer;
    border-radius: 6px;
    transition: all 0.15s ease;
    white-space: nowrap;
    flex-shrink: 0;
}

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

.view-tab.active {
    background: var(--primary-color);
    color: white;
    border-radius: var(--border-radius);
}

/* Wi-Fi View Tabs */
.wifi-view-tabs-wrapper {
    position: relative;
    display: flex;
    align-items: stretch;
    margin-bottom: 1.5rem;
}

.wifi-view-tabs {
    display: flex;
    gap: 0.4rem;
    border-bottom: 1px solid var(--border-color);
    margin-top: 0.5rem;
    padding-bottom: 0.5rem;
    overflow-x: auto;
    flex: 1;
    min-width: 0;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE/Edge */
}

.wifi-view-tabs::-webkit-scrollbar {
    display: none; /* Chrome/Safari */
}

.wifi-tabs-scroll-btn {
    display: none;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-secondary);
    cursor: pointer;
    padding: 0 0.4rem;
    font-size: 1.2rem;
    flex-shrink: 0;
    z-index: 1;
    transition: color 0.15s ease;
}

.wifi-tabs-scroll-btn:hover {
    color: var(--text-primary);
}

/* Show scroll buttons when tabs overflow */
.wifi-view-tabs-wrapper.has-overflow .wifi-tabs-scroll-btn {
    display: flex;
}

/* Collapse button when scrolled to start/end */
.wifi-view-tabs-wrapper.at-start .wifi-tabs-scroll-left,
.wifi-view-tabs-wrapper.at-end .wifi-tabs-scroll-right {
    width: 0;
    padding: 0;
    overflow: hidden;
    pointer-events: none;
}

.wifi-view-tab {
    padding: 0.5rem 0.68rem;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-size: 0.9rem;
    cursor: pointer;
    border-radius: 6px;
    transition: all 0.15s ease;
    white-space: nowrap;
    flex-shrink: 0;
}

.wifi-view-tab:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.wifi-view-tab.active {
    background: var(--primary-color);
    color: white;
    border-radius: var(--border-radius);
}

/* Change Control: the site gateway's provisioning state, at the right of the tab row. */
.cc-gateway-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-left: auto;
    padding: 0 0.5rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    white-space: nowrap;
    flex-shrink: 0;
}

.cc-gateway-status.is-provisioning {
    color: var(--warning-color);
}

.cc-gateway-status.is-done {
    color: var(--success-color);
}

@media (max-width: 768px) {
    .wifi-view-tabs-wrapper {
        margin-bottom: 0.75rem;
    }

    .wifi-stats-row {
        margin-bottom: 16px;
    }
}

/* ============================================
   Roaming Analytics Component
   ============================================ */


.roaming-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.roaming-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.roaming-loading,
.roaming-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Roaming Stats Row */
.roaming-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.roaming-stat-card {
    flex: 1;
    min-width: 120px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}


.roaming-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.roaming-stat-card.rate-excellent .roaming-stat-value { color: var(--success-color); }
.roaming-stat-card.rate-good .roaming-stat-value { color: #3b82f6; }
.roaming-stat-card.rate-fair .roaming-stat-value { color: var(--warning-color); }
.roaming-stat-card.rate-poor .roaming-stat-value { color: var(--danger-color); }

/* Topology Visualization */
.roaming-topology-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.section-subtitle {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.topology-graph {
    width: 100%;
    height: 300px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    overflow: hidden;
    padding: 10px 0;
}

.topology-graph-inner {
    position: relative;
    width: 100%;
    height: 100%;
    margin-top: -15px;
}

.topology-node {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 40px;
    height: 40px;
}

.node-icon {
    width: 40px;
    height: 40px;
    background: var(--bg-secondary);
    border: 2px solid var(--primary-color);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--primary-color);
    flex-shrink: 0;
}

.node-label {
    position: absolute;
    top: 100%;
    margin-top: 0.25rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-primary);
    text-align: center;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.node-model {
    position: absolute;
    top: calc(100% + 1.1rem);
    font-size: 0.65rem;
    color: var(--text-muted);
    text-align: center;
    white-space: nowrap;
}

.topology-edges {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
}

.topology-edge {
    fill: none;
    stroke-linecap: round;
}

.topology-edge-hit {
    fill: none;
    stroke: transparent;
    stroke-width: 12px;
    stroke-linecap: round;
    cursor: pointer;
}

.topology-edge.edge-excellent { stroke: var(--success-color); }
.topology-edge.edge-good { stroke: #3b82f6; }
.topology-edge.edge-fair { stroke: var(--warning-color); }
.topology-edge.edge-poor { stroke: var(--danger-color); }

.topology-legend {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.legend-line {
    width: 24px;
    height: 3px;
    border-radius: 2px;
}

.legend-line.legend-excellent { background: var(--success-color); }
.legend-line.legend-good { background: #3b82f6; }
.legend-line.legend-fair { background: var(--warning-color); }
.legend-line.legend-poor { background: var(--danger-color); }

/* Roaming Paths Table */
.roaming-paths-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.roaming-paths-table {
    border: 1px solid var(--border-color);
    border-radius: 6px;
    overflow: hidden;
}

.paths-header {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
}

.paths-row {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.875rem;
    cursor: pointer;
    transition: background 0.15s ease;
}

.paths-row:hover {
    background: var(--bg-tertiary);
}

.path-col {
    display: flex;
    align-items: center;
}

.path-aps {
    gap: 0.5rem;
}

.path-arrow {
    color: var(--text-muted);
    font-size: 0.75rem;
}

.path-aps .ap-name {
    font-weight: 500;
}

.path-rate.rate-excellent { color: var(--success-color); }
.path-rate.rate-good { color: #3b82f6; }
.path-rate.rate-fair { color: var(--warning-color); }
.path-rate.rate-poor { color: var(--danger-color); }

/* Edge Details */
.edge-details-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
    border: 1px solid var(--primary-color);
}

.edge-details-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-top: 1rem;
}

.direction-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
}

.direction-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
    font-weight: 500;
}

.direction-arrow {
    color: var(--primary-color);
    font-size: 1.25rem;
}

.direction-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
}

.direction-stat {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.direction-stat .stat-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
}

.direction-stat .stat-value {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.direction-stat .stat-value.rate-excellent { color: var(--success-color); }
.direction-stat .stat-value.rate-good { color: #3b82f6; }
.direction-stat .stat-value.rate-fair { color: var(--warning-color); }
.direction-stat .stat-value.rate-poor { color: var(--danger-color); }

.trigger-stats {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.trigger-item {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: var(--text-secondary);
    margin-bottom: 0.25rem;
}

/* Top Clients Section */
.top-clients-section {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
}

.top-clients-section h5 {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.75rem;
}

.top-clients-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.top-client-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
}

.top-client-item .client-name {
    font-size: 0.8rem;
    font-weight: 500;
    flex: 1;
}

.top-client-item .client-mac {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.7rem;
}

.top-client-item .client-roams {
    color: var(--text-secondary);
}

.top-client-item .client-rate.rate-excellent { color: var(--success-color); }
.top-client-item .client-rate.rate-good { color: #3b82f6; }
.top-client-item .client-rate.rate-fair { color: var(--warning-color); }
.top-client-item .client-rate.rate-poor { color: var(--danger-color); }

/* Roaming Clients Grid */
.roaming-clients-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
}

.clients-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.75rem;
}

.client-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 0.75rem;
}

.client-info {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.client-info .client-name {
    font-weight: 500;
    font-size: 0.875rem;
}

.client-info .client-mac {
    font-size: 0.7rem;
    font-family: var(--font-mono);
    color: var(--text-muted);
}

.client-stats {
    display: flex;
    gap: 1rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
}

.client-stats .stat {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.client-stats .stat.rate-excellent { color: var(--success-color); }
.client-stats .stat.rate-good { color: #3b82f6; }
.client-stats .stat.rate-fair { color: var(--warning-color); }
.client-stats .stat.rate-poor { color: var(--danger-color); }

/* Responsive Roaming Analytics */
@media (max-width: 768px) {
    .roaming-stats-row {
        flex-direction: column;
    }

    .roaming-stat-card {
        min-width: unset;
    }

    .paths-header,
    .paths-row {
        grid-template-columns: 1.5fr 1fr 1fr;
    }

    .path-fast,
    .paths-header .path-fast,
    .path-success,
    .paths-header .path-success {
        display: none;
    }

    .edge-details-grid {
        grid-template-columns: 1fr;
    }

    .direction-stats {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ============================================
   Channel Analysis Component
   ============================================ */


.channel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.channel-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.channel-plan-age {
    font-size: 0.825rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.channel-loading,
.channel-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Channel Stats Row */
.channel-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.channel-stat-card {
    flex: 1;
    min-width: 100px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}

.channel-stat-card.stat-warning .channel-stat-value { color: var(--warning-color); }
.channel-stat-card.stat-danger .channel-stat-value { color: var(--danger-color); }


.channel-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

/* Band Tabs */
.band-tabs {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.band-tab {
    padding: 0.5rem 1rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-secondary);
    font-size: 0.875rem;
    cursor: pointer;
    transition: all 0.15s ease;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

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

.band-tab.active {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: white;
}

/* Band-specific colors for active tabs */
.band-tab.active.band-2ghz {
    background: #fbbf24;
    border-color: #fbbf24;
    color: var(--text-dark);
}

.band-tab.active.band-5ghz {
    background: #3b82f6;
    border-color: #3b82f6;
}

.band-tab.active.band-6ghz {
    background: #a855f7;
    border-color: #a855f7;
}


.band-tab .issue-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    background: var(--warning-color);
    color: white;
    border-radius: 50%;
    font-size: 0.65rem;
    font-weight: 600;
    margin-left: 0.7rem;
}

.band-tab .mesh-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    background: #3b82f6;
    color: white;
    border-radius: 50%;
    font-size: 0.5rem;
    font-weight: 600;
    margin-left: 0.5rem;
}

/* Channel Map */
.channel-map-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
}

.channel-map {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.channel-slot {
    width: 48px;
    height: 64px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.15s ease;
}

.channel-slot:hover {
    border-color: var(--primary-color);
}

.channel-slot.occupied {
    background: var(--bg-hover);
    border-color: var(--primary-color);
}

.channel-slot.overlap {
    border-color: var(--warning-color);
    background: rgba(231, 150, 19, 0.1);
}

.channel-slot.mesh {
    border-color: var(--primary-light);
    background: rgba(59, 130, 246, 0.1);
}

/* Channel width grouping - shows bonded channels with alternating half-outlines */
/* Odd groups: "hat" shape (top half) - horizontal top + vertical from 50% up */
/* Even groups: "cup" shape (bottom half) - horizontal bottom + vertical from 50% down */
.channel-slot.width-group {
    position: relative;
    --group-border-color: var(--success-color);
}

/* Band-specific colors matching the badge colors */
.channel-slot.band-2ghz { --group-border-color: #fbbf24; }
.channel-slot.band-5ghz { --group-border-color: #3b82f6; }
.channel-slot.band-6ghz { --group-border-color: #a855f7; }

/* Base styles for the outline pseudo-element */
.channel-slot.width-group::before {
    content: '';
    position: absolute;
    pointer-events: none;
}

/* === ODD GROUPS: "Hat" shape (top half) === */

/* Single channel - odd: top border + left/right from top to 50% */
.channel-slot.group-single.group-odd::before {
    left: 0;
    right: 0;
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group-border-color);
    border-left: 2px solid var(--group-border-color);
    border-right: 2px solid var(--group-border-color);
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

/* Start of group - odd: top border extending right + left vertical from top to 50% */
.channel-slot.group-start.group-odd::before {
    left: 0;
    right: calc(-0.5rem - 1px);
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group-border-color);
    border-left: 2px solid var(--group-border-color);
    border-radius: var(--border-radius) 0 0 0;
}

/* Middle of group - odd: top border only */
.channel-slot.group-middle.group-odd::before {
    left: calc(-0.5rem - 1px);
    right: calc(-0.5rem - 1px);
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group-border-color);
}

/* End of group - odd: top border extending left + right vertical from top to 50% */
.channel-slot.group-end.group-odd::before {
    left: calc(-0.5rem - 1px);
    right: 0;
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group-border-color);
    border-right: 2px solid var(--group-border-color);
    border-radius: 0 var(--border-radius) 0 0;
}

/* === EVEN GROUPS: "Cup" shape (bottom half) === */

/* Single channel - even: bottom border + left/right from 50% to bottom */
.channel-slot.group-single.group-even::before {
    left: 0;
    right: 0;
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group-border-color);
    border-left: 2px solid var(--group-border-color);
    border-right: 2px solid var(--group-border-color);
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

/* Start of group - even: bottom border extending right + left vertical from 50% to bottom */
.channel-slot.group-start.group-even::before {
    left: 0;
    right: calc(-0.5rem - 1px);
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group-border-color);
    border-left: 2px solid var(--group-border-color);
    border-radius: 0 0 0 var(--border-radius);
}

/* Middle of group - even: bottom border only */
.channel-slot.group-middle.group-even::before {
    left: calc(-0.5rem - 1px);
    right: calc(-0.5rem - 1px);
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group-border-color);
}

/* End of group - even: bottom border extending left + right vertical from 50% to bottom */
.channel-slot.group-end.group-even::before {
    left: calc(-0.5rem - 1px);
    right: 0;
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group-border-color);
    border-right: 2px solid var(--group-border-color);
    border-radius: 0 0 var(--border-radius) 0;
}

/* Hatched pattern for overlapping width groups - applied via background on element */
.channel-slot.width-overlap-hatched {
    background-image: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 3px,
        var(--group-border-color) 3px,
        var(--group-border-color) 5px
    );
    background-blend-mode: overlay;
}

/* === SECOND GROUP (has-group2): Renders via ::after === */
/* Uses group2-* classes to determine band color and position */

.channel-slot.has-group2 {
    --group2-border-color: var(--success-color);
}

.channel-slot.has-group2.group2-band-2ghz { --group2-border-color: #fbbf24; }
.channel-slot.has-group2.group2-band-5ghz { --group2-border-color: #3b82f6; }
.channel-slot.has-group2.group2-band-6ghz { --group2-border-color: #a855f7; }

.channel-slot.has-group2::after {
    content: '';
    position: absolute;
    pointer-events: none;
}

/* Second group ODD (hat/top) */
.channel-slot.has-group2.group2-single.group2-group-odd::after {
    left: 0;
    right: 0;
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group2-border-color);
    border-left: 2px solid var(--group2-border-color);
    border-right: 2px solid var(--group2-border-color);
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

.channel-slot.has-group2.group2-start.group2-group-odd::after {
    left: 0;
    right: calc(-0.5rem - 1px);
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group2-border-color);
    border-left: 2px solid var(--group2-border-color);
    border-radius: var(--border-radius) 0 0 0;
}

.channel-slot.has-group2.group2-middle.group2-group-odd::after {
    left: calc(-0.5rem - 1px);
    right: calc(-0.5rem - 1px);
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group2-border-color);
}

.channel-slot.has-group2.group2-end.group2-group-odd::after {
    left: calc(-0.5rem - 1px);
    right: 0;
    top: -3px;
    bottom: 50%;
    border-top: 2px solid var(--group2-border-color);
    border-right: 2px solid var(--group2-border-color);
    border-radius: 0 var(--border-radius) 0 0;
}

/* Second group EVEN (cup/bottom) */
.channel-slot.has-group2.group2-single.group2-group-even::after {
    left: 0;
    right: 0;
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group2-border-color);
    border-left: 2px solid var(--group2-border-color);
    border-right: 2px solid var(--group2-border-color);
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

.channel-slot.has-group2.group2-start.group2-group-even::after {
    left: 0;
    right: calc(-0.5rem - 1px);
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group2-border-color);
    border-left: 2px solid var(--group2-border-color);
    border-radius: 0 0 0 var(--border-radius);
}

.channel-slot.has-group2.group2-middle.group2-group-even::after {
    left: calc(-0.5rem - 1px);
    right: calc(-0.5rem - 1px);
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group2-border-color);
}

.channel-slot.has-group2.group2-end.group2-group-even::after {
    left: calc(-0.5rem - 1px);
    right: 0;
    top: 50%;
    bottom: -3px;
    border-bottom: 2px solid var(--group2-border-color);
    border-right: 2px solid var(--group2-border-color);
    border-radius: 0 0 var(--border-radius) 0;
}

.channel-number {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-primary);
}

.channel-aps {
    display: flex;
    gap: 2px;
}

.channel-ap-dot {
    width: 10px;
    height: 10px;
    background: var(--primary-color);
    border-radius: 50%;
}

.channel-ap-dot.dot-single {
    width: 14px;
    height: 14px;
}

/* Band-specific colors for AP dots */
.channel-ap-dot.band-2ghz { background: #fbbf24; }
.channel-ap-dot.band-5ghz { background: #3b82f6; }
.channel-ap-dot.band-6ghz { background: #a855f7; }

.channel-ap-more {
    font-size: 0.6rem;
    color: var(--text-muted);
}

.channel-util {
    font-size: 0.65rem;
}

.channel-util.util-low { color: var(--success-color); }
.channel-util.util-medium { color: var(--warning-color); }
.channel-util.util-high { color: var(--danger-color); }

.channel-recommendations {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.rec-channels {
    font-weight: 600;
    color: var(--success-color);
}

/* Channel Details Section */
.channel-details-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
    border: 1px solid var(--primary-color);
}

.overlap-warning {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: rgba(231, 150, 19, 0.1);
    border: 1px solid var(--warning-color);
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: var(--warning-color);
}

.overlap-warning .warning-icon {
    width: 20px;
    height: 20px;
    background: var(--warning-color);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.75rem;
}

.mesh-info {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: rgba(59, 130, 246, 0.1);
    border: 1px solid #60a5fa;
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: var(--primary-light);
}

.mesh-info .mesh-icon {
    width: 20px;
    height: 20px;
    background: #3b82f6;
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.65rem;
}

.channel-aps-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.channel-ap-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
}

.channel-ap-card .ap-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.channel-ap-card .ap-name {
    font-weight: 600;
    color: var(--text-primary);
}

.channel-ap-card .ap-model {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.ap-radio-details {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}

.ap-radio-details .detail-item {
    display: flex;
    flex-direction: column;
}

.ap-radio-details .detail-label {
    font-size: 0.65rem;
    color: var(--text-muted);
    text-transform: uppercase;
}

.ap-radio-details .detail-value {
    font-size: 0.875rem;
    font-weight: 500;
}

.ap-radio-details .detail-value.util-low { color: var(--success-color); }
.ap-radio-details .detail-value.util-medium { color: var(--warning-color); }
.ap-radio-details .detail-value.util-high { color: var(--danger-color); }

.ap-radio-details .detail-value.interf-low { color: var(--success-color); }
.ap-radio-details .detail-value.interf-medium { color: var(--warning-color); }
.ap-radio-details .detail-value.interf-high { color: var(--danger-color); }

.ap-radio-details .detail-value.sat-excellent { color: var(--success-color); }
.ap-radio-details .detail-value.sat-good { color: #3b82f6; }
.detail-value.sat-fair { color: var(--warning-color); }
.detail-value.sat-poor { color: var(--danger-color); }

/* APs Band Table */
.aps-band-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
}

.aps-band-table {
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    overflow: hidden;
}

.aps-header {
    display: grid;
    grid-template-columns: 2fr 0.8fr 0.8fr 200px 1.2fr 0.8fr 0.6fr;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
}

.aps-row {
    display: grid;
    grid-template-columns: 2fr 0.8fr 0.8fr 200px 1.2fr 0.8fr 0.6fr;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.875rem;
    align-items: center;
}

.aps-row:hover {
    background: var(--bg-tertiary);
}

.aps-row.clickable {
    cursor: pointer;
}

.aps-row .ap-power-col .power-bar-container {
    max-width: 170px;
    background: var(--bg-tertiary);
}

.aps-row .ap-power-col .power-mode-below {
    display: block;
    max-width: 170px;
    text-align: center;
    margin-top: 3px;
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: capitalize;
}

.ap-name-col {
    display: flex;
    flex-direction: column;
}

.ap-name-col .ap-name {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.ap-name-col .ap-model {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.channel-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.25rem 0.5rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-weight: 600;
}

.channel-badge.overlap {
    background: rgba(231, 150, 19, 0.2);
    color: var(--warning-color);
}

.channel-badge.mesh {
    background: rgba(59, 130, 246, 0.15);
    color: var(--primary-light);
}

.power-value {
    font-weight: 500;
}

.power-mode {
    font-size: 0.7rem;
    color: var(--text-muted);
    margin-left: 0.25rem;
}

.util-bar-container {
    width: 60px;
    height: 6px;
    background: var(--bg-tertiary);
    border-radius: 0 3px 3px 0;
    overflow: hidden;
    display: inline-block;
    margin-right: 0.5rem;
}

.util-bar {
    height: 100%;
    border-radius: 0 3px 3px 0;
    transition: width 0.3s ease;
}

.util-bar.util-low { background: var(--success-color); }
.util-bar.util-medium { background: var(--warning-color); }
.util-bar.util-high { background: var(--danger-color); }

.util-value {
    font-size: 0.75rem;
}

.ap-interf-col.interf-low { color: var(--success-color); }
.ap-interf-col.interf-medium { color: var(--warning-color); }
.ap-interf-col.interf-high { color: var(--danger-color); }

/* Channel Issues Section - wrapper only, issue styling from IssuesList component */
.channel-issues-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
}

/* Channel Recommendation View */
.recommendation-view {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.recommendation-view .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.channel-disclaimer {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: rgba(234, 179, 8, 0.08);
    border: 1px solid rgba(234, 179, 8, 0.25);
    border-radius: var(--border-radius);
    font-size: 0.85rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

.channel-disclaimer .disclaimer-content {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    flex: 1;
}

.channel-disclaimer .disclaimer-icon {
    flex-shrink: 0;
    color: var(--warning-color);
    margin-top: 2px;
}

.channel-disclaimer .disclaimer-link {
    color: var(--primary-color);
    text-decoration: underline;
}

.channel-disclaimer .disclaimer-link:hover {
    color: var(--primary-hover);
}

.channel-disclaimer .disclaimer-dismiss-btn {
    flex-shrink: 0;
    white-space: nowrap;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border: none;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.channel-disclaimer .disclaimer-dismiss-btn:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.info-tip {
    background: rgba(71, 151, 255, 0.1);
    border: 1px solid var(--info-color);
    border-left: 4px solid var(--info-color);
    border-radius: var(--border-radius);
    padding: 1rem;
    margin-top: 1rem;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: var(--text-primary);
}

.info-tip strong {
    color: var(--info-color);
}

.info-tip ul {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
}

.info-tip li {
    margin-top: 0.25rem;
}

.info-tip-actions {
    text-align: right;
}

/* Score coloring */
.score-excellent { color: #22c55e; }
.score-good { color: #3b82f6; }
.score-fair { color: #fbbf24; }
.score-poor { color: #f97316; }
.score-bad { color: #ef4444; }

/* Changed channel highlight */
.ap-recommendation-changed { background: rgba(249, 115, 22, 0.08); }
.rec-changed { color: var(--accent-color); font-weight: 600; }
.channel-change-arrow { color: var(--text-muted); display: inline-flex; align-items: center; }
.channel-change-arrow svg { vertical-align: middle; }
.rec-no-change { color: var(--text-muted); font-style: italic; margin-left: 0.5rem; }

/* DFS badge */
.dfs-badge {
    font-size: 0.625rem;
    padding: 0.1rem 0.3rem;
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
    border-radius: var(--border-radius-sm);
    margin-left: 0.25rem;
}

/* Mesh link badge */
.mesh-link-badge {
    font-size: 0.7rem;
    font-weight: 500;
    padding: 0.125rem 0.5rem;
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
    border-radius: 3px;
    margin-left: 0.5rem;
}

/* Channels recommendation row: pin toggle beside the AP name */
.rec-pin-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    opacity: 0.7;
}

.rec-pin-btn:hover {
    opacity: 1;
    background: var(--bg-hover);
    color: var(--text-primary);
}

.rec-pin-btn.pinned {
    opacity: 1;
    color: var(--accent-color);
}

.rec-pin-btn:disabled {
    cursor: default;
    opacity: 0.4;
}

.soak-badge {
    font-size: 0.7rem;
    font-weight: 500;
    padding: 0.125rem 0.5rem;
    background: rgba(43, 168, 154, 0.15);
    color: #2ba89a;
    border-radius: 3px;
    margin-left: 0.5rem;
}

/* Recommend Best Channels button - accent gradient matching Cleanest Channels box */
.btn-recommend {
    background: linear-gradient(135deg, var(--accent-color) 0%, var(--primary-color) 100%);
    color: white;
    border: none;
    height: 34px;
    padding: 0 1.25rem;
    font-size: 0.875rem;
    font-weight: 500;
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.btn-recommend:hover:not(:disabled) {
    filter: brightness(1.15);
    box-shadow: 0 2px 8px rgba(249, 115, 22, 0.4);
}

.btn-recommend:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.btn-recommend .spinner-sm {
    border-color: rgba(255, 255, 255, 0.4);
    border-top-color: white;
}

/* Unplaced AP notice */
.recommendation-notice {
    padding: 0.75rem;
    border-radius: var(--border-radius-lg);
    font-size: 0.8125rem;
    background: rgba(71, 151, 255, 0.1);
    color: var(--text-secondary);
}

.recommendation-notice.alert-warning {
    background: rgba(245, 158, 11, 0.1);
    color: var(--warning-color);
}

/* Apply Recommended Channels: button row and the progress / results panel. Sizes come from
   .recommendation-notice; spacing from .recommendation-view's gap. */
.recommendation-view .channel-apply-actions {
    justify-content: flex-end;
}

.recommendation-view .channel-apply-panel {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.recommendation-view .channel-apply-title {
    font-weight: 600;
    color: var(--text-primary);
}

.recommendation-view .channel-apply-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.recommendation-view .channel-apply-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.75rem;
}

.recommendation-view .channel-apply-ap {
    min-width: 10rem;
    font-weight: 500;
    color: var(--text-primary);
}

.recommendation-view .channel-apply-change {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

@media (max-width: 768px) {
    .recommendation-view .channel-apply-actions .btn {
        flex: 1 1 100%;
    }

    .recommendation-view .channel-apply-ap {
        flex-basis: 100%;
        min-width: 0;
    }
}

/* DFS preference toggle */
.dfs-toggle { margin: 0; }

/* How This Works expandable */
.recommendation-explainer {
    margin: 0.5rem 0.5rem 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
}
.recommendation-explainer summary {
    padding: 0.6rem 0.85rem;
    cursor: pointer;
    font-weight: 500;
    font-size: 0.85rem;
    color: var(--text-secondary);
    user-select: none;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.recommendation-explainer summary::-webkit-details-marker {
    display: none;
}
.recommendation-explainer summary::before {
    content: "▶";
    font-size: 0.65rem;
    transition: transform 0.2s ease;
}
.recommendation-explainer[open] summary::before {
    transform: rotate(90deg);
}
.recommendation-explainer summary:hover {
    color: var(--text-primary);
    background: var(--bg-elevated);
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
}
.recommendation-explainer:not([open]) summary:hover {
    border-radius: var(--border-radius-lg);
}
.recommendation-explainer-content {
    padding: 0 0.85rem 0.85rem 0.85rem;
    border-top: 1px solid var(--border-color);
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.5;
}
.recommendation-explainer-content p {
    margin: 0.6rem 0;
}
.recommendation-explainer-content ul {
    margin: 0.6rem 0;
    padding-left: 1.1rem;
}
.recommendation-explainer-content li {
    margin-bottom: 0.35rem;
}
.recommendation-explainer-content li strong {
    color: var(--text-secondary);
}

/* Improvement stat highlighting */
.stat-improvement .channel-stat-value { color: var(--success-color); }

/* Recommendation table - own grid, independent of regular aps-header/aps-row */
.rec-header,
.rec-row {
    display: grid;
    grid-template-columns: 2fr 0.6fr 2fr 0.8fr;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    font-size: 0.875rem;
    align-items: center;
}

.rec-header {
    background: var(--bg-tertiary);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.rec-row {
    border-top: 1px solid var(--border-color);
}

.rec-row:hover {
    background: var(--bg-tertiary);
}

.rec-name-col {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.rec-name-col .ap-name {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-weight: 500;
}

.rec-score-col {
    text-align: center;
}

.rec-channels-col {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
}

/* A width reason or a move's measurement sits on its own line under the channels. */
.rec-channels-col .rec-move-note {
    flex-basis: 100%;
    text-align: center;
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

/* Responsive Channel Analysis */
@media (max-width: 768px) {
    /* Used twice on Channels: the four summary stats (2x2) and the per-band plan summary of two
       or three cards. An odd last card takes the full row rather than sitting half-width alone. */
    .channel-stats-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.75rem;
    }

    .channel-stat-card {
        min-width: unset;
    }

    .channel-stat-card:last-child:nth-child(odd) {
        grid-column: 1 / -1;
    }

    .band-tabs {
        flex-wrap: wrap;
    }

    .channel-header {
        flex-wrap: wrap;
        gap: 0.75rem;
    }

    .channel-map-section,
    .aps-band-section,
    .channel-details-section,
    .channel-issues-section {
        padding: 1rem 0;
    }

    .channel-map {
        justify-content: center;
    }

    .aps-header,
    .aps-row {
        grid-template-columns: 1.5fr 0.8fr 0.8fr 1fr;
    }

    .ap-power-col,
    .aps-header .ap-power-col,
    .ap-interf-col,
    .aps-header .ap-interf-col,
    .ap-clients-col,
    .aps-header .ap-clients-col {
        display: none;
    }

    .ap-radio-details {
        grid-template-columns: repeat(2, 1fr);
    }

    /* Recommendation table mobile - hide score columns */
    .rec-header,
    .rec-row {
        grid-template-columns: 1.5fr 2.5fr;
    }

    .rec-score-col {
        display: none;
    }

    /* Wrap badges on mobile */
    .ap-name-col .ap-name,
    .rec-name-col .ap-name {
        flex-wrap: wrap;
    }
}

/* ============================================
   AP Load Balance Component
   ============================================ */


.load-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.load-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.load-loading,
.load-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Load Stats Row */
.load-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.load-stat-card {
    flex: 1;
    min-width: 100px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}


.load-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.load-stat-card.stat-good .load-stat-value { color: var(--success-color); }
.load-stat-card.stat-warning .load-stat-value { color: var(--warning-color); }
.load-stat-card.stat-danger .load-stat-value { color: var(--danger-color); }

/* Load Chart Section */
.load-chart-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.load-chart-section .chart-legend {
    display: flex;
    gap: 1rem;
}

.load-chart-section .legend-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.load-chart-section .legend-color {
    width: 12px;
    height: 12px;
    border-radius: 2px;
}

.load-chart-section .legend-color.band-2ghz { background: #fbbf24; }
.load-chart-section .legend-color.band-5ghz { background: #3b82f6; }
.load-chart-section .legend-color.band-6ghz { background: #a855f7; }

.load-chart {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem 0;
}

.load-bar-row {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.load-bar-label {
    width: 180px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
}

.load-bar-label .ap-name {
    font-weight: 500;
    font-size: 0.875rem;
    color: var(--text-primary);
}

.load-bar-label .ap-clients {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.load-bar-container {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.load-bar {
    height: 24px;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    display: flex;
    overflow: hidden;
    min-width: 4px;
}

.load-segment {
    height: 100%;
    transition: width 0.3s ease;
}

.load-segment.band-2ghz { background: #fbbf24; }
.load-segment.band-5ghz { background: #3b82f6; }
.load-segment.band-6ghz { background: #a855f7; }

.overload-indicator {
    width: 20px;
    height: 20px;
    background: var(--warning-color);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.75rem;
    flex-shrink: 0;
}

.ideal-line-container {
    position: relative;
    height: 24px;
    margin-left: 196px;
    border-top: 1px dashed var(--text-muted);
}

.ideal-marker {
    position: absolute;
    top: -8px;
    transform: translateX(-50%);
}

.ideal-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    background: var(--bg-secondary);
    padding: 2px 6px;
    border-radius: 3px;
}

/* AP Details Section */
.ap-details-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.ap-details-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.ap-detail-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
    border: 1px solid transparent;
}

.ap-detail-card.ap-overloaded {
    border-color: var(--warning-color);
}

.ap-detail-card.ap-underloaded {
    border-color: var(--info-color);
    opacity: 0.8;
}

.ap-detail-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 0.75rem;
}

.ap-detail-header .ap-info {
    display: flex;
    flex-direction: column;
}

.ap-detail-header .ap-name {
    font-weight: 600;
    color: var(--text-primary);
}

.ap-detail-header .ap-model {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.ap-client-count {
    text-align: right;
}

.ap-client-count.clickable {
    cursor: pointer;
    border-radius: 6px;
    transition: background-color 0.15s ease;
}

.ap-client-count.clickable:hover {
    background-color: var(--bg-hover);
}

.ap-client-count .count-value {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--text-primary);
}

.ap-client-count .count-label {
    font-size: 0.65rem;
    color: var(--text-muted);
    display: block;
}

.ap-radios-summary {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.radio-summary {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.8rem;
}

.radio-summary .radio-band {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
}

.radio-summary .radio-band.band-2ghz {
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}

.radio-summary .radio-band.band-5ghz {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
}

.radio-summary .radio-band.band-6ghz {
    background: rgba(168, 85, 247, 0.15);
    color: #a855f7;
}

.radio-summary .radio-clients {
    color: var(--text-secondary);
}

.radio-summary .radio-clients.clickable {
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.15s ease;
}

.radio-summary .radio-clients.clickable:hover {
    background-color: var(--bg-hover);
}

.radio-summary .radio-util {
    margin-left: auto;
}

.radio-summary .radio-util.util-low { color: var(--success-color); }
.radio-summary .radio-util.util-medium { color: var(--warning-color); }
.radio-summary .radio-util.util-high { color: var(--danger-color); }

.ap-satisfaction {
    display: flex;
    justify-content: space-between;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.8rem;
}

.ap-satisfaction .sat-label {
    color: var(--text-muted);
}

.ap-satisfaction .sat-value.sat-excellent { color: var(--success-color); }
.ap-satisfaction .sat-value.sat-good { color: #3b82f6; }
.ap-satisfaction .sat-value.sat-fair { color: var(--warning-color); }
.ap-satisfaction .sat-value.sat-poor { color: var(--danger-color); }

.ap-warning,
.ap-info-msg {
    margin-top: 0.5rem;
    padding: 0.5rem;
    border-radius: var(--border-radius);
    font-size: 0.75rem;
}

.ap-warning {
    background: rgba(231, 150, 19, 0.1);
    color: var(--warning-color);
}

.ap-info-msg {
    background: rgba(71, 151, 255, 0.1);
    color: var(--info-color);
}

/* Load Recommendations Section */
.load-recommendations-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
}

.recommendations-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.recommendation-item {
    display: flex;
    gap: 0.75rem;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
    border-left: 3px solid var(--border-color);
}

.recommendation-item.warning {
    border-left-color: var(--warning-color);
}

.recommendation-item.info {
    border-left-color: var(--info-color);
}

.rec-icon {
    width: 24px;
    height: 24px;
    background: var(--bg-secondary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
    flex-shrink: 0;
}

.recommendation-item.warning .rec-icon {
    background: var(--warning-color);
    color: white;
}

.recommendation-item.info .rec-icon {
    background: var(--info-color);
    color: white;
}

.rec-content {
    flex: 1;
}

.rec-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.rec-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.rec-action {
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--text-muted);
    border-left: 2px solid var(--info-color);
}

/* Responsive AP Load Balance */
@media (max-width: 768px) {
    .load-stats-row {
        flex-direction: column;
    }

    .load-stat-card {
        min-width: unset;
    }

    .load-bar-label {
        width: 120px;
    }

    .load-chart-section .chart-legend {
        flex-wrap: wrap;
        gap: 0.5rem;
    }

    .ideal-line-container {
        margin-left: 136px;
    }
}

@media (max-width: 768px) {
    .filterable-select {
        min-width: 0;
        max-width: 100%;
        width: 100%;
    }

    .client-selector-combo {
        width: 100%;
    }

    .client-selector {
        width: 100%;
        min-width: unset;
    }

    .client-info-details {
        flex-direction: column;
        gap: 0.5rem;
    }
}

/* ============================================
   Power & Coverage Analysis Component
   ============================================ */


.power-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.power-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.power-loading,
.power-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Power Stats Row */
.power-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.power-stat-card {
    flex: 1;
    min-width: 100px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}


.power-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.power-stat-card.stat-good .power-stat-value { color: var(--success-color); }
.power-stat-card.stat-warning .power-stat-value { color: var(--warning-color); }
.power-stat-card.stat-danger .power-stat-value { color: var(--danger-color); }

/* Signal quality classes */
.power-stat-card.signal-excellent .power-stat-value,
.signal-excellent { color: var(--signal-excellent); }
.power-stat-card.signal-good .power-stat-value,
.signal-good { color: var(--signal-good); }
.power-stat-card.signal-fair .power-stat-value,
.signal-fair { color: var(--signal-fair); }
.power-stat-card.signal-weak .power-stat-value,
.signal-weak { color: var(--signal-weak); }
.power-stat-card.signal-poor .power-stat-value,
.signal-poor { color: var(--signal-poor); }

/* WiFi Page Sections - Nested Card Colors */
.wifi-sections .card {
    background: var(--bg-tertiary);
}

.wifi-sections .card .data-table tbody tr {
    background: var(--bg-secondary);
}

.wifi-sections .card .card {
    background: var(--bg-secondary);
}

.wifi-sections .card .card .data-table tbody tr {
    background: var(--bg-tertiary);
}

.wifi-sections .card .card .card {
    background: var(--bg-tertiary);
}

.wifi-sections .card .card .card .data-table tbody tr {
    background: var(--bg-secondary);
}

.wifi-sections .card .card .card .card {
    background: var(--bg-secondary);
}

/* Power Sections */
.power-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}


.power-section .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.power-section .section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.power-section .section-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Signal Distribution Chart */
.signal-distribution {
    padding: 1rem 0;
}

.signal-bars {
    display: flex;
    align-items: flex-end;
    height: 150px;
    gap: 4px;
    padding: 0 0.5rem;
    margin-bottom: 0;
}

.signal-bar-wrapper {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

.signal-bar {
    width: 100%;
    border-radius: 0 0 var(--border-radius) var(--border-radius);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 4px;
    transition: height 0.3s ease;
    position: relative;
}

.signal-bar .bar-count {
    font-size: 0.65rem;
    color: white;
    font-weight: 600;
    position: absolute;
    top: 4px;
}

.signal-bar.signal-excellent { background: #10b981; }
.signal-bar.signal-good { background: #22c55e; }
.signal-bar.signal-fair { background: #eab308; }
.signal-bar.signal-weak { background: #f97316; }
.signal-bar.signal-poor { background: #ef4444; }

.signal-bar-label {
    font-size: 0.65rem;
    color: var(--text-muted);
    margin-top: 0.5rem;
    text-align: center;
}

.signal-legend {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: center;
}

.signal-legend .legend-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.signal-legend .legend-color {
    width: 12px;
    height: 12px;
    border-radius: 2px;
}

.signal-legend .legend-color.signal-excellent { background: #10b981; }
.signal-legend .legend-color.signal-good { background: #22c55e; }
.signal-legend .legend-color.signal-fair { background: #eab308; }
.signal-legend .legend-color.signal-weak { background: #f97316; }
.signal-legend .legend-color.signal-poor { background: #ef4444; }

/* TX Power Grid */
.ap-power-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}

.ap-power-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
}

.ap-power-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
}

.ap-power-header .ap-name {
    font-weight: 600;
    color: var(--text-primary);
}

.ap-power-header .ap-model {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.radio-power-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.radio-power-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.radio-power-item .radio-info {
    width: 80px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
}

.radio-power-item .radio-band {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
    width: fit-content;
}

.radio-power-item .radio-band.band-2ghz {
    background: rgba(251, 191, 36, 0.2);
    color: #fbbf24;
}

.radio-power-item .radio-band.band-5ghz {
    background: rgba(59, 130, 246, 0.2);
    color: #3b82f6;
}

.radio-power-item .radio-band.band-6ghz {
    background: rgba(168, 85, 247, 0.2);
    color: #a855f7;
}

.radio-power-item .radio-channel {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.power-bar-container {
    flex: 1;
    height: 20px;
    background: var(--bg-secondary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
    position: relative;
    display: flex;
    align-items: center;
}

.power-bar-stack {
    display: flex;
    height: 100%;
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
}

.power-bar-tx {
    height: 100%;
    transition: width 0.3s ease;
}

.power-bar-tx.power-high { background: linear-gradient(90deg, #f97316, #ea580c); }
.power-bar-tx.power-medium { background: linear-gradient(90deg, #22c55e, #16a34a); }
.power-bar-tx.power-low { background: linear-gradient(90deg, #3b82f6, #2563eb); }
.power-bar-tx.power-auto { background: linear-gradient(90deg, #3b82f6, #2563eb); }

.power-bar-gain {
    height: 100%;
    border-left: 1px dashed rgba(255, 255, 255, 0.3);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.power-bar-gain.power-high {
    background: repeating-linear-gradient(90deg, #f97316 0px, #f97316 3px, #ea580c 3px, #ea580c 6px);
}
.power-bar-gain.power-medium {
    background: repeating-linear-gradient(90deg, #22c55e 0px, #22c55e 3px, #16a34a 3px, #16a34a 6px);
}
.power-bar-gain.power-low {
    background: repeating-linear-gradient(90deg, #3b82f6 0px, #3b82f6 3px, #2563eb 3px, #2563eb 6px);
}
.power-bar-gain.power-auto {
    background: repeating-linear-gradient(90deg, #3b82f6 0px, #3b82f6 3px, #2563eb 3px, #2563eb 6px);
}

.power-values {
    position: absolute;
    right: 8px;
    display: flex;
    align-items: center;
    gap: 2px;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-primary);
    z-index: 1;
}

.power-tx {
    color: var(--text-primary);
}

.power-eirp {
    font-style: italic;
}

.power-unit {
    margin-left: 2px;
}

.power-mode {
    width: 50px;
    text-align: right;
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: capitalize;
}

.power-warning {
    margin-top: 0.75rem;
    padding: 0.5rem;
    border-radius: var(--border-radius);
    background: rgba(231, 150, 19, 0.1);
    color: var(--warning-color);
    font-size: 0.75rem;
}

/* Coverage Grid */
.coverage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.coverage-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
    border: 1px solid transparent;
}

.coverage-card.coverage-poor {
    border-color: var(--danger-color);
}

.coverage-card.coverage-fair {
    border-color: var(--warning-color);
}

.coverage-card.coverage-good {
    border-color: var(--success-color);
}

.coverage-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
}

.coverage-header .ap-name {
    font-weight: 600;
    color: var(--text-primary);
}

.coverage-header .client-count {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.coverage-metrics {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.coverage-metric {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
}

.coverage-metric .metric-label {
    font-size: 0.65rem;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
}

.coverage-metric .metric-value {
    font-size: 0.875rem;
    font-weight: 600;
}

.weak-clients-warning {
    padding: 0.5rem;
    border-radius: var(--border-radius);
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
    font-size: 0.75rem;
    margin-bottom: 0.75rem;
}

.coverage-distribution {
    height: 8px;
    display: flex;
    border-radius: var(--border-radius);
    overflow: hidden;
    background: var(--bg-secondary);
}

.dist-segment {
    height: 100%;
    transition: width 0.3s ease;
}

.dist-segment.signal-excellent { background: #10b981; }
.dist-segment.signal-good { background: #22c55e; }
.dist-segment.signal-fair { background: #eab308; }
.dist-segment.signal-weak { background: #f97316; }
.dist-segment.signal-poor { background: #ef4444; }

/* Overlap Issues */
.overlap-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.overlap-item {
    display: flex;
    gap: 0.75rem;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
    border-left: 3px solid var(--warning-color);
}

.overlap-icon {
    width: 24px;
    height: 24px;
    background: var(--warning-color);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
    flex-shrink: 0;
}

.overlap-content {
    flex: 1;
}

.overlap-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.overlap-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

/* Power/Coverage Recommendations */
.power-section .recommendations-list .rec-action {
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--text-muted);
    border-left: 2px solid var(--info-color);
}

/* Responsive Power/Coverage */
@media (max-width: 768px) {
    .power-stats-row {
        flex-direction: column;
    }

    .power-stat-card {
        min-width: unset;
    }

    .signal-bars {
        height: 120px;
    }

    .signal-legend {
        gap: 0.5rem;
    }

    .ap-power-grid,
    .coverage-grid {
        grid-template-columns: 1fr;
    }

    .coverage-metrics {
        flex-wrap: wrap;
    }

    .coverage-metric {
        min-width: calc(50% - 0.5rem);
    }
}

/* ============================================
   Band Steering Analysis Component
   ============================================ */


.steering-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.steering-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.steering-loading,
.steering-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Steering Stats Row */
.steering-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.steering-stat-card {
    flex: 1;
    min-width: 100px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}

.steering-stat-value {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.steering-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.steering-stat-card.band-2ghz-card {
    border-left: 3px solid #fbbf24;
}
.steering-stat-card.band-5ghz-card {
    border-left: 3px solid #3b82f6;
}
.steering-stat-card.band-6ghz-card {
    border-left: 3px solid #a855f7;
}

/* Steering Sections */
.steering-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}


.steering-section .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.steering-section .section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.steering-section .section-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Steering Effectiveness Chart */
.steering-effectiveness {
    padding: 1rem 0;
}

.effectiveness-chart {
    margin-bottom: 1rem;
}

.effectiveness-bar {
    height: 32px;
    display: flex;
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-tertiary);
}

.eff-segment {
    height: 100%;
    transition: width 0.3s ease;
}

.eff-segment.optimal { background: #22c55e; }
.eff-segment.suboptimal { background: #f97316; }
.eff-segment.legacy { background: #6b7280; }

.effectiveness-labels {
    display: flex;
    justify-content: space-between;
    margin-top: 0.25rem;
}

.eff-label {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.effectiveness-legend {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    flex-wrap: wrap;
}

.effectiveness-legend .legend-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.effectiveness-legend .legend-color {
    width: 12px;
    height: 12px;
    border-radius: 2px;
}

.effectiveness-legend .legend-color.optimal { background: #22c55e; }
.effectiveness-legend .legend-color.suboptimal { background: #f97316; }
.effectiveness-legend .legend-color.legacy { background: #6b7280; }

/* Steerable Groups */
.steerable-group {
    margin-bottom: 1rem;
}

.steerable-group:last-child {
    margin-bottom: 0;
}

.steerable-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
}

.steerable-band {
    padding: 0.25rem 0.75rem;
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    font-weight: 500;
}

.steerable-band.band-5ghz {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
}

.steerable-band.band-6ghz {
    background: rgba(168, 85, 247, 0.15);
    color: #a855f7;
}

.steerable-count {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.steerable-clients {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.steerable-client-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
}

.steerable-client-row .client-info {
    flex: 1;
    min-width: 0;
}

.steerable-client-row .client-name {
    font-weight: 500;
    color: var(--text-primary);
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.steerable-client-row .client-meta {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.steerable-client-row .client-current-band {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.steerable-client-row .current-label {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.band-badge {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
}

.band-badge.band-2ghz {
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}

.band-badge.band-5ghz {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
}

.band-badge.band-6ghz {
    background: rgba(168, 85, 247, 0.15);
    color: #a855f7;
}

.steerable-client-row .client-signal {
    font-size: 0.8rem;
    color: var(--text-secondary);
    min-width: 60px;
    text-align: right;
}

.more-clients {
    padding: 0.5rem;
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* Wi-Fi Generation Breakdown */
.wifi-gen-breakdown {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.wifi-gen-row {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.wifi-gen-label {
    width: 130px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.gen-badge {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 600;
}

.gen-badge.gen-7 { background: rgba(168, 85, 247, 0.15); color: #a855f7; }
.gen-badge.gen-6 { background: rgba(168, 85, 247, 0.15); color: #a855f7; }
.gen-badge.gen-6e {
    background: repeating-linear-gradient(
        -45deg,
        rgba(168, 85, 247, 0.15),
        rgba(168, 85, 247, 0.15) 3px,
        rgba(59, 130, 246, 0.15) 3px,
        rgba(59, 130, 246, 0.15) 6px
    );
    color: #a855f7;
}
.gen-badge.gen-5 { background: rgba(59, 130, 246, 0.15); color: #3b82f6; }
.gen-badge.gen-4 { background: rgba(251, 191, 36, 0.15); color: #fbbf24; }
.gen-badge.gen-legacy { background: rgba(107, 114, 128, 0.15); color: #6b7280; }

.gen-standard {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.wifi-gen-bar-container {
    flex: 1;
    height: 16px;
    background: var(--bg-tertiary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
    font-size: 0;
    white-space: nowrap;
}

.wifi-gen-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.wifi-gen-bar.gen-5, .gen-bar.gen-5 { background: #3b82f6; }
.wifi-gen-bar.gen-4, .gen-bar.gen-4 { background: #fbbf24; }
.wifi-gen-bar.gen-legacy, .gen-bar.gen-legacy { background: #6b7280; }

.wifi-gen-count {
    width: 40px;
    text-align: right;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-secondary);
}

/* Legacy Clients */
.legacy-clients-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.75rem;
}

.legacy-client-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 0.75rem;
}

.legacy-client-info {
    margin-bottom: 0.5rem;
}

.legacy-client-info .client-name {
    font-weight: 500;
    color: var(--text-primary);
    display: block;
}

.legacy-client-info .client-manufacturer {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.legacy-client-stats {
    display: flex;
    gap: 1rem;
}

.legacy-stat {
    display: flex;
    flex-direction: column;
}

.legacy-stat .stat-label {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.legacy-stat .stat-value {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

/* Band Steering Recommendations */
.steering-section .rec-action {
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--text-muted);
    border-left: 2px solid var(--info-color);
}

/* Responsive Band Steering */
@media (max-width: 768px) {
    .steering-stats-row {
        flex-direction: column;
    }

    .steering-stat-card {
        min-width: unset;
    }

    .steerable-client-row {
        flex-direction: column;
        align-items: flex-start;
    }

    .steerable-client-row .client-current-band {
        margin-top: 0.25rem;
    }

    .steerable-client-row .client-signal {
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

    .wifi-gen-label {
        width: 100px;
    }

    .wifi-gen-bar-container {
        flex: 1;
    }

    .legacy-clients-list {
        grid-template-columns: 1fr;
    }

    .effectiveness-legend {
        gap: 0.75rem;
    }
}

/* ============================================
   Airtime Fairness Component
   ============================================ */


.airtime-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
}

.airtime-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.header-actions {
    min-height: 34.5px;
    display: flex;
    align-items: center;
}

.airtime-loading,
.airtime-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Airtime Stats Row */
.airtime-stats-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.airtime-stat-card {
    flex: 1;
    min-width: 100px;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    text-align: center;
}

.airtime-stat-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.airtime-stat-card.stat-warning .airtime-stat-value {
    color: var(--warning-color);
}

/* Concept Explanation */
.airtime-concept {
    display: flex;
    gap: 0.75rem;
    padding: 1rem;
    background: var(--bg-primary);
    border-radius: var(--border-radius-lg);
    margin-bottom: 1.5rem;
    border-left: 3px solid var(--info-color);
}

.airtime-concept .concept-icon {
    width: 24px;
    height: 24px;
    background: var(--info-color);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
    flex-shrink: 0;
}

.airtime-concept .concept-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.airtime-concept .concept-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

/* Airtime Sections */
.airtime-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.airtime-section .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.airtime-section .section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.airtime-section .section-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Radio Utilization Grid */
.radio-utilization-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
}

.radio-util-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
}

.radio-util-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
}

.radio-util-header .ap-name {
    font-weight: 600;
    color: var(--text-primary);
}

.radio-util-header .client-count {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.radio-util-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.radio-util-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.radio-util-row .radio-info {
    width: 90px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
}

.radio-util-row .radio-band {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
    width: fit-content;
}

.radio-util-row .radio-channel {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.radio-util-bar-container {
    flex: 1;
    height: 16px;
    background: var(--bg-secondary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
    position: relative;
}

.radio-util-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.radio-util-bar.util-low { background: #22c55e; }
.radio-util-bar.util-medium { background: #eab308; }
.radio-util-bar.util-high { background: #ef4444; }

.radio-util-value {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-primary);
}

.radio-util-row .radio-clients {
    width: 30px;
    text-align: right;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.util-warning {
    margin-top: 0.75rem;
    padding: 0.5rem;
    border-radius: var(--border-radius);
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
    font-size: 0.75rem;
}

/* Wi-Fi Generation Airtime Chart */
.gen-airtime-chart {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.gen-airtime-row {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.gen-airtime-row .gen-label {
    width: 150px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
}

.gen-airtime-row .gen-factor {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.gen-bar-container {
    flex: 1;
    height: 20px;
    background: var(--bg-tertiary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
    font-size: 0;
    white-space: nowrap;
}

.gen-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

/* Band-segmented bars for Wi-Fi 6/7 */
.gen-bar-segment {
    height: 100%;
    display: inline-block;
    vertical-align: top;
    transition: width 0.3s ease;
}

.gen-bar-segment:first-child {
    border-radius: 0;
}

.gen-bar-segment:last-child {
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
}

.gen-bar-segment.band-2ghz {
    background: #fbbf24;
}

.gen-bar-segment.band-5ghz {
    background: #3b82f6;
}

.gen-bar-segment.band-6ghz {
    background: #a855f7;
}


.gen-airtime-row .gen-stats {
    width: 100px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.gen-airtime-row .gen-count {
    font-weight: 600;
    color: var(--text-primary);
}

.gen-airtime-row .gen-impact {
    font-size: 0.65rem;
}

.gen-impact.impact-low { color: var(--success-color); }
.gen-impact.impact-medium { color: var(--warning-color); }
.gen-impact.impact-high { color: var(--danger-color); }

/* Airtime Factor Legend */
.airtime-factor-legend {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    flex-wrap: wrap;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
}

.factor-item {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.factor-gen {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.factor-value {
    font-size: 0.7rem;
    color: var(--text-muted);
}

/* Airtime Clients List */
.airtime-clients-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.75rem;
}

.airtime-client-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 0.75rem;
    border-left: 3px solid var(--border-color);
}

.airtime-client-card.airtime-high {
    border-left-color: var(--danger-color);
}

.airtime-client-card.airtime-medium {
    border-left-color: var(--warning-color);
}

.airtime-client-card .client-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.airtime-client-card .client-name {
    font-weight: 500;
    color: var(--text-primary);
}

.airtime-indicator {
    font-size: 0.7rem;
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    background: var(--bg-secondary);
    color: var(--text-muted);
    white-space: nowrap;
}

.airtime-client-card.airtime-high .airtime-indicator {
    background: rgba(239, 68, 68, 0.15);
    color: var(--danger-color);
}

.airtime-client-card.airtime-medium .airtime-indicator {
    background: rgba(234, 179, 8, 0.15);
    color: var(--warning-color);
}

.airtime-client-card .client-details {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.airtime-client-card .client-detail {
    display: flex;
    flex-direction: column;
}

.airtime-client-card .detail-label {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.airtime-client-card .detail-value {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.airtime-client-card .client-reason {
    font-size: 0.75rem;
    color: var(--text-muted);
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
}

/* TX Retry Rates */
.retry-rate-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.retry-row {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.retry-ap-info {
    width: 240px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.retry-ap-info .ap-name {
    flex: 1;
    font-weight: 500;
    color: var(--text-primary);
    font-size: 0.875rem;
}

.retry-bar-container {
    flex: 1;
    height: 12px;
    background: var(--bg-tertiary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
}

.retry-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.retry-bar.retry-low { background: #22c55e; }
.retry-bar.retry-medium { background: #eab308; }
.retry-bar.retry-high { background: #ef4444; }

.retry-value {
    width: 50px;
    text-align: right;
    font-size: 0.875rem;
    font-weight: 500;
}

.retry-value.retry-low { color: var(--success-color); }
.retry-value.retry-medium { color: var(--warning-color); }
.retry-value.retry-high { color: var(--danger-color); }

/* Airtime Recommendations */
.airtime-section .rec-action {
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--text-muted);
    border-left: 2px solid var(--info-color);
}

/* Responsive Airtime */
@media (max-width: 768px) {
    .airtime-stats-row {
        flex-direction: column;
    }

    .airtime-stat-card {
        min-width: unset;
    }

    .radio-utilization-grid,
    .airtime-clients-list {
        grid-template-columns: 1fr;
    }

    .gen-airtime-row .gen-label {
        width: 120px;
    }

    .gen-airtime-row .gen-stats {
        width: 80px;
    }

    .retry-ap-info {
        width: 180px;
    }

    .airtime-factor-legend {
        gap: 0.75rem;
    }
}

/* ============================================
   Environmental Correlation Component
   ============================================ */


.env-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
    gap: 1rem;
}

.env-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.env-controls {
    display: flex;
    gap: 1rem;
    align-items: center;
    flex-wrap: wrap;
}

.env-controls .btn {
    margin-top: 1px;
}

.time-range-select {
    padding: 0.375rem 0.75rem;
    border-radius: var(--border-radius);
    border: 1px solid var(--border-color);
    background: var(--bg-tertiary);
    color: var(--text-primary);
    font-size: 0.875rem;
}

.env-loading,
.env-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Environmental Sections */
.env-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.env-section .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.env-section .section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.env-section .section-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Time of Day Grid */
.time-of-day-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}

.tod-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
    border-left: 3px solid var(--border-color);
}

.tod-card.period-good { border-left-color: var(--success-color); }
.tod-card.period-fair { border-left-color: var(--warning-color); }
.tod-card.period-poor { border-left-color: var(--danger-color); }

.tod-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}

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

.tod-hours {
    font-size: 0.7rem;
    color: var(--text-muted);
    margin-bottom: 0.75rem;
}

.tod-metrics {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.tod-metric {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
}

.tod-metric .metric-label {
    color: var(--text-muted);
}

.tod-metric .metric-value {
    font-weight: 500;
}

.tod-warning {
    margin-top: 0.5rem;
    padding: 0.25rem 0.5rem;
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
    font-size: 0.7rem;
    border-radius: 3px;
    text-align: center;
}

/* Heatmap */
.heatmap-container {
    overflow-x: auto;
}

.heatmap-row {
    display: flex;
    gap: 2px;
    margin-bottom: 2px;
}

.heatmap-row.header-row {
    margin-bottom: 4px;
}

.heatmap-label {
    width: 40px;
    flex-shrink: 0;
    font-size: 0.7rem;
    color: var(--text-muted);
    display: flex;
    align-items: center;
}

.heatmap-hour-label {
    flex: 1;
    min-width: 30px;
    font-size: 0.6rem;
    color: var(--text-muted);
    text-align: center;
}

.heatmap-cell {
    flex: 1;
    min-width: 30px;
    height: 24px;
    border-radius: 3px;
    cursor: default;
}

.heatmap-cell.heat-none { background: var(--bg-tertiary); }

.heatmap-legend {
    display: flex;
    gap: 1rem;
    justify-content: center;
    margin-top: 1rem;
    flex-wrap: wrap;
}

.heatmap-legend .legend-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.heat-color {
    width: 16px;
    height: 16px;
    border-radius: 3px;
}

.heat-color.heat-low { background: #22c55e; }
.heat-color.heat-medium { background: #eab308; }
.heat-color.heat-high { background: #f97316; }
.heat-color.heat-critical { background: #ef4444; }

/* Detected Patterns */
.patterns-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.pattern-card {
    display: flex;
    gap: 0.75rem;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
    border-left: 3px solid var(--border-color);
}

.pattern-card.warning { border-left-color: var(--warning-color); }
.pattern-card.info { border-left-color: var(--info-color); }

.pattern-icon {
    width: 28px;
    height: 28px;
    background: var(--bg-secondary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
    flex-shrink: 0;
    color: var(--text-muted);
}

.pattern-card.warning .pattern-icon {
    background: var(--warning-color);
    color: white;
}

.pattern-card.info .pattern-icon {
    background: var(--info-color);
    color: white;
}

.pattern-content {
    flex: 1;
}

.pattern-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.pattern-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin-bottom: 0.25rem;
}

.pattern-timing {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Band Environment Grid */
.band-env-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
}

.band-env-card {
    background: var(--bg-tertiary);
    border-radius: 6px;
    padding: 1rem;
    border-top: 3px solid var(--border-color);
}

.band-env-card.band-2ghz { border-top-color: #fbbf24; }
.band-env-card.band-5ghz { border-top-color: #3b82f6; }
.band-env-card.band-6ghz { border-top-color: #a855f7; }

.band-env-header {
    margin-bottom: 0.75rem;
}

.band-env-header .band-name {
    font-weight: 600;
    color: var(--text-primary);
}

.band-env-metrics {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.band-env-metric .metric-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 0.25rem;
}

.band-env-metric .metric-label {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.band-env-metric .metric-value {
    font-size: 0.8rem;
    font-weight: 500;
}

.band-env-metric .metric-bar {
    height: 6px;
    background: var(--bg-secondary);
    border-radius: 0 3px 3px 0;
    overflow: hidden;
}

.band-env-metric .metric-fill {
    height: 100%;
    border-radius: 0 3px 3px 0;
    background: var(--text-muted);
    transition: width 0.3s ease;
}

.band-env-metric .metric-fill.interference-low { background: #22c55e; }
.band-env-metric .metric-fill.interference-medium { background: #eab308; }
.band-env-metric .metric-fill.interference-high { background: #ef4444; }
.band-env-metric .metric-fill.util-low { background: #22c55e; }
.band-env-metric .metric-fill.util-medium { background: #eab308; }
.band-env-metric .metric-fill.util-high { background: #ef4444; }

.band-peak-time {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Interference/Util/Retry classes */
.interference-low, .metric-value.interference-low { color: var(--success-color); }
.interference-medium, .metric-value.interference-medium { color: var(--warning-color); }
.interference-high, .metric-value.interference-high { color: var(--danger-color); }

.util-low, .metric-value.util-low { color: var(--success-color); }
.util-medium, .metric-value.util-medium { color: var(--warning-color); }
.util-high, .metric-value.util-high { color: var(--danger-color); }

.retry-low, .metric-value.retry-low { color: var(--success-color); }
.retry-medium, .metric-value.retry-medium { color: var(--warning-color); }
.retry-high, .metric-value.retry-high { color: var(--danger-color); }

/* Environmental Recommendations */
.env-section .rec-action {
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.8rem;
    color: var(--text-muted);
    border-left: 2px solid var(--info-color);
}

/* Responsive Environmental */
@media (max-width: 900px) {
    .time-of-day-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .band-env-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    .env-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .env-controls {
        width: 100%;
    }

    .time-range-select {
        flex: 1;
    }

    .time-of-day-grid {
        grid-template-columns: 1fr;
    }

    .heatmap-container {
        overflow-x: auto;
        padding-bottom: 0.5rem;
    }

    .heatmap-cell {
        min-width: 24px;
    }

    .heatmap-legend {
        gap: 0.5rem;
    }
}

/* ============================================
   Connectivity Flow Component
   ============================================ */


.flow-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
    gap: 1rem;
}

.flow-header h3 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
}

.flow-loading,
.flow-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    color: var(--text-secondary);
    gap: 1rem;
}

/* Flow Sections */
.flow-section {
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin-bottom: 1.5rem;
}

.flow-section .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.flow-section .section-header h4 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.flow-section .section-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Flow Diagram - Connection Stages */
.flow-diagram {
    display: flex;
    align-items: stretch;
    gap: 0;
    padding: 1rem 0;
}

.flow-stage {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    min-width: 140px;
}

.stage-header {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.stage-icon {
    width: 32px;
    height: 32px;
    background: var(--bg-secondary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--text-muted);
    flex-shrink: 0;
}

.stage-icon.success-icon {
    background: var(--success-color);
    color: white;
}

.stage-info {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.stage-name {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.875rem;
}

.stage-desc {
    font-size: 0.7rem;
    color: var(--text-muted);
}

.stage-metrics {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.stage-count {
    font-size: 1.5rem;
    font-weight: 600;
}

.stage-count.success { color: var(--success-color); }
.stage-count.warning { color: var(--warning-color); }
.stage-count.danger { color: var(--danger-color); }

.stage-label {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.stage-bar {
    height: 6px;
    background: var(--bg-secondary);
    border-radius: 0 3px 3px 0;
    overflow: hidden;
    margin-top: auto;
}

.bar-fill {
    height: 100%;
    border-radius: 0 3px 3px 0;
    transition: width 0.3s ease;
}

.bar-fill.success { background: var(--success-color); }
.bar-fill.warning { background: var(--warning-color); }
.bar-fill.danger { background: var(--danger-color); }

/* Flow Connector - scoped to connectivity-flow to avoid conflict with speed test trace */
.connectivity-flow-container .flow-connector {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 60px;
    flex-shrink: 0;
    position: relative;
}

.connectivity-flow-container .connector-line {
    width: 100%;
    height: 2px;
    background: var(--border-color);
    position: relative;
}

.connectivity-flow-container .connector-line::after {
    content: "";
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    border-left: 6px solid var(--border-color);
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
}

.connectivity-flow-container .connector-drop {
    position: absolute;
    top: calc(50% + 10px);
    background: rgba(239, 68, 68, 0.15);
    color: var(--danger-color);
    padding: 0.25rem 0.5rem;
    border-radius: var(--border-radius);
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Flow Success Rate */
.flow-success-rate {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 1rem;
    margin-top: 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
}

.success-rate-label {
    font-weight: 500;
    color: var(--text-secondary);
}

.success-rate-value {
    font-size: 1.5rem;
    font-weight: 600;
}

.success-rate-value.rate-excellent { color: var(--success-color); }
.success-rate-value.rate-good { color: #22c55e; }
.success-rate-value.rate-fair { color: var(--warning-color); }
.success-rate-value.rate-poor { color: var(--danger-color); }

/* Connection Issues - WiFi specific additions */
.connection-issue-count {
    font-weight: 600;
    font-size: 1.125rem;
    padding: 0.25rem 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
}

.issue-item.issue-warning .connection-issue-count { color: var(--warning-color); }
.issue-item.issue-info .connection-issue-count { color: var(--info-color); }
.issue-item.issue-critical .connection-issue-count { color: var(--danger-color); }

.affected-clients {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.affected-client {
    padding: 0.25rem 0.5rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius);
    font-size: 0.75rem;
    color: var(--text-secondary);
}

a.affected-client {
    color: var(--primary-light);
    text-decoration: none;
}

a.affected-client:hover {
    color: var(--primary-lighter);
    text-decoration: underline;
}

.affected-more {
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem;
    color: var(--text-muted);
    font-style: italic;
}

/* Client Status Summary */
.status-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
}

.status-card {
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    padding: 1.25rem;
    text-align: center;
    position: relative;
    border-top: 3px solid var(--border-color);
}

.status-card.status-connected { border-top-color: var(--success-color); }
.status-card.status-authorized { border-top-color: var(--info-color); }
.status-card.status-guest { border-top-color: #a855f7; }
.status-card.status-issue { border-top-color: var(--warning-color); }

.status-value {
    font-size: 2rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.status-card.status-connected .status-value { color: var(--success-color); }
.status-card.status-issue .status-value { color: var(--warning-color); }

.status-label {
    font-size: 0.8rem;
    color: var(--text-muted);
}

.status-card .status-icon {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    font-size: 0.875rem;
    color: var(--text-muted);
}

/* Per-AP Connection Stats */
.ap-success-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ap-success-row {
    display: grid;
    grid-template-columns: 200px 1fr 60px;
    gap: 1rem;
    align-items: center;
    padding: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
}

.ap-info {
    display: flex;
    flex-direction: column;
}

.ap-info .ap-name {
    font-weight: 500;
    color: var(--text-primary);
    font-size: 0.875rem;
}

.ap-info .ap-clients {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.ap-success-bar-container {
    height: 8px;
    background: var(--bg-secondary);
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    overflow: hidden;
}

.ap-success-bar {
    height: 100%;
    border-radius: 0 var(--border-radius) var(--border-radius) 0;
    transition: width 0.3s ease;
}

.ap-success-bar.rate-excellent { background: var(--success-color); }
.ap-success-bar.rate-good { background: #22c55e; }
.ap-success-bar.rate-fair { background: var(--warning-color); }
.ap-success-bar.rate-poor { background: var(--danger-color); }

.ap-success-value {
    font-weight: 600;
    text-align: right;
}

.ap-success-value.rate-excellent { color: var(--success-color); }
.ap-success-value.rate-good { color: #22c55e; }
.ap-success-value.rate-fair { color: var(--warning-color); }
.ap-success-value.rate-poor { color: var(--danger-color); }

/* Responsive Connectivity Flow */
@media (max-width: 1024px) {
    .flow-diagram {
        flex-direction: column;
        gap: 0;
    }

    .flow-stage {
        width: 100%;
        flex-direction: row;
        align-items: center;
        padding: 0.75rem 1rem;
        border-radius: 0;
    }

    .flow-stage:first-child {
        border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
    }

    .flow-stage:last-child {
        border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
    }

    .stage-header {
        margin-bottom: 0;
        flex: 1;
    }

    .stage-metrics {
        flex-direction: column;
        align-items: flex-end;
        margin-bottom: 0;
        gap: 0;
    }

    .stage-bar {
        display: none;
    }

    .connectivity-flow-container .flow-connector {
        width: 100%;
        height: 30px;
        flex-direction: row;
    }

    .connectivity-flow-container .connector-line {
        width: 2px;
        height: 100%;
    }

    .connectivity-flow-container .connector-line::after {
        right: 50%;
        top: auto;
        bottom: 0;
        transform: translateX(50%);
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-top: 6px solid var(--border-color);
    }

    .connectivity-flow-container .connector-drop {
        top: auto;
        left: calc(50% + 20px);
    }

    .status-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .flow-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .flow-success-rate {
        flex-direction: column;
        gap: 0.5rem;
    }

    .ap-success-row {
        grid-template-columns: 1fr;
        gap: 0.5rem;
    }

    .ap-info {
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
    }

    .ap-success-value {
        text-align: left;
    }

    .status-grid {
        grid-template-columns: 1fr 1fr;
    }

    .status-card {
        padding: 1rem;
    }

    .status-value {
        font-size: 1.5rem;
    }
}

/* ============================================
   WAN Speed Test
   ============================================ */

.wan-speedtest .wan-mode-toggle {
    padding-top: 0.75rem;
}

.wan-speedtest .toggle-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-right: 0.25rem;
    cursor: pointer;
    user-select: none;
}

.wan-speedtest .toggle-switch input {
    display: none;
}

.wan-speedtest .toggle-slider {
    position: relative;
    width: 36px;
    height: 20px;
    background: var(--bg-secondary);
    border-radius: 10px;
    border: 1px solid var(--border-color);
    transition: background 0.15s ease-out;
}

.wan-speedtest .toggle-slider::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: var(--text-secondary);
    border-radius: 50%;
    transition: transform 0.2s, background 0.2s;
}

.wan-speedtest .toggle-switch input:checked + .toggle-slider {
    background: var(--primary-color);
    border-color: var(--primary-color);
}

.wan-speedtest .toggle-switch input:checked + .toggle-slider::after {
    transform: translateX(16px);
    background: white;
}

.identity-actions-note {
    color: var(--text-muted);
    font-size: 0.85rem;
}

.mi-form-fields,
.ws-edit-fields,
.threshold-fieldset {
    border: none;
    padding: 0;
    margin: 0;
    min-width: 0;
}

.toggle-switch input:disabled + .toggle-slider {
    opacity: 0.5;
    cursor: not-allowed;
}

.toggle-switch:has(input:disabled) {
    cursor: not-allowed;
}

.wan-speedtest .toggle-label {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.wan-speedtest .wan-test-options {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding-top: 0.5rem;
}

.wan-speedtest .wan-test-option {
    flex: 1;
    padding: 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
}

.wan-speedtest .wan-test-option-unavailable > *:not(.alert) {
    opacity: 0.6;
}

.wan-speedtest .wan-test-option-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.wan-speedtest .wan-test-option-label {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-primary);
}

.wan-speedtest .wan-test-option-badge {
    font-size: 0.7rem;
    padding: 0.15rem 0.5rem;
    border-radius: var(--border-radius-lg);
    background: var(--bg-secondary);
    color: var(--text-muted);
    border: 1px solid var(--border-color);
}

.wan-speedtest .wan-test-option-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    margin-bottom: 0.75rem;
}

.wan-speedtest .wan-select-row {
    flex: 0 0 100%;
}

.wan-speedtest .wan-reassign-select {
    max-width: 200px;
}

.wan-speedtest .wan-test-option-hint {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 1.4;
}

.wan-speedtest .wan-test-button {
    min-width: 168px;
}

.wan-speedtest .wan-result-summary {
    background: var(--bg-primary);
    padding: 0.125rem 0.375rem;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.wan-speedtest .wan-metadata {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-top: 1rem;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
    border: 1px solid var(--border-color);
}

.wan-speedtest .metadata-item {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.wan-speedtest .metadata-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.wan-speedtest .metadata-value {
    font-size: 0.9rem;
    color: var(--text-primary);
    font-weight: 500;
}

.wan-speedtest .test-details {
    gap: 1rem 1.4rem;
}

@media (max-width: 768px) {
    .wan-speedtest .wan-test-options {
        flex-direction: column;
    }

    .wan-speedtest .wan-test-option-controls {
        flex-direction: column;
    }

    .wan-speedtest .wan-reassign-select {
        max-width: 100%;
        width: 100%;
    }

    .wan-speedtest .wan-metadata {
        gap: 0.75rem;
    }

    .wan-speedtest .wan-test-button {
        width: 100%;
    }
}

/* WAN History Tabs */
.wan-history-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border-color);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.wan-history-tabs::-webkit-scrollbar {
    display: none;
}

.wan-history-tab {
    padding: 0.5rem 1rem;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: all 0.15s ease-out;
    white-space: nowrap;
    font-size: 0.9rem;
    margin-bottom: -1px;
}

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

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


/* Loaded Latency Legend */
.loaded-latency-chart-wrapper {
    position: relative;
}

.loaded-latency-legend {
    position: absolute;
    top: 0.25rem;
    right: 0.5rem;
    display: flex;
    gap: 1rem;
    z-index: 1;
}

.loaded-latency-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.loaded-latency-legend-item svg {
    flex-shrink: 0;
}

.wan-chart-container {
    margin-bottom: 0;
    min-height: 250px;
    margin-left: -0.75rem;
}

/* Never the tooltip: ApexCharts leaves it pointer-events none because a box that catches the
   pointer steals it from the chart the instant it opens under the cursor, and the chart then hides
   it on mouseout. Clicks reach the chart's own mouseup at the hovered point without it. */
.wan-chart-container .apexcharts-marker {
    cursor: pointer;
    pointer-events: auto;
}

.wan-time-slider {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 0 0 1rem;
}

.wan-time-slider input[type="range"] {
    width: 280px;
    height: 4px;
    -webkit-appearance: none;
    appearance: none;
    background: linear-gradient(to right, #3b82f6, #60a5fa);
    border-radius: 2px;
    cursor: pointer;
}

.wan-time-slider input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.wan-time-slider input[type="range"]::-moz-range-thumb {
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    cursor: pointer;
    border: none;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.wan-time-slider .time-label {
    font-size: 0.8rem;
    color: var(--text-muted);
    white-space: nowrap;
    min-width: 60px;
}

/* WAN Filter Badges */
.wan-filter-badges {
    /* Anchors the reset control at the right without moving the centred chips. */
    position: relative;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
    padding-bottom: 0.5rem;
}

.wan-filter-badges-reserved {
    padding-left: 2rem;
    padding-right: 2rem;
}

.wan-filter-controls {
    position: absolute;
    right: 0;
    top: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
}

.wan-filter-reset,
.wan-filter-inactive {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.35rem;
    border: none;
    background: transparent;
    color: var(--text-muted);
    line-height: 1;
    cursor: pointer;
}

.wan-filter-reset:hover,
.wan-filter-inactive:hover {
    color: var(--text-primary);
}

.wan-filter-inactive.active {
    color: var(--primary-color);
}

.monitoring-jump-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.35rem;
    border: none;
    background: transparent;
    color: var(--text-muted);
    line-height: 1;
    cursor: pointer;
}

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

/* Takes the button's own right padding back, so the glyph sits where the card's edge is rather
   than a third of a rem inside it. */
.isp-health-chart-card .card-header-right .monitoring-jump-btn {
    margin-right: -0.2rem;
}

#latency-charts-container .monitoring-chart-header {
    position: relative;
}

#latency-charts-container .monitoring-chart-header > .monitoring-jump-btn {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    margin: 0;
}

@media (max-width: 768px) {
    #latency-charts-container .monitoring-chart-header > .monitoring-jump-btn {
        top: -0.2rem;
        right: -0.2rem;
    }
}

.live-view-jump-row {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.live-view-jump-row .monitoring-jump-btn {
    margin-left: auto;
    margin-top: auto;
}

@media (max-width: 768px) {
    .live-view-jump-row .monitoring-jump-btn {
        margin-top: auto;
        margin-bottom: auto;
    }
}


.wan-filter-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 1rem;
    border-radius: var(--border-radius-lg);
    border: 1px solid var(--border-color);
    background: transparent;
    color: var(--text-primary);
    font-size: 0.9rem;
    cursor: pointer;
    transition: opacity 0.15s, border-color 0.15s;
}

.wan-filter-badge:hover {
    border-color: #fff;
}

.wan-filter-badge.wan-badge-unprobed {
    border-style: dashed;
    color: var(--text-secondary);
}

#latency-charts-container .wan-filter-badge,
#device-health-charts-container .wan-filter-badge,
#sfp-charts-container .wan-filter-badge,
#cellular-charts-container .wan-filter-badge,
#cm-charts-container .wan-filter-badge,
#ont-charts-container .wan-filter-badge,
#port-stats-card .wan-filter-badge {
    font-size: 0.8rem;
    padding: 0.4rem 0.875rem;
}

.isp-chart-wrap .wan-filter-reset svg,
.isp-chart-wrap .wan-filter-inactive svg {
    width: 16px;
    height: 16px;
}

.isp-chart-badges {
    gap: 0.375rem;
    margin-top: 0.5rem;
    margin-bottom: 0;
    padding-bottom: 0;
}

.isp-chart-wrap .wan-filter-badge {
    font-size: 0.7rem;
    padding: 0.3rem 0.65rem;
    gap: 0.375rem;
}

.isp-chart-wrap .wan-badge-dot {
    width: 7px;
    height: 7px;
}

.wan-history-table {
    padding-top: 0.5rem;
}

@media (max-width: 768px) {
    .wan-history-table {
        padding-top: 0.25rem;
    }
}

.wan-filter-badge.active {
    color: var(--text-primary);
    border-color: rgba(255, 255, 255, 0.5);
}

.wan-filter-badge.active:hover {
    border-color: #fff;
}

.wan-filter-badge.inactive {
    color: var(--text-muted, #666);
}

.stat-filter-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.6rem;
    border-radius: var(--border-radius-lg);
    border: 1px solid transparent;
    transition: border-color 0.15s;
    white-space: nowrap;
}

td[data-stat-id] {
    cursor: pointer;
}

td[data-stat-id]:hover .stat-filter-badge {
    border-color: rgba(255, 255, 255, 0.5);
}

th[data-sort-col] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

th[data-sort-col]:hover {
    color: var(--text-primary);
}

tr.stats-row-filtered {
    opacity: 0.35;
}

[class$="-stats-table"] .table-responsive {
    scrollbar-color: var(--bg-tertiary) transparent;
}

[class$="-stats-table"] .table-responsive::-webkit-scrollbar {
    height: 10px;
}

[class$="-stats-table"] .table-responsive::-webkit-scrollbar-track {
    background: transparent;
}

[class$="-stats-table"] .table-responsive::-webkit-scrollbar-thumb {
    background: var(--bg-tertiary);
    border-radius: 3px;
}

[class$="-stats-table"] .table-responsive::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
}

.wan-badge-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.wan-badge-dot-inline {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 0.3rem;
    vertical-align: middle;
}

@media (max-width: 768px) {
    .wan-chart-container {
        margin-left: -1.25rem;
    }

    .wan-time-slider input[type="range"] {
        width: 200px;
        height: 8px;
    }

    .wan-time-slider input[type="range"]::-webkit-slider-thumb {
        width: 20px;
        height: 20px;
    }

    .wan-time-slider input[type="range"]::-moz-range-thumb {
        width: 20px;
        height: 20px;
    }
}

/* ── Stepped distance scale bar (shared by all Leaflet maps) ─────── */

.stepped-scale-bar {
    background: rgba(15, 23, 42, 0.85);
    border: 1px solid rgba(100, 116, 139, 0.4);
    border-radius: var(--border-radius);
    padding: 4px 8px 3px;
    pointer-events: none;
}

.stepped-scale-segments {
    display: flex;
    height: 6px;
}

.stepped-scale-seg {
    height: 100%;
    border: 1px solid var(--text-secondary);
    border-right: none;
    box-sizing: border-box;
}

.stepped-scale-seg:last-child {
    border-right: 1px solid var(--text-secondary);
}

.stepped-scale-seg-filled {
    background: var(--text-secondary);
}

.stepped-scale-seg-empty {
    background: transparent;
}

.stepped-scale-labels {
    display: flex;
    justify-content: space-between;
    font-size: 9px;
    color: var(--text-secondary);
    margin-top: 1px;
    font-weight: 500;
}

/* Event Type Key Modal (Alerts > Rules tab) */
.event-type-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.event-type-modal {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 1.5rem;
    max-width: 960px;
    width: 100%;
    max-height: 85vh;
    overflow-y: auto;
}

.event-type-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
}

.event-type-modal-header h3 {
    margin: 0;
    font-size: 1.1rem;
    color: var(--text-primary);
}

.event-type-modal-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
}

@media (max-width: 768px) {
    .event-type-key-list > div {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.125rem;
    }
}

@media (max-width: 600px) {
    .event-type-modal {
        padding: 1rem;
    }
    .event-type-modal-grid {
        grid-template-columns: 1fr;
    }
    .event-type-key-list > div {
        flex-direction: row;
        align-items: baseline;
        gap: 0.5rem;
    }
}

@media (max-width: 420px) {
    .event-type-key-list > div {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.125rem;
    }
}

.event-type-group-header {
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
    letter-spacing: 0.05em;
}

.event-type-key-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.event-type-key-list > div {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.8125rem;
    line-height: 1.4;
    cursor: pointer;
    padding: 0.25rem 0.375rem;
    border-radius: 4px;
    margin: 0 -0.375rem;
}

.event-type-key-list > div:hover {
    background: var(--bg-tertiary);
}

.event-type-key-list code {
    flex-shrink: 0;
    font-size: 0.75rem;
    padding: 0.125rem 0.375rem;
    background: var(--bg-tertiary);
    border-radius: 3px;
    color: var(--info-color);
}

.event-type-key-list span {
    color: var(--text-secondary);
}

/* ==================== Monitoring ==================== */

.form-value {
    font-size: 0.875rem;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.form-value-line {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
}

/* 3D LAN Flow Map (spec 5.7) */
.lan-flow-map-body {
    padding: 0;
}
.lan-flow-map-stage {
    position: relative;
    width: 100%;
    height: clamp(520px, 70vh, 820px);
    background: var(--bg-primary);
    border-radius: 0 0 8px 8px;
    overflow: hidden;
}
.lan-flow-map-canvas {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--bg-primary);
    outline: none;
}
.lan-flow-map-panel {
    position: absolute;
    z-index: 5;
    background: rgba(16, 24, 32, 0.78);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    color: var(--text-primary);
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
    line-height: 1.3;
    pointer-events: auto;
}
.lan-flow-map-panel-body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.lan-flow-map-filter .lan-flow-map-panel-body {
    gap: 0.25rem;
} 
.lan-flow-map-panel-title {
    font-size: 0.825rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 0.45rem;
}
.lan-flow-map-controls {
    top: 3rem;
    right: 0.75rem;
    min-width: 178px;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.lan-flow-map-filter {
    top: 0.75rem;
    left: 0.75rem;
    min-width: 220px;
}
.lan-flow-map-legend {
    bottom: 0.75rem;
    right: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.5rem 0.7rem;
    font-size: 0.78rem;
}
.lan-flow-map-help {
    top: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.78rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.lan-flow-map-help .lan-flow-map-panel-body:not(.is-collapsed) {
    max-height: 320px;
    min-width: 180px;
}
.lan-flow-map-help .lan-flow-map-panel-body {
    gap: 0.3rem;
}
.lan-flow-map-help-row {
    display: flex;
    justify-content: space-between;
    gap: 0.6rem;
    white-space: nowrap;
}
.lan-flow-map-help-row .kbd {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    font-family: var(--font-mono, monospace);
    font-size: 0.825rem;
}
.lan-flow-map-status {
    bottom: 0.75rem;
    left: 0.75rem;
    font-size: 0.78rem;
    color: var(--text-muted);
}
.lan-flow-map-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.32rem 0.5rem;
    border-radius: 6px;
    cursor: pointer;
    user-select: none;
    color: var(--text-secondary);
    transition: background 0.15s ease;
}
.lan-flow-map-toggle:hover {
    background: rgba(255, 255, 255, 0.04);
}
.lan-flow-map-toggle.is-on {
    color: var(--text-primary);
    background: rgba(51, 133, 214, 0.12);
}
.lan-flow-map-toggle-pill {
    width: 28px;
    height: 16px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    position: relative;
    flex-shrink: 0;
    transition: background 0.15s ease;
}
.lan-flow-map-toggle-pill::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #f1f5f9;
    transition: transform 0.15s ease;
}
.lan-flow-map-toggle.is-on .lan-flow-map-toggle-pill {
    background: var(--speed-download-color, #3385d6);
}
.lan-flow-map-toggle.is-on .lan-flow-map-toggle-pill::after {
    transform: translateX(12px);
}
.lan-flow-map-search {
    width: 100%;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--text-primary);
    border-radius: 6px;
    padding: 0.32rem 0.5rem;
    font-size: 0.82rem;
}
.lan-flow-map-search::placeholder {
    color: var(--text-muted);
}
.lan-flow-map-search:focus {
    outline: none;
    border-color: var(--primary-color);
}

.map-addr-search {
    position: relative;
}
.map-addr-search-bar {
    display: flex;
    align-items: center;
    background: rgba(16, 24, 32, 0.82);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.map-addr-search.is-error .map-addr-search-bar {
    border-color: var(--danger-color);
}
.map-addr-search-input {
    width: 220px;
    max-width: 56vw;
    border: none;
    background: transparent;
    color: var(--text-primary);
    font-size: 0.85rem;
    padding: 0.42rem 0.6rem;
    outline: none;
    transition: width 0.2s ease, padding 0.2s ease, opacity 0.15s ease;
}
.map-addr-search-input::placeholder {
    color: var(--text-muted);
}
.map-addr-search.is-collapsed .map-addr-search-input {
    width: 0;
    padding-left: 0;
    padding-right: 0;
    opacity: 0;
}
.map-addr-search.is-error .map-addr-search-input {
    color: var(--danger-color);
}
.map-addr-search-toggle {
    position: relative;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--text-secondary);
    transition: color 0.15s ease, background 0.15s ease;
}
.map-addr-search-toggle:hover {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.06);
}
.map-addr-search-clear {
    flex-shrink: 0;
    display: none;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 34px;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    transition: color 0.15s ease;
}
.map-addr-search.is-dirty:not(.is-collapsed) .map-addr-search-clear {
    display: flex;
}
.map-addr-search-clear:hover {
    color: var(--text-primary);
}
.map-addr-search.is-loading .map-addr-search-toggle svg {
    opacity: 0;
}
.map-addr-search.is-loading .map-addr-search-toggle::after {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.25);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: map-addr-search-spin 0.7s linear infinite;
}
@keyframes map-addr-search-spin {
    to {
        transform: rotate(360deg);
    }
}
.map-addr-search-pin {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--primary-color);
    border: 3px solid #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.45);
}
.map-addr-search-popup {
    font-size: 0.82rem;
    line-height: 1.35;
    max-width: 220px;
}
.map-addr-search-results {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: 280px;
    max-width: 78vw;
    background: rgba(16, 24, 32, 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    overflow: hidden;
    max-height: 280px;
    overflow-y: auto;
    display: none;
}
.map-addr-search.is-open .map-addr-search-results {
    display: block;
}
.map-addr-search-result {
    padding: 0.5rem 0.6rem;
    font-size: 0.8rem;
    line-height: 1.3;
    color: var(--text-secondary);
    cursor: pointer;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.map-addr-search-result:last-child {
    border-bottom: none;
}
.map-addr-search-result:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary);
}
.map-addr-search-empty {
    padding: 0.5rem 0.6rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}
@media (max-width: 768px) {
    .map-addr-search-input {
        width: 180px;
        max-width: 60vw;
    }
    .map-addr-search-results {
        width: 240px;
    }
}

/* Satellite tile toggle button (bottom-left, above scale bar) */
.map-sat-ctrl {
    position: relative;
    /* Leaflet stacks bottom-left controls tight together; add a gap above the scale bar */
    margin-bottom: 8px !important;
    border: none;
    background: transparent;
    box-shadow: none;
}
.map-sat-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: rgba(16, 24, 32, 0.82);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 4px;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.map-sat-btn:hover {
    background: rgba(30, 40, 55, 0.92);
    color: var(--text-primary);
    border-color: rgba(255, 255, 255, 0.2);
}
.map-sat-btn.is-active {
    background: rgba(5, 89, 201, 0.35);
    border-color: var(--primary-color);
    color: #fff;
}
/* One-time non-commercial confirm dialog for the free Esri satellite layer */
.map-sat-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
    padding: 1rem;
}
.map-sat-confirm {
    background: var(--bg-card);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
    max-width: 420px;
    width: 100%;
    padding: 1.25rem 1.4rem;
}
.map-sat-confirm h3 {
    margin: 0 0 0.6rem;
    font-size: 1.05rem;
    color: var(--text-primary);
}
.map-sat-confirm p {
    margin: 0 0 1.1rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--text-secondary);
}
.map-sat-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* Leaflet zoom buttons on the Signal / floor plan and Speed Test maps —
   styled to match the 2D topology map */
.fp-map-container .leaflet-control-zoom a,
.map-container .leaflet-control-zoom a {
    width: 32px;
    height: 32px;
    line-height: 32px;
    font-size: 16px;
    background: rgba(26, 29, 35, 0.9);
    color: var(--text-secondary);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px !important;
}
.fp-map-container .leaflet-control-zoom a:hover,
.map-container .leaflet-control-zoom a:hover {
    background: rgba(51, 56, 68, 0.9);
    color: var(--text-primary);
}
/* Disabled state at min/max zoom — muted, no hover lift */
.fp-map-container .leaflet-control-zoom a.leaflet-disabled,
.map-container .leaflet-control-zoom a.leaflet-disabled,
.fp-map-container .leaflet-control-zoom a.leaflet-disabled:hover,
.map-container .leaflet-control-zoom a.leaflet-disabled:hover {
    background: rgba(26, 29, 35, 0.6);
    color: var(--text-muted);
    cursor: default;
}
/* Leaflet's .leaflet-touch .leaflet-bar adds a 2px outer border; its CSS is injected
   after app.css, so we need the extra .leaflet-touch class to win specificity. */
.fp-map-container .leaflet-touch .leaflet-bar,
.map-container .leaflet-touch .leaflet-bar,
.fp-map-container .leaflet-bar,
.map-container .leaflet-bar {
    border: none;
    box-shadow: none;
}
/* Gap between the stacked + and - buttons, matching the 2D map's 4px */
.fp-map-container .leaflet-control-zoom-in,
.map-container .leaflet-control-zoom-in {
    margin-bottom: 4px;
}

.lan-flow-map-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.45rem;
    margin-bottom: 0.15rem;
}
.lan-flow-map-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid transparent;
    color: var(--text-secondary);
    font-size: 0.74rem;
    cursor: pointer;
    user-select: none;
}
.lan-flow-map-chip.is-on {
    color: var(--text-primary);
    border-color: rgba(51, 133, 214, 0.45);
    background: rgba(51, 133, 214, 0.15);
}
/* WiFi band pills use the canonical band palette (matches WiFi Optimizer). */
.lan-flow-map-chip[data-band="2.4"].is-on {
    border-color: var(--band-24-color);
    background: color-mix(in srgb, var(--band-24-color) 18%, transparent);
}
.lan-flow-map-chip[data-band="5"].is-on {
    border-color: var(--band-5-color);
    background: color-mix(in srgb, var(--band-5-color) 18%, transparent);
}
.lan-flow-map-chip[data-band="6"].is-on {
    border-color: var(--band-6-color);
    background: color-mix(in srgb, var(--band-6-color) 18%, transparent);
}
.lan-flow-map-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
}
.lan-flow-map-legend-dot.down {
    background: var(--speed-download-color, #3385d6);
}
.lan-flow-map-legend-dot.up {
    background: var(--speed-upload-color, #24bc70);
}
.lan-flow-map-scrubber {
    position: absolute;
    z-index: 5;
    left: 50%;
    bottom: 0.75rem;
    transform: translateX(-50%);
    width: min(640px, calc(100% - 22rem));
    background: rgba(16, 24, 32, 0.78);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    padding: 0.55rem 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.lan-flow-map-scrubber-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.78rem;
    color: var(--text-secondary);
}
.lan-flow-map-scrubber-track {
    flex: 1;
    position: relative;
    display: flex;
    align-items: center;
}
.lan-flow-map-scrubber-range {
    flex: 1;
    accent-color: var(--speed-download-color, #3385d6);
}
.lan-flow-map-scrubber-ticks {
    position: absolute;
    left: 8px;
    right: 8px;
    top: 0;
    bottom: 0;
    pointer-events: none;
}
.lan-flow-map-scrubber-tick {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 1px;
    height: 0.6rem;
    background: rgba(255, 255, 255, 0.22);
}
.lan-flow-map-scrubber-window {
    background: transparent;
    border: 1px solid var(--border-color, #334155);
    color: var(--text-secondary);
    height: 1.75rem;
    border-radius: 0.25rem;
    font-size: 0.825rem;
    padding: 0 0.2rem;
    cursor: pointer;
    flex-shrink: 0;
}
.lan-flow-map-scrubber-window:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.lan-flow-map-scrubber-window option {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}
.lan-flow-map-scrubber-window option:disabled {
    color: var(--text-muted);
}
/* Right label swaps between "Live" and a long locale datetime as the user
   scrubs; without a min-width the flex row reflows and the slider thumb
   jumps right under the cursor as it approaches the live edge. */
.lan-flow-map-scrubber-row [data-role="right"] {
    display: inline-block;
    min-width: min(7.5rem, 30vw);
    text-align: center;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.lan-flow-map-scrubber-row [data-role="left"] {
    white-space: nowrap;
}
.lan-flow-map-scrubber-playpause {
    background: transparent;
    border: 1px solid var(--border-color, #334155);
    color: var(--text-secondary);
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 0.25rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    padding: 0;
    padding-bottom: 3px;
    flex-shrink: 0;
}
.lan-flow-map-scrubber-playpause:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.lan-flow-map-speed-control {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    flex-shrink: 0;
}
.lan-flow-map-speed-step {
    background: transparent;
    border: 1px solid var(--border-color, #334155);
    color: var(--text-secondary);
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 0.2rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0;
    line-height: 1;
}
.lan-flow-map-speed-step:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.lan-flow-map-signal-hint {
    position: absolute;
    z-index: 6;
    left: 50%;
    top: 3.5rem;
    transform: translateX(-50%);
    max-width: min(520px, calc(100% - 2rem));
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem 0.75rem;
    padding: 0.5rem 0.55rem 0.5rem 0.9rem;
    background: rgba(16, 24, 32, 0.88);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    font-size: 0.78rem;
    color: var(--text-secondary);
    text-align: center;
}
.lan-flow-map-signal-hint-text {
    flex: 1 1 auto;
    min-width: 0;
    line-height: 1.3;
}
.lan-flow-map-signal-hint-link {
    flex-shrink: 0;
    color: var(--primary-hover);
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
}
.lan-flow-map-signal-hint-link:hover {
    color: var(--info-color);
    text-decoration: underline;
}
.lan-flow-map-signal-hint-close {
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0.3rem;
    color: var(--text-muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.lan-flow-map-signal-hint-close:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}
.lan-flow-map-speed-label {
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    min-width: 2.2rem;
    text-align: center;
    color: var(--text-secondary);
}
/* SFP/Optical table device + port cell. Inline so device name, port label,
   and PON badge sit on one row vertically centered, evenly spaced. */
.sfp-port-cell {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.sfp-port-cell .text-muted {
    font-size: 0.85rem;
}
.cadence-select {
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--bg-hover);
    border-radius: 4px;
    padding: 0.15rem 0.35rem;
    font-size: 0.85rem;
    cursor: pointer;
}
.cadence-select:focus {
    outline: 1px solid var(--primary-color);
    border-color: var(--primary-color);
}
.lan-flow-map-mode {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    font-size: 0.825rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(36, 188, 112, 0.15);
    color: var(--success-color);
}
.lan-flow-map-mode.is-historic {
    background: rgba(231, 150, 19, 0.15);
    color: var(--warning-color);
}
.lan-flow-map-fullscreen-btn {
    position: absolute;
    z-index: 6;
    top: 0.75rem;
    right: 0.75rem;
    background: rgba(16, 24, 32, 0.78);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    color: var(--text-secondary);
    cursor: pointer;
    pointer-events: auto;
}

.lan-flow-map-fullscreen-btn:hover {
    color: var(--text-primary);
    background: rgba(16, 24, 32, 0.92);
}
.lan-flow-map-fullscreen-btn,
.lan-flow-map-fit-btn {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}
.lan-flow-map-fit-btn {
    position: absolute;
    z-index: 6;
    top: 0.75rem;
    right: 3rem;
    background: rgba(16, 24, 32, 0.78);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    color: var(--text-secondary);
    cursor: pointer;
    pointer-events: auto;
}
.lan-flow-map-fit-btn:hover {
    color: var(--text-primary);
    background: rgba(16, 24, 32, 0.92);
}
@media (max-width: 768px) {
    .lan-flow-map-fit-btn {
        right: 0.75rem;
        top: 3rem;
    }
}

.lan-flow-map-labels {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 1;
}
.lan-flow-map-label {
    position: absolute;
    transform: translate(-50%, -100%);
    background: rgba(16, 24, 32, 0.78);
    color: var(--text-primary);
    padding: 0.2rem 0.55rem;
    border-radius: 6px;
    font-size: 0.74rem;
    line-height: 1.25;
    white-space: nowrap;
    border: 1px solid rgba(255, 255, 255, 0.05);
    display: none;
}
.lan-flow-map-label.is-visible {
    display: block;
}
.lan-flow-map-label-name {
    font-weight: 500;
}
.lan-flow-map-label-rates {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    margin-top: 1px;
    font-size: 0.7rem;
}
.lan-flow-map-label-rates .down {
    color: var(--speed-download-color);
}
.lan-flow-map-label-rates .up {
    color: var(--speed-upload-color);
}
.lan-flow-map-link-label {
    position: absolute;
    transform: translate(-50%, -50%);
    background: rgba(16, 24, 32, 0.82);
    color: var(--text-primary);
    padding: 0.12rem 0.45rem;
    border-radius: 4px;
    font-size: 0.7rem;
    line-height: 1.25;
    white-space: nowrap;
    border: 1px solid rgba(255, 255, 255, 0.06);
    font-variant-numeric: tabular-nums;
    display: none;
    pointer-events: none;
}
.lan-flow-map-link-label.is-visible {
    display: inline-flex;
    gap: 0.55rem;
    pointer-events: auto;
    cursor: help;
    user-select: none;
}
.lan-flow-map-link-label .down {
    color: var(--speed-download-color);
}
.lan-flow-map-link-label .up {
    color: var(--speed-upload-color);
}
.lan-flow-map-wan-pill {
    position: absolute;
    transform: translate(-50%, 100%);
    background: rgba(36, 188, 112, 0.12);
    color: var(--success-color);
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    border: 1px solid rgba(36, 188, 112, 0.3);
    margin-top: 4px;
    white-space: nowrap;
    display: none;
}
.lan-flow-map-wan-pill.is-visible {
    display: block;
}
.lan-flow-map-cloud-rtt {
    position: absolute;
    transform: translate(-50%, 0%);
    background: rgba(148, 163, 184, 0.1);
    color: var(--text-secondary);
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    border: 1px solid rgba(148, 163, 184, 0.2);
    white-space: nowrap;
    display: none;
}
.lan-flow-map-cloud-rtt.is-visible {
    display: block;
}
.lan-flow-map-tooltip {
    position: absolute;
    background: rgba(16, 24, 32, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
    padding: 0.5rem 0.65rem;
    font-size: 0.78rem;
    line-height: 1.35;
    color: var(--text-primary);
    pointer-events: none;
    z-index: 10;
    max-width: 300px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
}
.lan-flow-map-tooltip.is-visible {
    opacity: 1;
    visibility: visible;
}
.lan-flow-map-tooltip-title {
    font-weight: 500;
    margin-bottom: 0.2rem;
}
.lan-flow-map-tooltip-row {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* Labels stay on one line ("Link speed (MLO)"); values may still wrap. */
.lan-flow-map-tooltip-row span:first-child {
    white-space: nowrap;
}
.lan-flow-map-tooltip-row .v {
    color: var(--text-primary);
}
.lan-flow-map-panel-body {
    overflow: hidden;
    max-height: 150px;
    opacity: 1;
    transition: max-height 0.2s ease-out, opacity 0.2s ease, width 0.2s ease;
}
.lan-flow-map-panel-body.is-collapsed {
    max-height: 0;
    width: 0;
    opacity: 0;
    transition: max-height 0.15s ease-in, opacity 0.15s ease, width 0.15s ease;
}
.lan-flow-map-panel-title-toggle {
    cursor: pointer;
    user-select: none;
}
.lan-flow-map-panel:has(.is-collapsed) {
    gap: 0;
}
.lan-flow-map-panel-title-toggle:has(+ .is-collapsed) {
    margin-bottom: 0;
}
.lan-flow-map-panel-title-toggle::after {
    content: "▼";
    float: right;
    font-size: 0.65rem;
    opacity: 0.6;
    transition: transform 0.2s ease;
    margin-left: 0.5rem;
    margin-right: -0.3rem;
}
.lan-flow-map-panel-title-toggle:not(:has(+ .is-collapsed))::after {
    transform: rotate(180deg);
}
@media (max-width: 768px) {
    .lan-flow-map-stage {
        height: clamp(300px, 55vh, 480px);
    }
    .lan-flow-map-filter,
    .lan-flow-map-controls {
        min-width: 0;
        max-width: 46%;
        font-size: 0.78rem;
    }
    .lan-flow-map-filter {
        left: 0.5rem;
        top: 0.5rem;
    }
    .lan-flow-map-controls {
        right: 3.1rem;
        top: 0.5rem;
    }
    .lan-flow-map-legend {
        bottom: 0.5rem;
        right: 0.5rem;
        font-size: 0.7rem;
        padding: 0.35rem 0.5rem;
    }
    .lan-flow-map-status {
        bottom: 0.5rem;
        left: 0.5rem;
    }
    .lan-flow-map-help {
        display: none;
    }
    .lan-flow-map-scrubber {
        position: static;
        transform: none;
        width: 100%;
        border-radius: 0 0 8px 8px;
        border-top: 1px solid rgba(255, 255, 255, 0.06);
    }
    .lan-flow-map-speed-control {
        display: none;
    }
    .lan-flow-map-scrubber-row [data-role="left"] {
        display: none;
    }
    .lan-flow-map-signal-hint {
        top: 0.5rem;
        max-width: calc(100% - 1rem);
        font-size: 0.72rem;
        padding: 0.45rem 0.5rem 0.45rem 0.75rem;
    }
    .lan-flow-map-signal-hint-close {
        width: 1.85rem;
        height: 1.85rem;
        font-size: 1.2rem;
    }
}
/* 2D LAN Flow Map */
.lan-flow-map-2d-card {
    overflow: hidden;
}
.lan-flow-map-2d-body {
    padding: 0;
    background: #202023;
    position: relative;
}
.lan-flow-map-2d-stage {
    position: relative;
    width: 100%;
    height: clamp(520px, 70vh, 820px);
}

.lan-flow-map-fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    height: 100% !important;
    max-height: none !important;
    background: var(--bg-primary);
    border-radius: 0;
}

.lfm2d-canvas {
    display: block;
    width: 100%;
    height: 100%;
}
.lfm2d-tooltip {
    position: absolute;
    background: rgba(16, 24, 32, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
    padding: 0.5rem 0.65rem;
    font-size: 0.78rem;
    line-height: 1.35;
    color: var(--text-primary);
    pointer-events: none;
    z-index: 10;
    max-width: 300px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
}
.lan-flow-map-2d-stage .lan-flow-map-controls {
    right: 3.1rem;
    top: 0.75rem;
}
.lfm2d-toolbar {
    position: absolute;
    top: 48px;
    right: 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    z-index: 2;
}
.lfm2d-btn {
    width: 32px;
    height: 32px;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 6px;
    background: rgba(26,29,35,0.9);
    color: var(--text-secondary);
    font-size: 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.lfm2d-btn:hover {
    background: rgba(51,56,68,0.9);
    color: var(--text-primary);
}
@media (max-width: 768px) {
    .lan-flow-map-2d-stage {
        height: auto;
    }
    .lan-flow-map-2d-stage .lan-flow-map-controls {
        top: 0.5rem;
    }
    .lan-flow-map-2d-stage .lfm2d-canvas {
        height: clamp(400px, 50vh, 600px);
    }
    .lan-flow-map-2d-stage.lan-flow-map-fullscreen .lfm2d-canvas {
        height: 100%;
    }
}

.lan-flow-map-context-menu {
    position: absolute;
    z-index: 20;
    background: rgba(16, 24, 32, 0.95);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    padding: 4px 0;
    min-width: 160px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}
.lan-flow-map-context-menu-item {
    padding: 7px 14px;
    font-size: 0.82rem;
    color: var(--text-primary);
    cursor: pointer;
    user-select: none;
}
.lan-flow-map-context-menu-item:hover {
    background: var(--bg-hover);
}
.lan-flow-map-reposition-hud {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 15;
    background: rgba(16, 24, 32, 0.92);
    border: 1px solid var(--primary-color);
    border-radius: 8px;
    padding: 8px 16px;
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 0.82rem;
    color: var(--text-primary);
    white-space: nowrap;
}
.lan-flow-map-reposition-title {
    font-weight: 500;
    color: var(--primary-hover);
}
.lan-flow-map-reposition-keys {
    color: var(--text-secondary);
}
.lan-flow-map-reposition-keys .kbd {
    display: inline-block;
    padding: 1px 5px;
    font-size: 0.825rem;
    background: var(--bg-tertiary);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 3px;
    font-family: inherit;
    line-height: 1.4;
}

.isp-score-excellent { color: var(--success-color); }
.isp-score-good { color: var(--good-color); }
.isp-score-fair { color: var(--warning-color); }
.isp-score-poor { color: var(--danger-color); }
.isp-score-none { color: var(--text-muted); }

.monitoring-stat-card .stat-value.isp-score-excellent { color: var(--success-color); }
.monitoring-stat-card .stat-value.isp-score-good { color: var(--good-color); }
.monitoring-stat-card .stat-value.isp-score-fair { color: var(--warning-color); }
.monitoring-stat-card .stat-value.isp-score-poor { color: var(--danger-color); }
.monitoring-stat-card .stat-value.isp-score-none { color: var(--text-muted); }

.isp-health-tile {
    position: relative;
    overflow: hidden;
    --tile-accent: var(--text-muted);
    background-image:
        radial-gradient(ellipse 85% 130% at 50% -20%, rgba(5, 80, 181, 0.18), transparent 70%),
        linear-gradient(160deg, rgba(43, 168, 154, 0.07), transparent 55%);
}

.isp-health-tile.isp-score-excellent { --tile-accent: var(--success-color); }
.isp-health-tile.isp-score-good { --tile-accent: var(--good-color); }
.isp-health-tile.isp-score-fair { --tile-accent: var(--warning-color); }
.isp-health-tile.isp-score-poor { --tile-accent: var(--danger-color); }
.isp-health-tile.isp-score-none { --tile-accent: var(--text-muted); }

.isp-health-tile .stat-value.isp-tile-score {
    font-weight: 700;
    letter-spacing: -0.5px;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.isp-health-tile.isp-score-excellent .stat-value.isp-tile-score { background-image: linear-gradient(120deg, #34d399, #24bc70); }
.isp-health-tile.isp-score-good .stat-value.isp-tile-score { background-image: linear-gradient(120deg, #60a5fa, #3b82f6); }
.isp-health-tile.isp-score-fair .stat-value.isp-tile-score { background-image: linear-gradient(120deg, #fbbf24, #f59e0b); }
.isp-health-tile.isp-score-poor .stat-value.isp-tile-score { background-image: linear-gradient(120deg, #f87171, #ef4444); }

.isp-health-tile.isp-score-none .stat-value.isp-tile-score {
    -webkit-text-fill-color: var(--text-muted);
    color: var(--text-muted);
}

.isp-tile-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background: var(--bg-tertiary);
}

.isp-tile-bar-fill {
    height: 100%;
    background: var(--tile-accent);
    transition: width 0.4s ease;
}

.isp-health-card {
    margin-bottom: 1rem;
}

.isp-health-card .issue-item + .issue-item {
    margin-top: 0.75rem;
}

.isp-health-card .issue-severity {
    margin-bottom: 0.375rem;
}

.isp-findings-header {
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Under an episode's hop table: the same Acknowledge as its recurring finding, bottom right. */
.isp-trace-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.5rem;
}

.isp-trace-actions .issue-action {
    margin-left: 0;
}

/* Pinned in the corner beside the severity badge, so the text keeps the card's full width. */
@media (min-width: 769px) {
    .isp-health-card .issue-item.has-action {
        position: relative;
    }

    .isp-health-card .issue-item.has-action .issue-title {
        padding-right: 7.5rem;
    }

    .isp-health-card .isp-finding-action {
        position: absolute;
        top: 0.75rem;
        right: 0.75rem;
    }
}

@media (max-width: 768px) {
    /* Its own row under the finding: beside the title it would squeeze the title into a sliver. */
    .isp-health-card .isp-finding-action {
        grid-column: 1 / -1;
        justify-self: end;
    }

    .isp-health-card .issue-severity {
        grid-column: 1;
        grid-row: 1;
        align-self: center;
        justify-self: start;
        margin-bottom: 0;
    }

    .isp-health-card .issue-title {
        grid-column: 2;
        grid-row: 1;
    }

    /* issue-content is display:contents here, so these become grid items; without an
       explicit span they auto-place into column 1 and stretch the badge column. */
    .isp-health-card .issue-recommendation,
    .isp-health-card .issue-investigate,
    .isp-health-card .issue-ack {
        grid-column: 1 / -1;
    }

    /* The generic rules pin description/recommendation to fixed rows for the audit-card
       layout (title in row 2, context in row 4). Here the title sits in row 1 and there
       is no context row, so fixed rows leave holes that the auto-placed investigate/ack
       blocks backfill out of order - let the content flow in DOM order instead. */
    .isp-health-card .issue-description,
    .isp-health-card .issue-recommendation {
        grid-row: auto;
    }

    /* The grid's row-gap already spaces the ack blurb here; the desktop margin doubles it. */
    .isp-health-card .issue-ack {
        margin-top: 0.375rem;
    }
}

.isp-health-toolbar {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.isp-health-toolbar .time-range-selector {
    background: var(--bg-tertiary);
}

.isp-health-toolbar .custom-range-btn {
    justify-content: center;
}

@media (max-width: 768px) {
    .isp-health-toolbar .btn {
        min-width: 0;
        padding: 0 12px;
    }

    .isp-health-toolbar {
        flex-wrap: wrap;
        row-gap: 0.5rem;
    }

    .isp-health-toolbar .wan-selector {
        flex-basis: 100%;
    }
}

.isp-health-toolbar .btn-label-narrow {
    display: none;
}

/* Below 400px the toolbar runs out of room, so the buttons drop to their short labels. The
   busy words go too - .btn-state-stack sizes to the widest state, so leaving "Refreshing"
   in would hold the width the short label just freed. */
@media (max-width: 400px) {
    .isp-health-toolbar .btn-label-wide {
        display: none;
    }

    .isp-health-toolbar .btn-label-narrow {
        display: inline;
    }
}

.isp-window-reduced {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 30px;
    padding: 0 10px;
    border: 1px solid var(--warning-color);
    border-radius: 6px;
    background: rgba(231, 150, 19, 0.12);
    color: var(--warning-color);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.isp-window-reduced:hover {
    background: rgba(231, 150, 19, 0.2);
}

.isp-window-reduced:disabled {
    opacity: 0.6;
    cursor: default;
}

.isp-popover-backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
}

.isp-filter-raised {
    z-index: 50;
}

.isp-health-updated {
    position: absolute;
    top: 0.6rem;
    right: 0.75rem;
    font-size: 0.825rem;
    color: var(--text-muted);
    z-index: 1;
}

.isp-health-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    min-height: 320px;
    overflow: hidden;
    border: 1px solid var(--border-color);
    background:
        radial-gradient(ellipse 60% 120% at 18% 0%, rgba(5, 80, 181, 0.12), transparent 60%),
        radial-gradient(ellipse 50% 100% at 85% 100%, rgba(43, 168, 154, 0.08), transparent 65%),
        var(--bg-card);
}

.isp-health-loading-spinner {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0%, var(--primary-color) 45%, #2ba89a 100%);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 4px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 4px));
    filter: drop-shadow(0 4px 16px rgba(43, 168, 154, 0.28));
    animation: spin 0.9s linear infinite;
}

.isp-health-loading-text {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.95rem;
    letter-spacing: 0.01em;
}

.isp-health-hero {
    position: relative;
    margin-bottom: 1rem;
    overflow: hidden;
    border: 1px solid var(--border-color);
    background:
        radial-gradient(ellipse 60% 120% at 18% 0%, rgba(5, 80, 181, 0.12), transparent 60%),
        radial-gradient(ellipse 50% 100% at 85% 100%, rgba(43, 168, 154, 0.08), transparent 65%),
        var(--bg-card);
}

.isp-health-hero-body {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 2rem;
    padding: 1.5rem 2rem;
    min-height: 249px;
}

.isp-health-hero-body-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
}

.isp-health-hero-gauge {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
}

.isp-gauge {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    width: 190px;
    filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.35));
}

.isp-gauge-small {
    width: 150px;
    filter: none;
}

.isp-gauge-small .isp-gauge-score {
    font-size: 30px;
}

.isp-gauge-small .isp-gauge-label {
    font-size: 17px;
}

.isp-gauge-score {
    font-size: 40px;
    font-weight: 700;
    letter-spacing: -1px;
}

.isp-gauge-label {
    font-size: 13px;
    fill: var(--text-secondary);
}

.isp-health-profile-chip {
    padding: 0.3rem 0.9rem;
    border-radius: 2rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    font-size: 0.78rem;
    white-space: nowrap;
}

.isp-health-profile-chip-selectable {
    position: relative;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease;
}

.isp-health-profile-chip-selectable:hover {
    border-color: var(--primary-color);
    color: var(--text-primary);
}

.isp-profile-chip-caret {
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-right: -0.4rem;
    vertical-align: middle;
    background: no-repeat center/13px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%235c5c66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

.isp-access-tech-title {
    display: inline-flex;
    align-items: center;
}

.isp-physical-link-source {
    max-width: 320px;
    margin-top: 0.5rem;
}

.isp-access-tech-select {
    margin-left: 0.75rem;
    padding: 0 1.1rem 0 0;
    border: none;
    background-color: transparent;
    color: var(--text-muted);
    font-size: 0.8125rem;
    font-weight: 400;
    vertical-align: middle;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235c5c66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right center;
}

.isp-access-tech-select:disabled {
    background-image: none;
    padding-right: 0;
    cursor: default;
    opacity: 1;
}

.isp-profile-chip-caret:has(+ .isp-profile-chip-select:disabled) {
    display: none;
}

.isp-access-tech-select:hover {
    color: var(--text-primary);
}

.isp-access-tech-select option {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.isp-profile-chip-select {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    border: none;
    appearance: none;
    -webkit-appearance: none;
    background: var(--bg-primary);
    color: var(--text-primary);
}

.isp-profile-chip-select option {
    background: var(--bg-primary);
    color: var(--text-primary);
}

a.isp-health-hero-speed {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    justify-self: center;
    text-align: center;
    color: inherit;
    text-decoration: none;
    border-radius: 0.5rem;
    padding: 0.5rem;
    margin: -0.5rem;
    transition: background-color 0.15s ease;
}

a.isp-health-hero-speed:hover {
    background-color: var(--bg-hover);
}

.isp-speed-label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
}

.isp-speed-headline {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.5rem;
}

.isp-speed-measured {
    font-size: 2.6rem;
    font-weight: 700;
    letter-spacing: -1.5px;
    line-height: 1;
    background: linear-gradient(120deg, #3b82f6, #2ba89a);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.isp-speed-unit {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.isp-speed-sub {
    display: flex;
    justify-content: center;
    align-items: baseline;
    gap: 0.45rem;
    flex-wrap: wrap;
    font-size: 0.95rem;
    color: var(--text-secondary);
}

.isp-speed-sub-label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.isp-speed-source {
    color: var(--text-muted);
}

.isp-speed-tested {
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-top: 0.1rem;
}

.isp-health-hero-side {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
}

.isp-health-uptime {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    text-align: center;
}

.isp-uptime-label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
}

.isp-uptime-value {
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -1px;
    line-height: 1.15;
}

.isp-uptime-sub {
    font-size: 0.78rem;
    color: var(--text-muted);
}

.isp-health-hero-dimensions {
    display: flex;
    gap: 0.75rem;
}

.isp-health-dimension-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin-bottom: 1rem;
}

.isp-health-dimension-grid .isp-health-card {
    margin-bottom: 0;
}

.isp-dimension-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.isp-dimension-score {
    font-size: 1.4rem;
    font-weight: 700;
}

.isp-card-body-tight-top {
    padding-top: 6px;
}

.isp-factor-row {
    display: grid;
    grid-template-columns: minmax(110px, 1fr) minmax(60px, 130px) 34px;
    gap: 0.75rem;
    align-items: center;
    margin-top: 0.9rem;
}

.isp-factor-label {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.isp-factor-name {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
}

.isp-factor-name-row {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
}

.isp-asn-name-row {
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.isp-involvement-pie {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.isp-involvement-pie svg {
    display: block;
}

.isp-factor-value {
    font-size: 0.75rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.isp-factor-bar-track {
    height: 7px;
    border-radius: 0 4px 4px 0;
    background: var(--bg-tertiary);
    overflow: hidden;
}

/* A deduction (Transit Health's Path Congestion) below the graded rows: no bar, a divider above. */
.isp-factor-row.isp-factor-deduction {
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.isp-factor-bar-track.isp-factor-bar-track-empty {
    background: transparent;
}

.isp-factor-bar {
    height: 100%;
    border-radius: 0 4px 4px 0;
    transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.isp-bar-excellent { background: linear-gradient(90deg, #1a9d5c, #24bc70); }
.isp-bar-good { background: linear-gradient(90deg, #2563eb, #3b82f6); }
.isp-bar-fair { background: linear-gradient(90deg, #d97706, #f59e0b); }
.isp-bar-poor { background: linear-gradient(90deg, #dc2626, #ef4444); }
.isp-bar-none { background: var(--bg-hover); }

.isp-factor-score {
    font-size: 0.9rem;
    font-weight: 700;
    text-align: right;
    cursor: default;
}

.isp-factor-score.isp-score-caveat,
.isp-asn-grade.isp-score-caveat {
    cursor: help;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}

.isp-factor-description {
    margin-top: 0.25rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.upstream-tech-select {
    max-width: 250px;
}

.upstream-tech-unset {
    outline: 2px solid rgba(59, 130, 246, 0.5);
    outline-offset: 2px;
    border-radius: 6px;
}

.upstream-tech-inferred {
    outline: 2px solid var(--warning-color);
    outline-offset: 2px;
    border-radius: 6px;
}

.upstream-tech-inferred-help {
    margin-top: 0.5rem;
    color: var(--warning-color);
}

.isp-plan-hint-compact {
    margin-top: 0.4rem;
    padding: 0.5rem 0.6rem;
    border-left: 2px solid var(--info-color);
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.isp-plan-hint-compact a {
    margin-left: 0.4rem;
    white-space: nowrap;
}

.isp-asn-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 0.85rem;
}

.isp-asn-card {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
    transition: border-color 0.2s ease, transform 0.2s ease;
}

.isp-asn-card:hover {
    border-color: var(--primary-hover);
    transform: translateY(-2px);
}

.isp-hop-list-overflow {
    margin-top: 0;
}

.isp-hop-list-overflow .isp-hop:first-child {
    border-top: 1px solid var(--border-color);
}

.isp-network-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    margin-top: 0.85rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}

.isp-network-toggle:hover {
    border-color: var(--primary-hover);
    color: var(--text-primary);
    background: var(--bg-hover);
}

.isp-network-toggle-chevron {
    display: inline-block;
    font-size: 0.75rem;
    line-height: 1;
    color: var(--text-muted);
    transition: transform 0.25s ease;
}

.isp-network-toggle-chevron.expanded {
    transform: rotate(180deg);
}

.isp-asn-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
}

.isp-asn-name {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.95rem;
}

.isp-asn-sub {
    font-size: 0.825rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.isp-asn-grade {
    font-size: 1.3rem;
    font-weight: 700;
    cursor: default;
}

.isp-asn-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.4rem 0.75rem;
}

.isp-asn-stat {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}

.isp-asn-stat .detail-label {
    font-size: 0.68rem;
}

.isp-asn-stat .detail-value {
    font-size: 0.85rem;
}

.isp-asn-stat .tooltip-icon {
    background-color: var(--btn-map-hover);
}

.isp-asn-score-track {
    height: 5px;
    border-radius: 0 3px 3px 0;
    background: var(--bg-primary);
    overflow: hidden;
}

.isp-event-timeline {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding-left: 1rem;
    border-left: 2px solid var(--bg-hover);
}

.isp-event-item {
    position: relative;
    display: grid;
    grid-template-columns: 7.5rem 5.5rem minmax(0, 1fr);
    justify-items: start;
    align-items: baseline;
    column-gap: 0.6rem;
    row-gap: 0.3rem;
}

.isp-event-item::before {
    content: "";
    position: absolute;
    left: calc(-1rem - 7.5px);
    top: 0.325rem;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--text-muted);
    border: 2px solid var(--bg-card);
}

.isp-event-badge {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 4px;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    cursor: default;
}

.isp-event-badge[data-tooltip] {
    cursor: help;
}

.isp-event-badge-warning {
    color: var(--warning-color);
    background: rgba(245, 158, 11, 0.15);
}

.isp-event-badge-info {
    color: var(--info-color);
    background: rgba(59, 130, 246, 0.15);
}

.isp-event-badge-danger {
    color: var(--danger-color);
    background: rgba(238, 99, 104, 0.15);
}

.isp-event-badge-congestion {
    color: var(--warning-color);
    background: rgba(245, 158, 11, 0.15);
}

.isp-event-badge-congestion-soft {
    color: rgba(231, 150, 19, 0.5);
    background: rgba(245, 158, 11, 0.08);
}

.isp-event-badge-shift {
    color: var(--info-color);
    background: rgba(59, 130, 246, 0.15);
}

.isp-event-badge-change {
    color: #a78bfa;
    background: rgba(167, 139, 250, 0.15);
}

.isp-events-header {
    flex-wrap: wrap;
    gap: 0.4rem;
}

.isp-event-filter .time-btn.active.evt-congestion {
    color: var(--warning-color);
    background: rgba(245, 158, 11, 0.15);
}

.isp-event-filter .time-btn.active.evt-shift {
    color: var(--info-color);
    background: rgba(59, 130, 246, 0.15);
}

.isp-event-filter .time-btn.active.evt-change {
    color: #a78bfa;
    background: rgba(167, 139, 250, 0.15);
}

.isp-event-filter .time-btn.active.evt-ack {
    color: var(--text-primary);
    background: rgba(160, 160, 168, 0.22);
}

/* A tap leaves :hover stuck on a phone, which made an off pill look selected. */
@media (hover: none) {
    .isp-event-filter .time-btn:not(.active):hover {
        color: var(--text-secondary);
        background: transparent;
    }
}

/* Four pills share a phone's width: none breaks onto two lines, and Acknowledged shortens. */
.isp-event-filter .time-btn {
    white-space: nowrap;
}

.isp-event-filter .evt-label-short {
    display: none;
}

@media (max-width: 768px) {
    .isp-event-filter .evt-label-long {
        display: none;
    }

    .isp-event-filter .evt-label-short {
        display: inline;
    }
}

.isp-event-time {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.isp-event-text {
    font-size: 0.85rem;
    color: var(--text-secondary);
    flex: 1 1 240px;
    /* With the minmax(0, ...) text track, this keeps an open hop table from widening the row past
       the card: it scrolls inside its .table-responsive instead. */
    min-width: 0;
    justify-self: stretch;
}

.isp-event-members-toggle {
    padding: 0;
    border: none;
    background: none;
    font-size: 0.8rem;
    color: var(--primary-hover);
    cursor: pointer;
}

/* Two toggles on one line (Show N paths, Show hop table): the space between them alone runs them together. */
.isp-event-members-toggle + .isp-event-members-toggle {
    margin-left: 0.75rem;
}

.isp-event-members-toggle:hover {
    text-decoration: underline;
}

.isp-event-members {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-top: 0.35rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* Path Localization: the hop table behind an episode row */
.path-episode-detail {
    margin-top: 0.5rem;
    font-size: 0.8rem;
}

.path-episode-summary {
    margin: 0 0 0.5rem;
    color: var(--text-muted);
}

.path-episode-destinations {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin-bottom: 0.5rem;
}

.path-episode-dest-label {
    display: inline-block;
    min-width: 4.5rem;
    color: var(--text-muted);
}

.path-episode-table-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0.5rem 0 0.25rem;
}

.path-episode-table-title {
    font-weight: 600;
}

.path-episode-target-name {
    display: inline-flex;
    align-items: center;
}

.path-episode-target-name .monitoring-jump-btn {
    padding: 0 0.25rem;
}

.path-episode-target-name .monitoring-jump-btn svg {
    width: 15px;
    height: 15px;
}

.path-episode-rerun {
    margin-left: auto;
}

.path-episode-table + .path-episode-table {
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
}

/* Fixed columns so every target's table lines up with the next. */
.path-episode-table .path-episode-hops {
    table-layout: fixed;
    min-width: 760px;
}

.path-episode-hops .path-col-hop { width: 3rem; }
.path-episode-hops .path-col-network { width: 13rem; }
.path-episode-hops .path-col-loss { width: 9rem; }
.path-episode-hops .path-col-rtt { width: 12rem; }
.path-episode-hops .path-col-return { width: 7.5rem; }

.path-episode-hops td,
.path-episode-hops th {
    padding: 0.3rem 0.5rem;
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

.path-episode-hops th,
.path-episode-hops td.path-hop-nowrap {
    white-space: nowrap;
}

.path-episode-hops tbody tr:nth-child(even) td {
    background: rgba(255, 255, 255, 0.025);
}

.path-episode-hops tbody tr.path-hop-elevated td {
    background: rgba(245, 158, 11, 0.07);
}

.path-episode-hops tbody tr.path-hop-elevated:nth-child(even) td {
    background: rgba(245, 158, 11, 0.1);
}

.path-episode-hops code.text-code {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    padding: 0 0.3rem;
    margin-left: 0.15rem;
}

.path-episode-hops tr.path-hop-icmp td {
    color: var(--text-muted);
}

/* One bar per trace behind the RTT text: the text stays on top, the bars read as background. */
.path-episode-hops td.path-rtt-cell {
    position: relative;
}

.path-rtt-bars {
    position: absolute;
    inset: 3px 0.5rem;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    pointer-events: none;
}

.path-rtt-bars i {
    flex: 1;
    min-height: 2px;
    border-radius: 1px 1px 0 0;
    background: var(--text-muted);
    opacity: 0.45;
}

.path-rtt-bars i.slow {
    background: var(--warning-color);
    opacity: 0.4;
}

.path-rtt-bars i.empty {
    background: transparent;
}

/* An ICMP-limited hop is shown, never blamed: its slow traces stay grey. */
.path-episode-hops tr.path-hop-icmp .path-rtt-bars i.slow {
    background: var(--text-muted);
    opacity: 0.3;
}

.path-rtt-value {
    position: relative;
    font-weight: 500;
    text-shadow: 0 0 3px var(--bg-card), 0 0 3px var(--bg-card), 0 0 2px var(--bg-card);
}

.path-hop-tag {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    font-size: 0.7rem;
    white-space: nowrap;
}

.path-hop-tag-onset {
    color: var(--warning-color);
    background: rgba(245, 158, 11, 0.15);
}

.path-hop-tag-clean {
    color: var(--success-color);
    background: rgba(16, 185, 129, 0.12);
}

.path-hop-tag-muted {
    color: var(--text-muted);
    background: var(--bg-tertiary);
}

.isp-outage-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.isp-outage {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
}

.isp-outage-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.4rem 0.7rem;
}

.isp-outage-duration {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.isp-outage-window {
    font-size: 0.78rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.isp-outage-scope {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-left: auto;
}

.isp-outage-ack {
    font-size: 0.825rem;
    color: var(--text-muted);
}

a.isp-outage-ack {
    color: var(--text-secondary);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

a.isp-outage-ack:hover {
    color: var(--text-primary);
}

.isp-outage-ack-done a {
    color: var(--text-secondary);
    margin-left: 0.3rem;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.isp-outage-ack-done a:hover {
    color: var(--text-primary);
}

.isp-outage-ack-locked {
    opacity: 0.5;
    pointer-events: none;
}

.issue-ack {
    margin-top: 0.75rem;
    margin-bottom: 0.25rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.issue-ack .isp-outage-ack {
    font-size: 0.75rem;
    margin-left: 0.35rem;
}

.isp-outage-shape {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.isp-outage-hop {
    display: grid;
    grid-template-columns: minmax(0, 8rem) 1fr minmax(0, 7rem);
    align-items: center;
    gap: 0.6rem;
}

/* 12-hour clocks need room for "back @ 12:59:59 PM". Desktop only: mobile stacks the row. */
@media (min-width: 769px) {
    .isp-outage-h12 .isp-outage-hop {
        grid-template-columns: minmax(0, 8rem) 1fr minmax(0, 9rem);
    }
}

.isp-outage-hop-name {
    font-size: 0.8rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.isp-outage-hop-track {
    height: 7px;
    border-radius: 4px;
    background: linear-gradient(90deg, var(--bg-tertiary) 0, var(--bg-tertiary) 3px, var(--primary-color) 3px);
    overflow: hidden;
}

.isp-outage-hop-dark {
    height: 100%;
    border-radius: 4px 0 0 4px;
    background:
        repeating-linear-gradient(45deg, transparent 0, transparent 2px, var(--bg-tertiary) 2px, var(--bg-tertiary) 5px),
        linear-gradient(90deg, var(--text-muted), 75%, var(--primary-color));
    transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.isp-outage-hop-loss {
    height: 100%;
    border-radius: 4px 0 0 4px;
    background: var(--warning-color);
    transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.isp-outage-hop-status {
    font-size: 0.825rem;
    color: var(--text-secondary);
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.isp-outage-hop-up {
    color: var(--success-color);
}

.isp-outage-shape-toggle {
    display: flex;
    justify-content: center;
}

.isp-outage-shape-toggle button {
    cursor: pointer;
}

/* Cancels the shape's flex gap around a seam wrapper so the 0fr state adds no
   phantom spacing; the visible child restores the gap itself (margin/padding-top). */
.isp-outage-seam {
    margin-top: -0.45rem;
}

.isp-outage-shape-middle {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding-top: 0.45rem;
}

.isp-outage-fault {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-top: 0.45rem;
    padding: 0.2rem 0;
    border: none;
    background: none;
    cursor: pointer;
}

/* The hidden middle reads as a fault: two dashed strands sheared 4px out of line,
   fading toward the card edges, meeting the count pill at the break. */
.isp-outage-fault::before,
.isp-outage-fault::after {
    content: "";
    position: absolute;
    height: 2px;
    opacity: 0.35;
    transition: opacity 0.15s ease;
}

.isp-outage-fault::before {
    left: 0;
    right: calc(50% + 4.75rem);
    top: calc(50% - 3px);
    background: repeating-linear-gradient(90deg, var(--text-muted) 0 7px, transparent 7px 13px);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 45%);
    mask-image: linear-gradient(90deg, transparent, #000 45%);
}

.isp-outage-fault::after {
    left: calc(50% + 4.75rem);
    right: 0;
    top: calc(50% + 1px);
    background: repeating-linear-gradient(270deg, var(--text-muted) 0 7px, transparent 7px 13px);
    -webkit-mask-image: linear-gradient(270deg, transparent, #000 45%);
    mask-image: linear-gradient(270deg, transparent, #000 45%);
}

.isp-outage-fault:hover::before,
.isp-outage-fault:hover::after {
    opacity: 0.6;
}

.isp-outage-fault-pill,
.isp-outage-shape-toggle button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.16rem 0.7rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--text-secondary);
    font-size: 0.825rem;
    white-space: nowrap;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.isp-outage-fault:hover .isp-outage-fault-pill,
.isp-outage-shape-toggle button:hover {
    color: var(--text-primary);
    border-color: var(--text-muted);
}

.isp-outage-fault-chevron {
    font-size: 0.55rem;
    line-height: 1;
}

@media (max-width: 768px) {
    .isp-outage-hop {
        grid-template-columns: 1fr auto;
        grid-template-areas: "name status" "track track";
        gap: 0.3rem 0.6rem;
    }
    .isp-outage-hop-name {
        grid-area: name;
    }
    .isp-outage-hop-status {
        grid-area: status;
    }
    .isp-outage-hop-track {
        grid-area: track;
    }
    .isp-outage-scope {
        margin-left: 0;
        flex: 1 0 auto;
    }

    .isp-outage-head .isp-outage-ack {
        margin-left: auto;
    }
}

@media (max-width: 1024px) {
    .isp-health-dimension-grid {
        grid-template-columns: 1fr;
    }
}

#isp-health-asn-chart {
    margin-left: -7px;
    margin-right: -2px;
}

@media (max-width: 768px) {
    #isp-health-asn-chart {
        margin-left: 0;
        margin-right: 0;
    }
    .isp-health-hero-body {
        grid-template-columns: 1fr;
        gap: 1.25rem;
        padding: 1.25rem 1rem;
        justify-items: center;
        /* Stacked layout is much taller than desktop's row, so the desktop min-height lets
           the hero collapse (and jump) when the loading spinner replaces the score. Hold the
           stacked height so the spinner box matches the score box. */
        min-height: 525px;
    }
    .isp-speed-measured {
        font-size: 2rem;
    }
    .isp-health-hero-side {
        gap: 1rem;
    }
    .isp-uptime-value {
        font-size: 1.75rem;
    }
    .isp-health-hero-dimensions {
        gap: 0.4rem;
        flex-wrap: wrap;
        justify-content: center;
        margin-left: -1.75rem;
        margin-right: -1.75rem;
    }
    .isp-gauge-small {
        width: min(115px, 28vw);
    }
    .isp-gauge-small .isp-gauge-label {
        font-size: 19px;
    }
    .isp-event-timeline {
        padding-left: 0.75rem;
    }
    .isp-event-item {
        grid-template-columns: auto minmax(0, 1fr);
        row-gap: 0.15rem;
    }
    .isp-event-text {
        grid-column: 1 / -1;
        padding-top: 0.25rem;
    }
    .isp-event-item::before {
        left: calc(-0.75rem - 7.5px);
    }
}

@media (max-width: 338px) {
    .isp-gauge-small {
        width: 115px;
    }
}

.isp-chart-wrap {
    position: relative;
}

.isp-health-chart-card,
#latency-charts-container,
#device-health-charts-container {
    overflow: visible;
}

.isp-chart-reset-btn {
    position: absolute;
    top: 0.25rem;
    right: 0.5rem;
    z-index: 5;
}

.isp-hop-list {
    display: flex;
    flex-direction: column;
    margin-top: 0.25rem;
}

.isp-hop {
    padding: 0.6rem 0;
}

.isp-hop + .isp-hop {
    border-top: 1px solid var(--border-color);
}

.isp-hop-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.isp-hop-main {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    flex: 1;
    min-width: 0;
}

.isp-hop-name {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 0.5rem;
    row-gap: 0.25rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-primary);
}

.isp-hop-stats {
    display: flex;
    gap: 1.25rem;
    margin-top: 0.45rem;
}

.isp-target-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    padding: 0.15rem 0.4rem;
    border: 0;
    border-radius: 4px;
    font-family: inherit;
    font-size: 0.62rem;
    font-weight: 600;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.isp-target-disable-hint {
    border: none;
    background: rgba(231, 150, 19, 0.2);
    color: var(--warning-color);
    cursor: pointer;
}

.isp-target-disable-hint:hover {
    background: rgba(231, 150, 19, 0.32);
}

.isp-target-stat {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.isp-target-stat-label {
    font-size: 0.62rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.isp-target-stat-value {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.isp-factor-link {
    color: var(--text-primary);
    text-decoration: underline dotted;
    text-decoration-color: var(--text-muted);
    text-underline-offset: 3px;
}

.isp-factor-link:hover {
    color: var(--primary-hover);
}

/* Arriving somewhere from a link elsewhere in Monitoring: the target rings itself so the eye lands
   on it, then fades out on its own. Every jump used to inline its own copy of this. The ring is
   painted with a transparent outline always present, so the color transition has something to
   animate from and the fade is not a hard cut. */
.nav-highlight,
.card-highlight {
    outline: 2px solid transparent;
    outline-offset: 4px;
    /* Card radius by default, since most targets are a card or a bare wrapper around one, which has
       no radius of its own and would otherwise ring square around rounded content. A target that is
       not card-shaped - a sub-card form, a button - overrides it by passing a radius to the helper,
       which sets --nav-highlight-radius on the element. Declared by the caller, never guessed at
       from the children. Not on the row variant below: a row tints rather than rings. */
    border-radius: var(--nav-highlight-radius, var(--border-radius-lg));
    transition: outline-color 0.9s ease-out;
}

/* .card-highlight is the same ring held on: a card that stays called out (MFA still to set up on
   Account Security) rather than one being pointed at by a jump. Same treatment either way, so the
   two cannot drift into different blues, which is what they had done. */
.nav-highlight-on,
.card-highlight {
    outline-color: color-mix(in srgb, var(--highlight-color) 50%, transparent);
    transition: outline-color 0.25s ease-in;
}

/* Row variant: a ring around a table row fights its neighbours, so a row tints instead. Same
   variable, same timing, so the two read as one behavior seen on different shapes. */
.nav-highlight-row {
    transition: background-color 0.9s ease-out;
}

.nav-highlight-row.nav-highlight-on {
    background-color: color-mix(in srgb, var(--highlight-color) 30%, transparent);
    transition: background-color 0.25s ease-in;
}

.isp-events-jump {
    cursor: pointer;
    text-decoration: underline dotted;
    /* A dimmed version of the score color the value is carrying, not a flat grey: the count is
       colored by its grade, so its underline should be a quieter shade of the same thing. */
    text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
    text-underline-offset: 3px;
}

body.kiosk-mode .hamburger-btn {
    display: block;
}

body.kiosk-mode .mobile-logo {
    display: block;
    height: 60px;
    margin: -0.5rem 0;
    max-height: 20vw;
}

body.kiosk-mode .mobile-logo img {
    height: 100%;
    width: auto;
}

body.kiosk-mode .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    height: 100dvh;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    z-index: 1000;
    overflow-y: auto;
}

body.kiosk-mode .sidebar.open {
    transform: translateX(0);
}

body.kiosk-mode .sidebar-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
}

body.kiosk-mode .sidebar-overlay.visible {
    display: block;
}

body.kiosk-mode .main-content {
    width: 100%;
}

body.kiosk-mode .top-bar {
    height: auto;
    padding: 0.75rem 1rem;
    gap: 0.5rem;
}

body.kiosk-mode .header-actions {
    flex: 1;
    justify-content: flex-end;
}

body.kiosk-mode .status-indicators {
    display: none;
}

/* The shared stats table drops its top margin because it normally follows a chart, which brings
   its own space below the plot. This one follows the filter chips instead and needs the gap. */
.port-stats-table .chart-card {
    margin-top: 0.5rem;
}

.port-stats-table .data-table th,
.port-stats-table .data-table td {
    white-space: nowrap;
}

.port-cell {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

.port-stats-scroll-top {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-color: var(--bg-tertiary) transparent;
}

.port-stats-scroll-top > div {
    height: 1px;
}

.port-stats-scroll-top::-webkit-scrollbar {
    height: 10px;
}

.port-stats-scroll-top::-webkit-scrollbar-track {
    background: transparent;
}

.port-stats-scroll-top::-webkit-scrollbar-thumb {
    background: var(--bg-tertiary);
    border-radius: 3px;
}

.port-stats-scroll-top::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
}

.port-label {
    color: var(--text-primary);
}

.port-client-link,
.port-client-link:visited {
    color: var(--info-color);
}

.port-client-link:hover {
    text-decoration: underline;
}

@media (max-width: 768px) {
    .port-stats-1dev .data-table thead th:first-child,
    .port-stats-1dev .data-table td[data-stat-id] {
        display: none;
    }
}

.port-icon {
    display: inline-flex;
    align-items: center;
    color: var(--text-secondary);
    user-select: none;
    cursor: default;
}

.port-icon.port-icon-down {
    color: var(--text-muted);
    opacity: 0.5;
}

.port-speed-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.9rem;
    margin-top: 0.75rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.port-speed-key {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.port-speed-swatch {
    width: 11px;
    height: 11px;
    border-radius: 2px;
    background-color: currentColor;
}

.port-speed-10m { color: #6b7280; }
.port-speed-100m { color: #8b5cf6; }
.port-speed-1g { color: #3b82f6; }
.port-speed-2_5g { color: #06b6d4; }
.port-speed-5g { color: #14b8a6; }
.port-speed-10g { color: #10b981; }
.port-speed-20g { color: #22c55e; }
.port-speed-25g { color: #84cc16; }
.port-speed-40g { color: #eab308; }
.port-speed-50g { color: #f97316; }
.port-speed-100g { color: #ef4444; }

.site-switcher {
    position: relative;
}

.site-switcher-trigger {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--bg-tertiary);
    border: none;
    border-radius: 8px;
    color: var(--text-primary);
    padding: 0.4rem 0.75rem;
    cursor: pointer;
    font-size: 0.85rem;
}

.site-switcher-trigger:hover {
    background: var(--bg-hover);
}

.site-switcher-icon {
    width: 18px;
    height: 18px;
}

.site-switcher-name {
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.site-switcher-chevron {
    width: 16px;
    height: 16px;
    color: var(--text-secondary);
    transition: transform 0.15s;
}

.site-switcher-chevron.open {
    transform: rotate(180deg);
}

.site-switcher-backdrop {
    position: fixed;
    inset: 0;
    z-index: 999;
}

.site-switcher-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 260px;
    width: max-content;
    max-width: min(360px, calc(100vw - 1.5rem));
    background: var(--bg-card);
    border: 1px solid var(--bg-tertiary);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    z-index: 1000;
    padding: 0.35rem;
}

.site-switcher-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    background: none;
    border: none;
    color: var(--text-primary);
    padding: 0.5rem 0.75rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    text-align: left;
}

.site-switcher-item:hover {
    background: var(--bg-hover);
}

.site-switcher-item.active {
    background: rgba(5, 80, 181, 0.18);
}

.site-switcher-item-name {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.site-switcher-item-slug {
    flex-shrink: 0;
    color: var(--text-muted);
    font-family: monospace;
    font-size: 0.75rem;
    white-space: nowrap;
}

.site-switcher-all {
    display: block;
    padding: 0.5rem 0.75rem 0.25rem;
    margin-top: 0.25rem;
    border-top: 1px solid var(--bg-tertiary);
    color: var(--primary-hover);
    font-size: 0.85rem;
    text-decoration: none;
}

.site-switcher-all:hover {
    background: var(--bg-hover);
    border-radius: 0 0 6px 6px;
}

@media (max-width: 768px) {
    .site-switcher-trigger {
        padding: 0.6rem 0.9rem;
        font-size: 0.95rem;
    }

    .site-switcher-menu {
        min-width: 260px;
        padding: 0.5rem;
    }

    .site-switcher-item {
        min-height: 44px;
        padding: 0.65rem 0.85rem;
        font-size: 0.95rem;
    }

    .site-switcher-all {
        padding: 0.75rem 0.85rem 0.5rem;
        font-size: 0.95rem;
    }
}

.sites-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
}

.site-card {
    display: block;
    padding: 1rem;
    cursor: pointer;
    border: 1px solid transparent;
    margin-bottom: 0;
    color: var(--text-primary);
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
}

.site-card:hover {
    background: var(--bg-tertiary);
}

.site-card-current {
    border-color: var(--primary-color);
}

.site-card-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.site-switcher-item-name .status-dot.empty,
.site-card-header .status-dot.empty {
    visibility: hidden;
}

.site-card-name {
    margin: 0;
    font-size: 1.05rem;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.site-card-meta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.5rem;
}

.site-card-slug {
    font-family: monospace;
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-right: auto;
}

.site-card-health {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.site-card-health > span:first-child {
    font-size: 1.1rem;
    font-weight: 600;
}

.site-card-footer {
    display: flex;
    margin-top: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.8rem;
}

.site-card-add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 110px;
    color: var(--text-secondary);
    border: 1px dashed var(--text-muted);
    background: transparent;
}

.site-card-add:hover {
    color: var(--text-primary);
    border-color: var(--text-secondary);
}

.site-card-add-plus {
    font-size: 1.4rem;
    line-height: 1;
    transform: translateY(-2.5px);
}

.sites-overview-card {
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
}

/* Dashboard Sites panel (Site Health, worst first) */
.sites-health-panel {
    padding: 0;
    margin-bottom: 1.5rem;
    overflow: hidden;
}

.shp-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--border-color);
}

.shp-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

.shp-inline-avg {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.shp-inline-avg b {
    font-size: 1.25rem;
    font-weight: 700;
    margin-right: 0.25rem;
}

.shp-spacer {
    flex: 1;
}

.shp-switcher {
    font-size: 0.8125rem;
}

.shp-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border-color);
}

.shp-avg {
    min-width: 200px;
    padding-right: 1rem;
    border-right: 1px solid var(--border-color);
}

.shp-avg-label,
.shp-avg-sub {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.shp-avg-value {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.15;
}

.shp-delta {
    font-size: 0.8125rem;
    font-weight: 500;
    margin-right: 0.25rem;
}

.shp-delta.down { color: var(--danger-color); }
.shp-delta.up { color: var(--success-color); }

.shp-chips,
.shp-count-chips {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
    gap: 0.5rem;
    flex: 1;
}

.shp-count-chips {
    padding: 0.75rem 1.25rem 0;
}

.shp-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.65rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}

.shp-chip-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}

.shp-chip.muted .shp-chip-dot { display: none; }
.shp-chip.danger { background: rgba(238, 99, 104, 0.14); color: #f38d91; }
.shp-chip.warning { background: rgba(231, 150, 19, 0.14); color: #f0b14d; }
.shp-chip.info { background: rgba(71, 151, 255, 0.14); color: #8ab9ff; }
.shp-chip.success { background: rgba(36, 188, 112, 0.14); color: var(--success-color); }

/* Firmware Rollout pill: a compact chip that links past the row or tile link under it. */
.shp-chip.shp-rollout {
    position: relative;
    z-index: 1;
    gap: 0.3rem;
    padding: 0.1rem 0.5rem;
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.45;
    white-space: nowrap;
    text-decoration: none;
}

.shp-chip.shp-rollout:hover {
    filter: brightness(1.2);
}

.shp-chip.shp-rollout .shp-chip-dot {
    width: 6px;
    height: 6px;
}

/* Scheduled: a hollow dot, not yet under way. */
.shp-chip.shp-rollout.muted .shp-chip-dot {
    display: inline-block;
    background: none;
    box-shadow: inset 0 0 0 1.5px currentColor;
}

.shp-head-row,
.shp-row {
    display: grid;
    grid-template-columns: 16px minmax(0, 1.4fr) 160px 56px minmax(0, 2fr) 72px 72px;
    column-gap: 0.85rem;
    align-items: center;
    padding: 0.55rem 1.25rem;
}

.shp-head-row {
    font-size: 0.75rem;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-color);
}

.shp-row {
    position: relative;
    color: var(--text-primary);
    border-bottom: 1px solid var(--bg-tertiary);
}

.shp-row:hover {
    background: var(--bg-hover-subtle);
}

.shp-row-link {
    position: absolute;
    inset: 0;
}

.shp-count-link {
    position: relative;
    z-index: 1;
    text-decoration: none;
}

.shp-count-link:hover {
    color: var(--primary-hover);
    text-decoration: underline;
}

.shp-head-row .num,
.shp-row .num {
    text-align: right;
}

.shp-name {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.shp-site {
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shp-sub {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.shp-name-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.5rem;
    min-width: 0;
}

/* Wide enough for "Agent offline", so the rollout pills start in one column. */
@media (min-width: 769px) {
    .shp-name-meta .shp-sub {
        min-width: 5.25rem;
    }
}

.shp-spark {
    width: 100%;
    height: 28px;
}

.shp-spark-line.healthy { stroke: var(--success-color); }
.shp-spark-line.degraded { stroke: var(--warning-color); }
.shp-spark-line.down { stroke: var(--danger-color); }
.shp-spark-line.unknown { stroke: var(--text-muted); }

.shp-now {
    font-size: 1.05rem;
    font-weight: 600;
}

.shp-issue {
    font-size: 0.8125rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shp-issue.muted {
    color: var(--text-muted);
}

/* A linked issue reads as text until hovered, like the count links beside it. */
a.shp-issue {
    color: inherit;
}

.shp-count {
    color: var(--text-secondary);
}

.shp-count.danger-text {
    color: var(--danger-color);
}

.shp-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 0.6rem;
    padding: 0.75rem 1.25rem 1rem;
}

.shp-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.65rem 0.8rem;
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
    border: 1px solid transparent;
    color: var(--text-primary);
    text-decoration: none;
    min-height: 44px;
}

.shp-tile:hover {
    color: var(--text-primary);
    border-color: var(--border-color);
}

.shp-tile.degraded { border-color: rgba(231, 150, 19, 0.5); }
.shp-tile.down { border-color: rgba(238, 99, 104, 0.5); }

.shp-tile-name {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shp-tile-health {
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.1;
}

.shp-tile-issue {
    font-size: 0.75rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Pinned to the tile's foot, so pills line up across a row of tiles. */
.shp-tile .shp-rollout {
    align-self: flex-start;
    max-width: 100%;
    margin-top: auto;
}

.shp-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.65rem 1.25rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .shp-header {
        padding: 0.75rem 1rem;
    }

    .shp-switcher {
        order: 5;
        flex: 1 1 100%;
    }

    .shp-summary {
        flex-direction: column;
        padding: 0.75rem 1rem;
    }

    .shp-avg {
        border-right: none;
        padding-right: 0;
    }

    .shp-row {
        grid-template-columns: 12px minmax(0, 1fr) 64px 44px;
        grid-template-areas: "dot name spark now" ". issue issue issue";
        row-gap: 0.2rem;
        padding: 0.65rem 1rem;
    }

    .shp-row > .status-dot { grid-area: dot; }
    .shp-row > .shp-name { grid-area: name; }
    .shp-row > .shp-spark { grid-area: spark; }
    .shp-row > .shp-now { grid-area: now; }
    .shp-row > .shp-issue { grid-area: issue; white-space: normal; }
    .shp-row > .shp-count { display: none; }

    .shp-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        padding: 0.75rem 1rem 1rem;
    }

    .shp-count-chips {
        padding: 0.75rem 1rem 0;
    }

    .shp-footer {
        padding: 0.65rem 1rem;
    }
}

.site-card-console {
    color: var(--text-secondary);
    font-size: 0.8rem;
    margin-top: 0.15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.agent-install pre {
    background: var(--bg-primary);
    padding: 0.75rem;
    border-radius: 6px;
    overflow-x: auto;
    max-width: 100%;
    margin: 0.5rem 0 0;
    font-size: 0.8125rem;
}

.agent-install code {
    font-size: 0.8125rem;
}

/* Inline code (long paths like the published binary location) wraps instead of
   pushing the card wider than the viewport on mobile. Code inside <pre> keeps its
   preformatted layout and scrolls horizontally instead. */
.agent-install :not(pre) > code {
    overflow-wrap: anywhere;
}

.agent-install .agent-flavor-title {
    margin: 1.25rem 0 0.25rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--text-primary);
}

.sites-overview-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.sites-overview-heading {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.sites-overview-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

.sites-overview-tiles .monitoring-stat-card {
    flex: 1 1 90px;
    min-height: 0 !important;
    border-bottom-width: 3px;
    background: var(--bg-tertiary);
}

.sites-overview-tiles .sites-tile-teal { border-bottom-color: #2ba89a; }
.sites-overview-tiles .sites-tile-teal .stat-value { color: #2ba89a; }
.sites-overview-tiles .sites-tile-emerald { border-bottom-color: #10b981; }
.sites-overview-tiles .sites-tile-emerald .stat-value { color: #10b981; }
.sites-overview-tiles .sites-tile-blue { border-bottom-color: #3b82f6; }
.sites-overview-tiles .sites-tile-blue .stat-value { color: #3b82f6; }
.sites-overview-tiles .sites-tile-purple { border-bottom-color: #a78bfa; }
.sites-overview-tiles .sites-tile-purple .stat-value { color: #a78bfa; }

.sites-overview-cta {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.sites-overview-cta svg {
    width: 16px;
    height: 16px;
}

.empty-icon img {
    width: 64px;
    height: 64px;
    opacity: 0.6;
}

@media (max-width: 768px) {
    .site-switcher-name {
        max-width: 90px;
    }

    .sites-overview-stats {
        gap: 1.25rem;
    }

    .sites-overview-cta span {
        display: none;
    }
}

.site-agent-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.4rem 0;
}

.site-agent-status {
    display: flex;
    place-items: center;
    gap: 0.75rem;
    flex: 1;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.site-agent-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* The upgrade block alternates a one-line heading and a command box, twice over, so each needs to sit
   off the thing below it. */
.agent-upgrade-cmd .form-help {
    margin-bottom: 0.3rem;
}

.agent-upgrade-cmd .code-copy-block {
    margin-bottom: 0.75rem;
}

/* Direct child, for the same reason as .history-details-row above: the panel row carries both
   classes, so as a descendant selector this kept zeroing the cells of the table inside the panel
   even once the other rule was scoped. */
.site-config-row > td {
    padding: 0;
}

.data-table tr.site-config-row {
    background: transparent;
}

/* Fixed layout so opening a panel cannot resize the columns. The panel row spans every column,
   so under the default auto layout its content participates in width calculation and the header
   columns jump the moment it appears. Widths are declared on the header cells below. */
.site-row-collapsible {
    cursor: pointer;
}

/* The caret sits beside the button group, not inside it. btn-group-wrap wraps its children, so a
   caret placed within it drops to a second line as soon as the buttons fill the row - which no
   column width can reliably prevent. */
.site-row-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.site-row-caret {
    flex-shrink: 0;
    white-space: nowrap;
    /* Pushed to the end of the cell rather than sitting against the last button, so it reads as the
       row's own affordance instead of another item in the button group. */
    margin-left: auto;
    padding-left: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.7rem;
}

.sites-table {
    table-layout: fixed;
}

/* The actions cell carries up to three buttons plus the caret, so it takes the space the first
   three columns were over-claiming - a short name, a slug and a date all read fine narrower. */
.sites-table th:nth-child(1) { width: 22%; }
.sites-table th:nth-child(2) { width: 17%; }
.sites-table th:nth-child(3) { width: 12%; }
.sites-table th:nth-child(4) { width: 8%; }
.sites-table th:nth-child(5) { width: 41%; }

@media (max-width: 768px) {
    .table-responsive:has(> .sites-table) {
        margin: 0 -0.25rem;
    }

    /* Each site reads as two lines on a phone - its columns, then its buttons across the full
       width - so the cells size to their content and the header, the fixed layout and the 500px
       floor all stop applying. One row still means one bottom border, so the two lines read as a
       single record. */
    .sites-table,
    .sites-table > tbody,
    .sites-table > tbody > tr.site-config-row,
    .sites-table > tbody > tr.site-config-row > td {
        display: block;
        min-width: 0;
    }

    .sites-table > thead {
        display: none;
    }

    .sites-table > tbody > tr:not(.site-config-row) {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        border-bottom: 1px solid var(--border-color);
    }

    .sites-table > tbody > tr:not(.site-config-row) > td {
        padding: 0.75rem 0.5rem;
        border-bottom: 0;
    }

    .sites-table > tbody > tr:not(.site-config-row) > td:not(:last-child) {
        flex: 1 1 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }

    /* Status is a badge or a dot and a word, so it takes what it needs and the name and site ID
       split the rest. */
    .sites-table > tbody > tr:not(.site-config-row) > td:nth-last-child(2) {
        flex: 0 0 auto;
    }

    .sites-table > tbody > tr:not(.site-config-row) > td:last-child {
        flex-basis: 100%;
        padding-top: 0;
    }
}

/* Created is hidden below 768px, so its share is redistributed rather than left as a gap. */
@media (max-width: 768px) {
    .sites-table th:nth-child(1) { width: 28%; }
    .sites-table th:nth-child(2) { width: 20%; }
    .sites-table th:nth-child(4) { width: 8%; }
    .sites-table th:nth-child(5) { width: 44%; }
}

.data-table tr.site-row-selected {
    background: var(--bg-hover);
}

/* An expanded row keeps its own background on hover. The generic row hover paints a lighter tint,
   so without this, hovering the row you just opened makes it look like it closed. Applied the same
   way to .history-row-expanded and .snmp-row-expanded. */
.data-table tr.site-row-selected:hover {
    background: var(--bg-row-expanded-hover);
}

.site-name-selected {
    font-weight: 600;
}

.site-config-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 0 0 0.75rem;
    padding: 1rem;
    background: var(--bg-tertiary);
    /* Square along the top so the panel reads as an extension of the row that opened it, rather
       than a separate card floating below it. */
    border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
}

/* .data-table holds a 500px floor, so on a phone this row runs past the wrapper's visible width
   into its scroll overflow, taking anything at its right edge - the command copy buttons - with
   it. Capped to the scroller's own inline size instead. */
.table-responsive:has(> .sites-table),
.waf-events .waf-matched {
    margin-top: 0.15rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.table-responsive:has(> .waf-events) {
    container-type: inline-size;
}

/* Drawn on the panel's inside edge. An outset ring is cut off here whichever element carries it:
   .expand-content hides overflow for the expand animation, and .table-responsive scrolls. */
.site-config-panel.nav-highlight {
    outline-offset: -2px;
}

.site-config-row .site-config-panel {
    max-width: 100cqw;
}

/* Threat Intelligence - WAF Events: the panel's gap spaces the exclusion help and its code block */
.waf-events .site-config-panel > .section-description,
.waf-events .site-config-panel .code-copy-block pre {
    margin: 0;
}

/* The exclusion form keeps the form-group rhythm, so the panel's flex gap is off here */
.waf-events .waf-exclusion-form {
    gap: 0;
}

.waf-events .waf-exclusion-form > .section-description {
    margin: 0 0 1rem;
}

.waf-events .waf-exclusion-form > .alert {
    margin: 0;
}

.waf-exclusion-form .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.waf-exclusion-form .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

@media (max-width: 768px) {
    .waf-exclusion-form .form-row {
        flex-direction: column;
        gap: 0;
    }

    .waf-exclusion-form .form-row > .form-group {
        flex: 0 0 auto;
    }
}

.waf-events tr:not(.history-details-row) > td:first-child {
    white-space: nowrap;
}

.site-config-section {
    padding: 0.85rem 1rem;
    background: var(--bg-secondary);
    border-radius: var(--border-radius-lg);
}

.site-config-section-title {
    margin-bottom: 0.6rem;
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.site-config-empty {
    margin: 0 0 0.6rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.site-config-override {
    margin-top: 1rem;
    margin-bottom: 0;
}

@media (max-width: 768px) {
    .site-config-panel {
        gap: 0.75rem;
        padding: 0.75rem;
    }

    .site-config-section {
        padding: 0.75rem;
    }

    .site-agent-row {
        flex-wrap: wrap;
    }

    .site-agent-status {
        flex-basis: 100%;
    }
}

.agent-status-inline {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    white-space: nowrap;
}

.site-context-badge {
    background: var(--primary-color);
    color: #fff;
    align-self: center;
}

.global-badge {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    align-self: center;
    margin-left: 0.5rem;
}

.status-badge.status-neutral {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}

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

.site-name-cell,
.inline-name-cell {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.site-name-edit-btn,
.inline-name-edit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.2rem;
    background: transparent;
    border: none;
    border-radius: 4px;
    color: var(--text-muted);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}

.site-name-edit-btn:hover,
.inline-name-edit-btn:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
}

.site-name-edit-btn svg,
.inline-name-edit-btn svg {
    width: 15px;
    height: 15px;
}

.site-name-edit,
.inline-name-edit {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.site-name-edit .form-control,
.inline-name-edit .form-control {
    width: auto;
    min-width: 8rem;
    max-width: 14rem;
}

/* Save and Cancel travel together: in a table cell there is rarely room for the field and both
   buttons, and wrapping them one at a time left Cancel stranded on its own line. */
.inline-name-edit-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* The name's own bottom margin moves to the wrapper, so the pencil centers on the text rather
   than on text plus margin. Block-level flex, so it takes the heading's place in the layout. */
.identity-name-cell {
    display: flex;
    margin-bottom: 2px;
}

.identity-name-cell > .identity-name {
    margin: 0;
}

.inline-name-edit-btn.inline-edit-save:hover {
    color: var(--success-color);
}

.inline-name-edit-btn.inline-edit-cancel:hover {
    color: var(--danger-color);
}

/* Beside small text such as a meta line: the pencil, check, and X are sized in em off that text,
   and the field shrinks to the same line. */
.inline-edit-compact {
    gap: 0.25rem;
}

.inline-edit-compact .inline-name-edit-btn {
    padding: 0.1rem;
}

.inline-edit-compact .inline-name-edit-btn svg {
    width: 1.15em;
    height: 1.15em;
}

.inline-name-edit.inline-edit-compact .form-control {
    width: 9.5rem;
    min-width: 0;
    padding: 0.1rem 0.4rem;
    font: inherit;
}

/* Sits on the edited value's line, sized off its text, not as a block under it. */
.form-error.inline-edit-error,
.form-help.inline-edit-notice {
    display: inline;
    margin: 0;
    font-family: var(--font-sans);
    font-size: 0.85em;
    align-self: center;
}

/* Client Stats: the IP's font lives on .client-ip, which edit mode removes, so the wrapper carries it. */
.client-info-main .inline-edit-compact {
    font-size: 0.875rem;
    font-family: monospace;
}

.checkbox-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    cursor: pointer;
}

.checkbox-toggle input {
    margin-top: 0.2rem;
    flex-shrink: 0;
}

.checkbox-toggle > span {
    flex: 1;
    min-width: 0;
    line-height: 1.5;
}

.form-hint {
    margin-top: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    line-height: 1.5;
}

.site-wizard {
    padding: 1rem 1.25rem 1.25rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
}

.site-wizard-steps {
    display: flex;
    margin-bottom: 1.25rem;
    user-select: none;
    cursor: default;
}

.site-wizard-step {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    text-align: center;
}

.site-wizard-step:not(:first-child)::before {
    content: "";
    position: absolute;
    top: 0.8rem;
    right: 50%;
    left: -50%;
    height: 2px;
    background: var(--border-color);
}

.site-wizard-step.current:not(:first-child)::before,
.site-wizard-step.done:not(:first-child)::before {
    background: var(--primary-color);
}

.site-wizard-step-node {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.7rem;
    height: 1.7rem;
    border-radius: 50%;
    background: var(--bg-secondary);
    border: 2px solid var(--border-color);
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 600;
}

.site-wizard-step.current .site-wizard-step-node {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--text-primary);
}

.site-wizard-step.done .site-wizard-step-node {
    background: var(--success-color);
    border-color: var(--success-color);
    color: var(--text-primary);
}

.site-wizard-step-label {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.site-wizard-step.current .site-wizard-step-label {
    color: var(--text-primary);
}

.site-wizard-step.done .site-wizard-step-label {
    color: var(--text-secondary);
}

.site-wizard-title {
    margin: 0 0 0.75rem;
    color: var(--text-primary);
    font-size: 1.05rem;
    font-weight: 600;
}

.site-wizard-success {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.site-wizard-success-icon {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--success-color);
    color: var(--text-primary);
    font-size: 1.15rem;
    font-weight: 700;
}

.site-wizard-success .site-wizard-title {
    margin-bottom: 0.25rem;
}

.site-wizard-agent-wait {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

@media (max-width: 768px) {
    .site-wizard {
        padding: 0.85rem;
    }

    .site-wizard-step-label {
        font-size: 0.7rem;
    }
}

.site-wizard .action-buttons {
    margin-top: 1.25rem;
}

.card .card .site-wizard .btn-secondary,
.card .card .site-wizard .btn-ghost,
.site-wizard .btn-secondary,
.site-wizard .btn-ghost {
    background: var(--bg-elevated);
}

.card .card .site-wizard .btn-secondary:hover:not(:disabled),
.card .card .site-wizard .btn-ghost:hover:not(:disabled),
.site-wizard .btn-secondary:hover:not(:disabled),
.site-wizard .btn-ghost:hover:not(:disabled) {
    background: var(--btn-map-hover);
}

.site-wizard pre {
    background: var(--bg-primary);
    padding: 0.75rem;
    border-radius: 6px;
    font-size: 0.8125rem;
    overflow-x: auto;
}

.form-error {
    color: var(--danger-color);
    margin-top: 0.5rem;
    font-size: 0.85rem;
}

.site-card-agents {
    margin-left: auto;
    color: var(--text-secondary);
}

.connection-banner.license-restricted-banner {
    background: var(--danger-color);
}

.license-key-cell {
    font-family: monospace;
}

.license-check-error {
    font-size: 0.8125rem;
}

.license-section-title {
    color: var(--text-primary);
    margin: 1.25rem 0 0.5rem;
}

.license-site-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--bg-tertiary);
}

.license-site-name {
    flex: 1;
    min-width: 0;
}

.license-site-name strong {
    font-size: 0.9rem;
    color: var(--text-primary);
}

.license-site-name span {
    font-size: 0.85rem;
    color: var(--text-muted);
}

.license-site-select {
    width: 100%;
    max-width: 600px;
}

.license-activate-actions {
    margin-top: -0.5rem;
    margin-bottom: 0.5rem;
}

.license-refresh-actions {
    margin-top: 1rem;
    margin-bottom: 0.5rem;
}

@keyframes tour-fade-in {
    from {
        opacity: 0;
    }
}

@keyframes tour-rise-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
}

.tour-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 1060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: tour-fade-in 0.2s ease;
}

.tour-modal {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    max-width: 480px;
    width: 100%;
    padding: 24px;
    animation: tour-rise-in 0.25s ease;
}

.tour-modal-title {
    margin: 0 0 8px;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text-primary);
}

.tour-modal-summary {
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.45;
    margin: 0 0 12px;
}

.tour-modal-steps {
    margin: 0 0 12px;
    padding-left: 20px;
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.5;
}

.tour-modal-steps li {
    margin: 2px 0;
    font-size: 0.85rem;
}

.tour-modal-meta {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin: 0 0 16px;
}

.tour-modal-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.tour-modal-optout {
    margin-left: auto;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.85rem;
    padding: 4px;
}

.tour-modal-optout:hover {
    color: var(--text-secondary);
    text-decoration: underline;
}

.tour-overlay {
    position: fixed;
    inset: 0;
    z-index: 1060;
    pointer-events: none;
}

.tour-hole {
    position: fixed;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0);
    border-radius: 8px;
    border: 2px solid transparent;
    transition: left 0.25s ease, top 0.25s ease, width 0.25s ease, height 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
    pointer-events: none;
}

.tour-overlay-on .tour-hole {
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.6);
    border-color: var(--primary-hover);
}

.tour-overlay-clear .tour-hole {
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0);
    border-color: transparent;
}

.tour-card {
    position: fixed;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 16px;
    width: 320px;
    max-width: calc(100vw - 20px);
    pointer-events: auto;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.tour-overlay-on .tour-card {
    opacity: 1;
    transform: none;
}

.tour-card-progress {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    color: var(--text-muted);
    font-size: 0.75rem;
    margin-bottom: 6px;
}

.tour-card-title {
    color: var(--text-primary);
    font-weight: 600;
    margin-bottom: 6px;
}

.tour-card-body {
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.45;
    margin-bottom: 14px;
}

.tour-card-para {
    margin: 0 0 8px;
}

.tour-card-para:last-child {
    margin-bottom: 0;
}

.tour-card-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.tour-card-spacer {
    flex: 1;
}

.tour-card-skip {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.85rem;
    padding: 4px 0;
}

.tour-card-skip:hover {
    color: var(--text-secondary);
    text-decoration: underline;
}

@media (max-width: 768px) {
    .tour-card {
        width: 280px;
    }
}

.tour-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.tour-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-tertiary);
    border-radius: 6px;
}

.tour-list-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.tour-list-title {
    color: var(--text-primary);
    font-weight: 500;
}

.tour-list-status {
    color: var(--text-muted);
    font-size: 0.8rem;
}

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

.tour-badge {
    font-size: 0.7rem;
    font-weight: 600;
    padding: 1px 7px;
    border-radius: 9px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.tour-badge-new {
    color: var(--info-color);
    background: rgba(71, 151, 255, 0.15);
}

.tour-badge-improved {
    color: var(--success-color);
    background: rgba(36, 188, 112, 0.15);
}

.tour-modal-steps .tour-badge {
    margin-left: 6px;
}

.tour-card-body strong {
    color: var(--text-primary);
    font-weight: 600;
}

.identity-loading {
    display: flex;
    justify-content: center;
    padding: 1.5rem 0;
}

.identity-user {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.identity-user-name {
    font-weight: 500;
    color: var(--text-primary);
}

.identity-user-display {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

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

.identity-lock {
    display: inline-flex;
}

.identity-role-select {
    min-width: 7.5rem;
    padding: 0.35rem 0.5rem;
}

.identity-role-cell {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

/* Lines up with the text inside the picker on the rows that have one. */
.identity-role-text {
    margin-left: 0.5rem;
}

.identity-credentials,
.identity-row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.identity-row-actions {
    justify-content: flex-end;
}

.identity-actions-col {
    text-align: right;
    white-space: nowrap;
}

.identity-inline-row > td {
    background: var(--bg-tertiary);
}

.identity-inline-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0.25rem 0;
}

.identity-inline-title {
    margin: 0;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.gate-refusal p {
    margin: 0.5rem 0 0.75rem 0;
}

.identity-roles-heading {
    margin-top: 1.25rem;
    margin-bottom: 0.5rem;
}

.identity-roles-footnote {
    margin-top: 0.75rem;
}

.identity-role-name {
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
}

.identity-role-mark {
    text-align: center;
    white-space: nowrap;
}

.identity-section-title {
    margin: 1.75rem 0 0.75rem;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.identity-subsection-title {
    margin: 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.identity-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 0.75rem 1rem;
}

/* The grid already spaces its rows, so .form-group's own 1.5rem stacked on top of the gap. */
.identity-form-grid .form-group {
    margin-bottom: 1rem;
}

.identity-mfa-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
}

.identity-form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.identity-add-form {
    margin-top: 1rem;
    padding: 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-tertiary);
}

.identity-card-actions {
    justify-content: flex-end;
    margin-top: 1rem;
}

.identity-managed-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* Both are grids on the LIST with each row's cells promoted into it, so columns line up across rows
   instead of every row sizing itself. They differ in how many columns they have, which is why they
   cannot share one rule: a link row is provider / subject / action. */
.identity-link-list,
.identity-url-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    align-items: center;
    gap: 0.4rem 0.75rem;
}

.identity-url-list {
    grid-template-columns: max-content 1fr;
}

.identity-link-list {
    grid-template-columns: max-content 1fr max-content;
}

/* The two sub-cards sit one above the other: what is linked, then how to link another. */
.identity-link-add {
    margin-top: 0.75rem;
}

.identity-link-item,
.identity-url-item {
    display: contents;
}

.identity-link-provider,
.identity-url-label {
    font-weight: 500;
    color: var(--text-primary);
    font-size: 0.85rem;
}

.identity-link-subject,
.identity-url-value {
    color: var(--text-secondary);
    word-break: break-all;
}

/* The URL sits beside its label in a flex row, so the copy block takes the rest of the line rather
   than collapsing to its content. */
.identity-url-item .code-copy-block {
    min-width: 0;
}

@media (max-width: 768px) {
    .account-recovery-codes code {
        font-size: 0.85rem;
    }

    .identity-row-actions {
        flex-direction: column;
        align-items: stretch;
    }

    .identity-row-actions > *,
    .identity-lock > .btn {
        width: 100%;
    }

    .identity-actions-col {
        text-align: left;
        white-space: normal;
    }

    .identity-card-actions {
        flex-direction: column;
        align-items: stretch;
    }

    .identity-card-actions .btn {
        width: 100%;
    }

    /* One column on a phone: three columns of provider, subject and action leave nothing readable,
       and the subject is a long opaque identifier. Each cell takes its own line instead. */
    .identity-link-list,
    .identity-url-list {
        grid-template-columns: 1fr;
        gap: 0.25rem;
    }

    .identity-link-item,
    .identity-url-item {
        padding-bottom: 0.5rem;
    }
}

.audit-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.audit-filter-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

/* An icon, not a button: it sits among the filter inputs to save the width a labelled control
   would take, so it carries no button chrome. */
.audit-filter-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
}

.audit-filter-clear:hover {
    color: var(--text-secondary);
}

.audit-pager {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1rem;
}

@media (max-width: 768px) {
    .audit-filter-actions {
        margin-left: 0;
    }
}

/* ---- Firmware Rollout ---- */

.firmware-rollout-timeline {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
    margin-bottom: 1.25rem;
}

.firmware-rollout-legend {
    position: absolute;
    right: 0.75rem;
    bottom: 0.75rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.17rem;
    padding: 0.27rem 0.4rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    font-size: 0.55rem;
    color: var(--text-muted);
    pointer-events: none;
}

.firmware-rollout-legend-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.57rem;
}

.firmware-rollout-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.23rem;
}

.firmware-rollout-legend-dot {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
}

.firmware-rollout-legend-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    padding-top: 0.04rem;
    width: 0.74rem;
    height: 0.74rem;
    border-radius: 50%;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    font-size: 0.44rem;
    font-weight: 600;
}

.firmware-rollout-track {
    position: relative;
    flex: 1;
    min-width: 200px;
    height: 14px;
    background: var(--bg-tertiary);
    border-radius: 7px;
    cursor: pointer;
    touch-action: none;
}

.firmware-rollout-wave-seg {
    position: absolute;
    top: 2px;
    bottom: 2px;
    background: var(--info-color);
    opacity: 0.65;
    border-radius: 5px;
    min-width: 4px;
}

.firmware-rollout-console-seg {
    background: var(--primary-hover);
    opacity: 0.8;
}

.firmware-rollout-playhead {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 2px;
    background: var(--primary-hover);
    border-radius: 1px;
    pointer-events: none;
}

.firmware-rollout-timeline-readout {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--text-secondary);
    min-width: 6.5rem;
    text-align: right;
}

.firmware-rollout-timeline-clock {
    color: var(--text-primary);
    font-weight: 600;
}

.firmware-rollout-timeline-clock:empty {
    display: none;
}

.firmware-rollout-playhead-label {
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .firmware-rollout-legend {
        display: none;
    }

    .firmware-rollout-timeline {
        gap: 0.5rem;
        flex-wrap: wrap;
    }

    .firmware-rollout-timeline-readout {
        flex-basis: 100%;
        flex-direction: row;
        justify-content: flex-end;
        align-items: baseline;
        gap: 0.4rem;
        min-width: 0;
    }
}

.firmware-rollout-map-waiting {
    display: flex;
    align-items: center;
    justify-content: center;
}

.firmware-rollout-map-waiting .empty-state p:last-child {
    margin-bottom: 0;
}

.firmware-rollout-map-fs.lan-flow-map-fullscreen {
    display: flex;
    flex-direction: column;
    padding: 0.75rem;
    gap: 0.5rem;
}

.firmware-rollout-map-fs.lan-flow-map-fullscreen .firmware-rollout-map-stage {
    flex: 1;
    height: auto;
    min-height: 0;
}

.firmware-rollout-map-stage {
    /* The map positions its own tooltip and panels against this box. */
    position: relative;
    width: 100%;
    height: 420px;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    overflow: hidden;
}

.firmware-rollout-landing {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.firmware-rollout-landing .firmware-rollout-note {
    margin: 0;
}

.firmware-rollout-landing .btn,
.firmware-rollout-landing .firmware-rollout-controls {
    flex-shrink: 0;
}

.firmware-rollout-autopilot-config,
.firmware-rollout-add-url {
    padding-top: 0;
}

.firmware-rollout-add-url .setup-guide {
    margin-top: 0.5rem;
}

.firmware-rollout-config-title {
    margin-bottom: 0.25rem;
}

.firmware-rollout-config-intro {
    display: block;
    margin-bottom: 1rem;
}

.firmware-rollout-config-save {
    margin-top: 1.5rem;
    justify-content: flex-end;
}

@media (max-width: 768px) {
    .firmware-rollout-console-verb {
        display: none;
    }

    .firmware-rollout-landing {
        flex-direction: column;
        align-items: flex-start;
        padding-top: 0.25rem;
    }

    .firmware-rollout-autopilot-config {
        margin-top: 1rem;
    }
}

.firmware-rollout-controls {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
}

/* Anchors the Set Time popover (the shared Custom Range popover) under its button. */
.firmware-rollout-set-time {
    position: relative;
}

/* Narrow screens: under the button it would run off the left edge, so it hangs from the row's right. */
@media (max-width: 768px) {
    .firmware-rollout-controls:has(.firmware-rollout-set-time) {
        position: relative;
    }

    .firmware-rollout-set-time {
        position: static;
    }
}

.firmware-rollout-deploy-now {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    justify-content: flex-end;
    margin-top: 1rem;
}

.firmware-rollout-deploy-now .firmware-rollout-note {
    margin: 0 0.5rem 0 0;
}

.firmware-rollout-note {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0.5rem 0 1.5rem;
}

.firmware-rollout-drift-note {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.firmware-rollout-plan-note {
    color: var(--text-muted);
    font-size: 0.85rem;
    margin: 0.25rem 0 0.75rem;
}

/* Pulled up under the schedule line: its 1.5rem bottom margin is sized for the map, not a note. */
.firmware-rollout-note + .firmware-rollout-plan-note {
    margin-top: -0.75rem;
}

.firmware-rollout-chip {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 10px;
    font-size: 0.78rem;
    white-space: nowrap;
}

.firmware-rollout-chip.chip-success { background: rgba(36, 188, 112, 0.15); color: var(--success-color); }
.firmware-rollout-chip.chip-danger { background: rgba(238, 99, 104, 0.15); color: var(--danger-color); }
.firmware-rollout-chip.chip-warning { background: rgba(231, 150, 19, 0.15); color: var(--warning-color); }
.firmware-rollout-chip.chip-active { background: rgba(71, 151, 255, 0.15); color: var(--info-color); }
.firmware-rollout-chip.chip-muted { background: var(--bg-tertiary); color: var(--text-secondary); }

.firmware-rollout-expander {
    border: 1px solid var(--border-color);
    border-radius: 8px;
    margin: 0.6rem 0;
}

.firmware-rollout-expander > summary {
    padding: 0.6rem 0.85rem;
    cursor: pointer;
    color: var(--text-secondary);
    user-select: none;
}

.firmware-rollout-expander[open] > summary {
    border-bottom: 1px solid var(--border-color);
    color: var(--text-primary);
}

.firmware-rollout-expander-body {
    padding: 0.75rem 0.85rem;
}

.firmware-rollout-expander-body .checkbox-label,
.firmware-rollout-expander-body .radio-label,
.form-group > .checkbox-label,
.form-group > .radio-label {
    padding: 0.25rem 0;
}

/* Exclusions read as removals, so the mark is a red X rather than a check. */
.firmware-rollout-exclude input[type="checkbox"] {
    appearance: none;
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    display: inline-grid;
    place-content: center;
    border: 1px solid var(--border-color);
    border-radius: 3px;
    background: var(--bg-secondary);
    cursor: pointer;
}

.firmware-rollout-exclude input[type="checkbox"]::before {
    content: "\2715";
    font-size: 0.7rem;
    line-height: 1;
    color: var(--danger-color);
    visibility: hidden;
}

.firmware-rollout-exclude input[type="checkbox"]:checked {
    border-color: var(--danger-color);
}

.firmware-rollout-exclude input[type="checkbox"]:checked::before {
    visibility: visible;
}

.firmware-rollout-exclude input[type="checkbox"]:disabled {
    cursor: default;
    opacity: 0.7;
}

.firmware-rollout-device-row {
    width: 100%;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border-color);
}

.firmware-rollout-device-row:last-child {
    border-bottom: none;
}

.firmware-rollout-guide .setup-guide-content {
    margin-top: 0.5rem;
    animation: firmware-rollout-expand 0.25s ease-out;
}

/* A native details element hides its content when closed, so the grid-height
   transition the Blazor-toggled panels use has nothing to animate here. */
@keyframes firmware-rollout-expand {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .firmware-rollout-guide .setup-guide-content {
        animation: none;
    }
}

.firmware-rollout-guide .setup-guide-content > .form-group.firmware-rollout-inline:last-child,
.firmware-rollout-add-url .setup-guide-content > .form-group:last-child {
    margin-bottom: 0.5rem;
}

@media (min-width: 769px) {
    .firmware-rollout-add-url .action-buttons {
        justify-content: flex-end;
    }
}

/* Deploy Known Firmware sits right under it. */
.firmware-rollout-add-url:not(.firmware-rollout-known) {
    padding-bottom: 8px;
}

.firmware-rollout-known .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.firmware-rollout-known .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

@media (max-width: 768px) {
    .firmware-rollout-known .form-row {
        flex-direction: column;
        gap: 0;
    }

    .firmware-rollout-known .form-row > .form-group {
        flex: 0 0 auto;
    }
}

.firmware-rollout-known option.firmware-rollout-known-older {
    color: var(--text-muted);
}

.firmware-rollout-muted {
    color: var(--text-muted);
    font-size: 0.8rem;
}

.firmware-rollout-inline {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.firmware-rollout-inline .form-label {
    margin: 0;
    min-width: 170px;
}

.firmware-rollout-select {
    max-width: 240px;
}

.firmware-rollout-num {
    max-width: 90px;
}

.firmware-rollout-mode-row {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.firmware-rollout-slider {
    width: 100%;
}

.firmware-rollout-slider-labels {
    display: flex;
    justify-content: space-between;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.firmware-rollout-exclusion-groups {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.firmware-rollout-exclusion-list {
    border-top: 1px solid var(--border-color);
    padding-top: 0.5rem;
}

.firmware-rollout-sku-btn {
    margin-left: auto;
}

.firmware-rollout-wizard-nav {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 1rem;
}

.firmware-rollout-wizard-nav > :only-child {
    margin-left: auto;
}

.firmware-rollout-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 2rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--border-radius-lg);
}

.firmware-rollout-stat {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.firmware-rollout-stat .detail-value {
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.2;
}

.firmware-rollout-stat .detail-label {
    font-size: 0.825rem;
    color: var(--text-muted);
}

.firmware-rollout-waves {
    margin-top: 0.75rem;
    margin-bottom: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.firmware-rollout-wave {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.35rem 0.5rem;
    background: var(--bg-tertiary);
    border-radius: 6px;
}

.firmware-rollout-wave-no {
    min-width: 1.6rem;
    text-align: center;
    font-weight: 600;
    color: var(--text-secondary);
}

.firmware-rollout-wave-eta {
    min-width: 4.5rem;
    color: var(--text-muted);
    font-size: 0.8rem;
}

.firmware-rollout-wave-devices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.85rem;
}

.firmware-rollout-wave-device {
    color: var(--text-primary);
    font-size: 0.85rem;
}

/* Device waves: one device per line, its Exclude button on the right. */
.firmware-rollout-wave-devices-rows {
    flex: 1;
    flex-direction: column;
    min-width: 0;
}

.firmware-rollout-wave-device-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.firmware-rollout-wave-device-row > span {
    min-width: 0;
}

.firmware-rollout-wave-device-row > .btn {
    flex-shrink: 0;
}

.firmware-rollout-version-badge {
    margin-left: 0.4rem;
    text-decoration: none;
}

a.firmware-rollout-version-badge:hover {
    color: var(--text-primary);
}

.firmware-rollout-steps {
    margin-top: 0.75rem;
}

@media (max-width: 768px) {
    .firmware-rollout-map-stage {
        height: 320px;
    }

    .firmware-rollout-inline {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }

    .firmware-rollout-inline .form-label {
        min-width: 0;
    }

    .firmware-rollout-stats {
        gap: 1rem;
    }
}

/* ===== MLO per-link breakdown (Wi-Fi Optimizer Client Stats + Client Performance) ===== */

.mlo-links {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    flex-basis: 100%;
}

.mlo-link-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.375rem 0.75rem;
    font-size: 0.8125rem;
    color: var(--text-primary);
}

.mlo-link-row .band-badge {
    min-width: 54px;
    text-align: center;
}

.mlo-link-meta {
    color: var(--text-secondary);
}

/* Idle link signals are muted, not signal-graded, so a parked -95 dBm link
   cannot read as a failing client. */
.mlo-link-idle .mlo-link-meta,
.mlo-link-idle .mlo-link-signal-muted {
    color: var(--text-muted);
}

.mlo-dim {
    opacity: 0.6;
}

.mlo-state {
    padding: 0.125rem 0.5rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
}

.mlo-state.mlo-state-active {
    background: rgba(36, 188, 112, 0.2);
    color: var(--success-color);
}

.mlo-state.mlo-state-idle {
    background: rgba(100, 116, 139, 0.2);
    color: var(--text-muted);
}

/* Segmented multi-band pill: one compound badge, since the single-band
   .band-badge cannot express several bands in one chip. */
.mlo-pill {
    display: inline-flex;
    align-items: stretch;
    border-radius: 3px;
    overflow: hidden;
    font-size: 0.7rem;
    font-weight: 500;
}

.mlo-pill-label {
    padding: 0.125rem 0.4rem;
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}

.mlo-pill-seg {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0.125rem 0.4rem;
}

.mlo-pill-seg.band-2ghz {
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}

.mlo-pill-seg.band-5ghz {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
}

.mlo-pill-seg.band-6ghz {
    background: rgba(168, 85, 247, 0.15);
    color: #a855f7;
}

.mlo-pill-seg.mlo-seg-idle {
    opacity: 0.45;
}

.mlo-seg-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
}

/* ============================================
   Settings - AP Telemetry (AP Agent fleet)
   ============================================ */

/* Muted second line under a status, name, or version: the cause or the next step. */
.ap-agent-note {
    display: block;
    color: var(--text-muted);
    font-size: 0.75rem;
    margin-top: 0.15rem;
    white-space: normal;
}

/* Fixed layout for the same reason as .sites-table: the expanded panel row spans every column, so
   under auto layout its content would resize the headers the moment it appears. */
.ap-agent-table {
    table-layout: fixed;
}

.ap-agent-table th:nth-child(1) { width: 20%; }
.ap-agent-table th:nth-child(2) { width: 15%; }
.ap-agent-table th:nth-child(3) { width: 27%; }
.ap-agent-table th:nth-child(4) { width: 12%; }
.ap-agent-table th:nth-child(5) { width: 26%; }

/* Inset panel for the expanded capability report row; data-table cells have their own padding. */
.ap-agent-cap-panel {
    background: var(--bg-inset);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 1rem;
    margin: 0.25rem 0;
}

.ap-agent-cap-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 0.15rem;
}

.ap-agent-cap-list {
    margin: 0.75rem 0 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.5rem 2rem;
}

.ap-agent-cap-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.8125rem;
}

.ap-agent-cap-row .status-dot {
    flex-shrink: 0;
    position: relative;
    top: -1px;
}

.ap-agent-cap-name {
    color: var(--text-primary);
}

.ap-agent-cap-row.cap-unavailable .ap-agent-cap-name {
    color: var(--text-secondary);
}

.ap-agent-cap-src {
    color: var(--text-muted);
    font-size: 0.75rem;
    font-family: var(--font-mono);
    margin-left: auto;
}

/* Bordered footer inside the panel: the opt-out toggle at the start, actions at the end. */
.ap-agent-cap-footer {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.ap-agent-cap-footer .checkbox-toggle {
    margin-right: auto;
}

@media (max-width: 768px) {
    .table-responsive:has(> .ap-agent-table) {
        margin: 0 -0.25rem;
    }

    /* Same two-line phone layout as .sites-table: an AP's name and status, then its buttons across
       the full width, with the header, the fixed layout, and the 500px floor all stopped. */
    .ap-agent-table,
    .ap-agent-table > tbody,
    .ap-agent-table > tbody > tr.site-config-row,
    .ap-agent-table > tbody > tr.site-config-row > td {
        display: block;
        min-width: 0;
    }

    .ap-agent-table > thead {
        display: none;
    }

    .ap-agent-table > tbody > tr:not(.site-config-row) {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        border-bottom: 1px solid var(--border-color);
    }

    .ap-agent-table > tbody > tr:not(.site-config-row) > td {
        padding: 0.75rem 0.5rem;
        border-bottom: 0;
    }

    .ap-agent-table > tbody > tr:not(.site-config-row) > td:not(:last-child) {
        flex: 1 1 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }

    /* The status cell carries the explanatory note, so it takes twice the name's share. */
    .ap-agent-table > tbody > tr:not(.site-config-row) > td:nth-child(3) {
        flex: 2 1 0;
    }

    .ap-agent-table > tbody > tr:not(.site-config-row) > td:last-child {
        flex-basis: 100%;
        padding-top: 0;
    }
}

.ap-agent-guide .setup-guide-content {
    font-size: 0.825rem;
}

.ap-agent-actions {
    margin-bottom: 1rem;
}

.setup-guide-summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    cursor: pointer;
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.setup-guide-summary .site-row-caret {
    margin-left: 0;
    padding-left: 0;
}

/* Button that sizes to its label rather than the .btn 6rem floor, keeping roomy padding while the
   row has space and tightening when it does not. For a control sharing a row with content it must
   not push, where .btn-sm alone still holds the 6rem minimum. */
.btn-fit {
    min-width: auto;
    padding-inline: 1.25rem;
}

/* Stepped, not scaled. The devices either side of this sit 37px apart, so a vw scale cannot give one
   comfortable padding and the other a tight fit. Above 420 the row has room; at or below it the row
   needs that space back to stay on one line. */
@media (max-width: 420px) {
    .btn-fit {
        padding-inline: 0.5rem;
    }
}

/* With the nav hidden the row runs full width, so the space it gave up can come back. The narrow
   case needs it most; a wider phone only wants a touch. */
body:has(.top-bar-hidden) .btn-fit {
    padding-inline: 1.375rem;
}

@media (max-width: 420px) {
    body:has(.top-bar-hidden) .btn-fit {
        padding-inline: 0.875rem;
    }
}

/* Bandwidth Hogs (Monitoring - Live View) */
.bandwidth-hogs-card .card-header {
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
}

.bandwidth-hogs-controls {
    flex-wrap: wrap;
    gap: 0.5rem;
}

.bandwidth-hogs-controls .time-btn {
    white-space: nowrap;
}

.bandwidth-hogs-window {
    width: max-content;
    max-width: 100%;
    margin-bottom: 0.75rem;
}

.bandwidth-hogs-wan-line {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.75rem;
    margin-bottom: 0.75rem;
    font-size: 0.9rem;
}

.bandwidth-hogs-wan-line .hogs-wan-detail {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

/* Down and up side by side, each with its rate at the left and "of 1 Gbps down" against its right
   edge: a fixed width on desktop, half the line each on a phone. */
.bandwidth-hogs-wan-line .hogs-wan-pair {
    display: flex;
    gap: 1.5rem;
    font-variant-numeric: tabular-nums;
}

.bandwidth-hogs-wan-line .hogs-wan-half {
    display: flex;
    justify-content: space-between;
    gap: 0.4rem;
    /* Wide enough for "999.9 Mbps" and "of 10 Gbps down", no wider, so the capacity stays by its rate. */
    width: 11.5rem;
    max-width: 11.5rem;
    min-width: 0;
    white-space: nowrap;
}

.bandwidth-hogs-wan-line .hogs-wan-of {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 768px) {
    .bandwidth-hogs-wan-line .hogs-wan-pair {
        flex: 1 1 100%;
        min-width: 0;
        gap: 1rem;
    }

    .bandwidth-hogs-wan-line .hogs-wan-half {
        width: auto;
        flex: 1 1 0;
    }

    /* The colors say which is which; the words do not fit beside two rates at half width. */
    .bandwidth-hogs-wan-line .hogs-wan-dir {
        display: none;
    }
}

/* Fixed proportions: the rates re-render every few seconds, and an auto-laid table let each
   new figure nudge its column. Digits are tabular for the same reason. */
.bandwidth-hogs-table {
    min-width: 0;
    table-layout: fixed;
    width: 100%;
    font-variant-numeric: tabular-nums;
}

.bandwidth-hogs-table th,
.bandwidth-hogs-table td {
    padding: 0.5rem 0.75rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.hogs-warmup {
    padding: 0.75rem 1rem;
    border-radius: var(--border-radius);
    margin-bottom: 1rem;
    font-size: 0.85rem;
}

.hogs-agent-notice {
    margin-bottom: 1rem;
}

/* Holds the collapsed five-row list's footprint while an answer loads, spinner centered,
   so a view or window switch doesn't collapse the card and jump the page. */
.hogs-loading {
    min-height: 240px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hogs-show-more {
    margin-top: 0.5rem;
}

.hogs-show-more-hidden {
    visibility: hidden;
}

.bandwidth-hogs-table .hogs-col-rank { width: 3.6rem; }
.bandwidth-hogs-table .hogs-col-via { width: 26%; }
.bandwidth-hogs-table .hogs-col-rate { width: 14%; }
.bandwidth-hogs-table .hogs-col-share { width: 17%; }

.bandwidth-hogs-table .hogs-rank {
    color: var(--text-muted);
    white-space: nowrap;
}

.bandwidth-hogs-table .hogs-chev-mobile {
    display: none;
}

@media (max-width: 768px) {
    .bandwidth-hogs-table .hogs-chev-mobile {
        display: inline-block;
    }
}

.bandwidth-hogs-table .hogs-client a {
    color: var(--text-primary);
    text-decoration: none;
}

.bandwidth-hogs-table .hogs-client a:hover {
    color: var(--primary-color);
}

.bandwidth-hogs-table .hogs-via {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.bandwidth-hogs-table .hogs-via .band-badge {
    margin-right: 0.4rem;
}

.band-badge.hogs-port-badge {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}

.bandwidth-hogs-table tr.hogs-fading td {
    opacity: 0.55;
}

.bandwidth-hogs-table .hogs-sub {
    display: block;
    color: var(--text-muted);
    font-size: 0.75rem;
}

.hogs-share {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.hogs-share .hogs-bar {
    display: block;
    width: 80px;
    height: 6px;
    border-radius: 0 3px 3px 0;
    background: var(--bg-tertiary);
    overflow: hidden;
}

.hogs-share .hogs-fill {
    display: block;
    height: 100%;
    border-radius: 0 3px 3px 0;
    background: var(--speed-download-color);
}

@media (max-width: 768px) {
    .bandwidth-hogs-controls {
        margin-left: 0;
    }

    .bandwidth-hogs-table th,
    .bandwidth-hogs-table td {
        padding: 0.5rem 0.4rem;
    }

    .bandwidth-hogs-table .hogs-col-rate { width: 25%; }
    .bandwidth-hogs-table .hogs-col-share { width: 16%; }

    .hogs-share .hogs-bar {
        display: none;
    }
}

/* ============================================
   Filter pills: a value in a table that filters the page on click (RF Environment's Heard By,
   Live Traffic). .active is the kept value and carries a .filter-pill-x.
   ============================================ */

.filter-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.filter-pill {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    min-width: 0;
    padding: 0.125rem 0.5rem;
    border: 1px solid transparent;
    border-radius: var(--border-radius);
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.8rem;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.filter-pill:hover {
    color: var(--text-primary);
    border-color: var(--primary-hover);
}

.filter-pill.active {
    background: var(--primary-color);
    color: var(--text-primary);
    font-weight: 600;
}

.filter-pill-text {
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-pill-x {
    margin-left: 0.3rem;
    opacity: 0.8;
}

.filter-pill-more {
    background: transparent;
    color: var(--text-muted);
}

/* ============================================
   Live Traffic (Monitoring - Live View card + /monitoring/live-traffic).
   lt- classes are this feature's own; nothing else uses the prefix.
   ============================================ */

/* On a phone the header controls wrap under the description: even space above and below them. */
@media (max-width: 768px) {
    /* The description's line height already leaves space above, and the cards' padding below. */
    .live-traffic .page-header {
        margin-bottom: 0.6rem;
    }

    .live-traffic .page-header-actions {
        margin-top: 0.4rem;
    }
}

/* Desktop: the controls sit on the description's line, just above the cards they drive. */
@media (min-width: 769px) {
    .live-traffic .page-header-actions {
        align-self: flex-end;
    }
}

/* Detailed View: in the By row on desktop, at the right of the title on a phone. */
.bandwidth-hogs-card .lt-header-detail {
    display: none;
}

@media (max-width: 768px) {
    .bandwidth-hogs-card .card-title-group {
        flex: 1 1 100%;
    }

    .bandwidth-hogs-card .lt-header-detail {
        display: inline-flex;
        margin-left: auto;
    }

    .bandwidth-hogs-card .lt-card-tools .lt-tools-right {
        display: none;
    }
}

/* The Dashboard card's header opens Live Traffic everywhere but its controls. */
.bandwidth-hogs-card .lt-header-link {
    cursor: pointer;
}

.bandwidth-hogs-card .lt-header-link:hover .card-title {
    color: var(--primary-light);
}

.bandwidth-hogs-card .lt-header-link .bandwidth-hogs-controls {
    cursor: default;
}

/* Card: the By row and Detailed View, the expand chevron, and a client's nested flows */
.lt-card-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
}

.lt-card-tools .lt-tools-right {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.lt-by-label {
    color: var(--text-secondary);
    font-size: 0.8rem;
}

.lt-icon-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.lt-icon-btn svg {
    width: 14px;
    height: 14px;
}

@media (max-width: 768px) {
    .lt-pause-btn {
        width: 28px;
        min-width: 0;
        padding: 0;
    }

    .lt-pause-btn span {
        display: none;
    }
}

/* The app's .expand-chevron, inline beside a rank or a name instead of in its own cell. */
.lt-chev {
    display: inline-block;
    width: auto;
    margin-right: 0.35rem;
}

.bandwidth-hogs-table tr.lt-row-open td {
    background: var(--bg-hover-subtle);
}

.bandwidth-hogs-table .lt-expandable {
    cursor: pointer;
}

.bandwidth-hogs-table tr.lt-nested > td {
    padding: 0 0 0.5rem 0;
    background: var(--bg-hover-subtle);
    white-space: normal;
}

.lt-nested-table {
    width: 100%;
    table-layout: fixed;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    border-collapse: collapse;
}

.lt-nested-table td,
.lt-nested-table th {
    padding: 0.3rem 0.75rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
}

.lt-nested-table th {
    color: var(--text-muted);
    font-weight: 500;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.lt-nested-table .hogs-col-rank { width: 2.6rem; }
.lt-nested-table .hogs-col-via { width: 26%; }
.lt-nested-table .hogs-col-rate { width: 14%; }
.lt-nested-table .hogs-col-share { width: 17%; }

.lt-nested-table td:nth-child(2) {
    padding-left: 1.6rem;
}

.lt-nested-more {
    padding: 0.25rem 0.75rem 0 4.2rem;
    font-size: 0.75rem;
}

/* Any value that filters on click */
.lt-pivot {
    color: inherit;
    border-bottom: 1px dotted transparent;
    cursor: pointer;
}

.lt-pivot:hover {
    color: var(--primary-light);
    border-bottom-color: var(--primary-light);
}

.lt-muted { color: var(--text-muted); }
/* An idle live rate keeps its direction class (for its fixed slot) but reads muted. */
.speed-down.lt-muted, .speed-up.lt-muted { color: var(--text-muted); }
.lt-secondary { color: var(--text-secondary); }
.lt-small { font-size: 0.75rem; }

/* App and route tags; routes take the graph palette (WAN teal, VPN purple, LAN amber) */
.lt-tag {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
    padding: 0.1rem 0.45rem;
    border-radius: 3px;
    font-size: 0.72rem;
    font-weight: 500;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}

.lt-tag.lt-pivot:hover {
    color: var(--primary-light);
}

.lt-route-wan { background: rgba(43, 168, 154, 0.15); color: #2ba89a; }
.lt-route-vpn { background: rgba(167, 139, 250, 0.15); color: #a78bfa; }
.lt-route-lan { background: rgba(245, 158, 11, 0.15); color: #f59e0b; }
.lt-bypass { background: rgba(231, 150, 19, 0.15); color: var(--warning-color); }
.lt-redirected { background: rgba(71, 151, 255, 0.15); color: var(--info-color); }
.lt-site-dns { background: rgba(43, 168, 154, 0.15); color: #2ba89a; }
.lt-action-blocked { background: rgba(238, 99, 104, 0.15); color: var(--danger-color); }
/* App icons, drawn as Client Performance draws them (its own .app-icon rules are scoped to that page). */
.lt-app-cell {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    gap: 0.4rem;
    max-width: 100%;
    min-width: 0;
}

.lt-app-icon {
    position: relative;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* live-traffic-motion.js holds an expanded row in place itself. Left on, the browser's scroll anchoring
   corrected the same insertion as well, so the page moved twice as far and the row jumped away. */
.lt-flip,
.lt-flip * {
    overflow-anchor: none;
}

/* In Where It's Going the icon sits alone in a foreignObject, not in a flex row, so it is sized as a block. */
.lt-sankey-icon {
    overflow: visible;
    pointer-events: none;
}

.lt-sankey-icon .lt-app-icon {
    display: block;
    width: 18px;
    height: 18px;
    font-size: 11px;
}

.lt-app-icon img,
.lt-app-initial,
.lt-app-glyph {
    position: absolute;
    inset: 0;
    border-radius: 4px;
}

.lt-app-glyph {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

/* Font Awesome's .fa-solid / .fa-brands load after app.css and set display: inline-block, which drops
   the glyph to the top of its box; this selector outranks them. */
.lt-app-icon .lt-app-glyph {
    display: flex;
    line-height: 1;
}

/* A full-color app mark (our own favicon for Network Optimizer's traffic), filling the glyph box. */
.lt-app-icon .lt-app-glyph.app-mark,
.app-glyph.app-mark {
    background: var(--bg-tertiary) center / 12px no-repeat;
}

.lt-app-icon .lt-app-glyph.app-mark-netopt,
.app-glyph.app-mark.app-mark-netopt {
    background-image: url('/favicon-32x32.png');
}

/* App marks Font Awesome lacks (Simple Icons, CC0), drawn like a glyph: 1em, in the text color, so
   they sit in .lt-app-glyph and Client Performance's .app-glyph exactly as an fa-brands icon does. */
.no-icon::before {
    content: "";
    width: 1em;
    height: 1em;
    background-color: currentColor;
    -webkit-mask: var(--no-icon) no-repeat center / contain;
    mask: var(--no-icon) no-repeat center / contain;
}

.no-icon-wireguard {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.98 11.645S24.533 0 11.735 0C.418 0 .064 11.17.064 11.17S-1.6 24 11.997 24C25.04 24 23.98 11.645 23.98 11.645zM8.155 7.576c2.4-1.47 5.469-.571 6.618 1.638.218.419.246 1.063.108 1.503-.477 1.516-1.601 2.366-3.145 2.728.455-.39.817-.832.933-1.442a2.112 2.112 0 0 0-.364-1.677 2.14 2.14 0 0 0-2.465-.75c-.95.36-1.47 1.228-1.377 2.294.087.99.839 1.632 2.245 1.876-.21.111-.372.193-.53.281a5.113 5.113 0 0 0-1.644 1.43c-.143.192-.24.208-.458.075-2.827-1.729-3.009-6.067.078-7.956zM6.04 18.258c-.455.116-.895.286-1.359.438.227-1.532 2.021-2.943 3.539-2.782a3.91 3.91 0 0 0-.74 2.072c-.504.093-.98.155-1.44.272zM15.703 3.3c.448.017.898.01 1.347.02a2.324 2.324 0 0 1 .334.047 3.249 3.249 0 0 1-.34.434c-.16.15-.341.296-.573.069-.055-.055-.187-.042-.283-.044-.447-.005-.894-.02-1.34-.003a8.323 8.323 0 0 0-1.154.118c-.072.013-.178.25-.146.338.078.207.191.435.359.567.619.49 1.277.928 1.9 1.413.604.472 1.167.99 1.51 1.7.446.928.46 1.9.267 2.877-.322 1.63-1.147 2.98-2.483 3.962-.538.395-1.205.62-1.821.903-.543.25-1.1.465-1.644.712-.98.446-1.53 1.51-1.369 2.615.149 1.015 1.04 1.862 2.059 2.037 1.223.21 2.486-.586 2.785-1.83.336-1.397-.423-2.646-1.845-3.024l-.256-.066c.38-.17.708-.291 1.012-.458q.793-.437 1.558-.925c.15-.096.231-.096.36.014.977.846 1.56 1.898 1.724 3.187.27 2.135-.74 4.096-2.646 5.101-2.948 1.555-6.557-.215-7.208-3.484-.558-2.8 1.418-5.34 3.797-5.83 1.023-.211 1.958-.637 2.685-1.425.47-.508.697-.944.775-1.141a3.165 3.165 0 0 0 .217-1.158 2.71 2.71 0 0 0-.237-.992c-.248-.566-1.2-1.466-1.435-1.656l-2.24-1.754c-.079-.065-.168-.06-.36-.047-.23.016-.815.048-1.067-.018.204-.155.76-.38 1-.56-.726-.49-1.554-.314-2.315-.46.176-.328 1.046-.831 1.541-.888a7.323 7.323 0 0 0-.135-.822c-.03-.111-.154-.22-.263-.283-.262-.154-.541-.281-.843-.434a1.755 1.755 0 0 1 .906-.28 3.385 3.385 0 0 1 .908.088c.54.123.97.042 1.399-.324-.338-.136-.676-.26-1.003-.407a9.843 9.843 0 0 1-.942-.493c.85.118 1.671.437 2.54.32l.022-.118-2.018-.47c1.203-.11 2.323-.128 3.384.388.299.146.61.266.897.432.14.08.233.24.348.365.09.098.164.23.276.29.424.225.89.234 1.366.223l.01-.16c.479.15 1.017.702 1.017 1.105-.776 0-1.55-.003-2.325.004-.083 0-.165.061-.247.094.078.046.155.128.235.131z M14.703 2.153a.118.118 0 0 0-.016.19.179.179 0 0 0 .246.065c.075-.038.148-.078.238-.125-.072-.062-.13-.114-.19-.163-.106-.087-.193-.032-.278.033z'/%3E%3C/svg%3E");
}

.no-icon-ooma {
    /* Traced from Ooma's flower mark: one line, six petals, six inward loops. */
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.1 8.7L10.5 8.3L10.8 7.9L11.0 7.4L11.1 6.8L11.0 6.2L10.8 5.6L10.4 5.0L9.9 4.5L9.3 4.1L8.5 3.8L7.7 3.6L6.9 3.6L6.0 3.7L5.1 4.0L4.3 4.4L3.6 5.0L2.9 5.6L2.3 6.4L1.9 7.3L1.7 8.2L1.6 9.1L1.6 10.1L1.8 11.0L2.2 11.8L2.6 12.5L3.2 13.1L3.8 13.6L4.5 13.9L5.2 14.1L5.9 14.1L6.5 14.0L7.0 13.8L7.5 13.4L7.9 13.0L8.1 12.5L8.1 12.0L8.1 11.5L7.9 11.0L7.5 10.6L7.0 10.2L6.5 10.0L5.9 9.9L5.2 9.9L4.5 10.1L3.8 10.4L3.2 10.9L2.6 11.5L2.2 12.2L1.8 13.0L1.6 13.9L1.6 14.9L1.7 15.8L1.9 16.7L2.3 17.6L2.9 18.4L3.6 19.0L4.3 19.6L5.1 20.0L6.0 20.3L6.9 20.4L7.7 20.4L8.5 20.2L9.3 19.9L9.9 19.5L10.4 19.0L10.8 18.4L11.0 17.8L11.1 17.2L11.0 16.6L10.8 16.1L10.5 15.7L10.1 15.3L9.6 15.1L9.1 15.1L8.5 15.2L8.0 15.4L7.5 15.8L7.1 16.3L6.8 16.9L6.6 17.6L6.5 18.3L6.6 19.1L6.9 19.9L7.3 20.6L7.8 21.3L8.5 22.0L9.3 22.5L10.1 22.8L11.0 23.1L12.0 23.1L13.0 23.1L13.9 22.8L14.7 22.5L15.5 22.0L16.2 21.3L16.7 20.6L17.1 19.9L17.4 19.1L17.5 18.3L17.4 17.6L17.2 16.9L16.9 16.3L16.5 15.8L16.0 15.4L15.5 15.2L14.9 15.1L14.4 15.1L13.9 15.3L13.5 15.7L13.2 16.1L13.0 16.6L12.9 17.2L13.0 17.8L13.2 18.4L13.6 19.0L14.1 19.5L14.7 19.9L15.5 20.2L16.3 20.4L17.1 20.4L18.0 20.3L18.9 20.0L19.7 19.6L20.4 19.0L21.1 18.4L21.7 17.6L22.1 16.7L22.3 15.8L22.4 14.9L22.4 13.9L22.2 13.0L21.8 12.2L21.4 11.5L20.8 10.9L20.2 10.4L19.5 10.1L18.8 9.9L18.1 9.9L17.5 10.0L17.0 10.2L16.5 10.6L16.1 11.0L15.9 11.5L15.9 12.0L15.9 12.5L16.1 13.0L16.5 13.4L17.0 13.8L17.5 14.0L18.1 14.1L18.8 14.1L19.5 13.9L20.2 13.6L20.8 13.1L21.4 12.5L21.8 11.8L22.2 11.0L22.4 10.1L22.4 9.1L22.3 8.2L22.1 7.3L21.7 6.4L21.1 5.6L20.4 5.0L19.7 4.4L18.9 4.0L18.0 3.7L17.1 3.6L16.3 3.6L15.5 3.8L14.7 4.1L14.1 4.5L13.6 5.0L13.2 5.6L13.0 6.2L12.9 6.8L13.0 7.4L13.2 7.9L13.5 8.3L13.9 8.7L14.4 8.9L14.9 8.9L15.5 8.8L16.0 8.6L16.5 8.2L16.9 7.7L17.2 7.1L17.4 6.4L17.5 5.7L17.4 4.9L17.1 4.1L16.7 3.4L16.2 2.7L15.5 2.0L14.7 1.5L13.9 1.2L13.0 0.9L12.0 0.9L11.0 0.9L10.1 1.2L9.3 1.5L8.5 2.0L7.8 2.7L7.3 3.4L6.9 4.1L6.6 4.9L6.5 5.7L6.6 6.4L6.8 7.1L7.1 7.7L7.5 8.2L8.0 8.6L8.5 8.8L9.1 8.9L9.6 8.9Z' fill='none' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.no-icon-ea {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.635 6.162l-5.928 9.377H4.24l1.508-2.3h4.024l1.474-2.335H2.264L.79 13.239h2.156L0 17.84h12.072l4.563-7.259 1.652 2.66h-1.401l-1.473 2.299h4.347l1.473 2.3H24zm-11.461.107L3.7 8.604l9.52-.035 1.474-2.3z'/%3E%3C/svg%3E");
}

.no-icon-openvpn {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .357C5.385.357 0 5.69 0 12.254c0 4.36 2.358 8.153 5.896 10.204l.77-5.076a7.046 7.046 0 01-1.846-4.719c0-3.897 3.18-7.076 7.13-7.076 3.948 0 7.126 3.18 7.126 7.076 0 1.847-.717 3.488-1.846 4.77L18 22.51c3.59-2.05 6-5.899 6-10.258C24 5.69 18.615.357 12 .357zm-.05 8.157a3.786 3.786 0 00-3.796 3.795 3.738 3.738 0 002.461 3.54L9.13 23.643h5.64l-1.435-7.795c1.385-.564 2.41-1.898 2.41-3.54a3.786 3.786 0 00-3.795-3.794z'/%3E%3C/svg%3E");
}

.no-icon-mqtt {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.657 23.994h-9.45A1.212 1.212 0 0 1 0 22.788v-9.18h.071c5.784 0 10.504 4.65 10.586 10.386Zm7.606 0h-4.045C14.135 16.246 7.795 9.977 0 9.942V6.038h.071c9.983 0 18.121 8.044 18.192 17.956Zm4.53 0h-.97C21.754 12.071 11.995 2.407 0 2.372v-1.16C0 .55.544.006 1.207.006h7.64C15.733 2.49 21.257 7.789 24 14.508v8.291c0 .663-.544 1.195-1.207 1.195ZM16.713.006h6.092A1.19 1.19 0 0 1 24 1.2v5.914c-.91-1.242-2.046-2.65-3.158-3.762C19.588 2.11 18.122.987 16.714.005Z'/%3E%3C/svg%3E");
}

.no-icon-openai {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z'/%3E%3C/svg%3E");
}

.no-icon-claude {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z'/%3E%3C/svg%3E");
}

.no-icon-anthropic {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z'/%3E%3C/svg%3E");
}

/* ICMP: a ping going out, a dot with fading waves. */
.no-icon-icmp {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='5.0' cy='12.0' r='2.6' fill='%23000' stroke='none'/%3E%3Cpath d='M9.60 7.40A6.5 6.5 0 0 1 9.60 16.60'/%3E%3Cpath d='M12.78 4.22A11 11 0 0 1 12.78 19.78' opacity='.65'/%3E%3Cpath d='M15.96 1.04A15.5 15.5 0 0 1 15.96 22.96' opacity='.35'/%3E%3C/svg%3E");
}

/* Roku has only its wordmark: cropped to it, so it takes the glyph's full width. */
.no-icon-roku {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 8 24 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.34 9.853l-2.254 2.254v-2.26H12.13v5.744h1.957v-2.33l2.353 2.33h2.46l-2.988-2.99 2.477-2.476v3.411c0 1.133.679 2.177 2.393 2.177.815 0 1.56-.462 1.922-.88l.88.759H24v-5.74h-1.951v3.718c-.22.384-.528.627-1.002.627-.482 0-.703-.286-.703-1.198V9.853zm-4.591 2.869A3.004 3.004 0 1 1 8.738 9.73a2.997 2.997 0 0 1 3.011 2.99m-3.011-1.57c-.518 0-.956.704-.956 1.572 0 .867.438 1.57.956 1.57.528 0 .968-.702.968-1.57 0-.869-.438-1.572-.968-1.572zm-2.206 4.447H4.313L2.55 13.153h-.594v2.44H0V8.26h2.8c1.616 0 2.935 1.1 2.935 2.45 0 .826-.505 1.562-1.273 2.013l2.07 2.875m-2.75-4.888A1.226 1.226 0 0 0 2.56 9.478h-.604v2.453h.605a1.225 1.225 0 0 0 1.22-1.221Z'/%3E%3C/svg%3E");
}

.no-icon-akamai {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.0548 0C6.384 0 .961 5.3802.961 12.0078.961 18.6354 6.3698 24 13.0548 24c.6168 0 .6454-.3572.0859-.5293-4.9349-1.5063-8.5352-6.069-8.5352-11.4629 0-5.4656 3.6725-10.0706 8.6934-11.5195C13.8153.3448 13.6716 0 13.0548 0Zm2.3242 1.8223c-5.2648 0-9.5254 4.2606-9.5254 9.5254 0 1.2193.2285 2.3818.6445 3.4433.1722.459.4454.4584.4024.0137-.0287-.3156-.0567-.6447-.0567-.9746 0-5.2648 4.2606-9.5254 9.5254-9.5254 4.9779 0 6.4698 2.2235 6.6563 2.08.2008-.1577-1.808-4.5624-7.6465-4.5624zm.4687 4.0703c-1.8622.0592-3.651.7168-5.1035 1.8554-.2582.2009-.1567.3284.1445.1993 2.4675-1.076 5.5812-1.1046 8.6368-.043 2.0514.7173 3.2413 1.7364 3.3418 1.6934.1578-.0718-1.1915-2.2226-3.6446-3.1407-1.1135-.4196-2.2576-.6-3.375-.5644z'/%3E%3C/svg%3E");
}

.no-icon-elasticsearch {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.394 0C8.683 0 4.609 2.716 2.644 6.667h15.641a4.77 4.77 0 0 0 3.073-1.11c.446-.375.864-.785 1.247-1.243l.001-.002A11.974 11.974 0 0 0 13.394 0zM1.804 8.889a12.009 12.009 0 0 0 0 6.222h14.7a3.111 3.111 0 1 0 0-6.222zm.84 8.444C4.61 21.283 8.684 24 13.395 24c3.701 0 7.011-1.677 9.212-4.312l-.001-.002a9.958 9.958 0 0 0-1.247-1.243 4.77 4.77 0 0 0-3.073-1.11z'/%3E%3C/svg%3E");
}

.no-icon-tailscale {
    /* The official mark (as VpnIcon draws it): faded dots filled at 20%, not the outlined rings that blur at 16px. */
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cellipse cx='2.45' cy='10.18' rx='2.45' ry='2.44'/%3E%3Cellipse cx='9.79' cy='10.18' rx='2.45' ry='2.44'/%3E%3Cellipse cx='17.13' cy='10.18' rx='2.45' ry='2.44'/%3E%3Cellipse cx='9.79' cy='17.51' rx='2.45' ry='2.44'/%3E%3Cellipse opacity='0.2' cx='2.45' cy='2.86' rx='2.45' ry='2.44'/%3E%3Cellipse opacity='0.2' cx='9.79' cy='2.86' rx='2.45' ry='2.44'/%3E%3Cellipse opacity='0.2' cx='17.13' cy='2.86' rx='2.45' ry='2.44'/%3E%3Cellipse opacity='0.2' cx='2.45' cy='17.51' rx='2.45' ry='2.44'/%3E%3Cellipse opacity='0.2' cx='17.13' cy='17.51' rx='2.45' ry='2.44'/%3E%3C/svg%3E");
}

.no-icon-matter {
    /* The Matter mark: three arrows pointing into the center. */
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 500' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M152 128.5c21.5 17.5 47.1 29.2 74.4 34.2V17.1L256.1 0l29.6 17.1v145.5c27.3-4.9 52.9-16.7 74.5-34.2l53.8 31.1c-87.6 86.5-228.5 86.5-316.1 0zM217.5 500c31.2-119.1-39.4-241.1-158.2-273.5v62.3c25.9 9.9 48.9 26.2 66.8 47.4L0 408.8V443l29.7 17 126.1-72.7c9.4 26.1 12 54.2 7.6 81.4l54.1 31.4Zm235.3-273.5C334 259 263.6 381 294.8 500l54-31.2c-4.4-27.4-1.7-55.4 7.6-81.4l126 72.6 29.6-17.1v-34.2L385.9 336c17.9-21.2 40.9-37.5 66.8-47.4v-62.2Z'/%3E%3C/svg%3E");
}

.no-icon-backblaze {
    --no-icon: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.3108.0003c.6527 1.3502 1.5666 4.0812-1.3887 7.1738-1.8096 1.8796-3.078 3.8487-2.3496 6.0644.3642 1.1037 1.1864 2.5079 2.8867 2.7852.6107.1008 1.3425-.0006 1.7403-.1406 2.4538-.8544 2.098-3.4138 1.5546-5.0469-.07-.2129-.1915-.7333-.2363-.9238-.3726-1.6023.776-2.6562 1.129-3.8047.028-.0925.0534-.1819.0702-.2715.042-.21.067-.423.0781-.6387 0-1.8264-.9882-2.6303-1.7754-3.5996C10.1794.5643 9.3107.0003 9.3107.0003Zm6.2754 6.0175s-.709.3366-1.2188.8829c-.4454.4818-.8635.8789-1.2949 1.8593-.028.14-.0518.2863-.0742.4375-.2325 1.6416 1.1473 3.1446.7187 5.1895-.112.535-.3554.7123-.7812 1.6367-.5098 1.1065-.383 2.588.3594 3.5293.6723.8488 1.879 1.2321 3.0527.9492 2.1065-.5042 3.0646-2.2822 2.8965-4.2851-.1317-1.58-.8154-2.7536-2.754-4.961-.9607-1.0925-1.6072-2.409-1.5624-3.4062.1373-1.2074.6582-1.832.6582-1.832zM4.8928 15.1936c-.0222.0145-.0439.0614-.0586.1602a.0469.0469 0 0 1-.0059.0195v.01c-.1148.5406-.1649 1.823.1153 2.9687.353 1.4427 1.4175 3.902 4.412 5.129 2.5184 1.0336 5.718.5411 7.8497-1.627.5294-.5435.408-.4897-.4883-.2012v-.002c-1.1121.3558-3.5182.5463-4.7676-1-1.5239-1.8852-.4302-3.3633-1.3574-3.1504-3.6164.8348-5.2667-1.4657-5.5469-2.1016-.0023-.002-.0857-.2487-.1523-.205z'/%3E%3C/svg%3E");
}

/* In the phone list's badge row the gap spaces the site badge; its margin is for beside a name. */
.lt-m-tags .lt-site-badge {
    margin-left: 0;
}

.lt-app-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: var(--bg-tertiary);
}

.lt-app-initial {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}

/* A custom app with no glyph chosen shows its initial: the empty glyph box would cover it. */
.lt-app-icon .lt-app-glyph.lt-app-initial-only {
    display: none;
}

/* An App Live Traffic could only call "UDP 21324": dotted, like an abbr, so the hover card is findable.
   A border, not text-decoration: .filter-pill-text clips its overflow, and that cuts an underline off. */
.lt-app-unnamed .filter-pill-text,
.lt-app-unnamed .lt-pivot {
    color: var(--text-secondary);
    border-bottom: 1px dotted var(--text-secondary);
}

/* The Dashboard card's pill is a link with its text directly inside. */
.lt-app-unnamed a.filter-pill {
    text-decoration: underline dotted;
    text-underline-offset: 2px;
}

.lt-sankey-node.lt-app-unnamed .lt-node-label {
    fill: var(--text-secondary);
    text-decoration: underline dotted;
}

/* ---------------------------------------------------------------- Custom Apps (Live Traffic dialog, Settings card) */

.custom-apps-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(0, 0, 0, 0.6);
}

.custom-apps-dialog {
    position: relative;
    width: 100%;
    max-width: 680px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    padding: 24px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 8px;
}

.custom-apps-close {
    position: absolute;
    top: 16px;
    right: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
}

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

.custom-apps-close svg {
    width: 18px;
    height: 18px;
}

.custom-apps-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

/* Clear of the close button. */
.custom-apps.is-dialog .custom-apps-header {
    padding-right: 40px;
}

.custom-apps-header .custom-apps-intro {
    flex: 1 1 240px;
    margin: 0;
}

.custom-apps-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.custom-apps-back,
.custom-apps-link {
    padding: 0;
    border: none;
    background: none;
    color: var(--primary-hover);
    font: inherit;
    cursor: pointer;
}

.custom-apps-back {
    font-size: 0.875rem;
}

.custom-apps-back:hover,
.custom-apps-link:hover {
    text-decoration: underline;
}

.custom-app-form .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.custom-app-form .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

.custom-app-icons {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.custom-app-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-size: 14px;
    cursor: pointer;
}

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

.custom-app-icon-btn.is-selected {
    border-color: var(--primary-color);
    background: rgba(5, 80, 181, 0.2);
    color: var(--text-primary);
}

.custom-app-initial {
    font-size: 12px;
    font-weight: 600;
}

.custom-app-preview {
    margin-bottom: 1.5rem;
}

.custom-app-preview-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    min-height: 28px;
}

.custom-app-live {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.custom-app-shadow {
    display: block;
    margin-top: 0.5rem;
    color: var(--warning-color);
}

.custom-apps-error {
    margin-top: 0.75rem;
}

.custom-apps-intro {
    margin: 0 0 0.75rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.custom-apps-empty p {
    margin: 0;
}

.custom-apps-list {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--border-color);
}

/* One definition: rank, name over its summary, then the actions; the actions wrap under on a phone. */
.custom-apps-item {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    padding: 0.75rem 0.5rem;
    border-bottom: 1px solid var(--border-color);
    transition: background 0.4s ease;
}

.custom-apps-item.is-new {
    background: rgba(5, 80, 181, 0.15);
}

.custom-apps-rank {
    flex: 0 0 1.25rem;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.custom-apps-main {
    flex: 1 1 240px;
    min-width: 0;
}

.custom-apps-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.custom-apps-sub {
    margin-top: 0.2rem;
    color: var(--text-secondary);
    font-size: 0.8rem;
}

.custom-apps-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-left: auto;
}

.custom-apps-move {
    width: 28px;
    min-width: 0;
    padding: 0;
}

.custom-apps-move svg {
    width: 14px;
    height: 14px;
}

.custom-apps-deleted {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.custom-apps-row-error {
    flex: 1 1 100%;
    margin-top: 0;
}

@media (max-width: 768px) {
    .custom-apps-dialog {
        padding: 16px;
    }

    .custom-apps-close {
        top: 8px;
        right: 8px;
    }

    .custom-app-form .form-row {
        flex-direction: column;
        gap: 0;
    }

    .custom-app-form .form-row > .form-group {
        flex: 0 0 auto;
    }

    /* Under the name, lined up with it rather than with the rank. */
    .custom-apps-actions {
        margin-left: calc(1.25rem + 0.75rem);
    }
}

.lt-streams { background: var(--bg-tertiary); color: var(--text-secondary); font-size: 0.72rem; }
.lt-site-badge { background: rgba(71, 151, 255, 0.15); color: var(--info-color); margin-left: 0.35rem; font-size: 0.72rem; }
/* A LAN peer's network, in the LAN route's amber. */
.lt-peer-badge { background: rgba(245, 158, 11, 0.15); color: #f59e0b; margin-left: 0.35rem; font-size: 0.72rem; }
.lt-m-tags .lt-peer-badge { margin-left: 0; }

.live-traffic .lt-mobile-sort {
    margin-bottom: 0.5rem;
}

.lt-dns-card .card-title > .tooltip-icon-sm {
    margin-left: 0.5rem;
}

/* A filter pill in a Live Traffic row, and the hide button that shows beside it on hover or focus */
.lt-pill {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    max-width: 100%;
    min-width: 0;
    vertical-align: middle;
}

.lt-pill-hide {
    display: none;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.lt-pill-hide svg {
    width: 12px;
    height: 12px;
}

.lt-pill-hide:hover {
    color: var(--danger-color);
    background: var(--bg-hover);
}

/* Keyboard focus only: a click leaves the pill focused, and :focus-within kept the button up after the pointer left. */
.lt-pill:hover .lt-pill-hide,
.lt-pill:has(:focus-visible) .lt-pill-hide {
    display: inline-flex;
}

@media (hover: none) {
    .lt-pill:hover .lt-pill-hide {
        display: none;
    }
}

.filter-pill.is-sub {
    padding: 0 0.35rem;
    font-size: 0.68rem;
    background: transparent;
    border-color: var(--border-color);
    color: var(--text-muted);
}

.filter-pill.is-sub:hover {
    color: var(--text-primary);
    border-color: var(--primary-hover);
}

.filter-pill.is-sub.active {
    background: var(--primary-color);
    border-color: transparent;
    color: var(--text-primary);
}

/* Full view */
.live-traffic .lt-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.live-traffic .lt-stat {
    margin: 0;
}

.live-traffic .lt-stat .card-body {
    padding: 0.9rem 1rem;
}

.lt-stat-label {
    color: var(--text-secondary);
    font-size: 0.75rem;
    margin-bottom: 0.3rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.lt-stat-value {
    font-size: 1.35rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.lt-stat-sub {
    color: var(--text-secondary);
    font-size: 0.78rem;
    margin-top: 0.2rem;
    font-variant-numeric: tabular-nums;
}

.lt-meter {
    height: 6px;
    border-radius: 3px;
    background: var(--bg-tertiary);
    overflow: hidden;
    margin-top: 0.5rem;
    display: flex;
}

.lt-meter span {
    display: block;
    height: 100%;
}

.lt-filterbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    align-items: center;
    margin-bottom: 1rem;
}

.lt-search {
    flex: 1 1 320px;
    max-width: 460px;
    position: relative;
}

.lt-search .form-control {
    padding-left: 2rem;
}

/* The phone's shorter placeholder (shown by the 768px rule). */
.lt-search-hint {
    display: none;
    position: absolute;
    left: calc(2rem + 1px);
    right: 0.875rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.875rem;
    color: var(--text-secondary);
    opacity: 0.75;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
}

.lt-search svg {
    position: absolute;
    left: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    width: 14px;
    height: 14px;
    color: var(--text-muted);
}

/* While it holds text the box is filtering the page: tinted like the filter chips beside it. */
.lt-search.is-active .form-control {
    background: rgba(46, 121, 196, 0.15);
    border-color: rgba(46, 121, 196, 0.6);
    box-shadow: 0 0 0 1px rgba(46, 121, 196, 0.35);
    padding-right: 2rem;
}

.lt-search.is-active svg {
    color: var(--primary-lighter);
}

.lt-search .lt-search-clear {
    position: absolute;
    right: 0.45rem;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    border: none;
    border-radius: 50%;
    background: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.lt-search .lt-search-clear:hover {
    background: var(--bg-elevated);
    color: var(--text-primary);
}

.lt-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.35rem 0.25rem 0.6rem;
    border-radius: 999px;
    background: rgba(46, 121, 196, 0.15);
    color: var(--primary-lighter);
    font-size: 0.78rem;
    border: 1px solid rgba(46, 121, 196, 0.35);
}

.lt-chip.is-exclude {
    background: rgba(238, 99, 104, 0.12);
    color: var(--danger-color);
    border-color: rgba(238, 99, 104, 0.35);
}

/* ---------------------------------------------------------------- filter chips: grouped, editable */

/* A chip and its editor: the editor opens under the chip it belongs to. */
.lt-chip-anchor {
    position: relative;
    display: inline-flex;
}

.live-traffic .lt-chip[role="button"] {
    cursor: pointer;
}

.lt-chip.is-open {
    outline: 1px solid var(--primary-hover);
}

.lt-chip-or {
    color: var(--text-muted);
    font-weight: 400;
}

.lt-add-filter {
    /* Above an open editor's click-outside layer, so one click starts over instead of first closing it. */
    position: relative;
    z-index: 62;
    background: transparent;
    border: 1px dashed var(--border-color);
    color: var(--text-secondary);
    border-radius: 999px;
    padding: 0.25rem 0.7rem;
    font-size: 0.78rem;
    cursor: pointer;
}

.lt-add-filter:hover,
.lt-add-filter[aria-expanded="true"] {
    color: var(--text-primary);
    border-color: var(--text-secondary);
}

/* A click outside closes the editor or the field menu. Transparent on a desktop, a scrim on a phone. */
.lt-fpop-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
}

.lt-fpop,
.lt-fmenu {
    position: absolute;
    top: calc(100% + 9px);
    left: 0;
    z-index: 61;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-lg);
}

.lt-fpop {
    width: 290px;
    max-width: calc(100vw - 32px);
    padding: 10px 12px 12px;
}

.lt-fpop-grab {
    display: none;
}

.lt-fpop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 8px;
}

.lt-fpop-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    font-weight: 600;
}

.lt-fpop-head .time-range-selector {
    margin: 0;
}

.lt-fpop .lt-fpop-search {
    height: 30px;
    font-size: 0.8125rem;
    margin-bottom: 6px;
}

.lt-fpop-list {
    max-height: 240px;
    overflow-y: auto;
    /* At either end the scroll stays here: chained on, it scrolled the page behind the editor. */
    overscroll-behavior: contain;
    margin: 0 -4px;
}

.lt-fpop-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 4px;
    border-radius: 4px;
    font-size: 0.8125rem;
    cursor: pointer;
}

.lt-fpop-item.is-active {
    background: var(--bg-tertiary);
}

.lt-fpop-item.is-idle {
    color: var(--text-secondary);
}

.lt-fpop-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lt-fpop-service {
    margin-left: 0.4rem;
    color: var(--text-muted);
}

.lt-fpop-n {
    margin-left: auto;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.lt-fpop-sep {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin: 8px 4px 2px;
}

.lt-fpop-empty {
    padding: 10px 4px;
    color: var(--text-muted);
    font-size: 0.8125rem;
}

.lt-fpop-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 10px;
}

.lt-fpop-foot a {
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.lt-fpop-bulk {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.lt-fpop-bulk-sep {
    color: var(--text-muted);
}

.lt-fmenu {
    width: 190px;
    padding: 6px;
}

.lt-fmenu button {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 6px 8px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--text-primary);
    font-size: 0.8125rem;
    text-align: left;
    cursor: pointer;
}

.lt-fmenu button:hover,
.lt-fmenu button:focus-visible {
    background: var(--bg-tertiary);
}

.lt-fmenu button i {
    width: 14px;
    color: var(--text-muted);
}

/* On a phone the editor is a bottom sheet over a dimmed page. */
@media (max-width: 768px) {
    .lt-fpop-backdrop:has(+ .lt-fpop) {
        background: rgba(0, 0, 0, 0.5);
    }

    /* The page stays put under the sheet: only its list scrolls, and a drag on the scrim or the rest of
       the sheet moves nothing (taps still work). */
    .lt-fpop-backdrop,
    .lt-fpop {
        touch-action: none;
    }

    .lt-fpop .lt-fpop-list {
        touch-action: pan-y;
    }

    /* Under the sheet's scrim like the rest of the page: a tap outside the sheet closes it. */
    .lt-add-filter {
        z-index: auto;
    }

    .lt-fpop {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        max-width: none;
        border-radius: 16px 16px 0 0;
        /* The bottom bar clears the home indicator on a phone that has one. */
        padding: 8px 16px calc(22px + env(safe-area-inset-bottom, 0px));
    }

    /* Drag the handle or the header down to close (App.razor); touch-action keeps the page from scrolling instead. */
    .lt-fpop-grab {
        display: block;
        width: 40px;
        height: 4px;
        border-radius: 2px;
        background: var(--border-color);
        background-clip: content-box;
        box-sizing: content-box;
        padding: 10px 40px;
        margin: -8px auto 0;
        touch-action: none;
    }

    .lt-fpop-head {
        touch-action: none;
    }

    .lt-fpop-list {
        max-height: 45vh;
    }

    .lt-fpop-item {
        padding: 9px 4px;
        font-size: 0.9rem;
    }
}

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

.lt-chip .lt-x {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    cursor: pointer;
}

.lt-chip .lt-x:hover {
    background: var(--bg-elevated);
}

/* Drawn, not the ✕ glyph: iOS's fallback font sat the glyph low in the circle. */
.lt-chip .lt-x svg {
    display: block;
    width: 8px;
    height: 8px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
}

.lt-clear {
    font-size: 0.78rem;
    color: var(--text-secondary);
}

/* FilterPresets: a save button and its slots, compact enough to sit beside filter chips. */
.filter-presets {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
}

/* A phone keeps slots 1-3: the everyday presets go in the first slots, and five crowd the filter row. */
@media (max-width: 768px) {
    .filter-preset[data-slot="4"],
    .filter-preset[data-slot="5"] {
        display: none;
    }
}

.filter-preset {
    min-width: 24px;
    height: 24px;
    padding: 0 0.3rem;
    border-radius: 6px;
    border: 1px solid var(--border-color, #2e2e33);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.filter-preset:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.filter-preset.is-set {
    color: var(--text-primary);
    border-color: rgba(46, 121, 196, 0.45);
}

/* The slot whose filters are on the page now. */
.filter-preset.is-active {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: #fff;
}

.filter-preset-save {
    color: var(--text-secondary);
}

.filter-preset-save svg {
    width: 13px;
    height: 13px;
}

.filter-preset-save[aria-pressed="true"] {
    background: rgba(46, 121, 196, 0.15);
    border-color: var(--primary-hover);
    color: var(--primary-lighter);
}

/* Save mode: every slot is a target. */
.filter-presets.is-saving .filter-preset:not(.filter-preset-save) {
    border-color: var(--primary-hover);
    color: var(--text-primary);
    animation: filter-preset-pulse 1.2s ease-in-out infinite;
}

@keyframes filter-preset-pulse {
    50% { background: rgba(46, 121, 196, 0.2); }
}

.filter-preset-note {
    font-size: 0.75rem;
    color: var(--success-color);
    margin-left: 0.15rem;
}

.filter-preset-note.is-error {
    color: var(--danger-color);
}

.lt-filterbar .lt-right {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.lt-starting {
    padding: 0.75rem 1rem;
    border-radius: var(--border-radius);
    margin-bottom: 1rem;
    font-size: 0.85rem;
}

.lt-body {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Phone only: Flows and Live DNS as tabs, with the bar above and below the content. */
.live-traffic .lt-mobile-tabs {
    display: none;
    margin-bottom: 1rem;
}

.live-traffic .lt-mobile-tabs-bottom {
    margin: 1rem 0 0;
}

.lt-mobile-tabs-bottom .wifi-view-tabs {
    border-bottom: none;
    border-top: 1px solid var(--border-color);
    margin-top: 0;
    padding: 0.5rem 0 0;
}

.lt-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: 1rem;
}

.live-traffic .lt-grid .card,
.live-traffic .lt-body > .card {
    margin: 0;
}

.lt-sankey-svg {
    width: 100%;
    height: auto;
    display: block;
}

.lt-sankey-node.is-clickable {
    cursor: pointer;
}

/* A node the page is filtered to: clicking it again removes the filter. */
.lt-sankey-svg .lt-sankey-node.is-filtered .lt-node-label {
    fill: var(--primary-light);
    font-weight: 600;
}

.lt-sankey-svg .lt-sankey-node.is-filtered rect {
    stroke: var(--primary-light);
    stroke-width: 1.5;
}

/* Where It's Going sits centered when Live DNS beside it runs taller; the note stays at the bottom. */
.lt-sankey-card {
    display: flex;
    flex-direction: column;
}

.lt-sankey-card > .card-body {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.lt-sankey-stage {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* The idle and loading states take the diagram's own height (its viewBox ratio), so the card does not shrink. */
.lt-sankey-stage > .lt-sankey-empty {
    aspect-ratio: 790 / 360;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin: 0;
}

/* Nodes and bands tween between refreshes instead of jumping. */
.lt-sankey-svg .lt-sankey-node,
.lt-sankey-svg .lt-node-text {
    transition: transform 0.45s ease;
}

.lt-sankey-svg .lt-sankey-node rect {
    transition: height 0.45s ease;
}

.lt-sankey-svg path {
    transition: d 0.45s ease, stroke-width 0.45s ease;
}

@media (prefers-reduced-motion: reduce) {
    .lt-sankey-svg .lt-sankey-node,
    .lt-sankey-svg .lt-node-text,
    .lt-sankey-svg .lt-sankey-node rect,
    .lt-sankey-svg path {
        transition: none;
    }
}

/* A row sliding into place is translated past the list's edge for a moment: clip it rather than
   let the scroll wrapper grow dead space and a scrollbar. */
.live-traffic .table-responsive,
.live-traffic .lt-mobile-list.lt-flip,
.lt-client .table-responsive,
.lt-client .lt-mobile-list.lt-flip {
    overflow-y: hidden;
}

.lt-sankey-node.is-clickable:hover .lt-node-label {
    fill: var(--primary-light);
}

.lt-sankey-svg .lt-node-label {
    fill: var(--text-primary);
    font-size: 12px;
    font-family: Inter, sans-serif;
}

.lt-sankey-svg .lt-node-sub .lt-sub-down { fill: var(--speed-download-color); }
.lt-sankey-svg .lt-node-sub .lt-sub-up { fill: var(--speed-upload-color); }
.lt-sankey-svg .lt-node-sub .lt-sub-idle { fill: var(--text-muted); }

/* A route node's hover card (App.razor routeHtml): one row per destination, name left, rate right. */
.tippy-box[data-theme~='custom'] .lt-route-tip-label { color: var(--text-secondary); font-size: 0.8em; margin: 0.15rem 0; }
.tippy-box[data-theme~='custom'] .lt-route-tip-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.15rem 0; }
.tippy-box[data-theme~='custom'] .lt-route-tip-name { display: flex; align-items: center; gap: 0.35rem; min-width: 0; overflow: hidden; white-space: nowrap; }
.tippy-box[data-theme~='custom'] .lt-route-tip-name .lt-tag { margin-left: 0; flex: 0 0 auto; }
.tippy-box[data-theme~='custom'] .lt-route-tip-name > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tippy-box[data-theme~='custom'] .lt-route-tip-ip { color: var(--text-muted); }
.tippy-box[data-theme~='custom'] .lt-route-tip-value { flex: 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tippy-box[data-theme~='custom'] .lt-route-tip-down { color: var(--speed-download-color); }
.tippy-box[data-theme~='custom'] .lt-route-tip-up { color: var(--speed-upload-color); }

.lt-sankey-svg .lt-node-sub {
    fill: var(--text-secondary);
    font-size: 10px;
    font-family: Inter, sans-serif;
    font-variant-numeric: tabular-nums;
}

/* A halo in the card's color, so a label stays legible where a wide ribbon runs under it. */
.lt-sankey-svg .lt-node-label,
.lt-sankey-svg .lt-node-sub {
    paint-order: stroke;
    stroke: var(--bg-card);
    stroke-width: 3px;
    stroke-linejoin: round;
}

.lt-sankey-svg .lt-col-label {
    fill: var(--text-muted);
    font-size: 10px;
    font-family: Inter, sans-serif;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.lt-legend-note {
    color: var(--text-muted);
    font-size: 0.75rem;
    margin-top: 0.5rem;
}

.lt-dns-table {
    width: 100%;
    min-width: 0;
    table-layout: fixed;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

.lt-dns-table th,
.lt-dns-table td {
    padding: 0.38rem 0.5rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lt-dns-table tr.is-bypass td {
    background: rgba(231, 150, 19, 0.06);
}

.lt-dns-table tr.is-redirected td {
    background: rgba(71, 151, 255, 0.07);
}

.lt-dns-sub {
    display: block;
    color: var(--text-muted);
    font-size: 0.7rem;
}

.lt-dns-table td.lt-dns-empty-cell {
    color: var(--text-secondary);
    text-align: center;
}

/* Live Traffic is a wide table plus Where It's Going and Live DNS side by side: it takes up to 1920px
   on a desktop instead of the layout's standard 1400px. */
.content:has(.live-traffic) {
    max-width: 1920px;
}

/* A lookup sent to an outside resolver that the Gateway redirected to a site one: the attempt, not a bypass. */
.lt-dns-redirect {
    color: var(--info-color);
    font-size: 0.75rem;
    margin-left: 0.3rem;
    white-space: nowrap;
}

.lt-dns-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.lt-dns-controls .lt-dns-local {
    margin: 0;
    font-size: 0.85rem;
    white-space: nowrap;
}

.lt-flows {
    table-layout: fixed;
    width: 100%;
    font-variant-numeric: tabular-nums;
}

.lt-flows th,
.lt-flows td {
    padding: 0.5rem 0.6rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lt-flows .lt-flow-row {
    cursor: pointer;
}

.lt-flows .lt-rank {
    color: var(--text-muted);
    white-space: nowrap;
    padding-right: 0.25rem;
    font-variant-numeric: tabular-nums;
}

/* Client Performance's page style gives .expand-chevron a 2rem centered box; the rank needs the room. */
.lt-flows .lt-rank .lt-chev {
    width: auto;
    text-align: left;
}

.lt-flows .lt-sub {
    display: block;
    color: var(--text-muted);
    font-size: 0.72rem;
    /* Its own ellipsis: the cell's applies only to the cell's own text, so a cut port read as a
       different port ("UDP 4164" for 41641) with no sign anything was missing. */
    overflow: hidden;
    text-overflow: ellipsis;
}

.lt-flows tr.lt-selected td {
    background: var(--bg-hover);
}

.lt-flows .lt-sub.lt-port-line {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.15rem;
    overflow: hidden;
}

.lt-flows tr.is-blocked:not(.lt-selected) td {
    background: rgba(238, 99, 104, 0.04);
}

/* History: the Timeline card */
.live-traffic .lt-timeline-card {
    margin: 0 0 1rem;
}

.lt-tl-readout {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    min-height: 1.2rem;
    margin-bottom: 0.35rem;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

.lt-tl-readout-time {
    color: var(--text-primary);
    font-weight: 600;
}

.lt-tl-blocked-text {
    color: #ef5858;
}

.lt-tl-svg {
    display: block;
    width: 100%;
    height: 124px;
    cursor: crosshair;
    user-select: none;
}

.lt-tl-grid {
    stroke: #374151;
    stroke-width: 0.5;
    vector-effect: non-scaling-stroke;
}

.lt-tl-allowed { fill: #3b82f6; }
.lt-tl-blocked { fill: #ef5858; }
.lt-tl-hit { fill: transparent; }
.lt-tl-selection { fill: rgba(46, 121, 196, 0.15); }

.lt-tl-bar.is-dim {
    opacity: 0.3;
}

.lt-tl-bar:hover .lt-tl-allowed,
.lt-tl-bar:hover .lt-tl-blocked {
    filter: brightness(1.3);
}

.lt-tl-ticks {
    position: relative;
    height: 1.1rem;
    font-size: 0.7rem;
    color: #9ca3af;
    font-variant-numeric: tabular-nums;
}

.lt-tl-ticks span {
    position: absolute;
    transform: translateX(-50%);
    white-space: nowrap;
}

.lt-tl-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.4rem;
}

.lt-tl-legend .lt-legend-note {
    margin: 0 0 0 0.25rem;
}

.lt-tl-legend .filter-pill-text::before {
    content: "";
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 0.35rem;
    border-radius: 2px;
}

.lt-tl-legend .lt-action-allowed .filter-pill-text::before { background: #3b82f6; }
.lt-tl-legend .lt-action-blocked .filter-pill-text::before { background: #ef5858; }

.lt-show-more {
    margin-top: 0.75rem;
}

.lt-detail-history {
    grid-template-columns: 1fr 1fr;
}

.lt-spark {
    width: calc(100% - 0.25rem);
    max-width: 90px;
    height: 22px;
    display: block;
}

.data-table.lt-flows tr.lt-detail > td,
.lt-client .lt-flows tr.lt-detail > td {
    white-space: normal;
    background: var(--bg-hover-subtle);
    padding: 0;
}

.lt-detail-wrap {
    display: grid;
    grid-template-columns: 1.2fr 1fr 1fr;
    gap: 1.25rem;
    padding: 1rem 1.25rem 1.1rem 3rem;
    cursor: default;
}

.lt-detail-wrap h4 {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    font-weight: 600;
    margin: 0 0 0.5rem;
}

/* A heading with Open in Client Performance at its right; the button's negative margins keep the row as
   tall as its neighbors' bare headings. */
.lt-detail-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
}

.lt-detail-head .monitoring-jump-btn {
    margin: -0.4rem -0.35rem -0.4rem 0;
}

.lt-kv {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.3rem 0.9rem;
    font-size: 0.8rem;
    margin: 0;
}

.lt-kv dt {
    color: var(--text-secondary);
    font-weight: 400;
}

.lt-kv dd {
    margin: 0;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A short grey line under a value that explains where it came from; it wraps instead of cutting off. */
.lt-kv dd .lt-kv-note {
    display: block;
    white-space: normal;
    color: var(--text-muted);
    font-size: 0.75rem;
    line-height: 1.35;
    margin-top: 0.1rem;
}

.lt-detail-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.9rem;
}

.lt-chart svg {
    width: 100%;
    height: 110px;
    display: block;
}

/* Phone: stacked rows replace the tables */
.lt-mobile-list,
.live-traffic .lt-mobile-only,
.lt-client .lt-mobile-only {
    display: none;
}

.lt-m-row {
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--border-color);
}

.lt-m-row:last-child {
    border-bottom: 0;
}

.lt-m-top {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.lt-m-top .lt-m-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

.lt-m-dest {
    color: var(--text-secondary);
    font-size: 0.78rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin: 0.15rem 0 0.35rem;
}

.lt-m-top + .lt-m-tags {
    margin-top: 0.4rem;
}

.lt-m-tags {
    display: flex;
    gap: 0.4rem 0.35rem;
    flex-wrap: wrap;
    align-items: center;
    font-size: 0.78rem;
}

.lt-m-rates {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-size: 0.8rem;
}

.lt-m-detail .lt-detail-wrap {
    grid-template-columns: minmax(0, 1fr);
    padding: 0.75rem 0 0;
}

@media (max-width: 768px) {
    .live-traffic .lt-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.6rem;
    }

    /* One part per line, never wrapped: the card height must not follow the live rates. */
    .live-traffic .lt-stat-label {
        overflow: hidden;
        white-space: nowrap;
    }

    .live-traffic .lt-sub-part {
        display: block;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    .live-traffic .lt-sub-sep {
        display: none;
    }

    /* A rate and its capacity: the rate at the left, "of 1 Gbps" against the right edge. */
    .live-traffic .lt-sub-part.lt-sub-ratio {
        display: flex;
        justify-content: space-between;
        gap: 0.35rem;
    }

    .live-traffic .lt-sub-ratio .lt-sub-of {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Room for the longest sub (a WAN without capacity: down, up, clients), so a part that comes and goes moves nothing. */
    .live-traffic .lt-stat-sub {
        min-height: calc(3 * 1.5em);
        line-height: 1.5;
    }

    /* After the desktop rule, so it wins: same specificity. */
    .live-traffic .lt-stat .card-body {
        padding: 0.5rem 0.6rem;
    }

    .lt-stat-value {
        font-size: 1.1rem;
    }

    .lt-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .lt-sankey-card,
    .lt-desktop-only {
        display: none;
    }

    .lt-mobile-list {
        display: block;
    }

    .live-traffic .lt-mobile-only,
    .lt-client .lt-mobile-only {
        display: flex;
    }

    .live-traffic .lt-mobile-tabs {
        display: flex;
    }

    .lt-body.lt-mtab-flows > .lt-grid,
    .lt-body.lt-mtab-dns > .card {
        display: none;
    }

    .lt-filterbar .lt-right,
    .lt-card-tools .lt-tools-right {
        margin-left: 0;
    }

    /* The presets share the search row and the pills wrap below it: the search leaves room for the presets
       alone. The shorter hint replaces the placeholder, which CSS cannot reword. */
    .lt-filterbar .lt-search {
        order: -2;
        flex: 1 1 calc(100% - 8rem);
        min-width: 0;
        max-width: none;
    }

    .lt-filterbar .filter-presets {
        order: -1;
    }

    .lt-search .form-control::placeholder {
        color: transparent;
    }

    .lt-search .form-control:placeholder-shown + .lt-search-hint {
        display: block;
    }

    .lt-tl-svg {
        height: 96px;
    }

    .lt-nested-table .hogs-col-rate { width: 25%; }
    .lt-nested-table .hogs-col-share { width: 16%; }

    .lt-nested-table td,
    .lt-nested-table th {
        padding: 0.3rem 0.4rem;
    }

    .lt-nested-table td:nth-child(2) {
        padding-left: 0.9rem;
    }

    .lt-nested-more {
        padding-left: 0.9rem;
    }
}

/* Client Performance - Data / Apps: one client's Live Traffic, in that page's card style. */
.lt-client .chart-card-header h3 {
    margin: 0;
}

.lt-client-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

/* The header's controls sit together at its right; the title takes what is left. */
.lt-client-header > .lt-client-title {
    flex: 1 1 auto;
}

/* A same-page jump beside a card title ("Live DNS ↓"). */
.lt-title-jump {
    font-size: 0.8rem;
    color: var(--text-secondary);
    text-decoration: none;
    white-space: nowrap;
    margin-left: 0.25rem;
}

.lt-title-jump:hover {
    color: var(--primary-hover);
}

.lt-client-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.lt-client-actions .monitoring-jump-btn:last-child {
    margin-right: -0.35rem;
}

@media (max-width: 768px) {
    .lt-client-actions .time-range-selector {
        flex: 0 0 auto;
        width: auto;
    }

    .lt-client-actions .time-range-selector .time-btn {
        flex: 0 0 auto;
        padding: 0.3rem 0.6rem;
        font-size: 0.75rem;
    }
}

/* Client Performance's table pads cells wider than Live Traffic's: the rank keeps its chevron and number. */
.lt-client .lt-flows .lt-rank {
    padding-right: 4px;
}

.lt-client-summary {
    margin: -4px 0 10px;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lt-client-chips {
    margin-bottom: 0.6rem;
}

.lt-client-state {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 4.5rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

/* The reason wraps whole; its link never breaks across lines. */
.lt-client-state {
    flex-wrap: wrap;
}

.lt-client-state > a {
    white-space: nowrap;
}

.lt-client-state.loading-container {
    flex-direction: column;
    justify-content: center;
}

/* No Gateway agent: the one-line reason, then the client's History from UniFi Network. */
.lt-client-state:has(+ .lt-client-history) {
    min-height: 0;
    margin-bottom: 0.9rem;
}

.lt-client-history-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.6rem;
    margin-bottom: 0.5rem;
}

.lt-client-empty {
    padding: 1.25rem 0;
}

.lt-client .lt-mobile-sort {
    margin-bottom: 0.5rem;
}

/* Padding rows: the height of a row with its sub-line, and nothing in them. */
.lt-client tr.lt-slot-empty td,
.live-traffic tr.lt-slot-empty td {
    border-bottom-color: transparent;
}

.lt-client .lt-mobile-list .lt-m-row.lt-slot-empty {
    min-height: 4.6rem;
    border-bottom-color: transparent;
}

.lt-client .lt-mobile-list .lt-m-row.lt-dns-slot {
    min-height: 3.4rem;
}

/* Applications - Right now: the client's live apps, wrapping so none is cut off at the card's edge.
   Baseline: the label sits on the text line of the first row of chips, whatever their height. */
.lt-now {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-height: 2rem;
    margin: 0 0 0.6rem;
}

.lt-now-label {
    flex: 0 0 auto;
    color: var(--text-secondary);
    font-size: 0.6875rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.lt-now-chips {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    gap: 0.4rem;
    min-width: 0;
}

.lt-now-chip {
    flex: 0 0 auto;
    gap: 0.4rem;
    padding: 0.25rem 0.55rem;
}

.lt-now-name {
    color: var(--text-primary);
}

/* Each rate in a fixed slot, so a chip keeps its width as the rate moves. */
.lt-now-rates {
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.lt-now-rates .speed-down,
.lt-now-rates .speed-up {
    display: inline-block;
    min-width: 4.8em;
}

.lt-now-rates .speed-down {
    text-align: right;
}

/* The kept app's chip is filled with the primary blue: its figures read in its text color. */
.lt-now-chip.active .speed-down,
.lt-now-chip.active .speed-up,
.lt-now-chip.active .lt-now-flows {
    color: inherit;
}

@media (max-width: 768px) {
    .lt-now-flows {
        display: none;
    }
}

.lt-now-flows {
    color: var(--text-muted);
    font-size: 0.72rem;
}

.lt-now-empty {
    color: var(--text-muted);
    font-size: 0.8rem;
    white-space: nowrap;
}

/* Client Performance - Speed: what the client moves through the Gateway, under Live Throughput. */
.lt-note {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 10px;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

.lt-note-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.lt-note-line {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lt-note-link {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* On a phone the link takes its own line under the two the note always has. */
@media (max-width: 768px) {
    .lt-note {
        flex-direction: column;
        align-items: stretch;
        gap: 0.2rem;
    }

    .lt-note-link {
        align-self: flex-start;
    }
}

/* ============================================
   Change Control (every rule scoped to .change-control)
   ============================================ */

.change-control {
    --cc-person: #3b82f6;
    --cc-unattributed: var(--warning-color);
    --cc-firmware: #a78bfa;
    --cc-no: #2ba89a;
    --cc-incident: rgba(239, 88, 88, 0.22);
    --cc-badge-col: 110px;
}

/* .card clips its content; the Custom Range popover opens below the toolbar, past the card's edge. */
.change-control .cc-toolbar-card {
    overflow: visible;
}

.change-control .cc-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    padding: 12px 16px;
}

.change-control .cc-toolbar-label {
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.change-control .cc-toolbar .form-control {
    width: auto;
    min-width: 120px;
}

/* A long option (a snapshot's time, a template's name) must not widen the bar; the open list
   still sizes to its options. */
.change-control .cc-toolbar select.form-control {
    max-width: 238px;
    text-overflow: ellipsis;
}
.change-control .cc-toolbar-spacer {
    flex: 1;
}

.change-control .cc-toolbar-note {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    margin-left: auto;
}

.change-control .cc-toolbar .cc-search {
    min-width: 260px;
}

.change-control .cc-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: none;
    font-size: 0.8125rem;
    cursor: pointer;
    min-height: 32px;
}

.change-control .cc-chip.off {
    background: transparent;
    color: var(--text-muted);
}

.change-control .cc-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
    flex-shrink: 0;
}

.change-control .cc-dot.person { background: var(--cc-person); }
.change-control .cc-dot.unattributed { background: var(--cc-unattributed); }
.change-control .cc-dot.firmware { background: var(--cc-firmware); }
.change-control .cc-dot.no { background: var(--cc-no); }
.change-control .cc-dot.online { background: var(--success-color); }
.change-control .cc-dot.offline { background: var(--warning-color); }

.change-control .cc-legend {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.change-control .cc-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.change-control .cc-legend .cc-band-key {
    width: 14px;
    height: 10px;
    background: var(--cc-incident);
    border-radius: 2px;
}

/* Stat tiles */
.change-control .cc-tiles {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.change-control .cc-tile {
    background: var(--bg-card);
    border-radius: var(--border-radius-lg);
    padding: 14px 16px;
}

.change-control .cc-tile-label {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.change-control .cc-tile-value {
    font-size: 1.5rem;
    font-weight: 600;
    margin: 0.2rem 0;
}

.change-control .cc-tile-value.danger { color: var(--danger-color); }
.change-control .cc-tile-value.warning { color: var(--warning-color); }

.change-control .cc-tile-sub {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

/* Rows that lead with a type badge: fixed badge column so the text aligns */
.change-control .cc-item {
    display: grid;
    grid-template-columns: var(--cc-badge-col) minmax(0, 1fr) auto;
    gap: 0.5rem 1rem;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
}

.change-control .cc-item:last-child {
    border-bottom: none;
}

.change-control .cc-item-title {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.change-control .cc-item-detail {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    margin-top: 0.15rem;
}

.change-control .cc-item-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.change-control .cc-site-chip {
    font-size: 0.75rem;
    padding: 0.1rem 0.45rem;
    border-radius: var(--border-radius);
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-weight: 500;
}

.change-control .cc-badge-col .status-badge,
.change-control .cc-sites-table .status-badge {
    white-space: nowrap;
}

.change-control .cc-two-col {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.change-control .cc-kv {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.875rem;
}

.change-control .cc-kv:last-child {
    border-bottom: none;
}

.change-control .cc-kv > :first-child {
    color: var(--text-secondary);
}

.change-control .cc-kv > :last-child {
    text-align: right;
}

.change-control .cc-upgrade-card .cc-kv > :last-child {
    font-size: 0.8125rem;
}

.change-control .cc-plan-row {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
}

.change-control .cc-plan-row:last-child {
    border-bottom: none;
}

.change-control .cc-plan-row-head {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    align-items: flex-start;
    font-weight: 500;
    font-size: 0.875rem;
}

.change-control .cc-progress {
    height: 4px;
    background: var(--bg-tertiary);
    border-radius: 2px;
    margin-top: 0.6rem;
    overflow: hidden;
}

.change-control .cc-progress > div {
    height: 100%;
    background: var(--primary-hover);
}

.change-control .danger-text { color: var(--danger-color); }
.change-control .warning-text { color: var(--warning-color); }
.change-control .success-text { color: var(--success-color); }
.change-control .muted-text { color: var(--text-muted); }

/* Timeline */
.change-control .cc-timeline {
    padding: 0 16px 12px;
}

.change-control .cc-tl-row {
    display: grid;
    grid-template-columns: 20px 190px minmax(0, 1fr) 130px;
    gap: 0 0.75rem;
    align-items: center;
    min-height: 52px;
    padding: 0 0.5rem;
    border-bottom: 1px solid var(--border-color);
}

.change-control .cc-tl-row.cc-tl-axis {
    min-height: 32px;
    border-bottom: none;
    color: var(--text-secondary);
    font-size: 0.8125rem;
}

.change-control .cc-tl-axis-labels {
    position: relative;
    height: 20px;
}

.change-control .cc-tl-axis-labels span {
    position: absolute;
    transform: translateX(-50%);
    white-space: nowrap;
}

.change-control .cc-tl-site {
    cursor: pointer;
}

.change-control .cc-tl-site:hover {
    background: var(--bg-hover-subtle);
}

.change-control .cc-tl-name {
    font-weight: 500;
    line-height: 1.25;
}

.change-control .cc-tl-sub {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.change-control .cc-tl-counts {
    text-align: right;
    font-size: 0.8125rem;
    color: var(--text-secondary);
    line-height: 1.3;
}

.change-control .cc-tl-counts b {
    color: var(--text-primary);
    font-weight: 600;
}

.change-control .cc-track {
    position: relative;
    height: 36px;
}

/* Placed, not auto-placed: the row's .cc-tl-lines already holds this cell, so auto-placement would skip past it. */
.change-control .cc-tl-row > .cc-track {
    grid-column: 3;
    grid-row: 1;
}

.change-control .cc-track.cc-lane-track {
    height: 64px;
}

.change-control .cc-track svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    /* Drawn over the bands: without this it takes their hover and their tooltips never open. */
    pointer-events: none;
}

/* Hover target for a band's tooltip only; the row layer (.cc-row-band) draws it across the full row. */
.change-control .cc-band {
    position: absolute;
    top: 0;
    bottom: 0;
}

.change-control .cc-select-line {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--text-primary);
    opacity: 0.85;
    transform: translateX(-1px);
    pointer-events: none;
}

.change-control .cc-after .status-badge,
.change-control .cc-who {
    white-space: nowrap;
}

/*
 * Each row's slice of the bands and change lines, full row height in the track's column, so the site row,
 * lanes, and Events row join into one. Every slice starts at the layer's top and offsets its pattern by
 * --cc-y (its offset in the timeline, set by cc-timeline.js), so dashes and stripes run on across rows.
 */
.change-control .cc-tl-lines {
    grid-column: 3;
    grid-row: 1 / -1;
    align-self: stretch;
    position: relative;
    pointer-events: none;
}

.change-control .cc-row-band,
.change-control .cc-marker-line {
    position: absolute;
    top: 0;
    bottom: 0;
    background-position: 0 calc(-1 * var(--cc-y, 0px));
}

.change-control .cc-row-band.incident {
    background-color: var(--cc-incident);
}

.change-control .cc-row-band.gap {
    background-image: repeating-linear-gradient(45deg, rgba(160, 160, 168, 0.16) 0 4px, transparent 4px 8px);
    background-size: 11.3137px 11.3137px;
}

.change-control .cc-marker-line {
    width: 1px;
    background-image: repeating-linear-gradient(to bottom, rgba(160, 160, 168, 0.45) 0 3px, transparent 3px 6px);
    background-size: 1px 6px;
}

/* The site row bridges its border and the lanes' margin and padding down to the first lane. */
.change-control .cc-tl-lines.from-marker > div {
    bottom: calc(-1px - 0.5rem);
}

/* Lines start at the site row's marker (mid-row) and stop at the Events row's; bands span the whole row. */
.change-control .cc-tl-lines.from-marker .cc-marker-line,
.change-control .cc-tl-lines.from-marker .cc-select-line {
    clip-path: inset(calc(50% - (1px + 0.5rem) / 2) 0 0 0);
}

.change-control .cc-tl-lines.to-marker .cc-marker-line,
.change-control .cc-tl-lines.to-marker .cc-select-line {
    clip-path: inset(0 0 50% 0);
}

.change-control .cc-marker {
    position: absolute;
    top: 50%;
    width: 12px;
    height: 12px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: none;
    padding: 0;
    cursor: pointer;
    background: var(--text-muted);
}

/* A small pad for a mouse: a wider one covers the next marker in a tight bunch, and the
   older (left) marker paints on top, so hover and click land on the wrong event. */
.change-control .cc-marker::before {
    content: "";
    position: absolute;
    inset: -3px;
}

/* 44px touch target around the 12px marker */
@media (pointer: coarse) {
    .change-control .cc-marker::before {
        inset: -16px;
    }
}

.change-control .cc-marker.person { background: var(--cc-person); }
.change-control .cc-marker.unattributed { background: var(--cc-unattributed); }
.change-control .cc-marker.no { background: var(--cc-no); }
.change-control .cc-marker.firmware {
    background: var(--cc-firmware);
    border-radius: 2px;
    transform: translate(-50%, -50%) rotate(45deg);
}

.change-control .cc-marker.selected {
    box-shadow: 0 0 0 3px var(--bg-card), 0 0 0 5px var(--text-primary);
}

.change-control .cc-lanes {
    background: var(--bg-hover-subtle);
    border-radius: var(--border-radius-lg);
    margin: 0.25rem 0 0.5rem;
    padding: 0.25rem 0;
}

.change-control .cc-lanes .cc-tl-row {
    border-bottom: none;
    min-height: 74px;
}

.change-control .cc-lane-latest {
    text-align: right;
    font-size: 0.8125rem;
    line-height: 1.4;
}

.change-control .cc-lane-stack span + span {
    margin-left: 0.4rem;
}

.change-control .cc-lane-latest .a { color: var(--cc-no); }
.change-control .cc-lane-latest .rtt { color: #d946ef; }
.change-control .cc-lane-latest .health { color: var(--success-color); }

/* Site Health levels (Change Control, Dashboard Sites panel, Sites page): 95+ healthy, 85+ degraded */
.health-healthy, .cc-health-healthy { color: var(--success-color); }
.health-degraded, .cc-health-degraded { color: var(--warning-color); }
.health-down, .cc-health-down { color: var(--danger-color); }
.health-unknown, .cc-health-unknown { color: var(--text-muted); }

.change-control .cc-health-line.healthy { stroke: var(--success-color); }
.change-control .cc-health-line.degraded { stroke: var(--warning-color); }
.change-control .cc-health-line.down { stroke: var(--danger-color); }
.change-control .cc-health-line.unknown { stroke: var(--text-muted); }

.change-control .cc-health-zone {
    position: absolute;
    top: 0;
    bottom: 0;
}

.change-control .cc-health-delta {
    margin-left: 0.25rem;
    font-size: 0.75rem;
}

.change-control .cc-health-delta.down { color: var(--danger-color); }
.change-control .cc-health-delta.up { color: var(--success-color); }
.change-control .cc-lane-latest .loss { color: #ef4444; }
.change-control .cc-lane-latest .b { color: var(--warning-color); }
.change-control .cc-lane-latest .cpu { color: var(--cc-firmware); }
.change-control .cc-lane-latest .down { color: var(--speed-download-color); }
.change-control .cc-lane-latest .up { color: var(--speed-upload-color); }

/* Change detail */
/* Zero intrinsic width: the details cell spans every column, so its content would otherwise re-split the table's columns as it opens. */
.change-control .history-details-row > td > .expand-wrapper {
    width: 0;
    min-width: 100%;
}

.change-control .cc-detail-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    padding: 0.75rem 16px 1rem;
}

.change-control .cc-panel {
    background: var(--bg-card);
    border-radius: var(--border-radius-lg);
    padding: 12px 16px;
}

.change-control .cc-panel-title {
    font-weight: 600;
    font-size: 0.875rem;
    margin-bottom: 0.25rem;
}

.change-control .cc-panel .action-buttons {
    margin-top: 0.75rem;
}

.change-control .cc-field-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 0.8125rem;
}

.change-control .cc-field-table td {
    padding: 0.4rem 0.5rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
    overflow-wrap: anywhere;
}

.change-control .cc-field-table tr:last-child td {
    border-bottom: none;
}

.change-control .cc-field-table .old { color: var(--danger-color); }
.change-control .cc-field-table .new { color: var(--success-color); }
.change-control .cc-field-table .label { color: var(--text-secondary); width: 50%; }

.change-control .cc-inset {
    background: var(--bg-inset);
    border-radius: var(--border-radius-lg);
    margin: 0 16px 0.75rem;
    padding: 0.25rem 0.5rem;
}

.change-control .cc-inset-note {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    padding: 0 16px 0.75rem;
}

.change-control .cc-action-text.created { color: var(--success-color); }
.change-control .cc-action-text.updated { color: var(--primary-light); }
.change-control .cc-action-text.deleted { color: var(--danger-color); }

/* The arrow between an old and a new value; the text stays for copy-paste and screen readers.
   Inline throughout: a flex or positioned box drops the spaces around "to" from copied text. */
.change-control .cc-to {
    margin: 0 0.35em;
    color: var(--text-muted);
}

.change-control .cc-to svg {
    vertical-align: -0.15em;
}

.change-control .cc-to-text {
    font-size: 0;
}

/* Change detail: Security Audit and Settings group headings, fixed and new issues, who made it. */
.change-control .cc-detail-head td {
    padding-top: 0.6rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.change-control .cc-audit-kind {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.change-control .cc-audit-kind.fixed { color: var(--success-color); }
.change-control .cc-audit-kind.new { color: var(--danger-color); }

.change-control .cc-audit-device,
.change-control .cc-source-via {
    color: var(--text-secondary);
    font-size: 0.75rem;
}

.change-control .cc-source {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.1rem;
}

.change-control .cc-source-who {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 600;
}

.change-control .cc-source-who svg { color: var(--text-secondary); }

.change-control .cc-source-via code {
    color: var(--text-muted);
    background: none;
    padding: 0;
    font-size: 0.75rem;
}

/* A policy order change: each moved rule with its neighbors before and after. */
.change-control .cc-order-move + .cc-order-move {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.change-control .cc-order-move-head {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}

.change-control .cc-order-pos {
    color: var(--text-secondary);
    white-space: nowrap;
}

.change-control .cc-order-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    margin-top: 0.4rem;
}

.change-control .cc-order-col-title {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-bottom: 0.2rem;
}

.change-control .cc-order-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.change-control .cc-order-list li {
    display: flex;
    gap: 0.4rem;
    padding: 0.15rem 0.35rem;
    border-radius: 4px;
    color: var(--text-secondary);
}

.change-control .cc-order-list li .n {
    color: var(--text-muted);
    min-width: 1.6rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.change-control .cc-order-list li.moved {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    font-weight: 600;
}

.change-control .cc-order-list li.end {
    color: var(--text-muted);
    font-style: italic;
}

.change-control .cc-order-more {
    margin-top: 0.5rem;
    color: var(--text-secondary);
}

@media (max-width: 768px) {
    .change-control .cc-order-cols { grid-template-columns: 1fr; }
}

.change-control .cc-group-row td {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    background: var(--bg-tertiary);
}

.change-control .cc-compare-sides {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 1rem;
    align-items: center;
    padding: 16px;
}

.change-control .cc-compare-sides .cc-panel {
    background: var(--bg-hover-subtle);
}

/* Old and new, in the diff tables' colors. */
.change-control .cc-side-from {
    border-left: 3px solid var(--danger-color);
}

.change-control .cc-side-to {
    border-left: 3px solid var(--success-color);
}

.change-control .cc-side-kicker {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
}

.change-control .cc-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--primary-hover);
    flex-shrink: 0;
}

.change-control .cc-side-label {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.change-control .cc-side-value {
    font-weight: 600;
    font-size: 1.05rem;
}

/* Snapshots: a long trigger is cut off with its full text in a tooltip, so it cannot squeeze the actions.
   The tooltip starts at 40 characters, below where 22rem cuts, so every cut-off trigger has one. */
.change-control .cc-trigger {
    display: block;
    max-width: 22rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.change-control .cc-row-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.25rem 0.75rem;
    flex-wrap: wrap;
}

.change-control .cc-link-btn {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.8125rem;
    padding: 0.35rem 0.25rem;
    min-height: 32px;
    cursor: pointer;
}

.change-control .cc-link-btn:hover {
    color: var(--text-primary);
}

.change-control .cc-action-spacer {
    display: inline-block;
    visibility: hidden;
}

/* The Baseline's pin: shown filled, but it is a state, not a control. */
.change-control .cc-pin-locked,
.change-control .cc-pin-locked:hover {
    display: inline-block;
    cursor: default;
    color: var(--text-secondary);
}

.change-control .cc-tags {
    display: inline-flex;
    gap: 0.35rem;
    flex-wrap: wrap;
}

.change-control .cc-card-footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 12px 16px;
    border-top: 1px solid var(--border-color);
}

/* Holds its height as approvals swap the footer's buttons and text. */
.change-control .cc-plan-footer {
    min-height: 70px;
}

/* Beside the buttons: .cc-remaining already takes the free space. */
.change-control .cc-plan-footer .cc-gateway-status {
    margin-left: 0;
}

.change-control .cc-card-footer .cc-remaining {
    margin-right: auto;
    font-size: 0.875rem;
}

.change-control .cc-remaining-icon {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.change-control .cc-remaining-icon svg {
    flex-shrink: 0;
}

.change-control .cc-card-footer .cc-edit-count {
    font-size: 0.875rem;
}

/* Review Plan */
.change-control .cc-strip {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.change-control .cc-impact-row {
    display: grid;
    grid-template-columns: var(--cc-badge-col) minmax(0, 1fr) auto;
    gap: 0.5rem 1rem;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    align-items: start;
}

.change-control .cc-impact-row:last-child {
    border-bottom: none;
}

.change-control .cc-confirm {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
    flex-wrap: wrap;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.change-control .cc-confirm .form-control {
    max-width: 240px;
}

.change-control .cc-write-step {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 0.75rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border-color);
}

.change-control .cc-write-step:last-child {
    border-bottom: none;
}

.change-control .cc-write-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.5rem;
}

.change-control .cc-write-summary .cc-link-btn {
    padding: 0;
    color: var(--primary-hover);
}

.change-control .cc-write-list {
    list-style: none;
    margin: 0.35rem 0 0.25rem;
    padding: 0.4rem 0.6rem;
    max-height: 18rem;
    overflow-y: auto;
    border-left: 2px solid var(--border-color);
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

.change-control .cc-write-list li {
    padding: 0.15rem 0;
    overflow-wrap: anywhere;
}

.change-control .cc-step-num {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-size: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.change-control .cc-state-track {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.875rem;
    color: var(--text-muted);
}

.change-control .cc-state-track .on {
    color: var(--text-primary);
}

.change-control .cc-state-track .on .cc-dot {
    background: var(--primary-hover);
}

.change-control .cc-sticky-footer {
    position: sticky;
    bottom: 0;
    z-index: 5;
    box-shadow: 0 -6px 16px rgba(0, 0, 0, 0.35);
}

.change-control .cc-ack-col {
    white-space: nowrap;
}

.change-control .cc-ack-col .checkbox-label {
    min-height: 44px;
    margin: 0;
}

/* Edit */
.change-control .cc-edit-grid {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.change-control .cc-collections button {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    background: none;
    border: none;
    border-left: 3px solid transparent;
    color: var(--text-primary);
    padding: 0.7rem 16px;
    min-height: 44px;
    font-size: 0.875rem;
    text-align: left;
    cursor: pointer;
}

.change-control .cc-collections button:hover {
    background: var(--bg-hover-subtle);
}

.change-control .cc-collections button.active {
    background: var(--bg-hover);
    border-left-color: var(--primary-hover);
}

.change-control .cc-collections .cc-count {
    color: var(--text-muted);
    font-size: 0.8125rem;
}

.change-control .cc-collections button.cc-no-hits > span:first-child {
    color: var(--text-muted);
}

/* Collections search: the header's own height, so opening it does not move the list. */
.change-control .cc-collections-header {
    min-height: 52px;
    gap: 0.5rem;
}

.change-control .cc-find {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    width: 100%;
    min-width: 0;
}

.change-control .cc-find .form-control {
    flex: 1 1 auto;
    min-width: 0;
    height: 28px;
    padding: 0 0.5rem;
    font-size: 0.8125rem;
}

.change-control .cc-find-count {
    flex: 0 0 auto;
    font-size: 0.75rem;
    white-space: nowrap;
    margin: 0 0.25rem;
}

.change-control .cc-find-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: var(--border-radius);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
}

.change-control .cc-find-btn:hover:not(:disabled),
.change-control .cc-find-btn:focus-visible {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.change-control .cc-find-btn:disabled {
    opacity: 0.4;
    cursor: default;
}

/* CodeMirror (js/cc-editor.js) draws inside; its theme there sets fonts, colors, and height. */
.change-control .cc-editor {
    min-height: 480px;
}

.change-control .cc-editor.is-loading {
    display: none;
}

/* One column set for every row (subgrid), so the location column fits its longest entry and the
   messages still line up. */
.change-control .cc-problems {
    display: grid;
    grid-template-columns: 90px minmax(140px, max-content) minmax(0, 1fr);
    column-gap: 1rem;
}

.change-control .cc-problem {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    gap: 0.5rem 1rem;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-color);
    /* On the text's baseline, not the top: the location's smaller monospace sat above the message. */
    align-items: baseline;
    font-size: 0.875rem;
}

.change-control .cc-problem > div:last-child {
    font-size: 0.8rem;
}

.change-control .cc-problem:last-child {
    border-bottom: none;
}

.change-control .cc-problem code {
    color: var(--text-muted);
    background: none;
    font-size: 0.75rem;
}

/* The location goes to its line in the editor. */
.change-control .cc-problem-loc {
    justify-self: start;
    padding: 0;
    border: none;
    background: none;
    text-align: left;
    cursor: pointer;
}

.change-control .cc-problem-loc:hover code,
.change-control .cc-problem-loc:focus-visible code {
    color: var(--text-secondary);
    text-decoration: underline;
}
/* Migrate */
.change-control .cc-action-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.change-control .cc-action-card {
    background: var(--bg-card);
    border: 1px solid transparent;
    border-radius: var(--border-radius-lg);
    padding: 16px;
    text-align: left;
    color: var(--text-primary);
    cursor: pointer;
}

.change-control .cc-action-card:hover {
    background: var(--bg-hover-subtle);
}

.change-control .cc-action-card.active {
    border-color: var(--primary-hover);
}

.change-control .cc-action-card h3 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.35rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.change-control .cc-action-card p {
    margin: 0;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.change-control .cc-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.875rem;
}

.change-control .cc-steps span {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-muted);
}

.change-control .cc-steps span.done,
.change-control .cc-steps span.current {
    color: var(--text-primary);
}

.change-control .cc-steps .cc-step-num.done {
    background: rgba(36, 188, 112, 0.2);
    color: var(--success-color);
}

.change-control .cc-steps .cc-step-num.current {
    background: var(--primary-color);
    color: #fff;
}

.change-control .cc-zones {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    padding: 0 16px 16px;
}

.change-control .cc-zone {
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    padding: 12px;
    min-height: 180px;
}

.change-control .cc-zone.drop-target {
    border-color: var(--primary-hover);
}

/* During a drag only the zone takes the pointer: a child under the cursor fires dragleave on the zone, and Drop here flickers. */
.change-control .cc-zones.dragging .cc-zone * {
    pointer-events: none;
}

.change-control .cc-zone-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
}

.change-control .cc-zone-desc {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    margin: 0.25rem 0 0.6rem;
}

.change-control .cc-net {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    background: var(--bg-tertiary);
    border: 1px solid transparent;
    border-radius: var(--border-radius);
    color: var(--text-primary);
    padding: 0.55rem 0.7rem;
    min-height: 44px;
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
    cursor: grab;
    text-align: left;
}

.change-control .cc-net.selected {
    border-color: var(--primary-hover);
}

.change-control .cc-net .cc-vlan {
    color: var(--text-secondary);
    margin-left: 0.4rem;
    font-size: 0.8125rem;
}

.change-control .cc-drop-here {
    border: 1px dashed var(--primary-hover);
    border-radius: var(--border-radius);
    color: var(--primary-light);
    text-align: center;
    padding: 0.55rem;
    min-height: 44px;
    font-size: 0.875rem;
    background: none;
    width: 100%;
    cursor: pointer;
}

/* Settings */
.change-control .cc-settings-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    align-items: start;
}

.change-control .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.change-control .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

@media (max-width: 1024px) {
    .change-control .cc-tiles {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .change-control .cc-two-col,
    .change-control .cc-edit-grid,
    .change-control .cc-settings-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .change-control .cc-zones {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 768px) {
    .change-control {
        --cc-badge-col: 92px;
    }

    .change-control .cc-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.75rem;
    }

    .change-control .cc-strip {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .change-control .cc-item {
        grid-template-columns: var(--cc-badge-col) minmax(0, 1fr);
    }

    .change-control .cc-item-actions {
        grid-column: 1 / -1;
        justify-content: flex-start;
    }

    .change-control .cc-impact-row {
        grid-template-columns: minmax(0, 1fr);
    }

    .change-control .cc-tl-row {
        grid-template-columns: 16px 104px minmax(0, 1fr);
    }

    .change-control .cc-tl-counts {
        display: none;
    }

    .change-control .cc-detail-grid {
        grid-template-columns: minmax(0, 1fr);
        padding: 0.75rem 0.5rem 1rem;
    }

    .change-control .cc-compare-sides {
        grid-template-columns: minmax(0, 1fr);
    }

    .change-control .cc-compare-sides .cc-arrow {
        display: none;
    }

    .change-control .cc-zones {
        grid-template-columns: minmax(0, 1fr);
    }

    .change-control .cc-problems {
        grid-template-columns: minmax(0, 1fr);
    }

    .change-control .cc-problem {
        grid-template-columns: 80px minmax(0, 1fr);
    }

    .change-control .cc-problem > code,
    .change-control .cc-problem > .cc-problem-loc {
        grid-column: 2;
        grid-row: 1;
        justify-self: end;
    }

    .change-control .cc-problem > div:last-child {
        grid-column: 1 / -1;
    }

    .change-control .cc-toolbar .cc-search {
        min-width: 0;
        flex: 1 1 100%;
    }

    .change-control .form-row {
        flex-direction: column;
        gap: 0;
    }

    .change-control .form-row > .form-group {
        flex: 0 0 auto;
    }

    .change-control .cc-toolbar-note {
        margin-left: 0;
    }
}

@media (max-width: 768px) {
    .change-control .cc-mobile-order {
        display: flex;
        flex-direction: column;
    }

    .change-control .cc-mobile-order > .cc-two-col,
    .change-control .cc-mobile-order .cc-side-col {
        display: contents;
    }

    .change-control .cc-sites-card { order: 1; }
    .change-control .cc-attention-card { order: 2; }
    .change-control .cc-plans-card { order: 3; }
    .change-control .cc-upgrade-card { order: 4; }
}

.change-control .cc-attention-card .empty-state p {
    margin-bottom: 0.25rem;
}

.change-control td .cc-dot {
    margin-right: 0.35rem;
}

.change-control .data-table th {
    white-space: nowrap;
}

.change-control .cc-tags .status-badge {
    white-space: nowrap;
}

@media (min-width: 769px) {
    .change-control .cc-toolbar .cc-search {
        min-width: 360px;
    }
}

.change-control .radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
}

.change-control .cc-site-list-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
}

.change-control .cc-site-list-row:last-child {
    border-bottom: none;
}

@media (max-width: 768px) {
    .change-control .cc-tile-sites,
    .change-control .cc-tile-drift {
        display: none;
    }

    .change-control .cc-tile-security { order: 1; }
    .change-control .cc-tile-changes { order: 2; }
    .change-control .cc-tile-unattributed { order: 3; }
    .change-control .cc-tile-plans { order: 4; }

    .change-control .cc-item {
        display: block;
    }

    .change-control .cc-item .cc-badge-col {
        display: flex;
        gap: 0.4rem;
        margin-bottom: 0.4rem;
    }

    .change-control .cc-item-actions {
        margin-top: 0.75rem;
    }

    .change-control .cc-item-actions .btn {
        flex: 1 1 0;
        min-height: 44px;
    }
}

.change-control .cc-plan-row-head .status-badge {
    white-space: nowrap;
    flex-shrink: 0;
}

.change-control .cc-change-card {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-size: 0.875rem;
}

.change-control .cc-change-card-head {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.8125rem;
}

@media (max-width: 768px) {
    .change-control .cc-toolbar .form-control,
    .change-control .cc-toolbar select.form-control {
        width: 100%;
        max-width: none;
    }

    .change-control .cc-toolbar .cc-toolbar-label {
        flex: 1 1 100%;
        margin-bottom: -0.4rem;
    }

    .change-control .cc-toolbar .time-range-selector {
        width: 100%;
    }

    .change-control .cc-toolbar .time-range-selector .time-btn {
        flex: 1;
        min-height: 36px;
    }

    .change-control .cc-tl-row,
    .change-control .cc-lanes .cc-tl-row {
        grid-template-columns: 16px minmax(0, 1fr) auto;
        grid-template-areas: "chev label counts" "track track track";
        gap: 0.35rem 0.5rem;
        padding: 0.5rem 0;
        min-height: 0;
    }

    .change-control .cc-tl-row.cc-tl-axis {
        grid-template-areas: "track track track";
        padding: 0;
    }

    .change-control .cc-tl-axis > span {
        display: none;
    }

    .change-control .cc-tl-axis-labels {
        grid-area: track;
    }

    .change-control .cc-tl-chev { grid-area: chev; }
    .change-control .cc-tl-label { grid-area: label; }
    .change-control .cc-tl-row > .cc-track { grid-area: track; }

    /* The track spans every column under the label, and the row's padding is covered so rows still join. */
    .change-control .cc-tl-lines {
        grid-column: 1 / -1;
        margin: -0.5rem 0;
    }

    /* The marker sits mid-track at the bottom of the row: padding plus half the 36px track. */
    .change-control .cc-tl-lines.from-marker .cc-marker-line,
    .change-control .cc-tl-lines.from-marker .cc-select-line {
        clip-path: inset(calc(100% - 1px - 1rem - 18px) 0 0 0);
    }

    .change-control .cc-tl-lines.to-marker .cc-marker-line,
    .change-control .cc-tl-lines.to-marker .cc-select-line {
        clip-path: inset(0 0 calc(0.5rem + 18px) 0);
    }

    .change-control .cc-tl-counts,
    .change-control .cc-lane-latest {
        display: block;
        grid-area: counts;
        text-align: right;
        white-space: nowrap;
    }

    .change-control .cc-tl-counts div,
    .change-control .cc-lane-latest div {
        display: inline;
    }

    .change-control .cc-tl-counts div + div::before {
        content: ", ";
    }

    .change-control .cc-lane-latest div + div::before {
        content: " ";
    }

    .change-control .cc-tl-sub {
        display: none;
    }

    /* No side padding, so lane tracks line up with the site row's and the bands and lines run straight. */
    .change-control .cc-lanes {
        padding: 0.25rem 0;
    }

    .change-control .cc-lanes .cc-tl-label,
    .change-control .cc-lanes .cc-lane-latest {
        padding: 0 0.5rem;
    }

    .change-control .cc-lane-row .cc-tl-chev {
        display: none;
    }

    .change-control .cc-lane-row {
        grid-template-areas: "label label counts" "track track track";
    }
}

@media (max-width: 768px) {
    .change-control .cc-tl-counts {
        display: flex;
        justify-content: flex-end;
    }
}

.change-control .cc-plan-card {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.875rem;
    cursor: pointer;
}

.change-control .cc-mobile-group {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    padding: 0.6rem 16px 0.3rem;
}

.change-control .cc-mobile-field {
    padding: 0.35rem 0.25rem;
    font-size: 0.8125rem;
}

@media (max-width: 768px) {
    .change-control .cc-tile-site {
        display: none;
    }

    .change-control .cc-sticky-footer .cc-card-footer .btn {
        flex: 1 1 40%;
        min-height: 44px;
    }

    .change-control .cc-sticky-footer .cc-card-footer .btn-primary {
        order: -1;
        flex-basis: 100%;
    }

    .change-control .cc-sticky-footer .cc-remaining {
        order: -2;
        flex-basis: 100%;
    }

    /* Its own line under the state track, above the primary button. */
    .change-control .cc-sticky-footer .cc-gateway-status {
        order: -2;
        flex-basis: 100%;
        padding: 0;
    }
}

.change-control .cc-phone-only,
.change-control .cc-phone-inline {
    display: none;
}

@media (max-width: 768px) {
    .change-control .cc-phone-only {
        display: block;
    }

    .change-control .cc-phone-inline {
        display: inline-flex;
    }
}

.change-control .cc-snap-card {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    cursor: pointer;
    font-size: 0.875rem;
}

.change-control .cc-snap-card input {
    width: 20px;
    height: 20px;
    margin-top: 2px;
}

@media (max-width: 768px) {
    .change-control .cc-card-footer .btn {
        flex: 1 1 40%;
        min-height: 44px;
    }
}

.change-control .cc-item-detail .cc-dot,
.change-control .cc-change-card-head .cc-dot,
.change-control .cc-site-list-row .cc-dot {
    margin-right: 0.35rem;
}

/* Right-aligned even when the toolbar wraps, so Discard Edits sits above the editor's own header actions. */
.change-control .cc-edit-actions {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-left: auto;
}

.change-control .cc-header-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* The edited badge goes to the next edit: a status badge that is a button. */
.change-control .cc-edited-badge {
    border: none;
    font-family: inherit;
    line-height: inherit;
    cursor: pointer;
}

.change-control .cc-edited-badge:hover,
.change-control .cc-edited-badge:focus-visible {
    box-shadow: inset 0 0 0 1px currentColor;
    outline: none;
}

@media (max-width: 768px) {
    .change-control .cc-edit-actions {
        display: none;
    }

    .change-control .cc-card-footer .cc-phone-inline.btn {
        justify-content: center;
        align-items: center;
    }

    .change-control .cc-card-footer .btn-primary {
        flex-basis: 100%;
    }

    .change-control .cc-card-footer .cc-remaining,
    .change-control .cc-card-footer .muted-text {
        flex-basis: 100%;
    }
}

/* Alerts & Schedule - Incidents: changes before an incident */
.cc-incident-changes {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.8125rem;
}

.cc-incident-change {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    padding: 0.4rem 0;
}

.cc-incident-change .cc-link-btn {
    background: none;
    border: 0;
    padding: 0;
    color: var(--primary-hover);
    cursor: pointer;
    text-align: left;
    font: inherit;
}

.cc-incident-change .btn {
    margin-left: auto;
}

@media (max-width: 768px) {
    .cc-incident-change .btn {
        min-height: 44px;
        margin-left: 0;
    }
}

/* Change Control - Snapshots: Templates card */
.change-control .cc-template-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    padding: 12px 16px;
    border-top: 1px solid var(--border-color);
}

.change-control .cc-template-main {
    flex: 1 1 260px;
    min-width: 0;
}

.change-control .cc-template-form {
    border-top: 1px solid var(--border-color);
}

.change-control .cc-template-form .form-row {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.change-control .cc-template-form .form-row > .form-group {
    flex: 1 1 180px;
    min-width: 0;
}

.change-control .cc-template-collections {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.4rem 1rem;
}

.change-control .cc-template-yaml {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.8125rem;
}

@media (max-width: 768px) {
    .change-control .cc-template-form .form-row {
        flex-direction: column;
        gap: 0;
    }

    .change-control .cc-template-form .form-row > .form-group {
        flex: 0 0 auto;
    }

    .change-control .cc-template-row .cc-row-actions .btn {
        min-height: 44px;
    }
}

@media (max-width: 768px) {
    .change-control .cc-template-row .cc-row-actions {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.5rem;
        width: 100%;
    }
}

/* Change Control - Migrate */
.change-control button.cc-action-card {
    font: inherit;
    width: 100%;
}

.change-control .cc-device-pair {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 1rem;
    align-items: center;
    padding: 16px;
}

.change-control .cc-device-box {
    background: var(--bg-tertiary);
    border-radius: var(--border-radius);
    padding: 12px 16px;
    min-width: 0;
}

.change-control .cc-device-box b {
    display: block;
    margin: 0.15rem 0;
}

.change-control .cc-migrate-form {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.change-control .cc-migrate-form > .form-group {
    flex: 1 1 260px;
    min-width: 0;
}

.change-control .cc-port-table td {
    vertical-align: middle;
}

.change-control .cc-port-select {
    max-width: 240px;
}

.change-control .cc-select-error {
    border-color: var(--danger-color);
}

.change-control .cc-row-error {
    background: rgba(238, 99, 104, 0.08);
}

.change-control .cc-inline-ack {
    display: inline-flex;
    margin-left: 0.75rem;
}

.change-control .cc-card-note {
    padding: 10px 16px;
    font-size: 0.875rem;
    color: var(--text-secondary);
    border-top: 1px solid var(--border-color);
}

.change-control .cc-setting-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 10px 16px;
    border-top: 1px solid var(--border-color);
    font-size: 0.875rem;
}

.change-control .cc-setting-row .status-badge,
.change-control .cc-setting-row > .btn {
    flex-shrink: 0;
}

.change-control .cc-recable-row > span:first-child {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.change-control .cc-recable-row > span:last-child {
    text-align: right;
}

.change-control .cc-map-card {
    padding: 12px 16px;
    border-top: 1px solid var(--border-color);
    display: grid;
    gap: 0.5rem;
}

.change-control .cc-map-card .cc-port-select {
    max-width: none;
    min-height: 44px;
}

.change-control .cc-more {
    display: block;
    padding: 12px 16px;
    border-top: 1px solid var(--border-color);
    width: 100%;
    text-align: left;
}

.change-control .cc-pending-row {
    display: flex;
    padding: 10px 16px;
    border-top: 1px solid var(--border-color);
    min-height: 44px;
}

@media (max-width: 768px) {
    .change-control .cc-device-pair {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.5rem;
    }
}

.change-control .cc-steps .cc-phone-inline {
    display: none;
}

@media (max-width: 768px) {
    .change-control .cc-steps .cc-phone-inline {
        display: inline;
    }

    .change-control .cc-steps > span {
        flex-direction: column;
        gap: 0.25rem;
        text-align: center;
    }
}


.change-control .cc-forget {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

/* Change Control - Migrate - Re-address Networks */
.change-control .cc-readdress-pattern {
    margin-bottom: 0;
    max-width: 560px;
}

.change-control .cc-reconnect-poe {
    margin-top: 0.5rem;
    font-size: 0.8125rem;
}

@media (max-width: 768px) {
    /* A phone card carries its own 16px padding: rows that pad themselves would sit 16px in from the title. */
    .change-control .card > .cc-card-intro,
    .change-control .card > .cc-setting-row,
    .change-control .card > .cc-card-note,
    .change-control .card > .cc-card-footer,
    .change-control .card > .cc-more,
    .change-control .card > .cc-phone-only > .cc-map-card {
        padding-left: 0;
        padding-right: 0;
    }

    .change-control .cc-step-row {
        flex-direction: column;
        align-items: stretch;
    }

    .change-control .cc-step-row > .btn {
        min-height: 44px;
    }
}

/* Change Control - Migrate - Set Up Zones */
.change-control .cc-card-intro {
    padding: 12px 16px 0;
    margin: 0 0 12px;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.change-control .cc-zone-head {
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.change-control .cc-zone-head .cc-zone-desc {
    font-weight: 400;
    margin-bottom: 0;
}

.change-control .cc-zone.current {
    border-color: var(--primary-hover);
}

.change-control .cc-zone-add {
    display: flex;
    align-items: center;
    justify-content: center;
    border-style: dashed;
}

.change-control .cc-zone-add.is-idle {
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.change-control .cc-zone-add.is-idle:hover {
    border-color: var(--primary-hover);
    background: var(--bg-hover);
}

.change-control .cc-moving {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}

.change-control .cc-zone-mode {
    margin: 0;
}

@media (max-width: 768px) {
    .change-control .cc-zone-empty {
        display: none;
    }

    .change-control .cc-zone {
        min-height: 0;
    }

    .change-control .cc-zone-mode-phone .cc-zone-mode {
        display: grid;
        grid-template-columns: 1fr 1fr;
        margin-bottom: 1rem;
    }

    .change-control .cc-zone-mode-phone .time-btn {
        min-height: 44px;
    }
}

/* "On this page" (js/card-index.js): beside the content when the gutter fits, else a row above the first card. */
.card-index {
    position: fixed;
    z-index: 5;
    width: 168px;
    font-size: 0.8125rem;
}

.card-index-label {
    margin: 0 0 0.5rem 0.75rem;
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.card-index .card-index-link {
    display: block;
    padding: 0.3rem 0.75rem;
    border-left: 2px solid var(--border-color);
    color: var(--text-secondary);
    text-decoration: none;
}

.card-index-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin: 0 0 1rem;
    font-size: 0.8125rem;
}

.card-index-row .card-index-link {
    color: var(--text-secondary);
    text-decoration: none;
}

.card-index .card-index-link:hover,
.card-index-row .card-index-link:hover {
    color: var(--text-primary);
}

.card-index .card-index-link.active {
    border-left-color: var(--primary-color);
    color: var(--text-primary);
    font-weight: 500;
}

.card-index-row .card-index-link.active {
    color: var(--text-primary);
}

.card-index,
.card-index-row {
    animation: card-index-in 0.2s ease-out;
    transition: opacity 0.15s ease-in;
}

.card-index-link {
    transition: color 0.15s ease, border-color 0.15s ease;
}

/* Three levels: idle dims slowly, a scroll brings it halfway up, hover or focus to full. */
.card-index {
    opacity: 0.7;
}

.card-index.card-index-idle {
    opacity: 0.4;
    transition: opacity 1.2s ease;
}

.card-index:hover,
.card-index:focus-within {
    opacity: 1;
    transition: opacity 0.15s ease-out;
}

.card-index.card-index-out,
.card-index-row.card-index-out {
    opacity: 0;
    transition: opacity 0.15s ease-in;
}

@keyframes card-index-in {
    from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .card-index,
    .card-index.card-index-idle,
    .card-index:hover,
    .card-index:focus-within,
    .card-index.card-index-out,
    .card-index-row,
    .card-index-row.card-index-out,
    .card-index-link {
        animation: none;
        transition: none;
    }
}

/* iOS home-screen app: a download goes to the share sheet, opened from this bar when the tap that asked for it has expired. */
.save-file-prompt {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom));
    z-index: 2000;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0.75rem 0.75rem 1rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    color: var(--text-primary);
}

.save-file-prompt .save-file-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.875rem;
}

.save-file-prompt .save-file-close {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 1.25rem;
    line-height: 1;
    padding: 0.25rem 0.4rem;
    cursor: pointer;
}
