* feat(web): introduce a brand new web ui * refactor(ui): align chat sidebar and UI components with Figma design - Restyle chat page sidebar: header with icon/title, search input, section labels, and "new session" footer button - Simplify bot-sidebar and session-sidebar to card-based layout matching Figma session card design (58px height, 26px avatar, status dots) - Update master-detail-sidebar-layout with bg-sidebar and 53px header - Unify border-radius across UI components to rounded-lg (8px): Card, Toggle, Alert, Popover, Item; Dialog uses rounded-xl (12px) * refactor(ui): move shared theme and design tokens from web to ui package CSS variables, @theme inline mappings, @custom-variant, and base layer styles now live in @memohai/ui/style.css. The web app imports them via @import "@memohai/ui/style.css", keeping only the Tailwind entry point and web-specific imports (markstream-vue, @source). * refactor(ui): apply flat design system from Figma spec Overhaul @memohai/ui component styles to match the new "high-contrast, flat" design language defined in the Figma design spec (DESIGN.md). Theme: - --primary-foreground: pure white -> #fafafa - --ring: purple -> foreground color (focus rings no longer use brand purple) Atoms (zero shadow, monochrome): - Button: default bg-primary -> bg-foreground; add explicit "primary" variant for Send CTA - Badge: rounded-full -> rounded-sm; default bg-primary -> bg-foreground; add warning/outline/size variants - Alert: rounded-lg -> rounded-[10px]; remove shadow-sm; destructive drops bg-red-50 - Card: add shadow-lg, rounded-lg -> rounded-xl, py-6 -> p-6 - Input/Textarea: remove shadow, text-sm -> text-[16px], focus ring non-purple - Checkbox: checked bg-primary -> bg-foreground - Switch: checked bg-primary -> bg-foreground - RadioGroup: indicator fill-primary -> fill-foreground - Slider: range/thumb border-primary -> border-foreground Floating panels (shadow-md): - DropdownMenu/Combobox/Select/ContextMenu Content: shadow-lg -> shadow-md - Sheet: shadow-2xl -> shadow-lg - MenuItem destructive focus: bg-red-50 -> bg-accent Other: - Pagination active: bg-foreground text-background (black, not purple) - Item variants: bg-transparent -> bg-background/bg-accent - Tabs active: shadow-sm -> border-border - Toggle: remove shadow-xs, unify hover to accent - SelectTrigger/NativeSelect: remove shadow, unify focus ring Docs: - Add packages/ui/DESIGN.md with full design system spec - Simplify apps/web/AGENTS.md, remove duplicated design info, reference DESIGN.md * refactor(chat-ui): restructure chat page components and styles (#288) * refactor(chat-ui): restructure chat page components and styles * feat(chat): add collapsible sidebar for both sides * feat(ui): add PinInput and BadgeCount components, align styles with Figma spec New components: - PinInput (OTP input): PinInput, PinInputGroup, PinInputSlot, PinInputSeparator based on reka-ui PinInput primitives with flat border-stitching design - BadgeCount: circular numeric counter with default/destructive/secondary variants Style updates to match Figma design: - Sonner: border-radius from 1rem to var(--radius-lg) (10px) - Table: add border border-border rounded-sm to container - TagsInput: remove shadow-xs, rounded-md -> rounded-lg, ring-[3px] -> ring-2 Updated DESIGN.md with all new component specifications. * chore: move up css to ui package * refactor: change npm package from @memoh to @memohai * Feat/chat layout (#295) * refactor(chat-ui): restructure chat page components and styles * feat(chat): add collapsible sidebar for both sides * fix: update chat page icon * style: refine UI components appearance * style: refine UI components appearance * chore(ci): update lock file * refactor: new layout * chore: adjust style * fix: tauri ui size * chore: remove bot session metadata * refactor: text size and muted color * fix: indirect height of bot-details pages * feat: add 5 icons * refactor: polish chat flow and settings navigation labels Persist chat selection across pages, simplify provider/settings sidebars, and refine chat/session UX so navigation and composer behavior feel consistent without extra session/provider jumps. * docs(web): refresh AGENTS frontend architecture guide Expand and align the web AGENTS documentation with the current route structure, component inventory, chat transport flow, and store responsibilities so implementation guidance matches the codebase. --------- Co-authored-by: Quincy <69751197+dqygit@users.noreply.github.com>
10 KiB
Design System
Overview
A modern, clean, and highly functional interface designed for the Memoh AI Agent platform. The design emphasizes a "high-contrast, flat" aesthetic. It moves away from mushy, ubiquitous soft shadows (shadow-sm) and brand-colored primary buttons, favoring a starker monochrome foundation with pure whites, light greys, and pure blacks. Brand colors are used extremely sparingly for distinct active states and primary conversion actions (like the chat "Send" button).
Colors
- Primary (
#8b56e3): Brand purple. Its usage is heavily restricted to specific active indicators (sidebar selection, "Send" action, status dots). It is not used for generic primary buttons. - Primary Foreground (
#fafafa): Used heavily as the background for sidebars (Navigation, Session List, Metadata) to separate them from the main content area. - Background (
#ffffff): Pure white, used for the central chat area, cards, alerts, and major input fields. - Foreground (
#171717or#0a0a0a): Near black. Now acts as the default visual weight for Primary Buttons and Default Badges. - Muted Foreground (
#737373): Mid-grey, extensively used for timestamps, secondary labels, placeholders, and inactive icons. - Accent (
#f5f5f5): Light grey, used for hover states, secondary buttons, code/badge backgrounds, and model selectors. - Border (
#e5e5e5): Very light grey, used uniformly for all structural dividers and component borders. - Destructive (
#dc2626): Pure red. Used exclusively for text or icons in critical actions (e.g., delete). It does not use colored backgrounds (e.g., nobg-red-50).
Typography
- Headline Font: Inter / Noto Sans SC / Noto Sans JP
- Body Font: Inter / Noto Sans SC / Noto Sans JP
- Mono Font: Geist Mono / Menlo (used for code blocks, component names in collapsibles, and tags like
thinking,tool_call)
Headlines and key labels use medium/semibold weights. Body text uses regular weight at 14px. Inputs use 16px to prevent iOS zoom. Secondary information uses 11px or 12px.
Elevation
The system employs a bimodal elevation strategy:
- Absolutely Flat (Zero Elevation): Interactive and atomic elements like Buttons, Inputs, Alerts, Badges, and Collapsibles have zero shadows. The default
shadow-smfrom Shadcn must be stripped out. Hierarchy is defined purely by 1px borders and background contrast. - High Floating (Shadow-lg/md):
- Large layout containers that sit above the main canvas (like a central Login
Card) use a pronouncedshadow-lgto starkly differentiate themselves from the flat UI underneath. - Popovers, Dropdowns, and Combobox menus use a tightly controlled
shadow-mdwithout thick borders.
- Large layout containers that sit above the main canvas (like a central Login
Components
Base Atoms
- Avatars: 26px rounded full. Default fallback uses
accent. Status badges require a 2px knockout border matching the background. - Badges: 4px radius (
rounded-sm). Default is pure black (bg-foreground text-background). Secondary isbg-accent text-foreground. Destructive is pure red background. Warning isbg-amber-500 text-white. Outline isbg-background border-border text-foreground. Supportssize="sm"(text-[11px] px-2) alongside default. - BadgeCount: Circular numeric counter.
rounded-full,h-[18px] min-w-[18px] px-1,text-[11px] font-medium. Variants: default (bg-foreground text-background), destructive (bg-destructive text-destructive-foreground), secondary (bg-accent text-foreground). Values above 99 display as "99+". - Buttons:
- Primary (Default): 8px radius,
foreground(black) background, white text. Flat. - Secondary / Outline: 8px radius,
accentbackground, 1pxborder. Flat. - Ghost: Icon buttons use
muted-foregrounddefaulting toforegroundon hover. - Grouped (
ButtonGroup): Unified outer border (border-border, 8px radius). Internal items divided byborder-rorborder-b, no individual borders or radiuses. - Brand Primary: Use
variant="primary"explicitly for Send button or active CTA. This is the only case wherebg-primaryis used.
- Primary (Default): 8px radius,
- Inputs: Flat design. 1px
border, purebackgroundfill, 8px/10px outer radius. Text must betext-[16px]. Focus state uses a stark black/grey ring, not primary purple. - Checkboxes/Radios: Flat, pure white background (
bg-background). 1pxborder. The checked state marker (tick/dot) isforeground(black), avoiding brand colors. - Separators: Uniformly use the 1px
bordercolor. Do not use padding/margins that detach them from the container edges (e.g., use full widthborder-bin menus instead of<Separator mx-1>).
Containers & Layouts
- Cards: The exception to the flat rule. 12px radius (
rounded-xl), purebackground, 1pxborder, and strongshadow-lg. Content spacing is tight (p-6, with 6px gap between title and description). - Alerts: Flat (
bg-background), 1pxborder, 10px radius (rounded-[10px]). No variant-specific colored backgrounds; errors use red text/icons but keep the white background. - Collapsible: Flat sub-panels.
bg-backgroundinside aborder-bordercontainer, items divided byborder-b(no bottom border on last child). Usesfont-monofor code-related items. - Dropdowns / Popovers / Comboboxes:
bg-backgroundwithborder-borderandshadow-md.- 8px outer radius.
- Items use 4px inner radius and
text-sm font-normal text-foreground. - Hover states use
bg-accentandtext-foreground(no brand color tints). - Group separators must be full-bleed
border-b.
- Breadcrumb: Minimalist. 14px icons, 4px-6px gaps. Active page is
text-foreground font-normal, inactive istext-muted-foreground. - Sidebar:
- Container uses
primary-foregroundbackground. - Active items use
accentbackground with a 2pxprimaryleft border indicator.
- Container uses
Items
- Global:
rounded-lg(8px),p-4,shadow-none,gap-4. - Variants:
- Default:
bg-background, no border. - Outline:
bg-background+border border-border. - Muted:
bg-accent, no border.
- Default:
Pagination
- Default page buttons:
bg-background border border-border text-foreground,rounded-lg,size-9. - Active/current page:
bg-foreground text-background border-foreground(black bg, white text — no brand purple). - Hover:
hover:bg-accent. - Disabled:
opacity-50 text-muted-foreground. - Previous/Next: ghost style, transparent bg, hover
bg-accent.
Complex / Domain Specific
- Sonner (Toast Notifications): Uses
bg-backgroundwithborder border-borderandshadow-md. Border radius isvar(--radius-lg)(10px). Title:text-sm font-medium text-foreground. Description:text-xs text-muted-foreground. Status icons aresize-4. Action buttons usebg-foreground text-background rounded-sm text-xs font-medium. Supports 6 states: default (with action button), loading (spinner), success, info, warning, error. - Table: Wrapped in a container with
border border-border rounded-sm(6px). Header row height 41px withpy-[10px], data rows 38px withpy-[8.5px]. Footer usesbg-muted/50. Empty state centers an icon +text-muted-foregroundmessage inh-[204px]. Caption is centeredtext-sm text-muted-foreground. - TagsInput: Flat design.
rounded-lg(no shadow). Focus state usesring-ring/20 ring-2(notring-[3px]). - Chat Input (Main Area):
- Flat container (
shadow-none),border-border, 10px radius. - Divided horizontally by top/bottom 1px borders (
border-t,border-b). - Send button uniquely retains
bg-primaryfor high conversion focus. - Model selector (Badge style) floats inside the top border area, using
bg-accentorbg-backgrounddepending on state.
- Flat container (
- OTP Input (PinInput): Flat group built on reka-ui
PinInput. Each cell issize-9 bg-background text-sm shadow-none. The first cell getsborder border-border rounded-l-lg, middle cells useborder-y border-r border-border(no left border to avoid doubling), and the last cell addsrounded-r-lg. Focus state appliesborder-2 border-ring(dark ring, not primary purple). Supports an optionalPinInputSeparatorbetween groups.
AI Image Generation & Component Reuse Rules
To ensure visual consistency when generating images or extrapolating designs via AI based on this system, strictly adhere to the following composition rules:
- The "Flat Atom" Law: If it's a basic interactive element (button, badge, input, toggle, checkbox), it cannot have a shadow. It must rely on
#e5e5e5borders and background contrast (#ffffffvs#f5f5f5vs#0a0a0a). - The "Menu Underline" Law: Whenever rendering a list of items inside a container (Dropdowns, Comboboxes, Sidebar Sub-menus, Collapsibles), items must be divided by a full-width, 1px horizontal line (
border-b), terminating cleanly on the last item. Do not leave floating separators with margins. - The "Monochrome Hover" Law: Focus and hover states for secondary items must always snap to
bg-[#f5f5f5]andtext-[#0a0a0a]. Never apply the brand purple (#8b56e3) as a background highlight for menus. - The "Bimodal Elevation" Trigger: Only use heavy, soft shadows (like
shadow-lg) when rendering a standalone focal piece (like a login modal or a central dashboard card) that sits distinctly above a complex, flat background layer. - The "Purple Scarcity" Law: The brand purple (
#8b56e3) is the most expensive pixel on the screen. It can only be used for:- The absolute primary completion action on a screen (e.g., the Chat "Send" button).
- Micro-indicators of "current active state" (e.g., a 2px vertical bar next to an active sidebar menu item, or a 5px status dot).
Do's and Don'ts
- Do use
bg-foreground(black) for standard primary actions like "Login" or "Register" instead of the brand purple. - Don't use
shadow-smon buttons, inputs, or alerts. Keep atomic components strictly flat. - Do use
shadow-lgfor large focal cards to make them pop against the flat UI. - Don't use colored backgrounds for Alert or Badge variants (like
bg-red-50). Keep them white and use text/icon color to convey meaning (or solid red for destructive badges). - Do maintain the 1px
#e5e5e5(--border) across all structural dividing lines, ensuring they connect edge-to-edge (no floating separators). - Don't use primary colors for hover or active states in standard dropdowns and menus; stick to
bg-accentandtext-foreground.