20 KiB
OpenWork Design Language
This is the definitive visual system for OpenWork product and landing work.
OpenWork should feel like a premium work tool: calm, useful, technical, and trustworthy. The design should read as software first, not a flashy marketing site. The goal is clarity with taste, not visual noise.
1. Core Design Position
OpenWork design is:
- quiet
- premium
- operational
- flat-first
- structured by typography, spacing, and borders
- atmospheric only in controlled places
OpenWork design is not:
- glossy
- glassy
- beige
- aggressively gradient-heavy
- border-heavy
- shadow-led
- decorative for its own sake
The basic rule:
Use structure before effects.
If something needs emphasis, prefer this order:
- layout
- spacing
- typography
- opacity
- background tint
- border
- shadow
Shadow should almost never be the first tool.
2. The OpenWork Mood
The product should feel like:
- a serious desktop tool
- a clean command center
- a modern open-source alternative to Claude Cowork
- something you would trust with real workflows, team sharing, and remote workers
Tone:
- polished, but restrained
- modern, but not trendy
- friendly, but not cute
- futuristic through discipline, not chrome
3. Color + Surface Rules
Base page color
- Default page/background base: very light cool neutral (
#f6f9fcor equivalent) - Prefer white and near-white surfaces over tinted beige panels
- Avoid warm paper/beige backgrounds unless there is a very strong reason
Surface hierarchy
Use only a few layers:
- Page background
- Primary white surface
- Soft secondary surface
- Interactive selected state
Do not create lots of micro-layers.
Preferred surface treatments
Flat app surface
For most application UI:
- white or near-white background
- 1px subtle border
- no visible shadow or only the smallest shadow possible
Soft shell
Use for landing sections that need grouping but should still feel calm.
landing-shell-softstyle direction- near-white background
- subtle edge definition
- no box shadow by default
This is no longer landing-only in spirit. For app surfaces like modals, package builders, and share flows, the same shell language is often the right starting point when the surface represents a workflow object instead of generic settings chrome.
Elevated showcase shell
Use only when a hero/demo needs one extra level of emphasis.
- may use
landing-shell - still soft
- never dark or “floating card everywhere”
- should be rare, not the default wrapper for all sections
Background imagery
Allowed only when all of the following are true:
- it sits behind content, not under core text blocks directly
- it is subtle
- it fades away or is spatially constrained
- it does not compete with reading
Pattern/background image rules:
- top-of-page background patterns should be low-opacity and fade out down the page
- section-specific image backgrounds are allowed for showcase frames
- content cards that sit on top of image backgrounds should still be white and legible
- use images as atmosphere, not content
4. Borders
Borders are one of the main structure tools in OpenWork.
Border philosophy
- prefer soft gray borders
- prefer low contrast
- prefer consistency over emphasis
What not to do
- do not use harsh black borders for selection
- do not outline selected cards with strong dark strokes
- do not stack border + heavy shadow + tint all at once
Good border usage
border-gray-200border-gray-300for stronger but still soft selection- low-alpha white borders for translucent landing shells
- soft shell borders like
#eceef1for app sidebars and large rounded utility panels
Do not use a dark or high-contrast outline as the main styling for a small icon tile, badge shell, or compact decorative container. If the element is just carrying an icon, prefer a soft filled tile over an outlined chip.
Selection should usually feel like:
- soft neutral fill
- darker text
- optional tiny border or tiny shadow only when needed
not:
- dark outline
- glow
- hard stroke
5. Shadows
Shadows must be restrained.
General rule
- App UI: almost flat
- Landing UI: soft and selective
- Selection states: tiny shadow only
Approved shadow levels
None
Default for most grouped surfaces.
Tiny control shadow
Use for active pills and secondary buttons:
0 0 0 1px rgba(0,0,0,0.06),
0 1px 2px 0 rgba(0,0,0,0.04)
Light card shadow
Use sparingly for a main demo shell or one hero card.
Strong CTA shadow
Reserved for the primary CTA only.
Never do
- large ambient shadows across many cards on one page
- floaty SaaS-marketing shadows everywhere
- using shadow as the main selected-state signal
- glassmorphism blur shadows in the app
6. Geometry + Radius
OpenWork should have a small set of radii and use them consistently.
Radius system
- Pills / buttons / chips:
rounded-full - Small controls / rows / compact cards:
rounded-xl - Medium panels / embedded demos:
rounded-2xl - Large showcase wrappers:
rounded-3xlorrounded-[2.5rem] - Sidebar/app shell wrappers:
rounded-[2rem]torounded-[2.5rem]
Rules
- Don’t mix too many different radii in one section
- If the outer shell is very rounded, inner panels should step down cleanly
- Pills should look intentional, not bubbly
7. Typography
Typography does most of the hierarchy work.
General tone
- clean sans-serif
- medium weight for important labels
- gray text for explanatory copy
- no overly stylized headings
Hierarchy
Eyebrows
- uppercase
- tracked
- small (
text-[11px]) - muted gray
Headlines
- medium weight
- tight tracking
- dark ink (
#011627or equivalent) - large enough to lead, not shout
Body
text-smortext-base- relaxed line height
text-gray-500ortext-gray-600
Active explanatory text
If paired with an active state (like a selected workflow descriptor), the copy may move from muted gray to dark ink.
Avoid
- giant type jumps
- ultra-light weights
- loud uppercase body copy
- dense paragraphs without breathing room
7.5 Copy Direction
OpenWork copy should feel as disciplined as the UI.
General tone
- concise
- product-led
- operational
- calm
- confident without overselling
Good copy behavior
- lead with the main user value, not the implementation detail
- prefer one clear idea per sentence
- keep interface copy shorter than marketing copy
- make support text explain utility, not restate the headline in different words
Avoid
- repetitive copy that says the same thing three ways
- enterprise filler words like "provisioned setups" when a simpler phrase exists
- admin-heavy or billing-heavy framing when the main value is team workflow
- overdescribing secondary features
Preferred OpenWork Cloud framing
For OpenWork Cloud, the primary story is:
- share setup across the team/org
- keep everything in sync
- background agents are secondary / alpha
- custom LLM providers are tertiary / coming soon
Do not make the product read like:
- a billing page first
- a hosting toggle first
- an equal split between desktop and Cloud
It should read like:
- team setup sharing first
- operational consistency second
- advanced/cloud extensions after that
Preferred terminology
Use:
- OpenWork Cloud
- Shared setups
- Shared templates
- Custom LLM providers
- Background agents
Prefer:
- "Manage your team’s setup, invite teammates, and keep everything in sync."
- "Create and update shared templates your team can use right away."
- "Standardize provider access for your team."
Avoid:
- "Den" in user-facing copy
- "Provisioned setups"
- "Configured setups"
- "Choose how to run..." when the real goal is to explain team value
Hierarchy rules for product pages
For sign-in, checkout, and dashboard copy:
- headline should state the core team value
- subcopy should explain the workflow benefit in one sentence
- supporting bullets/cards should not compete equally with the main value
- desktop should often appear as a fallback or secondary path, not a co-equal hero choice
Docs CTA language
When linking to supporting documentation, prefer short utility labels:
- Learn how
- How sharing works
- Read the guide
These should feel like helpful follow-through, not a second headline.
8. Buttons
There are only a few button families in OpenWork.
8.1 Primary button
Use for the main action only.
Characteristics:
- dark fill (
#011627) - white text
- fully rounded pill
- slightly stronger shadow than the rest of the system
- feels decisive but still clean
Canonical pattern: doc-button
Use for:
- Download
- Run task
- other main conversion/action moments
8.2 Secondary button
Use for support actions.
Characteristics:
- white fill
- no hard border
- tiny ring + small shadow
- black/dark text
- fully rounded pill
Canonical pattern: secondary-button
This is also the reference style for:
- active segmented controls
- selected pills inside a track
8.3 Tertiary / text actions
Use for less important actions.
Characteristics:
- no heavy box treatment
- rely on text color and hover only
Button rules
- Do not invent many new button styles
- Reuse the primary and secondary button logic whenever possible
- If a selector pill is active, it should usually resemble the secondary button family
9. Selectors, Tabs, and Pills
This is now one of the clearest OpenWork patterns.
Track pattern
Use a soft segmented track:
- light border
- subtle gray background
- full pill radius
- tiny inset padding
Example structure:
- track:
border border-gray-200 bg-gray-50/50 rounded-full p-1 - active item: white pill + tiny shadow
- inactive item: muted text only
Active state
Active tab/pill should look like:
- white pill
- soft ring/shadow
- dark text
Inactive state
Inactive tab/pill should look like:
- no card chrome
- muted gray text
- stronger text on hover
Do not
- use harsh dark borders for selection
- create heavy segmented controls with thick strokes
- use loud fills for tabs
Flat selected row pattern
For app navigation, especially dashboard sidebars:
- selected state should usually be a soft gray fill (
bg-gray-100/bg-slate-100family) - selected items should not default to white floating pills inside a white or near-white shell
- rely on fill + text weight before adding chrome
- hover state should usually be one step lighter than selected, not a different visual language
10. Lists and Row Systems
OpenWork has two primary list patterns.
10.1 Operational row list
Use for sessions, workspaces, activity rows, and compact app lists.
Pattern:
- flat container
- rounded-xl row
- light hover tint
- selected row uses a subtle fill and stronger text
- metadata remains quiet
Good signals:
font-medium- subtle background tint
- tiny status accent if needed
- rounded-2xl row inside a softer outer shell when the list is acting as a primary sidebar
Bad signals:
- white card floating above white page
- hard selected outline
- large shadows on list rows
10.1a Sidebar shell pattern
Use for app/dashboard sidebars when the sidebar itself should feel like a calm standalone object.
Pattern:
- outer shell uses a near-white neutral background, not pure white
- shell gets a large radius (
rounded-[2rem]range) - shell uses a faint border, often enough without any visible shadow
- internal rows stay flatter than the outer shell
- selected row uses a soft gray fill, not a stronger border treatment
- footer actions may appear as floating white pills/cards inside the shell if they need separation
This is the right pattern for:
- workspace sidebars
- Cloud dashboard sidebars
- utility navigation that should feel product-like rather than admin-like
10.2 Text-led preview list
Use when a list controls a larger preview panel to the right.
Pattern:
- no boxed cards for each item
- text blocks stacked vertically
- inactive items use lower opacity
- active item uses full opacity and darker copy
This is the right pattern for:
- feature explanation lists next to a demo panel
- “build / import / ready” style narratives
11. Cards and Section Layouts
Explanatory cards
Use only when the card itself is the unit of information.
Should be:
- simple
- lightly bordered
- white
- softly rounded
When not to use cards
If the user is just choosing between three conceptual options, don’t force every option into a boxed card. Use:
- pill selector
- text-only list
- opacity-driven stacked copy
Product object cards
Use when the UI is presenting a reusable worker, template, integration, or packaged setup.
Pattern:
- soft shell or near-white card
- generous padding
- title first
- one short supporting sentence
- compact status pill in the top-right if needed
- actions inline underneath or within the card
These should feel like curated product objects, not admin rows.
Icon tiles inside cards
When a card uses an icon block:
- use a soft filled tile (
bg-slate-50/ similar) - prefer no visible border by default
- let size, radius, and fill define the tile
- if a muted version is needed, use a quieter fill rather than an outline
Do not:
- put a dark stroke around the icon tile
- make the icon tile look like a separate outlined button unless it actually is one
- introduce standalone black/ink borders for decorative icon wrappers
Section composition
Most sections should follow one of these layouts:
- Headline + supporting copy + CTA
- Selector on left + live descriptor on right
- Text list on left + preview/demo on right
- Three-column summary cards
Do not mix too many interaction models in one section.
12. Demo and Mockup Styling
Embedded product demos should feel like software, not like illustrations.
Demo shell rules
- white inner content area
- subtle chrome
- soft border
- restrained shadow
- clear spacing
If the outer frame is atmospheric
Then the inner mockup must become simpler.
Meaning:
- image/pattern on outer background is okay
- inner card should stay clean and white
- do not combine colorful outer frame with complex inner effects
Content in demos
- use real-looking interaction states
- keep labels readable
- emphasize utility over visual flourish
Packaged workflow surfaces
When showing a workflow like share/package/export:
- prefer a soft shell over default modal chrome
- make the core object the hero (template, worker, integration, package)
- reduce the number of nested bordered panels
- use one or two strong cards, then flatter supporting sections
- present actions as intentional product actions, not generic form controls
13. Selection States
Selection should usually be shown through one or more of:
- darker text
- stronger opacity
- soft neutral fill
- soft gray border
- tiny shadow
Selection should not usually be shown through:
- black outline
- bright accent fill
- glow
- thick stroke
OpenWork selection should feel confident, not loud.
When a selected item sits inside a soft app shell, prefer:
- tinted gray fill first
- then weight and text color
- then at most a tiny white badge or tiny control shadow for supporting UI
Avoid making the selected state look like a separate floating card unless the interface is explicitly using segmented pills.
13.5 Modal Surfaces
Not every modal should look like a system dialog.
For workflow modals (share, package, connect, publish, save to team):
- use a large soft shell with a near-white background
- keep the header airy and typographic
- avoid harsh header separators unless they add real structure
- prefer one scrollable content region inside the shell
- use soft cards for major choices
- reduce mini-panels and stacked utility boxes
Good modal direction:
- feels like a product surface
- can contain object cards and actions
- uses soft hierarchy and breathing room
Bad modal direction:
- dense settings sheet
- too many small bordered sub-panels
- generic dialog chrome with no product feel
14. Motion
Motion should be tight and purposeful.
Allowed motion
- pill transitions with spring
- short opacity transitions
- tiny translateY on primary CTA hover
- soft content crossfades
Avoid
- floaty delayed animations everywhere
- scale-heavy hover effects
- decorative motion on non-interactive surfaces
Timing
- interactions should feel immediate
- most transitions should live around
150ms–300ms - spring motion should be controlled, not bouncy
15. OpenWork App vs Landing
The app and the landing share one system, but not the same degree of atmosphere.
App
- flatter
- more structural
- almost no decorative shadow
- almost no background texture
- strong emphasis on state clarity and density
Landing
- may use soft shells
- may use one atmospheric background image/pattern in a controlled region
- may use more spacing and larger radii
- still must obey the same button, border, and selection rules
Landing should feel like the same product family, not a separate visual brand.
16. Anti-Patterns
Do not introduce these:
- beige canvases as default backgrounds
- harsh black selected borders
- random glassmorphism
- multiple heavy shadow systems on one screen
- over-rounded cards everywhere
- boxed selectors when text or pills would be clearer
- giant gradients behind readable text
- decorative badges/counters with no functional meaning
- hiding anchor labels just to show hover actions
- outlined icon chips that read darker than the card they sit inside
If something looks “designed” before it looks “useful,” it is probably wrong.
17. Canonical Component Patterns
Primary CTA
- dark pill
- white text
- slight elevation
Secondary CTA / active segmented pill
- white pill
- tiny ring + tiny shadow
- dark text
Selector track
- light gray border
- soft neutral background
- internal padding
- active item is white
Text-led feature list
- no cards
- stacked copy
- inactive items at reduced opacity
- active item at full opacity
Operational list row
- rounded-xl
- subtle hover tint
- selected row uses fill/weight, not loud chrome
App sidebar shell
- large rounded outer shell
- faint neutral background
- subtle border
- flat internal rows
- selected row uses soft gray fill
- floating footer action can be white if it needs separation from the shell
Share/package modal
- soft shell modal
- object cards for reusable templates or integrations
- compact status pills
- strong dark primary CTA
- white secondary CTA with tiny ring/shadow
- avoid form-heavy utility styling unless the step is truly form-driven
Landing shell
- reserved for hero/showcase moments
- use sparingly
Landing soft shell
- flat, near-white, subtle border
- no shadow by default
18. Design Decision Tests
Before shipping a UI change, ask:
- Is this relying on layout and typography first, or on effects first?
- Is the selected state soft and obvious, rather than harsh?
- Are we reusing the existing primary/secondary button language?
- Does this section need cards, or would pills / text / opacity be cleaner?
- Is the shadow doing real work, or is it just decoration?
- Would this still feel like OpenWork if all colors were muted?
- Does this feel like one coherent product across app and landing?
If the answer to those is not clearly yes, simplify.
19. Canonical References in This Repo
Use these as implementation references:
- Landing button + shell primitives:
_repos/openwork/ee/apps/landing/app/globals.css - Landing hero and selector patterns:
_repos/openwork/ee/apps/landing/components/landing-home.tsx - Landing demo list rhythm:
_repos/openwork/ee/apps/landing/components/landing-app-demo-panel.tsx - Cloud dashboard sidebar shell + selected state:
_repos/openwork/ee/apps/den-web/app/(den)/o/[orgSlug]/dashboard/_components/org-dashboard-shell.tsx - Share/package modal direction:
_repos/openwork/apps/app/src/app/components/share-workspace-modal.tsx - App workspace/session list rhythm:
_repos/openwork/apps/app/src/app/components/session/workspace-session-list.tsx
When in doubt, prefer the calmer version.