Design language
The components are the vocabulary; these rules are the grammar. Each one is a decision that survived the reference apps, and together they decide where a new piece of UI goes and how it behaves before a line of it is written.
Principles
How the apps behave in the hand. Every other section serves these.
Tabs are the way through content
Related surfaces sit side by side under Metro-style pivot tabs, so a lazy thumb swipe moves you through an app. Any tab bar is always swipeable: the titles are labels, the gesture is the navigation.
Important actions live in the bottom half of the screen
Whatever matters – navigation, the primary action, a form's Save – stays where a thumb naturally rests. The frosted bottom pill is the canonical case, and the rule holds for any new surface. On desktop the same items morph into the header.
Drawers modify the page
The bottom drawer exists to change what's on the page – add, edit, confirm. Content you might want to look at – stats, charts, detail views – belongs in the main chrome as a page, a tab, or an inline expand.
Edits are deferred, dismissal is free
Nothing in a drawer applies until Save, so swiping it away, tapping the backdrop, pressing Escape, or hitting the Back button is always a safe cancel – no "discard changes?" interrogation on the way out.
Tap again instead of "Are you sure?"
Destructive actions arm on the first tap and commit on the second, right where your thumb already is. No dialog to travel to – and the armed state is announced to assistive tech.
Content first, chrome translucent
Headers, tab bars, and nav pills are frosted surfaces the content scrolls behind – the app is the content. Separation comes from the content itself rather than boxed panes and hard dividers.
Layout and navigation
One shell, shaped the same way in every app.
The header floats over the content
A frosted header sits above a single scrolling region, and the content passes behind it. The native scrollbar is hidden in favor of a slim indicator that starts below the header and fades when scrolling stops.
Navigation moves with the screen
On a phone, navigation and the primary action sit in a frosted pill at the bottom. From tablet width up, the same items move into the header, in the same order.
Three gaps carry the structure
24px between sections, 20px between cards in a stack, 12 to 16px inside a card. Cards in a stack sit closer to each other than to the next section, so the grouping reads without a rule drawn anywhere.
Panes share the page
Side-by-side panes inherit the page background and are separated by what they hold. At most one pane is elevated: the controls panel, frosted like the bottom pill.
A page arrives complete
A page renders its real content on the first frame, from the last value it read, so navigation never flashes a placeholder or shifts a column into place.
Surfaces
How things sit on the page and on each other.
Edges are lit
A card or filled control carries a half-pixel highlight along its inner edge in place of a border. It separates the surface from what it sits on without outlining it.
One edge treatment per surface
A surface takes a border or a bevel. Both at once read as a doubled outline, and a border pushes the bevel inside the shape.
Fields recess, buttons rise
Text fields and selects carry a soft inset shadow, so they read as cut into the surface. Buttons carry the bevel, so they read as sitting on top of it.
Subtle planes use the muted surface
A slightly raised area inside a card uses the muted surface token, which sits on the far side of the surface in each theme and so stays visible in both.
A drawer’s actions live in its footer
Actions sit in a frosted bar at the foot of the drawer, ordered from most destructive on the left to the primary action on the right. Content scrolls behind both the header and the footer.
Controls
Sizes, weights and labels shared by everything you can press.
One height scale
Controls are 36, 42 or 52px tall. 42 is the default for everything a finger lands on, so a button, a field and a select line up side by side. 52 is for landing-screen calls to action, 36 for dense chrome such as a sidebar rail.
Touch targets reach 44px
A control that must meet the 44px target size adds the touch-target utility on top of its height, so the visual scale and the hit area stay separate decisions.
Weight marks hierarchy
Control labels are 500 and headings 600, in every state. Selection shows through fill and color. The tab bar is the one exception, where the active tab goes semibold because it has no fill to carry the state.
Labels wrap
Heights are minimums. A long translated label wraps to a second line and the control grows taller. Button pairs go in a ButtonRow, which stacks them before they would wrap.
Phosphor icons, 16px in buttons
Every icon comes from Phosphor. Inside a button it is 16px, bold, beside the label.
Color and theme
Color comes from tokens, compiled from one source to CSS, JS, Swift and Kotlin.
Tokens only
Components and apps read color, radius, shadow and height from design-token variables. A hand-picked hex goes stale the next time the token moves.
One accent per app
Each app sets a single accent color. Its full scale and a contrast-checked foreground are derived from that one value, and desktop builds can follow the OS accent instead.
Status has its own scales
Success, warning, error and info have scales of their own, separate from the accent, so a status reads the same in every app whatever its accent.
Light, dark and system
Every app follows the system theme and offers an override, with a pure-black dark theme where OLED screens benefit. The browser and status-bar color follow the background token.
Motion
Movement explains a change, then gets out of the way.
Motion shows where things went
Slides follow the swipe that caused them, indicators glide to the tab you chose, and a drawer rises from the edge it belongs to. Nothing animates for decoration.
Reduced motion is respected everywhere
When the system asks for less motion, slides, springs and smooth scrolling are removed, in CSS and in the JavaScript-driven gestures alike.
Switched content starts fresh
Content swapped by a tab is keyed by what it shows, so a transition never plays the previous tab’s values into the new one.
Accessibility
WCAG 2.1 AA, built into the components so every app inherits it.
Keyboard reaches everything
Every control is reachable and operable by keyboard, overlays close on Escape and return focus to their trigger, and composite controls take the arrow keys.
A neutral focus ring
Focus shows as a high-contrast neutral ring with at least 3:1 contrast against its background. Accent colors fail that bar in light themes.
Dialogs hold focus
A drawer traps focus while open and restores it on close. A form drawer with several fields focuses the drawer itself, so opening it on a phone keeps the keyboard down and the form visible.
Every control has a name
Icon-only buttons carry a label and a matching tooltip, custom controls expose their role and state, and every field has a real label.
Color always has a partner
Meaning carried by color is carried a second way too, by text, an icon or a shape.
Changes are announced
Form errors, sync results and other status updates reach screen readers through a live region.
Writing
Words are part of the interface.
Say what a thing is
Copy states what something does in plain terms. It avoids defining a thing by what it is not.
En dashes
Sentence breaks use an en dash, in the interface and in the code alike.
Every string is translatable
All visible text, labels and tooltips included, comes from a translation key, and every locale an app ships gets every key.
Layouts mirror for right-to-left
Components use logical properties (start and end) so Arabic and Urdu layouts mirror without extra work, and swipe direction flips with them.
Building on it
How the system stays one system as it grows.
The system comes first
An app reaches for a design-system component before writing its own, and a fix to shared behavior lands in the system so every app gets it.
Components compose
Every component forwards its ref to its root and merges a caller’s className and style there, so it can be positioned, measured and restyled from outside.
State belongs to the caller
Interactive components are controlled: the caller holds the value and the component reports changes.
Two apps make a pattern
When the same pattern appears in two apps, it becomes a candidate for the system. Components are extracted only after they have proved themselves in shipping apps.
