Bring OpenCode theme presets into the UI foundation - #155
Conversation
Replace hardcoded status styling with semantic tokens and add shared drawer and resizable patterns so settings, repo, session, and file flows feel consistent across desktop and mobile.
Let the settings nav wrap naturally and widen the resize handle so the desktop sidebar is easier to read and drag while reviewing account and config sections.
Use percentage-based panel sizes with react-resizable-panels so the settings sidebar opens at a usable width and can be resized normally on desktop.
There was a problem hiding this comment.
Pull request overview
This PR refactors the frontend UI theme system from hardcoded Tailwind color classes (e.g., text-blue-500, bg-red-600) to semantic design tokens (e.g., text-primary, text-destructive, text-warning, text-info, text-success), using oklch color space. It also introduces new UI primitives (Drawer via vaul, resizable panels via react-resizable-panels) and applies them to the settings dialog for a resizable sidebar layout. The shadcn/ui configuration is updated from "default" to "new-york" style.
Changes:
- Replace all hardcoded color classes across ~45 files with semantic theme tokens (
text-primary,text-destructive,text-warning,text-info,text-success), and rebuild the CSS theme foundation inindex.csswith oklch tokens, scrollbar styling, surface utilities, and aprefers-reduced-motionmedia query. - Add
vaul(Drawer) andreact-resizable-panels(Resizable) UI primitives, and refactor theSettingsDialogfrom a horizontal tab bar to a resizable sidebar + content panel layout (desktop), with a mobile-friendly menu-then-detail flow using section intro cards. - Update base UI components (
Button,Badge,Card,Input,Select,Switch,Tabs,Dialog) with refined styling (rounded corners, backdrop blur, subtle borders, shadows) consistent with the new theme tokens.
Reviewed changes
Copilot reviewed 79 out of 80 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
frontend/src/index.css |
Complete theme overhaul: oklch tokens, semantic color variables, surface utilities, scrollbar styling, reduced-motion support |
frontend/components.json |
shadcn config updated from "default" to "new-york" style |
frontend/package.json |
Added vaul and react-resizable-panels dependencies |
pnpm-lock.yaml |
Lock file entries for new dependencies |
frontend/src/components/ui/drawer.tsx |
New Drawer primitive wrapping vaul |
frontend/src/components/ui/resizable.tsx |
New Resizable primitives wrapping react-resizable-panels |
frontend/src/components/ui/button.tsx |
Refined variants with semantic tokens, active translate, new focus ring |
frontend/src/components/ui/badge.tsx |
Added info, success, warning variants; updated existing variants |
frontend/src/components/ui/card.tsx |
Rounded-xl, backdrop-blur, border/bg adjustments |
frontend/src/components/ui/input.tsx |
Panel-based bg, ring focus style, shadow-xs |
frontend/src/components/ui/select.tsx |
Consistent styling with input and card updates |
frontend/src/components/ui/switch.tsx |
Semantic tokens for checked/unchecked states |
frontend/src/components/ui/tabs.tsx |
Updated TabsList/TabsTrigger styling |
frontend/src/components/ui/dialog.tsx |
Backdrop blur, data-slot attrs, updated close button |
frontend/src/components/ui/page-header.tsx |
Border-b with backdrop-blur header |
frontend/src/components/ui/back-button.tsx |
Semantic tokens, cn() utility |
frontend/src/components/ui/copy-button.tsx |
text-success for copied state |
frontend/src/components/ui/pending-action-badge.tsx |
Color type renamed from orange/blue to warning/info |
frontend/src/components/ui/session-status-indicator.tsx |
Semantic token replacements |
frontend/src/components/ui/mini-scanner.tsx |
Semantic token replacements |
frontend/src/components/ui/virtualized-text-view.tsx |
bg-warning/20 for highlights |
frontend/src/components/ui/delete-dialog.tsx |
Removed hardcoded red button classes |
frontend/src/components/ui/discard-dialog.tsx |
Removed hardcoded red button classes |
frontend/src/components/ui/header.tsx |
Semantic tokens for notification indicators |
frontend/src/components/settings/SettingsDialog.tsx |
Major refactor: resizable sidebar layout, section intros, typed menu items |
frontend/src/components/settings/TTSSettings.tsx |
Semantic tokens for provider selection and status |
frontend/src/components/settings/STTSettings.tsx |
Semantic tokens for test results and warnings |
frontend/src/components/settings/ProviderSettings.tsx |
Badge variant="success" for connected state |
frontend/src/components/settings/OpenCodeConfigManager.tsx |
Semantic tokens throughout |
frontend/src/components/settings/OpenCodeConfigEditor.tsx |
text-destructive for errors |
frontend/src/components/settings/NotificationSettings.tsx |
text-warning for denied state |
frontend/src/components/settings/MemoryPluginConfig.tsx |
Semantic icon colors |
frontend/src/components/settings/McpServerCard.tsx |
Badge variants for status, semantic destructive colors |
frontend/src/components/settings/McpOAuthDialog.tsx |
Semantic tokens for spinners and success |
frontend/src/components/settings/GeneralSettings.tsx |
text-success for version link |
frontend/src/components/settings/CreateConfigDialog.tsx |
text-destructive for errors |
frontend/src/components/settings/CommandsEditor.tsx |
Semantic destructive for delete buttons |
frontend/src/components/settings/AgentsMdEditor.tsx |
Semantic tokens |
frontend/src/components/settings/AgentsEditor.tsx |
Semantic destructive for delete |
frontend/src/components/settings/AccountSettings.tsx |
Success border/text for alerts |
frontend/src/components/settings/VersionSelectDialog.tsx |
Semantic tokens for current version |
frontend/src/components/repo/AddRepoDialog.tsx |
Major refactor: Drawer for mobile, structured form sections |
frontend/src/components/repo/RepoCard.tsx |
Semantic tokens throughout |
frontend/src/components/repo/RepoList.tsx |
text-muted-foreground for empty states |
frontend/src/components/repo/RepoMcpServerList.tsx |
Badge variants, semantic tokens |
frontend/src/components/repo/SwitchConfigDialog.tsx |
Semantic tokens, removed hardcoded blue button |
frontend/src/components/session/SessionCard.tsx |
Semantic tokens for selection, status, delete |
frontend/src/components/session/QuestionPrompt.tsx |
Comprehensive semantic token migration |
frontend/src/components/session/PermissionRequestDialog.tsx |
Warning tokens |
frontend/src/components/session/EditSessionTitleDialog.tsx |
Destructive tokens |
frontend/src/components/session/ContextUsageIndicator.tsx |
Success/warning/destructive for usage levels |
frontend/src/components/notifications/PendingActionsGroup.tsx |
Updated color prop names |
frontend/src/components/model/ModelSelectDialog.tsx |
Semantic tokens for selection and loading |
frontend/src/components/model/ModelQuickSelect.tsx |
text-warning for variant display |
frontend/src/components/message/ToolCallPart.tsx |
Semantic tokens for all status states |
frontend/src/components/message/TodoItem.tsx |
Semantic success/warning tokens |
frontend/src/components/message/TextPart.tsx |
Destructive tokens for mermaid errors |
frontend/src/components/message/SessionTodoDisplay.tsx |
bg-success for progress bars |
frontend/src/components/message/RetryPart.tsx |
Warning tokens for retry UI |
frontend/src/components/message/PromptInput.tsx |
Comprehensive semantic migration |
frontend/src/components/message/PatchPart.tsx |
text-info for file links |
frontend/src/components/message/MessageThread.tsx |
Primary/warning tokens for messages |
frontend/src/components/message/MessageSkeleton.tsx |
Primary tokens for skeletons |
frontend/src/components/message/MessagePart.tsx |
Info/destructive tokens |
frontend/src/components/message/FileToolRender.tsx |
Success/info tokens |
frontend/src/components/message/EditableUserMessage.tsx |
Primary hover token |
frontend/src/components/message/DiffStats.tsx |
Success/destructive tokens |
frontend/src/components/message/ContentDiffViewer.tsx |
Success/destructive for diff lines |
frontend/src/components/memory/MemoryList.tsx |
Semantic scope colors |
frontend/src/components/file-browser/FileTree.tsx |
Destructive for delete action |
frontend/src/components/file-browser/FilePreview.tsx |
Warning/info/success tokens |
frontend/src/components/file-browser/FileDiffView.tsx |
Comprehensive semantic diff styling |
frontend/src/components/ssh/SSHHostKeyDialog.tsx |
Destructive/warning tokens |
frontend/src/lib/git-status-styles.ts |
All colors migrated to semantic tokens |
frontend/src/pages/SessionDetail.tsx |
Semantic tokens for parent session, subtitle, actions |
frontend/src/pages/RepoDetail.tsx |
Badge variant, removed hardcoded blue button |
frontend/src/pages/Memories.tsx |
text-info for brain icon |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
You can also share your feedback on Copilot code review. Take the survey.
Simplify the running-state warning styles in tool call output and restore a visible hover state for the version update link so the semantic theme cleanup keeps its interaction cues.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 84 out of 89 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
You can also share your feedback on Copilot code review. Take the survey.
Use numeric resizable panel sizes so the settings layout behaves correctly and keep page header tests aligned with the refreshed header styling.
| <label className="text-sm font-medium text-foreground">{sourceLabel}</label> | ||
| <Input | ||
| placeholder={sourcePlaceholder} | ||
| value={sourceValue} | ||
| onChange={(e) => { | ||
| if (repoType === 'remote') { | ||
| handleRepoUrlChange(e.target.value) | ||
| } else if (repoType === 'local') { | ||
| setLocalPath(e.target.value) | ||
| } else { | ||
| setFolderPath(e.target.value) | ||
| } | ||
| }} | ||
| disabled={mutation.isPending} | ||
| /> |
There was a problem hiding this comment.
The plain <label> for the source field isn't associated with the Input control (no htmlFor on the label and no id on the input). This reduces accessibility/screen-reader usability. Consider using the shared Label component with htmlFor, and pass a stable id into the Input so the label is programmatically linked.
| <div className="space-y-2"> | ||
| <label className="text-sm text-zinc-400">Branch</label> | ||
| <label className="text-sm font-medium text-foreground">Branch</label> | ||
| <Input | ||
| placeholder="Optional - uses default if empty" | ||
| value={branch} | ||
| onChange={(e) => setBranch(e.target.value)} | ||
| disabled={mutation.isPending || repoType === 'folder'} | ||
| className="bg-[#1a1a1a] border-[#2a2a2a] text-white placeholder:text-zinc-500" | ||
| /> |
There was a problem hiding this comment.
Same as the source field: the "Branch" <label> isn't linked to its Input (missing htmlFor/id). Hooking these up (or using the existing Label component) improves keyboard and assistive-tech navigation.
Resolve conflicts with current main while preserving OpenCode theme presets, theme picker UI, and semantic surface styling. Drop memory plugin UI that was removed upstream.
Restore broken conflicted UI files from main, keep themed back-button, load .env.local overrides for a parallel dev stack on 5004/5174/5552.
|
Warning Review limit reached
Next review available in: 40 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (78)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Rebased/merged onto current mainThis branch is now updated against latest Conflict resolution notes
Local HMR (does not touch production Docker on :5003)
|
Omit fixed PASSKEY_ORIGIN so WebAuthn verifies against the request Origin. Keeps RP ID as the Tailscale hostname so prod passkeys work on :5174 HMR as well as :5003. Vite allows Tailscale hosts and pins HMR clientPort for Serve TLS.
Inject allowCredentials for discoverable passkey login (fixes Windows Hello cancel), isolate dev cookies, expose RP ID to login page, and preserve Origin through the Vite proxy.
Overview
This PR upgrades the existing UI theme foundation work from a generic semantic cleanup into a real OpenCode theme system pass.
The app now uses actual OpenCode theme preset data, exposes the same preset-style picker in Settings, and maps those palette tokens into the app shell so the product feels much closer to OpenCode instead of just being loosely inspired by it.
What Changed
themePresetalongside appearance mode so users can independently choose a palette and render it in dark, light, or system modeSettings > General Settingsinto a theme showcase panel with palette selection, appearance selection, and a live preview of key tokensOpenCode Theme Presets Included
This PR installs and exposes all 33 imported OpenCode presets:
OpenCode,GitHub,Tokyo Night,Vesper,Carbonfox,Cursor,Dracula,Night Owl,Everforest,Flexoki,Gruvbox,Kanagawa,Catppuccin,Catppuccin Frappe,Catppuccin Macchiato,Ayu,One Dark,Material,Monokai,Palenight,Rose Pine,Solarized,Aura,Cobalt2,Matrix,Mercury,Nord,Orng,Lucent Orng,Osaka Jade,Synthwave 84,Vercel,ZenburnWhy This Matters
/themeexperienceValidation
pnpm lintpnpm --filter frontend buildTheme Previews
These screenshots were captured from the Docker preview in
Settings > General Settingsat1920x1080after switching presets through the new theme picker.OpenCode (Dark)
GitHub (Light)
Tokyo Night (Dark)