| name | Rocket.Chat Desktop | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| description | Native desktop shell around one or more Rocket.Chat server webviews. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typography |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rounded |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spacing |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| components |
|
Creative North Star: "The Workshop Wall"
The desktop shell is a tool rail: a quiet 44-pixel column of workspaces hung along the side of a screen, each one sized for instant reach. Like a workshop wall, every tool has its place, density is the point, and the rail itself is invisible during work. Users move through the rail without thinking; they only notice it when a server badge calls them back, when they drag a workspace to reorder it, or when a dialog steps forward to handle something the browser cannot.
The visual system inherits directly from Fuselage, the Rocket.Chat web design system. This is deliberate: users move between web and desktop daily, and visual continuity is part of the trust contract. Tokens trace back to @rocket.chat/fuselage-tokens: primary uses the p ramp, neutral the n ramp, danger the d ramp, badges resolve through the SCSS badge() function (level-1 for unread count, level-3 for warning, level-4 for true alert). The Electron shell does not invent colors, weights, radii, or spacing values outside that scheme.
This system explicitly rejects four neighbors. It is not Discord (no neon, no drenched purple, no playful microcopy). It is not legacy Skype or Teams (no heavy gradients, no decorative iconography in the titlebar, no busy toolbar). It is not generic SaaS marketing (no hero metric tiles, no identical card grids, no gradient accents on numbers). And it is not Linear-minimalism for its own sake (sidebar density matters; sparse-when-it-could-be-useful is a regression).
Key Characteristics:
- 44-pixel server rail as the signature surface.
- Flat by default, depth through tonal tint shifts (
neutral-100→neutral-450→white). - Inter primary, system stack fallback (
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, ...). - One accent gesture: the 4-pixel selection stripe to the left of the active server, in
neutral-450. - Color follows Fuselage CSS variables (
--rcx-color-*), themed light / dark / auto viaPaletteStyleTag(resolved againstmachineThemeanduserThemePreference). - Native per-platform: macOS vibrancy + 22-pixel drag bar, Windows Mica, Linux fallback.
A small palette of muted tints with a precise role assignment for every accent. Every color resolves to a Fuselage CSS variable; the SCSS pipeline (primary($grade), neutral($grade), danger($grade), badge($level)) is the source of truth and the React getPaletteColor helper mirrors it. The desktop shell never invents colors outside the Fuselage palette.
- Action Blue (
#156ff5, oklch(57% 0.21 257), Fuselageprimary-500): The dominant action color. Primary buttons, focus rings, inline links inside dialogs. Hover steps toprimary-600(#095ad2), press toprimary-700(#10529e). Disabled background isprimary-200(#d1ebfe).
- Mention Slate (
#9ea2a8, oklch(68% 0.012 256), Fuselagebadge-level-1resolving toneutral-600): The unread-mention count badge background. Fuselage'sBadge variant='secondary'is a muted gray, not red. Restraint is intentional; the badge is a count, not an alarm.
- Caution Orange (
#f38c39, oklch(72% 0.16 51), Fuselagebadge-level-3resolving toservice-1-500): The warning-state badge ServerButton paints over a server avatar when the user is not logged in (FuselageBadge variant='warning'). Used as a state signal, never as a button background. - Alert Crimson (
#f5455c, oklch(65% 0.22 18), Fuselagebadge-level-4resolving todanger-550): Reserved for true alerts requiring user response. If introduced into the shell, it lives only on the destructive button family andBadge variant='danger'. Not currently in the rail vocabulary.
- Workshop Slate (
#2f343d, oklch(31% 0.014 256), Fuselageneutral-800): The deep neutral behind webviews when transparent-window mode is not engaged on darwin. Also the dark text color for body copy in the dialog surface. - Ink (
#1f2329, oklch(25% 0.013 256), Fuselageneutral-900): Titles and labels on light surfaces. - Annotation (
#6c727a, oklch(52% 0.012 256), Fuselageneutral-700): Secondary info, hint text, dropdown section labels. - Wall Cream (
#f7f8fa, oklch(98% 0.004 250), Fuselageneutral-100): The light sidebar background. Quiet enough to disappear next to webview content. - Active Tone (
#d7dbe0, oklch(88% 0.006 256), Fuselageneutral-450): The 4-pixel selection stripe fill and the hover background on rail items. - Hairline (
#e4e7ea, oklch(92% 0.005 250), Fuselageneutral-400): Dividers and ghost-button borders. One pixel, never offset.
The Fuselage Truth Rule. Every color in the desktop shell resolves to a --rcx-color-* custom property emitted by PaletteStyleTag. The hardcoded fallbacks (#2f343d, #d7dbe0) inside src/ui/components/SideBar/styles.tsx and Shell/styles.tsx exist only as last-resort backstops for the moment before the palette tag hydrates. Do not reuse those literal hex codes anywhere else; reference the CSS variable.
The One Stripe Rule. The 4-pixel left stripe on the selected server button is the entire decorative vocabulary of the rail. Do not add second stripes, glows, halos, or contrast borders to indicate selection elsewhere. If a new affordance needs to signal selection, repeat the stripe.
The Quiet Mention Rule. The mention-count badge is Fuselage Badge variant='secondary': gray on the avatar, white text. Not red. The badge is a number, not an alarm. Red is reserved for variant='danger' on confirmation buttons and true alerts. Warning state (not-logged-in) uses variant='warning': orange, also not red.
The Token-First Rule. When adding a color, look up the role in fuselage-tokens/src/<role>/base.json (status, font, surface, button, stroke, background). If no role token exists, do not add one in the shell; raise it as a Fuselage proposal.
Display Font: Inter (with fallback -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif).
Body Font: Inter (same stack).
Mono Font: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace. Reserved for code surfaces.
Character: Inter is the Fuselage standard. The shell prefers Inter where available and falls back through the system stack to remove font-loading flash on cold Electron start. The current shell's system-ui-only stylesheet (Shell/styles.tsx line 37) predates the Inter migration and should be brought in line with the Fuselage scale.
Use Fuselage fontScale props on Box and components rather than raw CSS. Each scale below is the exact @rocket.chat/fuselage-tokens/typography.json entry.
- hero (800, 48 / 64): Splash screens, marketing-style hero blocks. Not used inside the shell after first paint.
- h1 (700, 32 / 40): Settings view title, About title.
- h2 (700, 24 / 32): Section headers within Settings tabs, dialog titles in About / Update.
- h3 (700, 20 / 28): Subsection titles, large dialog titles where h2 is too dominant.
- h4 (700, 16 / 24): Form group labels, dropdown section labels (uppercase via Fuselage
Option.title). - h5 (700, 14 / 20): Compact list-item titles.
- p1 (400, 16 / 24): Primary running copy in dialogs. Also
p1m(500) for medium emphasis,p1b(700) for bold inline. - p2 (400, 14 / 20): Default shell body. Sidebar tooltips, settings form rows, dropdown item text.
p2mandp2bavailable. - c1 (400, 12 / 16): Server initials, badge numbers, metadata, micro-labels.
- c2 (700, 12 / 16): Emphasized micro-labels (badge counts when emphasized).
- micro (700, 10 / 12): Extreme density labels. Not currently used in the shell.
The fontScale Rule. Use Fuselage fontScale='p2' (or other key) on Box rather than raw font-size. The scale tag is the contract; pixel literals drift.
The Inter-First Rule. Add Inter at the front of the family stack. Do not strip it back to system-ui even if local Electron versions render fine without it; cross-platform parity with the Fuselage web app depends on Inter where the font is available.
The Sentence Case Rule. All shell strings are sentence case in source. Title case appears only when the host OS demands it (macOS menu items). The single exception is Option.title in dropdowns, which Fuselage uppercases at the component level (uppercased CSS, sentence-case source).
This system is flat by default with tonal layering. Depth steps through neutrals (neutral-100 → white → neutral-450). The single sanctioned shadow vocabulary lives inside Fuselage's shadow-colors map (elevation-1, elevation-2x, elevation-2y, elevation-border, all built from neutral-800 at low alpha) and is applied by Fuselage's transient-overlay components. The desktop shell never composes shadows directly; it relies on Fuselage Dropdown, Dialog, Tile to bring their own.
- elevation-1 (
neutral-800at 10% alpha): Default lift on tiles and contextual surfaces inside Fuselage components. - elevation-2 (split x/y at 8% / 12% alpha): Modal-tier lift on dialogs and menus.
- elevation-border (
stroke(extra-light)): One-pixel hairline used as the bottom edge of elevated surfaces.
The Tonal Step Rule. Adjacent shell surfaces differ by exactly one tint step (neutral-100 rail → white dialog → neutral-450 selection accent). Skipping a step or stacking two surfaces of the same tint is a layout bug, not a depth choice.
The Shadow Tenancy Rule. Shadows belong to Fuselage's transient overlays and to the OS-native layer (window chrome, vibrancy backdrops). The shell does not author box-shadow in any CSS it owns. If a thing looks like it wants a shadow, it wants a tonal step or a hairline.
- Shape: Fuselage
IconButton small secondary(28-pixel square hit target with 4-pixel radius), wrapped in a 44-pixel-wide list item. - Default: Favicon or two-letter
Initialsonneutral-100. Initials usec1typography. - Hover: Background steps to
neutral-450. - Selected: A 4-pixel-wide, 28-pixel-tall vertical bar in
neutral-450positionedleft: -8pxoutside the button, right-edge radius0 4px 4px 0. Height transitions onvar(--transitions-duration). (src/ui/components/SideBar/styles.tsxlines 22 to 49 is the canonical implementation.) This is the entire selected-state vocabulary. - Unread count: Fuselage
Badge variant='secondary'(gray,badge-level-1=#9ea2a8) anchored top-right withtranslate(30%, -30%). - Not logged in: Fuselage
Badge variant='warning'(orange,badge-level-3=#f38c39), same anchor. - Drag: Opacity 0.5 while dragged. No border highlight on the drop target.
- Context menu: Fuselage
DropdownwithOptions: Reload, Copy URL, Open Dev Tools, Server Info, Reload Clearing Cache, divider, Remove (variant='danger').
- Width: Exactly 44 pixels. Never grows, never collapses, never shows labels inline; labels live in tooltips.
- Background:
neutral-100in opaque mode;undefinedon macOS whenisTransparentWindowEnabled(vibrancy passes through). - Padding:
paddingBlockStart={8} paddingBlockEnd={8}. - Layout: Vertical
ButtonGroup largeof server buttons at the top,MenuV2(Downloads, Settings) anchored at the bottom.
- Render:
process.platform === 'darwin'only. Hidden on Windows and Linux. - Background:
neutral-100(orundefinedfor vibrancy). - Height: 22-pixel drag bar above the rail. Carries the macOS traffic-light spacing.
Dialogs (About, Update, Clear Cache, Screen Sharing, Outlook Credentials, Server Info, Supported Version)
- Surface: Fuselage
Dialogonwhite. - Corner:
rounded.medium(4px) at the Dialog level. - Internal padding: 24px on the outer Box; tighter inside form rows.
- Title: Fuselage
fontScale='h2'(700, 24 / 32) orh3(700, 20 / 28). - Body:
p1(400, 16 / 24) for primary copy. Max 65 to 75 characters per line. - Actions: Right-aligned
ButtonGroupat the dialog bottom. Primary usesbutton-primary(Action Blue). Destructive usesbutton-danger(danger-500=#ec0d2a).
- Layout: Full-window panel layered over the webview. Fuselage
Tabsat the top (General / Certificates / optional Developer). Scrollable content insideBox m='x24'. - Title:
Box fontScale='h1' color='default' padding={24}with optional back arrow (FuselageIconButton icon='arrow-back') when sidebar is disabled. - Background:
bg='room'(resolves toneutral-800in light theme). Matches webview canvas to prevent flash on transition.
- Primary:
backgroundPrimaryDefault=primary-500(#156ff5). Hoverprimary-600, pressprimary-700, focusprimary-500. Disabled backgroundprimary-200. Fontwhite. - Secondary:
backgroundSecondaryDefault=neutral-400. Hoverneutral-500, pressneutral-600. Fontneutral-900. - Danger:
backgroundDangerDefault=danger-500(#ec0d2a). Hoverdanger-600, pressdanger-700. Fontwhite. Used for Remove Server, Clear Cache, equivalent confirmations. - Warning:
backgroundWarningDefault=warning-400. Hoverw500, pressw600. Fontneutral-900(dark text on yellow). - Success:
backgroundSuccessDefault=success-500. Fontneutral-900. - Icon buttons: Fuselage
IconButton small secondaryis the rail and chrome default. No labels alongside icons in chrome; tooltips carry meaning.
- Surface:
whitewith Fuselage'selevation-2shadow (the only allowed shadow in the shell). - Items:
OptionIcon+OptionContent, single line,p2body typography. - Section labels:
rcx-option__titleuppercased by Fuselage; source is sentence case ("Workspace"). - Dangerous items:
variant='danger'(Fuselage colorsfont-dangertext on hover backgrounddanger-100). - Dividers:
OptionDividerpaintsneutral-400hairline.
level-0/ variant unset:neutral-400background (disabled state).level-1/variant='secondary':neutral-600(#9ea2a8) background, white text. Unread count.level-2/variant='primary':primary-550(#1d74f5) background. Not used in the rail.level-3/variant='warning':service-1-500(#f38c39) orange background. Not-logged-in state.level-4/variant='danger':danger-550(#f5455c) background. Reserved.
All badges use rounded.full and white text.
- Do import primitives from
@rocket.chat/fuselagefirst. ComposeBox,Button,IconButton,Badge,Dialog,Tabs,Dropdown,Option,MenuV2,Scrollablebefore reaching forstyledor@emotion/css. Acceptable web-only divergences: server rail, native dialogs, platform-specific affordances. - Do reference colors via
--rcx-color-*CSS custom properties (emitted byPaletteStyleTag). The hardcoded#2f343d/#d7dbe0fallbacks inSideBar/styles.tsxandShell/styles.tsxexist for hydration races, not for reuse. - Do use Fuselage
fontScale='h1'/'p2'/'c1'etc. onBoxand components rather than rawfont-sizeliterals. - Do keep the 44-pixel rail width sacred. Tooltips carry labels; the rail does not widen.
- Do use the 4-pixel left selection stripe as the only selected-state decoration. Repeat it if a new affordance needs the gesture.
- Do respect
prefers-reduced-motionon every shell transition (sidebar selection slide, dialog enter, badge appearance). - Do keep
Badge variant='secondary'(gray) for unread counts andvariant='warning'(orange) for not-logged-in. Never recolor a Badge by overriding its CSS. - Do keep mention-count and warning badges in their existing positions: top-right of the avatar at
translate(30%, -30%). - Do verify both light and dark themes (
PaletteStyleTagresolves againstmachineTheme+userThemePreference) hit WCAG 2.2 AA contrast before merging a color change. - Do use sentence case in source strings; Fuselage applies title or uppercase at the component layer when needed.
- Don't use Discord/gamer aesthetics: no neon accents, no drenched dark purple, no playful microcopy, no animated reactions in chrome.
- Don't revive old Skype or legacy Teams chrome: no heavy gradients, no layered drop shadows, no decorative iconography in titlebars, no busy multi-row toolbars.
- Don't use generic SaaS marketing patterns inside the app: no hero metric tiles, no identical icon-and-title card grids, no gradient accents on numbers.
- Don't pursue pure brand minimalism (Linear-empty) at the cost of sidebar density. The shell's value is showing many servers at once.
- Don't use
border-leftorborder-rightgreater than 1px as a colored stripe anywhere other than the canonical 4-pixel server selection stripe. That stripe is the entire vocabulary. - Don't use
background-clip: textgradient text. Solid Fuselage tokens only. - Don't introduce glassmorphism as a stylistic choice. macOS vibrancy is OS-provided and acceptable; CSS
backdrop-filteron rendered surfaces is forbidden. - Don't author
box-shadowin shell-owned CSS. Depth through tonal stepping; rely on Fuselage's overlay shadow onDropdownandDialog. - Don't strip Inter out of the font stack. Inter first, system fallback behind it. The current
Shell/styles.tsxfont-family: system-uiline predates the Fuselage Inter migration and should be aligned. - Don't wrap shell content in card grids. The shell is a rail, a webview canvas, and dialogs.
- Don't use modals as the first thought for new flows. The sidebar context menu (
Dropdown) and inline settings tabs are better placements; reach forDialogonly when interruption is genuinely required. - Don't rename, recolor, or re-style Fuselage
Badge,Option,Tabs,Dropdown,IconButtonprimitives. Override only via accepted Fuselage props. - Don't confuse the Badge variants: unread count is
secondary(gray), not-logged-in iswarning(orange), anddanger(red) is reserved for true alerts. Red mention badges are not part of this design system. - Don't invent a
border-radiusvalue outside2 / 4 / 8 / 9999pixels. Spacing literals outside Fuselage's 4-multiple scale (plus 1 and 2) are also disallowed. - Don't add a settings divergence between light and dark themes. Both themes must offer the same affordances; only the palette resolves differently.
- Don't use em dashes anywhere in shell copy. Commas, colons, semicolons, periods, parentheses only.