/* ==========================================================================
   LITZEN SYSTEMS — Server Dashboard
   Dark operations console. Self-hosted styles only: no external fonts, no
   CDN assets, nothing that would violate the page's own
   Content-Security-Policy (default-src 'self'; style-src 'self').

   No inline style attributes are used anywhere in the markup either — bars
   are <progress> elements and charts are <canvas>, both driven by
   attributes and by script, never by inline CSS.
   ========================================================================== */

:root {
  /* Surfaces — deep navy through charcoal */
  --bg: #080d18;
  --bg-grad-a: #0a1020;
  --bg-grad-b: #0d1424;
  --sidebar: #0a1020;
  --panel: #101a2e;
  --panel-raised: #14203a;
  --panel-inset: #0c1526;

  /* Lines */
  --line: #1c2942;
  --line-soft: #16223a;
  --line-strong: #26364f;

  /* Text */
  --ink: #e8eff9;
  --ink-soft: #a9bad4;
  --ink-dim: #6f83a3;
  --ink-faint: #4d5f7c;

  /* Accents */
  --blue: #4f9cf9;
  --blue-deep: #2b6fd4;
  --teal: #2dd4bf;
  --green: #3ddc97;
  --amber: #f5b544;
  --red: #f4736b;

  /* Accent washes for chart fills and glows */
  --blue-wash: rgba(79, 156, 249, 0.16);
  --teal-wash: rgba(45, 212, 191, 0.16);
  --green-wash: rgba(61, 220, 151, 0.16);

  --radius-lg: 16px;
  --radius: 13px;
  --radius-sm: 9px;
  --radius-pill: 999px;

  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.28);
  --shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.3);

  --sidebar-width: 264px;

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", monospace;
}

*,
*::before,
*::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  background-image:
    radial-gradient(1100px 620px at 78% -8%, rgba(45, 212, 191, 0.07), transparent 60%),
    radial-gradient(900px 560px at 12% 0%, rgba(79, 156, 249, 0.09), transparent 62%),
    linear-gradient(180deg, var(--bg-grad-a), var(--bg-grad-b));
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--panel-inset); }
::-webkit-scrollbar-thumb {
  background: #22314b;
  border: 2px solid var(--panel-inset);
  border-radius: var(--radius-pill);
}
::-webkit-scrollbar-thumb:hover { background: #2d4062; }

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.6rem 1rem;
  background: var(--blue);
  color: #04101f;
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 700;
  z-index: 100;
}
.skip-link:focus { left: 0; }

/* ==========================================================================
   Shell
   ========================================================================== */

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  min-height: 100vh;
}

/* ==========================================================================
   Sidebar
   ========================================================================== */

.sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.5rem 1rem 1.25rem;
  background: linear-gradient(180deg, rgba(12, 20, 38, 0.96), rgba(8, 13, 24, 0.98));
  border-right: 1px solid var(--line);
  overflow-y: auto;
}

.brand { padding: 0 0.6rem; }

.brand-mark {
  display: block;
}

/* The official horizontal logo. Scaled by width only, with `height: auto`, so
   the browser derives the height from the intrinsic ratio carried by the
   img's width/height attributes — the artwork is never stretched or cropped.
   The mark is white and blue on transparency, which is why it sits on the
   sidebar's dark gradient and is given no background, filter or blend mode of
   its own: recolouring it is not ours to do. `max-width` caps it on the
   widest sidebar; the artwork's own margins supply the breathing room. */
.brand-logo {
  display: block;
  width: 100%;
  max-width: 210px;
  height: auto;
}

.sidebar-heading {
  padding: 0 0.75rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.nav { display: flex; flex-direction: column; gap: 0.15rem; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.62rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  font-size: 0.88rem;
  font-weight: 500;
  border-left: 2px solid transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.nav-item:hover { background: rgba(79, 156, 249, 0.09); color: var(--ink); }

.nav-item.is-active {
  background: linear-gradient(90deg, rgba(79, 156, 249, 0.18), rgba(79, 156, 249, 0.02));
  border-left-color: var(--blue);
  color: #fff;
  font-weight: 600;
}

.nav-glyph {
  width: 1.15rem;
  text-align: center;
  font-size: 0.95rem;
  opacity: 0.9;
}

.nav-item.is-disabled {
  color: var(--ink-faint);
  cursor: not-allowed;
  pointer-events: none;
}

.nav-soon {
  margin-left: auto;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.sidebar-foot {
  margin-top: auto;
  padding: 0.85rem 0.75rem 0;
  border-top: 1px solid var(--line-soft);
  font-size: 0.7rem;
  line-height: 1.6;
  color: var(--ink-faint);
}

.sidebar-foot strong { color: var(--ink-dim); font-weight: 600; }

.sidebar-version { font-family: var(--font-mono); color: var(--ink-faint); }

/* ==========================================================================
   Top bar
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.95rem 1.9rem;
  background: rgba(10, 16, 32, 0.86);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.topbar-host { display: flex; align-items: center; gap: 0.85rem; min-width: 0; }

.topbar-host h1 {
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

.topbar-sub {
  font-size: 0.76rem;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
}

/* --- operating mode ------------------------------------------------------ */

/* Read-only is permanent and normal, so it is set as one more fact about the
   host rather than given a bordered pill next to the controls. Faint, and
   never coloured: a colour here would read as a warning. */
.topbar-mode {
  color: var(--ink-faint);
  text-transform: lowercase;
}

/* --- status indicator ---------------------------------------------------- */

/* Borderless on purpose. The dot carries the state; a border around it only
   competed with the controls to its right. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--green);
}

.status.is-degraded { color: var(--amber); }
.status.is-offline { color: var(--red); }

.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 3px rgba(61, 220, 151, 0.15);
  animation: pulse 2.4s ease-in-out infinite;
}

.status.is-degraded .status-dot { box-shadow: 0 0 0 3px rgba(245, 181, 68, 0.15); }

/* A lost connection is a state to read, not a thing to keep blinking. */
.status.is-offline .status-dot {
  animation: none;
  box-shadow: 0 0 0 3px rgba(244, 115, 107, 0.15);
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  .status-dot { animation: none; }
  html { scroll-behavior: auto; }
}

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

/* Manual refresh and the automatic-refresh state read as one control: a single
   bordered group with an internal divider, rather than two buttons and a
   free-floating countdown. */
.refresh {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  overflow: hidden;
}

.refresh-now {
  display: inline-flex;
  align-items: center;
  padding: 0.36rem 0.6rem;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.refresh-now:hover { background: var(--panel-inset); color: var(--ink); }
.refresh-now:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

/* The spinner state the refresh cycle already toggles. */
.refresh-now.is-busy { color: var(--blue); }
.refresh-now.is-busy .btn-glyph { animation: spin 0.9s linear infinite; }

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

@media (prefers-reduced-motion: reduce) {
  .refresh-now.is-busy .btn-glyph { animation: none; }
}

/* The countdown: present, but deliberately quiet. */
.refresh-static,
.refresh .menu-trigger {
  border-left: 1px solid var(--line-strong);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-dim);
}

.refresh-static {
  display: inline-flex;
  align-items: center;
  padding: 0.36rem 0.7rem;
}

/* --- menus (<details> disclosure) ---------------------------------------- */

/* Native <details> so the menu is keyboard-operable and announced without any
   script, and so its trigger is a <summary> rather than a third button
   needing a data-action of its own. */
.menu { position: relative; }

.menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.36rem 0.7rem;
  color: var(--ink-soft);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
  transition: background 0.15s ease, color 0.15s ease;
}

/* The default disclosure triangle, removed in both engines. */
.menu-trigger::-webkit-details-marker { display: none; }
.menu-trigger::marker { content: ""; }

.menu-trigger:hover { background: var(--panel-inset); color: var(--ink); }
.menu-trigger:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

.user-menu > .menu-trigger {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
}

.menu-caret { font-size: 0.6rem; opacity: 0.7; }

.menu[open] > .menu-trigger { background: var(--panel-inset); color: var(--ink); }

.menu-panel {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  z-index: 30;
  min-width: 12rem;
  padding: 0.35rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel);
  box-shadow: 0 12px 28px rgba(2, 6, 16, 0.45);
}

/* Anchored to the right edge for the menu nearest the window edge. */
.menu-panel--end { left: auto; right: 0; }

.menu-meta {
  margin: 0 0 0.3rem;
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: 0.68rem;
  color: var(--ink-faint);
}

.menu-meta span { font-family: var(--font-mono); }

.menu-item {
  display: block;
  width: 100%;
  padding: 0.42rem 0.5rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.menu-item:hover { background: var(--panel-inset); color: var(--ink); }
.menu-item:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

.menu-rule {
  height: 0;
  margin: 0.3rem 0.15rem;
  border: 0;
  border-top: 1px solid var(--line-soft);
}

/* Weightier than Sign out, and no more than that. A solid red block on a menu
   entry that is a legitimate, reversible action reads as a warning the action
   does not deserve; the colour is carried by the text, and the background only
   appears on hover. */
.menu-item--destructive { color: var(--red); font-weight: 600; }

.menu-item--destructive:hover {
  background: rgba(244, 115, 107, 0.12);
  color: var(--red);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.btn:hover { border-color: var(--blue); color: #fff; background: #182644; }

.btn[aria-pressed="true"] {
  border-color: rgba(61, 220, 151, 0.5);
  color: var(--green);
  background: rgba(61, 220, 151, 0.1);
}

.btn.is-busy { opacity: 0.55; cursor: progress; }

.btn-glyph { font-size: 0.85rem; line-height: 1; }
.btn.is-busy .btn-glyph { animation: spin 0.9s linear infinite; }

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

/* ==========================================================================
   Main content
   ========================================================================== */

.content {
  padding: 1.9rem;
  max-width: 1560px;
  margin: 0 auto;
  width: 100%;
}

.is-stale .content { opacity: 0.62; transition: opacity 0.25s ease; }

/* --- page header (every page) -------------------------------------------- */

.page-head {
  margin-bottom: 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line-soft);
}

.page-eyebrow {
  margin: 0;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--teal);
}

.page-head h2 {
  margin: 0.5rem 0 0.5rem;
  font-size: clamp(1.5rem, 2.3vw, 2.1rem);
  font-weight: 680;
  letter-spacing: -0.022em;
  line-height: 1.15;
}

.hero-host { color: var(--blue); }

.page-lede {
  margin: 0;
  max-width: 78ch;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.page-lede code,
.panel-inline-note code,
.panel-note code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  color: var(--ink);
}

/* --- hero ---------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.75rem;
  padding: 1.85rem 2rem;
  margin-bottom: 1.35rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(760px 320px at 88% 8%, rgba(45, 212, 191, 0.12), transparent 65%),
    linear-gradient(135deg, #12203a 0%, #101a2e 55%, #0e1728 100%);
  box-shadow: var(--shadow);
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  pointer-events: none;
}

.hero-eyebrow {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--teal);
}

.hero h2 {
  margin: 0.55rem 0 0.6rem;
  font-size: clamp(1.6rem, 2.5vw, 2.25rem);
  font-weight: 680;
  letter-spacing: -0.022em;
  line-height: 1.15;
}

.hero h2 .hero-host { color: var(--blue); }

.hero p {
  margin: 0;
  max-width: 62ch;
  color: var(--ink-soft);
  font-size: 0.92rem;
}

.hero-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem 1.6rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(8, 13, 24, 0.5);
}

.hero-fact-label {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.hero-fact-value {
  font-size: 0.9rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

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

.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 1.05rem;
  margin-bottom: 1.35rem;
}

.summary-card {
  position: relative;
  overflow: hidden;
  padding: 1.15rem 1.25rem 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--panel-raised), var(--panel));
  box-shadow: var(--shadow-soft);
  transition: border-color 0.18s ease, transform 0.18s ease;
}

.summary-card:hover { border-color: var(--line-strong); transform: translateY(-1px); }

.summary-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--accent, var(--blue));
  opacity: 0.85;
}

.summary-card--cpu { --accent: var(--blue); }
.summary-card--memory { --accent: var(--teal); }
.summary-card--disk { --accent: var(--green); }
.summary-card--network { --accent: #8b7bf7; }
.summary-card--uptime { --accent: var(--amber); }

.summary-head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.75rem;
}

.summary-glyph {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  font-size: 0.82rem;
}

.summary-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.summary-value {
  font-size: 1.95rem;
  font-weight: 640;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

/* Text-valued cards (throughput, uptime) run longer than a percentage, so
   they step down a size to stay on one line in a narrow card. */
.summary-value--net,
.summary-value--uptime {
  font-size: 1.45rem;
  letter-spacing: -0.02em;
}

.summary-value .unit {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink-dim);
  margin-left: 0.15rem;
}

.summary-sub {
  margin-top: 0.35rem;
  font-size: 0.75rem;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.summary-card .bar { margin-top: 0.9rem; }

/* --- panels -------------------------------------------------------------- */

.panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(370px, 1fr));
  gap: 1.15rem;
  align-items: start;
}

/* Paired layout: exactly two equal columns, and cards in the same row share a
   height. auto-fit would reflow into three narrow columns on a wide display,
   which is what made the lower half of the CPU page look scattered. */
.panel-grid--pairs {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  margin-top: 1.15rem;
}

.panel {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(170deg, var(--panel-raised) 0%, var(--panel) 100%);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.panel--wide { grid-column: 1 / -1; }

.panel-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 1.25rem;
  border-bottom: 1px solid var(--line-soft);
  background: rgba(8, 13, 24, 0.32);
}

.panel-head h3 {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.panel-head-glyph { color: var(--blue); font-size: 0.9rem; }

.panel-head-note {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* The body takes the slack in a stretched row, so a shorter card's footer
   note stays pinned to the bottom edge instead of floating mid-card. */
.panel-body { padding: 1.25rem; flex: 1 1 auto; }

.panel-body--flush { padding: 0; }

/* In a paired row the trailing note is the natural place for slack to land:
   pushing it down keeps the two cards' content visually aligned at the top. */
.panel-grid--pairs .panel-body { display: flex; flex-direction: column; }
/* Flex children default to min-width:auto, which would let a wide table push
   its card past the column instead of scrolling inside it. */
.panel-grid--pairs .panel-body > * { min-width: 0; }
.panel-grid--pairs .panel-inline-note:last-child { margin-top: auto; padding-top: 1rem; }

.panel-note {
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.72rem;
  color: var(--ink-faint);
  line-height: 1.6;
}

/* --- metric readouts ----------------------------------------------------- */

.readout {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.7rem;
}

.readout-value {
  font-size: 2.05rem;
  font-weight: 640;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.readout-caption {
  font-size: 0.78rem;
  color: var(--ink-dim);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- progress bars ------------------------------------------------------- */

.bar {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 7px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--panel-inset);
  overflow: hidden;
}

.bar--slim { height: 5px; }

.bar::-webkit-progress-bar {
  background: var(--panel-inset);
  border-radius: var(--radius-pill);
}

.bar::-webkit-progress-value {
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--blue-deep), var(--blue));
  transition: width 0.4s ease;
}

.bar::-moz-progress-bar {
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--blue-deep), var(--blue));
}

.bar--teal::-webkit-progress-value { background: linear-gradient(90deg, #17a394, var(--teal)); }
.bar--teal::-moz-progress-bar { background: linear-gradient(90deg, #17a394, var(--teal)); }

.bar--green::-webkit-progress-value { background: linear-gradient(90deg, #23a873, var(--green)); }
.bar--green::-moz-progress-bar { background: linear-gradient(90deg, #23a873, var(--green)); }

/* Severity overrides win over the colour variants below them. */
.bar.is-warn::-webkit-progress-value { background: linear-gradient(90deg, #c98a1c, var(--amber)); }
.bar.is-warn::-moz-progress-bar { background: linear-gradient(90deg, #c98a1c, var(--amber)); }

.bar.is-critical::-webkit-progress-value { background: linear-gradient(90deg, #c94b42, var(--red)); }
.bar.is-critical::-moz-progress-bar { background: linear-gradient(90deg, #c94b42, var(--red)); }

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

.chart-frame {
  position: relative;
  margin: 1.1rem 0 0.4rem;
  padding: 0.5rem 0.15rem 0;
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
  border: 1px solid var(--line-soft);
}

.chart-canvas {
  display: block;
  width: 100%;
  height: 118px;
}

.chart-legend {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.3rem 0.6rem 0.45rem;
  font-size: 0.66rem;
  color: var(--ink-faint);
  font-family: var(--font-mono);
}

.noscript-note {
  margin: 0.9rem 0 0;
  padding: 0.7rem 0.85rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  font-size: 0.74rem;
  color: var(--ink-dim);
}

/* --- key/value lists ----------------------------------------------------- */

.kv {
  display: grid;
  grid-template-columns: minmax(8.5rem, auto) minmax(0, 1fr);
  gap: 0.5rem 1.1rem;
  margin: 0;
  font-size: 0.85rem;
}

.kv dt {
  color: var(--ink-dim);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  align-self: center;
}

.kv dd {
  margin: 0;
  color: var(--ink);
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

.kv--split { border-top: 1px solid var(--line-soft); margin-top: 1rem; padding-top: 1rem; }

.mono { font-family: var(--font-mono); font-size: 0.82rem; }

/* --- per-core grid ------------------------------------------------------- */

.core-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 0.6rem 0.9rem;
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-soft);
  list-style: none;
}

.core {
  display: grid;
  grid-template-columns: 2.6rem 1fr 2.4rem;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.7rem;
  font-family: var(--font-mono);
  color: var(--ink-dim);
}

.core-value { text-align: right; color: var(--ink-soft); }

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

.table-scroll { overflow-x: auto; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.83rem;
  font-variant-numeric: tabular-nums;
}

thead th {
  padding: 0.62rem 1.25rem;
  text-align: left;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: rgba(8, 13, 24, 0.35);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

tbody th,
tbody td {
  padding: 0.68rem 1.25rem;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
  font-weight: 400;
  color: var(--ink-soft);
}

tbody th { color: var(--ink); font-weight: 600; }

tbody tr:last-child th,
tbody tr:last-child td { border-bottom: none; }

tbody tr:hover td,
tbody tr:hover th { background: rgba(79, 156, 249, 0.05); }

.cell-usage {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 12rem;
}

.cell-usage .bar { flex: 1; }

.cell-usage span { min-width: 3.3rem; text-align: right; }

.tag {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.02rem 0.36rem;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  text-transform: uppercase;
}

.tag--up { border-color: rgba(61, 220, 151, 0.42); color: var(--green); }
.tag--down { border-color: rgba(244, 115, 107, 0.38); color: var(--red); }

.rate { color: var(--ink); }
.rate-down { color: var(--teal); }
.rate-up { color: var(--blue); }

/* --- health checks ------------------------------------------------------- */

.checks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.79rem;
}

.check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
  font-family: var(--font-mono);
  font-size: 0.73rem;
  color: var(--ink-soft);
}

.check-mark {
  width: 17px;
  height: 17px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 0.62rem;
  font-weight: 700;
}

.check--ok .check-mark { background: rgba(61, 220, 151, 0.16); color: var(--green); }
.check--fail .check-mark { background: rgba(244, 115, 107, 0.16); color: var(--red); }
.check--fail { border-color: rgba(244, 115, 107, 0.3); color: var(--red); }

/* --- phase panel --------------------------------------------------------- */

.phase-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.35rem;
}

.phase-col h4 {
  margin-bottom: 0.65rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.phase-list { margin: 0; padding: 0; list-style: none; font-size: 0.82rem; }

.phase-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  padding: 0.28rem 0;
  color: var(--ink-soft);
}

.phase-list .marker { flex: none; font-size: 0.78rem; line-height: 1.5; }
.phase-list .marker--done { color: var(--green); }
.phase-list .marker--next { color: var(--blue); }
.phase-list .marker--blocked { color: var(--amber); }

.phase-banner {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1.15rem;
  padding: 0.75rem 0.95rem;
  border: 1px solid rgba(61, 220, 151, 0.28);
  border-radius: var(--radius-sm);
  background: rgba(61, 220, 151, 0.07);
  color: var(--green);
  font-size: 0.82rem;
  font-weight: 600;
}

/* ==========================================================================
   CPU page
   ========================================================================== */

/* --- health banner -------------------------------------------------------- */

.health-banner {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 1.15rem;
  margin-bottom: 1.35rem;
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--panel);
  font-size: 0.86rem;
}

.health-banner--ok { border-left-color: var(--green); background: rgba(61, 220, 151, 0.06); }
.health-banner--warn { border-left-color: var(--amber); background: rgba(245, 181, 68, 0.07); }
.health-banner--critical { border-left-color: var(--red); background: rgba(244, 115, 107, 0.08); }

.health-dot {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--ink-dim);
}

.health-banner--ok .health-dot { background: var(--green); box-shadow: 0 0 0 3px rgba(61, 220, 151, 0.16); }
.health-banner--warn .health-dot { background: var(--amber); box-shadow: 0 0 0 3px rgba(245, 181, 68, 0.16); }
.health-banner--critical .health-dot { background: var(--red); box-shadow: 0 0 0 3px rgba(244, 115, 107, 0.18); }

.health-copy { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.6rem; min-width: 0; }
.health-copy strong { font-size: 0.92rem; font-weight: 650; }
.health-copy span { color: var(--ink-dim); font-size: 0.8rem; }

.health-meta {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.health-meta code { font-family: var(--font-mono); }

/* --- summary card variants ------------------------------------------------ */

.summary-grid--cpu { grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); }

.summary-card--temp { --accent: var(--amber); }
.summary-card--clock { --accent: var(--teal); }
.summary-card--load { --accent: var(--green); }
.summary-card--sched { --accent: #8b7bf7; }

.summary-secondary {
  margin-top: -0.15rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.summary-value .unit + .unit { margin-left: 0; }

.summary-card--sched .summary-value .unit {
  display: block;
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* --- temperature colours -------------------------------------------------- */

.state-hot { color: #f59f4a; }
.state-critical { color: var(--red); }
.state-muted { color: var(--ink-dim); }

.bar--temp::-webkit-progress-value { background: linear-gradient(90deg, var(--teal), var(--amber)); }
.bar--temp::-moz-progress-bar { background: linear-gradient(90deg, var(--teal), var(--amber)); }
.bar--amber::-webkit-progress-value { background: linear-gradient(90deg, #c98a1c, var(--amber)); }
.bar--amber::-moz-progress-bar { background: linear-gradient(90deg, #c98a1c, var(--amber)); }
.bar--muted::-webkit-progress-value { background: linear-gradient(90deg, #2b3852, #3c4d6d); }
.bar--muted::-moz-progress-bar { background: linear-gradient(90deg, #2b3852, #3c4d6d); }

.readout-value .readout-secondary {
  margin-left: 0.5rem;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--ink-dim);
}

.chart-frame--tall { padding-top: 0.65rem; }
.chart-canvas--tall { height: 168px; }

.swatch--cpu { background: var(--blue); }

/* --- per-sensor readings -------------------------------------------------- */

.sensor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sensor {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
}

.sensor-label { color: var(--ink-dim); }
.sensor-value { margin-left: auto; font-weight: 650; }
.sensor-alt { color: var(--ink-faint); font-size: 0.7rem; }

/* --- CPU time breakdown --------------------------------------------------- */

.breakdown { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.55rem; }

.breakdown-row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) 3.6rem;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.breakdown-label { color: var(--ink-soft); }
.breakdown-value { text-align: right; color: var(--ink); }

/* --- stat row ------------------------------------------------------------- */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  gap: 0.75rem;
  margin-bottom: 0.9rem;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
}

.stat-label {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.stat-value { font-size: 1.25rem; font-weight: 640; font-variant-numeric: tabular-nums; }
.stat-sub { font-size: 0.7rem; color: var(--ink-dim); }

/* --- per-core detail grid ------------------------------------------------- */

.core-grid--detail {
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  border-top: none;
  margin-top: 0;
  padding-top: 0;
  gap: 0.5rem 1.1rem;
}

.core--detail {
  grid-template-columns: 3.9rem minmax(0, 1fr) 2.6rem 4.6rem;
  gap: 0.55rem;
}

.core-name { color: var(--ink-soft); }
.core-freq { text-align: right; color: var(--teal); font-size: 0.68rem; }

/* --- capability chips ----------------------------------------------------- */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--panel-inset);
  font-size: 0.72rem;
  color: var(--ink-dim);
}

.chip--on { border-color: rgba(45, 212, 191, 0.35); color: var(--ink); }
.chip--on .chip-mark { color: var(--teal); font-weight: 700; }
.chip--off { opacity: 0.55; }
.chip--off .chip-mark { color: var(--ink-faint); }

.table--compact th,
.table--compact td { padding: 0.45rem 0.7rem; }

.empty-state--boxed {
  padding: 1.6rem 1.25rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
  text-align: left;
}

.empty-title {
  margin: 0 0 0.45rem;
  font-size: 0.95rem;
  font-weight: 650;
  color: var(--amber);
}

.empty-state--boxed p { margin: 0.35rem 0; }

/* --- pending / coming soon ----------------------------------------------- */

.pending {
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  background: rgba(245, 181, 68, 0.05);
  overflow: hidden;
}

.pending-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.95rem;
  border-bottom: 1px dashed var(--line-strong);
  font-size: 0.85rem;
  color: var(--amber);
}

.pending-badge {
  padding: 0.1rem 0.5rem;
  border: 1px solid rgba(245, 181, 68, 0.45);
  border-radius: var(--radius-pill);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.pending-body {
  padding: 0.85rem 0.95rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.pending-body p { margin: 0 0 0.7rem; }
.pending-body p:last-child { margin-bottom: 0; }

.coming-soon {
  padding: 2.6rem 1.5rem;
  text-align: center;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  background:
    radial-gradient(520px 200px at 50% 0%, rgba(79, 156, 249, 0.09), transparent 70%),
    var(--panel-inset);
}

.coming-soon-badge {
  display: inline-block;
  margin: 0 0 1rem;
  padding: 0.3rem 0.9rem;
  border: 1px solid rgba(79, 156, 249, 0.45);
  border-radius: var(--radius-pill);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--blue);
}

.coming-soon h3 {
  margin: 0 0 0.7rem;
  font-size: 1.15rem;
  font-weight: 620;
}

.coming-soon p {
  margin: 0 auto;
  max-width: 62ch;
  color: var(--ink-dim);
  font-size: 0.86rem;
}

.empty-state {
  margin: 0;
  padding: 1.5rem;
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.85rem;
}

/* --- misc text helpers --------------------------------------------------- */

.subhead {
  margin: 1.5rem 0 0.75rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.panel-inline-note {
  margin: 1rem 0 0;
  font-size: 0.76rem;
  color: var(--ink-faint);
  line-height: 1.65;
}

.summary-link {
  display: inline-block;
  margin-top: 0.85rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ink-dim);
  transition: color 0.15s ease;
}

.summary-link:hover { color: var(--blue); }

.inline-link { color: var(--blue); font-weight: 600; }
.inline-link:hover { text-decoration: underline; }

.state-ok { color: var(--green); }
.state-warn { color: var(--amber); }

.kv--wide { grid-template-columns: minmax(9.5rem, auto) minmax(0, 1fr); }
.kv-wrap { white-space: normal; word-break: break-word; }

.readout-value--load { font-size: 1.5rem; letter-spacing: -0.02em; }

.core-grid--page {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

.swatch {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  vertical-align: baseline;
}

.swatch--rx { background: var(--teal); }
.swatch--tx { background: var(--blue); }

/* --- footer -------------------------------------------------------------- */

.footer {
  padding: 1.6rem 1.9rem 2.4rem;
  max-width: 1560px;
  margin: 0 auto;
  color: var(--ink-faint);
  font-size: 0.73rem;
  line-height: 1.7;
}

.footer p { margin: 0.15rem 0; }
.footer code { font-family: var(--font-mono); color: var(--ink-dim); }

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1080px) {
  .app-shell { grid-template-columns: 1fr; }

  .sidebar {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: 1.25rem;
    padding: 0.9rem 1.1rem;
    border-right: none;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
  }

  .sidebar-heading,
  .sidebar-foot { display: none; }

  /* The sidebar becomes a horizontal bar here, so the logo stops filling a
     column and takes an explicit, smaller cap beside the navigation. It must
     not be squeezed by the flex row, hence `flex: none` on its container. */
  .brand { flex: none; }
  .brand-logo { width: 168px; }

  .nav { flex-direction: row; gap: 0.3rem; }

  .nav-item {
    border-left: none;
    border-bottom: 2px solid transparent;
    white-space: nowrap;
  }

  .nav-item.is-active { border-left: none; border-bottom-color: var(--blue); }

  .content, .footer { padding-left: 1.1rem; padding-right: 1.1rem; }
  .topbar { padding: 0.85rem 1.1rem; }
}

/* Two columns need real width to stay readable; below this the paired grid
   collapses to a single column and the cards keep their natural heights. */
@media (max-width: 900px) {
  .panel-grid--pairs {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .panel-grid--pairs .panel-inline-note:last-child { margin-top: 1rem; padding-top: 0; }
}

@media (max-width: 640px) {
  .hero { padding: 1.35rem; }
  .hero-facts { grid-template-columns: 1fr; }
  .panel-grid { grid-template-columns: 1fr; }
  /* The countdown is the first thing to go when width is scarce; the
     refresh button and the account menu are not. */
  .refresh .menu-trigger, .refresh-static { display: none; }
}

/* ==========================================================================
   HISTORY RANGE SELECTOR
   A segmented control above a chart. Real <button> elements so it is
   keyboard-reachable and announces its pressed state; no inline styles or
   handlers, which the Content-Security-Policy would refuse.
   ========================================================================== */

.range-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0.9rem 0 0.35rem;
  padding: 3px;
  background: var(--panel-inset);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  width: fit-content;
  max-width: 100%;
}

.range-option {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.71rem;
  font-weight: 640;
  letter-spacing: 0.07em;
  padding: 0.34rem 0.72rem;
  border-radius: calc(var(--radius-sm) - 3px);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.range-option:hover { color: var(--ink); background: #16223a; }

.range-option:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 1px;
}

/* The selected range has to be unmistakable: a chart labelled 30D that is
   actually showing LIVE would be read as a claim about the last month. */
.range-option.is-selected {
  background: var(--blue);
  color: #04101f;
  box-shadow: 0 1px 4px rgba(79, 156, 249, 0.35);
}

.chart-envelope-note {
  color: var(--ink-faint);
  font-size: 0.68rem;
  margin-left: 0.3rem;
}

/* Sparse or absent history is a normal state on a new install, so it gets a
   plain sentence under the chart rather than an error treatment. */
.chart-status:empty { display: none; }

.chart-status {
  margin: 0.55rem 0 0;
  padding: 0.5rem 0.7rem;
  font-size: 0.74rem;
  line-height: 1.45;
  color: var(--ink-dim);
  background: var(--panel-inset);
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
}

/* ==========================================================================
   POWER PAGE
   ========================================================================== */

.summary-card--power  { --accent: var(--amber); }
.summary-card--avg    { --accent: var(--blue); }
.summary-card--peak   { --accent: var(--red); }
.summary-card--energy { --accent: var(--green); }
.summary-card--cost   { --accent: var(--teal); }

.swatch--power { background: var(--green); }
.swatch--temperature { background: var(--amber); }

.summary-card--power .summary-value .unit { margin-left: 0.15rem; }

/* ==========================================================================
   POWER SUPPLIES
   Severity is deliberately not a gradient from "fine" to "red". A supply that
   is present and healthy but unplugged is INFORMATION, not a fault; styling it
   critical would send someone to the rack for a cable pulled on purpose, and
   would teach the operator to ignore red.
   ========================================================================== */

.psu-grid {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 0.8rem;
}

.psu {
  background: var(--panel-inset);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 0.85rem 0.95rem;
}

.psu--ok       { border-left-color: var(--green); }
.psu--info     { border-left-color: var(--blue); }
.psu--warn     { border-left-color: var(--amber); }
.psu--critical { border-left-color: var(--red); }

.psu-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}

.psu-name { font-weight: 640; font-size: 0.86rem; }

.psu-state {
  font-size: 0.68rem;
  font-weight: 640;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.16rem 0.5rem;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  white-space: nowrap;
}

.psu-state--ok       { color: var(--green); }
.psu-state--info     { color: var(--blue); }
.psu-state--warn     { color: var(--amber); }
.psu-state--critical { color: var(--red); }

.psu-facts {
  display: grid;
  grid-template-columns: minmax(5.5rem, auto) minmax(0, 1fr);
  gap: 0.3rem 0.8rem;
  margin: 0;
  font-size: 0.78rem;
}

.psu-facts dt { color: var(--ink-dim); }
.psu-facts dd { margin: 0; font-variant-numeric: tabular-nums; }

.psu-raw {
  margin: 0.65rem 0 0;
  font-size: 0.68rem;
  color: var(--ink-faint);
  word-break: break-word;
}

.redundancy {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
  margin-top: 0.95rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--panel-inset);
}

.redundancy--ok       { border-color: rgba(61, 220, 151, 0.35); }
.redundancy--warn     { border-color: rgba(245, 181, 68, 0.35); }
.redundancy--critical { border-color: rgba(244, 115, 107, 0.4); }

.redundancy-label {
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.redundancy-reason {
  flex: 1 1 18rem;
  font-size: 0.76rem;
  color: var(--ink-soft);
}

/* Marks which period and origin a headline figure came from, so the BMC's
   ten-minute window and the dashboard's 24-hour history are never confused. */
.source-tag {
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 0.05rem 0.4rem;
}

/* Chart keys for the memory page's history charts, matching HISTORY_COLORS
   in dashboard.js so the swatch and the line agree. */
.swatch--memory { background: var(--teal); }
.swatch--swap { background: var(--green); }

/* ==========================================================================
   SCOPE SELECTOR
   Picks which mount point (or interface) a history chart describes. A real
   <select> because the list is as long as the host makes it; styled to sit
   beside the range selector without competing with it.
   ========================================================================== */

.scope-selector {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.9rem;
}

.scope-label {
  font-size: 0.68rem;
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.scope-select {
  appearance: none;
  font: inherit;
  font-size: 0.78rem;
  font-family: var(--font-mono);
  color: var(--ink);
  background: var(--panel-inset);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.32rem 1.9rem 0.32rem 0.7rem;
  cursor: pointer;
  /* Inline SVG caret: a data: URI, which the CSP's img-src allows, so no
     external asset and no inline style attribute. */
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236f83a3' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.65rem center;
  background-size: 10px 6px;
}

.scope-select:hover { border-color: var(--line-strong); }

.scope-select:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 1px;
}

/* The native dropdown list is painted by the OS; give it usable colours in a
   dark theme rather than leaving it white-on-white. */
.scope-select option {
  background: var(--panel);
  color: var(--ink);
}

.swatch--storage { background: var(--green); }

/* The stat row under the storage chart is a summary of one filesystem, not a
   second copy of the table, so it sits tighter than a panel's own stat row. */
#storage-selected { margin-top: 1rem; }

/* ==========================================================================
   SYSTEM INFO LAYOUT
   Three explicit rows instead of one auto-fitting grid. The default
   .panel-grid uses auto-fit, which reflows cards into whatever columns happen
   to fit and leaves them ragged; here the rows are a decision, so they are
   declared. Gap and padding are inherited from .panel-grid so the spacing
   matches the CPU, Memory and Network pages exactly.
   ========================================================================== */

.panel-grid--thirds {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Cards in a row end at the same baseline rather than each stopping at its
     own content height, which is what made the page look uneven. */
  align-items: stretch;
}

.panel-grid--thirds .panel-body { display: flex; flex-direction: column; }
.panel-grid--thirds .panel-body > * { min-width: 0; }

/* Anchor a card's closing note to the bottom so the shorter card in a row
   spends its extra height on something useful instead of a void. */
.panel-grid--pairs .panel-inline-note:last-child,
.panel-grid--thirds .panel-inline-note:last-child {
  margin-top: auto;
  padding-top: 1rem;
}

/* Several links in one note sit on a line of their own, evenly spaced. */
.panel-inline-note .summary-link { margin-top: 0.5rem; margin-right: 1rem; }

/* --- read surface ------------------------------------------------------- */

.surface-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1.1rem 1.6rem;
}

.surface-group { min-width: 0; }

.surface-label {
  display: block;
  font-size: 0.68rem;
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 0.55rem;
}

.surface-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.surface-chip {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--ink);
  background: var(--panel-inset);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.2rem 0.55rem;
  overflow-wrap: anywhere;
}

/* Amber, not red: these paths are refused by design, which is the system
   working rather than a fault. */
.surface-chip--denied {
  color: var(--amber);
  border-color: rgba(245, 181, 68, 0.32);
}

@media (max-width: 1100px) {
  .panel-grid--thirds { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .panel-grid--thirds { grid-template-columns: 1fr; align-items: start; }
}

/* ==========================================================================
   SYSTEM UNIT MONITORING
   A compact table rather than a card per service: a card each would be a
   wall, and the facts per unit are few enough to line up in columns.
   ========================================================================== */

.unit-summary {
  margin: 0 0 0.9rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.unit-description {
  display: block;
  font-size: 0.7rem;
  font-weight: 400;
  color: var(--ink-faint);
  margin-top: 0.15rem;
}

.unit-name { color: var(--ink-soft); }

.unit-state {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 640;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.16rem 0.5rem;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  white-space: nowrap;
}

/* No critical variant: this source cannot observe failure, so it never
   claims to. A unit that is not running reads neutrally. */
.unit-state--ok   { color: var(--green); }
.unit-state--info { color: var(--ink-dim); }
.unit-state--warn { color: var(--amber); }

.unit-gaps {
  margin: 0.5rem 0 0.9rem;
  padding-left: 1.1rem;
  font-size: 0.72rem;
  line-height: 1.6;
  color: var(--ink-faint);
}

.unit-gaps li { margin-bottom: 0.3rem; }

/* ==========================================================================
   LOG VIEWER
   Dense and operational: a log table earns its space by fitting many lines on
   screen, not by giving each one a card. Row height is fixed and long
   messages truncate, so scanning down the Time column is not interrupted by
   rows of varying depth.
   ========================================================================== */

/* --- control row -------------------------------------------------------- */

.log-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  margin-bottom: 1.15rem;
}

.log-control {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 0;
}

/* Search takes whatever the fixed-width controls leave. */
.log-control--grow { flex: 1 1 18rem; }

.log-control-label {
  font-size: 0.66rem;
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* One height for every control on the row, so they line up on their
   baselines instead of drifting by a pixel or two each. */
.log-controls .scope-select,
.log-controls .log-search,
.log-controls .range-selector,
.log-controls .btn--filter {
  height: 2.1rem;
  margin: 0;
}

.log-controls .range-selector {
  display: inline-flex;
  align-items: stretch;
  padding: 2px;
}

.log-controls .range-option {
  display: inline-flex;
  align-items: center;
  padding: 0 0.7rem;
  text-decoration: none;
}

.log-controls .btn--filter {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;          /* Refresh stays compact */
  white-space: nowrap;
}

.log-search {
  width: 100%;
  font: inherit;
  font-size: 0.82rem;
  color: var(--ink);
  background: var(--panel-inset);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0 0.7rem;
}

.log-search::placeholder { color: var(--ink-faint); }
.log-search:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* --- legacy banner ------------------------------------------------------ */

.log-banner {
  margin: 0 0 1rem;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  font-size: 0.78rem;
  border: 1px solid rgba(245, 181, 68, 0.32);
  background: var(--panel-inset);
  color: var(--ink-soft);
}
.log-banner--legacy strong { color: var(--amber); }

/* --- table -------------------------------------------------------------- */

/* Fixed layout so the columns keep their widths regardless of content; it is
   also what lets the message cell truncate instead of stretching the table. */
.log-table {
  table-layout: fixed;
  width: 100%;
  font-size: 0.78rem;
}

.log-table th,
.log-table td {
  padding: 0.34rem 0.7rem;
  border-bottom: 1px solid var(--line-soft);
}

.log-table tbody tr:last-child td { border-bottom: none; }
.log-table tbody tr:hover { background: rgba(79, 156, 249, 0.05); }

.log-table th:first-child,
.log-table td:first-child { padding-left: 0; }

/* Column widths: time and level are as wide as their content needs, source
   fits "systemd [1]" and "nginx [12345]", message takes the rest. */
.log-table th:nth-child(1), .log-table td:nth-child(1) { width: 5.5rem; }
.log-table th:nth-child(2), .log-table td:nth-child(2) { width: 6.25rem; }
.log-table th:nth-child(3), .log-table td:nth-child(3) { width: 11rem; }
.log-table th:nth-child(4), .log-table td:nth-child(4) { width: auto; }

/* One row, one line. The full text is on the cell's title attribute. */
.log-time,
.log-source,
.log-message {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.log-time { color: var(--ink-dim); font-size: 0.74rem; }

.log-source { color: var(--ink-soft); font-size: 0.74rem; }
.log-pid { color: var(--ink-faint); margin-left: 0.25rem; }

.log-message {
  color: var(--ink);
  font-size: 0.76rem;
  line-height: 1.5;
}

.log-level-cell { line-height: 1; }

.log-level {
  display: inline-block;
  width: 100%;
  max-width: 5.1rem;
  text-align: center;
  font-family: var(--font);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.14rem 0.3rem;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
}

.log-level--critical { color: var(--red); }
.log-level--warn     { color: var(--amber); }
.log-level--info     { color: var(--ink-dim); }
.log-level--muted    { color: var(--ink-faint); }

/* --- footer ------------------------------------------------------------- */

/* The result summary is about *this* query; the disclosure is a standing
   caveat. Separating them stops the second being read as part of the first. */
.log-summary {
  margin: 0.85rem 0 0;
  font-size: 0.76rem;
  color: var(--ink-soft);
}
.log-summary strong { color: var(--ink); }

.log-disclosure {
  margin: 0.5rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.7rem;
  line-height: 1.55;
  color: var(--ink-faint);
}

/* --- approved sources --------------------------------------------------- */

/* Two columns where there is room: one long column was a tall
   thin card next to a short wide one. */
.source-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 0.1rem 1.5rem;
}

.source-item {
  padding: 0.28rem 0;
  font-size: 0.79rem;
  min-width: 0;
}

/* Legacy sources stay visually distinct from active ones. */
.source-item--legacy .inline-link { color: var(--amber); }

.source-note {
  display: block;
  font-size: 0.67rem;
  line-height: 1.45;
  color: var(--ink-faint);
}

/* --- responsive --------------------------------------------------------- */

@media (max-width: 900px) {
  /* Controls stack; each takes the full width so nothing is squeezed. */
  .log-control,
  .log-control--grow { flex: 1 1 100%; }
  .log-controls .btn--filter { width: 100%; justify-content: center; }

  /* The table keeps its shape and scrolls inside .table-scroll rather than
     forcing the page sideways. */
  .log-table { min-width: 34rem; }
  .log-table th:nth-child(3), .log-table td:nth-child(3) { width: 8rem; }
}

/* ==========================================================================
   Sign-in screen
   --------------------------------------------------------------------------
   Its own layout, because the page deliberately does not extend the dashboard
   shell: no sidebar, no top bar, and nothing that would name the host to a
   visitor who has not signed in.
   ========================================================================== */

.login-shell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem;
}

.login {
  width: 100%;
  max-width: 26rem;
}

.login-panel {
  background: var(--surface, #151a21);
  border: 1px solid var(--border, #232a34);
  border-radius: 10px;
  padding: 2.25rem 2rem;
  text-align: center;
}

.login-eyebrow {
  margin: 0 0 0.35rem;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted, #8b95a3);
}

.login-title {
  margin: 0 0 1rem;
  font-size: 1.5rem;
  line-height: 1.2;
}

.login-lede {
  margin: 0 0 1.75rem;
  color: var(--muted, #8b95a3);
}

.login-notice {
  margin: 0 0 1.5rem;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  border: 1px solid var(--warn-border, #6b4b1f);
  background: var(--warn-surface, #241b0e);
  text-align: left;
}

.login-action {
  display: inline-block;
  min-width: 10rem;
  padding: 0.7rem 1.5rem;
  font-size: 1rem;
  text-decoration: none;
}

.login-foot {
  margin: 1.75rem 0 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted, #8b95a3);
}
