From fefaa45b7077e10dbd5f3e02c20b264a05720c2f Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Sun, 21 Jun 2026 00:20:54 +0200 Subject: [PATCH] refactor: replace shadcn color vocabulary with semantic tokens Remove the shadcn/ui color tokens (background, foreground, card, popover, muted, accent, secondary, destructive, input) and migrate every usage to LibreChat semantic surface/text/border tokens. Add surface-inverted/text-inverted for the neutral inverted CTA and surface-fixed/text-fixed for controls that must not flip with the theme (favicon chips, QR container, carousel arrows). New tokens are defined once in style.css (light + dark), createTailwindColors, the theme types, applyTheme and the default/dark theme objects so they stay overridable at runtime. Collapse paired dark: color variants into the dark-aware tokens and tokenize the remaining raw palette and white/black utilities, mapping status colors to the status-* tokens and legacy ring-black/ring-white focus rings to ring-text-primary. Retain the background, primary and ring tokens, which are still referenced by the SidePanel/Agents and SidePanel/Builder panels (excluded from this pass). --- client/src/components/Agents/AgentDetail.tsx | 4 +- .../components/Agents/AgentDetailContent.tsx | 4 +- client/src/components/Agents/AgentGrid.tsx | 4 +- client/src/components/Agents/SearchBar.tsx | 2 +- .../Agents/VirtualizedAgentGrid.tsx | 4 +- .../tests/AgentGrid.integration.spec.tsx | 2 +- .../tests/VirtualizedAgentGrid.test.tsx | 2 +- client/src/components/Chat/Input/ChatForm.tsx | 2 +- .../Chat/Input/Files/FileUpload.tsx | 2 +- .../Chat/Input/Files/ImagePreview.tsx | 2 +- .../Chat/Input/Files/MyFilesModal.tsx | 2 +- .../Chat/Input/Files/ProgressCircle.tsx | 2 +- .../Files/Table/ColumnVisibilityDropdown.tsx | 2 +- .../Chat/Input/Files/Table/DataTable.tsx | 4 +- .../Input/Files/Table/SortFilterHeader.tsx | 2 +- .../components/Chat/Input/MCPConfigDialog.tsx | 2 +- .../Chat/Input/TokenUsage/index.tsx | 2 +- client/src/components/Chat/Landing.tsx | 2 +- .../Chat/Menus/Endpoints/CustomMenu.tsx | 7 +-- .../Chat/Menus/Presets/EditPresetDialog.tsx | 2 +- .../Chat/Menus/Presets/PresetItems.tsx | 4 +- .../Chat/Messages/Content/Image.tsx | 2 +- .../Chat/Messages/Content/MessageContent.tsx | 2 +- .../Chat/Messages/Content/Parts/EmptyText.tsx | 2 +- .../Messages/Content/Parts/SubagentCall.tsx | 4 +- .../Chat/Messages/Content/Parts/Summary.tsx | 2 +- .../Chat/Messages/Content/Parts/Thinking.tsx | 2 +- .../Chat/Messages/Content/SearchContent.tsx | 2 +- .../Chat/Messages/Content/ToolCallGroup.tsx | 2 +- .../Messages/Content/UIResourceCarousel.tsx | 4 +- .../src/components/Chat/Messages/Feedback.tsx | 2 +- client/src/components/Chat/Messages/Fork.tsx | 10 ++-- .../components/Chat/Messages/HoverButtons.tsx | 2 +- .../src/components/Chat/Messages/Message.tsx | 2 +- .../components/Chat/Messages/MessageNav.tsx | 4 +- .../components/Chat/Messages/MessageParts.tsx | 2 +- .../components/Chat/Messages/MessagesView.tsx | 2 +- .../Chat/Messages/MinimalHoverButtons.tsx | 2 +- .../Chat/Messages/MinimalMessages.tsx | 2 +- .../Chat/Messages/SiblingSwitch.tsx | 2 +- .../components/Conversations/RenameForm.tsx | 4 +- .../Endpoints/Settings/Examples.tsx | 4 +- client/src/components/Files/ActionButton.tsx | 2 +- .../Files/FileList/DataTableFile.tsx | 10 ++-- .../Files/FileList/UploadFileButton.tsx | 2 +- .../Files/FileList/UploadFileModal.tsx | 4 +- .../Files/VectorStore/VectorStoreButton.tsx | 2 +- .../Input/Generations/Regenerate.tsx | 2 +- .../src/components/Input/Generations/Stop.tsx | 2 +- .../Input/ModelSelect/MultiSelectDropDown.tsx | 18 +++--- .../Input/ModelSelect/MultiSelectPop.tsx | 14 ++--- .../Input/ModelSelect/SelectDropDownPop.tsx | 6 +- .../Input/SetKeyDialog/GoogleConfig.tsx | 2 +- .../Input/SetKeyDialog/SetKeyDialog.tsx | 2 +- .../src/components/MCP/MCPServerMenuItem.tsx | 2 +- .../components/MCP/MCPServerStatusIcon.tsx | 6 +- .../components/Messages/MessageContent.tsx | 2 +- .../components/Nav/Bookmarks/BookmarkNav.tsx | 2 +- client/src/components/Nav/NavToggle.tsx | 4 +- client/src/components/Nav/Settings/Dialog.tsx | 2 +- .../SettingsTabs/Account/BackupCodesItem.tsx | 8 +-- .../SettingsTabs/Account/DeleteAccount.tsx | 4 +- .../Account/TwoFactorAuthentication.tsx | 2 +- .../Account/TwoFactorPhases/DisablePhase.tsx | 2 +- .../Account/TwoFactorPhases/QRPhase.tsx | 2 +- .../Nav/SettingsTabs/ApiKeys/ApiKeys.tsx | 2 +- .../Nav/SettingsTabs/Data/SharedLinks.tsx | 6 +- .../General/ArchivedChatsModal.tsx | 2 +- .../General/ArchivedChatsTable.tsx | 2 +- client/src/components/OAuth/OAuthError.tsx | 2 +- .../Plugins/Store/PluginAuthForm.tsx | 4 +- .../Plugins/Store/PluginPagination.tsx | 10 ++-- .../Prompts/display/PromptVersions.tsx | 8 +-- .../Prompts/fields/CategorySelector.tsx | 2 +- .../components/Prompts/forms/PromptForm.tsx | 2 +- .../components/Prompts/forms/VariableForm.tsx | 4 +- client/src/components/Share/Message.tsx | 2 +- client/src/components/Share/MessagesView.tsx | 4 +- client/src/components/Share/ShareView.tsx | 2 +- .../Sharing/GenericGrantAccessDialog.tsx | 4 +- .../PeoplePicker/SelectedPrincipalsList.tsx | 8 +-- .../Sharing/PublicSharingToggle.tsx | 6 +- .../components/Skills/buttons/SkillToggle.tsx | 2 +- .../Skills/forms/CategorySelector.tsx | 2 +- client/src/components/Tools/MCPToolItem.tsx | 4 +- client/src/components/Tools/ToolItem.tsx | 6 +- client/src/components/Web/SourceHovercard.tsx | 6 +- client/src/components/Web/Sources.tsx | 10 ++-- .../components/Web/SourcesErrorBoundary.tsx | 2 +- client/src/hooks/Endpoint/UnknownIcon.tsx | 4 +- client/src/routes/RouteErrorBoundary.tsx | 6 +- client/src/routes/Search.tsx | 2 +- client/src/style.css | 42 +++++-------- client/src/utils/buildTree.ts | 4 +- client/src/utils/index.ts | 8 +-- packages/client/src/components/Accordion.tsx | 2 +- .../client/src/components/AlertDialog.tsx | 11 ++-- .../src/components/AnimatedSearchInput.tsx | 4 +- packages/client/src/components/Breadcrumb.tsx | 6 +- packages/client/src/components/Button.tsx | 15 +++-- packages/client/src/components/Checkbox.tsx | 2 +- packages/client/src/components/Combobox.tsx | 20 +++---- packages/client/src/components/DataTable.tsx | 4 +- .../src/components/DataTable/DataTable.tsx | 2 +- .../DataTable/DataTableErrorBoundary.tsx | 4 +- packages/client/src/components/Dialog.tsx | 23 ++++--- .../client/src/components/DialogTemplate.tsx | 12 ++-- packages/client/src/components/Dropdown.tsx | 6 +- .../client/src/components/DropdownMenu.tsx | 10 ++-- .../client/src/components/DropdownNoState.tsx | 8 +-- .../client/src/components/DropdownPopup.tsx | 2 +- .../client/src/components/FilterInput.tsx | 4 +- packages/client/src/components/Input.tsx | 2 +- .../client/src/components/InputNumber.tsx | 2 +- packages/client/src/components/InputOTP.tsx | 6 +- .../src/components/InputWithDropDown.tsx | 6 +- packages/client/src/components/Label.tsx | 2 +- .../client/src/components/MultiSelect.tsx | 8 +-- .../src/components/OGDialogTemplate.tsx | 4 +- .../client/src/components/OriginalDialog.tsx | 4 +- packages/client/src/components/Progress.tsx | 7 ++- packages/client/src/components/Radio.tsx | 12 ++-- packages/client/src/components/Resizable.tsx | 8 +-- .../client/src/components/SecretInput.tsx | 2 +- packages/client/src/components/Select.tsx | 22 +++---- .../client/src/components/SelectDropDown.tsx | 20 +++---- packages/client/src/components/Slider.tsx | 8 ++- packages/client/src/components/Switch.tsx | 4 +- packages/client/src/components/Table.tsx | 8 +-- packages/client/src/components/Tabs.tsx | 2 +- packages/client/src/components/Textarea.tsx | 2 +- .../client/src/components/ThemeSelector.tsx | 4 +- packages/client/src/svgs/DotsIcon.tsx | 2 +- packages/client/src/svgs/NewChatIcon.tsx | 2 +- packages/client/src/svgs/SendIcon.tsx | 2 +- .../client/src/svgs/StopGeneratingIcon.tsx | 2 +- packages/client/src/theme/themes/dark.ts | 28 ++++----- packages/client/src/theme/themes/default.ts | 28 ++++----- packages/client/src/theme/types/index.ts | 60 +++++++------------ packages/client/src/theme/utils/applyTheme.ts | 20 +++---- .../src/theme/utils/createTailwindColors.js | 33 +++------- 141 files changed, 379 insertions(+), 455 deletions(-) diff --git a/client/src/components/Agents/AgentDetail.tsx b/client/src/components/Agents/AgentDetail.tsx index 4f71bb114f..9fa05a4d93 100644 --- a/client/src/components/Agents/AgentDetail.tsx +++ b/client/src/components/Agents/AgentDetail.tsx @@ -117,7 +117,7 @@ const AgentDetail: React.FC = ({ agent, isOpen, onClose }) => if (name && email) { return ( - + {name} ); @@ -125,7 +125,7 @@ const AgentDetail: React.FC = ({ agent, isOpen, onClose }) => if (email) { return ( - + {email} ); diff --git a/client/src/components/Agents/AgentDetailContent.tsx b/client/src/components/Agents/AgentDetailContent.tsx index 7a2a95401d..b9d724e461 100644 --- a/client/src/components/Agents/AgentDetailContent.tsx +++ b/client/src/components/Agents/AgentDetailContent.tsx @@ -116,7 +116,7 @@ const AgentDetailContent: React.FC = ({ agent }) => { if (name && email) { return ( - + {name} ); @@ -124,7 +124,7 @@ const AgentDetailContent: React.FC = ({ agent }) => { if (email) { return ( - + {email} ); diff --git a/client/src/components/Agents/AgentGrid.tsx b/client/src/components/Agents/AgentGrid.tsx index 285df3dc74..991f5e186e 100644 --- a/client/src/components/Agents/AgentGrid.tsx +++ b/client/src/components/Agents/AgentGrid.tsx @@ -129,7 +129,7 @@ const AgentGrid: React.FC = ({ // Simple loading spinner const loadingSpinner = (
- +
); @@ -207,7 +207,7 @@ const AgentGrid: React.FC = ({ aria-live="polite" aria-label={localize('com_agents_loading')} > - + {localize('com_agents_loading')} )} diff --git a/client/src/components/Agents/SearchBar.tsx b/client/src/components/Agents/SearchBar.tsx index 7fab811b4c..652fae974d 100644 --- a/client/src/components/Agents/SearchBar.tsx +++ b/client/src/components/Agents/SearchBar.tsx @@ -92,7 +92,7 @@ const SearchBar: React.FC = ({ value, onSearch, className = '' } diff --git a/client/src/components/Files/FileList/UploadFileModal.tsx b/client/src/components/Files/FileList/UploadFileModal.tsx index d8ffb3b5de..924eef38a8 100644 --- a/client/src/components/Files/FileList/UploadFileModal.tsx +++ b/client/src/components/Files/FileList/UploadFileModal.tsx @@ -63,7 +63,7 @@ const UploadFileModal = ({ open, onOpenChange }) => {
diff --git a/client/src/components/Input/Generations/Regenerate.tsx b/client/src/components/Input/Generations/Regenerate.tsx index 7eff9f0eae..7ba1fe7c53 100644 --- a/client/src/components/Input/Generations/Regenerate.tsx +++ b/client/src/components/Input/Generations/Regenerate.tsx @@ -8,7 +8,7 @@ export default function Regenerate({ onClick }: TGenButtonProps) { return ( ); diff --git a/client/src/components/Input/Generations/Stop.tsx b/client/src/components/Input/Generations/Stop.tsx index 44ce392d48..61330c60a0 100644 --- a/client/src/components/Input/Generations/Stop.tsx +++ b/client/src/components/Input/Generations/Stop.tsx @@ -8,7 +8,7 @@ export default function Stop({ onClick }: TGenButtonProps) { return ( ); diff --git a/client/src/components/Input/ModelSelect/MultiSelectDropDown.tsx b/client/src/components/Input/ModelSelect/MultiSelectDropDown.tsx index c9584a0e94..e13f872fce 100644 --- a/client/src/components/Input/ModelSelect/MultiSelectDropDown.tsx +++ b/client/src/components/Input/ModelSelect/MultiSelectDropDown.tsx @@ -81,7 +81,7 @@ function MultiSelectDropDown({ <> ) : ( - + )} -
+
))}
@@ -161,7 +161,7 @@ function MultiSelectDropDown({ @@ -175,7 +175,7 @@ function MultiSelectDropDown({ {!option.isButton && ( @@ -185,12 +185,12 @@ function MultiSelectDropDown({ {`${option.name} ) : ( - + )} -
+
)} diff --git a/client/src/components/Input/ModelSelect/MultiSelectPop.tsx b/client/src/components/Input/ModelSelect/MultiSelectPop.tsx index 6732097bd9..f72c84a45b 100644 --- a/client/src/components/Input/ModelSelect/MultiSelectPop.tsx +++ b/client/src/components/Input/ModelSelect/MultiSelectPop.tsx @@ -52,15 +52,13 @@ function MultiSelectPop({ diff --git a/client/src/components/MCP/MCPServerMenuItem.tsx b/client/src/components/MCP/MCPServerMenuItem.tsx index 7fcb773bb9..7fc0d1d28d 100644 --- a/client/src/components/MCP/MCPServerMenuItem.tsx +++ b/client/src/components/MCP/MCPServerMenuItem.tsx @@ -101,7 +101,7 @@ export default function MCPServerMenuItem({ className={cn( 'flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-sm border', isSelected - ? 'border-primary bg-primary text-primary-foreground' + ? 'border-border-xheavy bg-surface-inverted text-text-inverted' : 'border-border-xheavy bg-transparent', )} > diff --git a/client/src/components/MCP/MCPServerStatusIcon.tsx b/client/src/components/MCP/MCPServerStatusIcon.tsx index 30b85812c8..6d02050795 100644 --- a/client/src/components/MCP/MCPServerStatusIcon.tsx +++ b/client/src/components/MCP/MCPServerStatusIcon.tsx @@ -118,7 +118,9 @@ function CompactStatusDot({ serverStatus, isInitializing }: CompactStatusDotProp } if (!serverStatus) { - return
; + return ( +
+ ); } const { connectionState, requiresOAuth } = serverStatus; @@ -145,7 +147,7 @@ function LoadingStatusIcon({ serverName, onCancel, canCancel }: InitializingStat diff --git a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx index e1e5d19d19..18ac7dcb41 100644 --- a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx +++ b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx @@ -145,7 +145,7 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea setUseBackup(!useBackup); setOtpToken(''); }} - className="text-sm text-primary hover:underline" + className="text-sm text-text-primary hover:underline" > {useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')} @@ -182,7 +182,7 @@ const renderDeleteButton = ( diff --git a/client/src/components/Nav/SettingsTabs/Account/TwoFactorPhases/QRPhase.tsx b/client/src/components/Nav/SettingsTabs/Account/TwoFactorPhases/QRPhase.tsx index 12c8a78824..5bce67034e 100644 --- a/client/src/components/Nav/SettingsTabs/Account/TwoFactorPhases/QRPhase.tsx +++ b/client/src/components/Nav/SettingsTabs/Account/TwoFactorPhases/QRPhase.tsx @@ -28,7 +28,7 @@ export const QRPhase: React.FC = ({ secret, otpauthUrl, onNext }) diff --git a/client/src/components/Nav/SettingsTabs/ApiKeys/ApiKeys.tsx b/client/src/components/Nav/SettingsTabs/ApiKeys/ApiKeys.tsx index a857ddd8c3..769daf0476 100644 --- a/client/src/components/Nav/SettingsTabs/ApiKeys/ApiKeys.tsx +++ b/client/src/components/Nav/SettingsTabs/ApiKeys/ApiKeys.tsx @@ -30,7 +30,7 @@ export default function ApiKeys() { diff --git a/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx b/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx index 33cc7cd8fb..9a20fda1c9 100644 --- a/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx +++ b/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx @@ -199,7 +199,7 @@ export default function SharedLinks() { to={`/share/${shareId}`} target="_blank" rel="noopener noreferrer" - className="group flex items-center gap-1 truncate rounded-sm text-link underline decoration-1 underline-offset-2 hover:decoration-2 focus:outline-none focus:ring-2 focus:ring-ring" + className="group flex items-center gap-1 truncate rounded-sm text-link underline decoration-1 underline-offset-2 hover:decoration-2 focus:outline-none focus:ring-2 focus:ring-text-primary" title={title} > {title} @@ -275,7 +275,7 @@ export default function SharedLinks() { href={`/c/${row.original.conversationId}`} target="_blank" rel="noopener noreferrer" - className="flex h-8 w-8 items-center justify-center rounded-md p-0 transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-ring" + className="flex h-8 w-8 items-center justify-center rounded-md p-0 transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-text-primary" aria-label={localize('com_ui_open_source_chat_new_tab_title', { title: row.original.title || localize('com_ui_untitled'), })} @@ -324,7 +324,7 @@ export default function SharedLinks() { {localize('com_nav_shared_links')} diff --git a/client/src/components/Nav/SettingsTabs/General/ArchivedChatsModal.tsx b/client/src/components/Nav/SettingsTabs/General/ArchivedChatsModal.tsx index 0f8c84a3ab..fa0449d326 100644 --- a/client/src/components/Nav/SettingsTabs/General/ArchivedChatsModal.tsx +++ b/client/src/components/Nav/SettingsTabs/General/ArchivedChatsModal.tsx @@ -31,7 +31,7 @@ export function ArchivedChatsModal({ tabIndex={-1} onOpenAutoFocus={handleOpenAutoFocus} title={localize('com_nav_archived_chats')} - className="w-11/12 max-w-[1000px] bg-background text-text-primary shadow-2xl focus:outline-none" + className="w-11/12 max-w-[1000px] bg-surface-primary text-text-primary shadow-2xl focus:outline-none" > {localize('com_nav_archived_chats')} diff --git a/client/src/components/Nav/SettingsTabs/General/ArchivedChatsTable.tsx b/client/src/components/Nav/SettingsTabs/General/ArchivedChatsTable.tsx index 539d83b58b..7e3e0b6136 100644 --- a/client/src/components/Nav/SettingsTabs/General/ArchivedChatsTable.tsx +++ b/client/src/components/Nav/SettingsTabs/General/ArchivedChatsTable.tsx @@ -178,7 +178,7 @@ export default function ArchivedChatsTable({ to={`/c/${conversationId}`} target="_blank" rel="noopener noreferrer" - className="group flex items-center gap-1 truncate rounded-sm text-link underline decoration-1 underline-offset-2 hover:decoration-2 focus:outline-none focus:ring-2 focus:ring-ring" + className="group flex items-center gap-1 truncate rounded-sm text-link underline decoration-1 underline-offset-2 hover:decoration-2 focus:outline-none focus:ring-2 focus:ring-text-primary" title={title} aria-label={localize('com_ui_open_archived_chat_new_tab_title', { title })} > diff --git a/client/src/components/OAuth/OAuthError.tsx b/client/src/components/OAuth/OAuthError.tsx index 3e3206d210..012fa06b74 100644 --- a/client/src/components/OAuth/OAuthError.tsx +++ b/client/src/components/OAuth/OAuthError.tsx @@ -61,7 +61,7 @@ export default function OAuthError() {

{getErrorMessage(error)}

@@ -63,7 +63,7 @@ function ToolItem({ tool, onAddTool, onRemoveTool, isInstalled = false }: ToolIt ) : (
- {error &&
{getErrorMessage(error)}
} + {error && ( +
{getErrorMessage(error)}
+ )} ); } @@ -723,7 +725,7 @@ function SourcesComponent({ messageId, conversationId }: SourcesProps = {}) { containerClassName="flex min-w-full mb-4" tabListClassName="flex items-center mb-2 border-b border-border-light overflow-x-auto" tabPanelClassName="w-full overflow-x-auto scrollbar-none md:mx-0 md:px-0" - tabClassName="flex items-center whitespace-nowrap text-xs font-medium text-token-text-secondary px-1 pt-2 pb-1 border-b-2 border-transparent data-[state=active]:text-text-primary outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" + tabClassName="flex items-center whitespace-nowrap text-xs font-medium text-token-text-secondary px-1 pt-2 pb-1 border-b-2 border-transparent data-[state=active]:text-text-primary outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2" />
); @@ -752,7 +754,7 @@ export default function Sources(props: SourcesProps) { -
+
{formatStackTrace(errorDetails.stack).map(({ number, content }) => (
diff --git a/client/src/routes/Search.tsx b/client/src/routes/Search.tsx index b4db28c651..8f5962f0bc 100644 --- a/client/src/routes/Search.tsx +++ b/client/src/routes/Search.tsx @@ -96,7 +96,7 @@ export default function Search() {
{(messages && messages.length === 0) || messages == null ? (
-
+
{localize('com_ui_nothing_found')}
diff --git a/client/src/style.css b/client/src/style.css index 8dafa0008e..3c3b4b9a9b 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -133,24 +133,17 @@ html { --status-neutral: var(--gray-600); --status-neutral-subtle: var(--gray-100); --status-neutral-border: var(--gray-300); - /* These are test styles */ + --surface-inverted: var(--gray-850); + --surface-inverted-hover: var(--gray-700); + --text-inverted: var(--white); + --surface-fixed: var(--white); + --surface-fixed-hover: var(--gray-100); + --text-fixed: var(--gray-800); + /* Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration) */ --background: 0 0% 100%; - --foreground: 0 0% 3.9%; - --card: 0 0% 100%; - --card-foreground: 0 0% 3.9%; --primary: 0 0% 9%; --primary-foreground: 0 0% 98%; - --secondary: 0 0% 96.1%; - --secondary-foreground: 0 0% 9%; - --muted: 0 0% 96.1%; - --muted-foreground: 0 0% 45.1%; - --accent: 0 0% 96.1%; - --accent-foreground: 0 0% 9%; - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 0 0% 98%; - --border: 0 0% 89.8%; - --input: 0 0% 89.8%; --ring: 0 0% 3.9%; --radius: 0.5rem; --chart-1: 12 76% 61%; @@ -215,24 +208,17 @@ html { --status-neutral: var(--gray-300); --status-neutral-subtle: var(--gray-800); --status-neutral-border: var(--gray-700); - /* These are test styles */ + --surface-inverted: var(--white); + --surface-inverted-hover: var(--gray-100); + --text-inverted: var(--gray-850); + --surface-fixed: var(--white); + --surface-fixed-hover: var(--gray-100); + --text-fixed: var(--gray-800); + /* Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration) */ --background: 0 0% 7%; - --foreground: 0 0% 98%; - --card: 0 0% 3.9%; - --card-foreground: 0 0% 98%; --primary: 0 0% 98%; --primary-foreground: 0 0% 9%; - --secondary: 0 0% 14.9%; - --secondary-foreground: 0 0% 98%; - --muted: 0 0% 14.9%; - --muted-foreground: 0 0% 63.9%; - --accent: 0 0% 14.9%; - --accent-foreground: 0 0% 98%; - --destructive: 0 62.8% 40.6%; - --destructive-foreground: 0 0% 98%; - --border: 0 0% 14.9%; - --input: 0 0% 14.9%; --ring: 0 0% 83.1%; --chart-1: 220 70% 50%; --chart-2: 160 60% 45%; diff --git a/client/src/utils/buildTree.ts b/client/src/utils/buildTree.ts index 836e87b509..36e4cc1313 100644 --- a/client/src/utils/buildTree.ts +++ b/client/src/utils/buildTree.ts @@ -1,9 +1,9 @@ import type { TMessage } from 'librechat-data-provider'; const even = - 'w-full border-b border-black/10 dark:border-gray-800/50 text-gray-800 bg-white dark:text-gray-200 group dark:bg-gray-800 hover:bg-gray-200/25 hover:text-gray-700 dark:hover:bg-gray-800 dark:hover:text-gray-200'; + 'w-full border-b border-border-light text-text-primary bg-surface-secondary group hover:bg-surface-hover hover:text-text-primary'; const odd = - 'w-full border-b border-black/10 bg-gray-50 dark:border-gray-800/50 text-gray-800 dark:text-gray-200 group bg-gray-200 dark:bg-gray-700 hover:bg-gray-200/40 hover:text-gray-700 dark:hover:bg-gray-800 dark:hover:text-gray-200'; + 'w-full border-b border-border-light text-text-primary group bg-surface-active-alt hover:bg-surface-hover hover:text-text-primary'; export function groupIntoList({ messages, diff --git a/client/src/utils/index.ts b/client/src/utils/index.ts index ea322b047f..f961066acb 100644 --- a/client/src/utils/index.ts +++ b/client/src/utils/index.ts @@ -82,16 +82,16 @@ export const removeFocusRings = 'focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'; export const cardStyle = - 'transition-colors rounded-md min-w-[75px] border font-normal bg-white hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-700 dark:bg-gray-800 text-black dark:text-gray-600 focus:outline-none data-[state=open]:bg-gray-50 dark:data-[state=open]:bg-gray-700'; + 'transition-colors rounded-md min-w-[75px] border border-border-medium font-normal bg-surface-secondary hover:bg-surface-hover text-text-primary focus:outline-none data-[state=open]:bg-surface-hover'; export const defaultTextProps = - 'rounded-md border border-gray-200 focus:border-gray-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:focus:bg-gray-600 dark:focus:border-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:outline-none'; + 'rounded-md border border-border-light focus:border-border-heavy focus:bg-surface-secondary bg-transparent text-sm text-text-primary shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-text-primary focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50'; export const optionText = - 'p-0 shadow-none text-right pr-1 h-8 border-transparent hover:bg-gray-800/10 dark:hover:bg-white/10 dark:focus:bg-white/10 transition-colors'; + 'p-0 shadow-none text-right pr-1 h-8 border-transparent hover:bg-surface-hover transition-colors'; export const defaultTextPropsLabel = - 'rounded-md border border-gray-300 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.10)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-600 dark:focus:outline-none'; + 'rounded-md border border-border-medium bg-transparent text-sm text-text-primary shadow-[0_0_10px_rgba(0,0,0,0.10)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50'; export function capitalizeFirstLetter(string: string) { return string.charAt(0).toUpperCase() + string.slice(1); diff --git a/packages/client/src/components/Accordion.tsx b/packages/client/src/components/Accordion.tsx index b013d0378f..698be0be67 100644 --- a/packages/client/src/components/Accordion.tsx +++ b/packages/client/src/components/Accordion.tsx @@ -36,7 +36,7 @@ const AccordionTrigger: React.ForwardRefExoticComponent< {...props} > {children} - + )); diff --git a/packages/client/src/components/AlertDialog.tsx b/packages/client/src/components/AlertDialog.tsx index 3de8f59242..8aae1b5c1a 100644 --- a/packages/client/src/components/AlertDialog.tsx +++ b/packages/client/src/components/AlertDialog.tsx @@ -47,8 +47,7 @@ const AlertDialogContent: React.ForwardRefExoticComponent< (({ className = '', ...props }, ref) => ( )); @@ -106,7 +105,7 @@ const AlertDialogDescription: React.ForwardRefExoticComponent< >(({ className = '', ...props }, ref) => ( )); @@ -125,7 +124,7 @@ const AlertDialogAction: React.ForwardRefExoticComponent<
@@ -40,7 +40,7 @@ const AnimatedSearchInput = ({ onChange={onChange} placeholder={placeholder} aria-label={localize('com_ui_search')} - className={`peer relative z-20 w-full rounded-lg bg-surface-secondary py-2 pl-10 outline-none backdrop-blur-sm transition-all duration-500 ease-in-out placeholder:text-gray-500 focus:ring-ring`} + className={`peer relative z-20 w-full rounded-lg bg-surface-secondary py-2 pl-10 outline-none backdrop-blur-sm transition-all duration-500 ease-in-out placeholder:text-text-secondary focus:ring-text-primary`} /> {/* Gradient overlay */} diff --git a/packages/client/src/components/Breadcrumb.tsx b/packages/client/src/components/Breadcrumb.tsx index 09e0e5e9af..0629254313 100644 --- a/packages/client/src/components/Breadcrumb.tsx +++ b/packages/client/src/components/Breadcrumb.tsx @@ -24,7 +24,7 @@ const BreadcrumbList: React.ForwardRefExoticComponent<
    ); @@ -78,7 +78,7 @@ const BreadcrumbPage: React.ForwardRefExoticComponent< role="link" aria-disabled="true" aria-current="page" - className={cn('font-normal text-foreground', className)} + className={cn('font-normal text-text-primary', className)} {...props} /> ), diff --git a/packages/client/src/components/Button.tsx b/packages/client/src/components/Button.tsx index 53150bde5a..1bb4248655 100644 --- a/packages/client/src/components/Button.tsx +++ b/packages/client/src/components/Button.tsx @@ -21,18 +21,17 @@ const buttonVariants: ( } & ClassProp) | undefined, ) => string = cva( - 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', + 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium ring-offset-surface-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', { variants: { variant: { - default: 'bg-primary text-primary-foreground hover:bg-primary/90', - destructive: - 'bg-surface-destructive text-destructive-foreground hover:bg-surface-destructive-hover', + default: 'bg-surface-inverted text-text-inverted hover:bg-surface-inverted-hover', + destructive: 'bg-surface-destructive text-white hover:bg-surface-destructive-hover', outline: - 'text-text-primary border border-border-light bg-transparent hover:bg-accent hover:text-accent-foreground', - secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80', - ghost: 'hover:bg-surface-hover hover:text-accent-foreground', - link: 'text-primary underline-offset-4 hover:underline', + 'text-text-primary border border-border-light bg-transparent hover:bg-surface-hover hover:text-text-primary', + secondary: 'bg-surface-secondary text-text-primary hover:bg-surface-hover', + ghost: 'hover:bg-surface-hover hover:text-text-primary', + link: 'text-text-primary underline-offset-4 hover:underline', // hardcoded text color because of WCAG contrast issues (text-white) submit: 'bg-surface-submit text-white hover:bg-surface-submit-hover', }, diff --git a/packages/client/src/components/Checkbox.tsx b/packages/client/src/components/Checkbox.tsx index b4b45c221c..90369b45c6 100644 --- a/packages/client/src/components/Checkbox.tsx +++ b/packages/client/src/components/Checkbox.tsx @@ -27,7 +27,7 @@ const Checkbox: React.ForwardRefExoticComponent< span]:w-auto [&>svg]:hidden' : '', - 'bg-white text-black hover:bg-gray-50 focus-visible:ring-2 focus-visible:ring-gray-500 dark:bg-gray-850 dark:text-white', + 'bg-surface-secondary text-text-primary hover:bg-surface-hover focus-visible:ring-2 focus-visible:ring-text-primary', )} > @@ -105,18 +105,18 @@ export default function ComboboxComponent({ aria-label={ariaLabel + 's'} position="popper" className={cn( - 'bg-popover text-popover-foreground relative z-40 max-h-[52vh] min-w-[8rem] overflow-hidden rounded-md border border-gray-200 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-gray-600', + 'relative z-40 max-h-[52vh] min-w-[8rem] overflow-hidden rounded-md border border-border-light bg-surface-secondary text-text-primary shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', - 'bg-white dark:bg-gray-700', + 'bg-surface-secondary', )} > -
    - +
    +
    @@ -141,8 +141,8 @@ export default function ComboboxComponent({ { @@ -156,7 +156,7 @@ export default function ComboboxComponent({ -
    +
    {icon && icon}
    diff --git a/packages/client/src/components/DataTable.tsx b/packages/client/src/components/DataTable.tsx index 9b3712aa81..b9b06a5e6b 100644 --- a/packages/client/src/components/DataTable.tsx +++ b/packages/client/src/components/DataTable.tsx @@ -198,7 +198,7 @@ const DeleteButton = memo( ) : ( <> - + {!isSmallScreen && Delete} )} @@ -429,7 +429,7 @@ export default function DataTable({
    , TValue>({ return (
    @@ -98,7 +98,7 @@ class DataTableErrorBoundaryInner extends Component<
    {import.meta.env.MODE === 'development' && this.state.error && ( -
    +
    {this.props.localize('com_ui_error_details')} diff --git a/packages/client/src/components/Dialog.tsx b/packages/client/src/components/Dialog.tsx index c5b97cc2e6..832234227f 100644 --- a/packages/client/src/components/Dialog.tsx +++ b/packages/client/src/components/Dialog.tsx @@ -60,10 +60,9 @@ const DialogContent: React.ForwardRefExoticComponent< {children} {showCloseButton && ( - -