—<`) {
+ t.Errorf("expected em-dash placeholder for empty history")
+ }
+}
+```
+
+If the helper names differ, mirror what's already used by the
+existing dashboard / repo tests. Inspect `dashboard_filter_test.go`
+or `ui_repo_test.go` for the canonical setup.
+
+- [ ] **Step 2: Run test to verify it fails**
+
+Run: `go test ./internal/server/http -run TestDashboard_HostRowSparkline -v`
+Expected: FAIL — no `repo-sparkline` class in output.
+
+- [ ] **Step 3: Attach sparkline to dashboard rows**
+
+In `internal/server/http/ui_handlers.go`, extend `dashboardHostRow`:
+
+```go
+type dashboardHostRow struct {
+ Host store.Host
+ RunAllScheduleID string
+ NextRun *time.Time
+ UpdateAvailable bool
+ TargetVersion string
+ // RepoSparklineSVG is a 30-day total_size_bytes sparkline,
+ // pre-rendered server-side. Empty when no history rows exist
+ // for the host (rendered as the "—" placeholder).
+ RepoSparklineSVG template.HTML
+}
+```
+
+Add the `html/template` import if not present (it likely is —
+verify before adding).
+
+In `handleUIDashboard`, inside the per-host loop after computing
+`row`, fetch and render the sparkline. Add the import for the
+sparkline package (`"gitea.dcglab.co.uk/steve/restic-manager/internal/web/sparkline"`):
+
+```go
+since := time.Now().UTC().AddDate(0, 0, -30)
+pts, perr := s.deps.Store.ListHostRepoStatsHistory(r.Context(), h.ID, since)
+if perr != nil {
+ slog.Warn("ui dashboard: list repo history", "host_id", h.ID, "err", perr)
+}
+sparkPoints := make([]float64, len(pts))
+for i, p := range pts {
+ if p.TotalSizeBytes == nil {
+ sparkPoints[i] = math.NaN()
+ } else {
+ sparkPoints[i] = float64(*p.TotalSizeBytes)
+ }
+}
+row.RepoSparklineSVG = sparkline.RenderSparkline(sparkPoints, 88, 20)
+```
+
+Add `"math"` to the imports if missing.
+
+- [ ] **Step 4: Render the cell in the partial**
+
+Modify `web/templates/partials/host_row.html`. Insert a new cell
+between the existing "Repo size" cell (line 37) and the
+"Snapshots" cell (line 38):
+
+```html
+ {{bytes $h.RepoSizeBytes}}
+ {{.RepoSparklineSVG}}
+
+```
+
+- [ ] **Step 5: Update the dashboard column header**
+
+Open `web/templates/pages/dashboard.html`. Find the table's
+column-header row (search for the cell labelled "Repo size" or
+"Snapshots"). Add a new header cell with text "30d trend"
+between them, and update the grid-template-columns rule (or
+whatever column layout is used) so the sparkline cell has a fixed
+~96px width. Keep the change minimal — match the existing
+class-utility style.
+
+If the dashboard uses CSS grid like `grid-template-columns`
+defined in a `