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.
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.
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
- 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
Use only a few layers:
- Page background
- Primary white surface
- Soft secondary surface
- Interactive selected state
Do not create lots of micro-layers.
For most application UI:
- white or near-white background
- 1px subtle border
- no visible shadow or only the smallest shadow possible
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.
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
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
Borders are one of the main structure tools in OpenWork.
- prefer soft gray borders
- prefer low contrast
- prefer consistency over emphasis
- 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
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
Shadows must be restrained.
- App UI: almost flat
- Landing UI: soft and selective
- Selection states: tiny shadow only
Default for most grouped surfaces.
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)Use sparingly for a main demo shell or one hero card.
Reserved for the primary CTA only.
- 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
OpenWork should have a small set of radii and use them consistently.
- 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]
- 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
Typography does most of the hierarchy work.
- clean sans-serif
- medium weight for important labels
- gray text for explanatory copy
- no overly stylized headings
- uppercase
- tracked
- small (
text-[11px]) - muted gray
- medium weight
- tight tracking
- dark ink (
#011627or equivalent) - large enough to lead, not shout
text-smortext-base- relaxed line height
text-gray-500ortext-gray-600
If paired with an active state (like a selected workflow descriptor), the copy may move from muted gray to dark ink.
- giant type jumps
- ultra-light weights
- loud uppercase body copy
- dense paragraphs without breathing room
OpenWork copy should feel as disciplined as the UI.
- concise
- product-led
- operational
- calm
- confident without overselling
- 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
- 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
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
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
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
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.
There are only a few button families in OpenWork.
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
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
Use for less important actions.
Characteristics:
- no heavy box treatment
- rely on text color and hover only
- 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
This is now one of the clearest OpenWork patterns.
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 tab/pill should look like:
- white pill
- soft ring/shadow
- dark text
Inactive tab/pill should look like:
- no card chrome
- muted gray text
- stronger text on hover
- use harsh dark borders for selection
- create heavy segmented controls with thick strokes
- use loud fills for tabs
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
OpenWork has two primary list patterns.
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
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
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
Use only when the card itself is the unit of information.
Should be:
- simple
- lightly bordered
- white
- softly rounded
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
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.
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
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.
Embedded product demos should feel like software, not like illustrations.
- white inner content area
- subtle chrome
- soft border
- restrained shadow
- clear spacing
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
- use real-looking interaction states
- keep labels readable
- emphasize utility over visual flourish
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
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.
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
Motion should be tight and purposeful.
- pill transitions with spring
- short opacity transitions
- tiny translateY on primary CTA hover
- soft content crossfades
- floaty delayed animations everywhere
- scale-heavy hover effects
- decorative motion on non-interactive surfaces
- interactions should feel immediate
- most transitions should live around
150ms–300ms - spring motion should be controlled, not bouncy
The app and the landing share one system, but not the same degree of atmosphere.
- flatter
- more structural
- almost no decorative shadow
- almost no background texture
- strong emphasis on state clarity and density
- 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.
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.
- dark pill
- white text
- slight elevation
- white pill
- tiny ring + tiny shadow
- dark text
- light gray border
- soft neutral background
- internal padding
- active item is white
- no cards
- stacked copy
- inactive items at reduced opacity
- active item at full opacity
- rounded-xl
- subtle hover tint
- selected row uses fill/weight, not loud chrome
- 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
- 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
- reserved for hero/showcase moments
- use sparingly
- flat, near-white, subtle border
- no shadow by default
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.
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.