From 0ad72dccfab11456aa2f8072baca75834ea2850c Mon Sep 17 00:00:00 2001 From: Steven Enamakel <31011319+senamakel@users.noreply.github.com> Date: Sun, 17 May 2026 23:01:27 -0700 Subject: [PATCH] feat(theme): dark mode + UI primitives standardization (#2046) --- app/src/App.tsx | 43 +-- .../BootCheckGate/BootCheckGate.tsx | 96 ++++-- app/src/components/BottomTabBar.tsx | 6 +- app/src/components/ConnectionIndicator.tsx | 2 +- app/src/components/LanguageSelect.tsx | 2 +- app/src/components/OpenhumanLinkModal.tsx | 62 ++-- .../components/PersistRehydrationScreen.tsx | 12 +- app/src/components/PillTabBar.tsx | 4 +- app/src/components/RouteLoadingScreen.tsx | 2 +- .../components/accounts/AddAccountModal.tsx | 16 +- .../components/accounts/RespondQueuePanel.tsx | 28 +- app/src/components/accounts/WebviewHost.tsx | 20 +- .../channels/ChannelCapabilities.tsx | 2 +- .../channels/ChannelConfigPanel.tsx | 10 +- .../components/channels/ChannelFieldInput.tsx | 4 +- .../components/channels/ChannelSelector.tsx | 15 +- .../components/channels/ChannelSetupModal.tsx | 18 +- app/src/components/channels/DiscordConfig.tsx | 28 +- .../channels/DiscordServerChannelPicker.tsx | 26 +- .../components/channels/TelegramConfig.tsx | 14 +- .../components/channels/WebChannelConfig.tsx | 4 +- app/src/components/chat/TokenUsagePill.tsx | 20 +- .../composio/ComposioConnectModal.tsx | 82 +++-- .../components/composio/TriggerToggles.tsx | 40 ++- app/src/components/composio/toolkitMeta.tsx | 4 +- app/src/components/home/HomeBanners.tsx | 48 +-- .../intelligence/ActionableCard.tsx | 34 +- .../intelligence/ConfirmationModal.tsx | 18 +- .../intelligence/IntelligenceCallsTab.tsx | 30 +- .../intelligence/IntelligenceDreamsTab.tsx | 10 +- .../intelligence/IntelligenceMemoryTab.tsx | 46 ++- .../IntelligenceSubconsciousTab.tsx | 86 +++-- .../intelligence/IntelligenceTasksTab.tsx | 16 +- .../components/intelligence/MemoryGraph.tsx | 36 +- .../components/intelligence/MemoryHeatmap.tsx | 20 +- .../intelligence/MemoryInsights.tsx | 83 +++-- .../components/intelligence/MemorySources.tsx | 54 +-- .../intelligence/MemoryStatsBar.tsx | 26 +- .../intelligence/MemorySyncConnections.tsx | 38 ++- .../intelligence/MemoryWorkspace.tsx | 17 +- .../ScreenIntelligenceDebugPanel.tsx | 25 +- .../SubconsciousReflectionCards.tsx | 30 +- .../components/intelligence/VaultPanel.tsx | 60 ++-- .../intelligence/WhatsAppMemorySection.tsx | 14 +- .../notifications/NotificationCard.tsx | 20 +- .../notifications/NotificationCenter.tsx | 14 +- app/src/components/oauth/providerConfigs.tsx | 21 +- .../rewards/ReferralRewardsSection.tsx | 86 ++--- .../rewards/RewardsCommunityTab.tsx | 72 ++-- .../rewards/RewardsCouponSection.tsx | 67 ++-- app/src/components/settings/SettingsHome.tsx | 32 +- .../settings/SettingsSectionPage.tsx | 6 +- .../settings/components/PageBackButton.tsx | 2 +- .../settings/components/SettingsHeader.tsx | 16 +- .../settings/components/SettingsMenuItem.tsx | 14 +- .../settings/hooks/useSettingsNavigation.ts | 6 + .../components/settings/panels/AIPanel.tsx | 322 +++++++++++------- .../components/settings/panels/AboutPanel.tsx | 30 +- .../settings/panels/AgentChatPanel.tsx | 34 +- .../settings/panels/AppearancePanel.tsx | 148 ++++++++ .../panels/AutocompleteDebugPanel.tsx | 108 +++--- .../settings/panels/AutocompletePanel.tsx | 52 +-- .../settings/panels/BillingPanel.tsx | 26 +- .../settings/panels/ComposioPanel.tsx | 44 ++- .../settings/panels/ComposioTriagePanel.tsx | 28 +- .../settings/panels/ConnectionsPanel.tsx | 46 +-- .../settings/panels/CronJobsPanel.tsx | 8 +- .../settings/panels/DeveloperOptionsPanel.tsx | 67 ++-- .../settings/panels/LocalModelDebugPanel.tsx | 10 +- .../settings/panels/MascotPanel.tsx | 64 ++-- .../settings/panels/MemoryDebugPanel.tsx | 100 ++++-- .../settings/panels/MessagingPanel.tsx | 44 +-- .../panels/NotificationRoutingPanel.tsx | 66 ++-- .../settings/panels/NotificationsPanel.tsx | 30 +- .../settings/panels/PrivacyPanel.tsx | 74 ++-- .../settings/panels/RecoveryPhrasePanel.tsx | 56 +-- .../panels/ScreenAwarenessDebugPanel.tsx | 72 ++-- .../panels/ScreenIntelligencePanel.tsx | 40 ++- .../settings/panels/TeamInvitesPanel.tsx | 43 ++- .../settings/panels/TeamManagementPanel.tsx | 89 +++-- .../settings/panels/TeamMembersPanel.tsx | 60 ++-- .../components/settings/panels/TeamPanel.tsx | 61 ++-- .../components/settings/panels/ToolsPanel.tsx | 24 +- .../settings/panels/VoiceDebugPanel.tsx | 52 +-- .../components/settings/panels/VoicePanel.tsx | 126 ++++--- .../settings/panels/WebhooksDebugPanel.tsx | 74 ++-- .../panels/autocomplete/AppFilterSection.tsx | 40 +-- .../autocomplete/CompletionStyleSection.tsx | 84 +++-- .../panels/billing/AutoRechargeSection.tsx | 54 +-- .../panels/billing/BillingHistoryTab.tsx | 29 +- .../panels/billing/InferenceBudget.tsx | 26 +- .../panels/billing/PayAsYouGoCard.tsx | 53 +-- .../panels/billing/SubscriptionPlans.tsx | 52 +-- .../settings/panels/cron/CoreJobList.tsx | 54 +-- .../local-model/DeviceCapabilitySection.tsx | 86 ++--- .../local-model/ModelDownloadSection.tsx | 90 ++--- .../panels/local-model/ModelStatusSection.tsx | 161 +++++---- .../PermissionsSection.tsx | 28 +- .../skills/AutocompleteSetupModal.tsx | 36 +- .../components/skills/CreateSkillModal.tsx | 54 +-- .../components/skills/InstallSkillDialog.tsx | 34 +- app/src/components/skills/MeetingBotsCard.tsx | 40 +-- .../skills/ScreenIntelligenceSetupModal.tsx | 62 ++-- app/src/components/skills/SkillCard.tsx | 22 +- .../components/skills/SkillCategoryFilter.tsx | 4 +- .../components/skills/SkillDetailDrawer.tsx | 34 +- .../skills/SkillResourcePreview.tsx | 16 +- .../components/skills/SkillResourceTree.tsx | 16 +- app/src/components/skills/SkillSearchBar.tsx | 6 +- .../skills/UninstallSkillConfirmDialog.tsx | 10 +- app/src/components/skills/VoiceSetupModal.tsx | 34 +- app/src/components/skills/skillIcons.tsx | 16 +- app/src/components/ui/Button.tsx | 16 +- app/src/components/ui/Card.tsx | 41 +++ app/src/components/ui/Input.tsx | 36 ++ app/src/components/ui/index.ts | 8 + app/src/components/upsell/UpsellBanner.tsx | 20 +- app/src/components/upsell/UsageLimitModal.tsx | 18 +- .../walkthrough/WalkthroughTooltip.tsx | 16 +- .../webhooks/ComposeioTriggerHistory.tsx | 20 +- app/src/features/human/HumanPage.tsx | 6 +- app/src/features/human/MicComposer.tsx | 4 +- app/src/index.css | 87 ++++- app/src/lib/i18n/chunks/zh-CN-3.ts | 2 + app/src/lib/i18n/en.ts | 2 + app/src/main.tsx | 1 + app/src/pages/Accounts.tsx | 67 +++- app/src/pages/Channels.tsx | 4 +- app/src/pages/Conversations.tsx | 142 ++++---- app/src/pages/Home.tsx | 12 +- app/src/pages/Intelligence.tsx | 12 +- app/src/pages/Invites.tsx | 8 +- app/src/pages/Notifications.tsx | 36 +- app/src/pages/Settings.tsx | 6 +- app/src/pages/Skills.tsx | 82 ++--- app/src/pages/Webhooks.tsx | 38 ++- app/src/pages/Welcome.tsx | 12 +- .../components/AgentMessageBubble.tsx | 19 +- .../components/CitationChips.tsx | 4 +- .../conversations/components/LimitPill.tsx | 10 +- .../components/TaskKanbanBoard.tsx | 26 +- .../components/ToolTimelineBlock.tsx | 58 ++-- .../components/WorkerThreadRefCard.tsx | 18 +- .../onboarding/components/BetaBanner.tsx | 8 +- .../components/ConfigureLaterCallout.tsx | 8 +- .../onboarding/components/WizardStepper.tsx | 10 +- .../onboarding/pages/ChatProviderPage.tsx | 10 +- .../pages/onboarding/steps/ApiKeysStep.tsx | 22 +- .../onboarding/steps/ContextGatheringStep.tsx | 12 +- .../onboarding/steps/CustomWizardStep.tsx | 26 +- .../pages/onboarding/steps/LocalAIStep.tsx | 76 +++-- .../onboarding/steps/ReferralApplyStep.tsx | 20 +- .../onboarding/steps/RuntimeChoiceStep.tsx | 30 +- app/src/pages/onboarding/steps/SkillsStep.tsx | 42 +-- .../pages/onboarding/steps/WelcomeStep.tsx | 6 +- app/src/providers/ThemeProvider.tsx | 48 +++ app/src/store/index.ts | 8 + app/src/store/themeSlice.ts | 39 +++ app/src/styles/theme.css | 170 ++++++++- 159 files changed, 3814 insertions(+), 2298 deletions(-) create mode 100644 app/src/components/settings/panels/AppearancePanel.tsx create mode 100644 app/src/components/ui/Card.tsx create mode 100644 app/src/components/ui/Input.tsx create mode 100644 app/src/components/ui/index.ts create mode 100644 app/src/providers/ThemeProvider.tsx create mode 100644 app/src/store/themeSlice.ts diff --git a/app/src/App.tsx b/app/src/App.tsx index a964988b5..d314ef828 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -33,6 +33,7 @@ import { import ChatRuntimeProvider from './providers/ChatRuntimeProvider'; import CoreStateProvider, { useCoreState } from './providers/CoreStateProvider'; import SocketProvider from './providers/SocketProvider'; +import ThemeProvider from './providers/ThemeProvider'; import { trackPageView } from './services/analytics'; import { startCoreHealthMonitor, stopCoreHealthMonitor } from './services/coreHealthMonitor'; import { @@ -83,26 +84,28 @@ function App() { )}> } persistor={persistor}> - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/components/BootCheckGate/BootCheckGate.tsx b/app/src/components/BootCheckGate/BootCheckGate.tsx index b81b3cbcf..e531b6919 100644 --- a/app/src/components/BootCheckGate/BootCheckGate.tsx +++ b/app/src/components/BootCheckGate/BootCheckGate.tsx @@ -56,9 +56,11 @@ interface PanelProps { function Panel({ children }: PanelProps) { return ( -
+
-
+
{children}
@@ -212,16 +214,16 @@ function ModePicker({ onConfirm }: PickerProps) { return ( -

+

{isDesktop ? t('bootCheck.chooseCoreMode') : t('bootCheck.connectToCore')}

-

+

{isDesktop ? t('bootCheck.desktopDescription') : t('bootCheck.webDescription')}

{!isDesktop && (
{t('bootCheck.preferDesktop')}{' '}
{t('bootCheck.localRecommended')}
-
{t('bootCheck.localDescription')}
+
+ {t('bootCheck.localDescription')} +
)} @@ -260,18 +264,20 @@ function ModePicker({ onConfirm }: PickerProps) { aria-pressed={selected === 'cloud'} className={`rounded-xl border-2 p-5 text-left transition-colors focus:outline-none ${ selected === 'cloud' - ? '!border-primary-500 bg-primary-50 text-stone-900 shadow-sm' - : '!border-stone-200 bg-white text-stone-700 hover:!border-stone-300 hover:bg-stone-50' + ? '!border-primary-500 bg-primary-50 dark:bg-primary-500/15 text-stone-900 dark:text-neutral-100 shadow-sm' + : '!border-stone-200 dark:!border-neutral-700 bg-white dark:bg-neutral-900 text-stone-700 dark:text-neutral-200 hover:!border-stone-300 dark:hover:!border-neutral-600 hover:bg-stone-50 dark:hover:bg-neutral-800/60' }`}>
{t('bootCheck.cloudMode')}
-
{t('bootCheck.cloudDescription')}
+
+ {t('bootCheck.cloudDescription')} +
)} {selected === 'cloud' && (
-
-
@@ -316,7 +322,7 @@ function ModePicker({ onConfirm }: PickerProps) { type="button" onClick={handleTestConnection} disabled={testStatus.kind === 'testing'} - className="rounded-lg border border-stone-300 bg-white px-3 py-1.5 text-xs text-stone-700 hover:bg-stone-50 disabled:opacity-60"> + className="rounded-lg border border-stone-300 dark:border-neutral-700 bg-white dark:bg-neutral-900 px-3 py-1.5 text-xs text-stone-700 dark:text-neutral-200 hover:bg-stone-50 dark:hover:bg-neutral-800/60 disabled:opacity-60"> {testStatus.kind === 'testing' ? t('bootCheck.testing') : t('bootCheck.testConnection')} @@ -362,8 +368,10 @@ function CheckingScreen() { return (
-
-

{t('bootCheck.checkingCore')}

+
+

+ {t('bootCheck.checkingCore')} +

); @@ -398,8 +406,10 @@ function ResultScreen({ if (result.kind === 'unreachable') { return ( -

{t('bootCheck.cannotReach')}

-

+

+ {t('bootCheck.cannotReach')} +

+

{result.reason || t('bootCheck.cannotReachDesc')}

{actionError &&

{actionError}

} @@ -408,13 +418,13 @@ function ResultScreen({ type="button" onClick={onRetry} disabled={actionBusy} - className="rounded-lg border border-stone-300 bg-white px-4 py-2 text-sm text-stone-700 hover:bg-stone-50 disabled:opacity-60"> + className="rounded-lg border border-stone-300 dark:border-neutral-700 bg-white dark:bg-neutral-900 px-4 py-2 text-sm text-stone-700 dark:text-neutral-200 hover:bg-stone-50 dark:hover:bg-neutral-800/60 disabled:opacity-60"> {t('common.retry')}
@@ -457,8 +471,12 @@ function ResultScreen({ if (result.kind === 'outdatedLocal') { return ( -

{t('bootCheck.localNeedsRestart')}

-

{t('bootCheck.localNeedsRestartDesc')}

+

+ {t('bootCheck.localNeedsRestart')} +

+

+ {t('bootCheck.localNeedsRestartDesc')} +

{actionError &&

{actionError}

}
@@ -483,8 +501,12 @@ function ResultScreen({ if (result.kind === 'outdatedCloud') { return ( -

{t('bootCheck.cloudNeedsUpdate')}

-

{t('bootCheck.cloudNeedsUpdateDesc')}

+

+ {t('bootCheck.cloudNeedsUpdate')} +

+

+ {t('bootCheck.cloudNeedsUpdateDesc')} +

{actionError &&

{actionError}

}
@@ -509,8 +531,12 @@ function ResultScreen({ // noVersionMethod — treat like outdated, user picks which flavor of action return ( -

{t('bootCheck.versionCheckFailed')}

-

{t('bootCheck.versionCheckFailedDesc')}

+

+ {t('bootCheck.versionCheckFailed')} +

+

+ {t('bootCheck.versionCheckFailedDesc')} +

{actionError &&

{actionError}

}
diff --git a/app/src/components/BottomTabBar.tsx b/app/src/components/BottomTabBar.tsx index c41df7795..e9f50790e 100644 --- a/app/src/components/BottomTabBar.tsx +++ b/app/src/components/BottomTabBar.tsx @@ -197,7 +197,7 @@ const BottomTabBar = () => { onBlur={e => { if (!e.currentTarget.contains(e.relatedTarget as Node)) setRevealed(false); }}> -