Case study · Cloud infrastructure

OpenNebula

Turning 21 inconsistent resource views into one console pattern — audited against OpenNebula's own docs, iterated through three panel versions before anything shipped.

RoleProduct Designer
Year2026
PlatformWeb
ScopeNavigation + 21 resource views
OpenNebula Sunstone in a browser window on a pastel gradient — the Images list beside an open virtual machine detail drawer showing details, permissions and ownership
12Usability sessions and stakeholder interviews
−34%Usability-related tickets after release
6Functional prototypes built in HTML/CSS/JS
21Resource types, one shared pattern
01 — Overview

An open-source console, redesigned resource by resource.

OpenNebula is open-source software for building and managing private, public and edge clouds — data centers, virtual machines, storage and networking, all from one console called Sunstone. It's dense, powerful, and shows its age in the UI.

The redesign covers Sunstone 7.0's navigation and resource views: 21 resource types, from Virtual Machines and Templates down to Marketplaces and ACLs, each rebuilt with a consistent card/table/detail pattern instead of the inconsistent, resource-by-resource layouts in the current release.

Sunstone VM list, card view, dark theme
Fig. 01 — Card view: the default for 17 of 21 resources; three (Images, Files, Marketplace Apps) default to table instead.
02 — Problem

Twenty-one resources, no shared pattern.

Every resource type in Sunstone had grown its own list layout, its own detail-panel behaviour, and its own reading of what the product's own documentation actually recommends.

Auditing the shipped UI against OpenNebula's own 7.0 docs surfaced real mismatches: VM Groups lived under Templates when the docs treat them as an operational concept under Instances; Marketplace Apps were buried in Storage when user intent points to their own section; VNet Templates sat in Networks instead of Templates. The detail panel was worse — card view opened it as a right-side panel, table view opened it at the bottom of the screen, and switching view modes mid-task meant relearning where information lived.

03 — Process

Audit the docs, prototype the panel, ask the room.

Every resource got mapped against the official OpenNebula 7.0 documentation to settle what a card should show, what belongs in metric tiles, and which tabs a detail view needs — before touching a single screen. The open question that took the most iteration: where does the detail panel live?

V1 kept the old split (right panel for cards, bottom sheet for tables) and a stakeholder review flagged the inconsistency immediately. V2 tested "always right panel" against real data — it turned out right-side panels read better for tables too, since they steal columns instead of rows, and tables are scanned vertically anyway. V3, the current build, drops the panel in as an overlay from the right in both view modes, with the underlying list dimming slightly so users never lose their place.

Resource visualisation grid — mapping all 21 resource types to card fields, metric tiles and tabs against OpenNebula 7.0 documentation
Every resource mapped against the OpenNebula 7.0 documentation before any screen was drawn: what the card shows, which metric tiles it needs, which tabs the detail view gets.
Three iterations of detail-panel placement — V1 split by view mode, V2 always a right panel, V3 slide-in overlay over a dimmed list
Three answers to one question. V1 kept the old split and a stakeholder review rejected it; V2 unified on a docked right panel; V3 slides the panel in over a dimmed list, which is what shipped.
04 — Solution

One console, one set of patterns.

VM detail drawer, Info tab — details, permissions and capacity panels
VM detail drawer, Logs tab — scheduler log stream with search
Create-user wizard, step 1 of 3 — general credentials form
Multi-select summary — five VMs selected with aggregate stats and per-row actions
VM DETAIL

One drawer, every resource

The same right-side overlay pattern now covers all 21 resource types — the same muscle memory whether you're looking at a VM or an ACL rule.

MONITORING

Logs without losing context

Monitoring and log tabs sit inside the same drawer, so checking a VM's history never means leaving the list behind.

ONBOARDING

Multi-step wizards, broken down

Admin-heavy flows like user creation are split into clear steps instead of one long form — general info, permissions and groups handled in sequence.

BULK ACTIONS

Act on many at once

Selecting multiple resources surfaces a summary bar with the actions that make sense for the whole set — no more repeating the same action row by row.

05 — Design system

Tokens that hold up in both themes.

Every surface, border and status colour is a token mapped from Figma variables, verified in both dark and light mode side by side — not just a dark theme with light values guessed afterward. Typography holds to a small scale (12–24px, weights 400–600) so nav items, table cells and page titles stay visually consistent across all 21 resources.

Status is always colour + label + icon together, never colour alone — the same rule that makes the Labels and Tags work applies here: at-a-glance state should survive a screenshot, a colourblind user, or a low-quality projector in a conference room.

The Sunstone Overview dashboard in dark mode — VM, host, network and image counters, CPU and memory area charts, and host allocation meters.
The same Sunstone Overview dashboard in light mode, token for token.
One screen, one build, one set of tokens — drag to cross the theme boundary. Surfaces, borders, the chart fills and the status colours all resolve per theme; nothing is a dark screen with light values guessed afterward.
THE SYSTEM UNDERNEATH

One name, two values.

The tokens aren't transcribed from Figma by hand — a script generates them out of the Sunstone source, walking the same three-layer chain the product walks: primitives → aliases → per-scheme roles. 173 names, 98 of them colour roles, each resolving once for light and once for dark. Names map onto the palette, so --surface-action greps straight back to schemes/light/surface.js and a developer can find where any value came from.

Token Light Dark
--surface-page #FFFFFFneutral.white #222431neutral.950
--surface-primary #FFFFFFneutral.white #2a2d3dneutral.925
--text-headings #40435cneutral.900 #f5f7f9neutral.100
--text-body #637381neutral.default #c4cdd5neutral.300
--border-primary #e0e4e7neutral.200 #40435cneutral.900
--surface-action #007099primary.default #58d2ffprimary.500
--text-on-action #FFFFFFneutral.white #003447primary.900
--text-error #ff5779error.500 #ff5779error.500 — unchanged

#40435c is text/headings in light and border/primary in dark. The ramp is shared; the roles are not — which is the part a hex value on its own can never tell you, and the reason these are named for their job rather than their colour.

WHAT THE SIDE-BY-SIDE AUDIT FOUND

Three pairs that don't pass — left in on purpose.

Reading both schemes against each other turned up contrast failures a single-theme review would never surface: each of these passes comfortably in one scheme and fails in the other. I measured them, wrote them up, and raised them with the design-system team instead of quietly swapping in a nicer colour. A prototype that silently repairs the system stops being evidence about the system.

Selected item
1.03:1
icon/selected on surface/primary, dark

The icon on a selected sidebar row. At 1.03:1 it is not low-contrast, it is invisible — #003447 sitting on #2a2d3d. Passes at 5.56:1 in light.

Failed Deploy error
2.65:1
text/error on surface/error, light

Every error tag in the console. text/error is the one colour role in the table above that does not resolve twice — the same #ff5779 both schemes, which is fine on the dark #290008 (6.28:1) and fails on the light wash.

Virtual Machines
3.26:1
text/focus on surface/focus2, light

The selected sidebar item, the selected table row, the current page. Large text only — and this pair is unavoidable on every screen in the product. 6.22:1 in dark.

Ratios computed from the generated token values (WCAG 2.1). Four more accent pairs measured between 2.5 and 3.6:1; these three are the ones no screen can avoid.
06 — Retrospective

Make twenty-one resource types behave like one product.

What I took from it

01

Documentation is a research artefact

The product's own docs settled what each resource actually means to admins — a fixed reference the shipped interface could be audited against, resource by resource.

02

Test the boring decision twice

The right-panel-vs-bottom-sheet question felt small until it touched all 21 resources — worth validating with real data before committing.

03

Consistency is the actual feature

No single screen needed to be clever. The win was making all 21 feel like the same product.

04

Open questions stay open

Virtual Routers and VDCs still need a placement decision — logged, not quietly resolved by guessing.

06 — Public debut

Presented live in the official OpenNebula 7.4 webinar

Ahead of the 7.4 release, OpenNebula previewed the new Sunstone in a public webinar — and I walked the community through the design process behind it: the audit across all 21 resource views, the navigation decisions, and the design system that holds it together.

A First Look at the New Sunstone GUI in OpenNebula 7.4
OpenNebula — official channel
starts 18:07 / 1:02:01
Live walkthrough of the design decisions behind the new Sunstone, presented alongside the OpenNebula engineering team. Playback starts at the Process chapter (18:07).