/* UnifiedSDN console.
   Tokens first; light theme is the default, dark applies from the OS
   preference unless the person picks a theme ([data-theme] on <html>). */

:root {
  color-scheme: light;
  --bg: #f4f6f4;
  --surface: #ffffff;
  --surface-2: #f8faf8;
  --sunken: #eef2ef;
  --ink: #16201c;
  --ink-2: #55625b;
  --ink-3: #7a857f;
  --line: #dce2de;
  --line-strong: #c6cfca;
  --link: #2456c8;
  --focus: #2456c8;
  --primary: #16201c;
  --primary-ink: #ffffff;
  --primary-hover: #2c3a33;
  --ok: #1d7a4b;
  --ok-bg: #e6f3eb;
  --warn: #9a5b00;
  --warn-bg: #fbf0dc;
  --bad: #b42318;
  --bad-bg: #fdeceb;
  --idle: #66716b;
  --idle-bg: #eef1ef;
  --info-bg: #ecf1fb;
  --rail: #c6cfca;
  --rail-lit: #1d7a4b;
  --chart-line: #2f7d58;
  --chart-line-2: #9fb4a8;
  --chart-fill: #2f7d58;
  --chart-grid: #e3e8e5;
  /* Telemetry series: download and upload are fixed; s1-s6 are the
     palette for legs, classes and WANs, in that order. */
  --chart-down: #2563eb;
  --chart-up: #c2410c;
  --chart-s1: #0f766e;
  --chart-s2: #7c3aed;
  --chart-s3: #b45309;
  --chart-s4: #be185d;
  --chart-s5: #2563eb;
  --chart-s6: #4d7c0f;
  --overlay: rgb(16 22 19 / 0.42);
  --shadow-pop: 0 1px 2px rgb(16 22 19 / 0.06), 0 12px 32px rgb(16 22 19 / 0.14);

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
  /* Type scale: 1.2 minor third from a 14px base. */
  --t-xs: 0.75rem;
  --t-sm: 0.8125rem;
  --t-base: 0.875rem;
  --t-md: 1rem;
  --t-lg: 1.25rem;
  --t-xl: 1.625rem;
  --t-num: 2rem;
  /* Spacing on a 4px grid. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s8: 32px;
  --s10: 40px;
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --sidebar: 252px;
  --topbar: 60px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --fast: 140ms;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0e1311;
    --surface: #151c19;
    --surface-2: #19211e;
    --sunken: #111715;
    --ink: #e5ebe7;
    --ink-2: #a3afa8;
    --ink-3: #7e8a83;
    --line: #26302b;
    --line-strong: #34403a;
    --link: #86a8ff;
    --focus: #86a8ff;
    --primary: #e5ebe7;
    --primary-ink: #0e1311;
    --primary-hover: #c9d3cd;
    --ok: #57c78f;
    --ok-bg: #13291d;
    --warn: #e5a94a;
    --warn-bg: #2c2210;
    --bad: #f28b82;
    --bad-bg: #2f1715;
    --idle: #97a29c;
    --idle-bg: #1f2724;
    --info-bg: #172036;
    --rail: #34403a;
    --rail-lit: #57c78f;
    --chart-line: #57c78f;
    --chart-line-2: #4f6a5c;
    --chart-fill: #57c78f;
    --chart-grid: #232c28;
    --chart-down: #60a5fa;
    --chart-up: #fb923c;
    --chart-s1: #2dd4bf;
    --chart-s2: #a78bfa;
    --chart-s3: #fbbf24;
    --chart-s4: #f472b6;
    --chart-s5: #60a5fa;
    --chart-s6: #a3e635;
    --overlay: rgb(0 0 0 / 0.6);
    --shadow-pop: 0 1px 2px rgb(0 0 0 / 0.4), 0 16px 40px rgb(0 0 0 / 0.5);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0e1311;
  --surface: #151c19;
  --surface-2: #19211e;
  --sunken: #111715;
  --ink: #e5ebe7;
  --ink-2: #a3afa8;
  --ink-3: #7e8a83;
  --line: #26302b;
  --line-strong: #34403a;
  --link: #86a8ff;
  --focus: #86a8ff;
  --primary: #e5ebe7;
  --primary-ink: #0e1311;
  --primary-hover: #c9d3cd;
  --ok: #57c78f;
  --ok-bg: #13291d;
  --warn: #e5a94a;
  --warn-bg: #2c2210;
  --bad: #f28b82;
  --bad-bg: #2f1715;
  --idle: #97a29c;
  --idle-bg: #1f2724;
  --info-bg: #172036;
  --rail: #34403a;
  --rail-lit: #57c78f;
  --chart-line: #57c78f;
  --chart-line-2: #4f6a5c;
  --chart-fill: #57c78f;
  --chart-grid: #232c28;
  --chart-down: #60a5fa;
  --chart-up: #fb923c;
  --chart-s1: #2dd4bf;
  --chart-s2: #a78bfa;
  --chart-s3: #fbbf24;
  --chart-s4: #f472b6;
  --chart-s5: #60a5fa;
  --chart-s6: #a3e635;
  --overlay: rgb(0 0 0 / 0.6);
  --shadow-pop: 0 1px 2px rgb(0 0 0 / 0.4), 0 16px 40px rgb(0 0 0 / 0.5);
}

/* Accent palettes recolour actions, focus, links and the lit rail node. */
:root[data-accent="signal"] {
  --primary: #1f4fbf;
  --primary-hover: #183f9a;
  --rail-lit: #2456c8;
  --chart-line: #2456c8;
  --chart-fill: #2456c8;
}
:root[data-accent="graphite"] {
  --primary: #3b4148;
  --primary-hover: #2b3036;
  --rail-lit: #3b4148;
  --link: #3b4148;
  --focus: #3b4148;
  --chart-line: #4c5560;
  --chart-fill: #4c5560;
}
:root[data-accent="copper"] {
  --primary: #8a4a1f;
  --primary-hover: #723c18;
  --rail-lit: #b0612a;
  --link: #8a4a1f;
  --focus: #b0612a;
  --chart-line: #b0612a;
  --chart-fill: #b0612a;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"])[data-accent="signal"] {
    --primary: #86a8ff;
    --primary-hover: #a6bfff;
    --primary-ink: #0b1430;
    --rail-lit: #86a8ff;
    --chart-line: #86a8ff;
    --chart-fill: #86a8ff;
  }
  :root:not([data-theme="light"])[data-accent="graphite"] {
    --primary: #cdd3d9;
    --primary-hover: #e1e6ea;
    --rail-lit: #cdd3d9;
    --link: #cdd3d9;
    --focus: #cdd3d9;
    --chart-line: #aeb7c0;
    --chart-fill: #aeb7c0;
  }
  :root:not([data-theme="light"])[data-accent="copper"] {
    --primary: #e7a06c;
    --primary-hover: #f0b78d;
    --primary-ink: #2a1505;
    --rail-lit: #e7a06c;
    --link: #f0b78d;
    --focus: #e7a06c;
    --chart-line: #e7a06c;
    --chart-fill: #e7a06c;
  }
}
:root[data-theme="dark"][data-accent="signal"] {
  --primary: #86a8ff;
  --primary-hover: #a6bfff;
  --primary-ink: #0b1430;
  --rail-lit: #86a8ff;
  --chart-line: #86a8ff;
  --chart-fill: #86a8ff;
}
:root[data-theme="dark"][data-accent="graphite"] {
  --primary: #cdd3d9;
  --primary-hover: #e1e6ea;
  --rail-lit: #cdd3d9;
  --link: #cdd3d9;
  --focus: #cdd3d9;
  --chart-line: #aeb7c0;
  --chart-fill: #aeb7c0;
}
:root[data-theme="dark"][data-accent="copper"] {
  --primary: #e7a06c;
  --primary-hover: #f0b78d;
  --primary-ink: #2a1505;
  --rail-lit: #e7a06c;
  --link: #f0b78d;
  --focus: #e7a06c;
  --chart-line: #e7a06c;
  --chart-fill: #e7a06c;
}

/* ---------- Base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1,
h2,
h3,
p {
  margin: 0;
}
h1,
h2,
h3 {
  line-height: 1.25;
  text-wrap: balance;
}
p {
  text-wrap: pretty;
}
small {
  font-size: var(--t-sm);
  color: var(--ink-2);
}
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
button {
  cursor: pointer;
  border: 0;
  background: none;
  padding: 0;
}
button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
a {
  color: inherit;
  text-decoration: none;
}
svg {
  display: block;
}
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}
::selection {
  background: color-mix(in srgb, var(--link) 25%, transparent);
}
.icon {
  inline-size: 18px;
  block-size: 18px;
  flex-shrink: 0;
}
.mono {
  font-family: var(--mono);
  font-size: var(--t-sm);
  overflow-wrap: anywhere;
}
.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.skip-link {
  position: fixed;
  inset-block-start: var(--s2);
  inset-inline-start: var(--s2);
  z-index: 100;
  padding: var(--s2) var(--s4);
  background: var(--primary);
  color: var(--primary-ink);
  border-radius: var(--r-sm);
  transform: translateY(-200%);
}
.skip-link:focus {
  transform: none;
}
.error-text {
  color: var(--bad);
}
.warning-text {
  color: var(--warn);
}
.mt-16 {
  margin-block-start: var(--s4);
}
.spaced {
  margin-block-start: var(--s6);
}

/* ---------- Boot / skeleton ---------- */
.boot {
  display: grid;
  grid-template-columns: var(--sidebar) 1fr;
  min-height: 100dvh;
}
.boot-rail {
  background: var(--surface);
  border-inline-end: 1px solid var(--line);
}
.boot-main {
  padding: var(--s8);
  display: grid;
  gap: var(--s4);
  align-content: start;
}
.skeleton {
  border-radius: var(--r-md);
  background: linear-gradient(90deg, var(--sunken) 0%, var(--surface-2) 50%, var(--sunken) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.3s linear infinite;
}
.sk-title {
  block-size: 44px;
  inline-size: min(320px, 70%);
}
.sk-metrics {
  block-size: 120px;
}
.sk-panel {
  block-size: 360px;
}
@keyframes shimmer {
  to {
    background-position: -200% 0;
  }
}
@media (max-width: 960px) {
  .boot {
    grid-template-columns: 1fr;
  }
  .boot-rail {
    display: none;
  }
}

/* ---------- Shell ---------- */
.shell {
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  min-height: 100dvh;
}
.sidebar {
  position: sticky;
  inset-block-start: 0;
  block-size: 100dvh;
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s5) var(--s4);
  background: var(--surface);
  border-inline-end: 1px solid var(--line);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.01em;
  padding-inline: var(--s2);
}
.brand-mark {
  display: grid;
  place-items: center;
  inline-size: 30px;
  block-size: 30px;
  border-radius: 8px;
  background: var(--primary);
  color: var(--primary-ink);
}
.brand-mark .icon {
  inline-size: 18px;
  block-size: 18px;
}
.nav-label {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--ink-3);
  padding-inline: var(--s3);
  margin-block: var(--s2) calc(var(--s1) * -1);
}
/* The topology rail: nav items are nodes on one path; the active node lights. */
.nav {
  position: relative;
  display: grid;
  gap: 2px;
}
.nav::before {
  content: "";
  position: absolute;
  inset-block: 14px;
  inset-inline-start: 21px;
  border-inline-start: 1px dashed var(--rail);
}
.nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-block-size: 38px;
  padding: var(--s2) var(--s3);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-weight: 500;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.nav a .icon {
  position: relative;
  inline-size: 18px;
  block-size: 18px;
  padding: 0;
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--surface);
  border-radius: 4px;
}
.nav a:hover {
  background: var(--sunken);
  color: var(--ink);
}
.nav a[aria-current="page"] {
  background: var(--sunken);
  color: var(--ink);
  font-weight: 600;
}
.nav a[aria-current="page"] .icon {
  color: var(--rail-lit);
  background: var(--sunken);
  box-shadow: 0 0 0 3px var(--sunken);
}
.nav a[aria-current="page"]::before {
  content: "";
  position: absolute;
  inset-inline-start: -16px;
  inset-block: 9px;
  inline-size: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--rail-lit);
}
.nav .count {
  margin-inline-start: auto;
  min-inline-size: 22px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--sunken);
  color: var(--ink-2);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.nav a[aria-current="page"] .count {
  background: var(--surface);
}
.sidebar-bottom {
  margin-block-start: auto;
  display: grid;
  gap: var(--s3);
  padding-block-start: var(--s4);
  border-block-start: 1px solid var(--line);
}
.profile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2);
}
.profile strong,
.profile small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile small {
  text-transform: capitalize;
}
.avatar {
  display: grid;
  place-items: center;
  inline-size: 34px;
  block-size: 34px;
  border-radius: 50%;
  background: var(--sunken);
  border: 1px solid var(--line);
  font-size: var(--t-sm);
  font-weight: 700;
}
.profile button {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: var(--r-sm);
  color: var(--ink-2);
}
.profile button:hover {
  background: var(--sunken);
  color: var(--ink);
}

/* Workspace (organization) switcher */
.workspace {
  position: relative;
}
.workspace-trigger {
  display: flex;
  align-items: center;
  gap: var(--s2);
  inline-size: 100%;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  text-align: start;
  transition: border-color var(--fast) var(--ease);
}
.workspace-trigger:hover {
  border-color: var(--line-strong);
}
.workspace-copy {
  min-inline-size: 0;
  flex: 1;
}
.workspace-copy strong,
.workspace-copy small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.workspace-copy small {
  text-transform: capitalize;
}
/* Placed by setOrgMenu in viewport coordinates; it lives in the top layer
   where popovers are supported, and is top-most by z-index elsewhere. */
.workspace-menu {
  position: fixed;
  z-index: 2147483647;
  inset: auto;
  margin: 0;
  max-block-size: calc(100dvh - 24px);
  overflow-y: auto;
  min-inline-size: 260px;
  color: inherit;
  padding: var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--shadow-pop);
}
.workspace-menu[hidden],
.org-option[hidden],
.org-empty[hidden],
.field[hidden] {
  display: none;
}
.workspace-menu-heading {
  padding: var(--s2) var(--s2) var(--s3);
}
.workspace-menu-heading strong {
  display: block;
}
.workspace-menu-heading span {
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.org-search {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-block-end: var(--s2);
  padding: 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink-3);
}
.org-search input {
  flex: 1;
  min-inline-size: 0;
  block-size: 36px;
  border: 0;
  background: none;
  outline: none;
}
.org-options {
  display: grid;
  gap: 2px;
  max-block-size: 280px;
  overflow-y: auto;
}
.org-option {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2);
  border-radius: var(--r-sm);
  text-align: start;
}
.org-option:hover,
.org-option:focus-visible {
  background: var(--sunken);
}
.org-option.selected {
  background: var(--sunken);
}
.org-option-icon {
  display: grid;
  place-items: center;
  inline-size: 30px;
  block-size: 30px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  color: var(--ink-2);
}
.org-option-copy {
  flex: 1;
  min-inline-size: 0;
}
.org-option-copy strong,
.org-option-copy small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.org-option > .icon {
  color: var(--ok);
}
.org-divider {
  block-size: 1px;
  margin: var(--s1) var(--s2);
  background: var(--line);
}
.org-empty {
  padding: var(--s3);
  color: var(--ink-2);
}

/* ---------- Topbar ---------- */
.main {
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
}
.topbar {
  position: sticky;
  inset-block-start: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-block-size: var(--topbar);
  padding: var(--s2) var(--s8);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--line);
}
.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-inline-size: 0;
  font-size: var(--t-sm);
  color: var(--ink-2);
  white-space: nowrap;
}
.breadcrumb span:last-child {
  color: var(--ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}
.top-right {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-inline-start: auto;
}
.global-search {
  display: flex;
  align-items: center;
  gap: var(--s2);
  inline-size: clamp(180px, 28vw, 320px);
  padding: 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink-3);
  transition: border-color var(--fast) var(--ease);
}
.global-search:focus-within {
  border-color: var(--focus);
}
.global-search input {
  flex: 1;
  min-inline-size: 0;
  block-size: 36px;
  border: 0;
  background: none;
  outline: none;
  color: var(--ink);
}
.global-search input::-webkit-search-cancel-button {
  cursor: pointer;
}
.keyboard {
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-family: var(--mono);
  font-size: var(--t-xs);
  color: var(--ink-3);
}
.separator {
  inline-size: 1px;
  block-size: 22px;
  background: var(--line);
}
.icon-button {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.icon-button:hover {
  background: var(--sunken);
  color: var(--ink);
}
.mobile-menu {
  display: none;
}
.demo-tag {
  padding: 3px var(--s2);
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn);
  font-size: var(--t-xs);
  font-weight: 600;
  white-space: nowrap;
}
.theme-toggle .icon {
  inline-size: 18px;
  block-size: 18px;
}

/* ---------- Content ---------- */
.content {
  inline-size: 100%;
  max-inline-size: 1600px;
  padding: var(--s8);
  outline: none;
}
.page-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s4);
  margin-block-end: var(--s6);
}
.page-heading h1 {
  font-size: var(--t-xl);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.subtitle {
  margin-block-start: var(--s1);
  color: var(--ink-2);
  max-inline-size: 70ch;
}
.heading-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.page-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s2);
  margin-block-start: var(--s8);
  padding-block-start: var(--s4);
  border-block-start: 1px solid var(--line);
  font-size: var(--t-xs);
  color: var(--ink-3);
}
.page-footer > span {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
}

/* ---------- Buttons, links, badges ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-block-size: 36px;
  padding: 0 var(--s4);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  font-size: var(--t-sm);
  white-space: nowrap;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.btn:hover:not(:disabled) {
  background: var(--sunken);
}
.btn:active:not(:disabled) {
  transform: translateY(1px);
}
.btn .icon {
  inline-size: 16px;
  block-size: 16px;
}
.btn-primary {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-ink);
}
.btn-primary:hover:not(:disabled) {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}
.btn-danger {
  color: var(--bad);
  border-color: color-mix(in srgb, var(--bad) 40%, var(--line));
}
.btn-danger:hover:not(:disabled) {
  background: var(--bad-bg);
}
.btn[aria-busy="true"] {
  position: relative;
  color: transparent;
}
.btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inline-size: 16px;
  block-size: 16px;
  border: 2px solid currentColor;
  border-color: var(--primary-ink) var(--primary-ink) transparent transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.btn:not(.btn-primary)[aria-busy="true"]::after {
  border-color: var(--ink) var(--ink) transparent transparent;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
.text-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  color: var(--link);
  font-weight: 600;
  font-size: var(--t-sm);
}
.text-link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.text-link .icon {
  inline-size: 14px;
  block-size: 14px;
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px var(--s2);
  border-radius: 999px;
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
  text-transform: capitalize;
  background: var(--ok-bg);
  color: var(--ok);
}
.badge.orange {
  background: var(--warn-bg);
  color: var(--warn);
}
.badge.gray {
  background: var(--idle-bg);
  color: var(--idle);
}
.badge.blue {
  background: var(--info-bg);
  color: var(--link);
}
.badge.red {
  background: var(--bad-bg);
  color: var(--bad);
}
.dot {
  display: inline-block;
  inline-size: 7px;
  block-size: 7px;
  border-radius: 50%;
  background: var(--ok);
  flex-shrink: 0;
}
.dot.warning {
  background: var(--warn);
}
.dot.offline {
  background: var(--idle);
}
.dot.bad {
  background: var(--bad);
}
.badge .dot {
  background: currentColor;
}

/* ---------- Panels, tables ---------- */
.panel {
  min-inline-size: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  container-type: inline-size;
}
.panel-heading,
.table-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
}
.panel-heading > .icon {
  color: var(--ink-3);
}
.panel-heading h2,
.table-heading h2 {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--t-md);
  font-weight: 650;
}
.panel-heading p,
.table-heading p {
  margin-block-start: 2px;
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.sub-count {
  padding: 0 7px;
  border-radius: 999px;
  background: var(--sunken);
  color: var(--ink-2);
  font-size: var(--t-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.table-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
}
.table-actions select {
  block-size: 34px;
  padding: 0 var(--s6) 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
}
.table-wrap {
  overflow-x: auto;
  border-block-start: 1px solid var(--line);
  scrollbar-width: thin;
}
table {
  inline-size: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
th {
  padding: var(--s2) var(--s5);
  text-align: start;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--ink-2);
  background: var(--surface-2);
  border-block-end: 1px solid var(--line);
  white-space: nowrap;
}
td {
  padding: var(--s3) var(--s5);
  border-block-end: 1px solid var(--line);
  vertical-align: middle;
}
tbody tr:last-child td {
  border-block-end: 0;
}
tbody tr {
  transition: background var(--fast) var(--ease);
}
tbody tr:hover {
  background: var(--surface-2);
}
tr[data-device] {
  cursor: pointer;
}
td small {
  display: inline-block;
}
td.mono,
td .mono {
  overflow-wrap: normal;
  white-space: nowrap;
}
.warnings {
  margin: 0;
  padding-inline-start: var(--s4);
  display: grid;
  gap: var(--s2);
}
.table-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s2);
  padding: var(--s3) var(--s5);
  border-block-start: 1px solid var(--line);
  font-size: var(--t-xs);
  color: var(--ink-3);
}
.row-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--s2);
}
.row-actions > button:not(.btn):not(.icon-button),
.row-actions > .icon-link {
  display: grid;
  place-items: center;
  inline-size: 32px;
  block-size: 32px;
  border-radius: var(--r-sm);
  color: var(--ink-3);
}
.row-actions > button:not(.btn):not(.icon-button):hover,
.row-actions > .icon-link:hover {
  background: var(--sunken);
  color: var(--ink);
}
.device-cell {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-inline-size: 200px;
}
.device-cell strong,
.device-cell small {
  display: block;
}
.device-glyph {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: var(--r-md);
  background: var(--sunken);
  color: var(--ink-2);
  flex-shrink: 0;
}
.uplink {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  white-space: nowrap;
}
.uplink .icon {
  color: var(--ink-3);
  inline-size: 16px;
  block-size: 16px;
}

/* ---------- Overview ---------- */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  margin-block-end: var(--s6);
  overflow: hidden;
}
.metric {
  padding: var(--s5);
  min-inline-size: 0;
}
.metric + .metric {
  border-inline-start: 1px solid var(--line);
}
.metric-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.metric-label .icon {
  color: var(--ink-3);
}
.metric-value {
  margin-block: var(--s2) var(--s1);
  font-size: var(--t-num);
  font-weight: 650;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.metric-value small {
  margin-inline-start: var(--s1);
  font-size: var(--t-md);
  font-weight: 500;
  color: var(--ink-3);
  letter-spacing: 0;
}
.metric-bottom {
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.metric-bottom .positive {
  color: var(--ok);
}
.metric-bottom .attention {
  color: var(--warn);
}
.lower-grid {
  display: grid;
  align-items: start;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--s6);
  margin-block-start: var(--s6);
}
.core-meter {
  appearance: none;
  inline-size: 100%;
  block-size: 6px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  background: var(--sunken);
}
.core-meter::-webkit-progress-bar {
  background: var(--sunken);
}
.core-meter::-webkit-progress-value {
  background: var(--ok);
  border-radius: 999px;
}
.core-meter::-moz-progress-bar {
  background: var(--ok);
}

/* Activity */
.activity-list {
  display: grid;
  padding: 0 var(--s5) var(--s2);
}
.activity-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--s3);
  align-items: start;
  padding-block: var(--s3);
  border-block-end: 1px solid var(--line);
}
.activity-item:last-child {
  border-block-end: 0;
}
.activity-symbol {
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  border-radius: 50%;
  background: var(--sunken);
  color: var(--ink-2);
}
.activity-symbol .icon {
  inline-size: 14px;
  block-size: 14px;
}
.activity-body p {
  overflow-wrap: anywhere;
}
.activity-time {
  font-size: var(--t-xs);
  color: var(--ink-3);
  white-space: nowrap;
}

/* ---------- Notices & explainers ---------- */
.notice {
  padding: var(--s3) var(--s4);
  border-radius: var(--r-md);
  background: var(--info-bg);
  color: var(--ink);
  font-size: var(--t-sm);
  line-height: 1.55;
  margin-block-end: var(--s4);
}
.notice.warning {
  background: var(--warn-bg);
}
.notice:last-child {
  margin-block-end: 0;
}
.explainer {
  margin-block-end: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--t-sm);
}
.explainer summary {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}
.explainer summary::-webkit-details-marker {
  display: none;
}
.explainer summary .icon {
  inline-size: 16px;
  block-size: 16px;
  color: var(--ink-3);
  transition: transform var(--fast) var(--ease);
}
.explainer[open] summary .icon {
  transform: rotate(90deg);
}
.explainer p {
  padding: 0 var(--s4) var(--s4) calc(var(--s4) + 24px);
  color: var(--ink-2);
  max-inline-size: 90ch;
}

/* ---------- Empty states ---------- */
.empty {
  display: grid;
  justify-items: center;
  gap: var(--s2);
  padding: var(--s10) var(--s5);
  text-align: center;
  color: var(--ink-2);
}
.empty > .icon {
  inline-size: 28px;
  block-size: 28px;
  color: var(--ink-3);
  margin-block-end: var(--s1);
}
.empty strong {
  color: var(--ink);
  font-size: var(--t-md);
}
.empty p {
  max-inline-size: 48ch;
}
.empty .btn {
  margin-block-start: var(--s2);
}
/* ---------- Cards (organizations, wizards, infrastructure) ---------- */

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--s3);
  margin-block: var(--s2);
}
.detail-grid > div {
  display: grid;
  gap: var(--s1);
  justify-items: start;
  padding: var(--s3);
  border-radius: var(--r-md);
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.detail-grid strong {
  font-size: var(--t-md);
  font-variant-numeric: tabular-nums;
}
.detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-block: var(--s2);
}
.detail-header {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-block-end: var(--s3);
}
.detail-header strong,
.detail-header small {
  display: block;
}

/* Appearance choices */
.choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.choice {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-block-size: 36px;
  padding: 0 var(--s3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-2);
}
.choice .icon {
  inline-size: 16px;
  block-size: 16px;
}
.choice:hover {
  background: var(--sunken);
  color: var(--ink);
}
.choice[aria-pressed="true"] {
  border-color: var(--primary);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.swatch {
  inline-size: 14px;
  block-size: 14px;
  border-radius: 50%;
}
.swatch[data-swatch="forest"] {
  background: #1d7a4b;
}
.swatch[data-swatch="signal"] {
  background: #2456c8;
}
.swatch[data-swatch="graphite"] {
  background: #3b4148;
}
.swatch[data-swatch="copper"] {
  background: #b0612a;
}

/* Operations */
.operation {
  padding: var(--s4) var(--s5);
  border-block-start: 1px solid var(--line);
}
.operation-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--s2);
  margin-block-end: var(--s1);
}
.operation-head > div:last-child {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-block-start: var(--s3);
}
.step {
  display: grid;
  padding: var(--s1) var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  color: var(--ink-2);
  background: var(--surface-2);
}
.step.done {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 30%, var(--line));
  background: var(--ok-bg);
}
.step.action {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 35%, var(--line));
  background: var(--warn-bg);
}
.step small {
  color: inherit;
  opacity: 0.85;
}

/* Settings */
.settings-list {
  display: grid;
}
.settings-row {
  display: grid;
  grid-template-columns: minmax(160px, 260px) minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s4) var(--s5);
  border-block-start: 1px solid var(--line);
}
.settings-row p {
  color: var(--ink-2);
}

/* ---------- Key/value, code ---------- */
.kv {
  display: grid;
  grid-template-columns: minmax(120px, max-content) minmax(0, 1fr);
  gap: var(--s2) var(--s5);
  margin-block: var(--s3);
  font-size: var(--t-sm);
}
.kv > span:nth-child(odd) {
  color: var(--ink-2);
}
.kv > span:nth-child(even) {
  min-inline-size: 0;
  overflow-wrap: anywhere;
}
/* Router page sections. */
.tabs {
  display: flex;
  gap: var(--s1);
  margin-block-end: var(--s4);
  border-block-end: 1px solid var(--line);
  overflow-x: auto;
}
.tabs a {
  padding: var(--s2) var(--s3);
  border-block-end: 2px solid transparent;
  margin-block-end: -1px;
  color: var(--ink-2);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.tabs a:hover {
  color: var(--ink);
}
.tabs a[aria-current="page"] {
  color: var(--ink);
  border-block-end-color: var(--ink);
}
/* List filters and sorts, above a list's rows. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-block-start: 1px solid var(--line);
}
.filter-field {
  display: grid;
  gap: var(--s1);
}
.filter-field label {
  color: var(--ink-2);
  font-size: var(--t-xs);
  font-weight: 600;
}
.filter-field input,
.filter-field select {
  block-size: 34px;
  min-inline-size: 9rem;
  max-inline-size: 100%;
  padding: 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.filter-bar .text-link {
  block-size: 34px;
}
@media (max-width: 640px) {
  .filter-field {
    flex: 1 1 100%;
  }
}
/* "Tunnel › ether3 · Active": where the service lands, then its state. */
.tunnel-status {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1);
  white-space: nowrap;
}
.tunnel-where {
  color: var(--ink-2);
  font-size: var(--t-xs);
}
.cap-row {
  margin: 0 0 var(--s3);
  padding: var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.cap-row legend {
  padding: 0 var(--s1);
  color: var(--ink-2);
  font-size: var(--t-xs);
  font-weight: 600;
}
.total-row td {
  background: var(--surface-2);
}
.muted {
  color: var(--ink-2);
  margin: 0;
}
/* Content placed directly in a panel, aligned with its heading. */
.panel-pad {
  padding: 0 var(--s5) var(--s5);
}
/* A static port's addressing: one label/value line each, values unbroken. */
.addr {
  display: grid;
  grid-template-columns: max-content max-content;
  gap: 0 var(--s3);
  margin-block-start: var(--s1);
}
.addr > span:nth-child(odd) {
  color: var(--ink-2);
}
.addr > .mono {
  white-space: nowrap;
}
.code {
  margin: var(--s2) 0 var(--s3);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--sunken);
  font-family: var(--mono);
  font-size: var(--t-xs);
  line-height: 1.7;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-block-size: 340px;
  overflow: auto;
}
.review-subtitle {
  margin-block: var(--s5) var(--s1);
  font-size: var(--t-base);
  font-weight: 650;
}
.plan-step {
  display: flex;
  gap: var(--s3);
  align-items: flex-start;
  padding-block: var(--s2);
}
.plan-step strong,
.plan-step small {
  display: block;
}
.plan-number {
  display: grid;
  place-items: center;
  inline-size: 24px;
  block-size: 24px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  font-size: var(--t-xs);
  font-weight: 700;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
/* Provisioning: numbered steps with live state and reviewable commands. */
.prov-steps,
.prov-howto {
  margin: var(--s4) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s2);
}
.prov-howto {
  list-style: decimal;
  padding-inline-start: var(--s5);
  gap: var(--s3);
}
.prov-step {
  display: flex;
  gap: var(--s3);
  align-items: flex-start;
}
.prov-step > div {
  display: grid;
  gap: 4px;
  min-inline-size: 0;
  flex: 1;
}
.prov-step small {
  color: var(--ink-2);
}
.prov-step .badge {
  justify-self: start;
}
.prov-step details summary {
  cursor: pointer;
  font-size: var(--t-xs);
  color: var(--ink-2);
}
.prov-step pre.code {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.prov-launch {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-block-end: var(--s4);
}
.prov-launch span {
  color: var(--ink-2);
  flex: 1 1 16rem;
}
.prov-manual {
  margin-block-start: var(--s3);
}
.prov-manual summary {
  cursor: pointer;
  color: var(--ink-2);
}
.prov-manual pre.code {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0;
}
.prov-neighbors td:first-child {
  inline-size: 2rem;
}
.prov-neighbors label {
  cursor: pointer;
}
.prov-searching::before {
  content: "";
  display: inline-block;
  inline-size: 0.6rem;
  block-size: 0.6rem;
  margin-inline-end: var(--s2);
  border-radius: 50%;
  background: currentColor;
  animation: prov-pulse 1.2s ease-in-out infinite;
}
@keyframes prov-pulse {
  50% {
    opacity: 0.25;
  }
}
@media (prefers-reduced-motion: reduce) {
  .prov-searching::before {
    animation: none;
  }
}
.prov-confirm strong {
  display: block;
  margin-block-end: 4px;
}
.help-grid {
  display: grid;
  gap: var(--s3);
  color: var(--ink-2);
}

/* ---------- Forms ---------- */
.field {
  display: grid;
  gap: 6px;
  margin-block-end: var(--s4);
}
.field label {
  font-size: var(--t-sm);
  font-weight: 600;
}
.field input,
.field select,
.field textarea {
  inline-size: 100%;
  min-block-size: 40px;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.field textarea {
  min-block-size: 96px;
  resize: vertical;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 20%, transparent);
}
.field input:user-invalid,
.field select:user-invalid,
.field textarea:user-invalid {
  border-color: var(--bad);
}
.field small {
  font-size: var(--t-xs);
  color: var(--ink-2);
}
.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--s4);
}
.check-label {
  display: flex;
  gap: var(--s3);
  align-items: flex-start;
  margin-block: var(--s3);
  font-size: var(--t-sm);
  cursor: pointer;
}
.check-label input {
  margin-block-start: 3px;
  inline-size: 16px;
  block-size: 16px;
  accent-color: var(--primary);
  flex-shrink: 0;
}
.modal-error,
.login-error {
  min-block-size: 1em;
  color: var(--bad);
  font-size: var(--t-sm);
}
.modal-error:empty,
.login-error:empty {
  display: none;
}

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  /* A definite column, so wide content (an unwrapped script) scrolls inside
     the dialog instead of widening it past the screen. */
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  padding: var(--s4);
  background: var(--overlay);
  animation: fade var(--fast) var(--ease);
}
.modal {
  display: flex;
  flex-direction: column;
  inline-size: min(560px, 100%);
  max-block-size: min(88dvh, 900px);
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-pop);
  animation: rise 180ms var(--ease);
}
.modal.wide {
  inline-size: min(820px, 100%);
}
.modal-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-block-end: 1px solid var(--line);
}
.modal-heading h2 {
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: -0.01em;
}
.modal-body {
  padding: var(--s5);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal-body > .table-heading {
  padding-inline: 0;
}
.modal-body .table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.modal-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--s2);
  padding: var(--s3) var(--s5);
  border-block-start: 1px solid var(--line);
  background: var(--surface-2);
  border-end-start-radius: var(--r-lg);
  border-end-end-radius: var(--r-lg);
}
@keyframes fade {
  from {
    opacity: 0;
  }
}
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.99);
  }
}

/* ---------- Toasts ---------- */
#toasts {
  position: fixed;
  z-index: 60;
  inset-block-end: var(--s5);
  inset-inline-end: var(--s5);
  display: grid;
  gap: var(--s2);
  max-inline-size: min(420px, calc(100vw - 2 * var(--s5)));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-radius: var(--r-md);
  background: var(--primary);
  color: var(--primary-ink);
  box-shadow: var(--shadow-pop);
  font-size: var(--t-sm);
  font-weight: 500;
  pointer-events: auto;
  animation: rise 180ms var(--ease);
}
.toast.error {
  background: var(--bad);
  color: #fff;
}

/* ---------- Login ---------- */
.login-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(360px, 520px);
  min-block-size: 100dvh;
}
.login-story {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s8);
  padding: var(--s10);
  background: var(--sunken);
  border-inline-end: 1px solid var(--line);
}
.login-intro {
  max-inline-size: 520px;
}
.login-intro h1 {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
}
.login-intro > p {
  margin-block-start: var(--s4);
  font-size: var(--t-md);
  color: var(--ink-2);
  max-inline-size: 44ch;
}
.login-art {
  margin-block-start: var(--s8);
  color: var(--ink-3);
}
.login-art svg {
  inline-size: 100%;
  max-inline-size: 460px;
  block-size: auto;
}
.login-art .path {
  stroke: var(--rail);
}
.login-art .node {
  fill: var(--surface);
  stroke: var(--ink-3);
}
.login-art .node.lit {
  fill: var(--rail-lit);
  stroke: var(--rail-lit);
}
.login-story footer {
  font-size: var(--t-sm);
  color: var(--ink-3);
}
.login-form-side {
  display: grid;
  place-items: center;
  padding: var(--s8) var(--s6);
  background: var(--surface);
}
.login-box {
  inline-size: min(380px, 100%);
}
.login-box h2 {
  font-size: var(--t-xl);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.login-box > p {
  margin-block: var(--s2) var(--s6);
  color: var(--ink-2);
}
.login-box form .btn,
.login-box > .btn {
  inline-size: 100%;
  min-block-size: 42px;
}
.login-demo {
  margin-block-start: var(--s6);
  padding: var(--s4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
}
.login-demo strong {
  font-size: var(--t-sm);
}
.login-demo p {
  margin-block: var(--s1) var(--s3);
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.demo-roles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s2);
}
.demo-roles button {
  min-block-size: 34px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: var(--t-sm);
  font-weight: 600;
}
.demo-roles button:hover {
  background: var(--sunken);
}
.login-theme {
  position: fixed;
  inset-block-start: var(--s3);
  inset-inline-end: var(--s3);
}

/* ---------- Drawer backdrop ---------- */
.scrim {
  display: none;
}

/* ---------- Responsive ---------- */
@media (max-width: 1280px) {
  :root {
    --sidebar: 232px;
  }
  .content {
    padding: var(--s6);
  }
  .topbar {
    padding-inline: var(--s6);
  }
}
@media (max-width: 1100px) {
  .lower-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .metric:nth-child(3) {
    border-inline-start: 0;
  }
  .metric:nth-child(n + 3) {
    border-block-start: 1px solid var(--line);
  }
}
@media (max-width: 960px) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .sidebar {
    position: fixed;
    z-index: 40;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: min(300px, 86vw);
    transform: translateX(-102%);
    transition: transform 200ms var(--ease);
    box-shadow: var(--shadow-pop);
    visibility: hidden;
  }
  .sidebar.open {
    transform: none;
    visibility: visible;
  }
  .scrim {
    position: fixed;
    inset: 0;
    z-index: 35;
    background: var(--overlay);
  }
  .sidebar.open + .scrim {
    display: block;
  }
  .mobile-menu {
    display: grid;
  }
}
@media (max-width: 760px) {
  .content {
    padding: var(--s5) var(--s4);
  }
  .topbar {
    padding-inline: var(--s3);
    gap: var(--s2);
  }
  .breadcrumb {
    display: none;
  }
  .global-search {
    inline-size: auto;
    flex: 1;
    min-inline-size: 0;
  }
  .global-search .keyboard,
  .separator {
    display: none;
  }
  .top-right {
    flex: 1;
    min-inline-size: 0;
  }
  .page-heading {
    align-items: flex-start;
  }
  .page-heading h1 {
    font-size: var(--t-lg);
  }
  .heading-actions {
    inline-size: 100%;
  }
  .heading-actions .btn {
    flex: 1;
  }
  .form-row,
  .settings-row {
    grid-template-columns: minmax(0, 1fr);
  }
  .settings-row {
    gap: var(--s1);
  }
  .login-page {
    grid-template-columns: minmax(0, 1fr);
  }
  .login-story {
    padding: var(--s6) var(--s5);
    border-inline-end: 0;
    border-block-end: 1px solid var(--line);
  }
  .login-art,
  .login-story footer {
    display: none;
  }
  .login-form-side {
    padding: var(--s6) var(--s5) var(--s10);
    place-items: start center;
  }
  .modal-overlay {
    padding: 0;
    place-items: end stretch;
  }
  .modal,
  .modal.wide {
    inline-size: 100%;
    max-block-size: 92dvh;
    border-end-start-radius: 0;
    border-end-end-radius: 0;
  }
  .modal-footer {
    border-radius: 0;
  }
  .modal-footer .btn {
    flex: 1;
  }
  .kv {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
  .kv > span:nth-child(even) {
    margin-block-end: var(--s2);
  }
  .panel-heading,
  .table-heading,
  td,
  th {
    padding-inline: var(--s4);
  }
  #toasts {
    inset-inline: var(--s3);
    inset-block-end: var(--s3);
    max-inline-size: none;
  }
}
@media (max-width: 480px) {
  .metrics {
    grid-template-columns: minmax(0, 1fr);
  }
  .metric + .metric {
    border-inline-start: 0;
    border-block-start: 1px solid var(--line);
  }
  .topbar [data-action="notifications"] {
    display: none;
  }
  .chart-sample {
    margin-inline-start: 0;
  }
}
/* In narrow panels, table rows become labelled stacks (labels come from
   the column headers via data-label). */
@container (max-width: 620px) {
  .table-wrap {
    overflow: visible;
  }
  .table-wrap table,
  .table-wrap tbody,
  .table-wrap tr,
  .table-wrap td {
    display: block;
  }
  .table-wrap thead {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .table-wrap tr {
    padding-block: var(--s3);
    border-block-end: 1px solid var(--line);
  }
  .table-wrap tbody tr:last-child {
    border-block-end: 0;
  }
  .table-wrap td {
    position: relative;
    padding: 3px var(--s4) 3px calc(var(--s4) + min(34%, 120px) + var(--s3));
    border: 0;
    min-block-size: 26px;
  }
  .table-wrap td::before {
    content: attr(data-label);
    position: absolute;
    inset-inline-start: var(--s4);
    inset-block-start: 5px;
    inline-size: min(34%, 120px);
    font-family: var(--font);
    font-size: var(--t-xs);
    font-weight: 600;
    color: var(--ink-3);
    white-space: normal;
  }
  .table-wrap td:not([data-label]),
  .table-wrap td[data-label=""] {
    padding-inline-start: var(--s4);
  }
  .table-wrap td:not([data-label])::before,
  .table-wrap td[data-label=""]::before {
    content: none;
  }
  .table-wrap td:empty {
    display: none;
  }
  .table-wrap .row-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
  }
  .device-cell {
    min-inline-size: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
@media (forced-colors: active) {
  .badge,
  .btn,
  .panel,
  .step {
    border: 1px solid CanvasText;
  }
}

/* ---------- Connection and stale data ---------- */
/* Shown only while /v1/state is failing. */
.conn-lost {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: 3px var(--s3);
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn);
  font-size: var(--t-xs);
  font-weight: 600;
  white-space: nowrap;
}
.conn-lost[hidden] {
  display: none;
}
.conn-lost .icon {
  inline-size: 14px;
  block-size: 14px;
}
/* What an offline router last reported: badges lose their colour so none of
   them reads as a current state. */
.stale-data .badge {
  filter: grayscale(1);
  opacity: 0.75;
}

/* ---------- Overview: needs attention ---------- */
a.attention-item {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
a.attention-item:hover {
  background: var(--sunken);
}

/* ---------- Organizations tree ---------- */
.org-cell {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.org-cell.child {
  padding-inline-start: var(--s6);
}
.org-cell strong,
.org-cell small {
  display: block;
}
.org-cell small {
  color: var(--ink-2);
}

/* ---------- Forms ---------- */
/* An input with a button beside it, such as Generate for a password. */
.field-with-action {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--s2);
}
.field-with-action > .btn {
  margin-block-start: 1.75rem;
}
.account-form {
  display: grid;
  max-inline-size: 420px;
}
.account-form > .btn {
  justify-self: start;
}

/* ---------- Extra-large dialog (router scripts) ---------- */
.modal.xl {
  inline-size: min(1180px, 100%);
  max-block-size: 94dvh;
}
/* Scripts keep one RouterOS command per line and scroll sideways instead. */
.code.script {
  white-space: pre;
  overflow-wrap: normal;
  max-block-size: 56dvh;
}

/* ---------- Router page ---------- */
.page-heading .detail-header {
  margin: 0;
}
.page-heading .detail-header small {
  color: var(--ink-2);
}
.router-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  gap: var(--s6);
}
@media (max-width: 1100px) {
  .router-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* Actions in a settings row sit on the right; the copy wraps. */
.danger-zone .settings-row {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
}


/* Numbered instructions in a dialog. */
.steps-list {
  display: grid;
  gap: var(--s2);
  margin: var(--s3) 0;
  padding-inline-start: var(--s5);
}

/* Capture analyzer: packet list, protocol tree and bytes. */
.filter-field.grow {
  flex: 1 1 18rem;
}
.filter-field.grow input {
  inline-size: 100%;
}
.packet-list {
  max-block-size: 26rem;
  overflow: auto;
}
.packet-list td {
  padding-block: 2px;
  font-size: var(--t-sm);
  white-space: nowrap;
}
.packet-row {
  cursor: pointer;
}
.selected-row td {
  background: var(--info-bg);
}
.packet-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s3) var(--s4);
}
@media (max-width: 900px) {
  .packet-detail {
    grid-template-columns: minmax(0, 1fr);
  }
}
.proto-tree {
  font-family: var(--mono);
  font-size: var(--t-sm);
  overflow: auto;
  max-block-size: 28rem;
}
.proto-tree details > :not(summary) {
  margin-inline-start: var(--s4);
}
.proto-label {
  cursor: pointer;
}
.proto-label:hover {
  color: var(--link);
}
.hex-dump {
  margin: 0;
  max-block-size: 28rem;
  overflow: auto;
  font-size: var(--t-sm);
}
.hex-dump .hl {
  background: var(--warn-bg);
  color: var(--warn);
}
.hex-off {
  color: var(--ink-3);
}

/* ---------- Telemetry tabs: plain uPlot charts above their tables ---------- */
.chart-wrap {
  padding: var(--s2) var(--s5) var(--s4);
  border-block-start: 1px solid var(--line);
}
.chart-title {
  margin-block: var(--s2) var(--s1);
  color: var(--ink-2);
  font-size: var(--t-xs);
  font-weight: 600;
}
.chart {
  min-block-size: 160px;
  inline-size: 100%;
  overflow: hidden;
}
.chart .uplot {
  font-family: var(--font);
  color: var(--ink-2);
}
.chart .u-legend {
  font-size: var(--t-xs);
  text-align: start;
}
.chart .u-legend .u-marker {
  inline-size: 10px;
  block-size: 3px;
}
.chart .u-legend th {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-2);
  font-weight: 600;
}
.chart .u-legend td {
  padding: 0 var(--s1);
  border: 0;
  font-family: var(--mono);
}
.chart .u-legend tr,
.chart .u-legend tbody tr:hover {
  border: 0;
  background: none;
}
.modal .chart-wrap {
  padding-inline: 0;
  border: 0;
}
.click-row {
  cursor: pointer;
}
.switch-cell input {
  inline-size: 16px;
  block-size: 16px;
  accent-color: var(--primary);
}
.sampling {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--mono);
}
.sampling input {
  inline-size: 6rem;
  block-size: 30px;
  padding: 0 var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}
.leg-row {
  padding-block: var(--s2);
  border-block-end: 1px solid var(--line);
}
.leg-row .check-label {
  margin-block-end: var(--s1);
}
.dense td {
  font-size: var(--t-sm);
  overflow-wrap: anywhere;
}
/* Wide flow and call tables: tighter cells, until they become stacks. */
@container (min-width: 621px) {
  .dense td {
    padding-block: var(--s2);
  }
  .dense td,
  .dense th {
    padding-inline: var(--s3);
  }
}
.dense .sni {
  display: inline-block;
  max-inline-size: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.nowrap {
  white-space: nowrap;
}
.form-row.top {
  align-items: start;
}
.check-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s5);
}
.check-list {
  display: grid;
  gap: var(--s2);
  max-height: 50vh;
  overflow: auto;
  margin-block-end: var(--s3);
}
.check-list .check-row {
  flex-wrap: nowrap;
  gap: var(--s2);
  align-items: start;
}
.terminal-frame {
  padding: 0 var(--s3) var(--s3);
}
.terminal-frame iframe {
  display: block;
  width: 100%;
  height: min(70vh, 720px);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #101311;
}
