Overview
Monad’s web UI uses a layered surface system: dark-first, dense, quiet, and operational. The primary app canvas isrgb(32 33 36) in dark mode, with panels layered using semi-transparent surface containers instead of heavy shadows or decorative gradients. Light mode exists as the same token system inverted to a pale canvas, not as a separate visual language.
The core rule is token parity. Components should use the raw RGB token names when matching the base primitives (--backgroundColor-primary, --backgroundColor-surface-container, --textColor-primary, --borderColor-secondary) and semantic aliases (--background, --card, --foreground, --border) when building ordinary app UI. Do not hard-code one-off oklch or hex values for app chrome.
Colors
Raw base tokens
These tokens are stored as RGB channel triplets so they can be composed with alpha:Light
Dark
Semantic Aliases
packages/ui/src/styles.css maps the raw tokens into shadcn/Tailwind-compatible aliases:
--chart-1 … --chart-5 and the --sidebar-* family follow the same pattern; read
packages/ui/src/styles.css for the complete list.
The sidebar uses an app-chrome palette independent of content surfaces: foreground is
rgb(26 28 31) in light mode and white in dark mode; secondary text is 70% foreground,
selected rows are 5%, and hover states and borders are 8%. Keep brand purple for focus,
links, and semantic status instead of persistent navigation chrome.
Surfaces
App panels compose the surface-container token over the canvas, with alpha chosen per surface rather than baked into a single utility class:rgba(22, 23, 24, 0.5) over the
rgb(32, 33, 36) canvas; in light mode to rgba(255, 255, 255, 0.5) over
rgb(250, 250, 250). The --card, --popover, and --sidebar aliases resolve the same
token at full opacity — reach for those first and only drop to a raw alpha composite when
a surface genuinely needs to read through.
Use this layer for cards, sidebars, composer shells, settings panels, and compact dashboard
modules. Use --backgroundColor-secondary without alpha for menus and surfaces that must be
fully opaque.
Typography
Use the existing app font stack:--font-ui: the platform system stack (-apple-system,BlinkMacSystemFont,Segoe UI, …) for all interface text.--font-code: the system mono stack (ui-monospace,SF Mono,Menlo,Consolas, …) reserved for source code, terminals, commands, diffs, raw logs, and structured data editors.
App Density Reference
Use these values as the density target for Monad’s app chrome and operational screens.Font Families
Type Scale
The product UI scale is denser than Tailwind defaults:
Practical Monad mapping:
- Sidebar row text:
13px / 18px,font-weight: 400. - Active/sidebar emphasis: at most
500; avoid600except brand/title. - Toolbar/header title:
14px / 18px,font-weight: 500. - Button/control text:
12px / 18pxfor small controls,14px / 18pxfor toolbar/composer controls. - Settings labels/descriptions:
12-14px, mostly400; use500only for group titles. - Do not use
text-xl+inside app chrome except rare empty states or page headings.
Font Weight
Row And Toolbar Density
Reference row/toolbar tokens:
Use these as upper bounds for ordinary chrome. If a sidebar item needs two lines, keep the row at
px-2/py-1.5 or px-3/py-2; do not turn sidebar navigation into card-like rows.
Adjacent sidebar rows use a 1px gap, producing a 29px center-to-center rhythm.
Buttons And Controls
Reference button variants:
Composer button tokens:
28-32px high. Composer send/stop may be larger, but should remain visually subordinate to the input surface; avoid 56px controls unless the whole composer is intentionally oversized.
Lists, Sidebar, Settings
Extracted recurring component patterns:Composer And Thread Layout
Shapes, Borders, Shadow
Radii are tight. The1.25 corner-radius scale is already baked into the token values —
do not re-apply it:
Default app chrome favors hairline borders over elevation:
--shadow-2xs through --shadow-2xl; each step is a hairline plus a
soft ambient layer, never a hard drop shadow.
Use shadow-sm/md only for floating or elevated surfaces. Sidebars, route shells, settings groups, and composer surfaces should primarily use background contrast plus 0.5px-1px borders.
Motion
There are no motion custom properties — durations and easings are written as Tailwind utilities on the component. The budget:- Routine controls:
duration-150 ease-outon color, border, opacity, and shadow only (Button.tsxis the reference). - Larger panel/composer state changes:
300ms cubic-bezier(0.4, 0, 0.2, 1). - Never animate layout properties, and honor
prefers-reduced-motionfor anything beyond a state fade.
Shapes
Functional controls use tight radii:
Avoid pill-heavy app chrome unless the control is a segmented chip or mode selector.
Components
Buttons
Primary buttons use inverse surface fill:- Background:
--primary - Text:
--primary-foreground - Hover: slightly reduced opacity or state layer, not a new hue
- Radius:
--radius-md
--secondary, --background, --accent, and --border. Avoid shadows and translate-on-hover motion for routine app controls.
Cards And Panels
Default panels:- Background:
--card - Border:
1px solid var(--border) - Radius:
--radius-lg - Shadow: none by default
Composer
The composer should feel like a command surface:- Surface:
rgb(var(--backgroundColor-surface-container) / 0.5) - Idle border:
rgb(var(--borderColor-secondary) / 0.15) - Focus border: same as idle; focus is shown by the animated aurora ring, not a static accent border
- Focus ring: none on the shell; the aurora layer is the focus treatment
- Focus surface: same tokenized surface, with only the internal aurora glow layer fading in below content
- Placeholder:
--muted-foreground - Radius:
--radius-3xl - Transition:
300ms cubic-bezier(0.4, 0, 0.2, 1)for border, background, and ring state
duration: 3.4s, borderThickness: 1, borderOpacity: 1, gradientCoverage: 25, tailSoftness: 10, innerGlowBlur: 45, glowMode: inside, and the color set #9154E7, #6056F0, #40D9C6, #4285F4. On Monad’s darker app canvas, the internal glow should be tuned below innerGlowOpacity: 0.25 / innerGlowInset: 53 so it reads as a soft edge shimmer rather than a foreground sweep. It should remain a focused composer treatment, honor prefers-reduced-motion, and never become a decorative glow around ordinary panels.
Composer nesting must keep animation and content separated:
chat-input-frame only owns relative positioning. chat-input-aurora is the absolute pointer-events-none overlay sibling above the real surface (relative w-full containing an absolute z-[50] aurora layer plus a role="presentation" surface). The overlay must be internally constrained: inner glow uses four edge masks (top, bottom, left, right) and the border ring uses a content-box mask with padding: 1px. The rotating conic-gradient child is 150vmax, centered at top: 50% / left: 50%, and animated with translate(-50%, -50%) rotate(...); do not rotate the overlay box itself. Do not add a static focus border-color or shell box-shadow that competes with the animated ring.
Layout
The homepage is a workspace overview and must not show the session sidebar on first entry. App views after selecting a session or channel may use the sidebar. Dense operational panels are preferred over marketing layout patterns. Use full-width app bands and constrained inner content rather than card-in-card compositions. Cards are for individual repeated items, modals, settings groups, and framed tools.Motion
Motion should clarify state changes only:- Use 150-200ms transitions for color, border, opacity, and box-shadow.
- Avoid translate-on-hover for routine controls.
- Honor
prefers-reduced-motion. - Do not animate layout properties.
Do
- Use
--backgroundColor-primaryand related raw RGB tokens when implementing base primitive controls. - Keep dark mode anchored to
rgb(32 33 36). - Build surface hierarchy with
rgb(var(--backgroundColor-surface-container) / 0.5). - Keep borders low-alpha and crisp.
- Use accent purple only for links, focus, and small state cues.
Don’t
- Do not reintroduce a near-white marketing palette as the primary app system.
- Do not hard-code new hex/oklch app chrome colors when a token exists.
- Do not put sidebars on the root workspace homepage.
- Do not use heavy shadows, glow effects, or decorative gradient backgrounds for ordinary app panels.