When several standalone features are merged into one interface, one of the hardest decisions is not where there is enough room for another button. It is what kind of interaction relationship each entry point represents.
A toolbar action, a top-bar action, and a selection-context action may all look like buttons, but they have very different prerequisites. Some enter a mode before the user interacts with the scene. Some execute immediately. Others only make sense after a specific object has been selected.
I ran into this while combining five separate 3D interaction demos into a single prototype. Claude Code helped turn the features into a maintainable registry structure, but the important decisions were product-level: what does the user think this control is for, and what state should exist before and after they use it?
Two classification mistakes became especially useful because they showed the same pattern: states that look similar in code can belong to completely different levels in the user's mental model.
The shell UI ended up with three main entry types:
| Area | Interaction type | Examples |
|---|---|---|
| Right toolbar | Mutually exclusive work modes. The user chooses a mode first, then interacts with the scene | Select, distance measurement, volume measurement, notes, cube tool |
| Top bar | Immediate actions. The click completes the action without changing the meaning of later scene clicks | Model alignment, rotate 15°, reset orientation, reset view, change scale |
| Selection actions | Contextual operations on the currently selected object | Duplicate measurement |
The distinction is based on interaction prerequisites rather than visual similarity:
Once those relationships are clear, placement becomes much easier.
The first mistake came from the cube-gizmo demo.
Because the original prototype presented the Gizmo prominently, it was easy to interpret it as a persistent mobile controller. Claude Code initially carried that assumption into the combined prototype.
Walking through the actual product flow made the problem clear.
The Gizmo does not control the camera or the whole scene. It controls one specific cube that has already been created and selected.
The intended sequence is:
The Cube tool and the Gizmo therefore belong to different levels.
The tool is a work mode that defines what the next scene interaction will do. The Gizmo is a contextual control that only has meaning once a particular object exists and is selected.
A persistent overlay would still function technically, but it would suggest the wrong mental model: that the Gizmo is a global scene or camera controller.
The final structure keeps the Gizmo inside the feature's selection context rather than introducing another global UI slot.
The second mistake involved the top-view mode.
At first, it was placed next to Select, Measure, Notes, and the other toolbar modes. In code, that looked reasonable: all of them are buttons that switch some state.
But top view is not another work tool. It is a way of viewing the scene.
The active tool and the active camera view are independent state dimensions:
Tool mode: Select / Distance / Volume / Notes / Cube
View mode: 3D / TopThey should be combinable.
For example, Top View + Distance Measurement is a perfectly valid state. A user may want to stay in a top-down view while drawing measurements.
If Top View is inserted into the toolbar's mutually exclusive set, choosing a measurement mode would automatically cancel the view mode. That creates a restriction with no product reason behind it.
The final structure moved camera view state out of the feature registry and into the viewer layer, with a separate 3D / Top control in the interface.
Both mistakes can be tested with the same questions.
1. Does the user need to do something in the scene after clicking this control? If yes, it is likely a work mode rather than an immediate action.
2. Does this control require a selected object to make sense? If yes, it belongs to object context rather than a persistent global area.
3. Can this state coexist with the current tool? If yes, it should not be placed inside the same mutually exclusive set.
4. Does it change what the user is doing, or how they are viewing the scene? The first is usually a tool concern. The second is more likely a viewer or scene-level state.
These questions matter earlier than deciding whether a button belongs on the left, right, top, or bottom of the screen.
Claude Code handled much of the registry design and implementation structure, but the two important corrections happened at the product-semantics level.
AI can make a technically reasonable classification from code shape: these are all buttons, these all switch state, these can all be registered in a slot. From an engineering perspective, that structure may be completely valid.
What still needs human review is the interaction meaning: what must happen before the click, what happens after it, whether the state can coexist with others, and whether the control belongs to the scene, the active tool, or the selected object.
For this kind of combined prototype, the most useful workflow was to let AI expand the technical options quickly, then validate the resulting structure by walking through the actual user flow.
Each feature exports a common registration shape and declares its UI slot.
The shell renders toolbar, topbar, and selection entries independently.
The Gizmo is not a global slot; it is rendered as selection-specific feature content, such as SelectionGizmo.
View mode stays outside the feature registry and belongs to the viewer / camera layer because it describes how the scene is observed rather than what tool is active.