/* Themes. theme.js sets data-theme on <html> before the page is drawn:
   light | dark | ocean | forest ("System" resolves to light or dark). Every
   colour in the application comes from these variables. */
:root, :root[data-theme="light"] {
  --bg: #f3f5f8;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --border: #dde3ea;
  --text: #1c2430;
  --muted: #5d6b7c;
  --primary: #2563c9;
  --primary-hover: #1d4fa3;
  --primary-text: #ffffff;
  --side-bg: #16202c;
  --side-text: #c6d0dc;
  --side-active: #243244;
  --ok: #17803d;      --ok-bg: #e5f5ea;
  --warn: #9a6200;    --warn-bg: #fdf3dd;
  --bad: #c0262d;     --bad-bg: #fbe6e7;
  --info: #3b5b85;    --info-bg: #e8eef7;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
  --radius: 8px;
  --series: #2a64c8;
  --series-2: #c2610f;
  --meter-track: #e6eaf0;
  --mark: #ffe58f;
  --term-bg: #101820;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #0f151c; --surface: #17202a; --surface-2: #1c2632; --border: #2b3847;
  --text: #e3e9f0; --muted: #93a1b2; --primary: #4b8cf0; --primary-hover: #6aa0f3; --primary-text: #ffffff;
  --side-bg: #0b1016; --side-text: #aebccc; --side-active: #1c2733;
  --ok: #4cc47a; --ok-bg: #173323; --warn: #e2b04b; --warn-bg: #33291a;
  --bad: #f0686e; --bad-bg: #3a1c1f; --info: #8fb2e3; --info-bg: #1b283a;
  --series: #5b95f0; --series-2: #f0a050; --meter-track: #26313e; --mark: #6b5500; --term-bg: #0b1016;
  color-scheme: dark;
}
/* Ocean: deep navy with a teal accent. */
:root[data-theme="ocean"] {
  --bg: #0a1622; --surface: #10212f; --surface-2: #152b3d; --border: #23425b;
  --text: #dcebf7; --muted: #8eafc7; --primary: #2bb3c8; --primary-hover: #55cadb; --primary-text: #04222a;
  --side-bg: #060f18; --side-text: #9fc0d6; --side-active: #12304a;
  --ok: #4fd1a1; --ok-bg: #0f362c; --warn: #f0c05a; --warn-bg: #3a2e14;
  --bad: #ff8080; --bad-bg: #421a1f; --info: #7fc4f0; --info-bg: #12324c;
  --series: #36c2d8; --series-2: #f0c05a; --meter-track: #1c3449; --mark: #7a5c00; --term-bg: #060f18;
  color-scheme: dark;
}
/* Forest: light sage with a green accent. */
:root[data-theme="forest"] {
  --bg: #f0f4ec; --surface: #ffffff; --surface-2: #f5f8f1; --border: #d5dfce;
  --text: #1e2a22; --muted: #5a6b5e; --primary: #2f7d4f; --primary-hover: #24643e; --primary-text: #ffffff;
  --side-bg: #1a2b21; --side-text: #c3d5c8; --side-active: #2a4434;
  --ok: #1f7a3e; --ok-bg: #e2f3e6; --warn: #8a5e00; --warn-bg: #fbf1d6;
  --bad: #b3312b; --bad-bg: #f9e4e2; --info: #2c6a6a; --info-bg: #e1f0ee;
  --series: #2f7d4f; --series-2: #b0621c; --meter-track: #e2e9dc; --mark: #f4e08a; --term-bg: #16241c;
  color-scheme: light;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); color: var(--text); font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
h1 { font-size: 22px; margin: 0; }
h2 { font-size: 16px; margin: 0 0 12px; }
h3 { font-size: 14px; margin: 0 0 8px; }
a { color: var(--primary); }
code, .mono { font-family: var(--mono); font-size: 12.5px; }
.boot { padding: 40px; color: var(--muted); }
.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.hidden { display: none !important; }

/* Layout */
.shell { display: grid; grid-template-columns: 220px 1fr; min-height: 100vh; }
.sidebar { background: var(--side-bg); color: var(--side-text); display: flex; flex-direction: column; padding: 16px 10px; }
.brand { font-weight: 700; color: #fff; padding: 4px 10px 18px; font-size: 15px; letter-spacing: .2px; }
.brand span { display: block; font-weight: 400; font-size: 11.5px; color: var(--side-text); opacity: .8; }
.nav a { display: block; padding: 8px 12px; border-radius: 6px; color: var(--side-text); text-decoration: none; margin-bottom: 2px; }
.nav a:hover { background: var(--side-active); color: #fff; }
.nav a.active { background: var(--side-active); color: #fff; box-shadow: inset 3px 0 0 var(--primary); }
.side-foot { margin-top: auto; padding: 10px; font-size: 12px; }
.side-foot .user { color: #fff; font-weight: 600; }
.main { min-width: 0; }
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 28px; border-bottom: 1px solid var(--border); background: var(--surface); }
.content { padding: 24px 28px 48px; max-width: 1400px; }
.crumbs { font-size: 12.5px; color: var(--muted); margin-bottom: 2px; }
.crumbs a { color: var(--muted); }

/* Cards & grids */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; }
.grid { display: grid; gap: 16px; }
/* A grid item is min-width:auto by default, so one child that cannot be made
   narrower — a table holding a full SSH fingerprint, a long command — widens
   its whole column and pushes the page sideways on a phone. Letting items
   shrink puts the overflow back where it belongs: inside .table-wrap and the
   other scrollers. At desktop widths there is room to spare and this changes
   nothing. */
.grid > * { min-width: 0; }
.grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.grid.cards { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin-bottom: 20px; }
.stat .num { font-size: 26px; font-weight: 700; }
.stat .lbl { color: var(--muted); font-size: 12.5px; }
.server-card { cursor: pointer; transition: border-color .15s; text-align: left; font: inherit; color: inherit; width: 100%; text-decoration: none; }
.server-card:hover, .server-card:focus-visible { border-color: var(--primary); outline: none; }
.server-card .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.server-card .name { font-weight: 700; font-size: 15px; word-break: break-all; }
dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0; }
dl.kv dt { color: var(--muted); }
dl.kv dd { margin: 0; word-break: break-word; }
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }

/* Badges */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap; border: 1px solid transparent; }
.badge.ok { color: var(--ok); background: var(--ok-bg); }
.badge.warn { color: var(--warn); background: var(--warn-bg); }
.badge.bad { color: var(--bad); background: var(--bad-bg); }
.badge.info { color: var(--info); background: var(--info-bg); }
.badge.neutral { color: var(--muted); background: var(--surface-2); border-color: var(--border); }

/* Tables */
.table-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
th { font-size: 12px; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); background: var(--surface-2); font-weight: 600; }
tr:last-child td { border-bottom: none; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--surface-2); }
/* The real link in a clickable row: it carries the address (so it can be
   opened in a new tab) but reads as part of the row, not as a blue link. */
.row-link { color: inherit; text-decoration: none; }
.row-link:hover { text-decoration: underline; }
td.actions { text-align: right; white-space: nowrap; }
.empty { padding: 36px; text-align: center; color: var(--muted); }

/* Forms & buttons */
.btn { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); background: var(--surface); color: var(--text); padding: 7px 14px; border-radius: 6px; font: inherit; font-weight: 500; cursor: pointer; }
.btn:hover { background: var(--surface-2); }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
.btn.primary:hover { background: var(--primary-hover); }
.btn.danger { color: var(--bad); border-color: var(--bad); }
.btn.danger:hover { background: var(--bad-bg); }
.btn.small { padding: 4px 10px; font-size: 12.5px; }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.form { display: grid; gap: 14px; }
.form .row2 { display: grid; grid-template-columns: 1fr 140px; gap: 12px; }
label.field { display: grid; gap: 5px; font-weight: 500; }
label.field .hint { font-weight: 400; color: var(--muted); font-size: 12.5px; }
input[type=text], input[type=password], input[type=number], select, textarea {
  font: inherit; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px; width: 100%;
}
textarea { font-family: var(--mono); font-size: 12px; min-height: 140px; resize: vertical; }
input:focus, select:focus, textarea:focus, .btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.check { display: flex; gap: 8px; align-items: flex-start; font-weight: 500; }
.check input { margin-top: 3px; }
.error-box { border: 1px solid var(--bad); background: var(--bad-bg); color: var(--text); padding: 12px 14px; border-radius: 6px; }
.error-box strong { color: var(--bad); }
.note { border: 1px solid var(--border); background: var(--surface-2); padding: 12px 14px; border-radius: 6px; }
.note.warn { border-color: var(--warn); background: var(--warn-bg); }
.fingerprint { font-family: var(--mono); font-size: 14px; padding: 10px 12px; background: var(--surface-2); border: 1px dashed var(--border); border-radius: 6px; word-break: break-all; user-select: all; }
pre.output { font-family: var(--mono); font-size: 12px; background: var(--side-bg); color: #d6e1ec; padding: 12px; border-radius: 6px; overflow: auto; max-height: 360px; white-space: pre-wrap; word-break: break-word; margin: 0; }

/* Login */
.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.login { width: 100%; max-width: 380px; }
/* Setting a second factor up needs room for the key and the recovery codes. */
.wide-login { max-width: 560px; }
/* A six-digit code: wide, spaced characters so a mistype is obvious. */
.code-input { font-family: var(--mono); font-size: 20px; letter-spacing: 6px; text-align: center; }
/* The shared key, shown once for typing into an authenticator app. */
.secret-key { font-size: 17px; letter-spacing: 1px; word-spacing: 6px; padding: 12px 14px; background: var(--surface-2);
  border: 1px dashed var(--border); border-radius: 6px; user-select: all; word-break: break-all; margin: 6px 0 10px; }
.recovery-list { list-style: none; margin: 12px 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.recovery-list li { padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; text-align: center; user-select: all; }
.login h1 { margin-bottom: 4px; }
.login .sub { color: var(--muted); margin: 0 0 20px; }

/* Tabs */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
.tabs button { background: none; border: none; border-bottom: 2px solid transparent; padding: 8px 14px; font: inherit; color: var(--muted); cursor: pointer; }
.tabs button[aria-selected=true] { color: var(--text); border-bottom-color: var(--primary); font-weight: 600; }
.tabs button:disabled { opacity: .5; cursor: not-allowed; }
.tabs a { padding: 8px 14px; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; }
.tabs a:hover { color: var(--text); }
.tabs a[aria-selected=true] { color: var(--text); border-bottom-color: var(--primary); font-weight: 600; }
.toolbar input[type=search], .toolbar select { width: auto; min-width: 180px; padding: 5px 9px; }
input[type=search] { font: inherit; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px; }
.svc-name { font-weight: 600; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.badge.protected { font-size: 10.5px; padding: 0 6px; font-weight: 500; }
td.actions .btn { margin-left: 4px; }
dialog.wide { width: min(1080px, calc(100vw - 32px)); }
pre.output.tall { max-height: 60vh; min-height: 200px; }
.op-title { margin: 8px 0 12px; }
.tabs .soon { font-size: 10px; text-transform: uppercase; letter-spacing: .4px; margin-left: 5px; padding: 1px 5px; border-radius: 4px; background: var(--surface-2); border: 1px solid var(--border); }

/* Dialogs */
dialog { border: 1px solid var(--border); border-radius: 10px; padding: 0; width: min(620px, calc(100vw - 32px)); background: var(--surface); color: var(--text); }
dialog::backdrop { background: rgba(10, 16, 24, .55); }
.dlg-head { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.dlg-head h2 { margin: 0; }
.dlg-body { padding: 18px 20px; display: grid; gap: 14px; max-height: 70vh; overflow: auto; }
.dlg-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--border); }
.steps { display: flex; gap: 6px; font-size: 12px; color: var(--muted); }
.steps .on { color: var(--primary); font-weight: 700; }

/* Result panel: friendly status left, server output right */
.result { display: grid; grid-template-columns: minmax(200px, 1fr) 1.4fr; gap: 14px; }
@media (max-width: 720px) { .result { grid-template-columns: 1fr; } }

/* Meters (usage bars). Status colours are paired with a ▲ / ! text marker. */
.meter-row { display: grid; grid-template-columns: auto 1fr 64px; align-items: center; gap: 8px; }
.meter-row:not(:has(.meter-label)) { grid-template-columns: 1fr 64px; }
.meter-label { font-size: 12px; color: var(--muted); min-width: 34px; }
.meter { height: 8px; background: var(--meter-track); border-radius: 4px; overflow: hidden; }
.meter-fill { height: 100%; border-radius: 4px; background: var(--series); }
.meter-fill.warn { background: var(--warn); }
.meter-fill.bad { background: var(--bad); }
.meter-val { font-size: 12.5px; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.meter-val.warn { color: var(--warn); font-weight: 600; }
.meter-val.bad { color: var(--bad); font-weight: 600; }
.card-metrics { display: grid; gap: 6px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.stat .meter-row { margin: 6px 0 4px; grid-template-columns: 1fr auto; }
.grid > .stats { margin-bottom: 0; }
.section { margin-bottom: 16px; }
.usage-cell { min-width: 170px; }
td { font-variant-numeric: tabular-nums; }
.form .row2.wide { grid-template-columns: 1fr 180px; }

/* Range selector */
/* wrap: the segments run onto a second row on a narrow screen rather than
   pushing the page sideways; there is always room on a wide one. */
.seg { display: inline-flex; gap: 0; flex-wrap: wrap; }
.seg .btn { border-radius: 0; margin-left: -1px; }
.seg .btn:first-child { border-radius: 6px 0 0 6px; margin-left: 0; }
.seg .btn:last-child { border-radius: 0 6px 6px 0; }
.seg .btn.on { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }

/* Line charts: thin 2px series, recessive grid and axes */
.charts { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.chart-fig { margin: 0; min-width: 0; }
.chart-fig figcaption { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.chart-title { font-weight: 600; }
.chart { position: relative; width: 100%; height: 150px; }
.chart svg { display: block; }
.grid-line { stroke: var(--border); stroke-width: 1; }
.axis-text { fill: var(--muted); font-size: 11px; }
.series-line { fill: none; stroke: var(--series); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.series-point { fill: var(--series); }
/* Second series (network: sending) and the chart legend */
.series-line.series-2 { stroke: var(--series-2); }
.series-point.series-2 { fill: var(--series-2); }
.chart-legend { display: inline-flex; align-items: center; gap: 5px; margin-left: 8px; font-weight: 400; color: var(--muted); }
.chart-legend .key { display: inline-block; width: 10px; height: 3px; border-radius: 2px; background: var(--series); }
.chart-legend .key.key-tx { background: var(--series-2); margin-left: 6px; }
.chart-empty { display: flex; align-items: center; justify-content: center; text-align: center; border: 1px dashed var(--border); border-radius: 6px; padding: 12px; }
.series-dot { fill: var(--series); stroke: var(--surface); stroke-width: 2; }
.crosshair { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
.chart-tip { position: absolute; top: 0; pointer-events: none; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 6px 9px; box-shadow: 0 4px 12px rgba(0,0,0,.12); white-space: nowrap; }
.chart-tip .t { font-weight: 700; font-variant-numeric: tabular-nums; }

/* Log viewer */
.log-filters { margin-bottom: 10px; }
.log-filters input[type=text] { width: 190px; padding: 5px 9px; }
.log-filters input[type=search] { min-width: 220px; flex: 1; }
.log-view { font-family: var(--mono); font-size: 12px; border: 1px solid var(--border); border-radius: 6px; max-height: 65vh; overflow: auto; background: var(--surface); }
.log-row { display: grid; grid-template-columns: 150px 78px 150px 1fr; gap: 10px; padding: 4px 10px; border-bottom: 1px solid var(--border); border-left: 3px solid transparent; align-items: start; }
.log-row:last-child { border-bottom: none; }
.log-row.is-bad { border-left-color: var(--bad); }
.log-row.is-warn { border-left-color: var(--warn); }
.log-row .time { color: var(--muted); white-space: nowrap; }
.log-row .origin { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.log-row .msg { white-space: pre-wrap; word-break: break-word; }
.log-row .lvl.badge { font-size: 10.5px; padding: 0 6px; justify-self: start; }
.badge.dim { opacity: .7; }
mark { background: var(--mark); color: inherit; border-radius: 2px; padding: 0 1px; }
.inline-field { display: flex; align-items: center; gap: 8px; font-weight: 500; }
.inline-field select { width: auto; }
@media (max-width: 800px) { .log-row { grid-template-columns: 1fr; gap: 2px; } }

/* Data age & saved copies */
.page-status { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.page-status .checking { display: inline-flex; align-items: center; gap: 5px; }
.spinner.tiny { width: 10px; height: 10px; border-width: 1.5px; }

/* Firewall */
.fw-banner { display: grid; gap: 12px; border-left: 5px solid var(--border); }
.fw-banner.on { border-left-color: var(--ok); }
.fw-banner.off { border-left-color: var(--warn); }
.fw-banner-main { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.fw-state { display: flex; gap: 14px; align-items: flex-start; max-width: 820px; }
.fw-dot { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; font-size: 18px; font-weight: 700;
  color: var(--muted); background: var(--surface-2); border: 2px solid var(--border); }
.fw-banner.on .fw-dot { color: var(--ok); background: var(--ok-bg); border-color: var(--ok); }
.fw-banner.off .fw-dot { color: var(--warn); background: var(--warn-bg); border-color: var(--warn); }
.fw-title { font-size: 18px; font-weight: 700; margin-bottom: 2px; }
.fw-banner.on .fw-title { color: var(--ok); }
.fw-banner.off .fw-title { color: var(--warn); }
.fw-banner-meta { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding-top: 10px; border-top: 1px solid var(--border); }
.fw-quick .btn { background: var(--surface-2); }
.fw-form { display: grid; grid-template-columns: auto 150px minmax(170px, 1fr) minmax(260px, 1.4fr); gap: 14px; align-items: start; margin-bottom: 12px; }
.fw-form .field { display: grid; gap: 6px; font-weight: 500; align-content: start; }
.fw-form .field input[type=text] { margin-top: 2px; }
.fw-preview { display: grid; gap: 8px; padding: 12px 14px; margin-bottom: 12px; background: var(--surface-2); border: 1px dashed var(--border); border-radius: 6px; }
.fw-prev-item { display: grid; gap: 6px; }
.fw-prev-rule { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-weight: 600; }
.fw-check { display: grid; gap: 8px; }
.fw-rules td.pos { color: var(--muted); width: 36px; }
.fw-row.fw-shadowed td, .fw-row.fw-saved td { color: var(--muted); }
.fw-row.fw-parked td { background: var(--surface-2); color: var(--muted); }
.fw-row.fw-parked .mono { text-decoration: line-through; text-decoration-color: var(--muted); }
.fw-default td { background: var(--surface-2); font-style: italic; }
.fw-rules .btn.small { padding: 3px 9px; }
@media (max-width: 1000px) { .fw-form { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .fw-form { grid-template-columns: 1fr; } }

/* Capabilities */
.cap-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 4px 20px; }
.cap-list li { display: grid; grid-template-columns: 124px 1fr; gap: 10px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--border); }
.cap-list .badge { justify-self: start; }
.cap-label { font-weight: 500; }
.cap-hint { margin-top: 4px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.cap-hint code { background: var(--surface-2); border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px; }
.caps .note { margin-top: 12px; }

/* Settings rows */
.set-grid { display: grid; grid-template-columns: minmax(200px, 1fr) minmax(220px, 420px); gap: 14px 24px; align-items: center; margin: 6px 0 16px; }
.set-label > div:first-child { font-weight: 500; }
@media (max-width: 700px) { .set-grid { grid-template-columns: 1fr; gap: 6px; } }

/* Updates */
.stat .num.small-num { font-size: 18px; padding-top: 6px; }
.stat .num.warn-num { color: var(--warn); }
.pkg-list { max-height: 40vh; overflow: auto; }

/* Power stepper */
.power-card { border-color: var(--warn); margin-bottom: 16px; }
.stepper { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; margin: 4px 0 10px; }
.stepper li { display: grid; grid-template-columns: auto auto; column-gap: 8px; align-items: center; padding: 8px 14px; border: 1px solid var(--border); border-radius: 8px; min-width: 150px; color: var(--muted); }
.stepper li .dot { grid-row: span 2; font-weight: 700; }
.stepper li .lbl { font-weight: 600; }
.stepper li.done { color: var(--ok); border-color: var(--ok); background: var(--ok-bg); }
.stepper li.current { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }
.stepper li.failed { color: var(--bad); border-color: var(--bad); background: var(--bad-bg); }
.stepper li .small { color: var(--muted); }

/* Toasts */
.toasts { position: fixed; right: 18px; bottom: 18px; display: grid; gap: 8px; z-index: 50; max-width: min(420px, calc(100vw - 36px)); }
.toast { background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--info); border-radius: 6px; padding: 10px 14px; box-shadow: 0 6px 18px rgba(0,0,0,.15); }
.toast.ok { border-left-color: var(--ok); }
.toast.bad { border-left-color: var(--bad); }
.toast .t { font-weight: 600; }

.spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; display: inline-block; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* The sidebar stays in place while the page scrolls, so the menu, the open
   terminal indicator and Log out are always reachable. If the menu is ever
   taller than the window it scrolls on its own. */
@media (min-width: 801px) {
  .sidebar { position: sticky; top: 0; align-self: start; height: 100vh; height: 100dvh; overflow-y: auto; }
}

@media (max-width: 800px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { flex-direction: row; align-items: center; padding: 8px 12px; overflow-x: auto; }
  .brand { padding: 0 12px 0 0; white-space: nowrap; }
  .brand span, .side-foot { display: none; }
  .nav { display: flex; }
  .topbar, .content { padding-left: 16px; padding-right: 16px; }
  .form .row2 { grid-template-columns: 1fr; }
}

/* Appearance (theme picker). The previews use fixed colours on purpose. */
.themes { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.theme-card { display: grid; gap: 8px; padding: 10px; border: 2px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); font: inherit; cursor: pointer; text-align: left; }
.theme-card:hover { border-color: var(--muted); }
.theme-card[aria-pressed=true] { border-color: var(--primary); }
.theme-card .nm { font-weight: 600; }
.theme-swatch { height: 58px; border-radius: 6px; display: grid; grid-template-columns: 28% 1fr; overflow: hidden; border: 1px solid var(--border); }
.theme-swatch b { display: grid; align-content: center; gap: 6px; padding: 8px 10px; }
.theme-swatch b span { height: 7px; border-radius: 4px; display: block; }
.theme-swatch b span:first-child { width: 55%; }
.sw-light i { background: #16202c; } .sw-light b { background: #f3f5f8; } .sw-light b span:first-child { background: #2563c9; } .sw-light b span:last-child { background: #c9d2dd; }
.sw-dark i { background: #0b1016; } .sw-dark b { background: #17202a; } .sw-dark b span:first-child { background: #4b8cf0; } .sw-dark b span:last-child { background: #2b3847; }
.sw-ocean i { background: #060f18; } .sw-ocean b { background: #10212f; } .sw-ocean b span:first-child { background: #2bb3c8; } .sw-ocean b span:last-child { background: #23425b; }
.sw-forest i { background: #1a2b21; } .sw-forest b { background: #f0f4ec; } .sw-forest b span:first-child { background: #2f7d4f; } .sw-forest b span:last-child { background: #c9d6c1; }
.sw-system i { background: linear-gradient(180deg, #16202c 50%, #0b1016 50%); } .sw-system b { background: linear-gradient(135deg, #f3f5f8 50%, #17202a 50%); }
.sw-system b span:first-child { background: #2563c9; } .sw-system b span:last-child { background: #8794a3; }

/* Files */
.files-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.files-bar input[type=text] { flex: 1; min-width: 240px; font-family: var(--mono); font-size: 13px; padding: 6px 10px; }
.path-crumbs { display: flex; flex-wrap: wrap; align-items: center; font-family: var(--mono); font-size: 13px; margin-bottom: 12px; color: var(--muted); }
.path-crumbs button, .file-link { background: none; border: none; color: var(--primary); cursor: pointer; padding: 2px 5px; border-radius: 4px; font: inherit; text-align: left; }
.path-crumbs button:hover, .file-link:hover { background: var(--surface-2); text-decoration: underline; }
.file-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
.file-icon { flex: none; width: 22px; text-align: center; }
.file-link.dir { font-weight: 600; }
.file-plain { padding: 2px 5px; }
.files-table td.num { text-align: right; white-space: nowrap; }
.upload-box { border: 1px solid var(--border); background: var(--surface-2); border-radius: 6px; padding: 12px 14px; display: grid; gap: 8px; margin-bottom: 12px; }
.upload-box.ok { border-color: var(--ok); background: var(--ok-bg); }
.upload-box.bad { border-color: var(--bad); background: var(--bad-bg); }
.upload-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
progress { width: 100%; height: 10px; accent-color: var(--primary); }
.files-drop.drop-on { outline: 2px dashed var(--primary); outline-offset: -6px; }
pre.output.preview { max-height: 65vh; white-space: pre; word-break: normal; }

/* Terminal */
.term-card { padding: 0; overflow: hidden; }
.term-bar { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.term-bar .who { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.term-wrap { background: var(--term-bg); padding: 10px 4px 6px 12px; height: calc(100vh - 300px); min-height: 320px; }
.term-wrap .xterm { height: 100%; }
.term-hint { color: #9fb0c0; font-family: var(--mono); font-size: 13px; padding: 8px 4px; white-space: pre-wrap; }
.term-foot { padding: 8px 14px; border-top: 1px solid var(--border); }

/* Open-terminal indicator in the sidebar, and the kept terminal screen */
.term-ind { display: flex; align-items: center; gap: 9px; margin: 14px 4px 0; padding: 8px 10px; border-radius: 6px; border: 1px solid var(--side-active); background: var(--side-active); color: #fff; text-decoration: none; font-size: 12.5px; }
.term-ind:hover { border-color: var(--primary); }
.term-ind .dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: #3fd07f; box-shadow: 0 0 0 3px rgba(63, 208, 127, .25); }
.term-ind .lbl { display: block; font-weight: 600; }
.term-ind .srv { display: block; color: var(--side-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 150px; }
.term-screen { height: 100%; }
.files-table td.actions .btn { margin-left: 4px; }
@media (max-width: 800px) { .term-ind { margin: 0 0 0 8px; } .term-ind .srv { display: none; } }

/* Server page header: hostname beside the friendly name, status beside the actions */
.topbar h1 .host-sub { margin-left: 12px; font-size: 14px; font-weight: 400; color: var(--muted); padding: 2px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2); vertical-align: middle; }
.topbar .btn-row { align-items: center; }
/* Which clock this page is written in; only shown when it is not the device's
   own zone. A link, because the place to change it is one click away. */
.tz-note { display: inline-block; margin-top: 3px; font-size: 12.5px; color: var(--muted); text-decoration: none; border-bottom: 1px dotted var(--border); }
.tz-note:hover, .tz-note:focus-visible { color: var(--text); border-bottom-color: var(--muted); }
.top-status { display: inline-flex; margin-right: 6px; }
.top-status .badge { font-size: 12.5px; padding: 4px 11px; }

/* Needs attention: a coloured edge says how urgent the worst item is */
.attn-area:empty { display: none; }
.attn-area { margin-bottom: 16px; }
.attn-card { border-left: 5px solid var(--border); margin-bottom: 20px; }
.attn-area .attn-card { margin-bottom: 0; }
.attn-card.has-critical { border-left-color: var(--bad); }
.attn-card.has-warning { border-left-color: var(--warn); }
.attn-card.has-info { border-left-color: var(--info); }
.attn-card.all-clear { border-left-color: var(--ok); }
.attn-card .section-head { align-items: baseline; }
.attn-card .section-head h2 { margin-bottom: 0; }
.attn-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.attn-item { display: grid; grid-template-columns: 96px minmax(90px, 190px) 1fr; gap: 12px; align-items: baseline; padding: 7px 8px; border-radius: 6px; color: inherit; text-decoration: none; }
.attn-item.solo { grid-template-columns: 96px 1fr; }
.attn-item .badge { justify-self: start; }
a.attn-item:hover, a.attn-item:focus-visible { background: var(--surface-2); outline: none; }
.attn-server { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attn-clear { margin: 0; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
@media (max-width: 800px) { .attn-item, .attn-item.solo { grid-template-columns: 1fr; gap: 2px; } }

/* Tags and labels */
.tags { display: inline-flex; gap: 4px; flex-wrap: wrap; vertical-align: middle; }
.tag { display: inline-block; padding: 0 7px; border-radius: 4px; font-size: 11.5px; font-weight: 500; line-height: 18px; color: var(--info); background: var(--info-bg); white-space: nowrap; }
.server-card > .tags { margin: -4px 0 10px; }
/* Cards of different height (with or without tags) keep their content at the top. */
.server-card { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; }
.labels { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.labels .section-head { margin-bottom: 8px; }
.labels h3 { margin: 0; }
dd.notes { white-space: pre-wrap; }
textarea.notes-input { font-family: inherit; font-size: inherit; min-height: 90px; width: 100%; box-sizing: border-box; }
.note-form { margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }
.note-form .btn-row { align-items: center; }
.note-entry { padding: 12px 0; border-bottom: 1px solid var(--border); }
.note-entry:last-child { border-bottom: none; }
.note-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.note-head .btn { margin-left: auto; }
.note-text { white-space: pre-wrap; word-break: break-word; }
.list-filter { align-items: center; margin-bottom: 12px; }
.list-filter input[type=search] { min-width: 280px; }

/* Page width (Settings → Appearance). Standard keeps lines short enough to
   read comfortably; Wide and Full give tables more room on large screens. */
/* Automatic (the default): pages made of cards (.content.fluid: Dashboard,
   server Overview) use the whole window and show more cards per row; pages
   that are mostly tables stop at 1900px, where rows are still easy to follow. */
:root[data-width="auto"] .content, :root[data-width="wide"] .content { max-width: 1900px; }
:root[data-width="auto"] .content.fluid, :root[data-width="full"] .content { max-width: none; }
:root[data-width="auto"] .proc-cmd, :root[data-width="auto"] .proc-cmd div, :root[data-width="auto"] td.cmd-cell,
:root[data-width="wide"] .proc-cmd, :root[data-width="wide"] .proc-cmd div, :root[data-width="wide"] td.cmd-cell { max-width: 900px; }
:root[data-width="full"] .proc-cmd, :root[data-width="full"] .proc-cmd div, :root[data-width="full"] td.cmd-cell { max-width: 1300px; }

/* Server overview: one 12-column grid for all cards. The number of cards in
   a row follows the width of the page itself (a container query), so cards
   keep a comfortable size instead of stretching:
     under 760px   one card per row
     760px and up   2 small cards per row, tables full width   (as before)
     1500px and up  3 small cards per row, Storage and Network side by side
     2400px and up  4 small cards per row; CPU, Memory, Storage and Network share one row */
.contents { display: contents; }
.ov-wrap { container-type: inline-size; }
.ov-flow { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 16px; }
.ov-s, .ov-t { grid-column: span 12; min-width: 0; }
@container (min-width: 760px) { .ov-s { grid-column: span 6; } }
@container (min-width: 1500px) { .ov-s { grid-column: span 4; } .ov-t { grid-column: span 6; } }
@container (min-width: 2400px) { .ov-s { grid-column: span 3; } .ov-s.ov-metric { grid-column: span 2; } .ov-t { grid-column: span 4; } }
/* Browsers without container queries: two per row on anything but a phone. */
@supports not (container-type: inline-size) {
  @media (min-width: 1000px) { .ov-s { grid-column: span 6; } }
}
.sub-head { margin: 20px 0 4px; }
.width-swatch { height: 34px; border-radius: 6px; border: 1px solid var(--border); background: var(--surface-2); display: flex; padding: 6px; }
.width-swatch i { display: block; height: 100%; border-radius: 3px; background: var(--primary); opacity: .75; }
.width-swatch.w-auto i { width: 100%; background: linear-gradient(90deg, var(--primary) 0 62%, transparent 62% 66%, var(--primary) 66% 100%); }
.width-swatch.w-standard i { width: 55%; }
.width-swatch.w-wide i { width: 78%; }
.width-swatch.w-full i { width: 100%; }

/* Files: a measured folder size with its age and a small "measure again" button */
.btn.icon { padding: 1px 6px; margin-left: 6px; line-height: 1.2; }
.files-table td.dir-size { line-height: 1.35; }

/* Users: groups as clickable chips */
.tag-btn { border: 1px solid transparent; cursor: pointer; font: inherit; font-size: 11.5px; }
.tag-btn:hover, .tag-btn:focus-visible { border-color: var(--info); outline: none; }
.tag.tag-admin { color: var(--warn); background: var(--warn-bg); }
.tag.tag-own { color: var(--muted); background: var(--surface-2); }
.tag.on { border-color: var(--primary); }
.groups-bar { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin-bottom: 12px; }
.groups-bar strong { margin-right: 4px; }
.groups-table { margin-bottom: 14px; max-height: 420px; overflow-y: auto; }
td.groups-cell { min-width: 180px; max-width: 360px; }

/* Where a service or package comes from */
.badge.src-system { color: var(--muted); background: var(--surface-2); border-color: var(--border); }
.badge.src-installed { color: var(--info); background: var(--info-bg); }
.badge.src-thirdparty { color: var(--primary); background: var(--surface); border-color: var(--primary); }
.badge.src-custom { color: var(--text); background: var(--surface); border: 1px dashed var(--muted); }
.badge.src-snap { color: var(--ok); background: var(--ok-bg); }
td.svc-source { min-width: 150px; }
td.svc-source .small { margin-top: 3px; white-space: normal; }
.sw-table .upd { color: var(--warn); font-weight: 600; margin-top: 2px; }

/* A command to copy, inside step-by-step instructions */
.steps-list { margin: 0; padding-left: 22px; display: grid; gap: 10px; }
.cmd-line { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.cmd-line code { flex: 1; background: var(--surface-2); border: 1px solid var(--border); border-radius: 4px; padding: 6px 10px; font-size: 13px; user-select: all; }

/* Filter bars (History, Processes) */
.hist-filters, .filter-bar { display: flex; flex-wrap: wrap; gap: 12px 14px; align-items: flex-end; }
.hist-filters { padding: 14px 18px; margin-bottom: 10px; }
.filter-bar { margin-bottom: 12px; padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; }
.hist-filters label.field, .filter-bar label.field { font-size: 12.5px; color: var(--muted); }
.hist-filters select, .hist-filters input, .filter-bar select, .filter-bar input { width: auto; min-width: 150px; padding: 6px 9px; font-size: 14px; }
.filter-bar select { min-width: 120px; max-width: 220px; }
.hist-filters .grow, .filter-bar .grow { flex: 1 1 240px; }
.hist-filters .grow input, .filter-bar .grow input { width: 100%; }
.proc-summary { margin: 0 2px 10px; }
/* Sortable column headings */
.th-sort { background: none; border: none; padding: 0; font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer; white-space: nowrap; }
.th-sort:hover, .th-sort.on { color: var(--text); }
.th-sort:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 3px; }
th.num-cell { text-align: right; }
.hist-summary { margin: 0 2px 10px; min-height: 18px; }
input[type=datetime-local] { font: inherit; color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 6px; }

/* System tab, fleet updates */
a.btn { text-decoration: none; }
.tabs { flex-wrap: wrap; }
.num-cell { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.proc-table th, .fleet-table th { white-space: nowrap; }
.num-cell.warm { color: var(--warn); font-weight: 600; }
.num-cell.hot { color: var(--bad); font-weight: 700; }
.row-marker td { background: var(--surface-2); }
.ip-filter { min-width: 17em; }
.ip-note { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 8px 0; }
.ip-note > div.small { order: 2; flex: 1 1 100%; }
.ip-note > .btn { order: 1; margin-left: auto; }
.ip-note.warn { border-color: var(--warn); background: var(--warn-bg); }
.proc-table th:nth-child(3), .proc-table th:nth-child(4) { text-align: right; }
.proc-cmd { max-width: 520px; }
.proc-cmd strong { margin-right: 6px; }
.proc-cmd div, td.cmd-cell { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 520px; }
.srv-link { font-weight: 600; text-decoration: none; }
.srv-link:hover { text-decoration: underline; }
.fleet-table .detail-row td { background: var(--surface-2); padding: 10px 14px 14px; }
.pkg-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 4px 24px; }
.pkg-list li { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
