diff --git a/cmd/web-ui/static/app.js b/cmd/web-ui/static/app.js
index 1b57e22..22cd1c3 100644
--- a/cmd/web-ui/static/app.js
+++ b/cmd/web-ui/static/app.js
@@ -561,17 +561,22 @@
| Memory | ${escapeHTML(formatBytes(host.memory_kib ? host.memory_kib * 1024 : 0) || '-')} |
| Disk | ${escapeHTML(formatBytes(host.disk_actual_bytes) || '-')} |
| Autostart | ${host.autostart ? 'Yes' : 'No'} |
- ${guest ? `
- | Gateway | ${guest.service_active ? 'Active' : 'Inactive'} |
- | HTTP | ${guest.http_status || 'N/A'} |
+
+ ${guest ? `
+
+
+ | Gateway | ${guest.service_active ? 'Active' : 'Inactive'} |
+ | HTTP | ${guest.http_status || 'N/A'} |
| Version | ${escapeHTML(guest.version || '-')} |
- | Guest Memory | ${guest.memory_percent !== undefined ? guest.memory_percent.toFixed(1) : '-'}% |
+ | Guest Mem | ${guest.memory_percent !== undefined ? guest.memory_percent.toFixed(1) : '-'}% |
| Guest Disk | ${guest.disk_percent !== undefined ? guest.disk_percent.toFixed(1) : '-'}% |
| Load | ${guest.load_average !== undefined ? guest.load_average.toFixed(2) : '-'} |
| Uptime | ${escapeHTML(guest.service_uptime || '-')} |
- ` : ''}
-
- ${issues ? `
+
+ ` : ''}
+ ${issues && Object.values(issues).some(Boolean) ? `
+
+ Issues
${Object.entries(issues).filter(([, value]) => value).map(([key]) => `
${escapeHTML(key.replace(/_/g, ' '))}
diff --git a/cmd/web-ui/static/style.css b/cmd/web-ui/static/style.css
index fde4d06..e98c1bf 100644
--- a/cmd/web-ui/static/style.css
+++ b/cmd/web-ui/static/style.css
@@ -566,6 +566,19 @@ tr.expandable:hover .expand-icon::before {
background: rgba(52, 211, 153, 0.1);
color: var(--success);
border: 1px solid rgba(52, 211, 153, 0.2);
+ gap: 0.4rem;
+}
+
+.vm-status.running::before {
+ content: '';
+ display: inline-block;
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--success);
+ box-shadow: 0 0 6px rgba(52, 211, 153, 0.5);
+ animation: livePulse 2s ease-in-out infinite;
+ flex-shrink: 0;
}
.vm-status.stopped {
@@ -615,16 +628,16 @@ tr.expandable:hover .expand-icon::before {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
- margin-top: 0.875rem;
+ margin-top: 0;
}
.issue {
- font-size: 0.68rem;
- padding: 0.22rem 0.6rem;
+ font-size: 0.7rem;
+ padding: 0.28rem 0.7rem;
border-radius: 4px;
- font-weight: 700;
+ font-weight: 600;
text-transform: uppercase;
- letter-spacing: 0.06em;
+ letter-spacing: 0.05em;
}
.issue.gateway_down {
@@ -1321,3 +1334,19 @@ tr.expandable:hover .expand-icon::before {
color: var(--text-bright);
font-family: var(--font-mono);
}
+
+/* ── VM card divider ──────────────────────────────────────── */
+.vm-card-divider {
+ height: 1px;
+ background: var(--border-soft);
+ margin: 0.75rem 0;
+}
+
+.vm-issues-label {
+ font-size: 0.65rem;
+ font-weight: 700;
+ color: var(--text-dim);
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ margin-bottom: 0.5rem;
+}