Refactor the Infrastructure tier into the dark operator console from the design package, wired to the real fleet backend (no new plumbing): - InfraNav: page-scoped left nav grouped RUN HERE FIRST (Local & Tailscale, with online count + sub-items) / NEXT (Cloud providers, SOON) + coral "Connect a host" button; coral spine on the active view. - FleetConsole: center reads top-to-bottom — kicker → "Your fleet" → 5 stat tiles (HOSTS/ONLINE/MEMORY/STORAGE/CONTAINERS) → Tailscale device card → LOCAL HOSTS host cards + add-host dashed tile. Cloud view = how-it-works + SOON. - Host cards (design system): status dot (blink when online) + hostname, IP/version line, CPU/RAM meter bars (cyan→amber→coral by load), disk/load/ctrs mini-row, and a footer that's a copyable `ssh <node>` target (online) OR a "waiting for daemon" spinner (pairing) — PLUS a Terminal button that opens the in-app shell. - FleetPill (top bar, N/M hosts online) + FleetStatusBar (ambient: daemon · tailnet · WSS · sandbox). Per the chosen reconciliation: kept the cloud-apps computer pull-out as the right column, the connect-host wizard as a modal, and the in-app terminal. Dashboard infra branch rewired (InfraNav + FleetConsole + status bar; dropped the old InfraStage/InfraConsole split). cm-blink/spin/cm-fade keyframes already existed. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
9.0 KiB
Infrastructure Page — Design Guide
How the Clawmates Infrastructure page is put together, and the rules to follow if you want to build (or extend) a page in this style. Use this as the recipe; the .dc.html file in this folder is the working reference.
1. What this page is
A single full-bleed control surface for managing the agent fleet — the machines that run agents. It answers three questions at a glance:
- What hardware do I have, and is it healthy? (stats + host cards)
- How do I add more? (right-hand "Add to fleet" panel + wizards)
- Is the connective tissue up? (Tailscale status, daemon control plane, sandbox readiness)
The whole thing is a dark operator console — closer to a terminal/observability tool than a marketing page. Every design decision below serves that feeling: dense, calm, trustworthy, no decoration that isn't carrying information.
2. The layout system
The page is a fixed full-viewport shell (100vw × 100vh, overflow:hidden) divided into five regions. Lock this skeleton first — everything else hangs off it.
┌─────────────────────────────────────────────────────────┐
│ TOP BAR (50px) logo · breadcrumb · fleet pill · avatar │
├──┬──────────┬───────────────────────────────┬────────────┤
│ │ │ │ │
│IC│ LEFT NAV │ CENTER (fluid) │ RIGHT PANEL│
│ON│ 216px │ stats → network → cards │ 344px │
│54│ │ │ contextual│
│ │ │ │ │
├──┴──────────┴───────────────────────────────┴────────────┤
│ STATUS BAR (26px) daemon ok · tailnet · WSS · sandbox │
└─────────────────────────────────────────────────────────┘
- Icon rail (54px): product-level switcher (World / Agent / Infra). Pure glyphs + 7px mono labels.
- Left nav (216px): scoped to this page — sources of compute, grouped under
RUN HERE FIRSTandNEXT. The active item gets a 3px coral spine on its left edge. - Center (fluid, scrolls): the content. Reads top-to-bottom as a narrative: heading → fleet stats → network → host cards.
- Right panel (344px): the action surface. It is contextual — it swaps between a menu, the connect-a-host wizard, the Tailscale view, and the cloud wizard, but the column never moves. This separation (read on the left/center, act on the right) is the core interaction idea.
- Status bar (26px): ambient system truth. Always-on, mono, low-contrast.
Only the center and right-panel inner columns scroll; the rails, top bar and status bar are pinned (flex:none).
3. Color
A near-black warm-neutral base with functional accents only. Don't introduce a color unless it means something.
| Token | Value | Used for |
|---|---|---|
| Canvas | #08080a |
page background |
| Surface | #0d0d10 / #0c0c0f |
cards, panels |
| Rail / nav | #0a0a0c / #0b0b0e |
chrome columns |
| Hairline | rgba(255,255,255,.06–.08) |
every border & divider |
| Text high | #f3f3f5 |
headings, key values |
| Text mid | #8a8a92 / #9a9aa2 |
body copy |
| Text low | #5a5a62 / #6a6a72 |
mono labels, meta |
Accents (each owns a meaning — keep it that way):
- Coral
#ff6f61→ brand + the primary action / active nav. Used sparingly so it always pulls the eye to "the next thing to do." - Green
#5fd08a→ healthy / online / connected. - Cyan
#5ec8d8→ network, links, secondary actions, IPs. - Amber
#e8b465→ pending / pairing / cost / "SOON". - Coral→red gradient
linear-gradient(135deg,#ff8a7a,#ff5f57)is the one filled button treatment; green gradient marks a completed terminal action.
Rule of thumb: a screen should be ~90% neutral. If it looks colorful, you've over-accented.
4. Type
Two families, sharp roles:
- Helvetica Neue (system sans) — all UI prose, headings, labels-with-sentences.
- JetBrains Mono — anything machine: IPs, hostnames, commands, stat labels (
HOSTS,vCPU), counts, status text, the status bar. This mono/sans split is what makes the page read as an operator tool rather than a website. Use it deliberately.
Scale (don't go below these):
- Section heading:
26px / 700 / -.02em - Card title:
14px / 700 - Body:
12–13px - Mono labels:
9–10px, letter-spacing.1–.14em, low-contrast color. These uppercase mono kickers (LOCAL & TAILSCALE,PROVIDERS) sit above almost every block and are the page's connective rhythm.
5. Components & their patterns
Stat tiles — a 5-col grid of border + #0d0d10 cards: tiny mono label on top, big 22px/700 number below. Healthy/notable ones tint their border + number (green for ONLINE, cyan for CONTAINERS).
Host health card — the workhorse. Each one carries: status dot + name + status label; mono OS line; CPU & RAM as thin 4px meter bars (color shifts cyan→amber→coral as load climbs); a 3-up disk/load/ctrs mini-row; and a footer that is either a copyable ssh target (online) or a spinning "waiting for daemon" chip (pairing). Same card, state-driven contents.
Add-host tile — a dashed-border ghost card that ends the grid; clicking it opens the wizard. Always leave the "add another" affordance visible.
Section header row — mono kicker · 1px rule that flexes to fill · a cyan inline action (+ connect a host). Used to break the center column into labeled bands.
Right-panel wizards — stepped flows (install → connect → verify). A numbered stepper at top; one step visible at a time with a small cm-fade entrance; terminal "success" state uses the green gradient button. Faux terminals (mac traffic-light dots + mono body) show commands and check output.
Meters, dots, pills — health is shown the same way everywhere: a colored dot for state, a thin bar for utilization, a bordered pill for a labeled status. Reuse these three primitives instead of inventing new indicators.
6. Motion
Restrained and diegetic. Four keyframes only:
cm-blink— slow pulse on live "online" dots.cm-spin— spinners while waiting on the daemon / provisioning.cm-fade— 0.2s rise on step/panel changes.cm-pip— subtle status flicker.
No page-load chrome animation, no parallax, no decorative motion. Movement only ever means "something is live" or "the view just changed."
7. Voice
Technical, plain, reassuring about security. The copy keeps repeating the trust story: "outbound WSS — no inbound port, no keys", "credentials stay in the secret broker", "§15 network-isolated sandboxes". Lead with the user's own hardware (RUN HERE FIRST → Local & Tailscale), mark cloud as NEXT/SOON. Buttons say what will happen (I've run it — waiting for connection →, Add forge-02 to fleet), never just "Submit."
8. How it's built (structure)
This is a Design Component (.dc.html) — one self-contained file that opens in a browser.
- Template = the markup, styled entirely with inline styles (no CSS classes except the four
@keyframesand scrollbar rules in<helmet>). This is intentional: inline styles paint immediately as the file streams. - Logic = a
class Component extends DCLogicat the bottom. All state lives inthis.state(nav,addMode, wizardstep,connecting, etc.);renderVals()returns every value and handler the template binds with{{ … }}. - Data is mocked in
renderVals()—hosts,tsDevices,cloudProviders,cloudRunners. To wire this to real data, replace those arrays with your fetched fleet state; the rest of the template is shape-stable. - Control flow:
<sc-if>swaps the center view (local vs cloud) and the right-panel mode;<sc-for>repeats host cards, devices, providers. State-driven contents, not separate pages.
To build a new page in this style
- Drop the 5-region shell first (top bar / icon rail / nav / center / status bar) and pin everything but center.
- Establish the mono-kicker → content rhythm in the center column.
- Put all actions in the right panel; make it swap by
addMode, never navigate away. - Use only the five accents, each for its one meaning; keep ~90% neutral.
- Show state with the dot / meter / pill trio and the four keyframes — nothing more.
9. Files in this package
Clawmates Infrastructure.dc.html— the page (open directly in a browser).support.js— the runtime the.dc.htmlneeds; keep it beside the page.DESIGN-GUIDE.md— this document.