Orkhan Mammadov

Nous Portal & Hermes Agent

Designing a developer console from an existing visual language

Client
Nous Research
Role
Senior Product Designer
Product UI, end to end
Design system owner
Year
2025 – 2026
Discipline
Product Design
AI / ML Interfaces
Design Systems
Web
Nous Portal — usage console with ASCII-rendered token chart
[ THE PROBLEM ]

Nous had a strong visual language and a growing number of places it needed to live. A language proves itself on the screens it was never drawn for — a billing table, a terminal with no colour guarantee, an empty state at 2am. My job was to extend it into those places without diluting it, and to make it reproducible by people who were not in the original conversations.

Concepts in, product out

Leigh Taylor set the visual language and the initial concept for the Portal itself. I designed the product from there — every screen, state and flow in the console. A concept tells you what something should feel like; it does not tell you what happens when a run fails at step thirty, or how a billing table behaves at 2am with three months of data in it. That gap is the work.

Hermes Agent — terminal, cloud and desktop surfaces
Hermes Agent — terminal, cloud and desktop surfaces

Research where the concepts ran out

I synthesised the 2025–2026 literature on agentic developer interfaces into a prioritised list — the W3C APG combobox pattern for the command palette, agent activity ledgers from the visibility-into-AI-agents work (arXiv 2401.13138), cost-transparency primitives, human-in-the-loop approval for spend-affecting actions — tiered by leverage and ticked off as each shipped.

Research synthesis tiered by leverage, each pattern ticked off as it shipped
Research synthesis tiered by leverage, each pattern ticked off as it shipped

The console

Token usage renders as ASCII glyph art with LINE / AREA / ASCII as a first-class toggle. A developer console can borrow an idiom its audience already reads fluently, and a terminal-native chart says more about what this product is than any amount of brand language.

Glyph art means nothing to a screen reader, so the chart is aria-hidden inside a container with role="img" and a text summary. A crosshair HUD prints values as a status line rather than a tooltip that covers the data it describes.

Nous Portal — ASCII chart with LINE / AREA / ASCII render toggle
Nous Portal — ASCII chart with LINE / AREA / ASCII render toggle

Running agents, and stopping them

An agent card carries two independent signals: whether it is online, and whether it is healthy. Collapsing those into one status light is the obvious simplification and it fails exactly when it matters — an agent can be stopped and fine, or running and broken, and those need different responses from the person looking at it.

The available actions change with state rather than greying out. A running agent offers recovery, access control, channel configuration and stop; a stopped one offers start and delete. Nothing is shown that cannot be done.

Colour carries meaning consistently: amber for warnings that need attention, red only for actions that are irreversible or states that need it — stop, delete, offline. Reserving red rather than spending it on every alert is what keeps it legible when an agent is about to be destroyed.

Nous Portal — cost breakdown per model and per tool call
Nous Portal — cost breakdown per model and per tool call

What it costs, and why

Usage runs across the top as one row of tiles — spend, requests, input and output tokens, cache reads — and breaks down per model and per tool call below, so an unexpected bill has a traceable cause. The sidebar carries the number that actually matters day to day: balance, burn rate, and how long the money lasts. "$10 · run out in 30 days · $0.3/day" is a more useful sentence than any chart.

Billing was the hardest information design in the product. Subscription credits expire and roll over by plan rules; top-up credits never expire; usage draws down subscription credit first. That is three rules a user has to hold at once before they can predict their own bill, and getting it wrong means either a surprise charge or an agent that stops mid-run.

The page states the precedence in one sentence and then shows the two balances separately rather than collapsing them into a single misleading total. Auto-refill exists but carries its own guardrail — a trigger threshold, a refill amount, and a monthly ceiling — because an automated action that spends money without a stated limit is not a convenience.

The low-balance warning is amber. Red is the obvious choice and the wrong one here: saturated red adjacent to this blue produces a chromostereopsis shimmer, which the contrast audit had already flagged. The tier CTAs escalate rather than repeat — Try, Unlock, Unleash, Liberate — so the pricing table reads as a ladder instead of four identical buttons at different prices.

Nous Portal — numbered keyboard navigation rail
Nous Portal — numbered keyboard navigation rail

Keyboard first, because the audience is

The navigation rail is numbered 1–6 and those keys jump straight to a section, with a ⌘K palette over the top. Single-key shortcuts are suppressed inside inputs and contenteditable regions per WCAG success criterion 2.1.4 — the detail that separates a keyboard interface from a keyboard trap.

Nous UI kit — the type scale extracted into a documented system
Nous UI kit — the type scale extracted into a documented system

Consent in plain language

For an AI product the prompt is the sensitive thing, so the data-use choice cannot hide behind a policy link. Privacy Mode states its consequence directly: inference payloads are not stored, not used for training, product improvement or support, and inputs remain volatile. The alternative is written just as plainly rather than being framed as the generous default.

Email preferences say what they do not cover, too — transactional mail about account activity, billing and security still sends regardless of any toggle. A preference screen that only advertises what it switches off is quietly dishonest, and users find out at the worst moment. Only critical announcements are on by default.

Auditing an inherited palette — every pairing computed, failures recorded alongside passes
Auditing an inherited palette — every pairing computed, failures recorded alongside passes

The system

I extracted the language into tokens named for the role they play rather than the value they hold — BG/Primary-Background/Main, Text/White-Background/Secondary — which is what let it survive a terminal, where a background colour cannot be guaranteed. Sigurd Variable for display, DM Sans for body, DM Mono for captions and buttons. It ships as a real codebase rather than a Figma file with a handoff ritual attached.

Auditing the palette

I computed the contrast matrix and wrote down the failures as carefully as the passes. #0000f2 on #f5f5f5 is 8.4:1 and clears AAA. Dark text on that blue is 2.1:1 and is never allowed. The blue on near-black is 2.2:1, so a dark theme needs a lighter blue entirely. Saturated red beside it shimmers, and a blue focus ring on a blue active pill is invisible until you swap it for currentColor.

[ OUTCOME ]
4
surfaces held by one system: terminal, cloud, desktop, mobile
1M+
users on the product
WCAG 2.2 AA
inherited palette audited, keyboard model verified