:root {
  /* Tell the browser this is a dark app so native UI — the date-picker calendar
     popup, scrollbars, form-control internals — renders dark, and the date input's
     calendar icon is drawn light (visible) instead of dark-on-dark. */
  color-scheme: dark;
  --bg: #0f1117;
  --panel: #171a23;
  --panel-2: #1d212c;
  --border: #2a2f3c;
  --text: #e2e4e9;
  --muted: #8b93a7;
  --accent: #38bdac;
  --accent-2: #5eead4;
  --danger: #f87171;
  --warn: #fbbf24;

  /* Severity palette — ONE definition per band, referenced by all three rule
     families below (`.sev-*` badges, `.chart .seg-*` bar fills, `.chart-swatch.seg-*`
     legend squares). The three families used to carry their own copies of these
     hex values, which is how the legend swatches for Security and Recommended went
     missing entirely (their bar fills existed, but `.chart .seg-*` sets `fill` and
     is scoped to `.chart`, so it does nothing for a legend `<span>`).

     `-fg` is the badge's text tint; the badge background is derived from the solid
     color at 16-18% so a new band needs two values, not six.

     Adding a band means: a `--sev-x` / `--sev-x-fg` pair here, plus one line in
     each of the three families. `severity_css_defines_every_band` (util.rs) reads
     this file and fails if any of the four is missing. */
  --sev-critical: #f87171;
  --sev-critical-fg: #fca5a5;
  --sev-important: #fb923c;
  --sev-important-fg: #fdba74;
  --sev-security: #e879f9;
  --sev-security-fg: #f0abfc;
  --sev-moderate: #fbbf24;
  --sev-moderate-fg: #fcd34d;
  --sev-recommended: #22d3ee;
  --sev-recommended-fg: #67e8f9;
  --sev-low: #60a5fa;
  --sev-low-fg: #93c5fd;
  --sev-optional: #94a3b8;
  --sev-optional-fg: #cbd5e1;
  --sev-unknown: #6b7280;
  --sev-unknown-fg: #9ca3af;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
}

main {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  min-height: 100vh;
}

h1 {
  font-size: 18px;
  margin: 0;
}

h2 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0 0 10px;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 16px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo {
  color: var(--accent);
  font-size: 26px;
}

.subtitle {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pill {
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
}

.pill-on {
  color: var(--accent-2);
  border-color: var(--accent);
}

.pill-off {
  color: var(--muted);
}

.pill-demo {
  color: var(--warn);
  border-color: var(--warn);
}

/* Sample-data notice shown under the header in demo / web mode. */
.demo-banner {
  margin: 0;
  padding: 8px 14px;
  background: var(--panel);
  border: 1px solid var(--warn);
  border-radius: 10px;
  color: var(--warn);
  font-size: 13px;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
}

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

label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 12px;
  color: var(--muted);
}

label.inline {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

input,
select {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  padding: 8px 10px;
  font-size: 13px;
  outline: none;
}

input:focus,
select:focus {
  border-color: var(--accent);
}

input.narrow {
  width: 80px;
}

/* Date inputs: keep the (now light, via color-scheme) calendar icon clearly
   visible and clickable. */
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.9;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* Device / Patch filters: one filter per row, each row's title inline with its
   controls. The min-width on the titles lines the controls up into a single
   column; the shared width on inputs/selects keeps that column straight. */
.stacked-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}

.stacked-filters > .control-group > .chips-label {
  min-width: 148px;
}

.stacked-filters > .control-group > input,
.stacked-filters > .control-group > select {
  width: 260px;
  max-width: 100%;
}

/* The install-window field is a small number input — keep it compact rather than
   stretching to the shared 260px column width above. */
.stacked-filters > .control-group > input.narrow {
  width: 80px;
}

select:disabled {
  opacity: 0.5;
}

.chips,
.row,
.controls,
.control-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.chips,
.row {
  margin-top: 12px;
}

/* The Filters header is the only `.row` with an h2; its default bottom margin
   leaves dead space below the title and offsets it from the Show/Hide toggle.
   The row supplies its own gap, so drop the heading margin here. */
.row h2 {
  margin: 0;
}

.controls {
  gap: 14px;
}

.controls .presets {
  margin-top: 0;
}

.chips-label {
  font-size: 12px;
  color: var(--muted);
  margin-right: 2px;
}

.chip {
  flex-direction: row;
  align-items: center;
  gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 5px 10px;
  color: var(--text);
  cursor: pointer;
}

.chip input {
  margin: 0;
}

.chip-preset {
  gap: 2px;
  padding: 2px 4px 2px 10px;
}

.btn {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
}

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

.btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #06231f;
  font-weight: 600;
}

.btn-ghost {
  background: transparent;
}

/* Collapse toggle in the Filters header — pushed to the right, compact. */
.filters-toggle {
  margin-left: auto;
  padding: 4px 10px;
  font-size: 12px;
}

.link {
  background: none;
  border: none;
  color: var(--accent-2);
  cursor: pointer;
  padding: 4px 6px;
  font-size: 13px;
}

.x {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 2px 6px;
}

/* Sortable Patches-table column headers — a button styled as the header text. */
.th-sort {
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

.th-sort:hover {
  color: var(--text);
}

/* Two-click confirm: the first click "arms" a destructive control, the second
   fires it (mouseleave/blur disarm). Reuses the danger palette as a warning. */
.x-armed {
  background: rgba(248, 113, 113, 0.18);
  border-radius: 6px;
  color: #fca5a5;
  font-size: 12px;
  font-weight: 600;
}

.btn-armed {
  border-color: var(--danger);
  color: #fca5a5;
}

.seg {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--muted);
  padding: 6px 14px;
  cursor: pointer;
}

.seg-on {
  background: var(--accent);
  color: #06231f;
  border-color: var(--accent);
  font-weight: 600;
}

.preset-name {
  width: 150px;
}

.tabs {
  display: flex;
  /* The row's min content width (two labelled tab groups + summary) exceeds a
     phone viewport; without wrapping it overflows the panel's right edge. */
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
  padding-bottom: 8px;
}

.tab {
  background: none;
  border: none;
  color: var(--muted);
  padding: 6px 12px;
  cursor: pointer;
  border-radius: 8px;
}

.tab-on {
  background: var(--panel-2);
  color: var(--text);
}

.result-summary {
  margin-left: auto;
  color: var(--muted);
  font-size: 12px;
}

/* Tab bar grouped by scope tier (Filtered results | Fleet health). */
.tab-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tab-group-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-right: 2px;
}

.tab-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border);
  margin: 0 6px;
}

.table-wrap {
  overflow: auto;
  max-height: 56vh;
  border: 1px solid var(--border);
  border-radius: 10px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

thead th {
  position: sticky;
  top: 0;
  background: var(--panel-2);
  text-align: left;
  padding: 9px 10px;
  color: var(--muted);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

tbody td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

tbody tr:hover {
  background: var(--panel-2);
}

.patch-name {
  white-space: normal;
  max-width: 360px;
}

.empty,
.note {
  color: var(--muted);
  padding: 14px 4px;
}

.note {
  color: var(--warn);
}

.sev,
.stat {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 11.5px;
  font-weight: 600;
}

.sev-critical {
  background: color-mix(in srgb, var(--sev-critical) 18%, transparent);
  color: var(--sev-critical-fg);
}

.sev-important {
  background: color-mix(in srgb, var(--sev-important) 18%, transparent);
  color: var(--sev-important-fg);
}

.sev-security {
  background: color-mix(in srgb, var(--sev-security) 16%, transparent);
  color: var(--sev-security-fg);
}

.sev-moderate {
  background: color-mix(in srgb, var(--sev-moderate) 16%, transparent);
  color: var(--sev-moderate-fg);
}

.sev-recommended {
  background: color-mix(in srgb, var(--sev-recommended) 16%, transparent);
  color: var(--sev-recommended-fg);
}

.sev-low {
  background: color-mix(in srgb, var(--sev-low) 16%, transparent);
  color: var(--sev-low-fg);
}

/* Optional is a real NinjaOne severity and Unknown is one it sent that we couldn't
   map — both used to fall through to `.sev-none`, rendering "low priority" and
   "unidentified" identically in the Patches table. */
.sev-optional {
  background: color-mix(in srgb, var(--sev-optional) 16%, transparent);
  color: var(--sev-optional-fg);
}

.sev-unknown {
  background: color-mix(in srgb, var(--sev-unknown) 20%, transparent);
  color: var(--sev-unknown-fg);
  font-style: italic;
}

.sev-none {
  background: var(--panel-2);
  color: var(--muted);
}

.stat-installed {
  background: rgba(56, 189, 172, 0.18);
  color: var(--accent-2);
}

.stat-approved {
  background: rgba(96, 165, 250, 0.16);
  color: #93c5fd;
}

.stat-pending {
  background: rgba(251, 191, 36, 0.16);
  color: #fcd34d;
}

.stat-rejected {
  background: var(--panel-2);
  color: var(--muted);
}

.stat-failed {
  background: rgba(248, 113, 113, 0.18);
  color: #fca5a5;
}

.toast {
  position: fixed;
  bottom: 18px;
  right: 18px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--panel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  max-width: 480px;
}

.toast-ok {
  border-color: var(--accent);
}

.toast-err {
  border-color: var(--danger);
  color: #fca5a5;
}

/* Persistent record of the last failed query in the results area — same danger
   palette as .toast-err, but it stays until the next success or a dismiss. */
.error-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  padding: 8px 12px;
  border: 1px solid var(--danger);
  border-radius: 8px;
  background: rgba(248, 113, 113, 0.1);
  color: #fca5a5;
  font-size: 13px;
}

.error-banner .x {
  margin-left: auto;
}

/* --- Running-query progress --- */
.query-progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
}

.progress {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.3s ease;
}

.progress-indeterminate {
  width: 35%;
  animation: progress-slide 1.1s ease-in-out infinite;
}

@keyframes progress-slide {
  0% {
    margin-left: -35%;
  }
  100% {
    margin-left: 100%;
  }
}

.progress-label {
  color: var(--muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.query-hint {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 0.85rem;
}

/* --- Filter sub-section headings (Device / Patch) --- */
.subhead {
  margin: 14px 0 6px;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-top: 1px solid var(--border);
  padding-top: 12px;
}

.subhead:first-of-type {
  border-top: 0;
  padding-top: 0;
}

/* --- Patches table pagination --- */
.pager {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.pager-info {
  color: var(--muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* --- Update splash modal --- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}

.modal {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px 22px;
  width: min(560px, 100%);
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}

/* The container is focused programmatically on open (see app/modal.rs) so the
   first Tab starts inside the dialog; the ring belongs on the controls, not on
   the panel. */
.modal:focus {
  outline: none;
}

.modal h2 {
  margin: 0 0 4px;
  font-size: 18px;
}

.modal-sub {
  margin: 0 0 14px;
  color: var(--muted);
  font-size: 13px;
}

.changelog {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-2);
  padding: 12px 14px;
  margin-bottom: 16px;
}

.changelog h3 {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.changelog-body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  max-height: 40vh;
  overflow-y: auto;
}

.changelog-body h4 {
  margin: 12px 0 4px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.changelog-body ul {
  margin: 0;
  padding-left: 18px;
}

.changelog-body li {
  margin: 0 0 4px;
}

.changelog-body p {
  margin: 0 0 8px;
}

.changelog-body strong {
  font-weight: 600;
  color: var(--text);
}

.changelog-body > :first-child {
  margin-top: 0;
}

.changelog-body > :last-child {
  margin-bottom: 0;
}

.modal-actions {
  margin-top: 0;
}

.app-version {
  margin-top: 16px;
  font-size: 11px;
  color: var(--muted);
}

/* --- Scope clarity: per-tab scope banner + filter-section note --- */
.scope-banner {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--panel-2);
}

.scope-banner-filtered {
  border-left-color: var(--accent);
}

.scope-banner-fleet {
  border-left-color: var(--warn);
}

.scope-banner-tier {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.scope-banner-text {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--text);
}

.scope-banner-filters {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--muted);
}

/* Applied-filter chips: read-only snapshot of the filters behind the current result. */
.applied-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
}

.applied-chip {
  font-size: 11.5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
}

/* Patch-tier chip on a Fleet-health tab — the filter is set but ignored here. */
.applied-chip-dim {
  opacity: 0.4;
  text-decoration: line-through;
  cursor: help;
}

.applied-chip-none {
  color: var(--muted);
  font-style: italic;
}

.subhead-note {
  margin-left: 8px;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  font-size: 11px;
  color: var(--muted);
}

/* Shown in place of the patch-filter controls while a Fleet-health tab is active. */
.filters-hidden-note {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 12px;
}

/* Failures: the full affected-device list can be long — keep the cell readable. */
.device-list {
  max-width: 380px;
  font-size: 0.85rem;
  color: var(--muted);
}

/* --- Dashboard charts (inline SVG) --- */
.charts {
  display: grid;
  gap: 16px;
  margin-bottom: 16px;
}

.chart-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-2);
  padding: 14px 16px;
}

.chart-title {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* "Compliance by OS" section — divided from the per-org compliance above it. */
.compliance-os {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.compliance-os .chart-card {
  margin-bottom: 12px;
}

.chart {
  max-width: 100%;
  height: auto;
}

.chart-lbl {
  fill: var(--muted);
  font-size: 12px;
}

.chart-val {
  fill: var(--text);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.chart-track {
  fill: var(--border);
}

/* Compliance bar fills, by health band. */
.chart .bar-good {
  fill: var(--accent);
}

.chart .bar-warn {
  fill: var(--warn);
}

.chart .bar-bad {
  fill: var(--danger);
}

/* Severity segment fills (stacked bar) — solid variants of the .sev-* badges,
   from the same custom properties so the two can no longer disagree. */
.chart .seg-critical {
  fill: var(--sev-critical);
}

.chart .seg-important {
  fill: var(--sev-important);
}

.chart .seg-security {
  fill: var(--sev-security);
}

.chart .seg-moderate {
  fill: var(--sev-moderate);
}

.chart .seg-recommended {
  fill: var(--sev-recommended);
}

.chart .seg-low {
  fill: var(--sev-low);
}

.chart .seg-optional {
  fill: var(--sev-optional);
}

.chart .seg-unknown {
  fill: var(--sev-unknown);
}

.chart-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 0 0;
  margin: 0;
  font-size: 12px;
  color: var(--muted);
}

.chart-legend li {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Drill-down affordance on a rollup value: reads as the data it replaces until
   hovered/focused, so the tables stay scannable rather than turning into a wall of
   links. A real <button> keeps it keyboard-reachable and announced. */
.drill {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px dotted var(--muted);
}

.drill:hover,
.drill:focus-visible {
  color: var(--accent-2);
  border-bottom-color: var(--accent-2);
}

.drill-legend {
  display: flex;
  align-items: center;
  gap: 6px;
  border-bottom: none;
}

.drill-legend:hover,
.drill-legend:focus-visible {
  border-bottom: none;
  text-decoration: underline;
}

.chart-swatch {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  display: inline-block;
}

/* Legend squares. A separate family from `.chart .seg-*` because those set `fill`
   and are scoped to `.chart`, which does nothing to a legend `<span>` — Security and
   Recommended once had bar fills but no swatch, painting a transparent hole next to
   their counts. On third-party patches those are the *common* bands. */
.chart-swatch.seg-critical {
  background: var(--sev-critical);
}

.chart-swatch.seg-important {
  background: var(--sev-important);
}

.chart-swatch.seg-security {
  background: var(--sev-security);
}

.chart-swatch.seg-moderate {
  background: var(--sev-moderate);
}

.chart-swatch.seg-recommended {
  background: var(--sev-recommended);
}

.chart-swatch.seg-low {
  background: var(--sev-low);
}

.chart-swatch.seg-optional {
  background: var(--sev-optional);
}

.chart-swatch.seg-unknown {
  background: var(--sev-unknown);
}

/* --- Mobile / narrow viewports --- */
@media (max-width: 640px) {
  main {
    padding: 12px;
    gap: 12px;
  }

  .panel {
    padding: 12px 13px;
  }

  /* Each stacked filter row puts its label on its own line and lets the
     controls span the full width, instead of fighting the fixed 148px label
     column + 260px control width that crowd a phone screen. */
  .stacked-filters > .control-group > .chips-label {
    flex-basis: 100%;
    min-width: 0;
    margin-right: 0;
  }

  .stacked-filters > .control-group > input,
  .stacked-filters > .control-group > select {
    width: 100%;
  }

  /* The results summary takes its own full line under the wrapped tab groups
     instead of squeezing beside them (margin-left:auto only suits one row). */
  .result-summary {
    flex-basis: 100%;
    margin-left: 0;
  }
}

/* --- Device actions ------------------------------------------------------- */

/* Sticky so the running selection total and the action buttons stay reachable
   while scrolling a 100-row page. */
.action-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.action-bar-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 220px;
  font-size: 13px;
}

.action-bar-hint {
  color: var(--muted);
}

.action-bar-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Each group is one mechanism, labelled. "Install all approved" and "Install only
   the selected" are different endpoints with different blast radii, and the label
   above the pair is what distinguishes them — the buttons themselves only say
   which patch family. */
.action-group {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
}

/* Own line, so the buttons below it read as a pair belonging to it. */
.action-group-label {
  flex: 1 1 100%;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

.action-bar-targets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1 1 100%;
  font-size: 12px;
}

.action-target-chip {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--muted);
}

/* One row per scope. Each carries a label saying which actions it reaches, because
   "Dry run" next to a native Apply reads as protection that endpoint cannot give. */
.action-bar-options {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  flex: 1 1 100%;
  font-size: 12px;
  color: var(--muted);
}

.action-bar-options label {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.action-options-label {
  flex: 1 1 100%;
  font-size: 11px;
  opacity: 0.85;
}

.action-bar-reason {
  flex: 1 1 240px;
}

.action-bar-runas {
  flex: 0 1 180px;
}

/* Collapsed by default: the two "Install only the selected patches" buttons cover
   the common case, and this is the escape hatch for any other library script. */
.action-bar-script {
  flex: 1 1 100%;
  font-size: 12px;
}

.action-bar-script > summary {
  cursor: pointer;
  color: var(--muted);
  padding: 2px 0;
}

.action-bar-blocked {
  flex: 1 1 100%;
  margin: 0;
  font-size: 12px;
  color: var(--warn);
  display: flex;
  align-items: center;
  gap: 8px;
}

.link-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent-2);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

.btn-sm {
  padding: 4px 9px;
  font-size: 12px;
}

/* Row-selection column: narrow, unsortable, and outside PATCH_COLUMNS. */
.col-select {
  width: 32px;
  text-align: center;
}

/* A dispatch that will restart machines gets a visible accent, not just prose. */
.modal-danger {
  border-color: var(--danger);
}

.modal-blockers,
.modal-warnings {
  margin: 10px 0;
  padding-left: 18px;
  font-size: 13px;
}

.modal-blockers {
  color: var(--danger);
}

.modal-warnings {
  color: var(--warn);
}

.modal-label {
  margin: 12px 0 4px;
  font-size: 12px;
  color: var(--muted);
}

/* The exact string sent to the script — shown verbatim, wrapped rather than
   truncated so nothing is hidden from the operator approving it. */
.modal-params {
  margin: 0 0 12px;
  padding: 8px 10px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 12px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  /* One line per device for a targeted install, so a batch at the 25-device cap
     must not push the Confirm button off-screen. */
  max-height: 220px;
  overflow-y: auto;
}

.modal-targets,
.modal-skipped {
  margin: 8px 0;
  font-size: 12px;
  color: var(--muted);
}

.modal-targets ul,
.modal-skipped ul {
  margin: 6px 0 0;
  padding-left: 18px;
  max-height: 180px;
  overflow-y: auto;
}

.modal-typed {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 12px 0;
  font-size: 13px;
  color: var(--danger);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}

.script-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  margin: 8px 0 4px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
}

.script-picker-targets {
  flex: 1 1 100%;
  margin: 0;
  font-size: 12px;
  color: var(--muted);
}

.script-picker label {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.script-picker-params {
  flex: 1 1 100%;
}

.script-picker-meta {
  flex: 1 1 100%;
  margin: 0;
  font-size: 12px;
  color: var(--muted);
}

.script-picker-tags {
  margin-left: 8px;
  opacity: 0.8;
}

.checkbox {
  flex-direction: row !important;
  align-items: center;
  gap: 6px;
}

.jobs-toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}

.job-state {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  border: 1px solid transparent;
}

.job-state-ok {
  color: var(--accent-2);
  border-color: var(--accent);
}

.job-state-bad {
  color: var(--danger);
  border-color: var(--danger);
}

.job-state-warn {
  color: var(--warn);
  border-color: var(--warn);
}

.job-state-running {
  color: var(--muted);
  border-color: var(--border);
}

.job-state-muted {
  color: var(--muted);
  opacity: 0.75;
}

/* The displayed results predate a dispatched action. */
.stale-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
  padding: 8px 12px;
  border: 1px solid var(--warn);
  border-radius: 8px;
  background: var(--panel-2);
  font-size: 13px;
  color: var(--warn);
}

.settings-actions {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.settings-actions legend {
  padding: 0 6px;
  font-size: 12px;
  color: var(--muted);
}

.settings-hint {
  margin: 4px 0 10px;
  font-size: 12px;
  color: var(--muted);
}

.settings-disabled {
  opacity: 0.5;
}

/* --- Patches view modes + grouped view ---------------------------------- */

.view-modes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 10px 0;
}

/* The active view mode. `.chip` is also used for multi-select facets, so this
   only ever rides on the mode buttons, which are single-select. */
.chip-on {
  background: var(--accent-soft, rgba(56, 189, 172, 0.18));
  border-color: var(--accent-2, #38bdac);
  color: var(--accent-2, #38bdac);
}

.groups {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.group {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-2);
  overflow: hidden;
}

.group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
}

.group-toggle {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: none;
  border: 0;
  padding: 0;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.group-caret {
  color: var(--muted);
  width: 1em;
  flex: none;
}

.group-label {
  font-weight: 600;
}

.group-sub,
.group-count {
  font-size: 12px;
  color: var(--muted);
}

/* Pushes the member count to the right on wide viewports, but lets it wrap
   under the label on narrow ones rather than overflowing the panel. */
.group-count {
  margin-left: auto;
}

.chip-note {
  font-size: 11.5px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1px 6px;
}

.group-members {
  border-top: 1px solid var(--border);
}

.group-members td {
  padding: 6px 10px;
}

/* --- Scope multi-select (Organizations / Locations / Device Roles) ------------
   Sits in the same `.grid` the three single-selects used, so the panel keeps its
   layout; the popover is positioned relative to the picker rather than the grid so
   an open list overlays the row below instead of reflowing the whole panel. */
.scope-picker {
  display: flex;
  flex-direction: column;
  gap: 5px;
  position: relative;
}

.scope-picker__label {
  font-size: 12px;
  color: var(--muted);
}

.scope-picker__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  text-align: left;
}

.scope-picker__summary:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.scope-picker__value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.scope-picker__caret {
  color: var(--muted);
  flex: none;
}

.scope-picker__panel {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 28%);
}

.scope-picker__tools {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}

.scope-picker__search {
  flex: 1;
  min-width: 0;
}

/* Bounded so a tenant with hundreds of organizations scrolls the list rather than
   the page. */
.scope-picker__list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 240px;
  overflow-y: auto;
}

.scope-picker__empty {
  margin: 4px 2px;
  font-size: 12px;
  color: var(--muted);
}

/* The sentence stating which devices and which patch families the compliance
   numbers describe. Muted and small — it qualifies the figures below it rather
   than competing with them. */
.scope-note {
  margin: 8px 2px 12px;
  font-size: 12px;
  color: var(--muted);
}

/* Jobs tab section headings — the live session list and the durable audit trail
   are two different things and were previously one undifferentiated table. */
.jobs-heading {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 22px 0 4px;
  font-size: 0.95rem;
  color: var(--text);
}
.jobs-heading:first-of-type { margin-top: 8px; }
/* The two native applies install a device's whole approved backlog regardless of
   the selection. That reach used to be carried only by the 11px group heading
   above them, so the buttons themselves now read as the wider action. */
.btn-wide-radius {
  border-color: var(--warn);
  color: var(--warn);
}
.btn-wide-radius:disabled {
  border-color: var(--border);
  color: var(--muted);
}

/* Blast radius as the confirm dialog's first line, above the device list. */
.confirm-radius {
  margin: 0 0 0.75rem;
  color: var(--muted);
}
.confirm-radius-wide {
  color: var(--warn);
  font-weight: 600;
}

/* --- Trend tab: fleet health over the run history ------------------------- */

.trend-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--panel-2);
  color: var(--accent);
}
.trend-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.trend-title {
  font-weight: 600;
  color: var(--text);
}
/* Direction, not magnitude: more compliance is better, more of everything else
   here is worse, so the sign alone cannot carry the meaning. */
.trend-delta { font-variant-numeric: tabular-nums; color: var(--muted); }
.trend-better { color: var(--accent-2); }
.trend-worse { color: var(--danger); }
.trend-spark {
  display: block;
  width: 100%;
  height: 60px;
  margin: 6px 0 2px;
}
.trend-foot {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.trend-now { color: var(--text); font-weight: 600; }
/* Desktop build with no reachable Tauri backend. Replaces the whole UI rather than
   sitting above it: the point is that no fleet numbers are on screen at all, so
   there is nothing for this to annotate. See app.rs's `backend_missing` branch. */
.backend-missing {
  max-width: 60ch;
  margin: 15vh auto 0;
  border-color: var(--danger);
}
.backend-missing h2 {
  color: var(--danger);
  margin-top: 0;
}
