Upstream sing-box-lx already ships a docs/ mkdocs site; keep our project docs separate and unambiguous in docs-shater/ (parallels upstream's docs-lx/). Updated all references in README.md, CLAUDE.md, CONTEXT.md, ARCHITECTURE.md.
4.3 KiB
Design system — "Faceplate"
The shater admin panel has one visual direction: Faceplate — the UI is the front panel of a premium piece of network hardware, not a generic SaaS dashboard. It grows from what the product is (a physical OpenWrt appliance) and uses the brand orange as a disciplined accent.
North-star reference (live prototype): https://claude.ai/code/artifact/9f7c07e8-d8ac-4ae1-b113-5b25d0ba5dd2
Every screen is built to match that prototype. When in doubt, open it and copy the behaviour exactly. Below is the spec extracted from it.
Principles
- Instrument panel, not a webpage. Engraved labels, LED indicators, physical toggles/switches, segmented VU-style meters, corner screws, hairline grooves.
- Spend boldness in one place. Orange (
--accent) is only for the active state, key numbers, and LED glow. Everything else stays quiet. - Semantic color is separate from the accent. good / warn / crit have their own tokens and never double as the brand accent.
- Data reads at a glance. State is shown in form (LED, pill, meter fill),
not just in text. All digits use
font-variant-numeric: tabular-nums. - Both themes, equal care. Dark = anodized black panel. Light = brushed
aluminium. Not an inversion — each is tuned.
prefers-color-schemeis the default; adata-themeattribute on the root overrides it in both directions.
Tokens (copy verbatim into tokens.css)
Dark (anodized panel):
--panel:#15120c; --raised:#201a12; --sink:#100d08;
--ink:#ece4d5; --dim:#948b7c; --faint:#6b6456;
--accent:#ff6a1a; --accent-soft:#7a3d16;
--groove:#33291c; --edge:#2c2417; --shadow:rgba(0,0,0,.55);
--led-on:#7fb646; --amber:#e8a72c; --crit:#e5484d;
--seg-off:#2e2718; --seg-on:#ff6a1a;
Light (brushed aluminium):
--panel:#e7e2d6; --raised:#f4f0e6; --sink:#dcd6c8;
--ink:#211d15; --dim:#6c6555; --faint:#938b78;
--accent:#e5590d; --accent-soft:#f6b98a;
--groove:#c9c2b0; --edge:#ffffff; --shadow:rgba(60,50,30,.18);
--led-on:#5c9a2e; --amber:#c98416; --crit:#cf3a3a;
--seg-off:#cbc4b2; --seg-on:#e5590d;
Type
- Instrument voice (display, labels, all data): monospace —
ui-monospace, "JetBrains Mono", "Cascadia Code", "SF Mono", Menlo, Consolas, monospace. This is the signature face (silkscreen-on-metal), used deliberately, not a fallback. - Body / prose:
ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif. - Uppercase labels get
letter-spacing: .18–.24em. Wordmark is heavier with wider tracking. Do not pull a webfont from a CDN; if a custom face is wanted later, inline it as a@font-facedata URI.
Layout
A rack-unit faceplate: a bordered panel with corner screws and groove dividers. Top is a "1U" header (etched wordmark + sub-line, master LED, UTC clock, theme switch). Below it the two throughput meters, then a responsive module grid (3 cols → 2 → 1), then a streaming query-log, then a footer plate with serial + primary actions. Content max-width ~1080px, centered.
Components (build these once, reuse everywhere)
<Faceplate>— the panel shell (screws, grooves, brushed texture, header slot).<Module>— an engraved-label card: name + optional toggle/LED, a big mono value with a small unit, and arowslist of key/value lines.<Toggle>— physical sliding switch (aria-pressed); green when on.<Led>— status dot with glow; variantson / amber / crit / off, optionalpulse.<SegMeter>— segmented VU meter; last ~3 segments turn crit at peak; animates toward a target value with easing.<QueryLog>— streaming list, newest on top, tagsproxy / block / pass.- Buttons: mono, uppercase,
.btn(ghost) and.btn.primary(solid orange).
Non-negotiable quality floor
Responsive to mobile; visible :focus-visible (2px orange outline); respect
prefers-reduced-motion (kill animations/transitions); keep contrast legible in
both themes. Motion is subtle and purposeful (live meters, pulsing LEDs, log
slide-in) — never decorative churn.
Copy voice
Name things by what the operator controls (a person manages devices and blocklists, not nftsets). Active voice on controls ("Apply config" → toast "Applied"). Errors say what broke and how to fix it — no apologies, no vagueness. Sentence case in prose; uppercase only for silkscreen labels.