/* vision-central — main app skin.
   Layered over default.handlebars + default3.handlebars DOM.
   Activates on body.vision (added inline on those views).
   Tokens come from tokens.css via custom.css.
   Phase 2: chrome + global primitives (color, type, inputs, buttons, links,
   dialogs, context menus, scrollbar). Per-screen polish is Phase 3.
*/

/* ─── Base ────────────────────────────────────────────────────────────── */
body.vision {
  background: var(--bg-0) !important;
  color: var(--text-1) !important;
  font-family: var(--font-sans) !important;
  font-size: 13px;
  line-height: 1.45;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'ss01', 'cv11';
  min-width: 0 !important;
}
body.vision * { box-sizing: border-box; }
@media (max-width: 768px) {
  body.vision { min-width: 0 !important; }
  body.vision #container { min-width: 0 !important; width: 100%; }
}

body.vision #container {
  background: var(--bg-1) !important;
  border-left: 1px solid var(--border-2) !important;
  border-right: 1px solid var(--border-2) !important;
  color: var(--text-1);
}

/* ─── Masthead ────────────────────────────────────────────────────────── */
body.vision #masthead {
  background: var(--bg-1) !important;
  background-image:
    radial-gradient(ellipse 60% 90% at 0% 50%, rgba(34,211,238,0.10), transparent 70%) !important;
  background-repeat: no-repeat !important;
  border-bottom: 1px solid var(--border-2);
  color: var(--text-0);
  height: 56px;
  display: flex !important;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  position: relative;
}
body.vision #masthead > div[style*="float:left"] {
  float: none !important;
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}
body.vision #masthead .title {
  color: var(--text-0) !important;
  font-family: var(--font-sans) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  letter-spacing: -0.025em;
  text-shadow: none !important;
  height: auto !important;
  line-height: 1 !important;
  padding: 0 !important;
  position: static !important;
  margin: 0;
  flex: 0 0 auto;
  cursor: pointer;
  /* center in the 56px bar — baseline-align pinned the wordmark to the
     cross-start edge (top), clipping it against the viewport top. */
  align-self: center;
}
body.vision #masthead .title2 {
  color: var(--text-2) !important;
  font-family: var(--font-sans) !important;
  font-size: 12px !important;
  font-weight: 400 !important;
  text-shadow: none !important;
  height: auto !important;
  line-height: 1 !important;
  padding: 0 !important;
  position: static !important;
  margin: 0 0 0 var(--space-2);
  /* center with the wordmark; baseline-align pushed the masthead content
     to the top edge of the bar (see .title note above). */
  align-self: center;
  flex: 0 0 auto;
}
body.vision #masthead > div[style*="float:right"] {
  float: none !important;
  margin-left: auto;
  order: 99;
}
body.vision #masthead #logoutControl {
  position: static !important;
  margin: 0 0 0 auto !important;
  padding: 0 !important;
  height: 56px;
  display: inline-flex !important;
  align-items: center;
  order: 90;
  color: var(--text-2);
  font-size: 12px;
  white-space: nowrap;
}
body.vision #masthead #logoutControl > span { margin-right: 8px; }
body.vision #masthead .textnewui {
  order: 95;
  margin: 0 8px 0 0 !important;
  align-self: center;
}
body.vision #masthead img { filter: brightness(1.1); }
body.vision #masthead p { color: var(--text-2); }
/* "Welcome <name>." — base style.css hardcodes color:white, invisible on the
   light masthead. Use a token that reads in both dark + light. */
body.vision .LogoffLinkColor { color: var(--text-2) !important; }
/* Dead UI-switcher diamond (&diams; in #uiMenuButton): the Modern UI was
   retired (classic only), so this menu has nothing to switch to. Hide it. */
body.vision #uiMenuButton,
body.vision #masthead .textnewui { display: none !important; }

/* ─── Topbar (main nav) ───────────────────────────────────────────────── */
body.vision #topbar {
  background: var(--bg-1) !important;
  border-bottom: 1px solid var(--border-2);
  color: var(--text-2);
}
body.vision #topbar a,
body.vision #topbar .topbar_td {
  color: var(--text-2) !important;
  font-weight: 500;
  font-family: var(--font-sans);
  transition: color .12s, background .12s;
}
body.vision #topbar a:hover,
body.vision #topbar .topbar_td:hover {
  color: var(--accent-2) !important;
  background: var(--bg-2) !important;
}
body.vision #topbar .topbar_td.topbar_td_sel,
body.vision #topbar .topbar_td_sel {
  color: var(--accent-2) !important;
  background: var(--bg-2) !important;
  border-bottom: 2px solid var(--accent) !important;
}
body.vision .logoncontrolspan,
body.vision .logoncontrolspan2 { color: var(--text-2) !important; }

/* ─── Left + right columns ────────────────────────────────────────────── */
body.vision #column_l,
body.vision #column_l_show,
body.vision #column_r {
  background: var(--bg-0) !important;
  color: var(--text-1);
}
body.vision #page_leftbar,
body.vision #page_content {
  background: var(--bg-0) !important;
  color: var(--text-1);
}

/* ─── Typography defaults ─────────────────────────────────────────────── */
body.vision h1, body.vision h2, body.vision h3, body.vision h4 {
  color: var(--text-0);
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: -0.02em;
}
body.vision h1 { font-size: 22px; }
body.vision h2 { font-size: 18px; }
body.vision h3 { font-size: 16px; }
body.vision h4 { font-size: 13px; }
body.vision strong, body.vision b { color: var(--text-0); font-weight: 600; }
body.vision hr {
  border: 0;
  border-top: 1px solid var(--border-2);
  margin: 12px 0;
}
body.vision code, body.vision pre, body.vision kbd, body.vision samp {
  font-family: var(--font-mono);
  font-size: 12px;
}

/* ─── Links ───────────────────────────────────────────────────────────── */
body.vision a {
  color: var(--accent-2);
  text-decoration: none;
  transition: color .12s;
}
body.vision a:hover { color: var(--accent); text-decoration: underline; }
body.vision a:visited { color: var(--accent-2); }
/* destructive links read as danger, not benign cyan */
body.vision a[onclick*="delete" i],
body.vision a[onclick*="removeDevice" i] { color: var(--danger) !important; }
body.vision a[onclick*="delete" i]:hover,
body.vision a[onclick*="removeDevice" i]:hover { color: var(--danger) !important; text-decoration: underline; }

/* ─── Inputs / selects / textareas ────────────────────────────────────── */
/* 63 <input> elements in the views ship with NO type attribute (HTML defaults
   them to text), so every `input[type=text]` rule missed them and they rendered
   with the browser's white box on the dark skin — most visibly inside dialogs
   (username, email, topic, device value…). `input:not([type])` covers them. */
body.vision input:not([type]),
body.vision input[type=text],
body.vision input[type=email],
body.vision input[type=password],
body.vision input[type=number],
body.vision input[type=search],
body.vision input[type=tel],
body.vision input[type=url],
body.vision textarea,
body.vision select {
  /* background-color (not the `background` shorthand) so a select's chevron
     background-image set by the toolbar rule isn't erased — gave the All
     filter an arrowless box. */
  background-color: var(--bg-4) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  font-family: var(--font-sans) !important;
  font-size: 13px;
  padding: 4px 8px;
  min-height: 28px;
  transition: border-color .12s, background .12s, box-shadow .12s;
  outline: none;
}
body.vision input:hover, body.vision textarea:hover, body.vision select:hover {
  /* background-color so the select chevron image survives hover too */
  background-color: var(--bg-5) !important;
}
body.vision input:focus,
body.vision textarea:focus,
body.vision select:focus {
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg);
}
body.vision input::placeholder { color: var(--text-3); }
/* Fully custom checkboxes/radios — native accent-color leaves an unthemed
   white box on dark surfaces. appearance:none + tokens themes both modes. */
body.vision input[type=checkbox],
body.vision input[type=radio] {
  appearance: none;
  -webkit-appearance: none;
  width: 15px;
  height: 15px;
  margin: 0 4px 0 0;
  vertical-align: middle;
  cursor: pointer;
  flex: 0 0 auto;
  position: relative;
  background: var(--bg-4);
  border: 1px solid var(--border-3);
  border-radius: var(--radius-1);
  transition: background-color .12s, border-color .12s;
}
body.vision input[type=radio] { border-radius: 50%; }
body.vision input[type=checkbox]:hover,
body.vision input[type=radio]:hover { border-color: var(--accent-border); }
body.vision input[type=checkbox]:checked,
body.vision input[type=radio]:checked {
  background: var(--accent);
  border-color: var(--accent);
}
body.vision input[type=checkbox]:checked::after {
  content: '';
  position: absolute;
  left: 4px; top: 1px;
  width: 4px; height: 8px;
  border: solid var(--accent-fg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
body.vision input[type=radio]:checked::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-fg);
  transform: translate(-50%, -50%);
}
body.vision input[type=checkbox]:focus-visible,
body.vision input[type=radio]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-border);
}
body.vision input[type=checkbox]:disabled,
body.vision input[type=radio]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── Buttons ─────────────────────────────────────────────────────────── */
body.vision input[type=button],
body.vision input[type=submit],
body.vision button {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  font-family: var(--font-sans) !important;
  font-size: 13px !important;
  font-weight: 500;
  padding: 0 12px;
  height: 30px;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease, transform .08s ease, box-shadow .14s ease;
}
body.vision input[type=button]:hover,
body.vision input[type=submit]:hover,
body.vision button:hover {
  background: var(--bg-4) !important;
  border-color: var(--border-4) !important;
}
body.vision input[type=button]:active,
body.vision input[type=submit]:active,
body.vision button:active {
  transform: translateY(1px);
  background: var(--bg-5) !important;
}
body.vision input[type=submit] {
  background: var(--accent) !important;
  color: var(--accent-fg) !important;
  border-color: var(--accent) !important;
  font-weight: 600;
  box-shadow: 0 1px 0 rgba(255,255,255,0.06) inset, 0 1px 2px rgba(0,0,0,0.25);
}
body.vision input[type=submit]:hover {
  background: var(--accent-2) !important;
  border-color: var(--accent-2) !important;
  box-shadow: var(--accent-glow);
}
body.vision input[type=submit]:active {
  background: var(--accent-deep) !important;
  border-color: var(--accent-deep) !important;
}
body.vision input:disabled, body.vision button:disabled {
  background: var(--bg-2) !important;
  color: var(--text-3) !important;
  border-color: var(--border-2) !important;
  cursor: not-allowed !important;
  opacity: 0.6;
  box-shadow: none !important;
  transform: none !important;
}

/* ─── Tables ──────────────────────────────────────────────────────────── */
body.vision table { color: var(--text-1); border-collapse: collapse; }
body.vision table.pTable td,
body.vision #xdevices td,
body.vision #xdevices th {
  color: var(--text-1);
  border-color: var(--border-2) !important;
}
body.vision #xdevices th {
  background: var(--bg-2) !important;
  color: var(--text-2) !important;
  font-weight: 500;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border-3) !important;
}
body.vision #xdevices tr:hover td { background: var(--bg-2) !important; }
body.vision tr.selected td,
body.vision .DeviceSel td { background: var(--accent-bg) !important; color: var(--text-0); }

/* ─── Generic data tables (User Authorizations + JS-built tables) ─────── */
body.vision #p10 table[border="0"],
body.vision #p11 table[border="0"],
body.vision #p12 table[border="0"],
body.vision #p2 table[border="0"],
body.vision #p4 table[border="0"],
body.vision #column_l table[border="0"],
body.vision #column_l_show table[border="0"] {
  background: var(--bg-2) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3);
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,0.3);
  margin: 12px 0;
}
body.vision #p10 table[border="0"] th,
body.vision #p11 table[border="0"] th,
body.vision #p12 table[border="0"] th,
body.vision #p2 table[border="0"] th,
body.vision #p4 table[border="0"] th,
body.vision #column_l table[border="0"] th,
body.vision #column_l_show table[border="0"] th {
  background: var(--bg-3) !important;
  color: var(--text-2) !important;
  font-weight: 500 !important;
  text-transform: uppercase;
  font-size: 12px !important;
  letter-spacing: 0.04em;
  text-align: left !important;
  padding: 8px 12px !important;
  border-bottom: 1px solid var(--border-3) !important;
}
body.vision #p10 table[border="0"] tr,
body.vision #p11 table[border="0"] tr,
body.vision #p12 table[border="0"] tr,
body.vision #p2 table[border="0"] tr,
body.vision #p4 table[border="0"] tr,
body.vision #column_l table[border="0"] tr,
body.vision #column_l_show table[border="0"] tr {
  border-bottom: 1px solid var(--border-2);
}
body.vision #p10 table[border="0"] td,
body.vision #p11 table[border="0"] td,
body.vision #p12 table[border="0"] td,
body.vision #p2 table[border="0"] td,
body.vision #p4 table[border="0"] td,
body.vision #column_l table[border="0"] td,
body.vision #column_l_show table[border="0"] td {
  padding: 8px 12px !important;
  border: 0 !important;
  color: var(--text-1) !important;
  background: transparent !important;
}
body.vision #p10 table[border="0"] tr:hover td,
body.vision #p11 table[border="0"] tr:hover td,
body.vision #p2 table[border="0"] tr:hover td,
body.vision #p4 table[border="0"] tr:hover td {
  background: var(--bg-3) !important;
}

/* ".pTable" wrapper class — same polish */
body.vision .pTable {
  width: 100%;
  border-collapse: collapse;
}
body.vision .pTable td,
body.vision .pTable th {
  color: var(--text-1);
  border-color: var(--border-2);
  padding: 8px 12px;
}
body.vision .pTable th {
  background: var(--bg-2);
  color: var(--text-2);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border-3);
}
body.vision .pTable tr:hover > td { background: var(--bg-2); }

/* Users page table (.p3usersTable has no border attr — never matched generic rules) */
body.vision .p3usersTable { width: 100%; border-collapse: collapse; }
body.vision .p3usersTable th {
  background: var(--bg-3) !important;
  color: var(--text-2) !important;
  font-weight: 500;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.04em;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-3);
}
body.vision .p3usersTable th:first-child { text-align: left !important; }
body.vision .p3usersTable th:nth-child(n+2) { text-align: center !important; }
body.vision .p3usersTable th:nth-child(2) { width: auto !important; min-width: 96px; white-space: nowrap; }
body.vision .p3usersTable td { padding: 8px 12px; color: var(--text-1); }
body.vision .p3usersTable td.userTableHeader {
  background: var(--bg-2);
  color: var(--text-2);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 8px 12px;
  border-top: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
}

/* "Empty state inside data table" — e.g. "No users with special device permissions" */
body.vision table[border="0"] td[colspan]:only-child {
  text-align: center;
  color: var(--text-2);
  padding: var(--space-6) var(--space-3) !important;
  font-style: italic;
}

/* ─── Rescue: low-contrast affordances on dark bg ────────────────────── */
/* View-mode selectors (Left bar / Top bar / Fixed width) — were #DDD@0.3 */
body.vision .viewSelector {
  background-color: var(--bg-3, #141c30) !important;
  opacity: 0.7 !important;
  border: 1px solid var(--border-2, rgba(255,255,255,0.07)) !important;
}
body.vision .viewSelector:hover {
  opacity: 1 !important;
  background-color: var(--bg-4, #1a2238) !important;
  border-color: var(--accent-border, rgba(34,211,238,0.35)) !important;
}
body.vision .viewSelectorSel {
  background-color: var(--accent-bg, rgba(34,211,238,0.10)) !important;
  border-color: var(--accent-border, rgba(34,211,238,0.35)) !important;
  opacity: 1 !important;
}

/* Trace event pills */
body.vision .traceEvent {
  background-color: var(--bg-3, #141c30) !important;
  color: var(--text-1, #cbd4e1) !important;
  border: 1px solid var(--border-2, rgba(255,255,255,0.07));
}
body.vision .traceEvent:hover {
  background-color: var(--bg-4, #1a2238) !important;
  border-color: var(--accent-border, rgba(34,211,238,0.35));
}

/* "info" and "warning" banners (yellow ribbons) */
body.vision .deskinfobox,
body.vision .infobox {
  background: var(--bg-2, #0f1524) !important;
  color: var(--text-1, #cbd4e1) !important;
  border: 1px solid var(--border-3, rgba(255,255,255,0.12)) !important;
  border-left: 3px solid var(--info, #818cf8) !important;
  border-radius: var(--radius-2, 6px) !important;
  padding: 8px 12px !important;
}
body.vision .warningbox {
  background: var(--warn-bg, rgba(251,191,36,0.12)) !important;
  color: var(--warn, #fbbf24) !important;
  border: 1px solid rgba(251,191,36,0.3) !important;
  border-radius: var(--radius-2, 6px);
  padding: 8px 12px;
}

/* Help/tooltip yellow → token muted */
body.vision .helpbox,
body.vision [style*="background-color:#FFC"],
body.vision [style*="background-color:#FFFFCC"],
body.vision [style*="background-color: #FFC"],
body.vision [style*="background-color: #FFFFCC"] {
  background-color: var(--warn-bg, rgba(251,191,36,0.12)) !important;
  color: var(--warn, #fbbf24) !important;
  border: 1px solid rgba(251,191,36,0.25) !important;
}

/* Yellow caplock/scrolllock/numlock JS-set bg */
body.vision [style*="background-color:#A3FFB8"] {
  background-color: var(--online-bg, rgba(52,211,153,0.12)) !important;
  color: var(--online, #34d399) !important;
}

/* Anything with literal style="background-color:white|#fff|#FFF|#EEE|#DDD" */
body.vision [style*="background-color:white"]:not(img),
body.vision [style*="background-color: white"]:not(img),
body.vision [style*="background-color:#fff"]:not(img),
body.vision [style*="background-color:#FFF"]:not(img),
body.vision [style*="background-color: #fff"]:not(img),
body.vision [style*="background-color: #FFF"]:not(img),
body.vision [style*="background-color:#EEE"]:not(img),
body.vision [style*="background-color: #EEE"]:not(img),
body.vision [style*="background-color:#DDD"]:not(img),
body.vision [style*="background-color: #DDD"]:not(img) {
  background-color: var(--bg-2, #0f1524) !important;
}

/* Black-on-light inline */
body.vision [style*="color:black"]:not(img),
body.vision [style*="color: black"]:not(img),
body.vision [style*="color:#000"]:not(img),
body.vision [style*="color: #000"]:not(img) {
  color: var(--text-1, #cbd4e1) !important;
}

/* Status pills / colored badges with hardcoded bgs */
body.vision [style*="background-color:#F0ECCD"] {
  background: var(--warn-bg, rgba(251,191,36,0.12)) !important;
  color: var(--warn, #fbbf24) !important;
}
body.vision [style*="background-color:#F5F5F5"],
body.vision [style*="background-color: #F5F5F5"] {
  background-color: var(--bg-1, #0a0e17) !important;
  color: var(--text-1, #cbd4e1) !important;
}

/* Cells/headers inside JS-built tables that still have inline lights */
body.vision tr[style*="background-color:#AAA"] {
  background-color: var(--bg-3, #141c30) !important;
}
body.vision tr[style*="background-color:#AAAAAA"] {
  background-color: var(--bg-3, #141c30) !important;
}

/* Buttons / pill controls in p11 desktop / p12 terminal toolbar */
body.vision .lbbutton2,
body.vision .nodeButton,
body.vision .pButton {
  background-color: var(--bg-3, #141c30) !important;
  color: var(--text-0, #f1f5fa) !important;
  border: 1px solid var(--border-3, rgba(255,255,255,0.12)) !important;
}
body.vision .lbbutton2:hover,
body.vision .nodeButton:hover,
body.vision .pButton:hover {
  background-color: var(--bg-4, #1a2238) !important;
  border-color: var(--accent-border, rgba(34,211,238,0.35)) !important;
}

/* hr inside dark cards */
body.vision hr { border-color: var(--border-2, rgba(255,255,255,0.07)); }

/* ─── Device tree (left pane) ─────────────────────────────────────────── */
body.vision .DeviceHeader,
body.vision .deviceBar,
body.vision .meshBar {
  background: var(--bg-1) !important;
  color: var(--text-1);
  border-color: var(--border-2) !important;
}
body.vision .DeviceHeader { border-bottom: 1px solid var(--border-2) !important; }
body.vision .deviceBar:hover,
body.vision .meshBar:hover { background: var(--bg-2) !important; }
body.vision .DeviceSel { background: var(--accent-bg) !important; }

/* ─── Context menus + popups ──────────────────────────────────────────── */
body.vision .contextMenu {
  background: var(--bg-2) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-3) !important;
  box-shadow: var(--shadow-pop) !important;
  padding: 4px !important;
  color: var(--text-1);
}
body.vision .contextMenu .cmtext {
  color: var(--text-1) !important;
  border-radius: var(--radius-1);
  padding: 8px 12px;
  transition: background .12s, color .12s;
}
body.vision .contextMenu .cmtext:hover {
  background: var(--bg-4) !important;
  color: var(--text-0) !important;
}

/* ─── Dialogs (Q-dialog system uses #dialog*) ─────────────────────────── */
body.vision #dialog,
body.vision #dialog2,
body.vision #dialog3,
body.vision #dialog4,
body.vision #dialog5,
body.vision #dialog6,
body.vision #dialog7 {
  background: var(--bg-2) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-4) !important;
  box-shadow: var(--shadow-pop) !important;
}
body.vision .dialogHeader,
body.vision #id_dialogTitle {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  border-bottom: 1px solid var(--border-2) !important;
  font-weight: 600;
  letter-spacing: -0.02em;
}
body.vision .dialogBody,
body.vision #id_dialogBody { background: var(--bg-2) !important; color: var(--text-1) !important; }
body.vision .dialogFooter { background: var(--bg-2) !important; border-top: 1px solid var(--border-2) !important; }

/* Modal background overlay */
body.vision #dialog_back, body.vision #cmdialog {
  background: rgba(0, 0, 0, 0.5) !important;
}

/* ─── Toolbars / panel headers ────────────────────────────────────────── */
body.vision #devListToolbar,
body.vision #devListToolbarSpan,
body.vision .pageHeader,
body.vision .p2nh {
  background: var(--bg-1) !important;
  color: var(--text-1);
  border-color: var(--border-2) !important;
}

/* Device-list / KVM / Map / Users toolbar action strips */
body.vision #devListToolbar,
body.vision #kvmListToolbar,
body.vision #devMapToolbar,
body.vision td.style14 {
  background: var(--bg-1) !important;
  padding: 12px 16px !important;
  border-radius: var(--radius-3);
  border: 1px solid var(--border-2);
}
body.vision #devListToolbar > *,
body.vision #kvmListToolbar > *,
body.vision td.style14 > * {
  vertical-align: middle;
  margin-right: 8px;
}
body.vision #devListToolbar > *:last-child,
body.vision #kvmListToolbar > *:last-child,
body.vision td.style14 > *:last-child { margin-right: 0; }

/* Buttons inside toolbars — uniform height, spacing */
body.vision #devListToolbar input[type=button],
body.vision #kvmListToolbar input[type=button],
body.vision td.style14 input[type=button],
body.vision td.style14 button {
  height: 30px;
  padding: 0 12px;
  font-size: 12px;
  vertical-align: middle;
  margin: 0;
}

/* Inputs inside toolbars */
body.vision #devListToolbar input[type=text],
body.vision #devListToolbar input[type=search],
body.vision #devListToolbar input[type=input],
body.vision #kvmListToolbar input[type=search],
body.vision td.style14 input[type=text],
body.vision td.style14 input[type=search],
body.vision td.style14 input[type=input] {
  height: 30px;
  padding: 0 8px;
  font-size: 12px;
  min-width: 160px;
  vertical-align: middle;
  margin: 0;
}

/* Selects (All/Online filter, Sort dropdown) */
body.vision #devListToolbar select,
body.vision #kvmListToolbar select,
body.vision td.style14 select {
  height: 30px;
  padding: 0 24px 0 8px;
  font-size: 12px;
  background-color: var(--bg-4) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2);
  color: var(--text-0);
  vertical-align: middle;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2367e8f9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
  cursor: pointer;
}
body.vision #devListToolbar select:hover,
body.vision td.style14 select:hover {
  border-color: var(--border-4) !important;
  background-color: var(--bg-5) !important;
}

/* Toolbar checkbox-label combos: align with controls */
body.vision #devListToolbar label,
body.vision #kvmListToolbar label,
body.vision td.style14 label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 8px;
  font-size: 12px;
  color: var(--text-2);
  vertical-align: middle;
}
body.vision #devListToolbar label input[type=checkbox],
body.vision #kvmListToolbar label input[type=checkbox],
body.vision td.style14 label input[type=checkbox] { margin: 0; }

/* Sort / View / Size / Settings cell on the right */
body.vision #devListToolbarView,
body.vision #devListToolbarSort,
body.vision #devListToolbarSize,
body.vision #devListToolbarSettings {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 8px;
  font-size: 12px;
  color: var(--text-2);
  vertical-align: middle;
}
body.vision #devListToolbarView select,
body.vision #devListToolbarSort select,
body.vision #devListToolbarSize select { margin-left: 4px; }

/* Mobile wrap */
@media (max-width: 768px) {
  body.vision #devListToolbar,
  body.vision #kvmListToolbar,
  body.vision td.style14 {
    display: flex !important;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px !important;
  }
  body.vision #devListToolbar > *,
  body.vision #kvmListToolbar > *,
  body.vision td.style14 > * { margin-right: 0; }
}
body.vision #devListToolbarView,
body.vision #devListToolbarSort,
body.vision #devListToolbarSize,
body.vision #devListToolbarSettings {
  color: var(--text-2) !important;
}
body.vision #devListToolbarView:hover,
body.vision #devListToolbarSort:hover,
body.vision #devListToolbarSize:hover,
body.vision #devListToolbarSettings:hover { color: var(--accent-2) !important; }

/* ─── Badges / status dots (best-effort, MeshCentral uses inline colors) */
body.vision .green, body.vision .online { color: var(--online) !important; }
body.vision .red, body.vision .offline { color: var(--danger) !important; }
body.vision .yellow, body.vision .warn { color: var(--warn) !important; }

/* ─── Scrollbars ──────────────────────────────────────────────────────── */
body.vision ::-webkit-scrollbar { width: 10px; height: 10px; }
body.vision ::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.08);
  border-radius: var(--radius-2);
  border: 2px solid transparent;
  background-clip: padding-box;
}
body.vision ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.18); background-clip: padding-box; }
body.vision ::-webkit-scrollbar-track { background: transparent; }
body.vision ::-webkit-scrollbar-corner { background: transparent; }
/* Firefox */
body.vision { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.12) transparent; }

/* Lightmode parity (body can carry both `vision` and `lightmode`) */
body.vision.lightmode ::-webkit-scrollbar-thumb { background: rgba(15,23,42,0.18); background-clip: padding-box; }
body.vision.lightmode ::-webkit-scrollbar-thumb:hover { background: rgba(15,23,42,0.32); background-clip: padding-box; }
body.vision.lightmode { scrollbar-color: rgba(15,23,42,0.22) transparent; }

/* ─── Focus rings (keyboard nav) ──────────────────────────────────────── */
body.vision :focus-visible {
  outline: none;
  box-shadow: 0 0 0 1px var(--bg-1), 0 0 0 3px var(--accent-border) !important;
}

/* ─── Selection ───────────────────────────────────────────────────────── */
body.vision ::selection { background: var(--accent-bg-strong); color: var(--text-0); }

/* ─── Tab / panel content backgrounds + padding ──────────────────────── */
body.vision #p1, body.vision #p2, body.vision #p3,
body.vision #p4, body.vision #p5, body.vision #p6, body.vision #p10,
body.vision #p20, body.vision #p21, body.vision #p30, body.vision #p31,
body.vision #p40, body.vision #p41, body.vision #p42, body.vision #p50, body.vision #p52, body.vision #p60 {
  background: var(--bg-0);
  color: var(--text-1);
  padding: var(--space-4) var(--space-6) var(--space-8);
  box-sizing: border-box;
}
/* Session panels (Desktop/Terminal/Files) use a fixed-budget grid layout
   in style.css (#deskarea3x is sized as calc(100vh - 270px)). That
   budget breaks when warning callouts are shown, pushing the bottom
   toolbar (Input toggle, latency, action icons) off-screen. We make
   #p11/#p12/#p13 a flex column instead so the canvas auto-fills the
   remaining space and the foot toolbar is always reachable. */
/* Scope `display:flex` to the visible state. QV() sets inline
   `display:none` (without !important), so without :not() guard a CSS
   `display:flex !important` wins and the panel bleeds into other views. */
body.vision #p11, body.vision #p12, body.vision #p13 {
  background: var(--bg-0);
  color: var(--text-1);
  padding: 0 !important;
  flex-direction: column;
  height: 100% !important;
  max-height: 100% !important;
  overflow: hidden;
}
body.vision #p11:not([style*="display: none"]):not([style*="display:none"]),
body.vision #p12:not([style*="display: none"]):not([style*="display:none"]),
body.vision #p13:not([style*="display: none"]):not([style*="display:none"]) {
  display: flex !important;
}
/* column_l sets its own height via the CSS grid in style.css. Make sure
   it clips p11 so the foot toolbar can't escape under the footer. */
body.vision #column_l { overflow: hidden; }
body.vision #p11 > #deskarea0,
body.vision #p12 > #termTable,
body.vision #p13 > table#p13toolbar {
  flex: 1;
  min-height: 0;
  display: flex !important;
  flex-direction: column;
}
body.vision #p11 #deskarea3x,
body.vision #p12 #termarea3x {
  flex: 1 !important;
  min-height: 0 !important;
  max-height: none !important;
  height: auto !important;
  position: relative;
}
body.vision #p11 #DeskParent,
body.vision #p11 #DeskFocus {
  height: 100%;
}
/* Title + warnings remain natural-height; canvas eats the rest */
body.vision #p11 #p11title,
body.vision #p12 #p12title,
body.vision #p13 #p13title { flex: 0 0 auto; }
body.vision #p11 #p11warning,
body.vision #p11 #p11warning2,
body.vision #p12 #p12warning,
body.vision #p12 #p12warning2,
body.vision #p13 #p13warning { flex: 0 0 auto; }
body.vision #p11 #deskarea1,
body.vision #p11 #deskarea4,
body.vision #p12 .areaHead,
body.vision #p12 .areaFoot,
body.vision #p13 .areaHead,
body.vision #p13 .areaHead2,
body.vision #p13 .areaHead3 { flex: 0 0 auto; }
@media (max-width: 768px) {
  body.vision #p1, body.vision #p2, body.vision #p3, body.vision #p4, body.vision #p5,
  body.vision #p6, body.vision #p10, body.vision #p40, body.vision #p41 {
    padding: var(--space-3) var(--space-3) var(--space-6);
  }
}
/* Pull panel titles flush with the new padding (they had margin) */
body.vision #p1title, body.vision #p2title, body.vision #p3title,
body.vision #p4title, body.vision #p5title, body.vision #p6title,
body.vision #p10title, body.vision #p11title,
body.vision #p21title, body.vision #p31title { margin: 0; }
/* h1 inside titles — tighten top margin since panel has padding now */
body.vision #p1 h1, body.vision #p2 h1, body.vision #p3 h1,
body.vision #p4 h1, body.vision #p5 h1, body.vision #p6 h1,
body.vision #p10 h1, body.vision #p11 h1,
body.vision #p21 h1, body.vision #p31 h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--text-0);
  margin: 0 0 12px;
  padding: 0;
}

/* ─── Sub-tab strip (.style3 / .style3x cells in #topbar) ─────────────── */
body.vision #topbar,
body.vision #topbar table,
body.vision #topbar tr,
body.vision #topbar td {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
}
body.vision .style3,
body.vision .style3x,
body.vision .topbar_td,
body.vision .topbar_td_end {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  color: var(--text-2) !important;
  font-weight: 500 !important;
  text-align: center;
  border-bottom: 1px solid var(--border-2);
  transition: background .12s, color .12s;
}
body.vision .style3x:hover,
body.vision .topbar_td:hover {
  background: var(--bg-2) !important;
  background-color: var(--bg-2) !important;
  color: var(--text-0) !important;
}
body.vision .style3x.fullselect,
body.vision .style3sel {
  background: var(--accent-bg) !important;
  background-color: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  border-bottom: 2px solid var(--accent) !important;
  box-shadow: none;
}
/* The active sub-tab is the `style3sel` cell. Its accent rule above lost to
   the higher-specificity #topbar overriders (`#topbar td { background:..1 }`
   and `#topbar .topbar_td { color:..2 }`), so the selected tab read the same
   muted grey as inactive ones. Match that specificity with the #topbar scope
   + td so the accent wins. */
body.vision #topbar td.style3sel,
body.vision #topbar .topbar_td.style3sel {
  color: var(--accent-2) !important;
  background: var(--accent-bg) !important;
  background-color: var(--accent-bg) !important;
}
body.vision .style3x.semiselect {
  background: var(--bg-3) !important;
  background-color: var(--bg-3) !important;
  color: var(--text-1) !important;
}

/* ─── Footer ──────────────────────────────────────────────────────────── */
body.vision #footer {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border-top: 1px solid var(--border-2);
  color: var(--text-2);
}
body.vision #footer td,
body.vision #footer td:first-child,
body.vision .footer1,
body.vision .footer2 { color: var(--text-2) !important; }
body.vision #footer a {
  color: var(--accent-2) !important;
  text-decoration: none !important;
}
body.vision #footer a:hover { color: var(--accent) !important; text-decoration: underline !important; }

/* ─── Left sidebar (icon column) buttons ──────────────────────────────── */
body.vision .lbbutton {
  background: var(--bg-1) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3) !important;
  transition: background .12s, border-color .12s;
  position: relative;
  background-image: none !important;
}
/* Hide the original PNG icons rendered as inner content. `opacity:0` left them
   in layout at their native 68px width inside a 46px rail button — 200 real
   overflow findings from .pw/lint.js, and dead hit-area over the icon. Use the
   visually-hidden pattern so the label text stays in the accessibility tree
   while taking no space. */
body.vision .lbbutton > * {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0 !important;
}
/* Paint a flat SVG icon centered, tinted via currentColor */
body.vision .lbbutton::after {
  content: '';
  position: absolute;
  inset: 0;
  display: block;
  background: currentColor;
  color: var(--text-2);
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: 28px 28px;
          mask-size: 28px 28px;
  transition: color .12s;
}
body.vision #LeftMenuMyDevices::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='14' height='10' rx='1.5'/><path d='M7 18h6M10 14v4M14 9h6v8a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='14' height='10' rx='1.5'/><path d='M7 18h6M10 14v4M14 9h6v8a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1z'/></svg>");
}
body.vision #LeftMenuMyAccount::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='8' r='3.5'/><path d='M5 20c0-3.3 3-6 7-6s7 2.7 7 6'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='8' r='3.5'/><path d='M5 20c0-3.3 3-6 7-6s7 2.7 7 6'/></svg>");
}
body.vision #LeftMenuMyEvents::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12h4l3-9 4 18 3-9h4'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12h4l3-9 4 18 3-9h4'/></svg>");
}
body.vision #LeftMenuMyFiles::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M3 6a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/></svg>");
}
body.vision #LeftMenuMyUsers::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.5'/><path d='M3 19c0-3.3 2.7-6 6-6s6 2.7 6 6M16 11a3 3 0 1 0 0-6M21 18.5a5 5 0 0 0-4-4.9'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.5'/><path d='M3 19c0-3.3 2.7-6 6-6s6 2.7 6 6M16 11a3 3 0 1 0 0-6M21 18.5a5 5 0 0 0-4-4.9'/></svg>");
}
body.vision #LeftMenuMyServer::after {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='7' rx='1.5'/><rect x='3' y='13' width='18' height='7' rx='1.5'/><circle cx='7' cy='7.5' r='.7' fill='black' stroke='none'/><circle cx='7' cy='16.5' r='.7' fill='black' stroke='none'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='7' rx='1.5'/><rect x='3' y='13' width='18' height='7' rx='1.5'/><circle cx='7' cy='7.5' r='.7' fill='black' stroke='none'/><circle cx='7' cy='16.5' r='.7' fill='black' stroke='none'/></svg>");
}
body.vision .lbbutton:hover {
  background: var(--bg-2) !important;
  border-color: var(--border-3) !important;
}
body.vision .lbbutton:hover::after { color: var(--text-0); }
body.vision .lbbutton.lbbuttonsel,
body.vision .lbbuttonsel {
  background: var(--accent-bg) !important;
  border-color: var(--accent-border) !important;
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
body.vision .lbbutton.lbbuttonsel::after,
body.vision .lbbuttonsel::after { color: var(--accent-2); }

/* ─── Decorative stock images — hide entirely (clipart out of place) ─── */
body.vision #MainMeshImage,
body.vision #p2AccountImage,
body.vision #MainUserImageEx,
body.vision #welcomeimage,
body.vision img[src="serverpic.ashx"],
body.vision img[src*="user-256.png"],
body.vision img[src*="welcome"] {
  display: none !important;
}
/* Account image slot — show a clean SVG avatar instead via parent ::before */
body.vision #p2 #p2AccountImage + h1,
body.vision #p2 h1 { display: inline-block; }

/* ─── Page header titles (h1) inside panels — keep tight ──────────────── */
body.vision #p1 h1,
body.vision #p2 h1,
body.vision #p3 h1,
body.vision #p4 h1,
body.vision #p5 h1,
body.vision #p10 h1,
body.vision #p11 h1 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--text-0);
  margin: 16px 0 12px;
}

/* ─── Account-actions panel area (cards) ──────────────────────────────── */
body.vision #p2AccountActions,
body.vision .pageHeader,
body.vision #p3title,
body.vision #p4title {
  background: transparent;
}

/* ─── Device detail panels (p10 General, p11 Desktop, p12 Terminal, p13 Files, p14 AMT, p15 Console, p16 Events, p17 Info, p18 Software, p19 Plugins) */
body.vision #p10, body.vision #p11, body.vision #p12, body.vision #p13,
body.vision #p14, body.vision #p15, body.vision #p16, body.vision #p17,
body.vision #p18, body.vision #p19 {
  background: var(--bg-0);
  color: var(--text-1);
}
body.vision #p10title, body.vision #p11title, body.vision #p12title,
body.vision #p13title, body.vision #p14title, body.vision #p15title {
  background: var(--bg-1);
  border-bottom: 1px solid var(--border-2);
  padding: 12px 16px;
}
body.vision .backButton {
  background: var(--bg-3) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  transition: background .12s, border-color .12s;
}
body.vision .backButton:hover {
  background: var(--bg-4) !important;
  border-color: var(--accent-border) !important;
}
body.vision .backButtonEx {
  filter: brightness(1.6) saturate(0);
}
body.vision .warningbox {
  background: var(--warn-bg) !important;
  color: var(--warn) !important;
  border: 1px solid var(--warn-bg) !important;
  border-left: 3px solid var(--warn) !important;
  border-radius: var(--radius-2);
  padding: var(--space-3);
  margin: 0;
}
body.vision .deviceNotifyDotSub {
  filter: hue-rotate(180deg) saturate(1.2);
}
body.vision .deviceBatteryLarge {
  filter: brightness(1.2);
}
body.vision #p11capslock, body.vision #p11scrolllock, body.vision #p11numlock {
  background: var(--bg-3) !important;
  color: var(--text-2) !important;
  border: 1px solid var(--border-3) !important;
}
body.vision #p11capslock[style*="A3FFB8"], body.vision #p11scrolllock[style*="A3FFB8"], body.vision #p11numlock[style*="A3FFB8"] {
  /* JS sets bg #A3FFB8 when active — best-effort doesn't override inline,
     but the wrapper picks up dark theme */
}
/* Device general info table */
body.vision .style10, body.vision .style10s, body.vision .style14, body.vision .style6 {
  background: var(--bg-1) !important;
  color: var(--text-1) !important;
}
body.vision .auto-style1 { background: transparent !important; color: var(--text-1); }
body.vision .nodeViewCard,
body.vision .nodeViewSection {
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px 16px;
  margin: 8px 0;
}
/* Desktop KVM area */
body.vision #Desk, body.vision #DeskContainer {
  background: #000 !important;
}
body.vision #DeskControl, body.vision #DeskControlSpan {
  background: var(--bg-1) !important;
  color: var(--text-1) !important;
  border-bottom: 1px solid var(--border-2);
}
/* TitleBarBlock and quick-toggle pills */
body.vision #TitleBarBlock {
  background: var(--bg-1) !important;
  border-bottom: 1px solid var(--border-2);
}

/* ─── Empty states ────────────────────────────────────────────────────── */
body.vision #p2noMeshFound,
body.vision #xdevices:empty::before,
body.vision #p3users:empty::before,
body.vision #p3events:empty::before {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 64px 16px;
  color: var(--text-2);
}
body.vision #p2noMeshFound {
  padding: 40px 16px;
  border: 1px dashed var(--border-3);
  border-radius: var(--radius-4);
  background: var(--bg-1);
  margin: 24px 0;
}
body.vision #p2noMeshFound strong { color: var(--text-0); }

/* Events list: clamp to panel + style day-group header rows */
body.vision #p3events { padding-left: 0; padding-right: 0; }
body.vision #p3events td[colspan] {
  background: var(--bg-2);
  color: var(--text-2);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
}

/* ─── Bitmap icons → SVG via mask-image ─────────────────────────────────
   Both modes supported:
   1) Original <img src=images/link4.png …> tags: CSS hides the raster and
      paints the SVG mask over it.
   2) New <span class="vc-icon vc-icon-link4"></span> markup: pure SVG, no
      bitmap fetched.
   currentColor tints the icon.
*/
body.vision .vc-icon {
  display: inline-block;
  width: 14px;
  height: 14px;
  background: currentColor;
  color: var(--text-2);
  vertical-align: middle;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: 14px 14px;
          mask-size: 14px 14px;
  cursor: inherit;
}
body.vision a:hover .vc-icon, body.vision .vc-icon:hover { color: var(--accent-2); }
body.vision .vc-icon.vc-icon-link4,
body.vision img[src*="images/link4.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4v12M7 11l5 5 5-5M5 20h14'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4v12M7 11l5 5 5-5M5 20h14'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-link5,
body.vision img[src*="images/link5.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M12 20l9-9-2-2-9 9-3 3 5 -1zM14 6l4 4'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><path d='M12 20l9-9-2-2-9 9-3 3 5 -1zM14 6l4 4'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-link6,
body.vision img[src*="images/link6.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.5'/><path d='M3 19c0-3.3 2.7-6 6-6s6 2.7 6 6M19 8v8M15 12h8'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.5'/><path d='M3 19c0-3.3 2.7-6 6-6s6 2.7 6 6M19 8v8M15 12h8'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-info,
body.vision img[src*="images/info.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M12 8v.01M11 12h1v5h1'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M12 8v.01M11 12h1v5h1'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-gear,
body.vision img[src*="images/icon-gear.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1 1.55V21a2 2 0 0 1-4 0v-.09a1.7 1.7 0 0 0-1.11-1.55 1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 5 15a1.7 1.7 0 0 0-1.55-1H3.4a2 2 0 0 1 0-4h.09A1.7 1.7 0 0 0 5 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06A2 2 0 1 1 7.43 4.24l.06.06A1.7 1.7 0 0 0 9.36 4.6a1.7 1.7 0 0 0 1-1.55V3a2 2 0 0 1 4 0v.09A1.7 1.7 0 0 0 15.4 4.64a1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.7 1.7 0 0 0-.34 1.87 1.7 1.7 0 0 0 1.55 1H21a2 2 0 0 1 0 4h-.09a1.7 1.7 0 0 0-1.55 1z'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1 1.55V21a2 2 0 0 1-4 0v-.09a1.7 1.7 0 0 0-1.11-1.55 1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 5 15a1.7 1.7 0 0 0-1.55-1H3.4a2 2 0 0 1 0-4h.09A1.7 1.7 0 0 0 5 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06A2 2 0 1 1 7.43 4.24l.06.06A1.7 1.7 0 0 0 9.36 4.6a1.7 1.7 0 0 0 1-1.55V3a2 2 0 0 1 4 0v.09A1.7 1.7 0 0 0 15.4 4.64a1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.7 1.7 0 0 0-.34 1.87 1.7 1.7 0 0 0 1.55 1H21a2 2 0 0 1 0 4h-.09a1.7 1.7 0 0 0-1.55 1z'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-collapse,
body.vision img[src*="images/icon-collapse.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 12h12'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 12h12'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-expand,
body.vision img[src*="images/icon-expand.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 6v12M6 12h12'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 6v12M6 12h12'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-x,
body.vision img[src*="images/x16.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 6l12 12M18 6L6 18'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 6l12 12M18 6L6 18'/></svg>") !important;
}
body.vision .vc-icon.vc-icon-padlock,
body.vision img[src*="images/padlock12.png"] {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") !important;
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='11' width='16' height='10' rx='2'/><path d='M8 11V7a4 4 0 0 1 8 0v4'/></svg>") !important;
}
/* Hide the raster pixels when img is replaced */
body.vision img[src*="images/link4.png"],
body.vision img[src*="images/link5.png"],
body.vision img[src*="images/link6.png"],
body.vision img[src*="images/info.png"],
body.vision img[src*="images/icon-gear.png"],
body.vision img[src*="images/icon-collapse.png"],
body.vision img[src*="images/icon-expand.png"],
body.vision img[src*="images/x16.png"],
body.vision img[src*="images/padlock12.png"] {
  display: inline-block;
  width: 14px;
  height: 14px;
  background: currentColor;
  color: var(--text-2);
  vertical-align: middle;
}
body.vision img[src*="images/link4.png"],
body.vision img[src*="images/link5.png"],
body.vision img[src*="images/link6.png"],
body.vision img[src*="images/info.png"],
body.vision img[src*="images/icon-gear.png"],
body.vision img[src*="images/icon-collapse.png"],
body.vision img[src*="images/icon-expand.png"],
body.vision img[src*="images/x16.png"],
body.vision img[src*="images/padlock12.png"] {
  display: inline-block;
  width: 14px;
  height: 14px;
  background: currentColor;
  color: var(--text-2);
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: 14px 14px;
          mask-size: 14px 14px;
  visibility: visible;
  vertical-align: middle;
  border-radius: 0;
}
/* link4 = download affordance; link6 = batch create; hover tints accent */
body.vision a:hover img[src*="images/link"],
body.vision a:hover img[src*="images/icon-gear"] { color: var(--accent-2); }

/* ─── Action-button strip (Select All / Group Action / New Account…) ──── */
body.vision .pButton,
body.vision .pButtonNew {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
}
body.vision .pButton:hover,
body.vision .pButtonNew:hover {
  background: var(--bg-4) !important;
  border-color: var(--border-4) !important;
}

/* ─── Phase 3a: My Devices polish ─────────────────────────────────────── */

/* idle-timeout notice — was yellow inline */
body.vision #idleTimeoutNotify {
  color: var(--warn) !important;
  font-size: 12px;
  margin-left: 8px;
  padding: 4px 8px;
  background: var(--warn-bg);
  border: 1px solid rgba(251,191,36,0.25);
  border-radius: var(--radius-full);
}
body.vision #idleTimeoutNotify:empty { display: none; }

/* "Try the new MeshCentral UI" — promotional pill */
body.vision .textnewui,
body.vision #textnewui {
  background: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  border: 1px solid var(--accent-border) !important;
  border-radius: var(--radius-full) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  padding: 4px 12px !important;
  margin: 12px 12px 0 0 !important;
  cursor: pointer;
  display: inline-block;
  text-transform: none;
  letter-spacing: 0.01em;
  transition: background .12s, border-color .12s;
}
body.vision .textnewui:hover { background: var(--accent-bg-strong) !important; }
body.vision .textnewui b { font-weight: 500; }

/* notificationCount pill — JS toggles inline `display:none` when count is
   0; without the :not() guard the `!important` flex would keep a "0"
   pill visible on every page. */
body.vision #notificationCount {
  background: var(--danger) !important;
  color: #fff !important;
  border-radius: var(--radius-full) !important;
  width: 22px !important;
  height: 22px !important;
  min-width: 22px;
  font-size: 11px !important;
  font-weight: 600 !important;
  line-height: 22px !important;
  text-align: center !important;
  margin: 16px 16px 0 0 !important;
  cursor: pointer;
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 12px var(--danger-bg);
  align-items: center;
  justify-content: center;
}
body.vision #notificationCount:not([style*="display: none"]):not([style*="display:none"]) {
  display: inline-flex !important;
}

/* Toolbar tiny icon buttons (Collapse / Expand All) */
body.vision #devListToolbar button[id*="CollapseAll"],
body.vision #devListToolbar button[id*="ExpandAll"],
body.vision #kvmListToolbar button[id*="CollapseAll"],
body.vision #kvmListToolbar button[id*="ExpandAll"] {
  width: 30px;
  height: 30px;
  padding: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}
body.vision #devListToolbar button img,
body.vision #kvmListToolbar button img {
  width: 14px !important;
  height: 14px !important;
}

/* SearchInputClearButton x16 — proper position next to search */
body.vision #SearchInputClearButton,
body.vision #KvmSearchInputClearButton {
  display: inline-block !important;
  width: 0;
  position: relative !important;
}
body.vision #SearchInputClearButton img,
body.vision #KvmSearchInputClearButton img {
  position: absolute !important;
  right: 8px !important;
  top: 50%;
  left: auto !important;
  transform: translateY(-50%);
  opacity: 0.7;
  cursor: pointer;
}
body.vision #SearchInputClearButton img:hover,
body.vision #KvmSearchInputClearButton img:hover { opacity: 1; }

/* "No device groups" panel — proper empty state */
body.vision #NoMeshesPanel {
  background: var(--bg-1);
  border: 1px dashed var(--border-3);
  border-radius: var(--radius-4);
  padding: 32px;
  margin: 24px 0;
}
body.vision #NoMeshesPanel table { width: 100%; }
body.vision #NoMeshesPanel img { width: 28px !important; height: 28px !important; opacity: 0.6; }
body.vision #NoMeshesPanel #getStarted1,
body.vision #NoMeshesPanel #getStarted2 {
  color: var(--text-1);
  font-size: 13px;
  line-height: 1.5;
}
body.vision #NoMeshesPanel a strong {
  color: var(--accent-2);
  font-weight: 500;
}

/* Device list view-mode selector icons row */
body.vision #devListToolbarViewIcons {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: 12px;
}
body.vision #devViewPageState {
  color: var(--text-2);
  font-size: 12px !important;
  line-height: 30px !important;
  padding: 0 8px;
}

/* p1 / p2 title row — make breathing room */
body.vision #p1title,
body.vision #p2title,
body.vision #p3title,
body.vision #p4title,
body.vision #p5title,
body.vision #p10title,
body.vision #p11title,
body.vision #p20title,
body.vision #p21title,
body.vision #p30title,
body.vision #p31title,
body.vision #p40title,
body.vision #p50title,
body.vision #p60title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  min-height: 40px;
}

/* p2 My Account section ─────────────────────────────────────────────── */

/* Hide legacy 128px stock avatar; replace with subtle accent disc.
   float:none/clear so the frame is its own full-width row above ACCOUNT
   SECURITY instead of floating over the section dividers and squeezing the
   security cards short. */
body.vision #p2AccountImageFrame {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 0 24px;
  border-bottom: 1px solid var(--border-2);
  margin-bottom: 24px;
  float: none !important;
  clear: both !important;
  width: 100%;
  box-sizing: border-box;
}
body.vision #p2AccountImageFrame::before {
  content: '';
  display: block;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background:
    radial-gradient(circle at 30% 30%, var(--accent), var(--accent-deep)) 0 0/100% 100%,
    var(--bg-3);
  box-shadow: 0 0 0 1px var(--bg-1), 0 0 12px -4px var(--accent-bg-strong);
  flex: 0 0 40px;
  opacity: 0.85;
}
body.vision #p2AccountImageFrame > div { font-size: 12px; }
body.vision #p2AccountImageFrame a { font-size: 12px; }

/* p2 section headers */
body.vision #p2 p > strong:only-child,
body.vision #p2 p:has(> strong:only-child) {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-2);
  font-weight: 600;
  margin: 16px 0 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-2);
}

/* Account security rows — clean list-item style */
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] {
  margin-left: 0 !important;
  display: grid;
  gap: 4px;
}
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] > div {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  transition: background .12s, border-color .12s;
}
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] > div:hover {
  background: var(--bg-3);
  border-color: var(--border-3);
}
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] > div > span:last-child {
  flex: 1;
}
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] a {
  color: var(--text-1);
  font-weight: 500;
}
body.vision #p2AccountSecurity > div[style*="margin-left: 24px"] a:hover { color: var(--accent-2); }

/* Check mark pill — replace bare ✓ strong */
body.vision .p2AccountActions {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--text-3);
  font-size: 11px !important;
  flex: 0 0 20px;
}
body.vision .p2AccountActions span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
body.vision .p2AccountActions strong { font-weight: 500; }
/* When inner span is visible (factor enrolled), promote to "on" look */
body.vision .p2AccountActions:has(> span:not([style*="display: none"]):not([style*="display:none"])) {
  background: var(--online-bg);
  border-color: rgba(52,211,153,0.3);
  color: var(--online);
}
/* Hide the parent row's check entirely if the inner span is display:none */
body.vision .p2AccountActions > span[style*="display:none"],
body.vision .p2AccountActions > span[style*="display: none"] { display: none !important; }

/* Account actions list (mL class — bare bullet list) */
body.vision #p2AccountActions .mL,
body.vision p.mL {
  padding-left: 0;
  margin: 0 0 var(--space-2);
  display: grid;
  gap: var(--space-1);
}
body.vision p.mL > span {
  display: block;
  padding: 8px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  transition: background .12s, border-color .12s;
}
body.vision p.mL > span:hover {
  background: var(--bg-3);
  border-color: var(--border-3);
}
body.vision p.mL > span br { display: none; }
body.vision p.mL > span a {
  display: block;
  color: var(--text-1);
  font-weight: 500;
}
body.vision p.mL > span a:hover { color: var(--accent-2); }
/* Bare anchors in the same list (e.g. Localization / Notification Settings are
   not span-wrapped) flowed as plain text lines between span-cards, giving the
   ACCOUNT ACTIONS list an irregular, accidental-looking rhythm. Make them
   identical card rows so every action has one uniform gap. */
body.vision p.mL > a {
  display: block;
  padding: 8px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  color: var(--text-1);
  font-weight: 500;
  transition: background .12s, border-color .12s;
}
body.vision p.mL > a:hover {
  background: var(--bg-3);
  border-color: var(--border-3);
  color: var(--accent-2);
}
body.vision p.mL > br { display: none; }

/* "Server disconnected" p0 banner */
body.vision #p0 {
  background: var(--danger-bg);
  border: 1px solid rgba(248,113,113,0.3);
  border-radius: var(--radius-3);
  color: var(--danger);
  padding: 12px 16px;
  margin: var(--space-4) var(--space-6);
  font-size: 13px;
  font-weight: 500;
}
body.vision #p0 a, body.vision #p0 href {
  color: var(--accent-2);
  font-weight: 500;
}
body.vision #p0message u { text-decoration: none; }

/* Notification box at top */
body.vision .notifiyBox,
body.vision #notifiyBox {
  background: var(--bg-2);
  color: var(--text-0);
  border: 1px solid var(--accent-border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-pop);
  padding: 12px 12px;
  font-size: 13px;
}

/* Mesh / device row hover scale subtle */
body.vision .deviceBar,
body.vision .meshBar {
  transition: background .12s, border-color .12s;
}

/* ── viewSelector chip group (Columns / List / Desktops / Map) ── */
body.vision #devListToolbarViewIcons .viewSelector {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}

/* logoutControlSpan dropdown */
body.vision .logoncontrolspan,
body.vision .logoncontrolspan2 {
  font-size: 13px;
  padding-right: 12px;
}
body.vision #logoutControl {
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  height: 56px;
  line-height: 1;
}
body.vision .logoncontrolspan a,
body.vision .logoncontrolspan2 a { color: var(--text-1); }
body.vision .logoncontrolspan a:hover,
body.vision .logoncontrolspan2 a:hover { color: var(--accent-2); }

/* Left-bar (icon-only sidebar): make it a real fixed rail */
body.vision #page_leftbar {
  background: var(--bg-1) !important;
  border-right: 1px solid var(--border-2) !important;
  padding-top: 8px;
}
body.vision #page_leftbar .lbbutton {
  width: 48px !important;
  height: 48px !important;
  margin: var(--space-2) auto !important;
}

/* ─── Phase 3b: p3 / p4 / p5 / p6 polish ──────────────────────────────── */

/* pTable sub-toolbars (events filter, users filter, files filter) */
body.vision .pTable {
  background: transparent;
  border: 0;
  margin: 0 0 12px;
  box-shadow: none;
}
body.vision .pTable .h1, body.vision .pTable .h2 { width: auto; }

/* Server State stat rows — base CSS paints #d3d9d6 which reads as solid
   white on dark theme, hiding the label + value text. */
body.vision .serverStateTableCell {
  background: var(--bg-2) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  width: 100% !important;
  margin-bottom: 4px !important;
}
body.vision .serverStateTableCell td {
  padding: var(--space-2) var(--space-3);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}
body.vision .serverStateTableCell span:first-child { color: var(--text-2); }
body.vision .serverStateTableCell span:last-child { color: var(--text-0); font-weight: 600; float: none !important; }

/* Kill base white→grey gradient on .h1/.h2/.h2end edge strips that bracket
   every toolbar row. They render as bright white slivers on dark theme. */
body.vision td.h1,
body.vision td.h2,
body.vision td.h2end,
body.vision .h1,
body.vision .h2,
body.vision .h2end {
  background: transparent !important;
  background-image: none !important;
  width: 0 !important;
}
body.vision .pTable td.auto-style1,
body.vision .pTable td.style14 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 16px !important;
  background: var(--bg-1) !important;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
}
/* collapse empty toolbar cells so they don't render as dead bordered pills */
body.vision .pTable td.auto-style1:empty,
body.vision .pTable td.style14:empty { display: none !important; }
body.vision .pTable tr:has(> td.auto-style1:empty):not(:has(input,select,button,a,img)) { display: none !important; }

/* p4 toolbar — Right-side action icons (download, batch, gear) */
body.vision #p4 td.style14 div[style*="float:right"] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
body.vision #p4 td.style14 div[style*="float:right"] a img,
body.vision #p4 td.style14 div[style*="float:right"] > img {
  width: 16px;
  height: 16px;
  padding: 8px;
  box-sizing: content-box;
  border-radius: var(--radius-2);
  vertical-align: middle;
  margin: 0 !important;
}
body.vision #p4 td.style14 div[style*="float:right"] a:hover img,
body.vision #p4 td.style14 div[style*="float:right"] > img:hover {
  background: var(--bg-3);
}

/* p5 Files toolbar — flatten the nbsp-separated row */
body.vision #p5toolbar {
  background: transparent !important;
}
body.vision #p5filehead {
  display: block;
  background: transparent !important;
  padding: 0 !important;
}
body.vision #p5filehead > div {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 12px 16px;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3) var(--radius-3) 0 0;
}
body.vision #p5rightOfButtons {
  margin-left: auto;
  order: 99;
}
/* When empty (the default), #p5rightOfButtons would otherwise render as a
   30px wide pill sliver on the toolbar row because #p5filehead > div gets
   the pill background + border. Hide it until JS fills it. */
body.vision #p5filehead > #p5rightOfButtons:empty { display: none !important; }
body.vision #p5filehead input[type=button] {
  margin: 0 !important;
}

/* p5 path crumbs row */
body.vision #p5filesubhead {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-top: 0;
  border-bottom: 0;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
body.vision #p5currentpath {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-2);
  padding: 4px 8px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
}

/* p5 public share callout (was a plain div) */
body.vision #p5PublicShare {
  background: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-2);
  color: var(--accent-2);
  padding: 8px 12px;
  margin: 8px 0;
  font-size: 12px;
}
body.vision #p5PublicShare:empty,
body.vision #p5PublicShare > div:empty { display: none; }

/* bigok / bigfail full-screen toast — same hide-guard as p11/p12/p13:
   JS sets inline `display:none` (no !important), so the toast's
   `display:flex !important` would otherwise render a permanent X / ✓
   over empty pages (My Files etc.). */
body.vision #bigok,
body.vision #bigfail {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 120px;
  height: 120px;
  border-radius: var(--radius-full);
  align-items: center;
  justify-content: center;
  font-size: 64px !important;
  z-index: 10000;
  animation: vision-toast-pop .42s ease-out forwards;
}
body.vision #bigok:not([style*="display: none"]):not([style*="display:none"]),
body.vision #bigfail:not([style*="display: none"]):not([style*="display:none"]) {
  display: flex !important;
}
body.vision #bigok {
  background: var(--online-bg);
  color: var(--online) !important;
  border: 2px solid var(--online);
  box-shadow: 0 0 0 8px rgba(52,211,153,0.08), 0 16px 48px -12px rgba(0,0,0,0.7);
}
body.vision #bigfail {
  background: var(--danger-bg);
  color: var(--danger) !important;
  border: 2px solid var(--danger);
  box-shadow: 0 0 0 8px rgba(248,113,113,0.08), 0 16px 48px -12px rgba(0,0,0,0.7);
}
@keyframes vision-toast-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.7); }
  60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
  100% { transform: translate(-50%, -50%) scale(1); }
}

/* p5 bottom status bar */
body.vision #p5toolbarBottom {
  border-top: 1px solid var(--border-2);
}
body.vision #p5toolbarBottom td.style6 {
  background: var(--bg-1) !important;
  color: var(--text-2);
  padding: 8px 12px;
  font-size: 12px;
  border-radius: 0 0 var(--radius-3) var(--radius-3);
  border: 1px solid var(--border-2);
  border-top: 0;
}

/* Files table itself */
body.vision #p5filetable {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-top: 0;
  border-bottom: 0;
  min-height: 200px;
}

/* p6 server stats — chart frames */
body.vision .chartViewCanvas {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  padding: 4px;
  margin-bottom: 4px;
}
body.vision .chartViewText {
  color: var(--text-2);
  font-size: 12px;
  margin-bottom: 12px;
}
/* frame CPU/Mem donut + label as one cohesive stat card */
body.vision #serverCpuChartView,
body.vision #serverMemoryChartView {
  display: inline-flex !important;
  align-items: center;
  gap: var(--space-3);
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: var(--space-3) var(--space-4);
  margin-right: var(--space-3);
  vertical-align: top;
}
body.vision #serverCpuChartView .chartViewCanvas,
body.vision #serverMemoryChartView .chartViewCanvas {
  background: transparent; border: 0; padding: 0; margin: 0; flex: 0 0 auto;
  width: 44px; height: 44px !important;
  display: flex; align-items: center; justify-content: center;
}
body.vision #serverCpuChartView .chartViewText,
body.vision #serverMemoryChartView .chartViewText { margin: 0; }

/* p6 server stats table */
body.vision #serverStatsTable {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px;
  margin-bottom: 12px;
}
body.vision #serverStatsTable table {
  width: 100%;
}
body.vision #serverStatsTable td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-2);
  color: var(--text-1);
}
body.vision #serverStatsTable tr:last-child td { border-bottom: 0; }
body.vision #serverStatsTable .userTableHeader {
  display: block;
  width: 100% !important;
  box-sizing: border-box;
  background: transparent;
  border-bottom: 1px solid var(--border-2);
  padding: 0 0 var(--space-2) 0;
  /* !important to beat the inline margin-bottom:4px the serverStats markup
     generator sets — that gap put the divider ~4px above the stat-tile top
     border, reading as a doubled/glitchy line. */
  margin: 0 0 var(--space-3) 0 !important;
  color: var(--text-2);
}

/* Server warnings block */
body.vision #serverWarningsDiv {
  background: var(--warn-bg);
  border: 1px solid rgba(251,191,36,0.3);
  border-radius: var(--radius-3);
  padding: 16px;
  margin: 12px 0;
  color: var(--warn);
}

/* p10 device-general layout */
body.vision #p10info {
  padding-top: 4px;
}
body.vision #p10html,
body.vision #p10html2,
body.vision #p10html4,
body.vision #p10html5 {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-3);
}
body.vision #p10html5 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-4);
}
body.vision #p10html > table,
body.vision #p10html2 > table,
body.vision #p10html4 > table { width: 100%; }
body.vision #p10html2 td:first-child {
  white-space: nowrap;
  border-right: 1px solid var(--border-2) !important;
  padding-right: var(--space-3) !important;
}
body.vision #p10html2 .pwState { width: 100% !important; }

/* Right-rail device summary (icon + battery + notify dots) */
body.vision .deviceNotifyLargeDot {
  position: absolute;
  top: 6px; right: 6px;
  display: flex;
  gap: 4px;
  z-index: 2;
}
body.vision #MainComputerImage {
  filter: drop-shadow(0 0 24px rgba(34,211,238,0.15));
  max-width: 200px;
}
body.vision #MainComputerState {
  text-align: center;
  font-size: 12px;
  color: var(--text-2);
  margin-top: 4px;
}

/* Notes side panel */
body.vision #notesPanel {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px;
}
body.vision #notesPanel th {
  text-align: left;
  color: var(--text-2);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-2);
}
body.vision #notesPanelArea {
  background: var(--bg-2) !important;
  color: var(--text-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  padding: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
}

/* Section heads inside p10 ("Operations" / "Group" / "Tags" labels) */
body.vision #p10info table th,
body.vision #p10info table td.h1 {
  color: var(--text-2);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.04em;
}

/* "New" link beside "Device Groups" in p2 */
body.vision .newMeshBtn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  /* base style.css pins this to 12x12px (icon button) — the pill then
     wrapped only the '+' and the "New" label spilled outside. Let the box
     grow to wrap its text node. */
  width: auto !important;
  height: auto !important;
  background: var(--accent-bg);
  color: var(--accent-2) !important;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-full);
  font-size: 12px;
  font-weight: 500;
  text-decoration: none !important;
}
/* Hide the literal " - " text node sitting before the pill inside
   #p2createMeshLink1 (read as stray punctuation); restore size on the pill. */
body.vision #p2createMeshLink1 { font-size: 0; }
body.vision #p2createMeshLink1 .newMeshBtn { font-size: 12px; }
body.vision .newMeshBtn:hover {
  background: var(--accent-bg-strong);
  text-decoration: none !important;
}
body.vision .newMeshBtn::before {
  content: '+';
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
}

/* p2 Device Groups label */
body.vision #p2 > #p2info > strong:not(:empty) {
  display: inline-block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-2);
  font-weight: 600;
  margin: 16px 0 8px;
}

/* p2meshes container */
body.vision #p2meshes {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}

/* Legacy `.g1`/`.g2`/`.g1s`/`.g2s`/`.g2t`/`.e2`/`.e2t` gradient + bg fills
   bracket every device-group / event / user row. Base CSS paints them
   #c9c9c9 → #fff which reads as a bright white block on dark theme,
   obscuring the row text. Neutralize them theme-wide. */
body.vision .g1,
body.vision .g2,
body.vision .g1s,
body.vision .g2s,
body.vision .g2t {
  background: transparent !important;
  background-image: none !important;
  width: 0 !important;
}
body.vision .e2,
body.vision .e2t {
  background: transparent !important;
  color: var(--text-1) !important;
  padding-top: var(--space-1) !important;
  padding-bottom: var(--space-1) !important;
  line-height: 1.5;
}
body.vision #p3events .bar { border-bottom: 1px solid var(--border-1); }
body.vision #p3events .bar:nth-of-type(even) { background: var(--bg-1) !important; }
body.vision #p3events .bar:hover { background: var(--bg-2) !important; }
body.vision .e1 { color: var(--text-0); font-weight: 500; }
/* Hover state on each device-group card */
body.vision #p2meshes > div > div:hover .e2 { color: var(--accent-2) !important; }

/* Legacy `.bar` row + `.baricon` cell — light grey/white fills on the
   user list (Users tab) and event/group rows. Replace with theme bg. */
body.vision .bar,
body.vision #p3users .bar { background: transparent !important; color: var(--text-1) !important; }
/* List view device rows are `div#devs.bar18` with a hard #c9c9c9 fill that
   hid the name text on the dark theme. Neutralize like .bar. */
body.vision .bar18 {
  background: transparent !important;
  background-image: none !important;
  color: var(--text-1) !important;
}
/* The name (.style10) is an overflow:hidden box — a BFC. Beside the FLOATED
   .deviceBarCheckbox + .deviceBarIcon it cannot overlap the floats, and since
   it wants full width it drops BELOW the 18px row and is clipped → names
   looked blank. Flex the row instead: floats become inline flex items and the
   name shares the line; the old 44px dodge-the-floats indent is obsolete. */
body.vision .bar18 {
  display: flex;
  align-items: center;
}
body.vision .bar18 .style10 {
  flex: 1;
  min-width: 0;
  padding-left: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-sizing: border-box;
}
body.vision .sbar { background: transparent !important; }
body.vision .baricon { background: transparent !important; }
body.vision #p3events .baricon:empty,
body.vision #p3events .baricon:not(:has(img)) {
  width: var(--space-6) !important;
  min-width: var(--space-6) !important;
  padding: 0 !important;
}

/* ─── Phase 3c: Desktop (p11) / Terminal (p12) / Files (p13) ──────────── */

/* Title rows */
body.vision #p11deviceNameHeader,
body.vision #p12title,
body.vision #p13title,
body.vision #p14title,
body.vision #p15title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
/* hide the empty state-icon box that sits between back-arrow and title */
body.vision #p11deviceNameHeader > div:empty,
body.vision #p11deviceNameHeader > span:empty { display: none !important; }
body.vision #p11deviceNameHeader h1,
body.vision #p12title h1,
body.vision #p13title h1,
body.vision #p14title h1,
body.vision #p15title h1 { margin: 0; flex: 1; min-width: 180px; }

/* Caps/Scroll/Num lock pills — kill green inline bg */
body.vision #p11capslock,
body.vision #p11scrolllock,
body.vision #p11numlock {
  background-color: var(--bg-3) !important;
  color: var(--text-3) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-full) !important;
  padding: 4px 8px !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-left: 4px !important;
}
/* JS toggles inline bg-color #A3FFB8 (active) or another (inactive) — when
   active, paint cyan-active state via attribute selector */
body.vision #p11capslock[style*="A3FFB8"],
body.vision #p11scrolllock[style*="A3FFB8"],
body.vision #p11numlock[style*="A3FFB8"] {
  background-color: var(--online-bg) !important;
  color: var(--online) !important;
  border-color: rgba(52,211,153,0.3) !important;
}

/* areaHead / areaFoot — top & bottom toolbars on remote sessions */
body.vision .areaHead,
body.vision .areaFoot,
body.vision #deskarea1,
body.vision #deskarea4,
body.vision #termTable .areaHead,
body.vision #termTable .areaFoot,
body.vision #p13toolbar .areaHead {
  background: var(--bg-1) !important;
  border-top: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
  padding: 8px 12px !important;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 44px;
}
body.vision .areaHead { border-radius: var(--radius-3) var(--radius-3) 0 0; }
body.vision .areaFoot { border-radius: 0 0 var(--radius-3) var(--radius-3); }
body.vision .areaHead > div,
body.vision .areaFoot > div {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
body.vision .toright2 {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* deskareaicon — rotate / aspect ratio glyph buttons */
body.vision .deskareaicon {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-2);
  background: var(--bg-3);
  border-radius: var(--radius-2);
  cursor: pointer;
  font-size: 16px;
  color: var(--text-1);
  transition: background .12s, border-color .12s, color .12s;
}
body.vision .deskareaicon:hover {
  background: var(--bg-4);
  border-color: var(--accent-border);
  color: var(--accent-2);
}

/* Recording-active indicator (red dot) */
body.vision #deskRecordIcon,
body.vision #termRecordIcon,
body.vision #filesRecordIcon {
  background-color: var(--danger) !important;
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 12px var(--danger-bg);
  animation: vision-rec-pulse 1.6s ease-in-out infinite;
}
@keyframes vision-rec-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--bg-1), 0 0 12px var(--danger-bg); }
  50%      { box-shadow: 0 0 0 2px var(--bg-1), 0 0 22px var(--danger); }
}

/* Big "X" close-full button */
body.vision #idx_deskFullBtn2,
body.vision #idx_termFullBtn2 {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-2);
  cursor: pointer;
  color: var(--text-2);
  font-size: 13px;
  border: 1px solid var(--border-2);
  background: var(--bg-3);
  transition: background .12s, color .12s, border-color .12s;
}
body.vision #idx_deskFullBtn2:hover,
body.vision #idx_termFullBtn2:hover {
  background: var(--danger-bg);
  color: var(--danger);
  border-color: rgba(248,113,113,0.3);
}

/* deskstatus / termstatus — status pill */
body.vision #deskstatus,
body.vision #termstatus {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-radius: var(--radius-full);
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--text-2);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  height: 22px;
  line-height: 1 !important;
}
body.vision #deskstatus::before,
body.vision #termstatus::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--offline);
}
/* When status text contains "Connected", green up; CSS can't read text content
   reliably, so JS would need to add a class. Best-effort: when sibling Latency
   has content, assume connected — skip for now. */

/* Desktop console message overlay */
body.vision #p11DeskConsoleMsg,
body.vision #p12TermConsoleMsg {
  background: var(--bg-1) !important;
  color: var(--warn) !important;
  border: 1px solid var(--accent-border) !important;
  border-radius: var(--radius-3) !important;
  box-shadow: var(--shadow-2);
  font-family: var(--font-mono);
  font-size: 12px;
}

/* desktopButtons icon-strip (bottom of desktop) */
body.vision .desktopButtons {
  width: 18px !important;
  height: 18px !important;
  padding: 4px;
  border-radius: var(--radius-2);
  cursor: pointer;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  margin: 0 1px;
  filter: invert(0.85) hue-rotate(180deg);
  transition: background .12s, border-color .12s, filter .12s;
}
body.vision .desktopButtons:hover {
  background: var(--bg-4);
  border-color: var(--accent-border);
  filter: invert(1) hue-rotate(180deg) brightness(1.1);
}

/* bottombutton class on terminal — uniform pills */
body.vision .bottombutton {
  background: var(--bg-3) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-2) !important;
  height: 24px !important;
  padding: 0 8px !important;
  font-size: 12px !important;
  font-family: var(--font-mono) !important;
}
body.vision .bottombutton:hover {
  background: var(--bg-4) !important;
  border-color: var(--accent-border) !important;
}

/* DeskTools side panel (process list / services) */
body.vision #DeskTools {
  background: var(--bg-1) !important;
  border-left: 1px solid var(--border-2);
  color: var(--text-1);
}
body.vision #deskToolsAreaTop {
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-2);
  height: 36px;
  display: flex;
  align-items: center;
}
body.vision .deskToolsTopTab {
  height: 36px;
  line-height: 36px;
  padding: 0 12px;
  color: var(--text-2);
  cursor: pointer;
  position: relative;
  font-size: 12px;
  font-weight: 500;
  transition: color .12s;
}
body.vision .deskToolsTopTab:hover { color: var(--text-0); }
body.vision .deskToolsTopTab.deskToolsTopTabSelected,
body.vision .deskToolsTopTab[style*="color:gray"] { color: var(--text-0); }
body.vision .deskToolsTopTab.deskToolsTopTabSelected::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 2px;
  background: var(--accent);
}
body.vision #DeskToolsRefreshButton {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--accent-2);
  font-size: 12px;
}
body.vision #deskToolsHeader,
body.vision #deskToolsServiceHeader {
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-2);
  height: 28px;
  display: flex;
  align-items: center;
  padding: 0 8px;
}
body.vision #deskToolsHeader a,
body.vision #deskToolsServiceHeader a {
  color: var(--text-2);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.04em;
  cursor: pointer;
}
body.vision #deskToolsHeader a:hover,
body.vision #deskToolsServiceHeader a:hover { color: var(--text-0); text-decoration: none; }
body.vision #DeskToolsProcesses,
body.vision #DeskToolsServices {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--bg-1);
}

/* Tools button — toggle dock for processes/services panel */
body.vision #DeskToolsButton { margin: 0 4px; }

/* p11/12/13 inner Connect / Disconnect / RDP buttons — group */
body.vision .areaHead > div > input[type=button],
body.vision .areaHead > div > span > input[type=button] {
  height: 28px;
  margin: 0 !important;
}
body.vision .areaHead > div > span { margin-right: 4px; }

/* Latency / timer in foot */
body.vision #DeskLatency,
body.vision #DeskTimer,
body.vision #TermTimer {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 12px;
  margin-right: 8px;
  line-height: 22px !important;
}

/* deskmetadata pill */
body.vision #deskmetadata {
  color: var(--text-3);
  font-size: 11px;
  margin-left: 8px;
}

/* Terminal main area background */
body.vision #termTable,
body.vision #termarea3x {
  background: #000;
}
body.vision #termarea3xdiv,
body.vision #Term { background: #000; }

/* p11warning / p12warning / p13warning callout (top of pane).
   IMPORTANT: base style.css keeps these `display:none` and JS reveals them
   (inline `display:block`) only when the KVM feature is off or the device is
   powered off. Do NOT set `display` here — forcing flex made the banners show
   on every connected device (false "not powered on" / "KVM disabled"). Layout
   props below stay inert until the shown-state rule (further down) flips them
   to flex. */
body.vision #p11warning,
body.vision #p12warning,
body.vision #p13warning,
body.vision #p11warning2,
body.vision #p12warning2 {
  align-items: center;
  gap: 8px;
  cursor: pointer;
  margin: 8px 0;
  transition: filter .12s;
}
/* flex layout ONLY once JS has revealed the banner (inline display:block) */
body.vision #p11warning[style*="display:block"], body.vision #p11warning[style*="display: block"],
body.vision #p12warning[style*="display:block"], body.vision #p12warning[style*="display: block"],
body.vision #p13warning[style*="display:block"], body.vision #p13warning[style*="display: block"],
body.vision #p11warning2[style*="display:block"], body.vision #p11warning2[style*="display: block"],
body.vision #p12warning2[style*="display:block"], body.vision #p12warning2[style*="display: block"] {
  display: flex !important;
}
body.vision #p11warning:hover,
body.vision #p12warning:hover,
body.vision #p13warning:hover,
body.vision #p11warning2:hover,
body.vision #p12warning2:hover { filter: brightness(1.1); }
body.vision .icon2 {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  background: var(--warn);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/></svg>") center/contain no-repeat;
}
body.vision #p11warning .warningbox,
body.vision #p12warning .warningbox,
body.vision #p13warning .warningbox,
body.vision #p11warning2 .warningbox,
body.vision #p12warning2 .warningbox {
  flex: 1;
  background: var(--warn-bg) !important;
  color: var(--warn) !important;
  border: 1px solid var(--warn-bg) !important;
  border-left: 3px solid var(--warn) !important;
  border-radius: var(--radius-2) !important;
  padding: var(--space-3) !important;
}

/* DeskParent + Desk canvas centering */
body.vision #DeskParent {
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
}

/* CTRL keys / special key send row */
body.vision #DeskControlSpan {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  cursor: pointer;
}
body.vision #DeskControlSpan input[type=checkbox] { margin: 0; }
body.vision #DeskControlSpan:has(input:checked) {
  background: var(--accent-bg);
  border-color: var(--accent-border);
  color: var(--accent-2);
}

/* Input lock toggle icon */
body.vision #DeskInputLockedButton .desktopButtons {
  filter: invert(0.5) sepia(1) saturate(8) hue-rotate(310deg);
}

/* ─── Phase 3c++: p11/p12/p13 toolbar refinement (Desktop / Term / Files) */

/* Override: keep toolbar single-row, scroll horizontally if needed */
body.vision .areaHead,
body.vision .areaFoot,
body.vision #deskarea1,
body.vision #deskarea4,
body.vision #termTable .areaHead,
body.vision #termTable .areaFoot,
body.vision #p13toolbar .areaHead {
  flex-wrap: nowrap !important;
  overflow-x: auto;
  overflow-y: hidden;
  min-height: 40px !important;
  padding: 8px 12px !important;
  gap: 8px;
  scrollbar-width: thin;
}
body.vision .areaHead::-webkit-scrollbar,
body.vision .areaFoot::-webkit-scrollbar { height: 4px; }

/* Each row-half (left + toright2) — keep inline, do not wrap */
body.vision .areaHead > div,
body.vision .areaFoot > div {
  flex-wrap: nowrap !important;
  flex-shrink: 0;
  gap: 8px;
  display: inline-flex !important;
  align-items: center;
}
/* .toright2 is the FIRST child in source but should appear LAST visually.
   In default3 / default.handlebars the original CSS used float:right; we
   override the flow with `order: 2` so flex puts it after its later
   siblings (which default to order: 0). */
body.vision .areaHead > .toright2,
body.vision .areaFoot > .toright2 {
  order: 2 !important;
  margin-left: auto;
  flex-wrap: nowrap !important;
  flex-shrink: 0;
}
body.vision .areaHead > div:not(.toright2),
body.vision .areaFoot > div:not(.toright2) {
  order: 1 !important;
}

/* Slim down primary buttons in toolbars */
body.vision .areaHead input[type=button],
body.vision .areaFoot input[type=button],
body.vision #deskarea1 input[type=button],
body.vision #deskarea4 input[type=button] {
  height: 28px !important;
  padding: 0 var(--space-3) !important;
  font-size: var(--fs-small) !important;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Connect-button group — segmented control feel */
body.vision .areaHead > div > span[id*="connectbutton"],
body.vision .areaHead > div > span[id*="disconnectbutton"] {
  margin-right: 0 !important;
}
body.vision .areaHead > div > span[id*="connectbutton"] input,
body.vision .areaHead > div > span[id*="disconnectbutton"] input {
  border-radius: 0 !important;
  border-right-width: 0 !important;
  margin: 0 !important;
}
body.vision .areaHead > div > span[id*="connectbutton"]:first-of-type input { border-radius: var(--radius-2) 0 0 var(--radius-2) !important; }
body.vision .areaHead > div > span[id*="disconnectbutton"] input {
  border-radius: 0 var(--radius-2) var(--radius-2) 0 !important;
  border-right-width: 1px !important;
}
body.vision #connectbutton1,
body.vision #connectbutton2 {
  background: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  border-color: var(--accent-border) !important;
}
body.vision #connectbutton1:hover,
body.vision #connectbutton2:hover {
  background: var(--accent-bg-strong) !important;
}
body.vision #disconnectbutton1,
body.vision #disconnectbutton2 {
  background: var(--danger-bg) !important;
  color: var(--danger) !important;
  border-color: rgba(248,113,113,0.3) !important;
}
body.vision #disconnectbutton1:hover,
body.vision #disconnectbutton2:hover {
  background: rgba(248,113,113,0.18) !important;
}

/* Icon strip (bottom of desktop) — transparent chips, hover-bg only */
body.vision .areaFoot span[id^="Desk"][title]:not(#DeskToolsButton):not(#DeskControlSpan):not(#DeskLatency):not(#DeskTimer):not(#DeskMonitorSelectionSpan) {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: var(--radius-2);
  background: transparent !important;
  border: 1px solid transparent !important;
  transition: background .12s, border-color .12s;
  flex-shrink: 0;
}
body.vision .areaFoot span[id^="Desk"][title]:hover {
  background: var(--bg-3) !important;
  border-color: var(--border-2) !important;
}

/* Override per-button heavy frame from earlier rule */
body.vision .desktopButtons {
  width: 16px !important;
  height: 16px !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  margin: 0 !important;
  filter: invert(0.85) brightness(1.1) !important;
  transition: filter .12s;
  cursor: pointer;
}
body.vision .areaFoot span[id^="Desk"][title]:hover .desktopButtons {
  filter: invert(1) sepia(1) saturate(6) hue-rotate(150deg) !important;
}

/* Special icons: record button keeps red dot */
body.vision #DeskRecordButton .desktopButtons[src*="film"] { filter: invert(0.85) brightness(1.1) !important; }
body.vision #DeskRecordButton.recording .desktopButtons[src*="film"] { filter: invert(0.5) sepia(1) saturate(8) hue-rotate(330deg) !important; }
body.vision #DeskInputLockedButton .desktopButtons { filter: invert(0.5) sepia(1) saturate(8) hue-rotate(330deg) !important; }

/* deskareaicon — smaller, single-row */
body.vision .deskareaicon {
  width: 28px !important;
  height: 28px !important;
  font-size: 13px !important;
  flex-shrink: 0;
}

/* status pill height-match */
body.vision #deskstatus,
body.vision #termstatus,
body.vision #p13Status {
  height: 24px !important;
  flex-shrink: 0;
  padding: 0 8px !important;
}

/* deskkeys + send group — tight */
body.vision #deskkeys,
body.vision #specialkeylist {
  height: 28px !important;
  padding: 0 8px !important;
  font-size: 12px !important;
  max-width: 160px;
  flex-shrink: 0;
}
body.vision #DeskWD,
body.vision #DeskClip,
body.vision #DeskType,
body.vision #DeskESC,
body.vision #specialkeylistinput {
  height: 28px !important;
  padding: 0 8px !important;
}

/* DeskControlSpan — keep wider, label readable */
body.vision #DeskControlSpan {
  height: 28px !important;
  padding: 0 8px !important;
  font-size: 12px;
  flex-shrink: 0;
}

/* Tools button + Latency + Timer alignment */
body.vision #DeskLatency,
body.vision #DeskTimer,
body.vision #TermTimer {
  height: 28px;
  display: inline-flex !important;
  align-items: center;
  line-height: 1 !important;
  padding: 0 4px;
  flex-shrink: 0;
}
body.vision #DeskToolsButton { height: 28px !important; flex-shrink: 0; }

/* Caps/scroll/num lock pills — fix absolute positioning collision.
   default.handlebars wraps them in a `div style="position:absolute;
   right:16px;margin-top: -14px;..."` that crashes into the area-head
   toolbar below. (An earlier top:80px placement assumed the warning
   callouts were visible; with them hidden it landed on the toolbar's
   Actions/Settings buttons.) Anchor them in the title row instead,
   left of the fullscreen toggle. */
body.vision #p11 > div[style*="position:absolute"][style*="right:16px"] {
  position: absolute !important;
  right: 110px !important;
  top: 22px !important;
  margin-top: 0 !important;
  z-index: 5;
}
body.vision #p11capslock,
body.vision #p11scrolllock,
body.vision #p11numlock {
  margin-left: 4px !important;
  height: 22px;
  line-height: 1 !important;
  display: inline-flex !important;
  align-items: center;
}

/* p11warning / p12warning — only render when text visible (JS sets display) */
body.vision #p11warning[style*="display:none"],
body.vision #p12warning[style*="display:none"],
body.vision #p13warning[style*="display:none"],
body.vision #p11warning2[style*="display:none"],
body.vision #p12warning2[style*="display:none"] { display: none !important; }

/* The wrap-fallback for tight screens: at <720px allow row to wrap */
@media (max-width: 720px) {
  body.vision .areaHead,
  body.vision .areaFoot {
    flex-wrap: wrap !important;
    overflow-x: visible;
  }
}

/* areaHead2 / areaHead3 sub-toolbars (Files etc.) */
body.vision .areaHead2,
body.vision .areaHead3 {
  background: var(--bg-1) !important;
  border-bottom: 1px solid var(--border-2);
  padding: 8px 12px !important;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 40px;
}
body.vision .areaHead2 > div,
body.vision .areaHead3 > div {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
body.vision .areaHead2 input[type=button],
body.vision .areaHead3 input[type=button] { margin: 0 !important; }

/* p13 path crumb */
body.vision #p13currentpath {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-2);
  padding: 4px 8px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
}

/* p13 file table */
body.vision #p13filetable {
  background: var(--bg-0);
  border: 1px solid var(--border-2);
  border-top: 0;
  border-bottom: 0;
  min-height: 220px;
  position: relative;
}
body.vision #p13toolbarBottom {
  border-top: 1px solid var(--border-2);
}
body.vision #p13toolbarBottom td.style6 {
  background: var(--bg-1) !important;
  color: var(--text-2);
  padding: 8px 12px;
  font-size: 12px;
  border-radius: 0 0 var(--radius-3) var(--radius-3);
  border: 1px solid var(--border-2);
  border-top: 0;
}

/* p13 / p11 toast (success/fail) — guard against leaking when hidden */
body.vision #p13bigok,
body.vision #p13bigfail,
body.vision #p11bigok,
body.vision #p11bigfail {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 120px;
  height: 120px;
  border-radius: var(--radius-full);
  align-items: center;
  justify-content: center;
  font-size: 64px !important;
  z-index: 100;
  pointer-events: none;
  animation: vision-toast-pop .42s ease-out forwards;
}
body.vision #p13bigok:not([style*="display: none"]):not([style*="display:none"]),
body.vision #p13bigfail:not([style*="display: none"]):not([style*="display:none"]),
body.vision #p11bigok:not([style*="display: none"]):not([style*="display:none"]),
body.vision #p11bigfail:not([style*="display: none"]):not([style*="display:none"]) {
  display: flex !important;
}
body.vision #p13bigok,
body.vision #p11bigok {
  background: var(--online-bg);
  color: var(--online) !important;
  border: 2px solid var(--online);
}
body.vision #p13bigfail,
body.vision #p11bigfail {
  background: var(--danger-bg);
  color: var(--danger) !important;
  border: 2px solid var(--danger);
}

/* p13 console message overlay */
body.vision #p13FilesConsoleMsg {
  background: rgba(0,0,0,0.7) !important;
  color: var(--warn) !important;
  border: 1px solid var(--accent-border) !important;
  border-radius: var(--radius-3) !important;
  font-family: var(--font-mono);
  font-size: 12px;
  backdrop-filter: blur(6px);
}

/* p14 AMT iframe */
body.vision #p14iframe {
  width: 100%;
  height: calc(100vh - 200px);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  background: var(--bg-1);
}
/* AMT desktop-redirect canvas + native toolbars — keep them inside the dark theme */
body.vision #p14 #DeskParent,
body.vision #p14 [id*='deskarea'],
body.vision #p14 .DeskArea,
body.vision #p14 canvas { background: #000 !important; }
body.vision #p14 .areaHead,
body.vision #p14 .areaFoot {
  background: var(--bg-1) !important;
  color: var(--text-1) !important;
  border-top: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
}

/* p15 console pane */
body.vision #consoleTable {
  width: 100%;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  overflow: hidden;
}
body.vision #p15agentConsole {
  background: var(--bg-0) !important;
  height: calc(100vh - 320px);
  padding: 0;
}
body.vision #p15agentConsoleText {
  background: var(--bg-0);
  color: var(--text-1);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  padding: 12px 16px;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
}
body.vision #p15consoleText {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  font-family: var(--font-mono) !important;
  font-size: 13px !important;
  height: 30px !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
}
body.vision #p15consoleText:focus {
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg) !important;
}
body.vision #p15coreName {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 0 8px;
}
body.vision #p15statetext {
  color: var(--text-2);
  font-size: 12px;
}

/* areaProgress / consoleprogressbar */
body.vision .areaProgress {
  background: var(--bg-2);
  height: 3px;
  overflow: hidden;
  margin: 0;
}
body.vision #consoleprogressbar {
  background: var(--accent);
  height: 100%;
  transition: width .25s;
}

/* p17 details / Live Graph */
body.vision #p17graph {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px;
  margin-bottom: 12px;
}
body.vision #p17graph img { display: none; }
body.vision .DevSt b {
  color: var(--text-0);
  font-size: 13px;
  font-weight: 600;
}
body.vision #p17info2 {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px;
}

/* p18 Software — kill light toolbar */
body.vision #p18toolbar {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border: 1px solid var(--border-2) !important;
  border-bottom: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3);
  padding: 12px 16px !important;
  display: flex !important;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
body.vision #p18SearchInput {
  height: 30px;
  width: 250px !important;
}
body.vision #p18Status[style*="color:gray"],
body.vision #p18Status {
  color: var(--text-2) !important;
  font-size: 12px;
}
body.vision #p18info {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-top: 0;
  border-radius: 0 0 var(--radius-3) var(--radius-3);
  padding: var(--space-4) !important;
  min-height: 220px;
}
body.vision #p18info > div[style*="color:gray"],
body.vision #p18html > div[style*="color:gray"] {
  color: var(--text-3) !important;
}
body.vision #p18html i { color: var(--text-3); }

/* p19 Plugins page */
body.vision #p19headers {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border-2);
  margin-bottom: 12px;
}
body.vision #p19headers > * {
  padding: 8px 12px;
  background: transparent;
  color: var(--text-2);
  border-radius: var(--radius-2) var(--radius-2) 0 0;
  cursor: pointer;
  font-weight: 500;
  font-size: 12px;
}
body.vision #p19headers > *:hover { color: var(--text-0); background: var(--bg-2); }
body.vision #p19pages {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px;
  min-height: 220px;
}

/* p20 mesh header */
body.vision #p20 #MainMeshImage,
body.vision #p20 picture#MainMeshImage {
  display: block !important;
  filter: drop-shadow(0 0 32px var(--accent-bg-strong));
  opacity: 0.9;
}
body.vision #p20info,
body.vision #p20info2 {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px 16px;
  margin: 12px 0;
  color: var(--text-1);
}

/* p21 mesh-summary chart grid */
body.vision #p21main > div > div[style*="display:table"] {
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px !important;
  width: 100% !important;
}
body.vision #meshPowerChartDiv,
body.vision #meshOsChartDiv,
body.vision #meshConnChartDiv,
body.vision #meshSecurityChartDiv {
  width: auto !important;
  max-width: none !important;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px !important;
}
body.vision #meshPowerChartDiv > div:first-child,
body.vision #meshOsChartDiv > div:first-child,
body.vision #meshConnChartDiv > div:first-child,
body.vision #meshSecurityChartDiv > div:first-child {
  font-size: 12px !important;
  font-weight: 500;
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 12px !important;
}
body.vision #p21info {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px 16px;
  margin-top: 12px;
}

/* p30 / p51 user header avatar — replace 200x stock with accent disc */
body.vision #p30 picture#MainUserImage,
body.vision #p30 #MainUserImageEx,
body.vision #p51 picture#MainUserImage {
  display: none !important;
}
body.vision #p30 td:last-child::before,
body.vision #p51 td:last-child::before {
  content: '';
  display: block;
  width: 120px;
  height: 120px;
  margin: 0 auto;
  border-radius: var(--radius-full);
  background:
    radial-gradient(circle at 30% 30%, var(--accent), var(--accent-deep)) 0 0/100% 100%,
    var(--bg-3);
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 32px -4px var(--accent-bg-strong);
}
body.vision #MainUserState {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-2);
  font-weight: 500;
}
body.vision #p30html,
body.vision #p30html2,
body.vision #p30html3,
body.vision #p51group,
body.vision #p51group2 {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px 16px;
  margin-bottom: 12px;
}

/* User-auth-strategy logo (OAuth provider) */
body.vision .userAuthStrategyLogo {
  border-radius: var(--radius-2);
  border: 1px solid var(--border-2);
  background: var(--bg-3);
  padding: 8px;
  width: 48px !important;
  height: 48px !important;
}

/* p40 server stats canvas */
body.vision #serverMainStats {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 8px;
  width: 100% !important;
  height: 380px !important;
  margin-top: 12px;
}

/* p41 trace status pill */
body.vision #p41traceStatus {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: var(--radius-full);
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--text-2);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-left: 4px;
}
body.vision #p41events {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  margin-top: 12px;
  padding: 8px;
  max-height: 60vh;
  overflow-y: auto;
}

/* p42 plugins "Notice" banner — gold inline */
body.vision #pluginRestartNotice,
body.vision .areaHead[style*="background-color:gold"] {
  background: var(--warn-bg) !important;
  background-color: var(--warn-bg) !important;
  border: 1px solid rgba(251,191,36,0.3) !important;
  border-radius: var(--radius-3);
  color: var(--warn) !important;
  margin: 8px 0;
}
body.vision #pluginRestartNotice b { color: var(--warn); }
body.vision #pluginNoneNotice {
  color: var(--text-3);
  font-size: 13px;
  padding: 40px 12px !important;
  background: var(--bg-1);
  border: 1px dashed var(--border-3);
  border-radius: var(--radius-3);
  margin-top: 8px;
}

/* p42 table */
body.vision #p42tbl {
  width: 100%;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  border-collapse: separate;
  border-spacing: 0;
  margin-top: 12px;
  overflow: hidden;
}
body.vision #p42tbl tr.DevSt th {
  background: var(--bg-2);
  color: var(--text-2);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.04em;
  font-weight: 500;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-3);
}

/* p43 plugin iframe */
body.vision #p43iframe {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
}

/* p52 recordings */
body.vision #p52recordings {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 8px;
  margin-top: 8px;
  min-height: 220px;
}

/* p60 reports */
body.vision #p60generatedReportContents,
body.vision #p60reports {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 12px 16px;
  margin-top: 12px;
}

/* p20info ".style10" / ".style10s" mesh detail tables */
body.vision .style10,
body.vision .style10s {
  width: 100%;
}
body.vision .style10 td,
body.vision .style10s td {
  padding: 8px 12px !important;
  border-bottom: 1px solid var(--border-2);
  font-size: 12px;
}
body.vision .style10 tr:last-child td,
body.vision .style10s tr:last-child td { border-bottom: 0; }
body.vision .style10 th,
body.vision .style10s th {
  background: var(--bg-2);
  color: var(--text-2);
  text-align: left;
  padding: 8px 12px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 500;
}

/* ─── Phase 4: default-mobile.handlebars overrides ─────────────────────── */

/* Body inline `font-family:'Trebuchet MS'…` — promote to Geist */
body.vision[style*="Trebuchet"] {
  font-family: var(--font-sans) !important;
  background: var(--bg-0) !important;
  color: var(--text-1) !important;
}

/* Mobile masthead — kill blue logo block */
body.vision #masthead[style*="background-color:#036"],
body.vision #masthead[style*="logo.png"] {
  background: var(--bg-1) !important;
  background-image:
    radial-gradient(ellipse 60% 90% at 0% 50%, rgba(34,211,238,0.10), transparent 70%) !important;
  background-repeat: no-repeat !important;
  border-bottom: 1px solid var(--border-2);
  height: 56px !important;
}
body.vision #masthead[style*="logo.png"] font {
  font-family: var(--font-sans) !important;
  color: var(--text-0) !important;
  text-shadow: none !important;
  font-size: 18px !important;
  letter-spacing: -0.02em;
}
body.vision #masthead[style*="logo.png"] div[style*="color:#c8c8c8"] font[style*="font-size:12px"] {
  color: var(--text-2) !important;
  font-size: 11px !important;
  font-weight: 400 !important;
}
body.vision #masthead[style*="logo.png"] > div > div:nth-child(2) font {
  color: var(--text-2) !important;
  font-size: 11px !important;
}

/* Mobile back-button "curve" tabs — modern button */
body.vision .menucurve {
  display: none !important;
}
body.vision td[onclick*="goBack"] > div[style*="background-color:#036"] {
  background: var(--bg-2) !important;
  background-color: var(--bg-2) !important;
  border-radius: var(--radius-3) !important;
  width: 44px !important;
  height: 44px !important;
  font-size: 18px !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-2);
  display: flex !important;
  align-items: center;
  justify-content: center;
  margin: 8px;
}
body.vision td[onclick*="goBack"] {
  color: var(--text-1) !important;
}

/* xdevicesBar — grey bottom filter bar */
body.vision #xdevicesBar[style*="background-color:#aaa"] {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  color: var(--text-1) !important;
  border-top: 1px solid var(--border-2);
  height: 44px !important;
}
body.vision #xdevicesBar input[type=search] {
  background: var(--bg-3) !important;
  background-color: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  height: 28px !important;
  padding: 0 8px !important;
  font-size: 12px;
}
body.vision #xdevicesBar span[onclick*="clearSearchInput"] b {
  color: var(--text-2) !important;
}
body.vision #xdevicesBar label {
  color: var(--text-2) !important;
  font-size: 12px;
}

/* tagSpan — was light-gray pill */
body.vision .tagSpan,
body.vision .night .tagSpan {
  background: var(--accent-bg) !important;
  background-color: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  border: 1px solid var(--accent-border) !important;
  border-radius: var(--radius-full) !important;
  padding: 1px 8px !important;
  font-size: 11px;
  font-weight: 500;
}

/* d3/d2 server action toolbar — was #d3d9d6 light grey */
body.vision #d3serveraction,
body.vision #d2serveraction {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 8px 12px !important;
  color: var(--text-1);
}
body.vision #d3serverfiles,
body.vision #d2serverfiles {
  background: var(--bg-0) !important;
  background-color: var(--bg-0) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3) !important;
  color: var(--text-1);
}

/* p5 mobile file table toolbar — was #d3d9d6 */
body.vision #p5toolbar td[style*="background-color:#d3d9d6"] {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border-top: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
}
body.vision #p5toolbar input[type=button] {
  margin: 2px !important;
  height: 32px;
}

/* Mobile device-info account image (128x128 stock) — hide, use disc */
body.vision #p3info > img#p2AccountImage,
body.vision div[id="p3info"] > img[src*="user-256.png"] {
  display: none !important;
}
body.vision #p3info::before {
  content: '';
  position: absolute;
  right: 16px; top: 16px;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  background:
    radial-gradient(circle at 30% 30%, var(--accent), var(--accent-deep)) 0 0/100% 100%,
    var(--bg-3);
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 16px -2px var(--accent-bg-strong);
}

/* p3 mobile My Account section headers + items */
body.vision #p3info strong:not(:has(span)) {
  display: inline-block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-2);
  font-weight: 600;
}
body.vision #p3info div[style*="margin-top: 4px"] {
  margin-top: 0 !important;
  padding: 8px 12px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-2);
}
body.vision #p3info div[style*="margin-top: 4px"]:first-child { border-radius: var(--radius-2) var(--radius-2) 0 0; }
body.vision #p3info div[style*="margin-top: 4px"]:last-child { border-radius: 0 0 var(--radius-2) var(--radius-2); border-bottom: 0; }
body.vision #p3info a[onclick*="account_"],
body.vision #p3info a[onclick*="showNotes"],
body.vision #p3info a[onclick*="toggleNightMode"] {
  color: var(--text-1) !important;
  font-weight: 500;
}
body.vision #p3info a:hover { color: var(--accent-2) !important; }

/* Mobile page-content background */
body.vision #page_content {
  background: var(--bg-0);
}

/* deskButton sticky icons on remote desktop on mobile */
body.vision .deskButton {
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-full);
  padding: 4px;
  width: 40px !important;
  height: 40px !important;
  filter: invert(0.9) hue-rotate(180deg);
  opacity: 0.85;
}
body.vision .deskButton:hover { opacity: 1; }

/* notificationCount mobile */
body.vision #notificationCount[style*="font-size:28px"] {
  background: var(--danger) !important;
  color: #fff !important;
  border-radius: var(--radius-full) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  width: 32px !important;
  height: 32px !important;
  top: 8px !important;
  right: 60px !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 12px var(--danger-bg);
}
body.vision #notificationCount #notificationCount2 {
  padding: 0 !important;
}

/* topMenuIcon (hamburger) */
body.vision #topMenuIcon {
  filter: invert(0.85);
  opacity: 0.85;
}
body.vision #topMenuIcon:hover { opacity: 1; }

/* Search input on mobile with bg #FFF inline */
body.vision input[style*="background-color:#FFF"] {
  background: var(--bg-3) !important;
  background-color: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
}

/* page_content position-absolute with bottom:32px etc. is fine */

/* Larger touch targets on mobile inputs */
@media (max-width: 768px) {
  body.vision input[type=button],
  body.vision input[type=submit],
  body.vision button {
    height: 36px;
    min-height: 36px;
  }
  body.vision input[type=text],
  body.vision input[type=email],
  body.vision input[type=password],
  body.vision input[type=search],
  body.vision input[type=number],
  body.vision select,
  body.vision textarea {
    min-height: 36px;
    font-size: 13px;
  }
  body.vision .lbbutton {
    width: 44px !important;
    height: 44px !important;
  }
}

/* ─── Phase 5: sharing.handlebars (public share page) ──────────────────── */

/* LeftSideToolBar — kill blue gradient, modern rail */
body.vision #LeftSideToolBar,
body.vision [id="LeftSideToolBar"][style*="linear-gradient"] {
  background: var(--bg-1) !important;
  background-image: none !important;
  border-right: 1px solid var(--border-2) !important;
  color: var(--text-2) !important;
  width: 56px !important;
  padding-top: 8px;
}
body.vision .slbbutton {
  width: 44px !important;
  height: 44px !important;
  margin: var(--space-2) auto !important;
  border-radius: var(--radius-3) !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  transition: background .12s, border-color .12s;
}
body.vision .slbbutton:hover {
  background: var(--bg-2) !important;
  border-color: var(--border-2) !important;
}
body.vision .slbbutton.slbbuttonsel,
body.vision .slbbutton.slbbuttonsel2 {
  background: var(--accent-bg) !important;
  border-color: var(--accent-border) !important;
}
body.vision .slbbutton > div[class^="slb"] {
  filter: brightness(0) invert(0.8) hue-rotate(180deg);
  width: 28px;
  height: 28px;
  position: relative !important;
  top: 0 !important;
  left: 0 !important;
}
body.vision .slbbutton.slbbuttonsel > div[class^="slb"],
body.vision .slbbutton.slbbuttonsel2 > div[class^="slb"] {
  filter: brightness(0) invert(0.6) sepia(1) saturate(8) hue-rotate(140deg);
}

/* sharing body inline bg black — already OK, but tighten page padding */
body.vision[style*="background-color:black"] {
  background: var(--bg-0) !important;
  color: var(--text-1) !important;
}

/* sharing top-right "X" close — match desktop */
body.vision #p11 #idx_deskFullBtn2,
body.vision #p12 #idx_termFullBtn2 {
  margin-left: 8px;
}

/* sharing footer status pill */
body.vision #deskstatus,
body.vision #termstatus,
body.vision #filesStatus { vertical-align: middle; }

/* ─── Phase 6: player.handlebars (session recording playback) ──────────── */

/* progress bar — accent fill, click target */
body.vision .areaProgress[onclick*="progressBarSeek"] {
  background: var(--bg-2) !important;
  height: 10px !important;
  border-radius: var(--radius-full);
  margin: 0 8px;
  cursor: pointer;
  position: relative;
}
body.vision .areaProgress[onclick*="progressBarSeek"] #progressbar {
  background: linear-gradient(90deg, var(--accent-deep), var(--accent)) !important;
  height: 100% !important;
  border-radius: var(--radius-full);
  box-shadow: 0 0 12px var(--accent-bg-strong);
  transition: width .08s linear;
}
body.vision .areaProgress[onclick*="progressBarSeek"]:hover {
  background: var(--bg-3) !important;
}

/* timespan — monospace clock */
body.vision #timespan {
  font-family: var(--font-mono);
  color: var(--text-1);
  font-size: 13px;
  padding: 4px 8px !important;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
}

/* metadatadiv */
body.vision #metadatadiv[style*="color:lightgrey"] {
  color: var(--text-2) !important;
  font-family: var(--font-mono);
  font-size: 12px;
  background: rgba(0,0,0,0.4);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  margin: 12px;
  max-width: 480px;
}

/* Player dialog (custom, not Q-dialog) */
body.vision #dialog,
body.vision #player #dialog {
  background: var(--bg-2) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-4) !important;
  box-shadow: var(--shadow-pop) !important;
  color: var(--text-1) !important;
}
body.vision #dialogHeader {
  background: var(--bg-3);
  color: var(--text-0);
  font-weight: 600;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-2);
  border-radius: var(--radius-4) var(--radius-4) 0 0;
  display: flex;
  align-items: center;
}
body.vision #id_dialogtitle { flex: 1; }
body.vision #id_dialogclose {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-2);
  cursor: pointer;
  color: var(--text-2);
  margin-left: auto;
  order: 99;
}
body.vision #id_dialogclose:hover { color: var(--danger); background: var(--danger-bg); }
body.vision #dialogBody { padding: 16px; }
body.vision #idx_dlgButtonBar {
  background: var(--bg-1);
  padding: 12px 16px;
  border-top: 1px solid var(--border-2);
  border-radius: 0 0 var(--radius-4) var(--radius-4);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Player speed dropdown */
body.vision #PlaySpeed {
  margin: 0 4px;
}

/* ─── Phase 7: mstsc.handlebars (Web-RDP connect form) ─────────────────── */

body.vision .signinform {
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-4);
  padding: 24px;
  box-shadow: var(--shadow-pop);
}
body.vision #computerName {
  color: var(--text-0) !important;
  font-size: 22px !important;
  font-weight: 600 !important;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
  text-align: center;
}
body.vision .formLabel {
  color: var(--text-2);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 500;
}
body.vision .formControl,
body.vision .formDropdown {
  background: var(--bg-4) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  padding: 8px 12px !important;
  font-size: 13px !important;
}
body.vision .formControl:focus,
body.vision .formDropdown:focus {
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg);
  outline: none;
}
body.vision .connectButton {
  background: var(--accent) !important;
  color: #001019 !important;
  border: 1px solid var(--accent) !important;
  border-radius: var(--radius-2) !important;
  font-weight: 500 !important;
  font-size: 13px !important;
  padding: 8px !important;
  margin-top: 12px !important;
  cursor: pointer;
  transition: background .12s;
}
body.vision .connectButton:hover { background: var(--accent-2) !important; }

/* ─── Phase 8: messenger.handlebars ────────────────────────────────────── */
/* (Loaded as standalone chat. Inherits .messenger.css.) */
body.vision .messenger-container,
body.vision #messenger {
  background: var(--bg-0);
  color: var(--text-1);
}
body.vision .messenger-msg {
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 8px 12px;
  margin: 4px 0;
}
body.vision .messenger-msg.own {
  background: var(--accent-bg);
  border-color: var(--accent-border);
  margin-left: auto;
}

/* Messenger bubbles override (chat) */
body.vision .remoteBubble {
  background: var(--bg-2) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: 12px 12px 12px 2px !important;
  padding: 8px 12px !important;
  max-width: 70%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4) !important;
}
body.vision .localBubble {
  background: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  border: 1px solid var(--accent-border) !important;
  border-radius: 12px 12px 2px 12px !important;
  padding: 8px 12px !important;
  max-width: 70%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4) !important;
}

/* Messenger top-bar icon buttons */
body.vision .topButton,
body.vision .topRedButton {
  border-radius: var(--radius-2) !important;
  background-color: var(--bg-3) !important;
  border: 1px solid var(--border-2) !important;
  filter: invert(0.9) hue-rotate(180deg);
  transition: background .12s, border-color .12s;
}
body.vision .topButton:hover {
  background-color: var(--bg-4) !important;
  border-color: var(--accent-border) !important;
}
body.vision .topRedButton:hover {
  background-color: var(--danger-bg) !important;
  border-color: rgba(248,113,113,0.4) !important;
}

/* Messenger icon sprite squares — neutralize grey bg */
body.vision .topButton[class*="icon"],
body.vision .topRedButton[class*="icon"] {
  background-color: var(--bg-3) !important;
}

/* File-transfer progress bar inside bubble (inline lightgray bg) */
body.vision [class*="Bubble"] div[style*="background-color:lightgray"] {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border: 1px solid var(--border-2);
}
body.vision [id*="FILEUP-PROGRESS"][style*="background-color:green"] {
  background: var(--online) !important;
  background-color: var(--online) !important;
}

/* Messenger input area */
body.vision #composeText,
body.vision #msgInput,
body.vision #messageInput {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2) !important;
  padding: 8px 12px !important;
}

/* Messenger main area */
body.vision[style*="font-family:Arial"] {
  font-family: var(--font-sans) !important;
  background: var(--bg-0) !important;
  color: var(--text-1) !important;
}

/* ─── Phase 9: utility pages (invite/agentinvite/download/error/message/terms) ── */

/* Shared: any masthead with the legacy logo + #036 — already fixed in mobile-login section.
   Make sure rule order has these working here too: */
body.vision .AgentInviteMasthead,
body.vision #masthead[style*="logo.png"] {
  background: var(--bg-1) !important;
  background-image:
    radial-gradient(ellipse 60% 90% at 0% 50%, rgba(34,211,238,0.10), transparent 70%) !important;
  background-repeat: no-repeat !important;
  border-bottom: 1px solid var(--border-2);
  height: 56px !important;
  overflow: visible !important;
}
body.vision .AgentInviteMasthead font,
body.vision #masthead font {
  color: var(--text-0) !important;
  text-shadow: none !important;
  font-family: var(--font-sans) !important;
  font-size: 18px !important;
}
body.vision .AgentInviteMasthead p#logoutControl,
body.vision #masthead p#logoutControl {
  color: var(--text-2) !important;
}

/* agentinvite — tab strip */
body.vision .tab {
  background: var(--bg-1) !important;
  background-color: var(--bg-1) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3) var(--radius-3) 0 0 !important;
  overflow: hidden;
  display: flex;
  gap: 0;
}
body.vision .tab button {
  background: transparent !important;
  color: var(--text-2) !important;
  border-right: 1px solid var(--border-2) !important;
  padding: 12px 16px !important;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.02em;
  cursor: pointer;
}
body.vision .tab button:hover {
  background: var(--bg-2) !important;
  background-color: var(--bg-2) !important;
  color: var(--text-0) !important;
}
body.vision .tab button.active {
  background: var(--accent-bg) !important;
  background-color: var(--accent-bg) !important;
  color: var(--accent-2) !important;
  box-shadow: inset 0 -2px 0 var(--accent);
}
body.vision .tabcontent {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-top: 0;
  border-radius: 0 0 var(--radius-3) var(--radius-3);
  padding: 16px 16px !important;
  color: var(--text-1);
}

/* Inline error/success spans (e.g. <b style=color:#8C001A>) */
body.vision [style*="color:#8C001A"],
body.vision [style*="color: #8C001A"],
body.vision .msg.error b {
  color: var(--danger) !important;
}
body.vision .msg.success b,
body.vision .msg.success {
  color: var(--online) !important;
}

/* invite.handlebars invite-code card (#DDD background already overridden) */
body.vision #inviteCode {
  background: var(--bg-3) !important;
  color: var(--text-0) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-3) !important;
  padding: 12px 16px !important;
  font-family: var(--font-mono) !important;
  letter-spacing: 0.1em !important;
}
body.vision #inviteCode:focus {
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg) !important;
}

/* error404 / message page — center card */
body.vision #message[style*="font-size:16px"],
body.vision #message {
  color: var(--text-1);
  font-size: 13px;
}

/* terms.handlebars — long-form document */
body.vision #termsContent,
body.vision .termsBody,
body.vision .terms-body {
  max-width: 760px;
  margin: 28px auto;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-4);
  padding: 24px 32px;
  line-height: 1.6;
  color: var(--text-1);
}

/* download.handlebars — link list */
body.vision .downloadList,
body.vision #downloadlinks {
  display: grid;
  gap: 8px;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  padding: 16px;
}

/* ─────────────────────────────────────────────────────────────────────────
   ─── POLISH PASS 2 — UI/UX refinement ────────────────────────────────────
   Density, motion, semantic affordance, accessibility, light/dark parity.
   ────────────────────────────────────────────────────────────────────── */

/* Smooth scrolling — respects reduced-motion via the global guard below */
html { scroll-behavior: smooth; }

/* Tabular numerals on data-heavy surfaces — prevents column jitter on
   live-updating metrics (latency, counts, timestamps, IPs). */
body.vision table,
body.vision .pTable,
body.vision #xdevices,
body.vision #p11 .latency,
body.vision #termstatus,
body.vision #deskstatus,
body.vision .traceEvent,
body.vision code, body.vision kbd, body.vision pre,
body.vision .badge,
body.vision time,
body.vision [class*="count"],
body.vision [class*="metric"] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'ss01', 'cv11';
}

/* Subtle leading status dot so color is not the only meaning.
   Skips elements that already render a glyph/dot via background or ::before. */
body.vision span.green:not(:empty):not([style*="background"]):not(.has-icon)::before,
body.vision span.online:not(:empty):not([style*="background"]):not(.has-icon)::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--online);
  margin-right: 4px;
  vertical-align: 0.08em;
  box-shadow: 0 0 0 2px var(--online-bg);
}
body.vision span.red:not(:empty):not([style*="background"]):not(.has-icon)::before,
body.vision span.offline:not(:empty):not([style*="background"]):not(.has-icon)::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--danger);
  margin-right: 4px;
  vertical-align: 0.08em;
  box-shadow: 0 0 0 2px var(--danger-bg);
}
body.vision span.yellow:not(:empty):not([style*="background"]):not(.has-icon)::before,
body.vision span.warn:not(:empty):not([style*="background"]):not(.has-icon)::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--warn);
  margin-right: 4px;
  vertical-align: 0.08em;
  box-shadow: 0 0 0 2px var(--warn-bg);
}

/* Bootstrap modal backdrop — strengthen for contrast (default is too pale
   over a dark app shell so the modal floats poorly). */
body.vision .modal-backdrop,
body.vision .modal-backdrop.show {
  background-color: #000;
  opacity: 0.62 !important;
  backdrop-filter: blur(2px);
}
body.lightmode .modal-backdrop,
body.vision.lightmode .modal-backdrop {
  background-color: #0b1220;
  opacity: 0.42 !important;
}
body.vision .modal-content {
  border-radius: var(--radius-4) !important;
  box-shadow: var(--shadow-pop);
  overflow: hidden;
}
body.vision .modal-header { border-top-left-radius: var(--radius-4); border-top-right-radius: var(--radius-4); }
body.vision .modal-footer { border-bottom-left-radius: var(--radius-4); border-bottom-right-radius: var(--radius-4); }

/* Dialog entrance — subtle scale+fade. MeshCentral built-in dialog uses
   #dialog / #dialogBody / #idx_dlgButtonBar — give it the same treatment. */
@keyframes vision-dialog-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.97); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes vision-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
body.vision #dialog[style*="display: block"],
body.vision #dialog[style*="display:block"] {
  animation: vision-dialog-in .18s ease-out both;
}
body.vision .modal.show .modal-dialog {
  animation: vision-modal-in .18s ease-out both;
}

/* Tighter, more semantic focus ring on interactive primitives. Global
   :focus-visible rule above already covers most cases; this overlays a
   crisp accent ring on the few surfaces where it gets visually washed
   (large dark tables, transparent toolbar icons). */
body.vision a:focus-visible,
body.vision .tab button:focus-visible,
body.vision .nav-link:focus-visible {
  border-radius: var(--radius-2);
}
body.vision input:focus-visible,
body.vision textarea:focus-visible,
body.vision select:focus-visible {
  box-shadow: 0 0 0 3px var(--accent-bg), 0 0 0 1px var(--accent-border) !important;
}

/* Hover/active state for nav links — small but reads as polished */
body.vision a {
  transition: color .14s ease, opacity .14s ease;
}

/* Skeleton shimmer for async loads — opt-in via .vision-skel */
@keyframes vision-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
body.vision .vision-skel {
  background: linear-gradient(
    90deg,
    var(--bg-2) 0%,
    var(--bg-3) 50%,
    var(--bg-2) 100%
  );
  background-size: 800px 100%;
  border-radius: var(--radius-2);
  animation: vision-shimmer 1.4s ease-in-out infinite;
}

/* Toolbar / icon button press feedback — many MeshCentral toolbar icons
   are plain <a><img></a> with no state. Add subtle scale on active. */
body.vision .nodeButton:active,
body.vision .lbbutton:active,
body.vision .pButton:active,
body.vision .gButton:active,
body.vision #topbar a:active {
  transform: scale(0.96);
  transition: transform .06s ease;
}

/* Improve link readability — underline only on hover (not :focus-visible
   since that already gets a ring) */
body.vision a:not(.btn):not(.nav-link):not(.lbbutton):hover {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--accent-border);
}

/* Card-like surfaces — soften edges + add micro elevation on hover where
   the element is a known clickable card. Opt-in via .vision-card. */
body.vision .vision-card {
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-4);
  padding: 16px 16px;
  box-shadow: var(--shadow-1);
  transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
body.vision .vision-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
  border-color: var(--border-3);
}

/* Dialog buttons row — make sure primary action stands out (rightmost) */
body.vision #idx_dlgButtonBar { gap: 8px; display: flex; justify-content: flex-end; }

/* Status pill text/icon row alignment */
body.vision #termstatus, body.vision #deskstatus {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* ─── Global motion-reduction guard ───────────────────────────────────────
   Catches every animation/transition the theme adds, including third-
   party (Bootstrap, xterm). Respects user preference. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body.vision *,
  body.vision *::before,
  body.vision *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── Lightmode specific touch-ups ──────────────────────────────────────── */
body.vision.lightmode .modal-content { box-shadow: var(--shadow-pop); }
body.vision.lightmode .traceEvent {
  background-color: var(--bg-2) !important;
  color: var(--text-1) !important;
  border-color: var(--border-2) !important;
}
/* Bootstrap default focus ring is blue — align to accent in lightmode */
body.vision.lightmode .form-control:focus,
body.vision.lightmode .form-select:focus {
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg) !important;
}

/* ─── Device icons — theme-aware monochrome (vision theme) ────────────── */
/* Replace MeshCentral's 3D PNG sprites with flat SVG masks painted in the
   current theme's text color. Same SVG works at 16px (list/Desktops view)
   and 50px (Columns view) because it's vector. Color auto-flips with
   light/dark via --text-1. */
body.vision .i1, body.vision .i2, body.vision .i3, body.vision .i4,
body.vision .i5, body.vision .i6, body.vision .i7, body.vision .i8,
body.vision .j1, body.vision .j2, body.vision .j3, body.vision .j4,
body.vision .j5, body.vision .j6, body.vision .j7, body.vision .j8 {
  background: none !important;
  background-image: none !important;
  background-color: var(--text-1) !important;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: 78%;
          mask-size: 78%;
  border-radius: 6px;
  transition: background-color .15s ease;
}
body.vision .j1, body.vision .j2, body.vision .j3, body.vision .j4,
body.vision .j5, body.vision .j6, body.vision .j7, body.vision .j8 {
  -webkit-mask-size: 88%;
          mask-size: 88%;
  border-radius: 3px;
}
body.vision .i1, body.vision .j1 { -webkit-mask-image: url(../images/vision-icons/dev1.svg);  mask-image: url(../images/vision-icons/dev1.svg); }
body.vision .i2, body.vision .j2 { -webkit-mask-image: url(../images/vision-icons/dev2.svg);  mask-image: url(../images/vision-icons/dev2.svg); }
body.vision .i3, body.vision .j3 { -webkit-mask-image: url(../images/vision-icons/dev3.svg);  mask-image: url(../images/vision-icons/dev3.svg); }
body.vision .i4, body.vision .j4 { -webkit-mask-image: url(../images/vision-icons/dev4.svg);  mask-image: url(../images/vision-icons/dev4.svg); }
body.vision .i5, body.vision .j5 { -webkit-mask-image: url(../images/vision-icons/dev5.svg);  mask-image: url(../images/vision-icons/dev5.svg); }
body.vision .i6, body.vision .j6 { -webkit-mask-image: url(../images/vision-icons/dev6.svg);  mask-image: url(../images/vision-icons/dev6.svg); }
body.vision .i7, body.vision .j7 { -webkit-mask-image: url(../images/vision-icons/dev7.svg);  mask-image: url(../images/vision-icons/dev7.svg); }
body.vision .i8, body.vision .j8 { -webkit-mask-image: url(../images/vision-icons/dev8.svg);  mask-image: url(../images/vision-icons/dev8.svg); }

/* Connected devices — paint in accent color for clear status signal. */
body.vision [class*=" i"]:not(.gray),
body.vision [class*=" j"]:not(.gray) {
  /* no-op placeholder so the rule below has higher specificity than the base */
}
body.vision div.i1:not(.gray), body.vision div.i2:not(.gray), body.vision div.i3:not(.gray),
body.vision div.i4:not(.gray), body.vision div.i5:not(.gray), body.vision div.i6:not(.gray),
body.vision div.i7:not(.gray), body.vision div.i8:not(.gray),
body.vision div.j1:not(.gray), body.vision div.j2:not(.gray), body.vision div.j3:not(.gray),
body.vision div.j4:not(.gray), body.vision div.j5:not(.gray), body.vision div.j6:not(.gray),
body.vision div.j7:not(.gray), body.vision div.j8:not(.gray) {
  background-color: var(--accent, #22d3ee) !important;
}

/* Disconnected (.gray) — neutralize MeshCentral's grayscale+opacity dim;
   we already paint the mask in --text-1 which gives correct contrast. */
body.vision .i1.gray, body.vision .i2.gray, body.vision .i3.gray,
body.vision .i4.gray, body.vision .i5.gray, body.vision .i6.gray,
body.vision .i7.gray, body.vision .i8.gray,
body.vision .j1.gray, body.vision .j2.gray, body.vision .j3.gray,
body.vision .j4.gray, body.vision .j5.gray, body.vision .j6.gray,
body.vision .j7.gray, body.vision .j8.gray {
  opacity: 0.55;
  filter: none;
  -webkit-filter: none;
}

/* ─── View-mode selector icons — theme-aware SVG masks ───────────────── */
/* Inner icon divs (.viewSelector1..N) used to load slices of views.png.
   Replace with theme-colored SVG masks; the button shell (.viewSelector
   parent) is already styled above. */
body.vision .viewSelector1,
body.vision .viewSelector2,
body.vision .viewSelector3,
body.vision .viewSelector4,
body.vision .viewSelector5,
body.vision .viewSelector7 {
  background: none !important;
  background-image: none !important;
  background-color: var(--text-2) !important;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: 78%;
          mask-size: 78%;
  transition: background-color .12s ease;
}
body.vision .viewSelector1 { -webkit-mask-image: url(../images/vision-icons/view1.svg); mask-image: url(../images/vision-icons/view1.svg); }
body.vision .viewSelector2 { -webkit-mask-image: url(../images/vision-icons/view2.svg); mask-image: url(../images/vision-icons/view2.svg); }
body.vision .viewSelector3 { -webkit-mask-image: url(../images/vision-icons/view3.svg); mask-image: url(../images/vision-icons/view3.svg); }
body.vision .viewSelector7 { -webkit-mask-image: url(../images/vision-icons/view4.svg); mask-image: url(../images/vision-icons/view4.svg); }
body.vision .viewSelector5 { -webkit-mask-image: url(../images/vision-icons/expand.svg); mask-image: url(../images/vision-icons/expand.svg); }

/* Active button (.viewSelectorSel set by MeshCentral on parent) — paint
   the masked icon in the accent color so the selected mode is obvious. */
body.vision .viewSelectorSel .viewSelector1,
body.vision .viewSelectorSel .viewSelector2,
body.vision .viewSelectorSel .viewSelector3,
body.vision .viewSelectorSel .viewSelector4,
body.vision .viewSelectorSel .viewSelector5,
body.vision .viewSelectorSel .viewSelector7 {
  background-color: var(--accent) !important;
}
body.vision .viewSelector:hover .viewSelector1,
body.vision .viewSelector:hover .viewSelector2,
body.vision .viewSelector:hover .viewSelector3,
body.vision .viewSelector:hover .viewSelector4,
body.vision .viewSelector:hover .viewSelector5,
body.vision .viewSelector:hover .viewSelector7 {
  background-color: var(--text-1) !important;
}

/* ─── File browser icons (.fileIcon1..6) — replace base64 GIFs ────────── */
body.vision .fileIcon1, body.vision .fileIcon2, body.vision .fileIcon3,
body.vision .fileIcon4, body.vision .fileIcon5, body.vision .fileIcon6 {
  background: none !important;
  background-image: none !important;
  background-color: var(--text-1) !important;
  width: 16px; height: 16px;
  vertical-align: -3px;
  -webkit-mask-repeat: no-repeat;          mask-repeat: no-repeat;
  -webkit-mask-position: center;           mask-position: center;
  -webkit-mask-size: contain;              mask-size: contain;
  transition: background-color .12s ease;
}
body.vision .fileIcon1 { -webkit-mask-image: url(../images/vision-icons/folder.svg);    mask-image: url(../images/vision-icons/folder.svg); background-color: var(--accent) !important; }
body.vision .fileIcon2 { -webkit-mask-image: url(../images/vision-icons/file.svg);      mask-image: url(../images/vision-icons/file.svg); }
body.vision .fileIcon3 { -webkit-mask-image: url(../images/vision-icons/file-text.svg); mask-image: url(../images/vision-icons/file-text.svg); }
body.vision .fileIcon4 { -webkit-mask-image: url(../images/vision-icons/drive.svg);     mask-image: url(../images/vision-icons/drive.svg); }
body.vision .fileIcon5 { -webkit-mask-image: url(../images/vision-icons/usb.svg);       mask-image: url(../images/vision-icons/usb.svg); }
body.vision .fileIcon6 { -webkit-mask-image: url(../images/vision-icons/cd.svg);        mask-image: url(../images/vision-icons/cd.svg); }

/* ─── Mesh group icon (.mi) — 50x50 used in My Account device groups ──── */
body.vision .mi {
  background: none !important;
  background-image: none !important;
  background-color: var(--accent) !important;
  -webkit-mask: url(../images/vision-icons/mesh.svg) center/82% no-repeat;
          mask: url(../images/vision-icons/mesh.svg) center/82% no-repeat;
  border-radius: 8px;
}

/* ─── User row icons (.m1..m4) — replace images16.png slices ──────────── */
body.vision .m1, body.vision .m2, body.vision .m3, body.vision .m4 {
  background: none !important;
  background-image: none !important;
  background-color: var(--text-2) !important;
  -webkit-mask-repeat: no-repeat;          mask-repeat: no-repeat;
  -webkit-mask-position: center;           mask-position: center;
  -webkit-mask-size: 90%;                  mask-size: 90%;
}
body.vision .m1 { -webkit-mask-image: url(../images/vision-icons/user.svg);       mask-image: url(../images/vision-icons/user.svg); }
body.vision .m2 { -webkit-mask-image: url(../images/vision-icons/user.svg);       mask-image: url(../images/vision-icons/user.svg); }
body.vision .m3 { -webkit-mask-image: url(../images/vision-icons/user-group.svg); mask-image: url(../images/vision-icons/user-group.svg); }
body.vision .m4 { -webkit-mask-image: url(../images/vision-icons/user-group.svg); mask-image: url(../images/vision-icons/user-group.svg); }

/* ─── Power Status calendar — readable, theme-aware colors ────────────── */
/* Was using `yellow`, `blue`, `lightblue`, `blueviolet`, `darkgreen`,
   `lightseagreen` — clashing with dark theme. Remap to semantic tokens. */
body.vision .pwState {
  border-radius: 2px;
}
body.vision .pwsBlack         { background-color: var(--bg-1) !important; }
body.vision .pwsTransparent   { background-color: transparent !important; }
body.vision .pwsBlue,
body.vision .pwsBlue2         { background-color: var(--accent-deep) !important; }
body.vision .pwsLightblue     { background-color: var(--accent) !important; }
body.vision .pwsBlueviolet    { background-color: var(--info) !important; }
body.vision .pwsDarkgreen,
body.vision .pwsLightseagreen,
body.vision .pwsLightseagreen2 { background-color: var(--online) !important; }
body.vision .pwsYellow        { background-color: var(--warn) !important; }

/* Power calendar date rows — alt rows had hard-coded #DDD background
   leaving white-on-white text. Re-surface for dark theme. */
body.vision #p10html2 tr,
body.vision #p10html2 td {
  background-color: var(--bg-2) !important;
  color: var(--text-1) !important;
  border-color: var(--border-2) !important;
}
body.vision #p10html2 .altBack,
body.vision #p10html2 .altBack td {
  background-color: var(--bg-3) !important;
}
body.vision #p10html2 th {
  background-color: var(--bg-4) !important;
  color: var(--text-0) !important;
  border-color: var(--border-2) !important;
}

/* ─── Main device hero image — replace 3D PNG with line-art accent ────── */
/* #MainComputerImage uses icons256-*.png. Swap rendered src via content:. */
body.vision #MainComputerImage {
  content: url(../images/vision-icons/device-hero.svg);
  width: 140px !important;
  height: 140px !important;
  max-width: 140px;
  margin: 0 auto;
  opacity: 0.95 !important;
  filter: drop-shadow(0 0 24px rgba(34,211,238,0.15)) !important;
}

/* ─── Batch B: layout & polish fixes ─────────────────────────────────── */

/* My Devices Columns-view group overlap — cards from one group bleed into
   the next group's row. Force each group container to contain its float
   children + give a small visual gap between groups. */
body.vision .DevSt {
  display: flow-root;
  overflow: visible;
  padding: var(--space-2) var(--space-3);
  margin: 12px 0 4px;
  background-color: var(--bg-1);
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-2);
  position: relative;
  z-index: 5;
  box-sizing: border-box;
}

/* Device card grid (Columns view) — auto-fill grid for adaptive density.
   Cards reflow per viewport: 1 col mobile, 2-4 cols desktop. Honors 8dp
   rhythm: 16px gap, 24px between groups, 12px inner padding. */
body.vision [id^="DevxCol"] {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-3) var(--space-4);
  padding: var(--space-3) var(--space-3) var(--space-5);
  align-items: stretch;
  justify-items: stretch;
}
/* Desktops view grid. These rules used to identify a desktops tile by sniffing
   its inline `background-color:lightgray` — the KVM thumbnail hack. The tile now
   carries a real class (.devKvmTile / .devOfflineTile), so the selectors key on
   that instead; sniffing an inline style meant any change to the markup silently
   reclassified a tile as a Columns card (which is exactly what happened: tiles
   picked up card padding, centre alignment and a focus ring).
   Both tile kinds stretch, so columns are even. */
body.vision [id^="DevxCol"]:has(> .devKvmTile),
body.vision [id^="DevxCol"]:has(> .devOfflineTile) {
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  justify-content: start;
  align-items: stretch;
  justify-items: stretch;
}
body.vision [id^="DevxCol"] > .devKvmTile {
  background-color: var(--bg-2) !important;
  border: 1px solid var(--border-2) !important;
  border-radius: var(--radius-3);
  overflow: hidden;
  margin: 0 !important;
  color: var(--text-1) !important; /* name inherited near-black — unreadable */
}
/* The relay/notify badge (.deviceNotifyDot) anchors absolute to the tile's
   top-right and landed ON the name of small (not-connected) tiles. Reserve
   room for it in the header instead. */
body.vision [id^="DevxCol"] > .devKvmTile > div[tabindex] {
  padding-right: 32px !important;
}
body.vision [id^="DevxCol"] > .devKvmTile .deviceNotifyDot {
  top: 4px;
  right: 4px;
}
/* Columns view cards (every tile that is NOT a desktops tile) */
body.vision [id^="DevxCol"] > div:not(.devKvmTile):not(.devOfflineTile) {
  width: auto !important;
  margin: 0 !important;
  min-height: 56px;
  padding: 8px 12px !important;
  display: flex !important;
  align-items: center;
  gap: 12px;
  border-radius: var(--radius-2);
  background-color: var(--bg-2) !important;
  border: 1px solid var(--border-2);
  overflow: hidden;
  transition: border-color .15s ease, background-color .15s ease,
              transform .15s ease, box-shadow .15s ease;
}
body.vision [id^="DevxCol"] > div:not(.devKvmTile):not(.devOfflineTile):hover {
  border-color: var(--accent-border);
  background-color: var(--bg-3) !important;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px -6px rgba(0, 0, 0, 0.45),
              inset 0 0 0 1px var(--accent-border);
}
body.vision [id^="DevxCol"] > div:not(.devKvmTile):not(.devOfflineTile):focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent), inset 0 0 0 3px var(--accent-bg);
}
/* device name cell carries a JS-set inline width that blows out the grid track */
body.vision [id^="DevxCol"] .e2t,
body.vision [id^="DevxCol"] .e1t {
  width: auto !important;
  min-width: 0 !important;
  max-width: 100% !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Bigger gap between sections (group header → cards → next group). */
body.vision .DevSt {
  margin-top: 16px !important;
}
body.vision .DevSt:first-of-type {
  margin-top: 8px !important;
}
body.vision .devHeaderx {
  color: var(--text-1) !important;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* "Add Agent" / "Invite" group-header links — visible cyan with hover. */
body.vision .DevSt a[onclick*="addAgent"],
body.vision .DevSt a[onclick*="inviteAgent"] {
  color: var(--accent) !important;
  font-size: 12px !important;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: var(--radius-1);
  transition: background-color .12s, color .12s;
}
body.vision .DevSt a[onclick*="addAgent"]:hover,
body.vision .DevSt a[onclick*="inviteAgent"]:hover {
  background-color: var(--accent-bg);
  color: var(--accent-2) !important;
  text-decoration: none;
}

/* Files page breadcrumb (#p13currentpath) — promote from afterthought to
   a real breadcrumb bar; hide the standalone "Root" pill since the
   breadcrumb itself includes Root. */
body.vision #p13currentpath {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px 12px;
  background-color: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  font-size: 13px;
  color: var(--text-2);
  margin-left: 8px;
}
body.vision #p13currentpath a {
  color: var(--text-1);
  text-decoration: none;
  padding: 2px 4px;
  border-radius: var(--radius-1);
  transition: background-color .12s, color .12s;
}
body.vision #p13currentpath a:hover {
  background-color: var(--bg-3);
  color: var(--accent);
}

/* Server actions (My Server) — drop the empty 15px placeholder boxes
   that look like loading spinners; let the cyan links breathe. */
body.vision .p2AccountActions {
  display: none !important;
}
body.vision #p6 a[href]:not(.btn) {
  display: inline-block;
  padding: 4px 8px;
  margin: 2px 0;
  border-radius: var(--radius-1);
  transition: background-color .12s, color .12s;
}
body.vision #p6 a[href]:not(.btn):hover {
  background-color: var(--accent-bg);
  text-decoration: none;
}

/* Files-list empty state when device disconnected — surface a hint. */
body.vision #p13files:empty {
  display: flex !important;
  align-items: center;
  justify-content: center;
  min-height: 320px;
}
body.vision #p13files:empty::before {
  content: "Connect to the device to browse its files.";
  text-align: center;
  color: var(--text-3);
  font-size: 13px;
  padding: var(--space-5);
  font-style: italic;
}

/* Topbar account control — better Welcome / Logout typography. */
body.vision #logoutControl {
  font-size: 13px;
}
body.vision #logoutControl a {
  color: var(--accent) !important;
}
body.vision #logoutControl a:hover {
  color: var(--accent-2) !important;
  text-decoration: none;
}

/* ─── Batch C: polish ────────────────────────────────────────────────── */

/* Section headings — unify case + spacing across pages. */
body.vision h2, body.vision h3 {
  letter-spacing: -0.005em;
  font-weight: 600;
}
body.vision .style3 {
  font-weight: 600;
  color: var(--text-0);
  letter-spacing: 0.02em;
}

/* Native <select> dropdowns — match the vision form-control aesthetic. */
body.vision select:not(.form-select):not([class*="bs-"]) {
  background-color: var(--bg-4) !important;
  color: var(--text-1) !important;
  border: 1px solid var(--border-3) !important;
  border-radius: var(--radius-2);
  padding: 8px 12px;
  font-size: 13px;
  transition: border-color .12s, box-shadow .12s;
}
body.vision select:not(.form-select):not([class*="bs-"]):hover {
  border-color: var(--border-4) !important;
}
body.vision select:not(.form-select):not([class*="bs-"]):focus {
  outline: none;
  border-color: var(--accent-border) !important;
  box-shadow: 0 0 0 3px var(--accent-bg);
}

/* Native <input type=text> not styled by Bootstrap — bring into theme. */
body.vision input:not([type]):not(.form-control):not([class*="bs-"]),
body.vision input[type=text]:not(.form-control):not([class*="bs-"]):not(#username):not(#password):not([id*=token]),
body.vision input[type=input]:not(.form-control):not([class*="bs-"]) {
  background-color: var(--bg-4);
  color: var(--text-1);
  border: 1px solid var(--border-3);
  border-radius: var(--radius-2);
  padding: 8px 12px;
  font-size: 13px;
}
body.vision input:not([type]):focus:not([class*="bs-"]),
body.vision input[type=text]:focus:not([class*="bs-"]),
body.vision input[type=input]:focus:not([class*="bs-"]) {
  outline: none;
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px var(--accent-bg);
}

/* Toolbar icon images (User page download/person+/gear, etc.) — size up
   for hit target and color via CSS filter for dark theme legibility. */
body.vision #UsersUsersGeneralActions img,
body.vision #devListToolbar img,
body.vision .pTableToolbarButton img {
  width: 18px;
  height: 18px;
  opacity: 0.7;
  filter: invert(0.85) sepia(0.5) saturate(2) hue-rotate(155deg);
  transition: opacity .12s;
  vertical-align: middle;
}
body.vision #UsersUsersGeneralActions img:hover,
body.vision #devListToolbar img:hover,
body.vision .pTableToolbarButton img:hover {
  opacity: 1;
}

/* "OS Name" checkbox spacing — was crammed. */
body.vision input[type=checkbox] + label,
body.vision label > input[type=checkbox] {
  margin-right: 4px;
}

/* Disabled buttons — opacity:0.45 crushed already-muted text into
   unreadability. Signal disabled via a recessed surface + muted (but still
   legible, ~6:1) text instead of heavy dimming. */
body.vision input[type=button][disabled],
body.vision input[type=submit][disabled],
body.vision button[disabled],
body.vision input[type=button]:disabled,
body.vision button:disabled {
  opacity: 1;
  color: var(--text-2) !important;
  background: var(--bg-1) !important;
  border-color: var(--border-2) !important;
  cursor: not-allowed;
}

/* Left sidebar — soft active-state highlight already in place; ensure
   icons are crisp in both modes. */
body.vision #page_leftbar .lbbutton {
  border-radius: var(--radius-2);
  transition: background-color .12s;
}
body.vision #page_leftbar .lbbutton:hover {
  background-color: var(--bg-3);
}

/* Filter input on My Devices — larger / more prominent. */
body.vision #SearchInput {
  min-width: 240px;
  font-size: 13px;
}

/* Power calendar header — make day labels easier on the eye. */
body.vision #p10html2 th a img[src*="link4"] {
  filter: invert(0.7) sepia(0.5) saturate(3) hue-rotate(155deg);
  opacity: 0.8;
  vertical-align: middle;
  margin-right: 4px;
}

/* Tab bar (General / Stats / Console / Trace etc) — smoother active
   underline + hover. */
body.vision .topbar_td.style3x:not(.fullselect) {
  transition: color .12s;
}
body.vision .topbar_td.style3x:not(.fullselect):hover {
  color: var(--accent) !important;
}

/* Inline cyan "links pretending to be buttons" — make them feel clickable. */
body.vision a[href="#"][onclick]:not(.btn):not(.dropdown-item) {
  transition: color .12s;
}
body.vision a[href="#"][onclick]:not(.btn):not(.dropdown-item):hover {
  text-decoration: none;
  color: var(--accent-2) !important;
}

/* "n nodes" group count badge — pill style for clarity. */
body.vision .devHeaderx {
  display: inline-block;
  padding: 4px 8px;
  background-color: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-full);
  color: var(--accent) !important;
  font-size: 12px !important;
  font-weight: 500;
  letter-spacing: 0.02em;
}

/* Smooth scrollbars in vision (more discreet on dark). */
body.vision ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
body.vision ::-webkit-scrollbar-track {
  background: transparent;
}
body.vision ::-webkit-scrollbar-thumb {
  background-color: var(--border-3);
  border-radius: 6px;
  border: 2px solid var(--bg-0);
}
body.vision ::-webkit-scrollbar-thumb:hover {
  background-color: var(--border-4);
}

/* ─── Polish-again pass ──────────────────────────────────────────────── */

/* My Account avatar — was a floating cyan blob with disconnected "Change
   image" link. Make it a proper avatar card aligned to the top-right of
   the page header. */
/* keep the integrated flex frame defined earlier (~1428); do NOT re-float it */
body.vision #p2AccountImageFrame {
  position: static;
}
/* legacy 96px stock avatar — intent is the accent disc (::before), hide the img */
body.vision #p2AccountImage {
  display: none !important;
}
body.vision #p2AccountImageFrame a {
  font-size: 12px;
  color: var(--text-2) !important;
}
body.vision #p2AccountImageFrame a:hover {
  color: var(--accent) !important;
}

/* My Files / device Files file list rows — give them breathing room +
   hover affordance. */
body.vision #p5files .filelist,
body.vision #p13files .filelist {
  padding: var(--space-2) var(--space-3) !important;
  margin: 2px var(--space-2) !important;
  border-radius: var(--radius-2);
  display: flex !important;
  align-items: center;
  gap: var(--space-2);
  transition: background-color .12s;
}
body.vision #p5files .filelist:hover,
body.vision #p13files .filelist:hover {
  background-color: var(--bg-3);
}

/* Files toolbar — buttons in a card-style group. */
body.vision #p5toolbar,
body.vision #p13toolbar {
  padding: 8px !important;
  background-color: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  margin-bottom: 12px;
}

/* Files page "Root" pill on My Files — visually unify with breadcrumb. */
body.vision #p5folderlink {
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  background-color: var(--bg-3) !important;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  color: var(--text-1) !important;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  font-family: var(--font-sans) !important;
}
body.vision #p5folderlink:hover {
  background-color: var(--bg-4) !important;
  border-color: var(--accent-border);
}

/* Users page — Permissions column "User" / "Administrator" chip style. */
body.vision #UsersUsersGeneral td a[onclick*="showUserGroupDialog"],
body.vision td.userPermissionsLabel {
  display: inline-block;
  padding: 4px 8px;
  background-color: var(--accent-bg);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-full);
  color: var(--accent) !important;
  font-size: 12px;
  font-weight: 500;
}

/* Account Actions — wrap inline-styled Localization/Notification links
   into proper button-like cards matching the surrounding pattern. */
body.vision #p2 a[onclick*="account_showLocalization"],
body.vision #p2 a[onclick*="account_showAccountNoti"],
body.vision #p2 a[onclick*="account_manageWebRelay"] {
  display: inline-block;
  padding: 8px 12px;
  margin: 4px 4px 4px 0;
  background-color: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  color: var(--text-1) !important;
  text-decoration: none;
  font-size: 13px;
  transition: background-color .12s, border-color .12s, color .12s;
}
body.vision #p2 a[onclick*="account_showLocalization"]:hover,
body.vision #p2 a[onclick*="account_showAccountNoti"]:hover,
body.vision #p2 a[onclick*="account_manageWebRelay"]:hover {
  background-color: var(--bg-3);
  border-color: var(--accent-border);
  color: var(--accent) !important;
  text-decoration: none;
}

/* "DEVICE GROUPS" section spacing on Account page. */
body.vision #p2 #MyMeshList > div {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  margin: 4px 0;
  background-color: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-2);
  transition: border-color .12s, background-color .12s;
}
body.vision #p2 #MyMeshList > div:hover {
  border-color: var(--accent-border);
  background-color: var(--bg-3);
}

/* =====================================================================
   Device detail polish — heading icons, Details cards, Events row icons,
   Console status pill, offline Desktops-view tiles.  (audit follow-up)
   ===================================================================== */

/* ---- Panel heading icons (Events / Details) ---- */
body.vision .panelHeadIcon {
  display: inline-block;
  width: 22px;
  height: 22px;
  vertical-align: -4px;
  margin-right: 8px;
  background-color: var(--accent);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: 22px 22px;
  mask-size: 22px 22px;
}
body.vision .panelHeadIconEvents {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M3%2012a9%209%200%201%200%209-9%209.75%209.75%200%200%200-6.74%202.74L3%208'/%3E%3Cpath%20d='M3%203v5h5'/%3E%3Cpath%20d='M12%207v5l3%202'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M3%2012a9%209%200%201%200%209-9%209.75%209.75%200%200%200-6.74%202.74L3%208'/%3E%3Cpath%20d='M3%203v5h5'/%3E%3Cpath%20d='M12%207v5l3%202'/%3E%3C/svg%3E");
}
body.vision .panelHeadIconDetails {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='12'%20r='9'/%3E%3Cpath%20d='M12%2011v5'/%3E%3Cpath%20d='M12%208h.01'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='12'%20r='9'/%3E%3Cpath%20d='M12%2011v5'/%3E%3Cpath%20d='M12%208h.01'/%3E%3C/svg%3E");
}

/* ---- Details tab: card grid ---- */
body.vision #p17info2 .detailCardGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: var(--space-4);
  padding: var(--space-2) 0 var(--space-6);
  align-items: start;
}
body.vision #p17info2 .detailCard {
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  overflow: hidden;
  transition: border-color .12s, box-shadow .12s;
}
body.vision #p17info2 .detailCard:hover {
  border-color: var(--accent-border);
  box-shadow: var(--shadow-1);
}
body.vision #p17info2 .detailCardHead {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-1);
}
body.vision #p17info2 .detailCardIcon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.4));
}
body.vision #p17info2 .detailCardTitle {
  font-weight: 600;
  font-size: 13px;
  color: var(--text-0);
  letter-spacing: .2px;
}
body.vision #p17info2 .detailCardBody {
  padding: 12px 16px 12px;
  color: var(--text-1);
  font-size: 13px;
}
body.vision #p17info2 .detailCardBody table { width: 100%; }
body.vision #p17info2 .detailEmpty {
  padding: var(--space-12);
  text-align: center;
  color: var(--text-2);
}

/* ---- Device Events row icons (modernized, themed) ---- */
body.vision #p16events .si3, body.vision #p3events .si3,
body.vision #p16events .m2, body.vision #p3events .m2,
body.vision #p16events .relayIcon16, body.vision #p3events .relayIcon16 {
  background-image: none !important;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: 15px 15px; mask-size: 15px 15px;
}
body.vision #p16events .si3, body.vision #p3events .si3 {
  background-color: var(--text-2) !important;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='3'%20y='4'%20width='18'%20height='7'%20rx='1.5'/%3E%3Crect%20x='3'%20y='13'%20width='18'%20height='7'%20rx='1.5'/%3E%3Cpath%20d='M7%207.5h.01M7%2016.5h.01'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='3'%20y='4'%20width='18'%20height='7'%20rx='1.5'/%3E%3Crect%20x='3'%20y='13'%20width='18'%20height='7'%20rx='1.5'/%3E%3Cpath%20d='M7%207.5h.01M7%2016.5h.01'/%3E%3C/svg%3E");
}
body.vision #p16events .m2, body.vision #p3events .m2 {
  background-color: var(--accent) !important;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='8'%20r='4'/%3E%3Cpath%20d='M5%2020a7%207%200%200%201%2014%200'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='8'%20r='4'/%3E%3Cpath%20d='M5%2020a7%207%200%200%201%2014%200'/%3E%3C/svg%3E");
}
body.vision #p16events .relayIcon16, body.vision #p3events .relayIcon16 {
  background-color: var(--online) !important;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M9%2017H7A5%205%200%200%201%207%207h2'/%3E%3Cpath%20d='M15%207h2a5%205%200%200%201%200%2010h-2'/%3E%3Cpath%20d='M8%2012h8'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M9%2017H7A5%205%200%200%201%207%207h2'/%3E%3Cpath%20d='M15%207h2a5%205%200%200%201%200%2010h-2'/%3E%3Cpath%20d='M8%2012h8'/%3E%3C/svg%3E");
}

/* ---- Console agent-state pill ---- */
body.vision #p15statetext.consoleStatePill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-radius: var(--radius-full);
  font-size: 12px;
  font-weight: 600;
}
body.vision #p15statetext.consoleStatePill::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
}
body.vision #p15statetext.consoleStateOn  { color: var(--online);  background: var(--online-bg); }
body.vision #p15statetext.consoleStateOn::before  { background: var(--online); box-shadow: 0 0 6px var(--online); }
body.vision #p15statetext.consoleStateOff { color: var(--offline); background: var(--offline-bg); }
body.vision #p15statetext.consoleStateOff::before { background: var(--offline); }

/* ---- Desktops view tiles — ONE box contract for BOTH renderers ----
   default.handlebars draws two different tiles into the same CSS grid:
   .devKvmTile for online KVM-capable devices (updateDeviceViewHtml) and
   .devOfflineTile for everyone else. Only the second was ever themed, so a mixed
   row came out ragged: mismatched widths, a status label pinned at top:27px over
   an empty grey box, tiles that didn't stretch to the row height. Both now share
   the contract below — see design/UI-CONTRACT.md §7. */
body.vision .devOfflineTile,
body.vision .devKvmTile {
  width: auto;
  align-self: stretch;
  justify-self: stretch;
  display: flex !important;
  flex-direction: column;
  /* the grid container sets align-items:center, which shrink-wrapped the inner
     wrapper to its content (86px inside a 402px tile) — that, not the padding,
     is why tile contents looked like a narrow column floating in a wide box. */
  align-items: stretch !important;
  padding: 0 !important;   /* the inner wrapper owns the padding, not the tile */
  vertical-align: top;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-3);
  opacity: .92;
  overflow: hidden;
}
body.vision .devOfflineTile:hover,
body.vision .devKvmTile:hover { opacity: 1; border-color: var(--border-3); }
/* inner clickable wrapper must also be a flex column so the thumb can grow to
   the row height (set by taller live-KVM tiles), removing under-tile gaps. */
body.vision .devOfflineTile > div,
body.vision .devKvmBody {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  padding: var(--space-2) !important;
  cursor: pointer;
}
body.vision .devOfflineThumb,
body.vision .devKvmThumb {
  flex: 1 1 auto;
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-0);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-2);
  margin-bottom: var(--space-2);
  overflow: hidden;
  position: relative;
}
/* the live KVM canvas is appended into the thumb at runtime (its pixel size is
   computed by the view code); the placeholder icon steps aside once it lands. */
body.vision .devKvmThumb canvas {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-2);
}
body.vision .devKvmThumb:has(canvas) .devKvmIcon { display: none; }
body.vision .devOfflineIcon,
body.vision .devKvmIcon { opacity: .5; transform: scale(1.25); filter: grayscale(.4); }
body.vision .devOfflineTileOn .devOfflineIcon,
body.vision .devKvmTile .devKvmIcon { opacity: .8; filter: none; }
body.vision .devOfflineName,
body.vision .devKvmName {
  color: var(--text-1);
  font-size: var(--fs-small);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 var(--space-1);
  text-align: center;
}
body.vision .devOfflineState,
body.vision .devKvmState {
  color: var(--text-3);
  font-size: var(--fs-micro);
  margin-top: var(--space-1);
  padding: 0 var(--space-1) var(--space-1);
  text-align: center;
  cursor: pointer;
}
body.vision .devOfflineTileOn .devOfflineState { color: var(--online); }
/* KVM tiles are online devices whose *session* is not connected — colour the
   label as secondary text, not as an online/offline device state. */
body.vision .devKvmState { color: var(--text-2); }

/* Two view buttons were both titled "Desktops" and render identically; hide
   the redundant one so the Desktops view is a single, clear choice. */
body.vision #devViewButton5 { display: none !important; }

/* Single UI: the Modern/Bootstrap UI is retired (server always renders classic).
   Hide its remaining entry points — the "Try the new UI" promo + the toggle. */
body.vision #textnewui,
body.vision #uiViewButton7 { display: none !important; }

/* ---- Software tab (p18): theme the installed-apps table (overrides inline light colors) ---- */
body.vision #p18html table { border-collapse: collapse; width: 100%; }
body.vision #p18html thead tr,
body.vision #p18html thead th {
  background-color: var(--bg-3) !important;
  color: var(--text-1) !important;
  border-color: var(--border-2) !important;
}
body.vision #p18html tbody tr { background-color: var(--bg-1) !important; }
body.vision #p18html tbody tr:nth-child(even) { background-color: var(--bg-2) !important; }
body.vision #p18html tbody tr:hover { background-color: var(--accent-bg) !important; }
body.vision #p18html td {
  color: var(--text-1) !important;
  border-color: var(--border-1) !important;
}
body.vision #p18html th { border-color: var(--border-2) !important; }
body.vision #p18html h4 { color: var(--text-0); }
body.vision #p18toolbar {
  background-color: var(--bg-1) !important;
  border-bottom: 1px solid var(--border-2) !important;
}

/* =====================================================================
   Demo account banner (floating, bottom-right)
   ===================================================================== */
#demoBanner {
  display: none;
  position: fixed;
  right: 16px;
  /* Clears the fixed footer links (Verify Email / Terms & Privacy) that sit in the same corner --
     at 16px the banner covered them, and "Verify Email" is the one link a new trial user needs. */
  bottom: 48px;
  z-index: 1000;
  max-width: 340px;
  padding: 12px 16px;
  background: rgba(15, 21, 36, 0.92);
  backdrop-filter: blur(8px);
  border: 1px solid var(--accent-border, rgba(34, 211, 238, 0.35));
  border-radius: 10px;
  color: var(--text-1, #cbd4e1);
  font-size: 13px;
  line-height: 1.5;
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.6);
}
#demoBanner b { color: var(--accent, #22d3ee); }
#demoBanner a { color: var(--accent, #22d3ee); }

/* ─── Fix pass: terminal-view screenshot (2026-06-12) ─────────────────── */

/* uiMenuButton (♦) on app pages — same icon-button treatment the login
   page already has; base style.css anchors it absolute top-right. */
body.vision #uiMenuButton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 24px;
  border-radius: var(--radius-2);
  color: var(--text-3);
  font-size: 13px;
  cursor: pointer;
  transition: color .12s, background .12s;
}
body.vision #uiMenuButton:hover {
  color: var(--accent-2);
  background: var(--bg-2);
}
body.vision #uiMenu {
  position: absolute;
  right: 0;
  margin-top: 4px;
  background: var(--bg-2);
  border: 1px solid var(--border-3);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-pop);
  padding: 8px;
  z-index: 50;
}
body.vision .uiSelector {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-2);
  border: 1px solid var(--border-3);
  background: var(--bg-3);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color .12s, background .12s;
}
body.vision .uiSelector:hover {
  background: var(--bg-4);
  border-color: var(--accent-border);
}

/* Fullscreen toggle in session title rows carries float:right inline, which
   flex ignores — it rendered between the back arrow and the h1 looking like
   a broken device icon. Push it to the row end. */
body.vision #p11deviceNameHeader > div[id^="devListToolbarViewIcons"],
body.vision #p12title > div[id^="devListToolbarViewIcons"],
body.vision #p13title > div[id^="devListToolbarViewIcons"],
body.vision #p14title > div[id^="devListToolbarViewIcons"],
body.vision #p15title > div[id^="devListToolbarViewIcons"] {
  order: 9;
  margin-left: auto;
}
/* #p11title is itself a flex row (generic panel-title rule), so the header
   shrink-wraps and its h1 flex:1 has nothing to grow into — let it fill. */
body.vision #p11title > #p11deviceNameHeader { flex: 1 1 auto; }

/* Disconnected terminal is a pure black void — show a hint. #Term is the
   built-in renderer; #termarea3xdiv is the xterm.js container used when
   xterm is active. Both are empty until the first connect. */
body.vision #Term:empty::before,
body.vision #termarea3xdiv:empty::before {
  content: "Not connected — press Connect to start a session";
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 64px 16px;
  color: var(--text-3);
  font-size: 13px;
}

/* areaHead/areaFoot scroll horizontally when crowded, which pushed the
   right-side controls (✖ / Actions, Send) out of view. Pin them. */
body.vision .areaHead > .toright2,
body.vision .areaFoot > .toright2 {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--bg-1);
  padding-left: 8px;
  box-shadow: -10px 0 10px -6px var(--bg-1);
}

/* ─── Audit batch: list/desktops/account/events/server polish ─────────── */

/* List-view name cell: when a device has a description, the name markup
   becomes `<div float:right>desc</div><div>name</div>` inside .style10, which
   is max-height:18px + overflow:hidden — the name block wrapped onto a 2nd
   line and got clipped, leaving a blank name cell. Lay the inner divs inline
   so name + desc share the single visible line. */
body.vision .bar18 .style10 > div {
  display: inline;
  float: none !important;
}
body.vision .bar18 .style10 > div[style*="float:right"] {
  display: inline-block;
  float: right !important;
  margin-left: 8px;
  color: var(--text-2);
}

/* List-view row band: the lighter band only covered the name <td> (the
   .bar18 div), so USER/ADDRESS/CONNECTIVITY cells sat on the darker page bg —
   a hard vertical seam down every group table. The row is a
   <tr name=xxdevice2> of <td> cells; theme every cell the same so resting
   rows span full width. (.bar18 itself stays transparent — set elsewhere.) */
body.vision tr[name="xxdevice2"] > td {
  background-color: var(--bg-1);
}
body.vision tr[name="xxdevice2"]:hover > td {
  background-color: var(--bg-2);
}
/* The checkbox + icon wells inside the bar carry base background-color:white
   (no .night here) — white strips on the dark row. Make them transparent so
   the row band shows through uniformly. */
body.vision .deviceBarCheckbox,
body.vision .deviceBarIcon {
  background-color: transparent !important;
}

/* Columns-card checkbox seam: the card body is one bg, but the inner
   `<table id=devs>` (checkbox + icon + name cells) kept its own opaque cells,
   leaving a darker vertical strip just right of the checkbox. Make the inner
   table + its cells transparent so the whole card body reads as one surface.
   The card already clips to its own radius (overflow:hidden), so the
   hover/selected ring follows the card geometry. */
body.vision [id^="DevxCol"] > div:not(.devKvmTile):not(.devOfflineTile) table#devs,
body.vision [id^="DevxCol"] > div:not(.devKvmTile):not(.devOfflineTile) table#devs td {
  background-color: transparent !important;
}

/* Battery overlay (.deviceBatterySmall): upstream raster sprite (batteries
   sprite) sits at left:26px/top:32px and, in the Columns card layout, lands on
   top of the row checkbox as a glossy colorful graphic that clashes with the
   flat icon language. Recolor + reposition to the bottom-right of the device
   icon, off the checkbox hit area, and desaturate so it reads flat. */
body.vision .deviceBatterySmall {
  left: 58px !important; /* bottom-right corner of the 40px device icon */
  top: 34px !important;
  filter: grayscale(0.5) brightness(1.15) drop-shadow(0 0 1px var(--bg-0));
  opacity: 0.9;
  pointer-events: none;
}

/* The KVM canvas used to be given the light foreground token as its inline
   background (var(--text-1) ≈ #cbd4e1), which rendered as a glaring light-grey
   block inside a dark tile. That is now fixed at source — the view code emits
   var(--bg-0) — so no !important override is needed here; the canvas simply
   blends with .devKvmThumb until real frames paint.
   The "Disconnected"/"Connecting…" label is .devKvmState, styled with the tile
   contract above; it no longer needs an id-prefix override. */

/* Devices toolbar split: #devListToolbarSpan is a 1-row table whose left cell
   (#devListToolbar.style14) is a bordered pill while the right cell
   (.auto-style1, Sort/View) sits separate — reading as two boxes with a seam
   at ~75% width. Make the left cell fill the row and drop its right
   border/radius so the bar reads as one continuous full-width toolbar with the
   (transparent) Sort cell riding flush at the right edge. */
body.vision #devListToolbarSpan { width: 100%; }
body.vision #devListToolbarSpan td#devListToolbar {
  width: 100%;
  border-right: 0 !important;
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
}
body.vision #devListToolbarSpan td.auto-style1 {
  white-space: nowrap;
  padding-left: var(--space-3);
  /* match the left pill's top/bottom/right border so the row is one bar */
  border: 1px solid var(--border-2);
  border-left: 0;
  border-top-right-radius: var(--radius-3);
  border-bottom-right-radius: var(--radius-3);
  background: var(--bg-1) !important;
}

/* Filter input clear "×": inline left:-18px;top:-8px (sized for upstream's
   shorter input) pinned it to the top-right corner of the taller themed
   input. Center it vertically within the ~30px input height. */
body.vision #SearchInputClearButton img,
body.vision #KvmSearchInputClearButton img {
  top: 50% !important;
  transform: translateY(-50%);
}

/* Events page stray empty pill: the first td.auto-style1 holds only a
   display:none "Download Report" button, so the :empty collapse rule never
   fires and a hollow bordered bar renders above the filter toolbar. Hide any
   auto-style1 cell whose sole content is a hidden input. */
body.vision .pTable td.auto-style1:has(> input[style*="display:none"]):not(:has(> *:not([style*="display:none"]):not([style*="display: none"]))) {
  display: none !important;
}

/* Events page device-row icons: events tied to a device node use the raster
   device-type sprite class `si1`/`si2`/`si4`…`si8` (icons16.png — a colorful
   3D monitor), which is unthemed next to the flat cyan person / green link
   glyphs. (.si3 is already themed above.) Mask them all to one flat monitor
   glyph in the events tables, matching the existing event-icon treatment. */
body.vision #p16events .si1, body.vision #p3events .si1,
body.vision #p16events .si2, body.vision #p3events .si2,
body.vision #p16events .si4, body.vision #p3events .si4,
body.vision #p16events .si5, body.vision #p3events .si5,
body.vision #p16events .si6, body.vision #p3events .si6,
body.vision #p16events .si7, body.vision #p3events .si7,
body.vision #p16events .si8, body.vision #p3events .si8 {
  background-image: none !important;
  background-color: var(--text-2) !important;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: 15px 15px; mask-size: 15px 15px;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='3'%20y='4'%20width='18'%20height='12'%20rx='1.5'/%3E%3Cpath%20d='M8%2020h8M12%2016v4'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='3'%20y='4'%20width='18'%20height='12'%20rx='1.5'/%3E%3Cpath%20d='M8%2020h8M12%2016v4'/%3E%3C/svg%3E");
}

/* Users toolbar icon trio (#p4: download link4 / batch link6 / gear): the
   mask-icon block tints via `color` set on the img without !important, so the
   upstream link-blue inherited from the anchor (and the grey gear) leaked
   through as currentColor at ~2:1. Force one visible tint; hover → accent. */
body.vision #p4 img[src*="images/link4.png"],
body.vision #p4 img[src*="images/link6.png"],
body.vision #p4 img[src*="images/icon-gear.png"] {
  color: var(--text-1) !important;
}
body.vision #p4 a:hover img[src*="images/link4.png"],
body.vision #p4 a:hover img[src*="images/link6.png"],
body.vision #p4 img[src*="images/icon-gear.png"]:hover {
  color: var(--accent-2) !important;
}

/* Files toolbar: #p5filesubhead row holds a 32px-tall styled Sort select +
   "Root" breadcrumb that hung below the toolbar card border (float-based,
   fixed-height row). Make it a flex row with auto height + centered content so
   both sit fully inside the card; un-float the Sort group and push it right. */
body.vision #p5filesubhead {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  height: auto !important;
  padding: var(--space-2) 0;
}
body.vision #p5filesubhead > div[style*="float:right"] {
  float: none !important;
  margin-left: auto;
  order: 9;
}

/* My Files / device file list: the row icon (div.fileIconN, inside a span
   next to the name <a>) sat ~2px from the first letter, reading as one fused
   glyph ("⊟Default"). Add a small right margin on the file-list icon so icon
   and filename get breathing room. */
body.vision #p5files .filelist [class^="fileIcon"],
body.vision #p13files .filelist [class^="fileIcon"] {
  margin-right: var(--space-2);
}

/* SERVER STATE stat cells: each .serverStateTableCell sits in a shrink-wrap
   `display:inline-block` wrapper, so cells packed into a segmented bar and a
   wrapped 9th cell looked like a detached orphan. Lay the container's children
   out as a uniform grid of equal tiles with a consistent gap on both axes so
   any wrap reads as intentional. */
body.vision #serverStatsTable > div {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-2);
  align-items: stretch;
}
/* The per-group header spans the full grid row. */
body.vision #serverStatsTable > div > .userTableHeader {
  grid-column: 1 / -1;
}
/* Each stat cell becomes its own full tile (override the shrink-wrap width). */
body.vision #serverStatsTable > div > div {
  display: block;
}
body.vision #serverStatsTable .serverStateTableCell {
  width: 100% !important;
  margin: 0 !important;
}

/* Group header layout: the node-count pill (a float:right span, holding
   .devHeaderx) sat alone top-right while the group name + Add Agent/Invite
   links sat a line lower bottom-left — two staggered half-rows. .DevSt holds
   only the header (device cards are a sibling DevxCol div), so lay it as one
   flex row: collapse-arrow + name + actions left, node-count pill pushed
   right via margin-left:auto. */
body.vision div.DevSt {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
body.vision div.DevSt > span[style*="float:right"],
body.vision div.DevSt > .devHeaderx[style*="float:right"] {
  float: none !important;
  margin-left: auto;
  order: 9;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONTRACT ENFORCEMENT — snap upstream spacing/type onto the scale
   ---------------------------------------------------------------------------
   Everything below fixes a value that comes from MeshCentral's own style.css or
   from inline markup, where the fork's theme layer is the only place we can
   reach it. Each line was produced by `node .pw/lint.js`, which flags computed
   padding/gap/font-size that is off the scale in design/UI-CONTRACT.md §1-§4.
   Re-run the linter after editing: these rules should shrink over time as the
   underlying markup is converted, not grow.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Page gutters: 15px -> 16px (§1) */
body.vision #column_l {
  padding-left: var(--space-4) !important;
  padding-right: var(--space-4) !important;
}

/* Footer: 6px band / 10px cells -> 8px / 12px (§1-§2) */
body.vision #footer {
  padding-top: var(--space-2) !important;
  padding-bottom: var(--space-2) !important;
}
body.vision #footer .footer1,
body.vision #footer .footer2 { padding: var(--space-3) !important; }

/* Standalone views (terms / message / download / invite): 60px hero pad -> 48px,
   16px + 14px body type -> the 15px subhead + 13px body steps (§4) */
body.vision #text1 { padding-top: var(--space-12) !important; }
body.vision #text2 { font-size: var(--fs-subhead) !important; }
body.vision #text3,
body.vision #text3 a,
body.vision #text3 a b { font-size: var(--fs-body) !important; }

/* Device toolbar controls + search inputs: 10px side padding -> 12px (§2) */
body.vision #devListToolbarSort,
body.vision #devListToolbarSize,
body.vision #SearchInput,
body.vision #KvmSearchInput,
body.vision #id_p15consoleClear,
body.vision #deskstatus {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-3) !important;
}
/* select keeps room for its arrow, but on the scale: 26px -> 24px */
body.vision #DevFilterSelect {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-6) !important;
}

/* Device group containers: 20px tail -> 16px; the collapse chevron is an <img>
   that was padded 20px at the bottom to fake alignment — it is vertically
   centred by the group bar's flex row instead. */
body.vision [id^="DevxCol"] { padding-bottom: var(--space-4) !important; }
body.vision img[id^="DevxColImg"] { padding-bottom: 0 !important; vertical-align: middle; }

/* Device / console panel titles: 18px gutters -> 16px, and their content
   blocks 20px -> 16px, so title and body share one left edge (§1) */
body.vision #p10title,
body.vision #p15title,
body.vision #p20title,
body.vision #p30title {
  padding-left: var(--space-4) !important;
  padding-right: var(--space-4) !important;
}
body.vision #p10html,
body.vision #p10html2,
body.vision #p10html4 {
  padding-left: var(--space-4) !important;
  padding-right: var(--space-4) !important;
}
body.vision #p10info { padding-top: var(--space-2) !important; }

/* Device rows/tiles carried 16px/14px type from an inherited rule; the tile's
   own name/state sizes come from the tile contract, so scope this to the row
   shell only rather than blanket-setting #devs (§4). */
body.vision .devOfflineTile,
body.vision .devKvmTile { font-size: var(--fs-body); }
body.vision #devs > .style10,
body.vision #devs.bar18 { font-size: var(--fs-body); }

/* Login page: 28px panel padding -> 24px, 10px field padding -> 12px (§1-§2).
   The brand wordmark is display type, allowed above the body scale. */
body.vision #loginpanel { padding: var(--space-6) !important; }
body.vision #username,
body.vision #password {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-3) !important;
}

/* Masthead inner row: 7px -> 8px (§1) */
body.vision #masthead > div { padding-top: var(--space-2) !important; }

/* Empty-state text inside a data table gets its own 6px box -> 8px (§1) */
body.vision table td[colspan] > div { padding: var(--space-2); }

/* Console panel (p15) overran its column by 6px because a child carries a fixed
   pixel width from the view code; clamp children instead of hiding overflow so
   nothing is cut off. */
body.vision #p15 > * { max-width: 100%; box-sizing: border-box; }

/* Session player: 20px panel pad -> 16px, 10px button pad -> 12px (§1-§2) */
body.vision #metadatadiv { padding: var(--space-4) !important; }
/* (player transport buttons are covered by the .areaFoot toolbar button rule) */

/* Masthead on the standalone views (terms/message/download) carries 14px/5px
   inline gutters -> 16px/4px (§1) */
body.vision #masthead > div { padding-left: var(--space-4) !important; }
body.vision #masthead > div > div { padding-left: var(--space-1) !important; }

/* ── Contract pass 2 — offenders from `node .pw/lint.js` run 3 ────────────── */

/* Device-row name cell and list "bar" rows still inherited 14-16px type (§4) */
body.vision #devs > .style10 { font-size: var(--fs-body) !important; }
body.vision .bar,
body.vision .bar div,
body.vision .bar span,
body.vision .bar a { font-size: var(--fs-body); }

/* Search inputs / toolbar affordances: 10px -> 12px, 6px -> 8px (§1-§2) */
body.vision #mapSearchLocation,
body.vision #UserSearchInput,
body.vision #devListToolbarSettings {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-3) !important;
}
body.vision #DeskLatency {
  padding-left: var(--space-2) !important;
  padding-right: var(--space-2) !important;
}

/* Account avatar frame: 22px tail -> 24px (§1) */
body.vision #p2AccountImageFrame { padding-bottom: var(--space-6) !important; }

/* Every panel title shares the 16px gutter (§1). Upstream ships 18px on the
   session panels (p11-p16) and 16px elsewhere, so titles and their content
   never lined up on the same left edge. */
body.vision [id^="p"][id$="title"] {
  padding-left: var(--space-4) !important;
  padding-right: var(--space-4) !important;
}

/* Keyboard lock indicators were 10px on a muted grey (2.9:1 — below the 3:1
   floor for small text). Put them on the micro step and a readable colour. */
body.vision #p11capslock,
body.vision #p11scrolllock,
body.vision #p11numlock {
  font-size: var(--fs-micro) !important;
  color: var(--text-1) !important;
  padding: var(--space-1) var(--space-2) !important;
}

/* Optional device-detail sections render as empty styled panels when the server
   sends no content for them (p10html2 was a 34px empty card under the info
   card). Collapse a section that has no element children. */
body.vision #p10html:not(:has(*)),
body.vision #p10html2:not(:has(*)),
body.vision #p10html3:not(:has(*)),
body.vision #p10html4:not(:has(*)),
body.vision #p13html:not(:has(*)),
body.vision #p20html:not(:has(*)) { display: none !important; }

/* Device action links were joined by a single &nbsp;, so "Change Group Delete
   Device MeshCmd Web-VNC Web-RDP" read as one run-on string. Lay them out as
   rows with a real gap (§3). */
body.vision .p10html3left,
body.vision .p10html3right {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-group);
}
body.vision .p10html3right { justify-content: flex-end; }

/* Session status chips (desktop/terminal/files toolbars): 10px/6px -> 12px/8px */
body.vision #DeskTimer,
body.vision #TermTimer {
  padding-left: var(--space-2) !important;
  padding-right: var(--space-2) !important;
}
body.vision #DeskControlSpan,
body.vision #termstatus,
body.vision #p13Status,
body.vision #specialkeylistinput {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-3) !important;
}

/* ── Contract pass 3 ─────────────────────────────────────────────────────── */

/* Upstream paints the events panels near-black (`.night #p16events, #p31events
   { color: #222 }`), so "No Events Found" rendered at 1.26:1 — invisible. */
body.vision #p16events,
body.vision #p31events,
body.vision #p3events { color: var(--text-1); }
body.vision #p16events i,
body.vision #p31events i,
body.vision #p3events i { color: var(--text-2); }

/* Console panel: a nested table is 5px wider than its column, so p15 scrolled
   sideways. Clamp the table rather than hiding the overflow. */
body.vision #p15 table,
body.vision #p15 .areaProgress { max-width: 100%; box-sizing: border-box; }
/* a cell's min-content width still pushed the table 6px past its column, so a
   fixed layout is what actually makes it fit. */
body.vision #p15 > table,
body.vision #p15 .areaProgress table { table-layout: fixed; width: 100%; }

/* Plugin panel headers: 7px/10px -> 8px/12px (§1) */
body.vision #p19headers {
  padding-right: var(--space-2) !important;
  padding-bottom: var(--space-3) !important;
}

/* List "bar" rows kept 16px type from an inline attribute in some paths (§4) */
body.vision .bar,
body.vision .bar div,
body.vision .bar span,
body.vision .bar a { font-size: var(--fs-body) !important; }

/* The agent console table (#consoleTable) is the actual 6px overrun inside p15:
   a fixed layout plus clamped children keeps every cell inside the column. */
body.vision #consoleTable { table-layout: fixed; width: 100%; }
body.vision #p15agentConsole,
body.vision #p15agentConsole > * { max-width: 100%; box-sizing: border-box; }

/* ── Mobile (<=768px): stop panels overflowing the viewport ──────────────────
   Every rule here fixes a horizontal overflow reported by `node .pw/lint.js
   --viewports mobile`. MeshCentral lays its toolbars out as <table>, which
   cannot wrap — at 390px the devices toolbar was 467px wide inside a 266px
   column, so the whole page scrolled sideways. */
@media (max-width: 768px) {
  /* toolbars: turn the layout table into stacked blocks so controls wrap */
  body.vision #devListToolbarSpan,
  body.vision #devListToolbarSpan tbody,
  body.vision #devListToolbarSpan tr,
  body.vision #devListToolbarSpan td {
    display: block;
    width: 100%;
    max-width: 100%;
  }
  /* …but the view code hides the inactive toolbar by setting an inline
     display:none on its cell. Blanket `display:block` above re-showed it, so the
     Columns and List toolbars rendered on top of each other and over the device
     rows. Keep hidden cells hidden. */
  body.vision #devListToolbarSpan td[style*="display:none"],
  body.vision #devListToolbarSpan td[style*="display: none"],
  body.vision #devListToolbarSpan tr[style*="display:none"],
  body.vision #devListToolbarSpan tr[style*="display: none"] { display: none !important; }
  body.vision #devListToolbar,
  body.vision #kvmListToolbar {
    flex-wrap: wrap;
    gap: var(--gap);
  }

  /* the device list itself must span its column — with the toolbar table no
     longer forcing a width, #xdevices was shrink-wrapping to ~14px */
  body.vision #xdevices { width: 100%; }
  /* device grid collapses to one column; tiles never force a wider track */
  body.vision [id^="DevxCol"] { grid-template-columns: 1fr !important; }
  body.vision .devKvmTile,
  body.vision .devOfflineTile { min-width: 0; }
  body.vision .devKvmThumb canvas { max-width: 100% !important; height: auto !important; }

  /* wide data tables scroll inside their own box instead of the page */
  body.vision #p2meshes,
  body.vision #p3,
  body.vision #p4,
  body.vision #p31,
  body.vision #p42,
  body.vision #p30html2,
  body.vision #termTable,
  body.vision #serverStats,
  body.vision #serverStatsTable,
  body.vision #serverStatsTable > div {
    max-width: 100%;
    overflow-x: auto;
  }

  /* Dialogs were 4px wider than the viewport (a fixed width plus the shell's
     own margins), so every dialog pushed the page sideways. */
  body.vision #dialog {
    left: var(--space-2) !important;
    right: var(--space-2) !important;
    width: auto !important;
    max-width: calc(100vw - var(--space-4)) !important;
    box-sizing: border-box;
  }
  body.vision #dialogHeader,
  body.vision #idx_dlgButtonBar { margin-left: 0 !important; margin-right: 0 !important; }

  /* Device list group headers and rows are wide data tables; let them scroll
     inside their own box instead of dragging the page with them. */
  body.vision #xdevices { overflow-x: auto; }

  /* Session toolbar: the right-hand icon cluster sat on top of the status text */
  body.vision #deskarea1 .toright2 { position: static; float: none; }
  body.vision #deskarea1 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap);
  }

  /* My Files: entry labels ran past the column at 390px */
  body.vision #p5files,
  body.vision #p5files .filelist { max-width: 100%; }
  body.vision #p5files .filelist span {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
  }

  /* the Terms page is pasted Word markup with fixed-width paragraphs */
  body.vision #column_l p,
  body.vision #column_l .MsoNormal {
    max-width: 100%;
    word-wrap: break-word;
  }
}

/* ── Dialog chrome (design/UI-CONTRACT.md §5 .v-dialog) ──────────────────────
   The title bar shipped a 5px box and the close affordance a 3px one, so every
   one of the 23 audited dialogs had a header off the scale and a close target
   below the 24px minimum. */
body.vision #id_dialogtitle { padding: var(--pad-section) !important; }
body.vision #id_dialogclose {
  padding: var(--space-1) !important;
  min-width: 24px;
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
body.vision .dialogText {
  padding-left: var(--space-3) !important;
  padding-right: var(--space-3) !important;
}

/* Notification badge: white on the danger fill is 2.77:1 — under the 3:1 floor.
   Dark ink on the light-red pill instead. */
body.vision #notificationCount,
body.vision #notificationCount2 { color: var(--bg-0) !important; font-weight: 700; }

/* ── Vertical rhythm (§1) — margins, the other half of the spacing scale ─────
   The linter only checked padding/gap at first; adding marginTop/marginBottom
   surfaced 616 more off-scale values. These are the shared ones. */

/* Sidebar rail buttons: 6px stack -> 8px */
body.vision .lbbutton,
body.vision .lbbutton2 {
  margin-top: var(--space-2) !important;
  margin-bottom: var(--space-2) !important;
}

/* Dialog chrome: 6px / 3px / 5px -> 8px / 4px / 4px */
body.vision #dialogHeader { margin-bottom: var(--space-2) !important; }
body.vision #dialog2 {
  margin-top: var(--space-1) !important;
  margin-bottom: var(--space-1) !important;
}
body.vision #idx_dlgButtonBar { margin-bottom: var(--space-1) !important; }

/* Prose blocks inherit the browser's 1em margin, which lands on 13px with our
   13px body size — snap to the scale so text blocks stack on the same rhythm. */
body.vision #column_l p,
body.vision #column_l pre,
body.vision pre {
  margin-top: var(--space-3);
  margin-bottom: var(--space-3);
}
body.vision #column_l h1 {
  margin-top: var(--space-4);
  margin-bottom: var(--space-4);
}

/* Device/event list cells and the back button: 3px / 6px -> 4px / 8px */
body.vision .e1t,
body.vision .e1 { margin-bottom: var(--space-1) !important; }
body.vision .backButtonEx { margin-top: var(--space-2) !important; }

/* Account avatar frame: 7px top -> 8px */
body.vision #p2AccountImageFrame { margin-top: var(--space-2) !important; }

/* ── Phone UI (views/default-mobile.handlebars) ─────────────────────────────
   A separate document from the desktop SPA, with its own markup and its own
   inline <style> block. Its device rows were built to run flush to the screen
   edge (flat right corners, no gutter), which reads as clipped on a 390px
   viewport — the row's right edge landed 1px past the viewport. */
body.vision .devList3 {
  margin-right: var(--space-2);
  border-radius: var(--radius-3) !important;
  padding-right: var(--space-3);
}
/* The notification badge is absolutely positioned at top:0 with a 28px glyph in
   a 50px box, so the counter was clipped by the 48px header. Centre it and size
   it as a proper badge. */
body.vision #notificationCount {
  top: 50% !important;
  transform: translateY(-50%);
  width: 28px !important;
  height: 28px !important;
  right: var(--space-12) !important;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
}
body.vision #notificationCount2 {
  padding-top: 0 !important;
  font-size: var(--fs-small) !important;
  line-height: 1;
}

/* The "Add Device Group / MeshCmd / Router" links are emitted as the last child
   of the device container. In the Desktops view that container is the tile grid,
   so the links rendered as an extra device card among the machines. Span the row
   and read as a footer, not a tile. */
body.vision .devListFooterLinks {
  grid-column: 1 / -1;
  border-top: 1px solid var(--border-2);
  margin-top: var(--space-1);
  padding-top: var(--space-3);
  font-size: var(--fs-body);
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-group);
  background: none !important;
  border-left: 0; border-right: 0; border-bottom: 0;
  border-radius: 0;
}

/* Columns view: the device-name cell carries a JS-computed inline width, and the
   row is an auto-layout <table>, so a long name (e.g. a 46-character branch
   machine) widened the whole cell past its card instead of ellipsising —
   invisible with a 5-device fixture, obvious at real fleet size. A fixed table
   layout makes max-width:100% on .e1t/.e2t actually bind. */
body.vision [id^="DevxCol"] table#devs {
  table-layout: fixed;
  width: 100%;
}
/* With a fixed layout, `max-width:0` on the name cell is the standard way to make
   it take the leftover width and actually clip; without it the cell still grows
   to its content and the ellipsis never triggers. */
body.vision [id^="DevxCol"] table#devs td.e2t {
  width: 100% !important;
  max-width: 0 !important;
}
body.vision [id^="DevxCol"] table#devs td.e2t > .e1t {
  width: 100% !important;
  max-width: 100% !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── Billing: trial banner actions and the end-of-trial paywall ──────── */

#demoBanner .vcBannerActions {
  margin-top: var(--space-3, 12px);
}

#demoBanner .vcBannerBtn,
#vcPaywall .vcPlanBtn {
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
}

body.vision #demoBanner .vcBannerBtn {
  height: 30px;
  padding: 0 var(--space-4, 16px);
  border: 1px solid var(--accent-border, rgba(34, 211, 238, 0.35)) !important;
  border-radius: var(--radius-2, 6px) !important;
  background: var(--accent-bg, rgba(34, 211, 238, 0.10)) !important;
  color: var(--accent, #22d3ee) !important;
}

body.vision #demoBanner .vcBannerBtn:hover {
  background: var(--accent-bg-strong, rgba(34, 211, 238, 0.18)) !important;
}

#vcPaywall {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2000;
  align-items: center;
  justify-content: center;
  padding: var(--space-6, 24px);
  background: rgba(6, 8, 13, 0.88);
  backdrop-filter: blur(6px);
}

#vcPaywall .vcPaywallCard {
  width: 100%;
  max-width: 420px;
  padding: var(--space-8, 32px);
  background: var(--bg-2, #0f1524);
  border: 1px solid var(--border-2, rgba(255, 255, 255, 0.07));
  border-radius: var(--radius-4, 12px);
  box-shadow: var(--shadow-pop, 0 16px 48px -12px rgba(0, 0, 0, 0.7));
  text-align: center;
}

#vcPaywall .vcPaywallTitle {
  margin-bottom: var(--space-3, 12px);
  color: var(--text-0, #f1f5fa);
  font-size: 18px;
  font-weight: 600;
}

#vcPaywall .vcPaywallText {
  margin-bottom: var(--space-6, 24px);
  color: var(--text-2, #8a96ab);
  font-size: 13px;
  line-height: 1.5;
}

#vcPaywall .vcPlanRow {
  display: flex;
  gap: var(--space-3, 12px);
}

body.vision #vcPaywall .vcPlanBtn {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1, 4px);
  height: auto;
  padding: var(--space-4, 16px);
  border: 1px solid var(--border-3, rgba(255, 255, 255, 0.12)) !important;
  border-radius: var(--radius-3, 8px) !important;
  background: var(--bg-3, #141c30) !important;
  color: var(--text-1, #cbd4e1) !important;
  line-height: 1.45;
  text-align: center;
}

body.vision #vcPaywall .vcPlanBtn:hover {
  border-color: var(--accent-border, rgba(34, 211, 238, 0.35)) !important;
  background: var(--bg-4, #1a2238) !important;
}

body.vision #vcPaywall .vcPlanBtnBest {
  border-color: var(--accent-border, rgba(34, 211, 238, 0.35)) !important;
  background: var(--accent-bg, rgba(34, 211, 238, 0.10)) !important;
}

body.vision #vcPaywall .vcPlanName {
  color: var(--text-2, #8a96ab);
  font-size: 12px;
}

body.vision #vcPaywall .vcPlanPrice {
  color: var(--text-0, #f1f5fa);
  font-size: 15px;
  font-weight: 600;
}

body.vision #vcPaywall .vcPlanNote {
  color: var(--accent, #22d3ee);
  font-size: 12px;
}

#vcPaywall .vcPaywallFoot {
  margin-top: var(--space-5, 20px);
}

#vcPaywall .vcPaywallFoot a {
  color: var(--text-3, #5a6679);
  font-size: 12px;
}

/* My Account -> Subscription block */

body.vision .vcBillingBody {
  margin-left: var(--space-6, 24px);
}

body.vision .vcBillingMuted {
  color: var(--text-2, #8a96ab);
}

body.vision .vcBillingWarn {
  color: var(--warn, #fbbf24);
}

/* ---------------------------------------------------------------------------
   WhatsApp contact button — floating, bottom-right, every app view.
   Sits under dialogs (z 1000+) and above page content.
   --------------------------------------------------------------------------- */

.vcWaFab {
  position: fixed;
  right: var(--space-6, 24px);
  bottom: var(--space-6, 24px);
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #25d366;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
  text-decoration: none;
  transition: transform 0.15s ease-out, background-color 0.15s ease-out;
}

.vcWaFab:hover {
  background: #1eb457;
  transform: scale(1.05);
}

.vcWaFab:active {
  transform: scale(0.98);
}

.vcWaFab:focus-visible {
  outline: 3px solid rgba(34, 211, 238, 0.6);
  outline-offset: 2px;
}

.vcWaFab svg {
  display: block;
  width: 24px;
  height: 24px;
  fill: #fff;
}

@media (max-width: 600px) {
  .vcWaFab {
    right: var(--space-4, 16px);
    bottom: var(--space-4, 16px);
  }
}

@media print {
  .vcWaFab { display: none; }
}
