design: three hi-fi dashboard directions for review
CI / Test (linux/amd64) (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Build (windows/amd64) (push) Has been cancelled
CI / Build (linux/amd64) (push) Has been cancelled
CI / Build (linux/arm64) (push) Has been cancelled

Three deliberately differentiated takes on the dashboard so we can
lock the visual register before the UI work starts (P1-23 onwards).

  v1 — Operator console (Linear/Datadog dark register).
       Dense table, monospace numerics, restrained colour, pulsing
       status dot only when a job is running. The natural fit for
       the audience and the most defensible choice.

  v2 — Editorial calm (Stripe/Notion light register).
       Serif hero headline that humanises the data, cards with
       breathing room in a 2-up grid, demoted "quiet hosts" strip,
       subtle rust accent. Reads as trustworthy infrastructure.

  v3 — Print spec (Tufte/aerospace monospace register).
       Pure monospace, near-monochrome, status as typeset glyphs
       (●▶▲○✗) so the screen survives greyscale. "Requires
       attention" block groups problem hosts at the top; activity
       tail reads like a real log. Most polarising; highest
       craft ceiling.

Each file is self-contained (Tailwind via CDN + Google Fonts) and
includes a philosophy preamble + the dashboard hero + a component
vocabulary section so we can read the system, not just one screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 18:39:57 +01:00
parent b6cfa99413
commit 81c7825937
3 changed files with 1911 additions and 0 deletions
+575
View File
@@ -0,0 +1,575 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>restic-manager · v1 Operator Console</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root {
/* Warm-dark slate, deliberately not pitch black — eyes prefer it on long sessions. */
--bg: oklch(0.17 0.006 250);
--panel: oklch(0.20 0.007 250);
--panel-hi: oklch(0.23 0.008 250);
--line: oklch(0.27 0.010 250);
--line-soft: oklch(0.23 0.008 250);
--ink: oklch(0.96 0.005 250);
--ink-mid: oklch(0.78 0.005 250);
--ink-mute: oklch(0.58 0.006 250);
--ink-fade: oklch(0.42 0.006 250);
--ok: oklch(0.78 0.14 155);
--warn: oklch(0.82 0.13 80);
--bad: oklch(0.70 0.20 25);
--off: oklch(0.50 0.005 250);
--accent: oklch(0.82 0.12 195);
--accent-dim:oklch(0.55 0.10 195);
}
html { background: var(--bg); }
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
color: var(--ink);
font-feature-settings: 'cv11', 'ss01', 'ss03';
}
.mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.hairline { box-shadow: inset 0 -1px 0 var(--line-soft); }
.panel { background: var(--panel); border: 1px solid var(--line-soft); }
.row-hover:hover { background: var(--panel-hi); }
.dot { width: 7px; height: 7px; border-radius: 9999px; display: inline-block; }
.dot-online { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ok), transparent 80%); }
.dot-degraded { background: var(--warn); box-shadow: 0 0 0 3px color-mix(in oklch, var(--warn), transparent 80%); }
.dot-offline { background: var(--off); }
.dot-failed { background: var(--bad); box-shadow: 0 0 0 3px color-mix(in oklch, var(--bad), transparent 80%); }
/* The 120% detail: status dots get a quiet pulse only when the host is currently running a job. */
.pulse {
animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent), transparent 80%); }
50% { box-shadow: 0 0 0 6px color-mix(in oklch, var(--accent), transparent 92%); }
}
.tag {
font-size: 11px; line-height: 1; padding: 4px 7px;
border: 1px solid var(--line); color: var(--ink-mid);
border-radius: 3px; letter-spacing: 0.01em;
}
.btn {
font-family: 'Inter'; font-size: 12px; font-weight: 500;
padding: 6px 11px; border-radius: 5px;
color: var(--ink-mid);
background: transparent; border: 1px solid var(--line);
transition: all 120ms ease;
}
.btn:hover { background: var(--panel-hi); color: var(--ink); border-color: var(--line); }
.btn-primary {
color: oklch(0.18 0.01 195); background: var(--accent); border-color: var(--accent);
}
.btn-primary:hover { background: var(--accent); filter: brightness(1.08); color: oklch(0.16 0.01 195);}
.btn-ghost { border-color: transparent; }
.btn-ghost:hover { border-color: var(--line); }
.nav-tab {
font-size: 13px; padding: 18px 0; color: var(--ink-mute);
border-bottom: 2px solid transparent; margin-right: 28px;
cursor: pointer;
}
.nav-tab.active { color: var(--ink); border-color: var(--accent); }
.nav-tab:hover { color: var(--ink); }
.text-balance { text-wrap: balance; }
::selection { background: color-mix(in oklch, var(--accent), transparent 70%); }
/* doc shell — separates the philosophy preamble from the hi-fi screen */
.doc {
max-width: 1280px; margin: 0 auto; padding: 0 32px;
}
.philosophy {
border-bottom: 1px solid var(--line-soft);
padding: 56px 0 40px;
}
.philosophy h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
.philosophy p {
color: var(--ink-mid); max-width: 680px;
margin-top: 14px; line-height: 1.65;
text-wrap: pretty;
}
.philosophy .meta { color: var(--ink-fade); font-size: 12px; margin-top: 14px; }
.stage-frame {
margin: 48px -32px;
border-top: 1px solid var(--line-soft);
border-bottom: 1px solid var(--line-soft);
}
.stage-frame::before, .stage-frame::after {
content: ''; display: block; height: 0;
}
.components-section { margin: 64px 0 96px; }
.components-section h2 { font-size: 14px; font-weight: 600; color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.08em; }
</style>
</head>
<body class="bg-[color:var(--bg)]">
<div class="doc">
<!-- Philosophy preamble -->
<header class="philosophy">
<div class="text-xs uppercase tracking-[0.18em] text-[color:var(--ink-fade)] mb-3">v1 · Direction A</div>
<h1>Operator console.</h1>
<p>
Optimised for the daily 30-second glance. Dense by default, never fussy. Every
pixel earns its place; colour is reserved for state, not decoration. Numerics
are monospaced and right-aligned so the eye can scan a column without
tracking labels. Hover reveals secondary actions; primary actions are always visible.
</p>
<p>
Reference: Linear, Datadog, Vercel observability. Built for someone who looks
at this every morning while their coffee brews.
</p>
<p class="meta">
Not for: a public-facing landing page, a marketing surface, a screen anyone
shows to non-technical stakeholders. This is a tool, not a product page.
</p>
</header>
<!-- Stage: full hi-fi dashboard -->
<div class="stage-frame">
<div style="background: var(--bg); padding: 0;">
<!-- Top bar -->
<div class="hairline" style="background: var(--bg);">
<div class="doc flex items-center justify-between" style="padding: 16px 0;">
<div class="flex items-center gap-3">
<div class="mono" style="font-size:13px; letter-spacing: 0.02em; color: var(--ink); font-weight:500;">restic-manager</div>
<div class="mono" style="font-size:11px; color: var(--ink-fade);">v0.1.0-alpha</div>
</div>
<div class="flex items-center gap-5">
<div class="mono" style="font-size:12px; color: var(--ink-mute);">steve@dcglab</div>
<button class="btn btn-ghost">Sign out</button>
</div>
</div>
</div>
<!-- Primary nav -->
<div class="hairline" style="background: var(--bg);">
<div class="doc flex items-end justify-between">
<nav class="flex items-end">
<div class="nav-tab active">Dashboard</div>
<div class="nav-tab">Repos</div>
<div class="nav-tab">Alerts <span class="mono ml-1.5" style="font-size:11px; color: var(--bad);">5</span></div>
<div class="nav-tab">Audit</div>
<div class="nav-tab">Settings</div>
</nav>
<div class="pb-3">
<button class="btn btn-primary">+ Add host</button>
</div>
</div>
</div>
<!-- Fleet summary strip -->
<div class="doc" style="padding: 28px 32px;">
<div class="grid grid-cols-12 gap-6">
<div class="col-span-3">
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;">Fleet</div>
<div class="mono" style="font-size: 28px; font-weight: 500; letter-spacing: -0.02em;">12 <span style="color: var(--ink-mute); font-size:13px; font-weight:400;">hosts</span></div>
<div class="flex items-center gap-3 mt-2.5 text-xs">
<span class="flex items-center gap-1.5"><span class="dot dot-online"></span><span class="mono" style="color: var(--ink-mid);">10</span><span style="color: var(--ink-mute);">online</span></span>
<span class="flex items-center gap-1.5"><span class="dot dot-degraded"></span><span class="mono" style="color: var(--ink-mid);">1</span><span style="color: var(--ink-mute);">degraded</span></span>
<span class="flex items-center gap-1.5"><span class="dot dot-offline"></span><span class="mono" style="color: var(--ink-mid);">1</span><span style="color: var(--ink-mute);">offline</span></span>
</div>
</div>
<div class="col-span-3">
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;">Backed up</div>
<div class="mono" style="font-size: 28px; font-weight: 500; letter-spacing: -0.02em;">4.9 <span style="color: var(--ink-mute); font-size:13px; font-weight:400;">TB across 12 repos</span></div>
<div class="text-xs mt-2.5" style="color: var(--ink-mute);"><span class="mono" style="color: var(--ink-mid);">23,649</span> snapshots total</div>
</div>
<div class="col-span-3">
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;">Last 24h</div>
<div class="mono" style="font-size: 28px; font-weight: 500; letter-spacing: -0.02em;">147 <span style="color: var(--ink-mute); font-size:13px; font-weight:400;">jobs</span></div>
<div class="text-xs mt-2.5"><span class="mono" style="color: var(--ok);">144</span> <span style="color: var(--ink-mute);">succeeded</span> · <span class="mono" style="color: var(--bad);">2</span> <span style="color: var(--ink-mute);">failed</span> · <span class="mono" style="color: var(--ink-mid);">1</span> <span style="color: var(--ink-mute);">cancelled</span></div>
</div>
<div class="col-span-3">
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;">Open alerts</div>
<div class="mono" style="font-size: 28px; font-weight: 500; letter-spacing: -0.02em; color: var(--bad);">5 <span style="color: var(--ink-mute); font-size:13px; font-weight:400;">unresolved</span></div>
<div class="text-xs mt-2.5" style="color: var(--ink-mute);">oldest <span class="mono" style="color: var(--ink-mid);">3h</span> · acknowledge in panel</div>
</div>
</div>
</div>
<!-- Hosts table -->
<div class="doc" style="padding: 8px 32px 24px;">
<!-- table head -->
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-3">
<h2 style="font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: 0.01em;">Hosts</h2>
<div style="font-size: 12px; color: var(--ink-fade);">12 of 12</div>
</div>
<div class="flex items-center gap-2">
<input type="text" placeholder="Filter by name, tag, status…"
class="mono px-3 py-1.5 text-xs"
style="background: var(--panel); border: 1px solid var(--line-soft); color: var(--ink); border-radius: 5px; width: 280px; outline: none;"
/>
<button class="btn">Group: tag ▾</button>
<button class="btn">Sort: status ▾</button>
</div>
</div>
<!-- table -->
<div class="panel" style="border-radius: 7px; overflow: hidden;">
<!-- header row -->
<div class="grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 10px 16px; font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">
<div></div>
<div>Host</div>
<div>OS · arch</div>
<div>Last backup</div>
<div class="text-right">Repo size</div>
<div class="text-right">Snapshots</div>
<div class="text-right">Alerts</div>
<div>Tags</div>
<div></div>
</div>
<!-- row: prod-db-01 — online + currently running -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online pulse"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">prod-db-01</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--accent);">backup running…</span><br>
<span class="mono" style="color: var(--ink-fade);">started 3m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">412 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">1,847</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">db</span></div>
<div class="text-right"><button class="btn btn-ghost">View →</button></div>
</div>
<!-- row: prod-db-02 -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">prod-db-02</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">4m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">389 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">1,802</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">db</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: prod-web-01 -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">prod-web-01</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">11m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">87 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">2,103</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">web</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: prod-web-02 -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">prod-web-02</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">12m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">87 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">2,098</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">web</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: prod-cache-01 — degraded with alerts -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-degraded"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">prod-cache-01</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">1h ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">128 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">1,402</div>
<div class="text-right mono" style="color: var(--bad); font-weight: 500;">3</div>
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">cache</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: homelab-nas -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">homelab-nas</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/arm64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">2h ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">3.7 <span style="color: var(--ink-mute); font-size: 11px;">TB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">8,912</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">homelab</span><span class="tag">storage</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: homelab-pi -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">homelab-pi</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/arm64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">6h ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">8.4 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">421</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">homelab</span><span class="tag">iot</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: dev-laptop — offline -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-offline"></span></div>
<div class="mono" style="color: var(--ink-mid); font-weight: 500;">dev-laptop</div>
<div class="mono" style="color: var(--ink-mute); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mute);">
<span>last seen <span class="mono">2d ago</span></span>
</div>
<div class="text-right mono" style="color: var(--ink-mid);">64 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mute);">127</div>
<div class="text-right mono" style="color: var(--bad); font-weight: 500;">1</div>
<div class="flex gap-1.5"><span class="tag">dev</span><span class="tag">personal</span></div>
<div class="text-right"><span class="mono text-xs" style="color: var(--ink-fade);">offline</span></div>
</div>
<!-- row: windows-vm -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">windows-vm</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">windows/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">28m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">44 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">156</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">staging</span><span class="tag">vm</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<!-- row: build-runner — failed -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">build-runner</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--bad); font-weight:500;">failed</span> · <span class="mono">47m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">97 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">2,847</div>
<div class="text-right mono" style="color: var(--bad); font-weight: 500;">1</div>
<div class="flex gap-1.5"><span class="tag">ci</span><span class="tag">build</span></div>
<div class="text-right"><button class="btn">Retry</button></div>
</div>
<!-- row: backup-test — never -->
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">backup-test</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mute);">
<span style="color: var(--ink-fade); font-style: italic;">never run</span>
</div>
<div class="text-right mono" style="color: var(--ink-fade);"></div>
<div class="text-right mono" style="color: var(--ink-fade);"></div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">test</span></div>
<div class="text-right"><button class="btn">Run first</button></div>
</div>
<!-- row: edge-node-eu (last row, no hairline) -->
<div class="row-hover grid items-center" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">edge-node-eu</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/arm64</div>
<div class="text-xs" style="color: var(--ink-mid);">
<span style="color: var(--ok);">succeeded</span> · <span class="mono">7m ago</span>
</div>
<div class="text-right mono" style="color: var(--ink);">23 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">934</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">edge</span><span class="tag">prod</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
</div>
</div>
<!-- Recent jobs strip -->
<div class="doc" style="padding: 16px 32px 56px;">
<div class="flex items-center justify-between mb-3">
<h2 style="font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: 0.01em;">Recent activity</h2>
<a class="text-xs" style="color: var(--ink-mute);">View all jobs →</a>
</div>
<div class="panel" style="border-radius: 7px;">
<div class="grid hairline" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 9px 16px; font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em;">
<div>Job</div><div>Host</div><div>Kind</div><div>Status</div><div>Started</div><div class="text-right">Bytes / Δ</div>
</div>
<div class="grid hairline mono" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 10px 16px; font-size: 12px;">
<div style="color: var(--ink-mute);">01KQH…E59B</div>
<div style="color: var(--ink);">prod-db-01</div>
<div style="color: var(--ink-mid);">backup</div>
<div style="color: var(--accent);">running · 38%</div>
<div style="color: var(--ink-mid);">3m ago</div>
<div class="text-right" style="color: var(--ink-mid);">1.4 GB</div>
</div>
<div class="grid hairline mono" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 10px 16px; font-size: 12px;">
<div style="color: var(--ink-mute);">01KQH…D9XK</div>
<div style="color: var(--ink);">prod-db-02</div>
<div style="color: var(--ink-mid);">backup</div>
<div style="color: var(--ok);">succeeded</div>
<div style="color: var(--ink-mid);">4m ago</div>
<div class="text-right" style="color: var(--ink-mid);">1.2 GB</div>
</div>
<div class="grid hairline mono" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 10px 16px; font-size: 12px;">
<div style="color: var(--ink-mute);">01KQH…7P2R</div>
<div style="color: var(--ink);">edge-node-eu</div>
<div style="color: var(--ink-mid);">backup</div>
<div style="color: var(--ok);">succeeded</div>
<div style="color: var(--ink-mid);">7m ago</div>
<div class="text-right" style="color: var(--ink-mid);">18 MB</div>
</div>
<div class="grid hairline mono" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 10px 16px; font-size: 12px;">
<div style="color: var(--ink-mute);">01KQH…M4QQ</div>
<div style="color: var(--ink);">prod-web-01</div>
<div style="color: var(--ink-mid);">backup</div>
<div style="color: var(--ok);">succeeded</div>
<div style="color: var(--ink-mid);">11m ago</div>
<div class="text-right" style="color: var(--ink-mid);">42 MB</div>
</div>
<div class="grid mono" style="grid-template-columns: 1fr 1.5fr 0.8fr 1fr 1fr 1fr; padding: 10px 16px; font-size: 12px;">
<div style="color: var(--ink-mute);">01KQH…9F8C</div>
<div style="color: var(--ink);">build-runner</div>
<div style="color: var(--ink-mid);">backup</div>
<div style="color: var(--bad);">failed · repo locked</div>
<div style="color: var(--ink-mid);">47m ago</div>
<div class="text-right" style="color: var(--ink-fade);"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Component vocabulary -->
<section class="components-section">
<h2>Component vocabulary</h2>
<p style="color: var(--ink-mute); font-size: 13px; margin-top: 8px; max-width: 620px;">
Pulled out of the live screen so the system reads cleanly. Anything that doesnt appear
here doesnt exist in this direction — and the goal is for the list below to stay short.
</p>
<div class="grid grid-cols-2 gap-10 mt-10">
<!-- status states -->
<div>
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 12px;">Status</div>
<div class="panel" style="border-radius: 7px; padding: 14px 18px;">
<div class="flex items-center justify-between text-sm py-2">
<span class="flex items-center gap-3"><span class="dot dot-online"></span><span>online</span></span>
<span class="mono text-xs" style="color: var(--ink-mute);">heartbeat &lt; 90s</span>
</div>
<div class="flex items-center justify-between text-sm py-2 hairline">
<span class="flex items-center gap-3"><span class="dot dot-online pulse"></span><span>online · running job</span></span>
<span class="mono text-xs" style="color: var(--ink-mute);">pulse only when active</span>
</div>
<div class="flex items-center justify-between text-sm py-2 hairline">
<span class="flex items-center gap-3"><span class="dot dot-degraded"></span><span>degraded</span></span>
<span class="mono text-xs" style="color: var(--ink-mute);">open alerts &gt; 0</span>
</div>
<div class="flex items-center justify-between text-sm py-2 hairline">
<span class="flex items-center gap-3"><span class="dot dot-offline"></span><span>offline</span></span>
<span class="mono text-xs" style="color: var(--ink-mute);">no heartbeat &gt; 90s</span>
</div>
<div class="flex items-center justify-between text-sm py-2 hairline">
<span class="flex items-center gap-3"><span class="dot dot-failed"></span><span>last job failed</span></span>
<span class="mono text-xs" style="color: var(--ink-mute);">distinct from offline</span>
</div>
</div>
</div>
<!-- buttons -->
<div>
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 12px;">Buttons</div>
<div class="panel" style="border-radius: 7px; padding: 16px 18px;">
<div class="flex items-center gap-2 flex-wrap">
<button class="btn btn-primary">+ Add host</button>
<button class="btn">Run now</button>
<button class="btn btn-ghost">View →</button>
<button class="btn" style="color: var(--bad); border-color: color-mix(in oklch, var(--bad), transparent 70%);">Cancel job</button>
<button class="btn" disabled style="opacity: 0.4; cursor: not-allowed;">Run now</button>
</div>
<div class="text-xs mt-3" style="color: var(--ink-mute);">
One <span style="color:var(--ink);">primary</span> per page (Add host). Everything else is the
neutral <span style="color:var(--ink);">secondary</span> or <span style="color:var(--ink);">ghost</span>; danger only on destructive verbs.
</div>
</div>
</div>
</div>
<!-- host card states (the rows compressed into 3 distinct examples) -->
<div class="mt-10">
<div style="font-size: 11px; color: var(--ink-fade); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 12px;">Host row · 3 states</div>
<div class="panel" style="border-radius: 7px;">
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-online"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">healthy-host</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);"><span style="color: var(--ok);">succeeded</span> · <span class="mono">5m ago</span></div>
<div class="text-right mono" style="color: var(--ink);">87 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">2,103</div>
<div class="text-right mono" style="color: var(--ink-mute);"></div>
<div class="flex gap-1.5"><span class="tag">prod</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<div class="row-hover grid items-center hairline" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-degraded"></span></div>
<div class="mono" style="color: var(--ink); font-weight: 500;">degraded-host</div>
<div class="mono" style="color: var(--ink-mid); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mid);"><span style="color: var(--ok);">succeeded</span> · <span class="mono">1h ago</span></div>
<div class="text-right mono" style="color: var(--ink);">128 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">1,402</div>
<div class="text-right mono" style="color: var(--bad); font-weight: 500;">3</div>
<div class="flex gap-1.5"><span class="tag">prod</span></div>
<div class="text-right"><button class="btn">Run now</button></div>
</div>
<div class="row-hover grid items-center" style="grid-template-columns: 24px 1.6fr 1fr 1.1fr 0.8fr 0.7fr 0.7fr 1.2fr 88px; padding: 11px 16px; font-size: 13px;">
<div><span class="dot dot-offline"></span></div>
<div class="mono" style="color: var(--ink-mid); font-weight: 500;">offline-host</div>
<div class="mono" style="color: var(--ink-mute); font-size:12px;">linux/amd64</div>
<div class="text-xs" style="color: var(--ink-mute);">last seen <span class="mono">2d ago</span></div>
<div class="text-right mono" style="color: var(--ink-mid);">64 <span style="color: var(--ink-mute); font-size: 11px;">GB</span></div>
<div class="text-right mono" style="color: var(--ink-mute);">127</div>
<div class="text-right mono" style="color: var(--bad); font-weight: 500;">1</div>
<div class="flex gap-1.5"><span class="tag">dev</span></div>
<div class="text-right"><span class="mono text-xs" style="color: var(--ink-fade);">offline</span></div>
</div>
</div>
</div>
</section>
</div>
</body>
</html>
+670
View File
@@ -0,0 +1,670 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>restic-manager · v2 Editorial Calm</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,500;6..72,600;6..72,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--bg: oklch(0.985 0.008 80);
--paper: #ffffff;
--line: oklch(0.90 0.012 75);
--line-soft: oklch(0.94 0.010 75);
--ink: oklch(0.22 0.02 60);
--ink-mid: oklch(0.42 0.015 60);
--ink-mute: oklch(0.58 0.012 60);
--ink-fade: oklch(0.70 0.010 60);
--ok: oklch(0.58 0.10 150);
--warn: oklch(0.65 0.13 70);
--bad: oklch(0.55 0.18 28);
--off: oklch(0.62 0.005 60);
/* The 120% detail in this direction is typography — a single
restrained accent in a deep editorial rust, used very sparingly. */
--accent: oklch(0.50 0.16 38);
--accent-soft: oklch(0.94 0.04 38);
}
html { background: var(--bg); }
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
color: var(--ink);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
.serif {
font-family: 'Newsreader', Georgia, serif;
font-feature-settings: 'liga', 'kern';
}
.mono {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-variant-numeric: tabular-nums;
font-weight: 400;
}
.text-balance { text-wrap: balance; }
.text-pretty { text-wrap: pretty; }
::selection { background: var(--accent-soft); color: var(--accent); }
.paper {
background: var(--paper);
border: 1px solid var(--line-soft);
border-radius: 14px;
box-shadow:
0 1px 0 rgba(60, 40, 20, 0.02),
0 1px 2px rgba(60, 40, 20, 0.03),
0 8px 24px -16px rgba(60, 40, 20, 0.06);
}
.hairline { border-top: 1px solid var(--line-soft); }
/* status chip — softer than a dot, reads as a label */
.chip {
display: inline-flex; align-items: center; gap: 7px;
font-size: 12px; line-height: 1; padding: 5px 10px 5px 8px;
border-radius: 9999px;
background: oklch(0.96 0.006 80);
color: var(--ink-mid);
border: 1px solid var(--line-soft);
letter-spacing: 0.005em;
}
.chip::before {
content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 9999px;
background: var(--off);
}
.chip.online::before { background: var(--ok); }
.chip.degraded::before { background: var(--warn); }
.chip.failed::before { background: var(--bad); }
.chip.offline::before { background: var(--off); }
.chip.never::before { background: var(--ink-fade); }
.tag {
display: inline-flex; align-items: center;
font-size: 11px; padding: 3px 8px; border-radius: 9999px;
background: oklch(0.96 0.008 80);
color: var(--ink-mid);
border: 1px solid var(--line-soft);
letter-spacing: 0.01em;
}
.btn {
font-size: 13px; font-weight: 500; padding: 8px 14px;
border-radius: 8px; border: 1px solid var(--line);
background: var(--paper); color: var(--ink);
transition: all 140ms ease;
}
.btn:hover { background: oklch(0.97 0.008 80); border-color: oklch(0.85 0.014 75); }
.btn-primary {
background: var(--ink); color: var(--bg); border-color: var(--ink);
}
.btn-primary:hover { background: oklch(0.30 0.02 60); }
.btn-quiet {
background: transparent; border-color: transparent; color: var(--ink-mid);
}
.btn-quiet:hover { background: oklch(0.96 0.008 80); color: var(--ink); }
/* nav */
.nav-link {
font-size: 14px; color: var(--ink-mid);
padding: 6px 0; margin-right: 28px;
border-bottom: 1.5px solid transparent;
transition: all 120ms ease;
}
.nav-link.active { color: var(--ink); border-color: var(--ink); }
.nav-link:hover { color: var(--ink); }
.doc { max-width: 1280px; margin: 0 auto; padding: 0 40px; }
.philosophy {
padding: 56px 0 40px;
}
.philosophy h1 { font-size: 32px; font-weight: 500; letter-spacing: -0.015em; }
.philosophy p {
color: var(--ink-mid); max-width: 640px;
margin-top: 18px; line-height: 1.7; font-size: 15px;
text-wrap: pretty;
}
.philosophy .meta { color: var(--ink-mute); font-size: 13px; margin-top: 14px; }
.stage-frame {
margin: 56px -40px;
background: var(--bg);
padding: 0;
}
.components-section { margin: 64px 0 96px; }
.components-section h2 {
font-size: 18px; font-weight: 600;
letter-spacing: -0.005em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="doc">
<!-- Philosophy preamble -->
<header class="philosophy">
<div class="text-xs uppercase tracking-[0.2em] text-[color:var(--ink-mute)] mb-3">v2 · Direction B</div>
<h1 class="serif">Editorial calm.</h1>
<p>
Optimised for trust. The product fades, the data foregrounds. Generous
whitespace, a serif display face, one rust accent used sparingly. Status
reads as language, not flashing colour. The screen feels like a quietly
maintained ledger — something you look at and feel reassured.
</p>
<p>
Reference: Stripe, Notion, the Pentagram-era Mailchimp dashboards. Tools
that feel like they respect your attention.
</p>
<p class="meta">
Risk: an operator who scans this 30 seconds at a time may find it less
glanceable than a tighter table; calm has a density cost.
</p>
</header>
<!-- Stage: full hi-fi dashboard -->
<div class="stage-frame">
<div style="background: var(--bg); padding: 0;">
<!-- Top bar -->
<div style="background: var(--paper); border-bottom: 1px solid var(--line-soft);">
<div class="doc flex items-center justify-between" style="padding: 18px 0;">
<div class="flex items-baseline gap-3">
<div class="serif" style="font-size: 20px; font-weight: 500; letter-spacing: -0.01em;">restic-manager</div>
<div class="mono" style="font-size: 11px; color: var(--ink-fade);">v0.1.0-alpha</div>
</div>
<div class="flex items-center gap-5">
<div style="font-size: 13px; color: var(--ink-mid);">steve@dcglab</div>
<button class="btn btn-quiet">Sign out</button>
</div>
</div>
</div>
<!-- Primary nav -->
<div style="background: var(--paper); border-bottom: 1px solid var(--line-soft);">
<div class="doc flex items-end justify-between" style="padding-top: 4px;">
<nav class="flex items-end" style="padding: 14px 0 14px;">
<a class="nav-link active">Dashboard</a>
<a class="nav-link">Repos</a>
<a class="nav-link">Alerts <span class="ml-1.5 mono" style="font-size: 11px; color: var(--bad);">5</span></a>
<a class="nav-link">Audit</a>
<a class="nav-link">Settings</a>
</nav>
<div class="pb-2.5">
<button class="btn btn-primary">Add host</button>
</div>
</div>
</div>
<!-- Hero summary -->
<div class="doc" style="padding: 56px 40px 32px;">
<div class="flex items-end justify-between mb-2">
<div>
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute);">Fleet · last 24 hours</div>
<h1 class="serif text-balance" style="font-size: 36px; font-weight: 500; letter-spacing: -0.018em; margin-top: 8px;">
<span style="color: var(--ink);">All but two of your hosts backed up cleanly today.</span>
</h1>
</div>
</div>
<div class="grid grid-cols-12 gap-8 mt-12">
<div class="col-span-3">
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute);">Hosts</div>
<div class="serif mt-2" style="font-size: 38px; font-weight: 500; letter-spacing: -0.02em;">12</div>
<div class="mt-3 text-sm" style="color: var(--ink-mid);">
<span class="mono" style="color: var(--ok);">10</span> online ·
<span class="mono" style="color: var(--warn);">1</span> degraded ·
<span class="mono" style="color: var(--off);">1</span> offline
</div>
</div>
<div class="col-span-3">
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute);">Backed up</div>
<div class="serif mt-2" style="font-size: 38px; font-weight: 500; letter-spacing: -0.02em;">4.9 <span style="font-size: 24px; color: var(--ink-mute); font-weight:400;">TB</span></div>
<div class="mt-3 text-sm" style="color: var(--ink-mid);"><span class="mono">23,649</span> snapshots</div>
</div>
<div class="col-span-3">
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute);">Last 24h</div>
<div class="serif mt-2" style="font-size: 38px; font-weight: 500; letter-spacing: -0.02em;">147 <span style="font-size: 24px; color: var(--ink-mute); font-weight:400;">jobs</span></div>
<div class="mt-3 text-sm" style="color: var(--ink-mid);">
<span class="mono" style="color: var(--ok);">144</span> ok ·
<span class="mono" style="color: var(--bad);">2</span> failed ·
<span class="mono">1</span> cancelled
</div>
</div>
<div class="col-span-3">
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute);">Open alerts</div>
<div class="serif mt-2" style="font-size: 38px; font-weight: 500; letter-spacing: -0.02em; color: var(--accent);">5</div>
<div class="mt-3 text-sm" style="color: var(--ink-mid);">oldest opened 3h ago →</div>
</div>
</div>
</div>
<!-- Hosts: card grid -->
<div class="doc" style="padding: 32px 40px 8px;">
<div class="flex items-baseline justify-between mb-6">
<h2 class="serif" style="font-size: 22px; font-weight: 500; letter-spacing: -0.01em;">Hosts</h2>
<div class="flex items-center gap-3 text-sm" style="color: var(--ink-mid);">
<span>Showing all 12 ·</span>
<a class="underline underline-offset-4 decoration-1" style="text-decoration-color: var(--line);">filter</a>
<a class="underline underline-offset-4 decoration-1" style="text-decoration-color: var(--line);">group by tag</a>
</div>
</div>
<div class="grid grid-cols-2 gap-5">
<!-- card: prod-db-01 — running -->
<div class="paper" style="padding: 22px 24px;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">prod-db-01</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip online">online · running</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1" style="color: var(--accent); font-weight:500;">running…</div>
<div class="mono text-xs" style="color: var(--ink-mute);">started 3m ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">412 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">1,847 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--ink-fade);"></div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">db</span></div>
<div class="text-xs" style="color: var(--ink-mute);">View →</div>
</div>
</div>
<!-- card: prod-db-02 -->
<div class="paper" style="padding: 22px 24px;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">prod-db-02</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip online">online</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1">succeeded</div>
<div class="mono text-xs" style="color: var(--ink-mute);">4 minutes ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">389 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">1,802 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--ink-fade);"></div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">db</span></div>
<button class="btn-quiet btn">Run backup now</button>
</div>
</div>
<!-- card: prod-cache-01 — degraded -->
<div class="paper" style="padding: 22px 24px; border-color: oklch(0.88 0.05 70);">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">prod-cache-01</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip degraded">degraded</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1">succeeded</div>
<div class="mono text-xs" style="color: var(--ink-mute);">1 hour ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">128 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">1,402 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--accent);">3</div>
<div class="text-xs" style="color: var(--ink-mute);">review →</div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">cache</span></div>
<button class="btn-quiet btn">Run backup now</button>
</div>
</div>
<!-- card: prod-web-01 -->
<div class="paper" style="padding: 22px 24px;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">prod-web-01</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip online">online</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1">succeeded</div>
<div class="mono text-xs" style="color: var(--ink-mute);">11 minutes ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">87 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">2,103 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--ink-fade);"></div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">prod</span><span class="tag">web</span></div>
<button class="btn-quiet btn">Run backup now</button>
</div>
</div>
<!-- card: homelab-nas -->
<div class="paper" style="padding: 22px 24px;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">homelab-nas</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/arm64</div>
</div>
<span class="chip online">online</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1">succeeded</div>
<div class="mono text-xs" style="color: var(--ink-mute);">2 hours ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">3.7 <span style="font-size: 13px; color: var(--ink-mute);">TB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">8,912 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--ink-fade);"></div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">homelab</span><span class="tag">storage</span></div>
<button class="btn-quiet btn">Run backup now</button>
</div>
</div>
<!-- card: build-runner — failed -->
<div class="paper" style="padding: 22px 24px; border-color: oklch(0.85 0.10 28);">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">build-runner</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip failed" style="color: var(--bad);">last job failed</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1" style="color: var(--bad);">failed</div>
<div class="mono text-xs" style="color: var(--ink-mute);">47 minutes ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">97 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">2,847 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--accent);">1</div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">ci</span><span class="tag">build</span></div>
<button class="btn">Retry job</button>
</div>
</div>
<!-- card: dev-laptop — offline -->
<div class="paper" style="padding: 22px 24px; opacity: 0.85;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em; color: var(--ink-mid);">dev-laptop</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip offline">offline · last seen 2d</span>
</div>
<div class="hairline mt-4 pt-4 grid grid-cols-3 gap-4">
<div>
<div class="text-xs" style="color: var(--ink-mute);">Last backup</div>
<div class="text-sm mt-1">succeeded</div>
<div class="mono text-xs" style="color: var(--ink-mute);">2 days ago</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Repo size</div>
<div class="serif mt-1" style="font-size: 18px;">64 <span style="font-size: 13px; color: var(--ink-mute);">GB</span></div>
<div class="mono text-xs" style="color: var(--ink-mute);">127 snapshots</div>
</div>
<div>
<div class="text-xs" style="color: var(--ink-mute);">Alerts</div>
<div class="serif mt-1" style="font-size: 18px; color: var(--accent);">1</div>
</div>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">dev</span><span class="tag">personal</span></div>
<span class="text-xs" style="color: var(--ink-mute);">awaiting agent</span>
</div>
</div>
<!-- card: backup-test — never -->
<div class="paper" style="padding: 22px 24px; background: oklch(0.985 0.005 80);">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 19px; font-weight: 500; letter-spacing: -0.005em;">backup-test</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip never">never run</span>
</div>
<div class="hairline mt-4 pt-4">
<p class="text-sm text-pretty" style="color: var(--ink-mid); line-height: 1.6;">
Newly enrolled. No backup has run yet — kick off the first one to populate
this card.
</p>
</div>
<div class="hairline mt-4 pt-4 flex items-center justify-between">
<div class="flex gap-1.5"><span class="tag">test</span></div>
<button class="btn btn-primary">Run first backup</button>
</div>
</div>
</div>
<!-- second row of less-noteworthy cards: condensed -->
<div class="mt-5 paper" style="padding: 8px 0;">
<div class="text-xs px-6 py-3" style="color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.12em;">Quiet hosts · last backup &gt; 5min and no alerts</div>
<div class="hairline grid grid-cols-3 gap-x-6 px-6" style="padding-top: 4px;">
<!-- compact list of remaining 4 hosts -->
<div class="hairline-bottom flex items-center justify-between py-3" style="border-bottom: 1px solid var(--line-soft);">
<div>
<div class="serif" style="font-size: 15px; font-weight: 500;">prod-web-02</div>
<div class="mono text-xs" style="color: var(--ink-mute);">linux/amd64 · 87 GB</div>
</div>
<div class="text-xs" style="color: var(--ink-mute);">12m ago</div>
</div>
<div class="hairline-bottom flex items-center justify-between py-3" style="border-bottom: 1px solid var(--line-soft);">
<div>
<div class="serif" style="font-size: 15px; font-weight: 500;">homelab-pi</div>
<div class="mono text-xs" style="color: var(--ink-mute);">linux/arm64 · 8.4 GB</div>
</div>
<div class="text-xs" style="color: var(--ink-mute);">6h ago</div>
</div>
<div class="hairline-bottom flex items-center justify-between py-3" style="border-bottom: 1px solid var(--line-soft);">
<div>
<div class="serif" style="font-size: 15px; font-weight: 500;">windows-vm</div>
<div class="mono text-xs" style="color: var(--ink-mute);">windows/amd64 · 44 GB</div>
</div>
<div class="text-xs" style="color: var(--ink-mute);">28m ago</div>
</div>
<div class="flex items-center justify-between py-3">
<div>
<div class="serif" style="font-size: 15px; font-weight: 500;">edge-node-eu</div>
<div class="mono text-xs" style="color: var(--ink-mute);">linux/arm64 · 23 GB</div>
</div>
<div class="text-xs" style="color: var(--ink-mute);">7m ago</div>
</div>
</div>
</div>
</div>
<!-- Recent activity -->
<div class="doc" style="padding: 56px 40px 64px;">
<div class="flex items-baseline justify-between mb-6">
<h2 class="serif" style="font-size: 22px; font-weight: 500; letter-spacing: -0.01em;">Recent activity</h2>
<a class="text-sm underline underline-offset-4 decoration-1" style="color: var(--ink-mid); text-decoration-color: var(--line);">View all jobs →</a>
</div>
<div class="paper" style="padding: 4px 0;">
<div class="grid items-center px-6 hairline" style="grid-template-columns: 1.4fr 1fr 1.6fr 1fr; padding-top: 14px; padding-bottom: 14px; border-top: none;">
<div class="serif" style="font-size: 16px; font-weight: 500;">prod-db-01</div>
<div class="text-sm" style="color: var(--accent); font-weight: 500;">backup running…</div>
<div class="text-sm" style="color: var(--ink-mid);">38% · 1.4 GB transferred · ETA 2m</div>
<div class="text-sm text-right" style="color: var(--ink-mute);">3m ago</div>
</div>
<div class="grid items-center px-6 hairline" style="grid-template-columns: 1.4fr 1fr 1.6fr 1fr; padding-top: 14px; padding-bottom: 14px;">
<div class="serif" style="font-size: 16px; font-weight: 500;">prod-db-02</div>
<div class="text-sm" style="color: var(--ok);">succeeded</div>
<div class="text-sm" style="color: var(--ink-mid);">1.2 GB transferred</div>
<div class="text-sm text-right" style="color: var(--ink-mute);">4m ago</div>
</div>
<div class="grid items-center px-6 hairline" style="grid-template-columns: 1.4fr 1fr 1.6fr 1fr; padding-top: 14px; padding-bottom: 14px;">
<div class="serif" style="font-size: 16px; font-weight: 500;">edge-node-eu</div>
<div class="text-sm" style="color: var(--ok);">succeeded</div>
<div class="text-sm" style="color: var(--ink-mid);">18 MB transferred</div>
<div class="text-sm text-right" style="color: var(--ink-mute);">7m ago</div>
</div>
<div class="grid items-center px-6 hairline" style="grid-template-columns: 1.4fr 1fr 1.6fr 1fr; padding-top: 14px; padding-bottom: 14px;">
<div class="serif" style="font-size: 16px; font-weight: 500;">prod-web-01</div>
<div class="text-sm" style="color: var(--ok);">succeeded</div>
<div class="text-sm" style="color: var(--ink-mid);">42 MB transferred</div>
<div class="text-sm text-right" style="color: var(--ink-mute);">11m ago</div>
</div>
<div class="grid items-center px-6" style="grid-template-columns: 1.4fr 1fr 1.6fr 1fr; padding-top: 14px; padding-bottom: 14px;">
<div class="serif" style="font-size: 16px; font-weight: 500;">build-runner</div>
<div class="text-sm" style="color: var(--bad);">failed</div>
<div class="text-sm" style="color: var(--ink-mid);">repo locked — concurrent operation</div>
<div class="text-sm text-right" style="color: var(--ink-mute);">47m ago</div>
</div>
</div>
</div>
</div>
</div>
<!-- Component vocabulary -->
<section class="components-section">
<h2 class="serif">Component vocabulary</h2>
<p style="color: var(--ink-mid); max-width: 580px; line-height: 1.7;" class="text-pretty">
A few honest pieces. The system stays small on purpose — every chip
and every button below is repeated in the live screen above, nothing more.
</p>
<div class="grid grid-cols-2 gap-6 mt-10">
<div class="paper" style="padding: 24px 28px;">
<div class="text-xs uppercase tracking-[0.16em]" style="color: var(--ink-mute); margin-bottom: 14px;">Status chips</div>
<div class="flex flex-col gap-3">
<div class="flex items-center gap-3"><span class="chip online">online</span> <span class="text-xs" style="color: var(--ink-mute);">heartbeat &lt; 90s</span></div>
<div class="flex items-center gap-3"><span class="chip online">online · running</span> <span class="text-xs" style="color: var(--ink-mute);">a job is in flight</span></div>
<div class="flex items-center gap-3"><span class="chip degraded">degraded</span> <span class="text-xs" style="color: var(--ink-mute);">open alerts &gt; 0</span></div>
<div class="flex items-center gap-3"><span class="chip offline">offline · last seen 2d</span> <span class="text-xs" style="color: var(--ink-mute);">no heartbeat &gt; 90s</span></div>
<div class="flex items-center gap-3"><span class="chip failed" style="color: var(--bad);">last job failed</span> <span class="text-xs" style="color: var(--ink-mute);">distinct from offline</span></div>
<div class="flex items-center gap-3"><span class="chip never">never run</span> <span class="text-xs" style="color: var(--ink-mute);">enrolled but cold</span></div>
</div>
</div>
<div class="paper" style="padding: 24px 28px;">
<div class="text-xs uppercase tracking-[0.16em]" style="color: var(--ink-mute); margin-bottom: 14px;">Buttons</div>
<div class="flex flex-wrap items-center gap-2">
<button class="btn btn-primary">Add host</button>
<button class="btn">Run backup now</button>
<button class="btn-quiet btn">View →</button>
<button class="btn" style="color: var(--bad); border-color: oklch(0.85 0.07 28);">Cancel job</button>
</div>
<div class="text-xs mt-4 text-pretty" style="color: var(--ink-mute); line-height: 1.6;">
One primary per page (<em>Add host</em>); everything else is the neutral
secondary. <em>Quiet</em> is reserved for "View →" affordances inside cards.
</div>
</div>
</div>
<!-- host card states -->
<div class="mt-10">
<div class="text-xs uppercase tracking-[0.16em]" style="color: var(--ink-mute); margin-bottom: 14px;">Host card · 3 states</div>
<div class="grid grid-cols-3 gap-5">
<div class="paper" style="padding: 18px 20px;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 16px; font-weight: 500;">healthy-host</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip online">online</span>
</div>
<div class="hairline mt-3 pt-3 text-xs" style="color: var(--ink-mid); line-height: 1.6;">
87 GB · 2,103 snapshots · last 11m ago
</div>
</div>
<div class="paper" style="padding: 18px 20px; border-color: oklch(0.88 0.05 70);">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 16px; font-weight: 500;">degraded-host</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip degraded">degraded</span>
</div>
<div class="hairline mt-3 pt-3 text-xs" style="color: var(--ink-mid); line-height: 1.6;">
128 GB · 1,402 snapshots · <span style="color: var(--accent);">3 alerts</span>
</div>
</div>
<div class="paper" style="padding: 18px 20px; opacity: 0.85;">
<div class="flex items-start justify-between">
<div>
<div class="serif" style="font-size: 16px; font-weight: 500; color: var(--ink-mid);">offline-host</div>
<div class="text-xs mt-1" style="color: var(--ink-mute);">linux/amd64</div>
</div>
<span class="chip offline">offline</span>
</div>
<div class="hairline mt-3 pt-3 text-xs" style="color: var(--ink-mid); line-height: 1.6;">
64 GB · 127 snapshots · last seen 2d ago
</div>
</div>
</div>
</div>
</section>
</div>
</body>
</html>
+666
View File
@@ -0,0 +1,666 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>restic-manager · v3 Print Spec</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=IBM+Plex+Sans:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--paper: oklch(0.985 0.011 82);
--paper-2: oklch(0.974 0.012 82);
--rule: oklch(0.20 0.008 60);
--rule-soft:oklch(0.78 0.014 75);
--rule-fade:oklch(0.88 0.012 75);
--ink: oklch(0.16 0.008 60);
--ink-mid: oklch(0.36 0.010 60);
--ink-mute: oklch(0.50 0.010 60);
--ink-fade: oklch(0.66 0.010 60);
/* Single state colour. Used only for `failed` / `alert`. Everything else
is type weight, brackets, and rule emphasis. */
--warn: oklch(0.50 0.20 28);
}
html, body {
background: var(--paper);
color: var(--ink);
font-family: 'IBM Plex Mono', ui-monospace, Menlo, Consolas, monospace;
font-feature-settings: 'kern', 'liga', 'tnum';
font-variant-numeric: tabular-nums;
-webkit-font-smoothing: antialiased;
}
/* The 120% detail in this direction is rule discipline — every horizontal
line falls on a strict baseline grid, and the rule weight encodes
hierarchy more reliably than colour ever does. */
.rule { border-bottom: 1.5px solid var(--rule); }
.rule-soft { border-bottom: 1px solid var(--rule-soft); }
.rule-fade { border-bottom: 1px solid var(--rule-fade); }
.rule-double {
border-bottom: 1.5px solid var(--rule);
box-shadow: 0 4px 0 -2.5px var(--rule);
}
.sans { font-family: 'IBM Plex Sans', ui-sans-serif, sans-serif; }
::selection { background: var(--ink); color: var(--paper); }
/* status as text glyph + label — no dots, no colour (except WARN) */
.st { display: inline-flex; align-items: baseline; gap: 4px; font-size: 12px; }
.st-glyph { font-weight: 600; letter-spacing: 0; }
.st-online .st-glyph { color: var(--ink); }
.st-degraded .st-glyph { color: var(--warn); }
.st-offline .st-glyph { color: var(--ink-fade); }
.st-failed .st-glyph { color: var(--warn); }
.st-never .st-glyph { color: var(--ink-fade); }
.st-running .st-glyph { color: var(--ink); }
.tag {
display: inline-block; font-size: 11px; padding: 0 6px;
color: var(--ink-mid);
border: 1px solid var(--rule-soft);
border-radius: 0;
line-height: 18px;
letter-spacing: 0.02em;
}
/* bracket buttons — visually a typed command */
.btn {
font-family: 'IBM Plex Mono', monospace;
font-size: 12px; padding: 4px 10px;
border: 1px solid var(--rule);
background: var(--paper);
color: var(--ink);
border-radius: 0;
transition: all 80ms linear;
cursor: pointer;
letter-spacing: 0.01em;
}
.btn::before { content: '['; margin-right: 4px; color: var(--ink-mid); }
.btn::after { content: ']'; margin-left: 4px; color: var(--ink-mid); }
.btn:hover { background: var(--ink); color: var(--paper); }
.btn:hover::before, .btn:hover::after { color: var(--paper); }
.btn-primary { background: var(--ink); color: var(--paper); }
.btn-primary::before, .btn-primary::after { color: var(--paper); }
.btn-primary:hover { filter: brightness(1.4); }
.btn-quiet {
border-color: transparent;
padding: 4px 6px;
}
.btn-quiet::before, .btn-quiet::after { color: var(--ink-fade); }
.btn-quiet:hover { background: var(--paper-2); color: var(--ink); }
.doc { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
.num { font-feature-settings: 'tnum', 'kern'; }
.philosophy { padding: 56px 0 32px; }
.philosophy h1 {
font-size: 22px; font-weight: 500;
letter-spacing: -0.005em;
}
.philosophy p {
color: var(--ink-mid); max-width: 640px;
margin-top: 16px; line-height: 1.65;
text-wrap: pretty;
}
.philosophy .meta { color: var(--ink-mute); font-size: 12px; margin-top: 14px; }
.stage-frame {
margin: 48px -32px;
border-top: 1.5px solid var(--rule);
border-bottom: 1.5px solid var(--rule);
background: var(--paper);
}
/* hosts table layout — fixed columns so numbers line up cleanly */
.hosts-grid {
display: grid;
grid-template-columns:
14ch /* status */
1fr /* host name */
14ch /* os/arch */
18ch /* last backup */
9ch /* size */
9ch /* snapshots */
6ch /* alerts */
14ch /* tags */
11ch; /* action */
align-items: baseline;
column-gap: 12px;
padding: 7px 16px;
font-size: 13px;
line-height: 1.55;
}
.hosts-grid > .ralign { text-align: right; }
.hosts-grid > .ralign-tags {
display: flex; gap: 4px; flex-wrap: nowrap; overflow: hidden;
}
.hosts-grid:hover { background: var(--paper-2); }
.col-head {
font-size: 11px; color: var(--ink-mute);
text-transform: uppercase; letter-spacing: 0.08em;
font-weight: 500;
}
.components-section { margin: 64px 0 96px; }
.components-section h2 {
font-size: 14px; font-weight: 600;
text-transform: uppercase; letter-spacing: 0.12em;
margin-bottom: 22px;
color: var(--ink-mid);
}
</style>
</head>
<body>
<div class="doc">
<!-- Philosophy preamble -->
<header class="philosophy">
<div class="text-xs uppercase tracking-[0.18em]" style="color: var(--ink-mute); margin-bottom: 12px;">v3 · Direction C</div>
<h1 class="sans" style="font-weight: 600;">Print spec.</h1>
<p>
Optimised for legibility under any condition: bright sunlight, copy-pasted
into Slack as a screenshot, printed on A4 and stuck to a server cabinet.
Monospace throughout so columns line up without effort. Status conveyed by
typeset glyph (<span class="num" style="color: var(--ink); font-weight:600;"></span>
online · <span class="num" style="color: var(--warn); font-weight:600;"></span>
degraded · <span class="num" style="color: var(--ink-fade); font-weight:600;"></span>
offline) so the screen survives being read in greyscale. One accent
colour, used only when something is wrong. Every horizontal rule earns its
weight; weight encodes hierarchy.
</p>
<p>
Reference: Edward Tufte, vintage aerospace datasheets, restic's own
<span class="num" style="color: var(--ink); font-weight: 500;">--json</span>
output, the wireframe register but at maximum craft.
</p>
<p class="meta">
Risk: the most polarising of the three. Some readers will love the
typographic discipline; others will read it as cold. There is no middle.
</p>
</header>
<!-- Stage: full hi-fi dashboard -->
<div class="stage-frame">
<!-- Top header — print-style with rules above and below -->
<div style="background: var(--paper);">
<div class="rule-fade">
<div class="doc flex items-baseline justify-between" style="padding: 10px 0;">
<div class="flex items-baseline gap-3" style="font-size: 11px; color: var(--ink-mute); letter-spacing: 0.04em;">
<span>RESTIC-MANAGER · DASHBOARD</span>
<span style="color: var(--ink-fade);">/</span>
<span>v0.1.0-alpha</span>
<span style="color: var(--ink-fade);">/</span>
<span>generated 2026-05-01 14:23 UTC</span>
</div>
<div class="flex items-baseline gap-3" style="font-size: 11px; color: var(--ink-mute); letter-spacing: 0.04em;">
<span>steve@dcglab</span>
<span style="color: var(--ink-fade);">/</span>
<a style="color: var(--ink-mid); text-decoration: underline; text-underline-offset: 3px;">sign out</a>
</div>
</div>
</div>
<!-- Big title row -->
<div class="rule" style="background: var(--paper);">
<div class="doc flex items-end justify-between" style="padding: 18px 0 12px;">
<h1 class="sans" style="font-size: 28px; font-weight: 600; letter-spacing: -0.015em;">restic-manager <span style="color: var(--ink-fade); font-weight: 400;">/ fleet dashboard</span></h1>
<div class="flex items-center gap-2">
<button class="btn btn-quiet">repos</button>
<button class="btn btn-quiet">alerts <span class="num" style="color: var(--warn); font-weight:600; padding-left:4px;">5</span></button>
<button class="btn btn-quiet">audit</button>
<button class="btn btn-quiet">settings</button>
<span style="width: 12px;"></span>
<button class="btn btn-primary">+ add host</button>
</div>
</div>
</div>
</div>
<!-- Fleet summary as a print-style ledger -->
<div class="doc" style="padding: 28px 32px 8px;">
<div class="grid grid-cols-4 gap-px" style="background: var(--rule-fade); border: 1px solid var(--rule-fade);">
<div style="background: var(--paper); padding: 18px 20px;">
<div class="col-head">FLEET</div>
<div class="num sans" style="font-size: 32px; font-weight: 500; letter-spacing: -0.02em; margin-top: 6px;">12 <span style="font-size: 13px; color: var(--ink-mute); font-weight: 400; font-family: 'IBM Plex Mono';">hosts</span></div>
<div style="font-size: 12px; margin-top: 10px; color: var(--ink-mid);">
<span class="num" style="color: var(--ink); font-weight: 500;">10</span>&nbsp;online &nbsp;
<span class="num" style="color: var(--warn); font-weight: 500;">1</span>&nbsp;degraded &nbsp;
<span class="num" style="color: var(--ink-fade); font-weight: 500;">1</span>&nbsp;offline
</div>
</div>
<div style="background: var(--paper); padding: 18px 20px;">
<div class="col-head">BACKED UP</div>
<div class="num sans" style="font-size: 32px; font-weight: 500; letter-spacing: -0.02em; margin-top: 6px;">4.9 <span style="font-size: 13px; color: var(--ink-mute); font-weight: 400; font-family: 'IBM Plex Mono';">TB · 12 repos</span></div>
<div style="font-size: 12px; margin-top: 10px; color: var(--ink-mid);">
<span class="num" style="color: var(--ink); font-weight: 500;">23,649</span>&nbsp;snapshots
</div>
</div>
<div style="background: var(--paper); padding: 18px 20px;">
<div class="col-head">LAST 24H</div>
<div class="num sans" style="font-size: 32px; font-weight: 500; letter-spacing: -0.02em; margin-top: 6px;">147 <span style="font-size: 13px; color: var(--ink-mute); font-weight: 400; font-family: 'IBM Plex Mono';">jobs</span></div>
<div style="font-size: 12px; margin-top: 10px; color: var(--ink-mid);">
<span class="num" style="color: var(--ink); font-weight: 500;">144</span>&nbsp;ok &nbsp;
<span class="num" style="color: var(--warn); font-weight: 500;">2</span>&nbsp;failed &nbsp;
<span class="num" style="color: var(--ink-mid); font-weight: 500;">1</span>&nbsp;cancelled
</div>
</div>
<div style="background: var(--paper); padding: 18px 20px;">
<div class="col-head">OPEN ALERTS</div>
<div class="num sans" style="font-size: 32px; font-weight: 500; letter-spacing: -0.02em; margin-top: 6px; color: var(--warn);">5 <span style="font-size: 13px; color: var(--ink-mute); font-weight: 400; font-family: 'IBM Plex Mono';">unresolved</span></div>
<div style="font-size: 12px; margin-top: 10px; color: var(--ink-mid);">
oldest <span class="num" style="color: var(--ink); font-weight: 500;">3h</span> · review →
</div>
</div>
</div>
</div>
<!-- Hosts ledger -->
<div class="doc" style="padding: 32px 32px 12px;">
<div class="flex items-baseline justify-between" style="padding-bottom: 8px;">
<div class="flex items-baseline gap-4">
<h2 class="sans" style="font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Hosts</h2>
<span style="font-size: 12px; color: var(--ink-mute);">12 of 12 — sorted by status, then last activity</span>
</div>
<div class="flex items-center gap-2">
<span style="font-size: 12px; color: var(--ink-mute);">filter:</span>
<input
type="text"
placeholder="name | tag | status…"
style="font-family: 'IBM Plex Mono'; font-size: 12px; padding: 4px 10px; background: var(--paper); border: 1px solid var(--rule-soft); border-radius: 0; color: var(--ink); width: 220px; outline: none;"
value=""
/>
<button class="btn btn-quiet">group: tag</button>
</div>
</div>
<div class="rule"></div>
<!-- table head -->
<div class="hosts-grid col-head" style="padding-top: 8px; padding-bottom: 8px;">
<div></div>
<div>host</div>
<div>os/arch</div>
<div>last backup</div>
<div class="ralign">size</div>
<div class="ralign">snaps</div>
<div class="ralign">alerts</div>
<div>tags</div>
<div class="ralign"></div>
</div>
<div class="rule-soft"></div>
<!-- ATTENTION block: degraded + failed + offline up top -->
<div style="font-size: 11px; color: var(--warn); padding: 10px 16px 4px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600;">▲ requires attention</div>
<!-- prod-cache-01 — degraded -->
<div class="hosts-grid">
<div class="st st-degraded"><span class="st-glyph"></span><span style="color: var(--ink-mid);">degraded</span></div>
<div style="color: var(--ink); font-weight: 500;">prod-cache-01</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);"><span style="color: var(--ink);">ok</span> 1h ago</div>
<div class="ralign num" style="color: var(--ink);">128<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">1,402</div>
<div class="ralign num" style="color: var(--warn); font-weight: 600;">3</div>
<div class="ralign-tags"><span class="tag">prod</span><span class="tag">cache</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- build-runner — failed -->
<div class="hosts-grid">
<div class="st st-failed"><span class="st-glyph"></span><span style="color: var(--ink-mid);">failed</span></div>
<div style="color: var(--ink); font-weight: 500;">build-runner</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--warn);">repo locked 47m ago</div>
<div class="ralign num" style="color: var(--ink);">97<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">2,847</div>
<div class="ralign num" style="color: var(--warn); font-weight: 600;">1</div>
<div class="ralign-tags"><span class="tag">ci</span><span class="tag">build</span></div>
<div class="ralign"><button class="btn">retry</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- dev-laptop — offline -->
<div class="hosts-grid">
<div class="st st-offline"><span class="st-glyph"></span><span style="color: var(--ink-mid);">offline</span></div>
<div style="color: var(--ink-mid); font-weight: 500;">dev-laptop</div>
<div style="color: var(--ink-mute);">linux/amd64</div>
<div style="color: var(--ink-mute);">last seen 2d ago</div>
<div class="ralign num" style="color: var(--ink-mid);">64<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mute);">127</div>
<div class="ralign num" style="color: var(--warn); font-weight: 600;">1</div>
<div class="ralign-tags"><span class="tag">dev</span><span class="tag">personal</span></div>
<div class="ralign" style="color: var(--ink-fade); font-size: 11px;">offline</div>
</div>
<div class="rule"></div>
<!-- HEALTHY hosts -->
<div style="font-size: 11px; color: var(--ink-mute); padding: 10px 16px 4px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 500;">● online · last 24h</div>
<!-- prod-db-01 — running -->
<div class="hosts-grid">
<div class="st st-running"><span class="st-glyph"></span><span style="color: var(--ink-mid);">running</span></div>
<div style="color: var(--ink); font-weight: 500;">prod-db-01</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink);">backup · 38% · ETA 2m</div>
<div class="ralign num" style="color: var(--ink);">412<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">1,847</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">prod</span><span class="tag">db</span></div>
<div class="ralign"><button class="btn btn-quiet">view</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- prod-db-02 -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">prod-db-02</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);">ok 4m ago</div>
<div class="ralign num" style="color: var(--ink);">389<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">1,802</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">prod</span><span class="tag">db</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- edge-node-eu -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">edge-node-eu</div>
<div style="color: var(--ink-mid);">linux/arm64</div>
<div style="color: var(--ink-mid);">ok 7m ago</div>
<div class="ralign num" style="color: var(--ink);">23<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">934</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">edge</span><span class="tag">prod</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- prod-web-01 -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">prod-web-01</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);">ok 11m ago</div>
<div class="ralign num" style="color: var(--ink);">87<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">2,103</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">prod</span><span class="tag">web</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- prod-web-02 -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">prod-web-02</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);">ok 12m ago</div>
<div class="ralign num" style="color: var(--ink);">87<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">2,098</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">prod</span><span class="tag">web</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- windows-vm -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">windows-vm</div>
<div style="color: var(--ink-mid);">windows/amd64</div>
<div style="color: var(--ink-mid);">ok 28m ago</div>
<div class="ralign num" style="color: var(--ink);">44<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">156</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">staging</span><span class="tag">vm</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- homelab-nas -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">homelab-nas</div>
<div style="color: var(--ink-mid);">linux/arm64</div>
<div style="color: var(--ink-mid);">ok 2h ago</div>
<div class="ralign num" style="color: var(--ink);">3.7<span style="color: var(--ink-mute);">T</span></div>
<div class="ralign num" style="color: var(--ink-mid);">8,912</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">homelab</span><span class="tag">storage</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- homelab-pi -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">homelab-pi</div>
<div style="color: var(--ink-mid);">linux/arm64</div>
<div style="color: var(--ink-mid);">ok 6h ago</div>
<div class="ralign num" style="color: var(--ink);">8.4<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">421</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">homelab</span><span class="tag">iot</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- backup-test — never -->
<div class="hosts-grid">
<div class="st st-never"><span class="st-glyph"></span><span style="color: var(--ink-mid);">never</span></div>
<div style="color: var(--ink); font-weight: 500;">backup-test</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-fade); font-style: italic;">no backup yet</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">test</span></div>
<div class="ralign"><button class="btn">run first</button></div>
</div>
<div class="rule"></div>
</div>
<!-- Recent activity log — log-tail style -->
<div class="doc" style="padding: 24px 32px 56px;">
<div class="flex items-baseline justify-between mb-3">
<h2 class="sans" style="font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Activity tail</h2>
<span style="font-size: 12px; color: var(--ink-mute);">last 5 jobs · all hosts · <a style="text-decoration: underline; text-underline-offset: 3px; color: var(--ink-mid);">view all</a></span>
</div>
<div class="rule"></div>
<div style="font-size: 13px; padding: 6px 16px 0; line-height: 1.85;">
<div style="display: grid; grid-template-columns: 16ch 18ch 14ch 1fr 9ch 7ch; column-gap: 18px; padding: 4px 0;">
<span class="num" style="color: var(--ink-mute);">14:23:01.382</span>
<span style="color: var(--ink); font-weight:500;">prod-db-01</span>
<span class="num" style="color: var(--ink);">▶ running</span>
<span style="color: var(--ink-mid);">backup · 38% · 1.4 GB · ETA 2m</span>
<span class="num ralign" style="color: var(--ink-mid);">3m ago</span>
<span class="ralign" style="font-size: 11px; color: var(--ink-fade);">…E59B</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 16ch 18ch 14ch 1fr 9ch 7ch; column-gap: 18px; padding: 4px 0;">
<span class="num" style="color: var(--ink-mute);">14:22:17.011</span>
<span style="color: var(--ink); font-weight:500;">prod-db-02</span>
<span class="num" style="color: var(--ink);">● ok</span>
<span style="color: var(--ink-mid);">backup succeeded · 1.2 GB</span>
<span class="num ralign" style="color: var(--ink-mid);">4m ago</span>
<span class="ralign" style="font-size: 11px; color: var(--ink-fade);">…D9XK</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 16ch 18ch 14ch 1fr 9ch 7ch; column-gap: 18px; padding: 4px 0;">
<span class="num" style="color: var(--ink-mute);">14:19:44.227</span>
<span style="color: var(--ink); font-weight:500;">edge-node-eu</span>
<span class="num" style="color: var(--ink);">● ok</span>
<span style="color: var(--ink-mid);">backup succeeded · 18 MB</span>
<span class="num ralign" style="color: var(--ink-mid);">7m ago</span>
<span class="ralign" style="font-size: 11px; color: var(--ink-fade);">…7P2R</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 16ch 18ch 14ch 1fr 9ch 7ch; column-gap: 18px; padding: 4px 0;">
<span class="num" style="color: var(--ink-mute);">14:15:08.946</span>
<span style="color: var(--ink); font-weight:500;">prod-web-01</span>
<span class="num" style="color: var(--ink);">● ok</span>
<span style="color: var(--ink-mid);">backup succeeded · 42 MB</span>
<span class="num ralign" style="color: var(--ink-mid);">11m ago</span>
<span class="ralign" style="font-size: 11px; color: var(--ink-fade);">…M4QQ</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 16ch 18ch 14ch 1fr 9ch 7ch; column-gap: 18px; padding: 4px 0;">
<span class="num" style="color: var(--ink-mute);">13:39:12.604</span>
<span style="color: var(--ink); font-weight:500;">build-runner</span>
<span class="num" style="color: var(--warn); font-weight:600;">✗ failed</span>
<span style="color: var(--warn);">repo locked — concurrent operation</span>
<span class="num ralign" style="color: var(--ink-mid);">47m ago</span>
<span class="ralign" style="font-size: 11px; color: var(--ink-fade);">…9F8C</span>
</div>
</div>
</div>
</div>
<!-- Component vocabulary -->
<section class="components-section">
<h2 class="sans">Component vocabulary</h2>
<div class="grid grid-cols-2 gap-x-10 gap-y-12">
<!-- statuses -->
<div>
<div class="col-head" style="margin-bottom: 12px;">Status glyphs</div>
<div class="rule"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--ink); font-weight: 600;"></span>
<span style="color: var(--ink); font-weight: 500;">online</span>
<span style="color: var(--ink-mute);">heartbeat &lt; 90s</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--ink); font-weight: 600;"></span>
<span style="color: var(--ink); font-weight: 500;">online · running</span>
<span style="color: var(--ink-mute);">a job is in flight</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--warn); font-weight: 600;"></span>
<span style="color: var(--ink); font-weight: 500;">degraded</span>
<span style="color: var(--ink-mute);">open alerts &gt; 0</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--ink-fade); font-weight: 600;"></span>
<span style="color: var(--ink-mid); font-weight: 500;">offline</span>
<span style="color: var(--ink-mute);">no heartbeat &gt; 90s</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--warn); font-weight: 600;"></span>
<span style="color: var(--ink); font-weight: 500;">last job failed</span>
<span style="color: var(--ink-mute);">distinct from offline</span>
</div>
<div class="rule-fade"></div>
<div style="display: grid; grid-template-columns: 4ch 14ch 1fr; padding: 10px 0; column-gap: 16px; font-size: 13px;">
<span class="num" style="color: var(--ink-fade); font-weight: 600;"></span>
<span style="color: var(--ink-mid); font-weight: 500;">never</span>
<span style="color: var(--ink-mute);">enrolled but cold</span>
</div>
<div class="rule"></div>
</div>
<!-- buttons -->
<div>
<div class="col-head" style="margin-bottom: 12px;">Buttons</div>
<div class="rule"></div>
<div style="padding: 16px 0; display: flex; flex-wrap: wrap; gap: 8px; align-items: center;">
<button class="btn btn-primary">+ add host</button>
<button class="btn">run</button>
<button class="btn">retry</button>
<button class="btn btn-quiet">view</button>
<button class="btn" style="color: var(--warn); border-color: var(--warn);">cancel</button>
</div>
<div class="rule"></div>
<p style="font-size: 12px; color: var(--ink-mute); padding-top: 14px; line-height: 1.7;" class="text-pretty">
Bracketed verbs read as commands. One filled "primary" per page (<span class="num" style="color: var(--ink); font-weight: 500;">+ add host</span>),
everything else outline. Ghost variant for inline view links.
</p>
</div>
</div>
<!-- host row, 3 states -->
<div class="mt-14">
<div class="col-head" style="margin-bottom: 12px;">Host row · 3 states</div>
<div class="rule"></div>
<div class="hosts-grid col-head" style="padding: 8px 16px;">
<div></div>
<div>host</div>
<div>os/arch</div>
<div>last backup</div>
<div class="ralign">size</div>
<div class="ralign">snaps</div>
<div class="ralign">alerts</div>
<div>tags</div>
<div class="ralign"></div>
</div>
<div class="rule-soft"></div>
<!-- healthy -->
<div class="hosts-grid">
<div class="st st-online"><span class="st-glyph"></span><span style="color: var(--ink-mid);">online</span></div>
<div style="color: var(--ink); font-weight: 500;">healthy-host</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);">ok 5m ago</div>
<div class="ralign num" style="color: var(--ink);">87<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">2,103</div>
<div class="ralign num" style="color: var(--ink-fade);"></div>
<div class="ralign-tags"><span class="tag">prod</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- degraded -->
<div class="hosts-grid">
<div class="st st-degraded"><span class="st-glyph"></span><span style="color: var(--ink-mid);">degraded</span></div>
<div style="color: var(--ink); font-weight: 500;">degraded-host</div>
<div style="color: var(--ink-mid);">linux/amd64</div>
<div style="color: var(--ink-mid);">ok 1h ago</div>
<div class="ralign num" style="color: var(--ink);">128<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mid);">1,402</div>
<div class="ralign num" style="color: var(--warn); font-weight: 600;">3</div>
<div class="ralign-tags"><span class="tag">prod</span></div>
<div class="ralign"><button class="btn">run</button></div>
</div>
<div class="rule-fade" style="margin-left: 16px; margin-right: 16px;"></div>
<!-- offline -->
<div class="hosts-grid">
<div class="st st-offline"><span class="st-glyph"></span><span style="color: var(--ink-mid);">offline</span></div>
<div style="color: var(--ink-mid); font-weight: 500;">offline-host</div>
<div style="color: var(--ink-mute);">linux/amd64</div>
<div style="color: var(--ink-mute);">last seen 2d ago</div>
<div class="ralign num" style="color: var(--ink-mid);">64<span style="color: var(--ink-mute);">G</span></div>
<div class="ralign num" style="color: var(--ink-mute);">127</div>
<div class="ralign num" style="color: var(--warn); font-weight: 600;">1</div>
<div class="ralign-tags"><span class="tag">dev</span></div>
<div class="ralign" style="color: var(--ink-fade); font-size: 11px;">offline</div>
</div>
<div class="rule"></div>
</div>
</section>
</div>
</body>
</html>