afce98f105
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>
671 lines
34 KiB
HTML
671 lines
34 KiB
HTML
<!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 > 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 < 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 > 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 > 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>
|