Files
restic-manager/design/v1-operator-console.html
T
steve afce98f105 design: three hi-fi dashboard directions for review
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>
2026-05-01 18:39:57 +01:00

576 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>