Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building or expanding a colour system.
The English summary is being prepared. Showing the original description.
Top bar, sidebar rail, app launcher, tenant and environment cue, status bar. Use when designing the persistent shell, a collapsible sidebar, or navigation between apps behind one login.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
The shell is the part of the screen that does not change when the user navigates: the bar across the top, whatever sits in it, and in heavy tools a strip along the bottom. Everything between them belongs to the application. The shell is small, and it carries more weight than its size suggests — it is the only thing a user sees on every screen of every tool.
One company rarely has one application. It has a public site, a shop, a customer portal, an internal admin tool, and something older that nobody wants to touch but that people depend on. The user crosses between them during a working day, and each crossing is where the sense of one company either holds or breaks.
The rule: the top bar is estate-level furniture. The app owns everything below it. An app that restyles the shared bar to fit its own look has taken something that was not its to change — the bar's job is to be the one fixed point.
But fixed is not the same as full. What the shell contains may shrink to whatever of its jobs are still unanswered here; what remains is identical — same position, same behaviour, same wording. Quantity flexes, treatment does not.
This also settles a hierarchy question that otherwise gets argued per team. Anything above the application in scope lives in the shell; anything within the application lives in the app's own navigation.
| Lives in the shell (above the app) | Lives in the app's own nav (within it) |
|---|---|
| Tenant / customer / organisation | Sections, modules, pages |
| Region or market | Filters and views |
| Language and locale | Entity-level actions |
| Identity, role, sign-out | Feature settings |
| App launcher | Search within this tool |
If a control changes what the whole estate shows you, it is a shell control. If it changes what this tool shows you, it is not.
A sub-application entered only from its parent has one estate-level job left — the way back — so the shell may collapse to a single line: one label, one icon, on the same background as the content, no bar and no chrome. Everything else the shell would carry was already answered upstream, and repeating it is noise.
The condition is the entry path, and it is the whole rule:
Name it by destination, not by action. ← Dashboard stays true when history and hierarchy disagree; ← Back does not. Back is a history concept, up is a hierarchy concept, and a shell that conflates them lies exactly when the user is most lost.
When a user has access to more than three tools, the shell needs a launcher: one icon in the top bar that opens the full set. It is what replaces the bookmark folder and the link someone pasted in chat two years ago.
In a multi-tenant or multi-customer tool, the user must always know whose data is on screen. Two related controls, one important difference.
Environment is worth a colour. Production, staging, and a local build should be impossible to confuse, because the cost of the confusion is a real change to real data. A coloured strip or a tinted bar is the right tool, and this is one of the few places where deliberately breaking the calm of the shell is correct.
Tenant is not. Tinting the whole UI per customer is a tempting idea that makes every customer a different-looking product, breaks the brand, and quietly wrecks contrast the moment a customer's colour is not one you chose. Show the tenant as a label in the shell — name, and an avatar or initials if you have one — not as a theme. If a tenant genuinely needs its own visual identity, that is a white-label decision made once at the product level, not a per-session tint ([[brand-visual-language]]).
Whoever is selected, the shell states it plainly and permanently, and destructive actions repeat it in the confirmation ([[ui-context-and-scope]]).
Heavy tools — dispatch boards, data managers, editors people sit in for six hours ([[operational-expert-tool-ui]]) — benefit from a strip along the bottom that carries ambient state. It answers questions the user would otherwise have to go looking for:
connection and sync state · environment · active filters and how many records they match · selection count · last saved · the one keyboard hint that matters here
It is ambient, so it stays quiet: the same small, muted type as the rest of the shell, no animation, no colour except when something is genuinely wrong. A status bar that flashes is a notification in the wrong place ([[notifications-and-recovery]]).
Consumer products almost never need one. If the user is not in the tool long enough to build a habit of glancing down, the strip is just a stolen row of screen.
A single application often has no top bar at all: a sidebar down the left edge is the whole shell. Then the sidebar carries both jobs — the estate-level controls from the table above, and the app's own sections — and it must keep them visibly apart. Sections go in the middle and scroll if they must. Estate-level controls go in a footer that is pinned to the bottom, so the user always finds them in the same place regardless of how many sections the app grows. The whole sidebar is sticky to the viewport: a long page scrolls under it and the nav never leaves.
Order the footer by what it does. Scope first (tenant, location, customer — the control that decides what the app shows), then preferences (language, theme — how it shows it), then identity and sign-out, separated by a rule. Scope and preferences are different decisions and read wrong when mixed in one row; preferences can share a row, since they are small and cost no height.
Logo at the top, inside the sidebar. Lockup when expanded, mark alone when collapsed, with the clear space the brand asks for. Padding is what shrinks the logo, so solve the padding from the exclusion zone rather than picking a round number.
The logo links home. In a sidebar app the logo is the one way back to the front door, so it is a link, not a picture. Swap the asset with the theme rather than filtering it; a logo built for a dark rail rarely survives inversion.
Identity lives in one place. Either the sidebar footer or the page header, never both. Put it in the footer when the sidebar is the only persistent chrome; move it to the page header when every page already has one and the footer is better spent on scope.
Show what sign-in unlocks, hide what role unlocks. An item the user could reach by signing in stays visible with a quiet mark, because it is an invitation. An item gated by role is removed, because a link that returns a 403 teaches the user to distrust the whole nav.
A sidebar that collapses to an icon rail gives the content column back the expanded width minus the rail, which in a canvas or table tool is the difference between seeing the work and scrolling it. Four rules make the rail usable instead of merely narrow:
title tooltip.On a phone-width viewport (below about 768px) the sidebar is not narrowed, it is gone, and a drawer takes its place ([[modal-and-overlay-patterns]]). The drawer is the same sidebar — same logo row, same items in the same order, same footer — so the user keeps one mental model across devices ([[responsive-paradigms]]). What changes is the entry: a floating trigger in the bottom corner, inside the safe-area insets so a home indicator never covers it. The drawer scrims the page, locks body scroll, and closes itself on navigation; a drawer that stays open after a tap has made the user do the closing.
Active state is a background shift plus weight, never colour alone ([[status-colors-and-errors]]). A dark rail inside a light app is fine, and common, but it needs its own surface tokens — base, raised, sunken — rather than borrowing the content area's ([[surface-separation]]).
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building or expanding a colour system.
The English summary is being prepared. Showing the original description.
Product visuals must show the real product with real data. Use when building landing pages, hero sections, screenshots or demo panels.
The English summary is being prepared. Showing the original description.
Shape language across type, radius and icons carries brand personality. Use when starting a design system, picking icons or radius tokens, or reviewing visual consistency.
The English summary is being prepared. Showing the original description.
Rest, hover, active, focus, disabled and loading states, derived from the base colour. Use when designing buttons, links, inputs or any clickable component.
The English summary is being prepared. Showing the original description.
Rebuild a live web page 1:1 from measurement into Figma, Penpot or code, then verify it. Use when reproducing a page or checking a rebuild against the original.
The English summary is being prepared. Showing the original description.
Light, dark or both, and when a theme selector is worth it. Use when defining a base palette or deciding on dark mode support.
The English summary is being prepared. Showing the original description.