/* ============================================================
   Ineapple Canopy — console reskin (Canopy Fleet Map Redesign,
   2026-09-01). jina.ai dashboard language: near-black canvas, one
   console frame, top icon tabs with a sliding cyan underline,
   sharp-cornered 1px-bordered boxes, mono accents. Theming: CSS
   variables per [data-theme]; the inline head script sets the
   attribute pre-paint. Status colors are never alone — text labels
   always accompany dots and gauges.
   ============================================================ */

:root[data-theme="dark"] {
  --bg: #0b0b0c;            /* page behind the frame */
  --panel: #161719;         /* console surface (frame) */
  --bg-raise: #1d1e21;      /* raised rows/bars (frame-2) */
  --card: #141517;          /* inner boxed cards */
  --card-2: #1d1e21;
  --line: #313338;          /* 1px structural borders */
  --line-soft: #232427;
  --line-strong: #4a4d54;
  --text: #e8eaea;
  --muted: #9aa2a6;
  --faint: #5d6468;
  --accent: #f0941f;        /* Canopy CTA orange */
  --accent-hi: #ffb457;
  --accent-soft: rgba(240, 148, 31, .13);
  --accent-ink: #221100;
  --cyan: #7fd8e8;          /* jina-style active accent */
  --cyan-dim: rgba(127, 216, 232, .12);
  --gold: #e8c355;
  --pine: #7fd8e8;          /* gauge needle arc rides the cyan accent */
  --ok: #3ec78b;
  --ok-soft: rgba(62, 199, 139, .12);
  --bad: #ef5f5f;
  --bad-soft: rgba(239, 95, 95, .12);
  --warn: #f0b429;
  --warn-soft: rgba(240, 180, 41, .12);
  --hover: rgba(255, 255, 255, .025);
  --tab-active-bg: #101112;
  --pin-ring: #0b0b0c;
  --shadow: none;
  --shadow-pop: 0 16px 56px rgba(0, 0, 0, .6);
  --term-bg: #0c0d0f;
  --map-water: #101112;
  --mono: ui-monospace, "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  color-scheme: dark;
}
:root[data-theme="light"] {
  --bg: #ececea;
  --panel: #fbfbfa;
  --bg-raise: #f1f1ef;
  --card: #ffffff;
  --card-2: #f1f1ef;
  --line: #d4d5d0;
  --line-soft: #e4e5e0;
  --line-strong: #b9bab4;
  --text: #22262a;
  --muted: #5c646a;
  --faint: #8e959b;
  --accent: #cf7207;
  --accent-hi: #a85a03;
  --accent-soft: rgba(207, 114, 7, .1);
  --accent-ink: #ffffff;
  --cyan: #0e7d92;          /* darkened for contrast on white */
  --cyan-dim: rgba(14, 125, 146, .09);
  --gold: #8f6b0a;
  --pine: #0e7d92;
  --ok: #148855;
  --ok-soft: rgba(20, 136, 85, .1);
  --bad: #c73a3a;
  --bad-soft: rgba(199, 58, 58, .09);
  --warn: #9c6a08;
  --warn-soft: rgba(156, 106, 8, .12);
  --hover: rgba(20, 32, 26, .04);
  --tab-active-bg: #ffffff;
  --pin-ring: #ffffff;
  --shadow: none;
  --shadow-pop: 0 16px 56px rgba(34, 38, 42, .22);
  --term-bg: #ffffff;
  --map-water: #e8ecee;
  --mono: ui-monospace, "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  color-scheme: light;
}

/* ---------- base ---------- */
* { box-sizing: border-box; margin: 0; }
html, body { height: 100%; }
body {
  background: var(--bg); color: var(--text);
  font: 13.5px/1.5 "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
}
.hidden { display: none !important; }
.muted { color: var(--muted); }
.err { color: var(--bad); font-size: 13px; }
a { color: var(--cyan); text-decoration: none; }
a:hover { color: color-mix(in srgb, var(--cyan) 70%, var(--text)); }
code { font-family: var(--mono); font-size: .92em; }
button { font: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
::selection { background: var(--accent-soft); }
input, select, textarea {
  background: var(--bg-raise); border: 1px solid var(--line); color: var(--text);
  border-radius: 7px; padding: 8px 11px; font: inherit;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--cyan); }
input::placeholder { color: var(--faint); }
.mono { font-family: var(--mono); font-size: 12px; }

/* numbers line up in tables and gauges */
table, .gauge, .conn-pill, .badge { font-variant-numeric: tabular-nums; }

/* ---------- brand mark ---------- */
.mark { display: inline-flex; flex: none; }
.brand-logo { display: block; flex: none; object-fit: contain; }

/* ---------- login (Jina-style particle terrain, redesign 2026-09-01) ---------- */
.login { position: fixed; inset: 0; z-index: 50; background: var(--bg); overflow: hidden; }
#forest { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.login-topbar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 4;
  display: flex; align-items: center; gap: 14px; padding: 14px 22px;
}
.login-topbar .login-mark { width: 38px; height: 38px; }
.login-topbar .login-pine { width: 26px; height: 34px; margin-left: 2px; }
:root[data-theme="light"] .login-topbar .brand-logo { filter: saturate(.9) brightness(.92); }
.login-topbar b { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.login-sep { width: 1px; height: 22px; background: color-mix(in srgb, var(--text) 16%, transparent); }
.login-by { font-size: 12.5px; color: var(--muted); letter-spacing: .06em; }
.login .theme-btn {
  margin-left: auto; background: transparent; color: var(--muted);
  border: 1px solid color-mix(in srgb, var(--text) 16%, transparent);
  border-radius: 999px; padding: 6px 14px; font-size: 12px; cursor: pointer;
}
.login .theme-btn:hover { color: var(--text); border-color: var(--accent); }

.login-hero {
  position: absolute; left: clamp(24px, 6vw, 110px); top: 26%; z-index: 3;
  pointer-events: none;
}
.login-hero .l1 { font-size: clamp(34px, 4.8vw, 64px); font-weight: 300; letter-spacing: -.01em; line-height: 1.08; }
.login-hero .l2 { font-size: clamp(44px, 6.4vw, 86px); font-weight: 800; letter-spacing: -.02em; line-height: 1.05; }
.login-hero .l2 em { font-style: normal; color: var(--accent); }
.login-hero .sub { margin-top: 14px; font-size: 14px; color: var(--muted); letter-spacing: .04em; }

/* the boxed segmented sign-in row */
.login-col {
  position: absolute; left: clamp(24px, 6vw, 110px);
  top: 52%; z-index: 3; width: min(440px, calc(100vw - 48px));
}
.login-row { display: flex; flex-direction: column; gap: 10px; }
.cell {
  border: 1px solid color-mix(in srgb, var(--text) 45%, transparent);
  border-radius: 10px; overflow: hidden;
  display: flex; align-items: center; min-height: 58px;
  background: color-mix(in srgb, var(--bg) 55%, transparent);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
}
.cell input {
  background: transparent; border: 0; color: var(--text); font: inherit;
  padding: 10px 20px; width: 100%; min-width: 0; font-size: 15px;
}
.cell input::placeholder { color: var(--faint); }
.cell input:focus { outline: none; border-color: transparent; }
.cell input:-webkit-autofill {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px transparent inset; transition: background-color 9999s;
}
.cell:focus-within { border-color: var(--accent); z-index: 1; position: relative; }
.cell.c-btn { border-color: var(--accent); background: var(--accent); }
.cell.c-btn button {
  background: none; border: 0; color: var(--accent-ink); font-weight: 700; font-size: 15px;
  padding: 14px 34px; cursor: pointer; width: 100%; letter-spacing: .02em;
}
.cell.c-btn:hover { background: var(--accent-hi); border-color: var(--accent-hi); }
.login-foot { margin-top: 14px; font-size: 11.5px; color: var(--faint); letter-spacing: .03em; }
#login-err { margin-top: 10px; }
@media (max-width: 880px) {
  .login-hero { top: 16%; }
  .login-col { top: 42%; }
}

/* ---------- shell: the console frame ---------- */
.shell { display: flex; flex-direction: column; min-height: 100vh; background: var(--panel); }

/* ---------- tab bar ---------- */
.tabbar {
  display: flex; align-items: stretch; border-bottom: 1px solid var(--line);
  background: var(--panel); position: sticky; top: 0; z-index: 20;
}
.tab-logo {
  display: flex; align-items: center; justify-content: center; width: 58px;
  border-right: 1px solid var(--line); flex: none;
}
.tab-logo img { width: 34px; height: 34px; object-fit: contain; transition: transform .25s; }
.tab-logo:hover img { transform: scale(1.12) rotate(-6deg); }
.tabs { display: flex; align-items: stretch; position: relative; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }

/* the two groups expand IN PLACE, horizontally */
.nav-sect { display: flex; align-items: stretch; }
.nav-group {
  display: flex; align-items: center; gap: 8px; padding: 0 16px; height: 54px;
  border: 0; background: none; cursor: pointer;
  color: var(--faint); font-size: 11px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; white-space: nowrap;
  border-right: 1px solid var(--line-soft);
  transition: color .18s, background .18s, box-shadow .18s;
}
.nav-group:hover { color: var(--text); }
.nav-group .gcaret { font-style: normal; opacity: .6; transition: transform .3s; }
.nav-group.open .gcaret { transform: rotate(90deg); }
.nav-group.open {
  color: var(--accent); background: rgba(240, 148, 31, .05);
  box-shadow: inset 0 -2px 0 rgba(240, 148, 31, .4);
}
.nav-group.here:not(.open) { color: color-mix(in srgb, var(--accent) 55%, var(--faint)); }
.nav-sub {
  display: flex; align-items: stretch; max-width: 1400px; overflow: hidden;
  transition: max-width .35s cubic-bezier(.6, .1, .25, 1), opacity .25s;
}
.nav-sect:not(.open) .nav-sub { max-width: 0; opacity: 0; }
.nav-list { display: flex; flex-direction: row; align-items: stretch; }
.nav-item {
  display: flex; align-items: center; gap: 9px; padding: 0 18px; height: 54px;
  color: var(--muted); text-decoration: none;
  font-size: 12.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap; position: relative; transition: color .18s, background .18s;
}
.nav-item svg { flex: none; opacity: .8; transition: opacity .18s; }
.nav-item:hover { color: var(--text); background: var(--hover); }
.nav-item.active { color: var(--cyan); background: var(--tab-active-bg); }
.nav-item.active svg { opacity: 1; }
.nav-tick { display: none; }
.nav-disabled { opacity: .4; cursor: default; pointer-events: none; }
.soon {
  font-size: 9px; border: 1px solid var(--line); padding: 1px 6px;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-family: var(--mono);
}
.tab-ink {
  position: absolute; bottom: 0; height: 2px; background: var(--cyan); z-index: 2;
  transition: left .28s cubic-bezier(.6, .1, .25, 1), width .28s cubic-bezier(.6, .1, .25, 1);
  box-shadow: 0 0 12px rgba(127, 216, 232, .55);
}
@media (prefers-reduced-motion: reduce) {
  .nav-sub, .nav-group .gcaret, .tab-ink { transition: none; }
}
.tabbar-right { margin-left: auto; display: flex; align-items: center; padding-right: 16px; gap: 6px; }
.icon-btn {
  display: inline-flex; align-items: center; gap: 7px; padding: 7px 12px;
  color: var(--muted); font-size: 12px; border: 1px solid transparent;
  background: none; cursor: pointer; text-decoration: none;
}
.icon-btn:hover { color: var(--text); border-color: var(--line); }

/* ---------- utility bar ---------- */
.utilbar {
  display: flex; align-items: center; gap: 4px; padding: 6px 12px;
  border-bottom: 1px solid var(--line); background: var(--panel); font-size: 12px;
  position: sticky; top: 54px; z-index: 10;
}
.utilbar .icon-btn { padding: 5px 10px; }
.util-crumb {
  font-family: var(--mono); font-size: 11px; color: var(--faint);
  letter-spacing: .1em; text-transform: uppercase; padding: 0 8px; white-space: nowrap;
}
.util-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.status-dot { display: inline-flex; align-items: center; gap: 7px; color: var(--muted); font-size: 12px; white-space: nowrap; }
.status-dot i { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 8px var(--ok); flex: none; }
#conn-summary { font-size: 12px; color: var(--muted); white-space: nowrap; }

.user-chip { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.chip-name { color: var(--text); font-weight: 600; }
.badge {
  font-size: 10px; padding: 2px 8px; border: 1px solid var(--line);
  color: var(--muted); text-transform: uppercase; letter-spacing: .06em;
  font-family: var(--mono); cursor: help;
}
.badge-role { color: var(--gold); border-color: color-mix(in srgb, var(--gold) 45%, transparent); }
.badge-console { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: var(--ok-soft); }
.badge-ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: var(--ok-soft); }
.badge-bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 55%, transparent); background: var(--bad-soft); }

.ghost-btn {
  background: transparent; color: var(--muted); border: 1px solid var(--line);
  border-radius: 7px; padding: 5px 11px; font-size: 11.5px; cursor: pointer;
}
.ghost-btn:hover { color: var(--cyan); border-color: var(--cyan); }

/* ---------- stage ---------- */
.content { flex: 1; min-width: 0; display: flex; flex-direction: column; }
main { padding: 22px 24px 40px; max-width: 1500px; width: 100%; margin: 0 auto; }
.page { animation: panel-in .30s cubic-bezier(.3, .7, .3, 1); }
@keyframes panel-in { from { opacity: 0; transform: translateX(var(--dir, 26px)); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .page { animation: none; } }

/* ---------- console-skin vocabulary ---------- */
.sec-label {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint); font-family: var(--mono); margin: 4px 0 10px;
}
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; margin-bottom: 20px; }
.cards:empty { display: none; }
.card {
  border: 1px solid var(--line); background: var(--card); padding: 18px;
  transition: border-color .18s, transform .18s;
}
.card:hover { border-color: var(--line-strong); transform: translateY(-1px); }
.card .k { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); font-family: var(--mono); }
.card .v { font-size: 34px; font-weight: 300; margin: 8px 0 2px; letter-spacing: -.01em; }
.card .v b { font-weight: 700; }
.card .s { font-size: 12px; color: var(--muted); }
.card.ok .v { color: var(--ok); } .card.warn .v { color: var(--warn); } .card.gold .v { color: var(--gold); }

.chip {
  font-family: var(--mono); font-size: 11px; padding: 2px 8px;
  border: 1px solid var(--line); color: var(--muted); white-space: nowrap;
}
.chip.cyan { color: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 35%, transparent); background: var(--cyan-dim); }
.bar-mini { display: inline-block; width: 64px; height: 4px; background: var(--line-soft); position: relative; vertical-align: middle; }
.bar-mini i { position: absolute; inset: 0 auto 0 0; background: var(--cyan); }
.bar-mini i.hot { background: var(--warn); }
.bar-mini i.crit { background: var(--bad); }
.pct { font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-left: 8px; }
.row-btn {
  background: none; border: 1px solid var(--line); color: var(--muted);
  font-size: 11px; padding: 4px 12px; cursor: pointer; white-space: nowrap;
  font-family: var(--mono); letter-spacing: .06em; text-transform: uppercase;
}
.row-btn:hover { color: var(--cyan); border-color: var(--cyan); }
.empty { padding: 60px 20px; text-align: center; color: var(--faint); font-family: var(--mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }

/* fleet header row: label left, search middle, view toggle right */
.fleet-head { display: flex; align-items: center; gap: 12px; margin: 4px 0 10px; flex-wrap: wrap; }
.fleet-head .sec-label { margin: 0; }
#fleet-search { width: min(280px, 40%); padding: 6px 11px; font-size: 12.5px; }
#fleet-count { font-size: 11.5px; font-family: var(--mono); }
.fleet-head .view-toggle { margin-left: auto; }

/* the campaign form box (Updates, left column) */
.split { display: grid; grid-template-columns: minmax(330px, 420px) 1fr; gap: 14px; align-items: start; }
@media (max-width: 1020px) { .split { grid-template-columns: 1fr; } }
.form-box { border: 1px solid var(--line); background: var(--card); }
.form-box .fb-head {
  padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 12px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  font-family: var(--mono); display: flex; align-items: center; gap: 8px;
}
.form-box .fb-head .hint { margin-left: auto; }
.form-box .fb-body { padding: 16px; display: flex; flex-direction: column; gap: 14px; }
.f-label { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint); font-family: var(--mono); margin-bottom: 6px; display: block; }
.opt-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-top: 1px solid var(--line-soft); }
.opt-row:first-of-type { border-top: 0; }
.opt-row .t { font-size: 13px; display: block; }
.opt-row .d { font-size: 11.5px; color: var(--faint); display: block; }
.cta {
  background: var(--accent); color: var(--accent-ink); border: 0; font-weight: 700;
  padding: 11px 18px; letter-spacing: .02em; transition: background .15s; width: 100%;
  text-transform: uppercase; cursor: pointer;
}
.cta:hover { background: var(--accent-hi); }

/* campaign cards with the segmented progress strip */
.camp { border: 1px solid var(--line); background: var(--card); margin-bottom: 14px; }
.camp-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
.camp-head h3, .camp-head strong { font-size: 13.5px; font-weight: 650; }
.camp-head .meta { font-size: 11.5px; color: var(--faint); font-family: var(--mono); }
.camp-head .row-btn, .camp-head button { margin-left: auto; }
.prog { display: flex; gap: 3px; padding: 10px 16px 0; }
.prog i { flex: 1; height: 3px; background: var(--line-soft); }
.prog i.done { background: var(--ok); }
.prog i.run { background: var(--warn); animation: prog-pulse 1.2s ease-in-out infinite; }
.prog i.bad { background: var(--bad); }
@keyframes prog-pulse { 50% { opacity: .35; } }
.camp-rows { padding: 6px 0 8px; }
.camp-row { display: grid; grid-template-columns: 150px 100px 1fr auto; gap: 10px; padding: 7px 16px; font-size: 12.5px; align-items: center; }
.camp-row .detail { font-family: var(--mono); font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 860px) { .camp-row { grid-template-columns: 1fr auto; } .camp-row .detail { grid-column: 1/-1; } }

/* the tab search palette */
.search-card { width: min(460px, 92vw); padding: 14px; align-self: flex-start; margin-top: 12vh; }
.search-card input { width: 100%; font-size: 14px; padding: 11px 14px; }
.search-list { margin-top: 10px; display: flex; flex-direction: column; }
.search-hit {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer;
  color: var(--muted); font-size: 12.5px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 600; border: 1px solid transparent; background: none; text-align: left; width: 100%;
}
.search-hit svg { flex: none; opacity: .8; }
.search-hit .search-group { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--faint); letter-spacing: .12em; }
.search-hit:hover { color: var(--text); background: var(--hover); }
.search-hit.sel { color: var(--cyan); background: var(--cyan-dim); border-color: color-mix(in srgb, var(--cyan) 35%, transparent); }
.search-none { padding: 14px 12px; color: var(--faint); font-family: var(--mono); font-size: 12px; }

/* ---------- fleet cards ---------- */
#hosts { display: grid; grid-template-columns: repeat(auto-fill, minmax(440px, 1fr)); gap: 16px; }
.host-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 16px 16px 8px; box-shadow: var(--shadow); position: relative; overflow: hidden;
}
/* health strip: instantly scannable at 20+ hosts */
.host-card::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--ok);
}
.host-card:has(.gauge.hot)::before { background: var(--warn); }
.host-card:has(.gauge.crit)::before, .host-card:has(.bar i.hot)::before { background: var(--warn); }
.host-card:has(.dot.off)::before { background: var(--bad); }
.host-card:has(.dot.off) { border-color: color-mix(in srgb, var(--bad) 35%, var(--line)); }

.host-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 6px; }
.host-head h3 { font-size: 15px; font-weight: 650; letter-spacing: -.01em; display: flex; align-items: center; }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; flex: none; }
.dot.on { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); animation: pulse 2.6s ease-in-out infinite; }
.dot.off { background: var(--bad); box-shadow: 0 0 0 3px var(--bad-soft); }
@keyframes pulse { 50% { box-shadow: 0 0 0 5px var(--ok-soft); } }
.host-links { white-space: nowrap; }
.host-links a { color: var(--muted); text-decoration: none; font-size: 11.5px; margin-left: 12px; }
.host-links a:hover { color: var(--accent); }

/* CPU trend (10-minute history), kept under the gauges */
.trend { border-top: 1px dashed var(--line); padding: 8px 2px 4px; }
.trend-label {
  display: block; font-size: 10px; color: var(--faint);
  text-transform: uppercase; letter-spacing: .07em; margin-bottom: 2px;
}
.spark { width: 100%; height: 34px; }
.spark polyline { fill: none; stroke: var(--accent); stroke-width: 1.5; opacity: .9; }

/* ---------- automotive gauges (CPU / RAM / Disk) ---------- */
.gauges { display: flex; gap: 18px; margin: 6px 0 12px; flex-wrap: wrap; }
.gauge { flex: 0 1 150px; min-width: 110px; text-align: center; }
.gauge svg { width: 100%; height: auto; display: block; overflow: visible; }
.gauge .g-track { fill: none; stroke: var(--line); stroke-width: 8; stroke-linecap: round; }
.gauge .g-zone { fill: none; stroke-width: 8; }
.gauge .g-zone.warn { stroke: var(--warn); opacity: .5; }
.gauge .g-zone.crit { stroke: var(--bad); opacity: .6; }
.gauge .g-val { fill: none; stroke: var(--pine); stroke-width: 8; stroke-linecap: round; transition: stroke-dasharray .5s ease, stroke .3s; }
.gauge.hot .g-val { stroke: var(--warn); }
.gauge.crit .g-val { stroke: var(--bad); }
.gauge .g-needle line { stroke: var(--text); stroke-width: 2; stroke-linecap: round; }
.gauge .g-needle circle { fill: var(--card-2); stroke: var(--text); stroke-width: 1.6; }
.gauge .g-needle { transition: transform .6s cubic-bezier(.34,1.3,.64,1); }
.gauge .g-ticknum { fill: var(--faint); font-size: 7.5px; }
.gauge .g-num { fill: var(--text); font-size: 15px; font-weight: 650; }
.gauge.hot .g-num { fill: var(--warn); }
.gauge.crit .g-num { fill: var(--bad); }
.g-label {
  display: block; font-size: 10.5px; color: var(--muted); margin-top: 2px;
  text-transform: uppercase; letter-spacing: .05em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gauge.crit .g-label { color: var(--bad); font-weight: 650; }
.gauge.hot .g-label { color: var(--warn); font-weight: 650; }

/* legacy thin-bar gauge kept for any residual callers */
.gauge .bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; margin-top: 5px; }
.gauge .bar i { display: block; height: 100%; background: var(--pine); border-radius: 2px; transition: width .4s; }
.gauge .bar i.hot { background: var(--warn); }

.vm { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid var(--line); padding: 9px 0; gap: 10px; }
.vm-name { font-weight: 600; font-size: 13px; }
.state {
  font-size: 10px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line-strong);
  color: var(--muted); text-transform: uppercase; letter-spacing: .05em; white-space: nowrap;
}
.state.running { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: var(--ok-soft); }
.state.shutoff { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 55%, transparent); background: var(--bad-soft); }
.state.paused { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); background: var(--warn-soft); }

.vm-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.vm-actions button {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 4px 10px; font-size: 12px; cursor: pointer;
}
.vm-actions button:hover { border-color: var(--accent); color: var(--accent); }
.vm-actions button.danger { color: var(--muted); }
.vm-actions button.danger:hover { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
.vm-actions button.console-open:hover { border-color: var(--pine); color: var(--pine); }

/* fleet loading / empty state */
#hosts:empty { display: block; }
#hosts:empty::before {
  content: "Waiting for agents to report in…";
  display: block; text-align: center; color: var(--faint); font-size: 13px;
  padding: 72px 20px; border: 1px dashed var(--line-strong); border-radius: 14px;
  animation: breathe 1.6s ease-in-out infinite;
}
@keyframes breathe { 50% { opacity: .55; } }

/* ---------- snapshots ---------- */
.snap-toggle { background: transparent; color: var(--muted); border: 0; font-size: 11px; cursor: pointer; padding: 3px 4px; }
.snap-toggle:hover { color: var(--accent); text-decoration: underline; }
.snap-panel { border-top: 1px dashed var(--line-strong); padding: 8px 0 6px; }
.snap-empty { font-size: 12px; padding: 4px 0; }
.snap-table { width: 100%; font-size: 12px; }
.snap-table th { font-size: 9.5px; }
.snap-table td { padding: 4px 8px 4px 0; border-bottom: 0; }
button.snap-del {
  background: transparent; color: var(--muted); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 2px 8px; font-size: 11px; cursor: pointer;
}
button.snap-del:hover { color: var(--bad); border-color: var(--bad); background: var(--bad-soft); }

/* ---------- panels & tables ---------- */
.panel {
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 4px 16px 8px; box-shadow: var(--shadow); overflow-x: auto;
}
.panel .role-hint { padding-top: 12px; }
table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th {
  text-align: left; color: var(--faint); font-weight: 600; padding: 11px 10px 8px;
  border-bottom: 1px solid var(--line-strong); font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .07em; white-space: nowrap;
  position: sticky; top: 0; background: var(--card); z-index: 1;
}
td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: color-mix(in srgb, var(--line) 26%, transparent); }

/* status language — dot + tinted text, consistent everywhere */
.st-ok, .st-done, .st-failed, .st-denied, .st-pending, .st-delivered, .st-requested { white-space: nowrap; font-weight: 600; }
.st-ok::before, .st-done::before, .st-failed::before, .st-denied::before,
.st-pending::before, .st-delivered::before, .st-requested::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 7px; vertical-align: 1px; background: currentColor;
}
.st-ok, .st-done { color: var(--ok); }
.st-failed, .st-denied { color: var(--bad); }
.st-pending, .st-delivered, .st-requested { color: var(--warn); }

/* table empty state (JS fills tbody) */
.panel:has(tbody:empty)::after {
  content: "Nothing here yet."; display: block; text-align: center;
  color: var(--faint); font-size: 12.5px; padding: 40px 0 32px;
}

/* ---------- users ---------- */
.user-add { display: flex; gap: 8px; align-items: center; padding: 14px 0 4px; flex-wrap: wrap; }
.user-add button[type="submit"] {
  background: var(--accent); color: var(--accent-ink); border: 0; border-radius: 8px;
  padding: 7px 14px; font-weight: 650; cursor: pointer;
}
.user-add button[type="submit"]:hover { background: var(--accent-hi); }
.check-inline { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); }
#users-table button {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 3px 9px; font-size: 11.5px; cursor: pointer; margin-right: 4px;
}
#users-table button:hover { border-color: var(--accent); color: var(--accent); }
.role-hint { font-size: 12px; margin: 8px 0 12px; max-width: 680px; }

/* ---------- the "?" hint ---------- */
.panel { position: relative; }
.hint {
  display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border: 0; border-radius: 50%; background: none; color: var(--faint); cursor: pointer; padding: 0;
  vertical-align: middle; transition: color .12s, background .12s;
}
.hint:hover, .hint.on { color: var(--accent); background: var(--accent-soft); }
.panel-hint { position: absolute; top: 12px; right: 12px; }
.section-title .hint { margin-left: 4px; }
.inline-hint { margin-left: 4px; }
.wiz-note { font-size: 12px; margin: 6px 0 10px; }
.hint-pop {
  position: fixed; z-index: 90; padding: 10px 12px; font-size: 12.5px; line-height: 1.45; white-space: pre-line;
  color: var(--text); background: var(--card); border: 1px solid var(--line-strong); border-radius: 10px;
  box-shadow: var(--shadow-pop); animation: hint-in .12s ease-out;
}
@keyframes hint-in { from { opacity: 0; transform: translateY(-3px); } }

/* toggle switch (console permission) */
.switch { display: inline-flex; align-items: center; cursor: pointer; vertical-align: middle; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 30px; height: 17px; border-radius: 999px; background: var(--line-strong);
  position: relative; transition: background .15s; flex: none;
}
.switch-track::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px;
  border-radius: 50%; background: var(--card); box-shadow: 0 1px 2px rgba(0,0,0,.3);
  transition: left .15s;
}
.switch input:checked + .switch-track { background: var(--ok); }
.switch input:checked + .switch-track::after { left: 15px; }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- device console ---------- */
.console-overlay {
  position: fixed; inset: 0; background: rgba(8, 9, 11, .74); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; z-index: 70; padding: 24px;
}
.console-frame {
  background: var(--card); border: 1px solid var(--line-strong); border-radius: 14px;
  width: min(1100px, 96vw); height: min(760px, 92vh);
  display: flex; flex-direction: column; box-shadow: var(--shadow-pop); overflow: hidden;
  transition: width .15s, height .15s;
}
.console-frame.expanded { width: 100vw; height: 100vh; border-radius: 0; border: 0; }
.console-overlay:has(.console-frame.expanded) { padding: 0; }
.console-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 11px 16px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.console-bar strong { font-size: 13.5px; margin-right: 10px; }
.console-bar-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.console-bar-actions .ghost-btn.active { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
/* body is a real flex child with min-height:0 — xterm's fit addon measures this box */
.console-body { flex: 1 1 auto; min-height: 0; background: var(--term-bg); padding: 6px; overflow: hidden; position: relative; }
#console-term, #console-term .terminal, #console-term .xterm-screen { height: 100%; width: 100%; }
#console-term .xterm-viewport { overflow-y: auto; }
#console-screen { display: flex; align-items: center; justify-content: center; }
#console-screen canvas { max-width: 100%; max-height: 100%; }
.console-foot {
  padding: 8px 16px; font-size: 11px; border-top: 1px solid var(--line);
  background: var(--panel); color: var(--muted);
}
.console-foot code { background: var(--bg-raise); padding: 1px 5px; border-radius: 4px; }

/* ---------- modal ---------- */
.modal {
  position: fixed; inset: 0; background: rgba(8, 9, 11, .6); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; z-index: 50;
}
.modal-card {
  background: var(--card); border: 1px solid var(--line-strong); border-radius: 14px;
  padding: 24px; width: 440px; max-width: 92vw; box-shadow: var(--shadow-pop);
}
.modal-card h3 { font-size: 15px; font-weight: 650; margin-bottom: 8px; }
.modal-card input { width: 100%; margin-top: 14px; padding: 9px 11px; border-radius: 9px; }
.check-row { display: flex; align-items: flex-start; gap: 8px; margin-top: 14px; font-size: 13px; color: var(--muted); cursor: pointer; }
.check-row input { width: auto; margin: 2px 0 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
.modal-actions button {
  border-radius: 8px; padding: 8px 16px; border: 1px solid var(--line-strong);
  background: var(--bg-raise); color: var(--text); cursor: pointer;
}
.modal-actions button:hover { border-color: var(--muted); }
#modal-ok { background: var(--accent); color: var(--accent-ink); font-weight: 650; border-color: transparent; }
#modal-ok:hover { background: var(--accent-hi); }
#modal-ok.danger { background: var(--bad); color: #fff; border-color: transparent; }
#modal-ok.danger:hover { background: color-mix(in srgb, var(--bad) 85%, #000); }

/* ---------- toast ---------- */
.toast {
  position: fixed; right: 20px; bottom: 20px; background: var(--card);
  border: 1px solid var(--line-strong); border-left: 3px solid var(--accent);
  border-radius: 10px; padding: 12px 16px; z-index: 80; max-width: 380px;
  box-shadow: var(--shadow-pop); font-size: 13px;
}
.toast.ok { border-left-color: var(--ok); }
.toast.bad { border-left-color: var(--bad); }

/* ---------- Batch D: images / blueprints / backups / deploy ---------- */
.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 11.5px; }
.badge-cache { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: var(--ok-soft); }
.disk-warn, .disk-crit {
  margin-left: 8px; font-weight: 650;
  color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
}
.disk-crit { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 55%, transparent); background: var(--bad-soft); }

.bp-form { padding: 14px 0 4px; }
.bp-grid { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; align-items: flex-end; }
.bp-grid .field { display: flex; flex-direction: column; gap: 4px; flex: 0 1 110px; min-width: 0; }
.bp-grid .field.grow { flex: 2 1 240px; }
.bp-grid .field label { font-size: 11.5px; color: var(--muted); }
.bp-grid .field input, .bp-grid .field select { width: 100%; }
.bp-grid .field-btn { flex: 0 0 auto; }
.bp-grid button[type="submit"] {
  background: var(--accent); color: var(--accent-contrast, #fff); border-color: transparent; font-weight: 600;
}
.section-title { font-size: 13px; font-weight: 650; margin-top: 18px; }
.mini-bar {
  width: 120px; height: 4px; border-radius: 2px; margin-top: 5px;
  background: color-mix(in srgb, var(--line-strong) 60%, transparent); overflow: hidden;
}
.mini-bar i { display: block; height: 100%; background: var(--accent); border-radius: 2px; transition: width .5s; }
.err-detail { font-size: 11px; color: var(--muted); max-width: 320px; margin-top: 3px; white-space: normal; }
.auto-wrap {
  display: inline-flex; align-items: center; gap: 5px; margin-left: 8px;
  font-size: 10.5px; color: var(--muted); vertical-align: middle;
}
.auto-wrap .switch-track { transform: scale(.85); }
.auto-wrap.auto-warn { color: var(--warn); font-weight: 600; }

#deploy-modal .modal-card { width: min(560px, 92vw); }
.deploy-label { display: block; margin-top: 12px; margin-bottom: 4px; font-size: 12px; color: var(--muted); }
#deploy-modal select, #deploy-modal textarea { width: 100%; }
#deploy-modal input { width: 100%; margin-top: 0; }
#deploy-modal textarea {
  resize: vertical; font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 11.5px;
  background: var(--bg-input, var(--card)); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: 8px; padding: 9px 11px;
}
#deploy-modal textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
#deploy-ok { background: var(--accent); color: #fff; border-color: transparent; font-weight: 600; }
#images-table td:nth-child(5) button, .bp-deploy { white-space: nowrap; }

/* ---------- fleet table + host detail (v2 layout) ---------- */
.fleet-toolbar { display: flex; align-items: center; gap: 12px; padding: 14px 0 10px; flex-wrap: wrap; }
#fleet-search { width: min(300px, 50%); }
#fleet-settings { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }

/* table | map switch */
.view-toggle {
  display: inline-flex; background: var(--bg-raise); border: 1px solid var(--line-strong);
  border-radius: 9px; padding: 2px; gap: 2px;
}
.view-toggle button {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 0; color: var(--muted); border-radius: 7px;
  padding: 5px 14px; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.view-toggle button:hover { color: var(--text); }
.view-toggle button.active { background: var(--card); color: var(--accent); box-shadow: var(--shadow); }

/* extra columns scroll sideways instead of squeezing the table */
.table-scroll { overflow-x: auto; }
.table-scroll table { min-width: 100%; }
.table-scroll td, .table-scroll th { white-space: nowrap; }
.os-cell { max-width: 340px; overflow: hidden; text-overflow: ellipsis; }

/* Table tools (tabletools.js, 2026-09-15): click a header to sort, drag its
   right edge to widen. Widened tables switch to fixed layout so a column
   can also be made narrower, and long values clip with an ellipsis. */
th.tt-sortable { cursor: pointer; user-select: none; }
th.tt-sortable:hover { color: var(--text); }
th[data-tt-dir="asc"]::after { content: " ↑"; color: var(--accent); }
th[data-tt-dir="desc"]::after { content: " ↓"; color: var(--accent); }
.tt-grip { position: absolute; top: 0; right: -5px; width: 10px; height: 100%; cursor: col-resize; z-index: 2; }
.tt-grip:hover, .tt-grip.on { box-shadow: inset 2px 0 0 var(--accent); }
body.tt-resizing, body.tt-resizing * { cursor: col-resize !important; user-select: none !important; }
table.tt-fixed { table-layout: fixed; }
table.tt-fixed td, table.tt-fixed th { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A long value shown short until its column is widened (a checksum). */
.ellip { display: inline-block; max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

/* density: padding only, chosen in the Table settings drawer */
table.density-compact td { padding: 5px 10px; }
table.density-comfy td { padding: 8px 10px; }
table.density-spacious td { padding: 13px 10px; }

/* ---------- fleet map view ---------- */
#fleet-map-wrap {
  position: relative; height: clamp(420px, calc(100vh - 260px), 760px);
  border-radius: 12px; overflow: hidden; border: 1px solid var(--line);
  background: var(--map-water); margin: 2px 0 10px;
}
.cmap { position: absolute; inset: 0; overflow: hidden; cursor: grab; touch-action: none; }
.cmap.dragging { cursor: grabbing; }
.cmap-tiles, .cmap-markers { position: absolute; inset: 0; }
.cmap-tiles img { position: absolute; top: 0; left: 0; user-select: none; pointer-events: none; }
/* charcoal night-map treatment for the reference look */
:root[data-theme="dark"] .cmap-tiles img {
  filter: invert(1) hue-rotate(180deg) saturate(.25) brightness(.78) contrast(.92);
}
:root[data-theme="light"] .cmap-tiles img { filter: saturate(.55) contrast(.96); }

/* air-gapped fallback: styled coordinate grid instead of tiles */
.cmap-fallback {
  position: absolute; inset: 0; display: none;
  background:
    repeating-linear-gradient(0deg, transparent 0 79px, var(--line) 79px 80px),
    repeating-linear-gradient(90deg, transparent 0 79px, var(--line) 79px 80px),
    radial-gradient(1200px 700px at 50% 40%, color-mix(in srgb, var(--pine) 7%, transparent), transparent 70%),
    var(--map-water);
}
.cmap.cmap-offline .cmap-tiles, .cmap.cmap-offline .cmap-attr { display: none; }
.cmap.cmap-offline .cmap-fallback { display: block; }
.cmap-fallback-note {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  font-size: 11px; color: var(--muted); background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 12px; white-space: nowrap;
}
.cmap-attr {
  position: absolute; right: 8px; bottom: 6px; font-size: 10px; color: var(--faint);
  background: color-mix(in srgb, var(--bg) 70%, transparent); padding: 1px 6px; border-radius: 5px;
  pointer-events: none;
}
.cmap-ctl { position: absolute; top: 12px; left: 12px; display: flex; flex-direction: column; gap: 4px; z-index: 6; }
.cmap-ctl button {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line-strong);
  background: var(--card); color: var(--text); font-size: 15px; cursor: pointer;
  box-shadow: var(--shadow); line-height: 1;
}
.cmap-ctl button:hover { border-color: var(--accent); color: var(--accent); }

/* host pins: marker color = status, with a text label so color is never alone */
.map-pin {
  position: absolute; top: 0; left: 0; z-index: 4;
  background: none; border: 0; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.map-pin .pin-inner {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  transform: translate(-50%, -8px); /* dot center sits on the coordinate */
}
.map-pin .pin-dot {
  width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 2.5px solid var(--card); box-shadow: 0 2px 8px rgba(0,0,0,.4);
  background: var(--ok);
}
.map-pin.warn .pin-dot { background: var(--warn); }
.map-pin.off .pin-dot { background: var(--bad); animation: pin-blink 1.6s ease-in-out infinite; }
@keyframes pin-blink { 50% { box-shadow: 0 2px 8px rgba(0,0,0,.4), 0 0 0 6px var(--bad-soft); } }
.map-pin .pin-label {
  font-size: 10.5px; font-weight: 600; color: var(--text); white-space: nowrap;
  background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  padding: 1px 8px; box-shadow: var(--shadow);
  opacity: 0; transition: opacity .12s;
}
.map-pin:hover .pin-label, .map-pin.selected .pin-label { opacity: 1; }
.map-pin.selected .pin-dot { outline: 3px solid color-mix(in srgb, var(--accent) 60%, transparent); outline-offset: 1px; }
.map-pin:focus-visible { outline: none; }
.map-pin:focus-visible .pin-dot { outline: 2px solid var(--accent); outline-offset: 2px; }

/* legend — text + color, bottom left */
.map-legend {
  position: absolute; left: 12px; bottom: 12px; z-index: 6;
  display: flex; gap: 12px; align-items: center;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 6px 12px; font-size: 11px; color: var(--muted); box-shadow: var(--shadow);
}
.map-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 5px; vertical-align: -1px; }
.map-legend .lg-on i { background: var(--ok); }
.map-legend .lg-warn i { background: var(--warn); }
.map-legend .lg-off i { background: var(--bad); }
#map-missing { color: var(--faint); border-left: 1px solid var(--line); padding-left: 12px; }

/* the reference-style side panel with the selected host's assets */
.map-panel {
  position: absolute; top: 12px; right: 12px; bottom: 12px; width: min(330px, 82%);
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-pop); z-index: 7; overflow-y: auto; padding: 16px;
  animation: panel-in .22s ease;
}
@keyframes panel-in { from { opacity: 0; transform: translateX(14px); } }
.mp-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 2px; }
.mp-head h3 { font-size: 15px; font-weight: 650; display: flex; align-items: center; min-width: 0; }
.mp-head h3 span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-panel-close {
  margin-left: auto; background: transparent; border: 0; color: var(--muted);
  font-size: 15px; cursor: pointer; padding: 2px 6px; border-radius: 6px; flex: none;
}
.map-panel-close:hover { color: var(--text); background: var(--card-2); }
.mp-status { font-size: 11.5px; font-weight: 600; margin-bottom: 2px; }
.mp-status.on { color: var(--ok); }
.mp-status.off { color: var(--bad); }
.mp-addr { font-size: 11.5px; color: var(--muted); margin-bottom: 10px; line-height: 1.45; }
.map-panel .gauges { gap: 8px; margin: 10px 0 4px; flex-wrap: nowrap; }
.map-panel .gauge { flex: 1 1 0; min-width: 0; }
.map-panel .gauge .g-num { font-size: 17px; }
.map-panel .trend { margin-bottom: 10px; }
.mp-sec {
  font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .1em;
  margin: 14px 0 6px; font-weight: 600;
}
.mp-vm {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 10px; margin-bottom: 6px;
}
.mp-vm .vm-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; }
.mp-auto { font-size: 10px; color: var(--muted); white-space: nowrap; }
.mp-auto.auto-off { color: var(--warn); font-weight: 600; }
.mp-empty { font-size: 12px; color: var(--faint); padding: 6px 2px; }
.map-open-host {
  width: 100%; margin-top: 12px; padding: 9px 12px; border-radius: 9px; border: 0;
  background: var(--accent); color: var(--accent-ink); font-weight: 650; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.map-open-host:hover { background: var(--accent-hi); }
.mp-agent { font-size: 11px; color: var(--faint); margin-top: 10px; text-align: center; }

/* ---------- table settings drawer (slides in from the right) ---------- */
.drawer-overlay {
  position: fixed; inset: 0; z-index: 60; background: rgba(8, 9, 11, 0);
  pointer-events: none; transition: background .25s ease;
}
.drawer-overlay.open { background: rgba(8, 9, 11, .45); pointer-events: auto; }
.drawer {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(320px, 88vw);
  background: var(--card); border-left: 1px solid var(--line-strong);
  box-shadow: var(--shadow-pop); padding: 18px 20px; overflow-y: auto;
  transform: translateX(100%); transition: transform .25s ease;
}
.drawer-overlay.open .drawer { transform: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.drawer-head h3 { font-size: 15px; font-weight: 650; }
.drawer-sec { padding: 12px 0; border-bottom: 1px solid var(--line); }
.drawer-sec h4 {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--faint); font-weight: 600; margin-bottom: 8px;
}
.drawer-sec .muted { font-size: 11.5px; padding-bottom: 6px; }
.drawer-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 12.5px; cursor: pointer; }
.drawer-row input { accent-color: var(--accent); }
.drawer-locked { color: var(--muted); cursor: default; }
#drawer-reset { margin-top: 14px; }

/* instant tooltip: native title has a fixed OS delay, this shows on hover
   immediately with a short fade */
.tip-wrap { position: relative; cursor: default; }
.tip-wrap::after {
  content: attr(data-tip);
  position: absolute; left: 0; bottom: calc(100% + 6px);
  background: var(--card); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 7px 10px; font-size: 11.5px; font-weight: 400;
  width: max-content; max-width: 300px; white-space: normal; line-height: 1.45;
  box-shadow: var(--shadow-pop); z-index: 40;
  opacity: 0; visibility: hidden; transition: opacity .1s ease;
  pointer-events: none;
}
.tip-wrap:hover::after { opacity: 1; visibility: visible; }

/* ---------- resource editor ---------- */
#res-modal .modal-card { width: min(440px, 92vw); }
.res-mem-row { display: flex; align-items: center; gap: 12px; }
.res-mem-row input[type="range"] { flex: 1; accent-color: var(--accent); margin-top: 0; }
.res-mem-row input[type="number"] { width: 92px; margin-top: 0; }
.res-scale { display: flex; justify-content: space-between; font-size: 10.5px; margin-top: 3px; }
.res-cpu-row { display: flex; align-items: center; gap: 8px; }
.res-cpu-row input { width: 64px; text-align: center; margin-top: 0; }
.res-cpu-row button { width: 32px; font-size: 15px; }
#res-ok { background: var(--accent); color: var(--accent-ink); font-weight: 650; border-color: transparent; }

/* ---------- address editor ---------- */
#address-modal .modal-card { width: min(460px, 92vw); }
#address-modal select, #address-modal input { width: 100%; margin-top: 0; }
.addr-row { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; }
#addr-clear { margin-right: auto; color: var(--muted); }
#addr-clear:hover { color: var(--bad); border-color: var(--bad); }
#addr-ok { background: var(--accent); color: var(--accent-ink); font-weight: 650; border-color: transparent; }
#fleet-table th.sortable { cursor: pointer; user-select: none; }
#fleet-table th.sortable:hover { color: var(--text); }
#fleet-table th.sortable[data-dir="asc"]::after { content: " ↑"; color: var(--accent); }
#fleet-table th.sortable[data-dir="desc"]::after { content: " ↓"; color: var(--accent); }
#fleet-table tr.host-row { cursor: pointer; }
#fleet-table tr.host-row:hover td { background: color-mix(in srgb, var(--accent) 6%, transparent); }
#fleet-table .row-open { font-size: 16px; text-align: right; }
.mono-sub { font-size: 10.5px; margin-left: 6px; }
.ghost-icon {
  background: transparent; border: none; padding: 2px 4px; margin-left: 4px; cursor: pointer;
  color: var(--muted); opacity: 0; transition: opacity .12s; vertical-align: middle;
}
#fleet-table tr:hover .ghost-icon { opacity: 1; }
.ghost-icon:hover { color: var(--accent); }

.host-detail-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; flex-wrap: wrap; }
.host-detail-head h2 { font-size: 17px; font-weight: 650; display: flex; align-items: center; gap: 8px; }
.host-detail-head .host-links { margin-left: auto; }
.back-btn { display: inline-flex; align-items: center; gap: 4px; text-decoration: none; }
.detail-card { margin-bottom: 14px; }
.detail-card .gauges { justify-content: flex-start; gap: 28px; padding: 8px 4px 2px; }
.detail-card .gauge { flex: 0 1 200px; }

.vm-list .vm-block { padding: 12px 4px 4px; }
.vm-list .vm-block + .vm-block, .vm-list .snap-panel + .vm-block { border-top: 1px solid var(--line); margin-top: 8px; }
.vm-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.vm-btns { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; padding-bottom: 8px; }
.btn-group { display: inline-flex; gap: 6px; align-items: center; }
.btn-group + .btn-group { border-left: 1px solid var(--line); padding-left: 18px; }
.vm-btns button {
  display: inline-flex; align-items: center; gap: 6px;
}
.vm-btns button svg, .snap-table button svg { flex: none; }
.snap-table button { display: inline-flex; align-items: center; gap: 5px; }
.btn-console {
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: var(--accent-soft); font-weight: 600;
}
.btn-console:hover { background: color-mix(in srgb, var(--accent) 22%, transparent); }

/* ---------- responsive ---------- */
@media (max-width: 1100px) {
  #hosts { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  /* the tab bar collapses to icon-only tabs; titles still name them on hover */
  .nav-item span { display: none; }
  .nav-item { padding: 0 14px; }
  .nav-group span { display: none; }
}

/* ---------- enrollment + networks editor + templates (Batch F) ---------- */
.token-value {
  display: block; margin-top: 12px; padding: 12px; border-radius: 8px;
  background: var(--bg-raise); border: 1px dashed var(--line-strong);
  font-size: 12.5px; word-break: break-all; user-select: all;
}
#net-modal .modal-card { width: min(460px, 92vw); }
.net-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.net-gi { width: 34px; font-size: 12px; font-weight: 600; }
.net-row select { flex: 1; margin-top: 0; }
.net-row button { width: 30px; padding: 5px 0; }
#net-add { margin-top: 12px; }
.bp-template-row { border-bottom: 1px dashed var(--line); padding-bottom: 12px; margin-bottom: 12px; }
#res-disk { width: 92px; }

/* ---------- channel setup guide popup ---------- */
.guide-card { width: min(560px, 94vw); max-height: 84vh; overflow-y: auto; }
.guide-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.guide-head h3 { font-size: 15px; font-weight: 650; }
.guide-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 12px; }
.guide-tabs button {
  background: transparent; border: 1px solid var(--line-strong); color: var(--muted);
  border-radius: 999px; padding: 5px 14px; cursor: pointer; font-size: 12.5px;
}
.guide-tabs button.active { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.guide-steps { margin: 0; padding-left: 6px; list-style: none; counter-reset: gstep; }
.guide-steps li {
  counter-increment: gstep; position: relative; padding: 6px 0 6px 36px; font-size: 13px; line-height: 1.55;
}
.guide-steps li::before {
  content: counter(gstep); position: absolute; left: 0; top: 7px;
  width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); font-size: 11.5px; font-weight: 700;
}
.guide-pane code { background: var(--bg-raise); border: 1px solid var(--line); border-radius: 5px; padding: 1px 6px; font-size: 11.5px; word-break: break-all; }
.guide-pane .muted { font-size: 12px; margin-top: 10px; line-height: 1.5; }
.guide-code { display: block; margin-top: 8px; padding: 9px 11px !important; }

/* ---------- Stage 4: provisioning, campaigns, attestation ---------- */
.sp-bridge .sp-br-name, .sp-bridge .sp-br-nic { flex: 1; margin-top: 0; }
#sp-bridges { margin-top: 6px; }
#sp-add-bridge { margin-top: 8px; }

.camp-hosts { padding: 6px 0; }
.host-picker { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.host-picker-bar {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--fg) 3%, transparent);
}
.host-picker-bar input[type="search"] {
  flex: 1; border: none; background: transparent; padding: 4px 0; font-size: 13px; color: var(--fg);
}
.host-picker-bar input[type="search"]:focus { outline: none; }
.host-picker-bar .muted { font-size: 12px; white-space: nowrap; }
.host-picker-list { max-height: 240px; overflow-y: auto; }
.camp-host {
  display: flex; align-items: center; gap: 10px; font-size: 13px;
  padding: 7px 12px; cursor: pointer; border-top: 1px solid var(--line);
}
.camp-host:first-child { border-top: none; }
.camp-host:hover { background: color-mix(in srgb, var(--fg) 4%, transparent); }
.camp-host.off { opacity: .5; cursor: not-allowed; }
.camp-host input { accent-color: var(--accent); }
.camp-host .camp-host-site { color: var(--muted); font-size: 12px; margin-left: auto; }
.camp-opts { gap: 20px !important; align-items: center; }
.camp-card {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-top: 12px;
  background: var(--bg-raise);
}
.camp-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; font-size: 13px; }
.camp-head button { margin-left: auto; }
.camp-table { font-size: 12px; }
.camp-table td { padding: 4px 8px; border-bottom: 0; }

.tpm-box {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 16px; margin-bottom: 14px;
  background: var(--card);
}
.tpm-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.tpm-detail { font-size: 11.5px; margin-top: 6px; }
.tpm-rebase { margin-top: 10px; }
#media-modal .modal-card { width: min(520px, 92vw); }
/* .modal-card input sets width:100% for text fields. A radio must opt out of
   that or it becomes a full-width control and shoves its label off the card. */
#media-modal .drawer-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px;
  line-height: 1.5; margin-top: 8px; border: 1px solid var(--line);
  border-radius: 9px; font-size: 12.5px;
}
#media-modal .drawer-row:hover { border-color: var(--line-strong); }
#media-modal .drawer-row:has(input:checked) {
  border-color: var(--accent); background: var(--accent-soft);
}
#media-modal .drawer-row input[type="radio"] {
  width: auto; flex: 0 0 auto; margin: 3px 0 0; padding: 0; accent-color: var(--accent);
}
#media-modal .drawer-row span { flex: 1; min-width: 0; }
#media-modal .drawer-row code { font-size: 11px; word-break: break-all; }
#media-modal input[type="text"], #media-modal input[type="number"] { width: 100%; margin-top: 0; }
#media-ok { background: var(--accent); color: var(--accent-ink); font-weight: 650; border-color: transparent; }

/* Update campaigns: a dnf run prints hundreds of lines. The row shows the
   last meaningful one and keeps the table a table; the full transcript opens
   in a scrollable modal. Before this, one campaign row was taller than the
   screen and the host chips wrapped mid-word. */
.camp-table { width: 100%; table-layout: fixed; }
.camp-table td { vertical-align: top; }
.camp-host-name { width: 160px; white-space: nowrap; }
.camp-table td:nth-child(2) { width: 130px; white-space: nowrap; }
.camp-detail {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--mono, ui-monospace, monospace); font-size: 11.5px;
}
.camp-host { white-space: nowrap; }
.link-btn {
  background: none; border: 0; padding: 0 0 0 6px; color: var(--accent);
  cursor: pointer; font-size: 11.5px; text-decoration: underline;
}
.modal-pre {
  white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, monospace;
  font-size: 11.5px; max-height: 60vh; overflow-y: auto; text-align: left;
}

/* The tenant badge. Multi-tenancy that is invisible in the UI is
   indistinguishable from no multi-tenancy: an operator with access to two
   customers must be able to see which one is on screen without guessing. */
.badge-org {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent);
  font-weight: 600; letter-spacing: .02em;
}

/* ============================================================
   Batch F — network studio, deployment waves, deploy wizard
   The studio is an SVG diagram that is also a control surface: every
   colour here has to survive both themes, because an operator moving a
   management uplink at 2am is the exact person who runs light mode.
   ============================================================ */

/* ---------- host page tabs ---------- */
.host-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.host-tabs button {
  background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted);
  padding: 8px 14px; font-size: 13px; cursor: pointer;
}
.host-tabs button:hover { color: var(--text); }
.host-tabs button.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 650; }

/* ---------- revealed secrets ---------- */
.secret-cell { display: inline-flex; align-items: center; gap: 6px; }
.secret-value { letter-spacing: .06em; }
.secret-eye { padding: 2px; }

/* ---------- selection bars over a table ---------- */
.pend-bar { display: flex; align-items: center; gap: 10px; padding: 10px 0 6px; flex-wrap: wrap; }
.pend-bar input[type="text"] { flex: 1 1 260px; }
.pend-bar button {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 5px 12px; font-size: 12px; cursor: pointer;
}
.pend-bar button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.pend-bar button:disabled { opacity: .45; cursor: default; }
.pend-bar button.danger-quiet:hover:not(:disabled) { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
/* rows that are done with, kept visible because a denied machine that vanishes
   looks like a machine that was never there */
.row-quiet td { opacity: .55; }
#pending-table input[type="checkbox"], #enroll-hosts input[type="checkbox"], #hw-table input[type="checkbox"] { accent-color: var(--accent); }

/* ---------- hardware inventory ---------- */
.hw-bar .hw-link { font-size: 12px; margin-left: 4px; }
.hw-bar .hw-spacer { flex: 1 1 auto; }
#hw-modal .modal-card { width: min(640px, 92vw); }
#hw-modal .bp-grid { margin-top: 14px; }
#hw-modal .field.wide { flex: 1 1 100%; }
#hw-modal .modal-card input { margin-top: 0; }
#hw-save { background: var(--accent); color: var(--accent-ink); font-weight: 650; border-color: transparent; }
#hw-save:hover { background: var(--accent-hi); }
.hw-notes { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-sub { display: block; font-size: 11px; color: var(--muted); }
.hw-edit { padding: 3px 6px; }
.wave-iso { display: inline-flex; align-items: center; gap: 5px; font-weight: 650; }

/* ---------- network studio ---------- */
#net-studio { padding: 12px 16px 14px; }
.net-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-bottom: 10px; }
.net-toolbar button {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 7px; padding: 5px 11px; font-size: 12px; cursor: pointer;
}
.net-toolbar button:hover { border-color: var(--accent); color: var(--accent); }
.net-legend { font-size: 11.5px; flex: 1 1 240px; min-width: 0; }
.net-zoom { display: inline-flex; gap: 4px; }
.net-zoom button { min-width: 30px; justify-content: center; }

.net-canvas-wrap {
  position: relative; height: 540px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--panel); overflow: hidden;
}
#net-canvas { width: 100%; height: 100%; display: block; touch-action: none; cursor: grab; }
#net-canvas:active { cursor: grabbing; }

.net-col { fill: var(--faint); font-size: 10px; font-weight: 700; letter-spacing: .12em; }
.net-node rect { fill: var(--card-2); stroke: var(--line-strong); stroke-width: 1.2; }
.net-node { cursor: pointer; transition: opacity .15s; }
.net-node .net-title { fill: var(--text); font-size: 12.5px; font-weight: 650; }
.net-node .net-sub { fill: var(--muted); font-size: 10.5px; }
.net-node .net-vmrow { fill: var(--accent); font-size: 10.5px; font-weight: 650; }
.net-node .net-vmtap { fill: var(--muted); font-size: 10.5px; }
.net-node .net-vmsep { stroke: var(--line); stroke-width: 1; }
.net-node .net-lock { stroke: var(--warn); fill: none; stroke-width: 1.4; }
.nk-bridge rect { stroke: color-mix(in srgb, var(--accent) 55%, var(--line-strong)); }
.nk-vm rect { fill: var(--card); }
.net-node.locked rect { stroke: color-mix(in srgb, var(--warn) 60%, var(--line-strong)); }
/* staged objects do not exist on the host yet: dashed until they are applied */
.net-node.staged rect { stroke-dasharray: 5 3; stroke: var(--accent); }
.net-node.sel rect { stroke: var(--accent); stroke-width: 2.2; }
.net-node.dim { opacity: .22; }
.net-chip { fill: var(--accent-soft); stroke: color-mix(in srgb, var(--accent) 45%, transparent); }
.net-chip-t { fill: var(--accent); font-size: 11px; font-weight: 650; }

.net-edge { fill: none; stroke: var(--line-strong); stroke-width: 1.6; }
.net-edge.ne-uplink { stroke: color-mix(in srgb, var(--accent) 70%, var(--line-strong)); stroke-width: 2; }
.net-edge.ne-tap { stroke: var(--pine); stroke-dasharray: 4 3; }
.net-edge.dim { opacity: .15; }
/* The cable in your hand: drawn as the wire itself, not as a hint about one.
   It only goes dashed while it is over nothing, which is the state where it
   would snap back. Seating on a legal target makes it solid and thicker. */
.net-drag { fill: none; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 4;
  pointer-events: none; opacity: .75; }
.net-drag.landing { stroke-dasharray: none; stroke-width: 2.5; opacity: 1; }
/* The box it would land on. */
.net-node.over rect:first-of-type { stroke: var(--accent); stroke-width: 2; }
.net-handle { fill: var(--accent); stroke: var(--card); stroke-width: 2; cursor: grab; }
.net-handle.empty { fill: var(--card); stroke: var(--accent); stroke-dasharray: 3 2; }
.net-handle:hover { r: 8; }

.net-detail {
  position: absolute; top: 12px; right: 12px; width: 270px; max-height: calc(100% - 24px);
  overflow-y: auto; background: var(--card); border: 1px solid var(--line-strong);
  border-radius: 12px; padding: 14px; box-shadow: var(--shadow-pop);
}
.nd-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.nd-head strong { font-size: 13.5px; }
.nd-close { padding: 2px 7px; margin-left: auto; }
.nd-warn { font-size: 11.5px; color: var(--warn); line-height: 1.45; margin-bottom: 8px; }
.nd-warn svg { vertical-align: -2px; margin-right: 4px; }
.nd-props { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; font-size: 12px; margin-bottom: 12px; }
.nd-props dt { color: var(--muted); }
.nd-props dd { color: var(--text); word-break: break-word; }
.net-detail .net-del {
  display: inline-flex; align-items: center; gap: 5px; width: 100%; justify-content: center;
  background: var(--bad-soft); color: var(--bad); border: 1px solid color-mix(in srgb, var(--bad) 45%, transparent);
  border-radius: 7px; padding: 6px; font-size: 12px; cursor: pointer;
}

/* the review bar: nothing has been sent yet, and it should read that way */
.net-review {
  margin-top: 12px; border: 1px solid var(--accent); border-radius: 10px;
  background: var(--accent-soft); padding: 12px 14px;
}
.nr-head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.nr-head strong { font-size: 13px; }
.nr-head .nr-discard { margin-left: auto; }
.nr-moved { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 12px; color: var(--warn-fg, #8a5a00); }
.nr-moved svg { flex: none; }
.nr-list { margin: 0 0 4px; padding-left: 20px; font-size: 12.5px; }
.nr-list li { padding: 2px 0; }
.nr-ack { font-size: 12px; color: var(--text); align-items: flex-start; }
.nr-ack svg { vertical-align: -2px; margin-right: 3px; color: var(--warn); }
.nr-actions { display: flex; align-items: center; gap: 14px; margin-top: 12px; }
.nr-actions .muted { font-size: 11.5px; flex: 1; }
#nr-apply {
  background: var(--accent); color: var(--accent-ink); border: 0; border-radius: 8px;
  padding: 8px 16px; font-weight: 650; cursor: pointer; white-space: nowrap;
}
#nr-apply:hover { background: var(--accent-hi); }
#nr-apply:disabled { opacity: .5; cursor: default; }

.net-apply { margin-top: 12px; border: 1px solid var(--line-strong); border-radius: 10px; padding: 12px 14px; }
.na-head { display: flex; align-items: center; gap: 12px; font-size: 13px; }
.na-head .na-close { margin-left: auto; }
.na-guard { margin-top: 10px; }
.na-guard .muted { font-size: 11.5px; display: block; margin-top: 5px; }
.na-result { margin-top: 10px; font-size: 12.5px; }
.na-result p { margin-top: 8px; }
.na-list { margin: 4px 0 0; padding-left: 20px; font-size: 12px; }
.na-list li { padding: 1px 0; }

/* ---------- deploy wizard ---------- */
.wizard-frame {
  background: var(--card); border: 1px solid var(--line-strong); border-radius: 14px;
  width: min(1200px, 96vw); height: min(820px, 94vh);
  display: flex; flex-direction: column; box-shadow: var(--shadow-pop); overflow: hidden;
}
.wiz-steps { display: flex; gap: 6px; padding: 10px 16px 0; border-bottom: 1px solid var(--line); background: var(--panel); }
.wiz-steps button {
  background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted);
  padding: 8px 14px; font-size: 12.5px; cursor: pointer;
}
.wiz-steps button.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 650; }
.wiz-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 16px; }
.wiz-tools { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.wiz-tools .field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 260px; }
.wiz-tools .field label { font-size: 11.5px; color: var(--muted); }
.wiz-foot {
  display: flex; align-items: center; gap: 14px; padding: 11px 16px;
  border-top: 1px solid var(--line); background: var(--panel);
}
.wiz-foot #wiz-hint { flex: 1; font-size: 12px; }
#wiz-next, #wiz-start {
  background: var(--accent); color: var(--accent-ink); border: 0; border-radius: 8px;
  padding: 8px 16px; font-weight: 650; cursor: pointer;
}
#wiz-next:hover, #wiz-start:hover { background: var(--accent-hi); }
#wiz-next:disabled, #wiz-start:disabled { opacity: .5; cursor: default; }
#wiz-abort {
  background: var(--bg-raise); color: var(--muted); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 8px 16px; cursor: pointer;
}
#wiz-abort:hover { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
#wiz-day0 {
  width: 100%; background: var(--bg-raise); border: 1px solid var(--line-strong); color: var(--text);
  border-radius: 8px; padding: 9px 11px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px;
}
.wiz-table td, .wiz-table th { white-space: nowrap; }
.wiz-table input, .wiz-table select { width: 100%; min-width: 130px; }
.wiz-table input[type="checkbox"] { width: auto; min-width: 0; accent-color: var(--accent); }
/* a cell with no value is the reason Deploy is off, so it says so in colour
   and the count in the footer says so in words */
.cell-bad { border-color: var(--bad) !important; background: var(--bad-soft); }
.wiz-policy { align-items: flex-end; padding-bottom: 4px; }

.dep-pipe { white-space: normal; max-width: 420px; }
.dep-step {
  display: inline-block; font-size: 10px; padding: 2px 7px; margin: 1px 3px 1px 0;
  border-radius: 999px; border: 1px solid var(--line); color: var(--faint);
}
.dep-step.sp-done { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); background: var(--ok-soft); }
.dep-step.sp-now { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); background: var(--warn-soft); font-weight: 650; }
.dep-step.sp-bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 50%, transparent); background: var(--bad-soft); font-weight: 650; }
#wiz-board button.dep-retry {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 3px 9px; font-size: 11.5px; cursor: pointer;
}
#wiz-board button.dep-retry:hover { border-color: var(--accent); color: var(--accent); }

/* ---------- network templates ---------- */
#nettpl-table button, #nettpl-table a.tpl-open, #waves-table button {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 3px 9px; font-size: 11.5px; cursor: pointer; margin-right: 4px;
  display: inline-flex; align-items: center; gap: 5px; text-decoration: none;
}
#nettpl-table button:hover, #nettpl-table a.tpl-open:hover, #waves-table button:hover { border-color: var(--accent); color: var(--accent); }
#nettpl-table button.danger:hover, #waves-table button.danger:hover { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }

/* ============================================================
   Template editor + the four-step apply wizard
   One shape edited on one page, then the same canvas per host with
   the delta staged on it. The state chips and the diagram carry the
   meaning here; the prose that used to live on this page did not.
   ============================================================ */

.tpl-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.tpl-head h2 { font-size: 18px; font-weight: 650; letter-spacing: -.01em; }
.tpl-head .tpl-acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.tpl-acts button {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 6px 13px; font-size: 12.5px; cursor: pointer;
}
.tpl-acts button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.tpl-acts button:disabled { opacity: .45; cursor: default; }
.tpl-acts button.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 650; }
.tpl-acts button.primary:hover:not(:disabled) { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }
.tpl-acts button.danger:hover:not(:disabled) { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }

/* the stepper: four separate pages, and where you are in them */
.step-rail { display: flex; align-items: center; margin: 16px 0 18px; flex-wrap: wrap; row-gap: 8px; }
.step-rail button {
  display: flex; align-items: center; gap: 9px; background: none; border: 0;
  color: var(--faint); font-size: 12.5px; cursor: pointer; padding: 4px 0;
}
.step-rail button:disabled { cursor: default; }
.step-rail .step-n {
  display: grid; place-items: center; width: 23px; height: 23px; border-radius: 50%;
  border: 1px solid var(--line-strong); font-size: 11px; font-weight: 650; flex: none;
}
.step-rail button.done { color: var(--muted); }
.step-rail button.done .step-n { border-color: var(--accent); color: var(--accent); }
.step-rail button.active { color: var(--text); font-weight: 650; }
.step-rail button.active .step-n { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.step-line { flex: 1 1 24px; min-width: 20px; height: 1px; background: var(--line); margin: 0 14px; }

.step-foot {
  display: flex; align-items: center; gap: 14px; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--line);
}
.step-foot .step-hint { flex: 1; font-size: 12px; }
.step-foot button {
  background: var(--bg-raise); color: var(--text); border: 1px solid var(--line-strong);
  border-radius: 8px; padding: 8px 16px; font-size: 13px; cursor: pointer;
}
.step-foot button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.step-foot button.primary { background: var(--accent); color: var(--accent-ink); border: 0; font-weight: 650; }
.step-foot button.primary:hover:not(:disabled) { background: var(--accent-hi); color: var(--accent-ink); }
.step-foot button:disabled { opacity: .45; cursor: default; }

/* one state word per host, in colour, so the list reads at a glance */
.st-chip {
  font-size: 9.5px; padding: 2px 8px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--line-strong); color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em; font-variant-numeric: tabular-nums;
}
.st-chip.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); background: var(--ok-soft); }
.st-chip.part { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); background: var(--warn-soft); }
.st-chip.bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); background: var(--bad-soft); }
.st-chip.calm { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--accent-soft); }

/* step 2: every host stays on the list, the ones that cannot take it say why */
.pick-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.pick-bar select { min-width: 200px; }
.pick-bar .pick-all { margin-left: auto; }
.pick-list { display: flex; flex-direction: column; gap: 6px; max-height: 360px; overflow-y: auto; padding-right: 4px; }
.pick-row {
  display: flex; align-items: center; gap: 11px; padding: 9px 14px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg-raise);
}
.pick-row:hover { border-color: var(--line-strong); }
.pick-row input { accent-color: var(--accent); flex: none; }
.pick-row.on { border-color: var(--accent); background: var(--accent-soft); }
.pick-row.off { opacity: .5; cursor: default; }
.pick-name { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px; }
.pick-name strong { font-size: 13px; font-weight: 600; }
.pick-name span { font-size: 11px; color: var(--muted); }

/* step 3: hosts down the left, that host's whole canvas on the right */
.wire-split { display: grid; grid-template-columns: 236px minmax(0, 1fr); gap: 16px; align-items: start; }
.wire-hosts { display: flex; flex-direction: column; gap: 3px; }
.wire-host {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; cursor: pointer;
  padding: 10px 12px; border: 1px solid transparent; border-radius: 10px;
  background: none; color: var(--text); font-size: 13px;
}
.wire-host:hover { background: var(--bg-raise); }
.wire-host.sel { border-color: var(--accent); background: var(--accent-soft); }
.wire-host.skipped { opacity: .45; }
.wire-host .wh-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wire-skip {
  display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted);
  margin-left: auto; white-space: nowrap;
}
.wire-canvas .net-canvas-wrap { height: 500px; }
/* The per-host plan strip in the wizard's wiring step: what lands here, what
   cannot (with the reason in the open), what already matches. */
.wire-plan { margin: 0 0 10px; padding: 8px 12px; border: 1px solid var(--line, #e4e0d8); border-radius: 8px;
  display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.wire-plan .wp-do::before { content: "→ "; color: var(--accent); }
.wire-plan .wp-vm { color: var(--warn-fg, #8a5a00); }
.wire-plan .wp-vm::before { content: "⚡ "; }
.wire-plan .wp-skip { color: var(--warn-fg, #8a5a00); }
.wire-plan .wp-skip::before { content: "▲ "; }
.wire-plan .wp-ok { color: var(--muted, #8a857c); }
.wire-plan .wp-ok::before { content: "✓ "; }
.wire-ack { font-size: 12px; color: var(--warn-fg, #8a5a00); margin-right: auto; }

.wire-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-bottom: 10px; }
.wire-bar strong { font-size: 13.5px; }

/* step 4: one row per host, and what is still waiting on a restart */
.apply-board { display: flex; flex-direction: column; gap: 8px; }
.ab-row { border: 1px solid var(--line); border-radius: 10px; background: var(--bg-raise); padding: 12px 15px; }
.ab-head { display: flex; align-items: center; gap: 10px; }
.ab-head strong { font-size: 13.5px; }
.ab-head .ab-job { margin-left: auto; font-size: 11px; color: var(--faint); }
.ab-detail { margin-top: 8px; font-size: 12.5px; }
.ab-detail .na-list { margin-top: 3px; }

/* a VM whose wiring is written but not yet live */
.pend-chip {
  display: inline-flex; align-items: center; gap: 4px; cursor: help;
  font-size: 9.5px; padding: 2px 8px; border-radius: 999px;
  color: var(--warn); background: var(--warn-soft);
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  text-transform: uppercase; letter-spacing: .06em;
}
.vm-head .vm-restart {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg-raise); color: var(--muted); border: 1px solid var(--line-strong);
  border-radius: 6px; padding: 2px 9px; font-size: 11px; cursor: pointer;
}
.vm-head .vm-restart:hover { border-color: var(--warn); color: var(--warn); background: var(--warn-soft); }

/* canvas additions: template slots, staged VM moves, per-object validation */
.net-node .net-vmpend { fill: var(--warn); font-size: 9.5px; font-weight: 650; letter-spacing: .06em; }
.net-node .net-vmrow.moved, .net-node .net-vmtap.moved { fill: var(--accent); }
.net-node.err rect { stroke: var(--bad); stroke-width: 2; }
.net-edge.ne-tap.moved { stroke: var(--accent); stroke-width: 2; }
.net-vmhandle { fill: var(--card); stroke: var(--pine); stroke-width: 1.6; cursor: grab; }
.net-vmhandle:hover { r: 6.5; fill: var(--pine); }

/* the detail panel edits the template in place — a modal per property would put
   four dialogs between an operator and one bridge */
.nd-form { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.nd-form label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--muted); }
.nd-form input, .nd-form select { width: 100%; font-size: 12.5px; padding: 6px 9px; }
.nd-form .nd-check { flex-direction: row; align-items: center; gap: 8px; color: var(--text); font-size: 12px; }
.nd-form .nd-check input { width: auto; accent-color: var(--accent); }
.nd-members { display: flex; flex-direction: column; gap: 5px; }
.nd-members label { flex-direction: row; align-items: center; gap: 7px; color: var(--text); font-size: 12px; }
.nd-members input { width: auto; accent-color: var(--accent); }
.nd-form .pend-chip { align-self: flex-start; }
.nd-err {
  font-size: 11.5px; color: var(--bad); background: var(--bad-soft); line-height: 1.45;
  border: 1px solid color-mix(in srgb, var(--bad) 40%, transparent);
  border-radius: 8px; padding: 8px 10px; margin-bottom: 10px;
}
.tpl-empty { padding: 40px 0; text-align: center; color: var(--muted); font-size: 13px; }

@media (max-width: 900px) {
  .wire-split { grid-template-columns: minmax(0, 1fr); }
  .wire-hosts { flex-direction: row; overflow-x: auto; padding-bottom: 4px; }
  .wire-host { width: auto; flex: none; }
}

/* ---- Start-VM wizard ---- */
.vmwiz-modal { width: min(92vw, max(70vw, 720px)); max-height: 88vh; overflow-y: auto; }
.vmwiz-steps { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 14px; font-size: 12.5px; }
.vmw-step { color: var(--muted); padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); }
.vmw-step.cur { color: var(--fg); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.vmw-step.done { color: var(--accent); }
.vmw-sep { color: var(--muted); }
.vmw-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px; }
.vmw-shape { margin-top: 4px; }
#vmwiz .field { margin-top: 12px; }
#vmwiz .field label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 5px; }
#vmwiz select, #vmwiz input { width: 100%; margin-top: 0; padding: 9px 11px; border-radius: 9px; box-sizing: border-box; }
.vmw-cap { margin: 12px 0 0; font-size: 12.5px; }
.vmw-img { margin-top: 0; }
.vmw-mode { display: flex; gap: 6px; }
.vmw-mode-btn { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--line); background: transparent; color: var(--muted); cursor: pointer; }
.vmw-mode-btn.active { color: var(--fg); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.vmw-nic { margin-top: 8px; }
.vmw-warn { font-size: 12.5px; }
.vmw-review { width: 100%; border-collapse: collapse; }
.vmw-review th { text-align: left; color: var(--muted); font-weight: 500; padding: 6px 14px 6px 0; white-space: nowrap; vertical-align: top; }
.vmw-review td { padding: 6px 0; }
.vmw-day0-note { font-size: 12.5px; color: var(--muted); }
#vmwiz textarea { width: 100%; font-family: var(--mono, ui-monospace, monospace); font-size: 12px; resize: vertical; }
.host-images-table { width: 100%; }
.host-images-table td, .host-images-table th { padding: 6px 10px; }
button.vm-start { padding: 5px 12px; }
.modal-actions .grow { flex: 1; }

.net-port-tag { fill: var(--muted); font-size: 11px; }
.camp-host[hidden] { display: none; }
.host-picker .camp-host input[type="checkbox"] { width: auto; flex: 0 0 auto; margin: 0; }
.host-picker .camp-host-site { margin-left: auto; }
.host-picker-bar input[type="checkbox"] { width: auto; margin: 0; }
.camp-host-agent { margin-left: auto; display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.camp-host-agent button { padding: 4px 10px; font-size: 12px; }

.nd-vlan { margin: 12px 0; }
.nd-vlan h5 { font-size: 12.5px; margin-bottom: 6px; color: var(--muted); }
.nd-vlan-row { display: flex; align-items: center; gap: 6px; margin: 4px 0; font-size: 12.5px; flex-wrap: wrap; }
.nd-vlan-row input, .nd-vlan-row select { padding: 3px 6px; font-size: 12px; width: auto; }
.nd-vlan-row .hidden { display: none; }
.net-row .net-vlanids, .net-row .net-vlannative { width: 70px; }
.net-row select.net-vlanmode { width: auto; }
.net-vmqueued { fill: var(--warn, #e0a52a); }
.net-vmvlan { fill: var(--accent); }

/* ============================================================
   Console-skin harmonization (redesign 2026-09-01)
   Everything below re-tunes the components defined above to the
   jina-style console language: sharp corners, 1px var(--line)
   borders, flat surfaces, mono accents, cyan hover. It sits at
   the end of the sheet so it wins the cascade at equal
   specificity — the functional rules above stay untouched.
   ============================================================ */

/* sharp corners everywhere a box was rounded (dots/switches stay round) */
.panel, .modal-card, .drawer, .toast, .hint-pop, .console-frame, .wizard-frame,
.host-card, .camp-card, .tpm-box, .host-picker, .pick-row, .wire-host, .ab-row,
.token-value, .view-toggle, .view-toggle button, .ghost-btn, .vm-actions button,
.pend-bar button, .net-toolbar button, .net-canvas-wrap, .net-detail, .net-review,
.net-apply, #fleet-map-wrap, .map-panel, .mp-vm, .map-open-host, .cmap-ctl button,
.cmap-fallback-note, .cmap-attr, .map-pin .pin-label, .map-legend, .guide-tabs button,
.guide-pane code, .user-add button[type="submit"], .bp-grid button[type="submit"],
#users-table button, #nettpl-table button, #nettpl-table a.tpl-open, #waves-table button,
button.snap-del, .modal-actions button, .state, .st-chip, .pend-chip, .dep-step,
.vm-head .vm-restart, .link-btn, .tpl-acts button, .step-foot button, .wire-plan,
input, select, textarea, #wiz-day0, #deploy-modal textarea, .mini-bar, .drawer-row,
.soon, .disk-warn, .disk-crit, .badge, .badge-org, .vmw-step, .vmw-mode-btn,
#nr-apply, .net-detail .net-del, #wiz-next, #wiz-start, #wiz-abort,
#wiz-board button.dep-retry, .step-rail .step-n, .search-card, .console-foot code {
  border-radius: 7px;
}
.theme-btn, .switch-track, .switch-track::after, .dot, .status-dot i, .hint,
.map-pin .pin-dot { /* deliberately round */ }

/* flat boxed surfaces */
.panel {
  background: var(--card); border: 1px solid var(--line); box-shadow: none;
  padding: 4px 16px 8px;
}
.host-card, .camp-card, .tpm-box, .ab-row, .pick-row { background: var(--card); box-shadow: none; }
.modal-card, .drawer, .console-frame, .wizard-frame, .net-detail, .map-panel, .toast, .hint-pop {
  background: var(--panel); border-color: var(--line); box-shadow: var(--shadow-pop);
}

/* tables in the demo voice: mono TH, roomier cells, hover wash */
th {
  padding: 11px 12px 9px; color: var(--faint); font-size: 10.5px;
  letter-spacing: .12em; font-weight: 600; font-family: var(--mono);
  border-bottom: 1px solid var(--line); background: var(--card);
}
td { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); }
tbody tr:hover td { background: var(--hover); }
table { font-size: 13px; }
table.density-compact td { padding: 5px 12px; }
table.density-comfy td { padding: 10px 12px; }
table.density-spacious td { padding: 14px 12px; }
#fleet-table th.sortable[data-dir="asc"]::after { content: " ↑"; color: var(--cyan); }
#fleet-table th.sortable[data-dir="desc"]::after { content: " ↓"; color: var(--cyan); }
#fleet-table tr.host-row:hover td { background: var(--hover); }
#fleet-table .row-open { text-align: right; white-space: nowrap; padding-right: 16px; }

/* the status vocabulary keeps its dot, tuned to the demo weight */
.st-ok, .st-done, .st-failed, .st-denied, .st-pending, .st-delivered, .st-requested {
  font-size: 11.5px; font-weight: 650; letter-spacing: .05em;
}

/* action buttons speak in the row-btn voice: mono caps, cyan hover */
.vm-actions button, .pend-bar button, .net-toolbar button, #users-table button,
#nettpl-table button, #nettpl-table a.tpl-open, #waves-table button, button.snap-del,
.tpl-acts button, .step-foot button, .vm-head .vm-restart, #wiz-board button.dep-retry,
.guide-tabs button, button.vm-start, .agent-upd, .helper-upd {
  background: none; border: 1px solid var(--line); color: var(--muted);
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}
.vm-actions button:hover, .pend-bar button:hover:not(:disabled), .net-toolbar button:hover,
#users-table button:hover, #nettpl-table button:hover, #nettpl-table a.tpl-open:hover,
#waves-table button:hover, .tpl-acts button:hover:not(:disabled),
.step-foot button:hover:not(:disabled), #wiz-board button.dep-retry:hover,
.guide-tabs button:hover, button.vm-start:hover, .agent-upd:hover:not(:disabled), .helper-upd:hover {
  color: var(--cyan); border-color: var(--cyan); background: none;
}
.vm-actions button.danger:hover, .pend-bar button.danger-quiet:hover:not(:disabled),
button.snap-del:hover, .tpl-acts button.danger:hover:not(:disabled),
#nettpl-table button.danger:hover, #waves-table button.danger:hover {
  color: var(--bad); border-color: var(--bad); background: var(--bad-soft);
}
.vm-actions button.console-open, .btn-console {
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: var(--accent-soft); font-weight: 650;
}
.vm-actions button.console-open:hover, .btn-console:hover {
  color: var(--accent-hi); border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}
/* primary actions stay the Canopy orange CTA */
.user-add button[type="submit"], .bp-grid button[type="submit"], #modal-ok, #addr-ok,
#res-ok, #hw-save, #media-ok, #deploy-ok, #nr-apply, #wiz-next, #wiz-start,
.tpl-acts button.primary, .step-foot button.primary, .map-open-host {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  font-weight: 700; letter-spacing: .02em;
}

/* view toggle in the demo voice */
.view-toggle { background: none; border: 1px solid var(--line); padding: 0; gap: 0; }
.view-toggle button {
  padding: 6px 16px; font-size: 11px; letter-spacing: .1em; font-family: var(--mono);
  text-transform: uppercase; color: var(--muted); border-left: 1px solid var(--line);
  background: none; font-weight: 600;
}
.view-toggle button:first-child { border-left: 0; }
.view-toggle button.active { color: var(--cyan); background: var(--cyan-dim); box-shadow: none; }

/* section titles read like the demo's // labels */
.section-title, .trend-label, .mp-sec, .drawer-sec h4 {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint); font-weight: 600;
}
.section-title { margin-top: 18px; }

/* host page voice */
.host-detail-head h2 { font-size: 16px; }
.back-btn {
  border: 1px solid var(--line); color: var(--muted); padding: 6px 14px;
  font-size: 11px; font-family: var(--mono); letter-spacing: .08em; text-transform: uppercase;
}
.back-btn:hover { color: var(--cyan); border-color: var(--cyan); }
.host-tabs { border-bottom: 1px solid var(--line); }
.host-tabs button {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
}
.host-tabs button.active { color: var(--cyan); border-bottom-color: var(--cyan); }
.vm-name, .camp-host-name { font-family: var(--mono); font-weight: 650; font-size: 12.5px; }
.host-images-table td { font-size: 12.5px; }

/* gauges: ticks in mono (value arc already rides --pine → cyan) */
.gauge .g-ticknum { font-family: var(--mono); }
.gauge .g-needle circle { fill: var(--bg-raise); }
.spark polyline { stroke: var(--accent); }

/* switches flip cyan like the demo */
.switch input:checked + .switch-track { background: var(--cyan); }
.switch-track::after { background: var(--panel); }

/* map furniture */
.map-pin .pin-dot { border-color: var(--pin-ring); box-shadow: 0 0 10px var(--ok); }
.map-pin.warn .pin-dot { box-shadow: 0 0 10px var(--warn); }
.map-pin.off .pin-dot { box-shadow: 0 0 10px var(--bad); }
.map-pin.selected .pin-dot { outline: 2px solid var(--cyan); outline-offset: 2px; }
.map-pin .pin-label { font-family: var(--mono); font-size: 10px; background: var(--bg-raise); box-shadow: none; }
.map-legend { font-family: var(--mono); font-size: 10.5px; background: var(--bg-raise); box-shadow: none; }
.cmap-ctl button { background: var(--bg-raise); box-shadow: none; }
.cmap-ctl button:hover { border-color: var(--cyan); color: var(--cyan); }
.cmap-fallback-note { font-family: var(--mono); font-size: 10.5px; background: var(--bg-raise); }
:root[data-theme="dark"] .cmap-tiles img {
  filter: invert(1) hue-rotate(180deg) saturate(.22) brightness(.75) contrast(.95);
}
.mp-vm { background: var(--card); border-color: var(--line-soft); }
.mp-vm .vm-name { font-family: var(--mono); font-size: 11.5px; font-weight: 400; }

/* misc chips + labels */
.state, .st-chip, .pend-chip, .dep-step { font-family: var(--mono); border-radius: 6px; }
.badge-org {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--accent);
}
.mono-sub { font-family: var(--mono); font-size: 10.5px; }
.tip-wrap::after { border-radius: 7px; box-shadow: var(--shadow-pop); }
.host-picker { border-radius: 8px; } .host-picker-bar { border-radius: 8px 8px 0 0; }
.hw-bar .hw-link {
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  display: inline-flex; align-items: center; padding: 5px 11px; border: 1px solid var(--line-strong);
  border-radius: 7px; background: var(--bg-raise); color: var(--text); text-decoration: none;
}
.hw-bar .hw-link:hover { border-color: var(--cyan); color: var(--cyan); }
.link-btn { color: var(--cyan); }

/* network studio on the console surfaces */
.net-canvas-wrap { background: var(--card); }
.net-node rect { fill: var(--bg-raise); }
.nk-vm rect { fill: var(--panel); }
.net-edge.ne-tap { stroke: var(--pine); }
.net-handle { stroke: var(--panel); }

/* the fleet loading placeholder */
#hosts:empty::before { border-radius: 10px; font-family: var(--mono); font-size: 12px; letter-spacing: .06em; }
.panel:has(tbody:empty)::after {
  font-family: var(--mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}

/* narrow screens: the tab groups scroll sideways; the utilbar wraps */
@media (max-width: 900px) {
  main { padding: 16px; }
  .map-panel { width: min(300px, 88%); }
  .utilbar { flex-wrap: wrap; }
  #conn-summary { display: none; }
}

/* Inline field validation (users form, modal input): the field is marked and
   the message sits under it; the form or dialog stays open. */
.field { display: inline-flex; flex-direction: column; gap: 4px; }
input.invalid, .modal-card input.invalid { border-color: var(--bad) !important; box-shadow: 0 0 0 2px color-mix(in srgb, var(--bad) 25%, transparent); outline: none; }
.field-err { color: var(--bad); font-size: 12px; line-height: 1.3; }
.modal-card #modal-err { margin: 6px 0 0; }
.host-links .host-console-open { display: inline-flex; align-items: center; gap: 5px; }

/* /console.html — the popped-out console: one session filling the window. */
body.popout-page { margin: 0; background: var(--bg); overflow: hidden; }
body.popout-page .console-overlay { padding: 0; background: var(--bg); backdrop-filter: none; }

/* Bond member role: badge on the port, wire style into the bond. */
.net-role rect { fill: var(--bg-raise); stroke: var(--line-strong); stroke-width: 1; }
.net-role text { font-size: 9px; font-weight: 700; letter-spacing: .04em; fill: var(--muted); }
.net-role-active rect { fill: color-mix(in srgb, var(--ok) 18%, var(--bg-raise)); stroke: color-mix(in srgb, var(--ok) 60%, var(--line-strong)); }
.net-role-active text { fill: var(--ok); }
.net-role-lacp rect { stroke: color-mix(in srgb, var(--accent) 50%, var(--line-strong)); }
.net-role-lacp text { fill: var(--accent); }
.net-edge.ne-member.active { stroke: color-mix(in srgb, var(--ok) 60%, var(--line-strong)); stroke-width: 2; }
.net-edge.ne-member.standby { stroke-dasharray: 4 3; opacity: .7; }

/* Held host (serial changed, 2026-09-05): one banner on the host page, above
   the tabs, so the decision it asks for is the first thing on the screen. */
.held-banner { border-left: 3px solid var(--bad, #c0392b); margin: 12px 0; }
.held-banner p { margin: 6px 0; }
.held-banner .row-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* Fleet update settings (Updates tab, 2026-09-05): one box under the split. */
.upd-settings { margin-top: 16px; max-width: 720px; }
.upd-settings select, .upd-settings input[type="text"] { width: 100%; }

/* ===== redesign additions (Updates tab, Jobs drawer, grouped Jobs) — 2026-09-05 ===== */
.sel-actions { display: flex; align-items: center; gap: 12px; margin: 4px 0 10px; flex-wrap: wrap; }
.sel-actions .sel-count { font-family: var(--mono); font-size: 11.5px; color: var(--faint); }
.sel-actions input[type=search] { min-width: 260px; }
.actions-menu { position: relative; margin-left: auto; }
.actions-btn { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border: 1px solid var(--line); background: var(--card); color: var(--text); font: inherit; font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; cursor: pointer; }
.actions-btn:hover { border-color: var(--cyan); color: var(--cyan); }
.actions-list { position: absolute; right: 0; top: calc(100% + 4px); min-width: 360px; white-space: nowrap; background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow); z-index: 20; padding: 6px 0; }
.actions-list button { display: flex; width: 100%; align-items: center; gap: 10px; padding: 9px 14px; background: none; border: 0; color: var(--text); font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.actions-list button:hover { background: var(--hover); color: var(--cyan); }
.actions-list button[disabled] { color: var(--faint); cursor: default; }
.actions-list button .k { margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--faint); }
.actions-list .sep { border-top: 1px solid var(--line-soft); margin: 6px 0; }
.upd-table th, .upd-table td { white-space: nowrap; }
.upd-table td.sel, .upd-table th.sel { width: 32px; }
.pill { display: inline-block; padding: 2px 8px; border: 1px solid var(--line); font-family: var(--mono); font-size: 11px; }
.pill.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: var(--ok-soft); }
.pill.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); }
.pill.bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 55%, transparent); background: var(--bad-soft); }
.pill.muted { color: var(--faint); }
/* jobs drawer (top-right icon) */
.jobs-badge { position: absolute; top: -4px; right: -4px; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 8px; background: var(--warn); color: #111; font: 700 10px/15px var(--mono); text-align: center; }
#jobs-open { position: relative; }
#jobs-open.active { color: var(--cyan); border-color: var(--cyan); }
.jdrawer-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 40; }
.jdrawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(520px, 94vw); background: var(--bg, #0e1114); border-left: 1px solid var(--line); z-index: 41; display: flex; flex-direction: column; box-shadow: var(--shadow); }
.jdrawer-head { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--line); }
.jdrawer-head h2 { font-size: 16px; font-weight: 650; }
.jdrawer-head .close { margin-left: auto; }
.jdrawer-tabs { display: flex; gap: 0; padding: 0 18px; border-bottom: 1px solid var(--line); }
.jdrawer-tabs button { background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted); padding: 10px 12px; font: inherit; font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; cursor: pointer; }
.jdrawer-tabs button.active { color: var(--cyan); border-bottom-color: var(--cyan); }
.jdrawer-body { padding: 12px 18px; overflow: auto; display: flex; flex-direction: column; gap: 10px; }
.jdrawer-meta { font-family: var(--mono); font-size: 11px; color: var(--faint); display: flex; gap: 12px; align-items: center; }
.job-card { border: 1px solid var(--line); background: var(--card); padding: 12px 14px; cursor: pointer; }
.job-card:hover { border-color: var(--cyan); }
.job-card .jc-head { display: flex; align-items: center; gap: 10px; }
.job-card .jc-head strong { font-size: 13.5px; }
.job-card .jc-head .meta { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--faint); }
.job-card .jc-sub { font-family: var(--mono); font-size: 11px; color: var(--muted); margin-top: 6px; }
.job-card .prog { padding: 8px 0 0; }
/* job group page */
.job-page-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.job-page-head h2 { font-size: 18px; font-weight: 650; }
.job-page-head .meta { font-family: var(--mono); font-size: 11.5px; color: var(--faint); }
.job-page-head .btns { margin-left: auto; display: flex; gap: 8px; }
.kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px 18px; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
.kv div { font-size: 12.5px; }
.kv .k { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--faint); letter-spacing: .08em; text-transform: uppercase; }
.log-link { font-family: var(--mono); font-size: 11px; color: var(--cyan); }
/* grouped jobs tab */
.jobs-groups .grp { border: 1px solid var(--line); background: var(--card); margin-bottom: 10px; }
.jobs-groups .grp-head { display: grid; grid-template-columns: 22px minmax(0,1fr) 150px 130px 120px 120px; gap: 10px; align-items: center; padding: 10px 14px; cursor: pointer; font-size: 13px; }
.jobs-groups .grp-head:hover { background: var(--hover); }
.jobs-groups .grp-head a { color: inherit; text-decoration: none; }
.jobs-groups .grp-head a:hover strong { color: var(--cyan); }
.jobs-groups .grp-head .caret { color: var(--faint); font-size: 12px; }
.jobs-groups .grp-head .kind { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.jobs-groups .grp-rows { border-top: 1px solid var(--line-soft); padding: 4px 0 6px; }
.jobs-groups .grp-row { display: grid; grid-template-columns: 22px minmax(0,1fr) 150px 130px 120px 120px; gap: 10px; padding: 6px 14px 6px 36px; font-size: 12.5px; align-items: center; }
.jobs-groups .grp-row .detail { font-family: var(--mono); font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jobs-groups .grp.single .grp-head { cursor: default; }
.jobs-filter { display: flex; gap: 8px; align-items: center; margin: 4px 0 12px; flex-wrap: wrap; }
/* wizard */
.wizard { max-width: 760px; }
.wiz-steps { padding: 4px 16px 0; border-bottom: 1px solid var(--line-soft); }
.wiz-steps .step-rail { margin: 10px 0 12px; flex-wrap: nowrap; }
.wiz-steps .step-rail button { width: auto; flex: none; white-space: nowrap; opacity: 1; }
#upd-wizard .wiz-body { padding: 16px; display: flex; flex-direction: column; gap: 14px; }
#upd-wizard .wiz-foot { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 16px; border-top: 1px solid var(--line-soft); }
.host-chips { display: flex; flex-wrap: wrap; gap: 6px; }
#upd-modal .modal-card p { font-size: 13px; color: var(--muted); }

/* rounded corners across the console: panels, tables, tabs, chips, inputs */
.panel, .form-box, .card, .camp, .grp, .job-card, .tpm-box, .held-banner,
.wizard, .actions-list, .guide-code, .drawer-card, .empty { border-radius: 10px; }
.modal-card, .search-card, .console-frame, .wizard-frame { border-radius: 12px; }
.jdrawer { border-radius: 14px 0 0 14px; }
table thead th:first-child { border-top-left-radius: 8px; }
table thead th:last-child { border-top-right-radius: 8px; }
.icon-btn, .actions-btn, .back-btn, .cta, .row-btn,
.actions-list button, button, .camp-host { border-radius: 7px; }
/* top tab bar: floating pills, not full-height fills */
.tabs, .nav-sect, .nav-sub, .nav-list, .tabbar-right { align-items: center; }
.tabs { gap: 3px; padding: 0 8px; }
.nav-list { gap: 3px; }
.nav-group, .nav-item { height: 36px; border-radius: 8px; }
.nav-group { border-right: 0; margin-right: 3px; }
.nav-group.open { box-shadow: none; background: rgba(240, 148, 31, .1); }
.nav-item.active { border-radius: 8px; }
.tab-ink { display: none; }
.tab-logo { border-right: 0; }
.nav-sect.open .nav-sub { padding-right: 6px; border-right: 1px solid var(--line-soft); margin-right: 3px; }
.view-toggle { border-radius: 7px; overflow: hidden; }
.view-toggle button { border-radius: 0; }
.jdrawer-tabs button, .host-tabs button { border-radius: 7px 7px 0 0; }
.badge, .chip, .pill, .user-chip { border-radius: 6px; }
.prog i { border-radius: 2px; }
.switch-track { border-radius: 999px; } .switch-track::after { border-radius: 50%; }
.dot, .status-dot i { border-radius: 50%; }
/* images: host-picker wizard */
#iw-hosts { max-height: 340px; overflow: auto; display: flex; flex-direction: column; gap: 6px; padding-right: 4px; }
.iw-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line-soft); border-radius: 8px; cursor: pointer; font-size: 13px; }
.iw-row:hover { background: var(--hover); }
.iw-row.dis { opacity: .55; cursor: default; }
.iw-row.dis:hover { background: none; }
.iw-row .muted { margin-left: auto; font-family: var(--mono); font-size: 11px; }
.iw-listhead { display: flex; align-items: center; gap: 14px; font-size: 13px; }
.iw-listhead .muted { font-family: var(--mono); font-size: 11px; }
.img-acts { display: inline-flex; gap: 8px; }

/* A/B OS slots (2026-09-13, design 9.6): the Operating system panel on the
   host page, the trial banner above the tabs, the fleet pill, the library
   kind chips and the one-choice select in the shared modal. */
/* The OS line on a host page: slot A | slot B, states only (2026-09-15). */
.os-strip { display: grid; grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; column-gap: 14px; border-top: 1px dashed var(--line); padding: 10px 4px 4px; font-size: 12.5px; }
.os-strip-k { font-family: var(--mono); font-size: 10.5px; color: var(--faint); letter-spacing: .08em; text-transform: uppercase; }
.os-cell { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; overflow: hidden; }
.os-cell > span { flex: 0 0 auto; }
.os-cell .os-cell-detail { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.os-cell-name { font-family: var(--mono); font-weight: 700; }
.os-cell.booted .os-cell-name { color: var(--ok); }
.os-cell-detail { font-size: 11.5px; }
.os-sep { display: inline-block; width: 1px; align-self: stretch; min-height: 18px; background: var(--line-strong, var(--line)); }
.os-cell-note { font-size: 11.5px; grid-column: 1 / -1; padding-top: 4px; }
.os-strip .os-cell { max-width: none; }   /* the Updates-page cap above must not clip the host line */
.os-slot-pills { white-space: nowrap; }
.ow-images { display: grid; gap: 8px; }
.ow-image { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; line-height: 1.5; border: 1px solid var(--line); border-radius: 9px; font-size: 12.5px; cursor: pointer; }
.ow-image:hover { border-color: var(--line-strong); }
.ow-image.off { opacity: .6; cursor: not-allowed; }
#ow-next.danger { background: var(--bad); }
.ow-image:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.ow-image input[type="radio"] { width: auto; flex: 0 0 auto; margin: 3px 0 0; padding: 0; accent-color: var(--accent); }
.ow-image > span { flex: 1; min-width: 0; display: grid; }
.ow-image-detail { font-size: 11.5px; }
.ow-keep { display: flex; gap: 14px; font-size: 12.5px; white-space: nowrap; }
.ow-keep label { display: flex; align-items: center; gap: 5px; cursor: pointer; }
.ow-keep input { width: auto; margin: 0; accent-color: var(--accent); }
.os-review { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 12.5px; }
.os-review th { text-align: left; font-family: var(--mono); font-size: 10.5px; color: var(--faint); letter-spacing: .08em; text-transform: uppercase; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.os-review td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.os-review tr.skip td { opacity: .7; }
.os-panel .os-slots { margin-top: 10px; display: grid; gap: 6px; }
.os-slot { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-size: 12.5px; }
.os-slot-name { font-family: var(--mono); font-weight: 700; min-width: 14px; }
.os-slot-detail { font-size: 11.5px; }
.os-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.os-actions button[disabled] { opacity: .55; cursor: not-allowed; }
.os-trial-banner { border-left: 3px solid var(--warn); margin: 12px 0; }
.os-trial-banner p { margin: 6px 0; }
.os-trial-banner .row-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.os-trial-banner.bad { border-left-color: var(--bad); }
.os-trial-banner.calm { border-left-color: var(--muted); }
.os-pill { margin-left: 8px; font-size: 11px; }
.os-ab-note { font-size: 11.5px; margin: 6px 0 0; }
.img-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
.img-chip { background: none; border: 1px solid var(--line); color: var(--muted); font: inherit; font-size: 12px; padding: 4px 10px; border-radius: 999px; cursor: pointer; }
.img-chip .k { font-family: var(--mono); font-size: 10.5px; margin-left: 4px; color: var(--faint); }
.img-chip:hover { color: var(--cyan); border-color: var(--cyan); }
.img-chip.active { color: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 35%, transparent); background: var(--cyan-dim); }
#img-kind { min-width: 150px; }
#modal-select { display: block; width: 100%; margin-top: 14px; padding: 9px 11px; border-radius: 9px; }

/* per-host progress bar inside a job group row (2026-09-14) */
.prog.prog-row { margin-top: 4px; height: 4px; background: rgba(128,128,128,.25); border-radius: 2px; overflow: hidden; display: block; }
.prog.prog-row i { display: block; height: 100%; background: var(--accent, #d97706); }

/* New version served: one bar, one button, until the tab reloads. */
.ui-version-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 9px 16px; font-size: 13px;
  background: var(--accent); color: #111; box-shadow: var(--shadow-pop);
}
.ui-version-bar button { padding: 5px 12px; font-size: 12.5px; border-radius: 8px; border: 1px solid #111; background: #111; color: #fff; cursor: pointer; }
.ui-version-bar[hidden] { display: none; }

/* Images and Backups row actions in the waves-table voice: mono caps, slim,
   cyan hover, red hover for Delete (Mo, 2026-09-16). */
#images-table td button, #backups-table td button {
  background: none; border: 1px solid var(--line); color: var(--muted);
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  border-radius: 7px; padding: 3px 9px; margin-right: 4px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
}
#images-table td button:hover:not(:disabled), #backups-table td button:hover:not(:disabled) { color: var(--cyan); border-color: var(--cyan); background: none; }
#images-table td button.danger:hover:not(:disabled), #backups-table td button.danger:hover:not(:disabled) { color: var(--bad); border-color: var(--bad); background: var(--bad-soft); }
#images-table td button:disabled, #backups-table td button:disabled { opacity: .45; cursor: default; }
#images-table .img-acts { display: inline-flex; gap: 4px; white-space: nowrap; }

/* Page-level action buttons (Disk cleanup, Upload image, Build host OS image,
   Create wave, Fleet update settings, Actions): slimmer, and a tight group
   with a 6px gap so they read as one row of controls without touching. The
   Deployment waves / Pending hosts toggle is untouched. */
.sel-actions .actions-btn { padding: 6px 12px; font-size: 11.5px; border-radius: 7px; letter-spacing: .05em; gap: 6px; }
.sel-actions .actions-btn + .actions-btn,
.sel-actions .actions-btn + .actions-menu,
.sel-actions .actions-menu + .actions-btn { margin-left: -6px; }
.sel-actions .actions-menu .actions-btn { margin-left: 0; }
/* Hardware bar: same slim voice for Import CSV, Add hardware, Delete selected */
.hw-bar { gap: 6px; }
.hw-bar button, .hw-bar a.hw-link { padding: 5px 11px; font-size: 11px; border-radius: 7px; }
