diff --git a/plugins/host_agent/templates/widget_history.html b/plugins/host_agent/templates/widget_history.html
index cf9f492..5d1a464 100644
--- a/plugins/host_agent/templates/widget_history.html
+++ b/plugins/host_agent/templates/widget_history.html
@@ -43,7 +43,10 @@
elements: { point: { radius: 0 } },
scales: {
x: { type: "linear", ticks: { callback: function (v) { return fmtTime(v); }, maxTicksLimit: 6, color: "#8a8a92", font: { size: 10 } }, grid: { color: "#30303a" } },
- y: { beginAtZero: true, max: 100, ticks: { color: "#8a8a92", font: { size: 10 } }, grid: { color: "#30303a" } },
+ // Auto-scale to the data (with a little headroom) so the lines fill the
+ // panel instead of hugging the bottom of a fixed 0–100 axis. Axis labels
+ // still show the real %, so the values stay honest.
+ y: { beginAtZero: true, grace: "8%", ticks: { color: "#8a8a92", font: { size: 10 } }, grid: { color: "#30303a" } },
},
plugins: { legend: { labels: { color: "#b8b8b0", boxWidth: 10, font: { size: 11 } } } },
},
diff --git a/plugins/host_agent/templates/widget_table.html b/plugins/host_agent/templates/widget_table.html
index aa5ffc7..a403a0c 100644
--- a/plugins/host_agent/templates/widget_table.html
+++ b/plugins/host_agent/templates/widget_table.html
@@ -1,9 +1,10 @@
-{# host_agent widget — fleet glance: per-host row with a sparkline beside each
- metric (cpu/mem/disk/load), mirroring the host-page AGENT panel. #}
+{# host_agent widget — fleet glance. Per host: name on its own line (never
+ truncated), then a row of metric cells (cpu/mem/disk/load), each value with a
+ trend sparkline beneath it — the host-page AGENT panel, on the dashboard. #}
{% from "_macros.html" import metric_style %}
{% if rows %}
{% macro metric_cell(label, value, fmt, svg, style="", title="") %}
-
+
{{ label }}
{% if value is not none %}{{ fmt|format(value) }}{% else %}—{% endif %}
@@ -11,27 +12,31 @@
{{ svg | safe }}
{% endmacro %}
-
+
{% for r in rows %}
{% set stale = r.stale %}
-
-
- {% set name_style = "flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500;" %}
- {% if session.user_id %}
-
{{ r.host.name }}
- {% else %}
-
{{ r.host.name }}
- {% endif %}
-
+
+ {# Line 1 — health dot + full host name (own line) + last seen #}
+
+
+ {% if session.user_id %}
+
{{ r.host.name }}
+ {% else %}
+
{{ r.host.name }}
+ {% endif %}
+
+ {{ r.reg.last_seen_at.strftime("%H:%M:%S") if r.reg.last_seen_at else "never" }}
+
+
+ {# Line 2 — metric cells with value + trend; wraps instead of truncating #}
+
{{ metric_cell("cpu", r.cpu_pct, "%.0f%%", r.sparks.cpu, metric_style(r.cpu_pct), "Average CPU utilization") }}
{{ metric_cell("mem", r.mem_used_pct, "%.0f%%", r.sparks.mem, metric_style(r.mem_used_pct), "Memory in use") }}
{{ metric_cell("disk /", r.disk_root, "%.0f%%", r.sparks.disk, metric_style(r.disk_root), "Root filesystem (/) usage") }}
{{ metric_cell("load", r.load_1m, "%.2f", r.sparks.load, "", "Load average (1m)") }}
-
- {{ r.reg.last_seen_at.strftime("%H:%M:%S") if r.reg.last_seen_at else "never" }}
-
{% endfor %}
diff --git a/steward/templates/base.html b/steward/templates/base.html
index 1652153..b6c8012 100644
--- a/steward/templates/base.html
+++ b/steward/templates/base.html
@@ -163,7 +163,7 @@ textarea { resize: vertical; }
.ping-row { display:flex; align-items:center; gap:1rem; padding:0.45rem 0; border-bottom:1px solid var(--border); }
.ping-row:last-child { border-bottom:none; }
.ping-meta { min-width:120px; max-width:180px; flex-shrink:1; overflow:hidden; }
-.ping-name { font-size:0.875rem; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block; }
+.ping-name { font-size:0.875rem; font-weight:500; display:block; overflow-wrap:anywhere; }
a.ping-name:hover { text-decoration:underline; }
/* Dashboard widget grid — Gridstack-rendered. Static (positioned but inert) in
view mode; the dashboard itself becomes the edit surface when Edit is toggled,
@@ -174,6 +174,14 @@ a.ping-name:hover { text-decoration:underline; }
padding:0.8rem 1rem; display:flex; flex-direction:column; overflow:hidden;
}
.grid-stack-item-content .dash-cell-body { flex:1; min-height:0; overflow:auto; }
+/* The widget body is a query container, so fragments can restyle to their OWN
+ panel width (not the viewport) — widgets adapt as you resize them. */
+.dash-cell-body { container-type:inline-size; }
+/* Host-list widgets flow into columns as the panel widens: use the width, drop
+ the vertical deadspace; stay single-column (and untruncated) when narrow. */
+.host-blocks { display:grid; grid-template-columns:1fr; gap:0 1.5rem; }
+@container (min-width:520px) { .host-blocks { grid-template-columns:1fr 1fr; } }
+@container (min-width:900px) { .host-blocks { grid-template-columns:1fr 1fr 1fr; } }
.panel-chrome { display:none; }
.panel-drag { cursor:grab; color:var(--text-dim); user-select:none; }
.panel-drag:active { cursor:grabbing; }
diff --git a/steward/templates/dashboard/share_view.html b/steward/templates/dashboard/share_view.html
index 67d11c9..d0ed81f 100644
--- a/steward/templates/dashboard/share_view.html
+++ b/steward/templates/dashboard/share_view.html
@@ -44,7 +44,7 @@
.ping-row { display:flex; align-items:center; gap:1rem; padding:0.45rem 0; border-bottom:1px solid var(--border); }
.ping-row:last-child { border-bottom:none; }
.ping-meta { min-width:120px; max-width:180px; flex-shrink:1; overflow:hidden; }
- .ping-name { font-size:0.875rem; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block; }
+ .ping-name { font-size:0.875rem; font-weight:500; display:block; overflow-wrap:anywhere; }
.ping-addr { display:block; color:var(--text-muted); font-size:0.75rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ping-pills { display:flex; gap:2px; flex:1; min-width:0; overflow:hidden; align-items:center; }
.pill { display:inline-block; width:7px; height:22px; border-radius:2px; }
@@ -59,6 +59,10 @@
.dash-grid { display:grid; grid-template-columns:repeat(12,1fr); grid-auto-rows:70px; gap:1rem; }
.dash-grid > .dash-cell { margin-bottom:0; min-width:0; overflow:hidden; display:flex; flex-direction:column; }
.dash-cell .dash-cell-body { flex:1; min-height:0; overflow:auto; }
+ .dash-cell-body { container-type:inline-size; }
+ .host-blocks { display:grid; grid-template-columns:1fr; gap:0 1.5rem; }
+ @container (min-width:520px) { .host-blocks { grid-template-columns:1fr 1fr; } }
+ @container (min-width:900px) { .host-blocks { grid-template-columns:1fr 1fr 1fr; } }
@media (max-width:820px) {
.dash-grid { grid-template-columns:1fr; grid-auto-rows:auto; }
.dash-grid > .dash-cell { grid-column:1 / -1 !important; grid-row:auto !important; }
diff --git a/steward/templates/hosts/overview_widget.html b/steward/templates/hosts/overview_widget.html
index 8c2052b..16776e9 100644
--- a/steward/templates/hosts/overview_widget.html
+++ b/steward/templates/hosts/overview_widget.html
@@ -1,33 +1,38 @@
-{# Unified Hosts widget — monitor status + agent glance per host, links to the hub. #}
+{# Unified Hosts widget — monitor status + agent glance per host, links to the hub.
+ Name sits on its own line (never truncated); its data wraps beneath it, grouped
+ under the host. Prefer vertical growth over cramming a row. #}
{% from "_macros.html" import metric_style %}
{% if hosts %}
-
+
{% for host in hosts %}
{% set ping = latest_pings.get(host.id) %}
{% set dns = latest_dns.get(host.id) %}
{% set ut = uptime.get(host.id, {}) %}
{% set a = agent.get(host.name, {}) %}
{% set down = host.ping_enabled and ping and ping.status.value != 'up' %}
-
-
- {% set name_style = "flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500;" %}
- {% if session.user_id %}
-
{{ host.name }}
- {% else %}
-
{{ host.name }}
- {% endif %}
- {% set spark = cpu_sparks.get(host.name) %}
- {% if spark %}
{{ spark | safe }}{% endif %}
-
- {# Monitors #}
+ {% set spark = cpu_sparks.get(host.name) %}
+
+ {# Line 1 — status dot + full host name (own line) + cpu trend #}
+
+
+ {% if session.user_id %}
+
{{ host.name }}
+ {% else %}
+
{{ host.name }}
+ {% endif %}
+ {% if spark %}
{{ spark | safe }}{% endif %}
+
+ {# Line 2 — monitors + agent metrics; wraps instead of truncating #}
+
{% if host.ping_enabled and ping and ping.response_time_ms is not none %}
ping {{ "%.0f"|format(ping.response_time_ms) }}ms
{% endif %}
{% if ut.get('24h') is not none %}
24h {{ "%.1f"|format(ut['24h']) }}%
{% endif %}
- {# Agent glance — failing metric coloured amber/red (≥80/≥90) #}
{% if a %}
{% if a.get('cpu_pct') is not none %}cpu {{ "%.0f"|format(a.cpu_pct) }}%{% endif %}
{% if a.get('mem_used_pct') is not none %}mem {{ "%.0f"|format(a.mem_used_pct) }}%{% endif %}
@@ -36,7 +41,7 @@
{% else %}
no agent
{% endif %}
-
+
{% endfor %}
diff --git a/steward/templates/hosts/uptime_widget.html b/steward/templates/hosts/uptime_widget.html
index 50b34ed..52675e4 100644
--- a/steward/templates/hosts/uptime_widget.html
+++ b/steward/templates/hosts/uptime_widget.html
@@ -17,9 +17,9 @@
{% if session.user_id %}
{{ host.name }}
+ style="overflow-wrap:anywhere;color:inherit;text-decoration:none;">{{ host.name }}
{% else %}
-
{{ host.name }}
+
{{ host.name }}
{% endif %}
{% for window in ["24h", "7d", "30d"] %}
{% set pct = ut.get(window) %}