Skip to content

Commit c06291b

Browse files
KSemenenkoclaude
andcommitted
Finish the control-room console and record the design overhaul
The landing and /admin console are rebuilt as new layouts in the shared Liquid Glass identity: editorial paper, black display type, graphite instrument panels and Managed Code's iridescent marker, with no lime. Console fixes from the RF3 review: - graphite chart panels fill their height - time labels fit the mono axis width - the bottom status bar no longer covers content on phones - phone actions become icon buttons with accessible names - RF3 labels get a halo over the dashed links ADR-053, AdminDashboard AC-AD-006/010 and BenchmarkComparisons AC-BC-029 now describe the delivered concept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 06a9b63 commit c06291b

6 files changed

Lines changed: 57 additions & 20 deletions

File tree

‎docs/ADR/ADR-053-unified-visual-identity.md‎

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,21 @@ The two surfaces shared no logo, palette, typography or components, so KeyLoad r
1919
- **One brand source.** `src/KeyLoad.Server/Features/AdminDashboard/Assets/brand.css` holds the tokens and the shared primitives (`kl-brand`, `kl-btn`, `kl-card`, `kl-glass`, `kl-badge`, `kl-chip`, reduced motion). It is mirrored byte-for-byte to `site/Features/BenchmarkComparisons/brand.css`, and `logo.svg` to `site/favicon.svg`. The SiteTests drift test `AC_VI_001` fails on any difference.
2020
- **Style direction (owner, 2026-10-02).** Earlier candidates were rejected: a light-blue look, pastel/rainbow glass and a plain grey version. The adopted style is serious Apple-style Liquid Glass in the sibling brands' colours:
2121
- Managed Code: warm off-white, black ink and system typography.
22-
- Prostir: graphite, with lime `#c6f24e` as the only brand accent.
22+
- Prostir: graphite instrument panels (`.kl-graphite`).
23+
- Accent: Managed Code's pastel iridescence (peach `#ffb08a` → lilac `#e3a6ff` → periwinkle `#9fb4ff`), used as a marker stroke, a selection edge, a status dot or the KeyLoad bar, never as a background wash. Green and lime are not brand colours (owner direction 2026-10-02; this supersedes the earlier lime accent).
2324
- Glass: translucent surfaces with specular top edges and large blur, capsule controls and large radii.
2425
- No Material Design and no decorative colour blobs.
25-
- The logo is a graphite squircle with white replica blocks and chevron, plus one lime replica.
26-
- Data colours come from the dataviz-validated categorical order (lime-ink, lilac, peach, sky, pink, amber, teal, red). Status colours are reserved.
26+
- The logo is a graphite squircle with white replica blocks and chevron, plus one iridescent replica.
27+
- Data colours: violet, peach-ink, periwinkle, orchid, graphite, amber, grey, red (`--kl-c1..c8`). There is no green data colour; the deep green `--kl-good` is reserved for semantic success status.
2728
- **Surfaces.**
28-
- The console is a light glass shell: transparent navigation with a lime selection indicator, an opaque glass top bar and a glass content layer.
29-
- The site has a dark graphite hero with a full-width Three.js scene, followed by light glass sections.
29+
- Design overhaul (owner direction 2026-10-02/03: a complete re-layout, not a restyle). Both surfaces share editorial paper, oversized black display type, mono uppercase eyebrows, graphite instrument panels and the iridescent marker.
30+
- The console is a "control room":
31+
- a floating Liquid Glass command bar (the `<aside>`) with three segmented navigation clusters; at ≤1320 px it collapses to icons, with a label on the active view only;
32+
- an editorial masthead with the view title and live controls;
33+
- a pulse strip of four KPI numerals with sparklines;
34+
- graphite instrument panels for request activity, throughput, console events and RF3 voters;
35+
- a persistent bottom status bar, a split connect screen and a right-hand inspector sheet for JSON details.
36+
- The site reads like a spec sheet. See the Site bullet below.
3037
- **CSP and fonts.** System fonts only, no external fonts or CDNs. The console CSP is unchanged. Dynamic geometry uses CSSOM only.
3138
- **Console information architecture.**
3239
- **Monitoring:**
@@ -38,13 +45,17 @@ The two surfaces shared no logo, palette, typography or components, so KeyLoad r
3845
- Every original `data-view` and pinned browser hook is preserved.
3946
- **Real data only.** Charts plot at most 120 comparable session samples and reset on process change, failure or reconnect. The error log is a new bounded server observation: `AdminHttpSnapshot.RecentFailures`, at most 50 newest-first entries holding the route template, normalised method, status, aborted flag and duration. It never holds a raw path, query, payload or credential.
4047
- The voter figure uses configured membership (`AdminNodeSnapshot.LocalVoter`, `Voters`) and the reported leader. Peers are labelled as not observed from the executing node.
41-
- **Site.** The landing is a new product page, not a restyle:
48+
- **Site.** The landing is a new product page, not a restyle. Its numbered chapters (`01 — …`) run in this order:
4249
- a floating glass capsule navigation;
43-
- a graphite hero with a lime headline accent and the Three.js RF3 scene (lime logical-partition gem, replication beams to three graphite hosts with lime/lilac partition tiles; about 22 draw calls and 290 triangles, no idle loop);
44-
- an architecture-facts strip;
45-
- a capability grid;
46-
- glass benchmark and methodology sections;
47-
- a graphite reproduce panel.
50+
- an editorial hero with an oversized black headline and an iridescent marker under "AI agents";
51+
- a glass stage holding the live Three.js scene: a carousel of eight data-shape cards around the KeyLoad core, a transparent canvas over the stage gradient, 19 draw calls and 37 triangles. It moves as soon as it is ready, except under reduced motion, and settles when paused;
52+
- a four-fact strip;
53+
- the anatomy of one agent call: a numbered timeline beside a graphite MCP/SDK terminal;
54+
- a data-shape bento of eight models with line art;
55+
- a graphite engine cross-section (callers → request grain → partition grains → three PartitionHosts);
56+
- the evidence instrument: a toolbar, segmented scenarios, the chart and table, and a perforated evidence receipt for provenance;
57+
- a ledger of "open by default" items and items "not claimed yet";
58+
- a method rail, a graphite reproduce terminal and an editorial wordmark footer with "Developed by Managed Code".
4859

4960
Every tested hook, budget and lifecycle contract is unchanged.
5061

‎docs/Features/AdminDashboard.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Actors: an operator with a current persisted administrator principal, an unautho
6161
- **AC-AD-003 / REQ-AD-003**: process-local HTTP counters capture completed public API requests, failed requests and elapsed duration without high-cardinality labels/payloads; dashboard polling, admission/status observations, static, health and internal routes are excluded. UI computes HTTP requests/s and average response duration only from two samples of the same node/process and monotonic counters, retaining at most 120 samples. New process, failed observation and reconnect reset/mark history unavailable. Admission occupancy is not throughput; cluster throughput is not inferred from one node.
6262
- **AC-AD-004 / REQ-AD-004**: catalog uses explicit tenant/database and exclusive resource-name continuation, 1..100 limit (default 50), gated read plus bounded byte/cancellation budget. It returns metadata only (name/kind/domain/schema/index count/paused), no keys or policies. Collection rows use existing authorized query AST/cursor, 25-row pages; blob pages use existing authorized metadata listing and expose actual logical published length. Empty/missing/unsupported kinds and invalid scope/limits produce clear states. Text renders via safe DOM APIs; stored HTML is text, not executable markup.
6363
- **AC-AD-005 / REQ-AD-005**: queue page reads persisted counters and at most 100 metadata records (default 50), with exclusive message-ID continuation; messages expose lifecycle, attempts, versions and times without payload/header/lease-owner tokens. Inspection never receives, sweeps, claims, ACKs or changes ready sequence/counters/commit position. Due scheduled and expired leases remain their persisted states until ordinary queue work transitions them. Stored and in-flight counts are exact persisted counters; page state counts are not presented as total Ready/DLQ counts.
64-
- **AC-AD-006 / REQ-AD-006**: console provides coherent sidebar navigation (overview, collections, queues, files, cluster), readable metric cards and measured throughput plot, scope controls, manual refresh and bounded automatic refresh, paginated tables, document JSON details, empty/loading/unauthorized/disconnected/error states. Desktop and 390 px mobile layouts fit without page overflow; keyboard navigation, visible focus, labels, status announcements and reduced-motion behavior work. Disconnect clears credential and all sensitive DOM/history; one in-flight refresh per session and abort/epoch handling prevent stale post-disconnect renders. Background tabs suspend polling; overlapping polls cannot accumulate.
64+
- **AC-AD-006 / REQ-AD-006**: console provides coherent grouped navigation in a floating command bar (overview, collections, queues, files, cluster and the ADR-053 additions), readable metric cards and measured throughput plot, scope controls, manual refresh and bounded automatic refresh, paginated tables, document JSON details, empty/loading/unauthorized/disconnected/error states. Desktop and 390 px mobile layouts fit without page overflow; keyboard navigation, visible focus, labels, status announcements and reduced-motion behavior work. Disconnect clears credential and all sensitive DOM/history; one in-flight refresh per session and abort/epoch handling prevent stale post-disconnect renders. Background tabs suspend polling; overlapping polls cannot accumulate.
6565
- **AC-AD-007 / REQ-AD-007**: all three new reads are available through typed .NET SDK and explicit official MCP catalog/agent gateway with read-only/nondestructive hints and unchanged prior operation semantics. TUnit/Microsoft.Testing.Platform regressions use actual file-backed stores and actual Docker/Aspire RF3 + real .NET/official MCP clients; browser tests use the real server/browser, no mocked API or doubles. Exact-SHA GitHub build/format/analyzer/governance/unit/recovery/RF3/browser receipts and artifacts must exist before qualification is claimed. Required coverage thresholds stay mandatory; absent collector/result is an open gate, not success.
6666

6767
- **AC-AD-008 / REQ-AD-008**: `AdminHttpSnapshot.RecentFailures` keeps the newest 50 failed `/v1` and `/mcp` requests (status ≥ 400, aborted or faulted), newest first. Each entry holds the completion time, normalised method (unknown methods become `OTHER`), matched route template (or `unmatched`), status, aborted flag and duration.
@@ -76,6 +76,14 @@ Actors: an operator with a current persisted administrator principal, an unautho
7676
- Infrastructure: nodes, disk usage.
7777
- It also has KPI sparklines, stacked request activity with a crosshair tooltip, a storage donut, admission meters, catalog kind chips (page counts, never totals) and a disk category bar with largest files.
7878
- All AC-AD-006 hooks and behaviours stay intact. No horizontal overflow at 1440 and 390 px. A mobile menu toggle exposes `aria-expanded`.
79+
- Control-room layout (design overhaul, owner direction 2026-10-03):
80+
- the `<aside>` is a floating command bar with three segmented clusters; at ≤1320 px only icons show, plus the label of the active view; at ≤760 px `#menu-toggle` opens the clusters as a sheet;
81+
- an editorial masthead holds `#view-title`, `#refresh` and `#disconnect`;
82+
- a pulse strip shows the four KPIs;
83+
- graphite instrument panels hold activity, throughput, events and RF3 voters;
84+
- a fixed status bar holds `#connection-state`, `#session-node` and `#captured-at`;
85+
- the connect screen is split, and `#details-dialog` is a right-hand inspector sheet.
86+
- Every id, `data-view`/`data-goto` hook and pinned count is unchanged.
7987

8088
## Criterion-to-test matrix
8189

‎docs/Features/BenchmarkComparisons.md‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,15 +323,29 @@ Pages at https://www.keyload.cloud/ uses enforced HTTPS; live apex redirects301
323323

324324
## REQ-BC-029: shared KeyLoad visual identity
325325

326-
### AC-BC-029 owner revision, 2026-10-03 (KeyLoad OS)
327-
328-
- **Concept.** The landing is a Liquid Glass "desktop" in the Managed Code family: menu bar, windows with title bars, widgets, a Launchpad of capabilities, a Benchmarks app window with a sidebar, a terminal window and a bottom dock for navigation. There is no green brand accent; Managed Code's pastel iridescence is the only accent. The page presents KeyLoad as the database for AI agents on .NET 10 and Orleans and keeps the early-development wording.
329-
- **Agent session.** The illustrative "Agent session" window shows the real MCP tools `keyload_query_execute` and `keyload_documents_commit`, plus the real .NET SDK atomic command. It is labelled as an example with no live data.
326+
### AC-BC-029 owner revision, 2026-10-03 (design overhaul)
327+
328+
- **Concept.** The landing is an editorial product page that reads like a spec sheet, in the shared identity from [ADR-053](../ADR/ADR-053-unified-visual-identity.md):
329+
- paper surfaces, oversized black display type and mono chapter eyebrows (`01 — …`);
330+
- graphite instrument panels;
331+
- Managed Code's iridescent marker as the only accent. There is no green or lime.
332+
- **Order.** The page presents KeyLoad as the database for AI agents on .NET 10 and Orleans, keeps the early-development wording, and runs in this order:
333+
1. a hero with the live scene;
334+
2. a fact strip;
335+
3. the anatomy of one agent call;
336+
4. a data-shape bento;
337+
5. an engine cross-section;
338+
6. the evidence instrument, with a perforated provenance receipt;
339+
7. a ledger of claims that are not made yet;
340+
8. the method;
341+
9. reproduce;
342+
10. the footer.
343+
- **Agent call anatomy.** A numbered timeline beside a graphite terminal shows the real MCP tool `keyload_query_execute` and the real .NET SDK atomic command. It describes the path, not live data.
330344
- **3D scene motion contract (changed by owner direction).**
331345
- The carousel of data-shape cards around the KeyLoad mark starts moving as soon as it is ready. It spins while visible and follows a fine pointer.
332346
- It pauses offscreen, on hidden pages and when the visitor pauses it. It never moves under `prefers-reduced-motion`.
333347
- `AssertMotionPlaysThenSettles` proves that render calls advance while playing and are identical after pause. Budgets are unchanged: 19 draw calls and 37 triangles.
334-
- The poster is a pre-rendered frame of the same scene.
348+
- The poster is a pre-rendered frame of the same scene on the stage gradient. The canvas is transparent, so the scene sits on the glass stage.
335349
- **Comparable engines only.** The chart and table omit engines that do not implement the selected workload, and KeyLoad is highlighted. Their DOM rows, downloads and the engine count stay intact.
336350
- **Attribution.** The footer reads "Developed by Managed Code" and links to https://www.managed-code.com/ with a normal followed link (no `nofollow`).
337351

‎src/KeyLoad.Server/Features/AdminDashboard/Assets/constants.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const Config = Object.freeze({
3131
epsilon: 1e-9,
3232
longId: 12,
3333
xTicks: 4,
34-
xLabelWidth: 96,
34+
xLabelWidth: 124,
3535
padTop: 14,
3636
padRight: 12,
3737
padBottom: 28,

‎src/KeyLoad.Server/Features/AdminDashboard/Assets/layout.css‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,12 @@ body.connected .live-dot { background: var(--kl-accent); box-shadow: 0 0 0 3px v
245245
.masthead p { font-size: 14px; }
246246
.topbar-actions { width: 100%; flex-wrap: wrap; }
247247
.live-pill { margin-right: auto; }
248+
.topbar-actions .kl-btn { width: 38px; min-height: 38px; padding: 0; }
249+
.topbar-actions .kl-btn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
248250
.content { padding: 0 16px 24px; }
249251
.connect-card { padding: 24px 20px; }
250252
.connect-row { flex-direction: column; }
251253
.statusbar { flex-wrap: wrap; gap: 4px 12px; padding: 6px 16px; }
254+
.shell { padding-bottom: 92px; }
252255
.topology-note { display: none; }
253256
}

‎src/KeyLoad.Server/Features/AdminDashboard/Assets/views.css‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
.panel-head h2 { font: 700 16px/1.25 var(--kl-font-display); letter-spacing: -.02em; }
2828
.panel-head p { margin-top: 4px; color: var(--kl-muted); font-size: 12.5px; }
2929

30-
.panel--instrument { overflow: hidden; }
30+
.panel--instrument { display: flex; flex-direction: column; overflow: hidden; }
31+
.panel--instrument > .chart { flex: 1 0 auto; }
3132
.panel--instrument .panel-head p, .panel--instrument .legend { color: var(--kl-on-graphite-muted); }
3233
.panel--instrument .panel-head h2 { color: #fff; }
3334
.panel--instrument .accent { color: #c9b4ff; }
@@ -176,7 +177,7 @@ td button:hover { border-color: var(--kl-graphite); background: var(--kl-graphit
176177
.panel--instrument .topology line { stroke: rgba(255, 255, 255, .22); }
177178
.panel--instrument .topology .node circle { fill: var(--kl-graphite-3); stroke: rgba(255, 255, 255, .25); }
178179
.panel--instrument .topology .node.self circle { fill: #2f2a45; stroke: #c9b4ff; }
179-
.panel--instrument .topology text { fill: #fff; }
180+
.panel--instrument .topology text { fill: #fff; paint-order: stroke; stroke: #16171a; stroke-width: 6px; stroke-linejoin: round; }
180181
.panel--instrument .topology text.sub { fill: var(--kl-on-graphite-muted); }
181182
.panel--instrument .topology .node.self .glyph { color: #c9b4ff; }
182183
.panel--instrument .topology .node.leader circle.crown { stroke: var(--kl-graphite); }

0 commit comments

Comments
 (0)