Back to writing
E-029 / Essay

Muhit: How does a design decision work on screen?

How decisions about drafts, focus, errors, cancellation and themes take shape in Muhit’s working examples.

Preserving a filter, explaining a failed operation and letting someone return to the work they started. Muhit’s design approach becomes clearer as these small decisions take shape in practice.

In the first essay, I approached Muhit as a shared language of behaviour. An interface’s consistency depended on how someone’s work continued across screens, as much as on colours and typefaces.

To see what this means in practice, we can follow a small sequence: find a record, open it, write a note and return to the list.

One of Muhit’s current development examples is built around this sequence. It contains a few records, such as a research framework, shared resources and decision notes. The user narrows the list with a search, opens a record and writes a note. When they return to the list and reopen that record, both the search condition and the note remain.

It looks like an ordinary interaction. Yet making it work requires decisions about what the interface remembers, when it forgets and what it tells the user.

Decisions around a record

In the example, each record’s draft is kept under its own identifier. A note written for one record therefore does not appear in another record’s field. Returning to the list does not clear the draft, and the search field retains the user’s condition.

This prevents someone from having to reconstruct their work when they return to the screen. They do not have to type the search again, find the right record or try to remember the sentence they just wrote.

Retention time is also part of the design. The example keeps drafts only in the open page’s memory. Reloading the page or closing the tab loses them. This limit is stated explicitly beside the editing area.

The principle of preserving effort becomes a concrete question: What information do we preserve, within what scope, and for how long?

Another decision concerns focus between views. Opening a record moves keyboard focus to the detail heading. Returning to the list moves it back to that record’s button.

This gives the visual transition a counterpart for someone using a keyboard. The beginning of the new view, and the point to which they return, become clear.

A search with no matches also has its own state. The user is told that no record matches the query and can clear the search. This is not presented as a failure to load data. The next step differs: changing search results requires changing the query, whereas retrying may make sense after a failed request.

Error and cancellation within the flow

The same example includes an option to make the operation fail deliberately. The aim is to examine recovery behaviour alongside the screen’s smooth path.

When the user writes a note and starts the operation, the interface enters a waiting state. Duplicate submission is prevented, the note cannot be edited while the operation is pending, and a cancellation control becomes visible.

If the sample operation fails, the note remains. The message explains what happened and how to try again. The button’s label also adapts to the new state.

An error therefore does not force the user to repeat the entire sequence. There is still a place to continue around the failed operation.

Cancellation receives the same attention. If the user changes their mind while waiting, the sample operation stops; the draft remains and the interface says that no confirmation was given. A delayed result from the previous operation cannot later turn the screen into a success state.

This distinction needs greater care in an application connected to a real server. Cancelling a request on the client does not, by itself, prove that an operation already started on the server has been undone. The application must assess the actual outcome separately.

This boundary is also visible in Muhit’s React and Vue reference integrations. Rebuilding the form produces a cancellation signal for the pending operation. The application is expected to pass that signal to its network request and avoid updating its own state with a cancelled response.

The library’s and application’s responsibilities meet here. The component manages the interaction’s lifecycle; the application knows whether the record was actually saved.

That is why the button in the small working example is labelled “Confirm locally”. Success means confirmation in that tab’s memory only. It does not suggest that anything has been saved to a server or persistent storage.

The scope of the feedback should match the scope of the operation that actually took place.

Carrying the approach to other screens

Implementing these decisions again in every project becomes difficult over time. Components may need to be rebuilt, particularly when the language, theme or view changes.

In Muhit’s React and Vue references, rebuilding a table first captures a snapshot of the current view. In supported flows, filters, selection and column layout are carried to the new component. If the application explicitly supplies a new value, that value takes precedence.

This detail makes ownership of state clearer. Information that the application needs to control continuously should be reflected in its own state through the corresponding change events. It should be clear where behaviour expected to survive each redraw is managed.

The same distinction applies to Muhit’s JSON interface adapter. An invalid update preserves the current view; a successful update rebuilds it. The old table’s filters and selection do not automatically carry over through this path. If the interaction needs greater continuity, the application must establish it through the relevant component API.

Theme decisions also follow defined roles. Surface backgrounds, readable text, action emphasis and keyboard focus have separate variables. For example, --mh-surface is used with --mh-text, while text on an accented button uses --mh-on-accent.

This makes it easier to track a component’s meaning while changing the palette. The actual screen still needs inspection: Is the selected item clear? Is focus visible? Are controls comfortable to use in a denser layout?

When applying Muhit to a project, I therefore find it useful to begin with a small task that can be followed from start to finish rather than the most impressive screen. Finding and editing a record can be enough.

The same task then needs to be followed under different conditions: no matches, a failed operation, a user changing their mind, a language change and keyboard navigation.

These examples demonstrate working behaviours. Real-device and manual screen-reader acceptance remain among the evaluations still to be completed.

This is the practical expression I look for in Muhit: a design decision becomes visible when someone can continue the work they started. When their note is still there, the error is understandable and the confirmation on screen describes what actually happened.


This essay draws on the design principles, working record flow and integration contracts in Muhit’s local 0.16.0 development source. These examples do not claim production use or completed manual accessibility acceptance.

Resources: Muhit source code · JSON interface contract

Previous essay: Muhit: What makes an interface consistent?

Atlas concepts: Design · Software · Context · Systems

Continue reading

Publications that share subjects with this article.

This connects to