@nextclaw/ui 0.14.2 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/assets/{api-a14tR_z1.js → api-BP_8IaxB.js} +3 -3
  3. package/dist/assets/{channels-list-page-CFGkm4DT.js → channels-list-page-DEh5Jjqx.js} +1 -1
  4. package/dist/assets/chat-page-BRB0N5WW.js +105 -0
  5. package/dist/assets/config-split-page-CRhlZ_pH.js +1 -0
  6. package/dist/assets/{confirm-dialog-ClH_Ec7n.js → confirm-dialog-DsivFJ4r.js} +2 -2
  7. package/dist/assets/{desktop-update-config-DPNDnVpk.js → desktop-update-config-B0w9p2ep.js} +1 -1
  8. package/dist/assets/{dist-BtCS2Ucq.js → dist-CikkhOlq.js} +1 -1
  9. package/dist/assets/{dist-CLGGLm8b.js → dist-PVA_xL1D.js} +1 -1
  10. package/dist/assets/doc-browser-BoNJ7-tE.js +1 -0
  11. package/dist/assets/doc-browser-CdJ_d4ik.js +1 -0
  12. package/dist/assets/{doc-browser-context-D4JwMMxK.js → doc-browser-context-MTw4EvKd.js} +1 -1
  13. package/dist/assets/{ellipsis-CtJXjIol.js → ellipsis-y6vDtq4M.js} +1 -1
  14. package/dist/assets/{external-link-CdJiG13p.js → external-link-DVJIQf_G.js} +1 -1
  15. package/dist/assets/index-BiE-K8-q.css +1 -0
  16. package/dist/assets/index-D9BAE_L_.js +105 -0
  17. package/dist/assets/{mcp-marketplace-page-BU0kIjhR.js → mcp-marketplace-page-B1SZNY5m.js} +1 -1
  18. package/dist/assets/mcp-marketplace-page-Cq_Tw42T.js +1 -0
  19. package/dist/assets/{model-config-page-D6hYXROd.js → model-config-page-DotaTUHb.js} +1 -1
  20. package/dist/assets/plus-BbZqquJe.js +1 -0
  21. package/dist/assets/{provider-scoped-model-input-DAX2HgmR.js → provider-scoped-model-input-DsFRuWJH.js} +1 -1
  22. package/dist/assets/providers-config-page-DW4tQSLN.js +1 -0
  23. package/dist/assets/{react-C6cZgP44.js → react-VNqT5Zp7.js} +1 -1
  24. package/dist/assets/remote-B8TiUfwW.js +1 -0
  25. package/dist/assets/rotate-cw-DjHDTkCv.js +1 -0
  26. package/dist/assets/{runtime-config-page-C5xKaV3i.js → runtime-config-page-S6ErRHR8.js} +1 -1
  27. package/dist/assets/{save-DKA0x4zk.js → save-BOJ477H-.js} +1 -1
  28. package/dist/assets/{search-BNlcoj5c.js → search-BEti5beA.js} +1 -1
  29. package/dist/assets/{search-config-page-Cq9uJ-N8.js → search-config-page-DGj5am03.js} +1 -1
  30. package/dist/assets/{secrets-config-page-CxSbZLBo.js → secrets-config-page--IzrIOid.js} +1 -1
  31. package/dist/assets/{select-CvTlDZTQ.js → select-hoj8dK4K.js} +2 -2
  32. package/dist/assets/{tag-chip-8ffF2y2C.js → tag-chip-T8-h-die.js} +1 -1
  33. package/dist/assets/{use-config-DmT0o1gv.js → use-config-CjRV2hwL.js} +1 -1
  34. package/dist/assets/x-D9PXs_xP.js +1 -0
  35. package/dist/index.html +69 -19
  36. package/index.html +55 -5
  37. package/package.json +7 -7
  38. package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +3 -3
  39. package/src/app/components/layout/header.tsx +3 -3
  40. package/src/app/components/layout/page-layout.tsx +2 -2
  41. package/src/app/components/layout/runtime-status-entry.tsx +7 -7
  42. package/src/app/components/layout/sidebar-items.tsx +10 -10
  43. package/src/app/components/layout/sidebar-rail.styles.ts +2 -2
  44. package/src/app/components/layout/sidebar.tsx +6 -6
  45. package/src/app/styles/design-system.css +388 -26
  46. package/src/app/test/vitest-setup.ts +31 -0
  47. package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +3 -3
  48. package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +4 -2
  49. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
  50. package/src/features/chat/components/conversation/chat-conversation-header.tsx +7 -6
  51. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +1 -1
  52. package/src/features/chat/components/conversation/chat-conversation-skeleton.tsx +13 -13
  53. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +2 -2
  54. package/src/features/chat/components/layout/chat-page-shell.tsx +1 -1
  55. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +3 -3
  56. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +14 -14
  57. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +15 -15
  58. package/src/features/chat/components/layout/chat-sidebar.tsx +3 -3
  59. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +225 -0
  60. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +199 -0
  61. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +28 -9
  62. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +18 -6
  63. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +3 -13
  64. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +19 -3
  65. package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +7 -7
  66. package/src/features/chat/features/message/components/chat-message-list.container.tsx +6 -6
  67. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +5 -5
  68. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +4 -4
  69. package/src/features/chat/features/session/components/session-context-icon.tsx +2 -2
  70. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-project-badge.test.tsx +2 -2
  71. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +1 -1
  72. package/src/features/chat/features/session/components/session-header/chat-session-header-menu-item.tsx +1 -1
  73. package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
  74. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
  75. package/src/features/chat/features/session/components/session-run-badge.tsx +1 -1
  76. package/src/features/chat/features/session-type/hooks/use-chat-session-type-state.ts +10 -2
  77. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +0 -7
  78. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +3 -3
  79. package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +4 -4
  80. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +14 -19
  81. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
  82. package/src/features/chat/features/welcome/components/chat-welcome.tsx +4 -4
  83. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +6 -8
  84. package/src/features/chat/features/welcome/utils/chat-welcome-project-options.utils.ts +1 -16
  85. package/src/features/panel-apps/components/panel-app-list-item.tsx +8 -8
  86. package/src/features/panel-apps/components/panel-app-toolbar.tsx +4 -4
  87. package/src/features/panel-apps/components/panel-apps-list.tsx +20 -20
  88. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +70 -6
  89. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +10 -5
  90. package/src/features/service-apps/components/service-action-authorization-dialog.tsx +8 -8
  91. package/src/features/service-apps/components/service-apps-panel.tsx +24 -24
  92. package/src/features/settings/components/config/provider-advanced-settings-section.tsx +5 -5
  93. package/src/features/settings/components/config/provider-auth-section.tsx +7 -7
  94. package/src/features/settings/components/config/provider-form.tsx +10 -10
  95. package/src/features/settings/components/config/provider-models-section.tsx +16 -16
  96. package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
  97. package/src/features/settings/pages/providers-config-page.tsx +17 -17
  98. package/src/shared/components/config-split-page.tsx +11 -11
  99. package/src/shared/components/doc-browser/doc-browser-home-page.tsx +2 -2
  100. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +4 -4
  101. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +4 -4
  102. package/src/shared/components/doc-browser/doc-browser.tsx +3 -3
  103. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +1 -1
  104. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  105. package/src/shared/components/ui/button.tsx +4 -4
  106. package/src/shared/components/ui/card.tsx +4 -4
  107. package/src/shared/components/ui/dialog.tsx +5 -5
  108. package/src/shared/components/ui/input.tsx +1 -1
  109. package/src/shared/components/ui/label.tsx +1 -1
  110. package/src/shared/components/ui/popover.tsx +1 -1
  111. package/src/shared/components/ui/select.tsx +3 -3
  112. package/src/shared/components/ui/switch.tsx +3 -3
  113. package/src/shared/components/ui/tabs.tsx +4 -4
  114. package/src/shared/components/ui/textarea.tsx +1 -1
  115. package/src/shared/lib/i18n/locales/en-US/core.json +7 -2
  116. package/src/shared/lib/i18n/locales/zh-CN/core.json +7 -2
  117. package/src/shared/lib/theme/index.ts +94 -52
  118. package/dist/assets/chat-page-CEdavJXc.js +0 -105
  119. package/dist/assets/config-split-page-B5b9B0uE.js +0 -1
  120. package/dist/assets/doc-browser-5nMWYKBD.js +0 -1
  121. package/dist/assets/doc-browser-BJRLhztv.js +0 -1
  122. package/dist/assets/index-BDN1zzMQ.js +0 -105
  123. package/dist/assets/index-g3uSZXoc.css +0 -1
  124. package/dist/assets/mcp-marketplace-page-sMNFSq_T.js +0 -1
  125. package/dist/assets/plus-DPjb0piO.js +0 -1
  126. package/dist/assets/providers-config-page-BzAeaACA.js +0 -1
  127. package/dist/assets/remote-B0G80uPr.js +0 -1
  128. package/dist/assets/rotate-cw-DnEB1Rju.js +0 -1
  129. package/dist/assets/x-BiSSpgqB.js +0 -1
@@ -62,7 +62,7 @@ export function ServiceAppsPanel({
62
62
 
63
63
  if (serviceApps.isLoading || serviceActions.isLoading || serviceActionGrants.isLoading) {
64
64
  return (
65
- <div className="flex h-full items-center justify-center text-sm text-gray-500">
65
+ <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
66
66
  {t('serviceAppsLoading')}
67
67
  </div>
68
68
  );
@@ -90,13 +90,13 @@ export function ServiceAppsPanel({
90
90
  };
91
91
 
92
92
  return (
93
- <div className="flex h-full min-h-0 flex-col bg-white">
94
- <div className="flex items-center justify-between gap-2 border-b border-gray-100 px-4 py-3">
93
+ <div className="flex h-full min-h-0 flex-col bg-card text-card-foreground">
94
+ <div className="flex items-center justify-between gap-2 border-b border-border/70 px-4 py-3">
95
95
  <div className="flex min-w-0 items-center gap-2">
96
96
  {headerContent ?? (
97
97
  <>
98
98
  <Server className="h-4 w-4 text-primary" />
99
- <div className="truncate text-sm font-semibold text-gray-900">{t('serviceAppsTitle')}</div>
99
+ <div className="truncate text-sm font-semibold text-foreground">{t('serviceAppsTitle')}</div>
100
100
  </>
101
101
  )}
102
102
  </div>
@@ -110,7 +110,7 @@ export function ServiceAppsPanel({
110
110
  </div>
111
111
 
112
112
  {apps.length === 0 ? (
113
- <div className="flex flex-1 items-center justify-center px-6 text-center text-sm text-gray-500">
113
+ <div className="flex flex-1 items-center justify-center px-6 text-center text-sm text-muted-foreground">
114
114
  {t('serviceAppsEmpty')}
115
115
  </div>
116
116
  ) : (
@@ -172,15 +172,15 @@ function ServiceAppCard({
172
172
 
173
173
  return (
174
174
  <TooltipProvider delayDuration={250}>
175
- <section className="rounded-lg border border-gray-200 bg-white p-3">
175
+ <section className="rounded-lg border border-border bg-card p-3">
176
176
  <div className="flex items-start justify-between gap-3">
177
177
  <div className="min-w-0">
178
178
  <div className="flex items-center gap-2">
179
- <div className="truncate text-sm font-semibold text-gray-900">{app.title}</div>
179
+ <div className="truncate text-sm font-semibold text-foreground">{app.title}</div>
180
180
  <ServiceAppStatusBadge status={app.status} />
181
181
  </div>
182
182
  {app.description ? (
183
- <div className="mt-1 line-clamp-2 text-xs text-gray-500">{app.description}</div>
183
+ <div className="mt-1 line-clamp-2 text-xs text-muted-foreground">{app.description}</div>
184
184
  ) : null}
185
185
  {app.lastError ? (
186
186
  <div className="mt-2 rounded bg-rose-50 px-2 py-1 text-xs text-rose-700">{app.lastError}</div>
@@ -207,7 +207,7 @@ function ServiceAppCard({
207
207
  <PopoverTrigger asChild>
208
208
  <button
209
209
  type="button"
210
- className="rounded-md p-1.5 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-800 disabled:opacity-50"
210
+ className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:opacity-50"
211
211
  aria-label={t('serviceAppsMoreActions')}
212
212
  disabled={deletePending}
213
213
  >
@@ -309,7 +309,7 @@ function getServiceAppStatusView(status: ServiceAppStatus): {
309
309
  };
310
310
  case 'stopped':
311
311
  return {
312
- className: 'bg-gray-100 text-gray-600',
312
+ className: 'bg-muted text-muted-foreground',
313
313
  icon: PauseCircle,
314
314
  label: t('serviceAppsStatus_stopped'),
315
315
  tooltip: t('serviceAppsStatusHint_stopped'),
@@ -317,7 +317,7 @@ function getServiceAppStatusView(status: ServiceAppStatus): {
317
317
  case 'idle':
318
318
  default:
319
319
  return {
320
- className: 'bg-slate-100 text-slate-600',
320
+ className: 'bg-muted text-muted-foreground',
321
321
  icon: CircleDashed,
322
322
  label: t('serviceAppsStatus_idle'),
323
323
  tooltip: t('serviceAppsStatusHint_idle'),
@@ -345,7 +345,7 @@ function ServiceAppIconButton({
345
345
  type="button"
346
346
  onClick={onClick}
347
347
  disabled={disabled}
348
- className="rounded-md p-1.5 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-800 disabled:cursor-not-allowed disabled:text-gray-300 disabled:opacity-60 disabled:hover:bg-transparent"
348
+ className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:text-muted-foreground/40 disabled:opacity-60 disabled:hover:bg-transparent"
349
349
  aria-label={label}
350
350
  >
351
351
  <Icon className="h-3.5 w-3.5" />
@@ -374,7 +374,7 @@ function ServiceAppMenuItem({
374
374
  type="button"
375
375
  className={cn(
376
376
  'flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50',
377
- destructive ? 'text-destructive hover:bg-destructive/10' : 'text-gray-700 hover:bg-gray-100',
377
+ destructive ? 'text-destructive hover:bg-destructive/10' : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',
378
378
  )}
379
379
  disabled={disabled}
380
380
  onClick={onClick}
@@ -403,7 +403,7 @@ function ServiceAppDiagnostics({ app }: { app: ServiceAppRecordView }) {
403
403
  }
404
404
 
405
405
  return (
406
- <dl className="mt-3 grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-2 gap-y-1 border-t border-gray-100 pt-2 text-[11px]">
406
+ <dl className="mt-3 grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-2 gap-y-1 border-t border-border/70 pt-2 text-[11px]">
407
407
  {rows.map((row) => (
408
408
  <ServiceAppDiagnosticRow key={row.label} label={row.label} value={row.value} />
409
409
  ))}
@@ -420,8 +420,8 @@ function ServiceAppDiagnosticRow({
420
420
  }) {
421
421
  return (
422
422
  <>
423
- <dt className="text-gray-400">{label}</dt>
424
- <dd className="min-w-0 truncate font-mono text-gray-500" title={value}>
423
+ <dt className="text-muted-foreground/70">{label}</dt>
424
+ <dd className="min-w-0 truncate font-mono text-muted-foreground" title={value}>
425
425
  {value}
426
426
  </dd>
427
427
  </>
@@ -438,36 +438,36 @@ function ServiceActionRow({
438
438
  onRevoke: (grant: ServiceActionGrantView) => void;
439
439
  }) {
440
440
  return (
441
- <div className="rounded bg-gray-50 px-2 py-1.5">
441
+ <div className="rounded bg-muted/60 px-2 py-1.5">
442
442
  <div className="flex items-center justify-between gap-2">
443
443
  <div className="flex min-w-0 items-center gap-2">
444
- <Wrench className="h-3.5 w-3.5 shrink-0 text-gray-400" />
444
+ <Wrench className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70" />
445
445
  <div className="min-w-0">
446
- <div className="truncate text-xs font-medium text-gray-800">{action.title ?? action.name}</div>
446
+ <div className="truncate text-xs font-medium text-foreground">{action.title ?? action.name}</div>
447
447
  {action.description ? (
448
- <div className="truncate text-[11px] text-gray-500">{action.description}</div>
448
+ <div className="truncate text-[11px] text-muted-foreground">{action.description}</div>
449
449
  ) : null}
450
450
  </div>
451
451
  </div>
452
452
  <div className="flex shrink-0 items-center gap-1">
453
453
  {action.runtimeState ? (
454
- <span className="rounded bg-white px-1.5 py-0.5 text-[11px] text-gray-600">
454
+ <span className="rounded bg-card px-1.5 py-0.5 text-[11px] text-muted-foreground">
455
455
  {t(`serviceAppsRuntimeState_${action.runtimeState}`)}
456
456
  </span>
457
457
  ) : null}
458
- <span className="rounded bg-white px-1.5 py-0.5 text-[11px] text-gray-600">{action.risk}</span>
458
+ <span className="rounded bg-card px-1.5 py-0.5 text-[11px] text-muted-foreground">{action.risk}</span>
459
459
  </div>
460
460
  </div>
461
461
  {grants.map((grant) => (
462
462
  <div key={`${grant.caller.surface}:${grant.caller.appId}:${grant.actionId}`} className="mt-1 flex items-center justify-between gap-2 pl-5">
463
- <div className="flex min-w-0 items-center gap-1.5 text-[11px] text-gray-500">
463
+ <div className="flex min-w-0 items-center gap-1.5 text-[11px] text-muted-foreground">
464
464
  <ShieldCheck className="h-3 w-3 shrink-0 text-emerald-500" />
465
465
  <span className="truncate">{t('serviceAppsGrantedTo')} {grant.caller.appId}</span>
466
466
  </div>
467
467
  <button
468
468
  type="button"
469
469
  onClick={() => onRevoke(grant)}
470
- className="rounded-md p-1 text-gray-400 transition-colors hover:bg-white hover:text-rose-600"
470
+ className="rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-background hover:text-rose-600"
471
471
  title={t('serviceAppsRevokeGrant')}
472
472
  aria-label={t('serviceAppsRevokeGrant')}
473
473
  >
@@ -24,11 +24,11 @@ export function ProviderAdvancedSettingsSection(props: ProviderAdvancedSettingsS
24
24
  } = props;
25
25
 
26
26
  return (
27
- <div className="border-t border-gray-100 pt-4">
27
+ <div className="border-t border-border/70 pt-4">
28
28
  <button
29
29
  type="button"
30
30
  onClick={() => onShowAdvancedChange(!showAdvanced)}
31
- className="flex w-full items-center justify-between text-sm text-gray-600 transition-colors hover:text-gray-900"
31
+ className="flex w-full items-center justify-between text-sm text-muted-foreground transition-colors hover:text-foreground"
32
32
  >
33
33
  <span className="flex items-center gap-1.5">
34
34
  <Settings2 className="h-3.5 w-3.5" />
@@ -41,7 +41,7 @@ export function ProviderAdvancedSettingsSection(props: ProviderAdvancedSettingsS
41
41
  <div className="mt-4 space-y-5">
42
42
  {supportsWireApi ? (
43
43
  <div className="space-y-2">
44
- <Label htmlFor="wireApi" className="text-sm font-medium text-gray-900">
44
+ <Label htmlFor="wireApi" className="text-sm font-medium text-foreground">
45
45
  {wireApiLabel}
46
46
  </Label>
47
47
  {shouldUseWireApiPills ? (
@@ -68,9 +68,9 @@ export function ProviderAdvancedSettingsSection(props: ProviderAdvancedSettingsS
68
68
  ) : null}
69
69
 
70
70
  <div className="space-y-2">
71
- <Label className="text-sm font-medium text-gray-900">{extraHeadersLabel}</Label>
71
+ <Label className="text-sm font-medium text-foreground">{extraHeadersLabel}</Label>
72
72
  <KeyValueEditor value={extraHeaders} onChange={onExtraHeadersChange} />
73
- <p className="text-xs text-gray-500">{t('providerExtraHeadersHelpShort')}</p>
73
+ <p className="text-xs text-muted-foreground">{t('providerExtraHeadersHelpShort')}</p>
74
74
  </div>
75
75
  </div>
76
76
  ) : null}
@@ -29,13 +29,13 @@ export function ProviderAuthSection(props: ProviderAuthSectionProps) {
29
29
 
30
30
  return (
31
31
  <div className="space-y-2 rounded-xl border border-primary/20 bg-primary-50/50 p-3">
32
- <Label className="text-sm font-medium text-gray-900">
32
+ <Label className="text-sm font-medium text-foreground">
33
33
  {providerAuth.displayName || t('providerAuthSectionTitle')}
34
34
  </Label>
35
- {providerAuthNote ? <p className="text-xs text-gray-600">{providerAuthNote}</p> : null}
35
+ {providerAuthNote ? <p className="text-xs text-muted-foreground">{providerAuthNote}</p> : null}
36
36
  {providerAuthMethodsCount > 1 ? (
37
37
  <div className="space-y-2">
38
- <Label className="text-xs font-medium text-gray-700">{t('providerAuthMethodLabel')}</Label>
38
+ <Label className="text-xs font-medium text-foreground">{t('providerAuthMethodLabel')}</Label>
39
39
  {shouldUseAuthMethodPills ? (
40
40
  <ProviderPillSelector
41
41
  value={resolvedAuthMethodId}
@@ -44,7 +44,7 @@ export function ProviderAuthSection(props: ProviderAuthSectionProps) {
44
44
  />
45
45
  ) : (
46
46
  <Select value={resolvedAuthMethodId} onValueChange={onAuthMethodChange}>
47
- <SelectTrigger className="h-8 rounded-lg bg-white">
47
+ <SelectTrigger className="h-8 rounded-lg">
48
48
  <SelectValue placeholder={t('providerAuthMethodPlaceholder')} />
49
49
  </SelectTrigger>
50
50
  <SelectContent>
@@ -56,7 +56,7 @@ export function ProviderAuthSection(props: ProviderAuthSectionProps) {
56
56
  </SelectContent>
57
57
  </Select>
58
58
  )}
59
- {selectedAuthMethodHint ? <p className="text-xs text-gray-500">{selectedAuthMethodHint}</p> : null}
59
+ {selectedAuthMethodHint ? <p className="text-xs text-muted-foreground">{selectedAuthMethodHint}</p> : null}
60
60
  </div>
61
61
  ) : null}
62
62
  <div className="flex flex-wrap items-center gap-2">
@@ -85,12 +85,12 @@ export function ProviderAuthSection(props: ProviderAuthSectionProps) {
85
85
  </Button>
86
86
  ) : null}
87
87
  {authSessionId ? (
88
- <span className="text-xs text-gray-500">
88
+ <span className="text-xs text-muted-foreground">
89
89
  {t('providerAuthSessionLabel')}: {authSessionId.slice(0, 8)}…
90
90
  </span>
91
91
  ) : null}
92
92
  </div>
93
- {authStatusMessage ? <p className="text-xs text-gray-600">{authStatusMessage}</p> : null}
93
+ {authStatusMessage ? <p className="text-xs text-muted-foreground">{authStatusMessage}</p> : null}
94
94
  </div>
95
95
  );
96
96
  }
@@ -329,8 +329,8 @@ export function ProviderForm({ providerName, onProviderDeleted }: ProviderFormPr
329
329
  return (
330
330
  <ConfigSplitEmptyPane>
331
331
  <div>
332
- <h3 className='text-base font-semibold text-gray-900'>{t('providersSelectTitle')}</h3>
333
- <p className='mt-2 text-sm text-gray-500'>{t('providersSelectDescription')}</p>
332
+ <h3 className='text-base font-semibold text-foreground'>{t('providersSelectTitle')}</h3>
333
+ <p className='mt-2 text-sm text-muted-foreground'>{t('providersSelectDescription')}</p>
334
334
  </div>
335
335
  </ConfigSplitEmptyPane>
336
336
  );
@@ -437,13 +437,13 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
437
437
  <ConfigSplitDetailPane>
438
438
  <ConfigSplitPaneHeader className='px-6 py-4'>
439
439
  <div className='flex items-center justify-between'>
440
- <h3 className='truncate text-lg font-semibold text-gray-900'>{providerTitle}</h3>
440
+ <h3 className='truncate text-lg font-semibold text-foreground'>{providerTitle}</h3>
441
441
  <div className='flex items-center gap-3'>
442
442
  <button
443
443
  type='button'
444
444
  onClick={onDeleteProvider}
445
445
  disabled={isDeletePending}
446
- className='text-gray-400 transition-colors hover:text-red-500'
446
+ className='text-muted-foreground/70 transition-colors hover:text-red-500'
447
447
  title={t('providerDelete')}
448
448
  >
449
449
  <Trash2 className='h-4 w-4' />
@@ -456,7 +456,7 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
456
456
  <form onSubmit={onSubmit} className='flex min-h-0 flex-1 flex-col'>
457
457
  <ConfigSplitPaneBody className='space-y-5 px-6 py-5'>
458
458
  <div className='space-y-2'>
459
- <Label htmlFor='providerDisplayName' className='text-sm font-medium text-gray-900'>
459
+ <Label htmlFor='providerDisplayName' className='text-sm font-medium text-foreground'>
460
460
  {t('providerDisplayName')}
461
461
  </Label>
462
462
  <Input
@@ -467,11 +467,11 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
467
467
  placeholder={context.defaultDisplayName || t('providerDisplayNamePlaceholder')}
468
468
  className='rounded-xl'
469
469
  />
470
- <p className='text-xs text-gray-500'>{t('providerDisplayNameHelpShort')}</p>
470
+ <p className='text-xs text-muted-foreground'>{t('providerDisplayNameHelpShort')}</p>
471
471
  </div>
472
472
 
473
473
  <div className='space-y-2'>
474
- <Label htmlFor='apiKey' className='text-sm font-medium text-gray-900'>
474
+ <Label htmlFor='apiKey' className='text-sm font-medium text-foreground'>
475
475
  {context.apiKeyHint?.label ?? t('apiKey')}
476
476
  </Label>
477
477
  <MaskedInput
@@ -482,7 +482,7 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
482
482
  placeholder={context.apiKeyHint?.placeholder ?? t('enterApiKey')}
483
483
  className='rounded-xl'
484
484
  />
485
- <p className='text-xs text-gray-500'>{t('leaveBlankToKeepUnchanged')}</p>
485
+ <p className='text-xs text-muted-foreground'>{t('leaveBlankToKeepUnchanged')}</p>
486
486
  </div>
487
487
 
488
488
  <ProviderAuthSection
@@ -503,7 +503,7 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
503
503
  />
504
504
 
505
505
  <div className='space-y-2'>
506
- <Label htmlFor='apiBase' className='text-sm font-medium text-gray-900'>
506
+ <Label htmlFor='apiBase' className='text-sm font-medium text-foreground'>
507
507
  {context.apiBaseHint?.label ?? t('apiBase')}
508
508
  </Label>
509
509
  <Input
@@ -514,7 +514,7 @@ function ProviderFormDetailPane(props: ProviderFormDetailPaneProps) {
514
514
  placeholder={context.defaultApiBase || context.apiBaseHint?.placeholder || 'https://api.example.com'}
515
515
  className='rounded-xl'
516
516
  />
517
- <p className='text-xs text-gray-500'>{context.apiBaseHelpText}</p>
517
+ <p className='text-xs text-muted-foreground'>{context.apiBaseHelpText}</p>
518
518
  </div>
519
519
 
520
520
  <ProviderModelsSection
@@ -49,7 +49,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
49
49
  return (
50
50
  <div className="space-y-2">
51
51
  <div className="flex items-center justify-between">
52
- <Label className="text-sm font-medium text-gray-900">{t('providerModelsTitle')}</Label>
52
+ <Label className="text-sm font-medium text-foreground">{t('providerModelsTitle')}</Label>
53
53
  {!showModelInput ? (
54
54
  <button
55
55
  type="button"
@@ -99,8 +99,8 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
99
99
  ) : null}
100
100
 
101
101
  {models.length === 0 ? (
102
- <div className="rounded-xl border border-dashed border-gray-200 bg-gray-50 px-4 py-6 text-center">
103
- <p className="text-sm text-gray-500">{t('providerModelsEmptyShort')}</p>
102
+ <div className="rounded-xl border border-dashed border-border bg-muted/60 px-4 py-6 text-center">
103
+ <p className="text-sm text-muted-foreground">{t('providerModelsEmptyShort')}</p>
104
104
  {!showModelInput ? (
105
105
  <button
106
106
  type="button"
@@ -123,14 +123,14 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
123
123
  return (
124
124
  <div
125
125
  key={modelName}
126
- className="group inline-flex max-w-full items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1.5"
126
+ className="group inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-card px-3 py-1.5"
127
127
  >
128
- <span className="max-w-[140px] truncate text-sm text-gray-800 sm:max-w-[220px]">{modelName}</span>
128
+ <span className="max-w-[140px] truncate text-sm text-foreground sm:max-w-[220px]">{modelName}</span>
129
129
  <Popover>
130
130
  <PopoverTrigger asChild>
131
131
  <button
132
132
  type="button"
133
- className="inline-flex h-5 w-5 items-center justify-center rounded-full text-gray-400 opacity-100 transition-opacity hover:bg-gray-100 hover:text-gray-600 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100"
133
+ className="inline-flex h-5 w-5 items-center justify-center rounded-full text-muted-foreground/70 opacity-100 transition-opacity hover:bg-accent hover:text-accent-foreground md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100"
134
134
  aria-label={t('providerModelThinkingTitle')}
135
135
  title={t('providerModelThinkingTitle')}
136
136
  >
@@ -138,16 +138,16 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
138
138
  </button>
139
139
  </PopoverTrigger>
140
140
  <PopoverContent className="w-80 space-y-3">
141
- <div className="flex items-center justify-between gap-3 rounded-lg border border-gray-100 bg-gray-50 px-3 py-2">
141
+ <div className="flex items-center justify-between gap-3 rounded-lg border border-border bg-muted/60 px-3 py-2">
142
142
  <div className="min-w-0">
143
- <p className="text-xs font-semibold text-gray-800">{t('providerModelVisionTitle')}</p>
144
- <p className="text-xs text-gray-500">{t('providerModelVisionHint')}</p>
143
+ <p className="text-xs font-semibold text-foreground">{t('providerModelVisionTitle')}</p>
144
+ <p className="text-xs text-muted-foreground">{t('providerModelVisionHint')}</p>
145
145
  </div>
146
146
  <Switch checked={visionEnabled} onCheckedChange={(checked) => onSetModelVision(modelName, checked)} />
147
147
  </div>
148
148
  <div className="space-y-1">
149
- <p className="text-xs font-semibold text-gray-800">{t('providerModelThinkingTitle')}</p>
150
- <p className="text-xs text-gray-500">{t('providerModelThinkingHint')}</p>
149
+ <p className="text-xs font-semibold text-foreground">{t('providerModelThinkingTitle')}</p>
150
+ <p className="text-xs text-muted-foreground">{t('providerModelThinkingHint')}</p>
151
151
  </div>
152
152
  <div className="flex flex-wrap gap-1.5">
153
153
  {thinkingLevels.map((level) => {
@@ -160,7 +160,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
160
160
  className={`rounded-full border px-2.5 py-1 text-xs font-medium transition-colors ${
161
161
  selected
162
162
  ? 'border-primary bg-primary text-white'
163
- : 'border-gray-200 bg-white text-gray-600 hover:border-primary/40 hover:text-primary'
163
+ : 'border-border bg-card text-muted-foreground hover:border-primary/40 hover:bg-accent/70 hover:text-accent-foreground'
164
164
  }`}
165
165
  >
166
166
  {formatThinkingLevelLabel(level)}
@@ -169,7 +169,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
169
169
  })}
170
170
  </div>
171
171
  <div className="space-y-1.5">
172
- <Label className="text-xs font-medium text-gray-700">{t('providerModelThinkingDefault')}</Label>
172
+ <Label className="text-xs font-medium text-foreground">{t('providerModelThinkingDefault')}</Label>
173
173
  <Select
174
174
  value={defaultThinkingLevel ?? '__none__'}
175
175
  onValueChange={(value) =>
@@ -177,7 +177,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
177
177
  }
178
178
  disabled={supportedLevels.length === 0}
179
179
  >
180
- <SelectTrigger className="h-8 rounded-lg bg-white text-xs">
180
+ <SelectTrigger className="h-8 rounded-lg text-xs">
181
181
  <SelectValue />
182
182
  </SelectTrigger>
183
183
  <SelectContent>
@@ -190,7 +190,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
190
190
  </SelectContent>
191
191
  </Select>
192
192
  {supportedLevels.length === 0 ? (
193
- <p className="text-xs text-gray-500">{t('providerModelThinkingNoSupported')}</p>
193
+ <p className="text-xs text-muted-foreground">{t('providerModelThinkingNoSupported')}</p>
194
194
  ) : null}
195
195
  </div>
196
196
  </PopoverContent>
@@ -198,7 +198,7 @@ export function ProviderModelsSection(props: ProviderModelsSectionProps) {
198
198
  <button
199
199
  type="button"
200
200
  onClick={() => onRemoveModel(modelName)}
201
- className="inline-flex h-5 w-5 items-center justify-center rounded-full text-gray-400 opacity-100 transition-opacity hover:bg-gray-100 hover:text-gray-600 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100"
201
+ className="inline-flex h-5 w-5 items-center justify-center rounded-full text-muted-foreground/70 opacity-100 transition-opacity hover:bg-accent hover:text-accent-foreground md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100"
202
202
  aria-label={t('remove')}
203
203
  >
204
204
  <X className="h-3 w-3" />
@@ -16,7 +16,7 @@ export function ProviderPillSelector(props: ProviderPillSelectorProps) {
16
16
  type="button"
17
17
  onClick={() => onChange(option.value)}
18
18
  aria-pressed={selected}
19
- className={`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${selected ? 'border-primary bg-primary text-white shadow-sm' : 'border-gray-200 bg-white text-gray-700 hover:border-primary/40 hover:text-primary'}`}
19
+ className={`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${selected ? 'border-primary bg-primary text-primary-foreground shadow-sm' : 'border-border bg-card text-muted-foreground hover:border-primary/40 hover:bg-accent/70 hover:text-accent-foreground'}`}
20
20
  >
21
21
  {option.label}
22
22
  </button>
@@ -133,11 +133,11 @@ export function ProvidersConfigPage() {
133
133
  </Button>
134
134
  </PopoverTrigger>
135
135
  <PopoverContent className="w-[42rem] max-w-[calc(100vw-2rem)] p-3" align="start">
136
- <div className="mb-2 px-1 text-xs font-semibold text-gray-500">{t('providerTemplatePickerTitle')}</div>
136
+ <div className="mb-2 px-1 text-xs font-semibold text-muted-foreground">{t('providerTemplatePickerTitle')}</div>
137
137
  <div className="grid max-h-[24rem] grid-cols-2 gap-2 overflow-y-auto sm:grid-cols-3">
138
138
  <button
139
139
  type="button"
140
- className="flex min-h-20 w-full flex-col items-start gap-2 rounded-lg border border-dashed border-gray-300 bg-white px-3 py-2 text-left hover:border-primary/40 hover:bg-gray-50"
140
+ className="flex min-h-20 w-full flex-col items-start gap-2 rounded-lg border border-dashed border-border bg-card px-3 py-2 text-left transition-colors hover:border-primary/40 hover:bg-accent/70"
141
141
  onClick={async () => {
142
142
  try {
143
143
  const result = await createProvider.mutateAsync({ data: { providerType: null } });
@@ -150,8 +150,8 @@ export function ProvidersConfigPage() {
150
150
  }
151
151
  }}
152
152
  >
153
- <LogoBadge name="custom" className="h-8 w-8 rounded-lg border border-gray-200 bg-white" />
154
- <span className="line-clamp-2 min-w-0 text-xs font-semibold leading-4 text-gray-800">
153
+ <LogoBadge name="custom" className="h-8 w-8 rounded-lg border border-border bg-background" />
154
+ <span className="line-clamp-2 min-w-0 text-xs font-semibold leading-4 text-foreground">
155
155
  {t('providerAddCustom')}
156
156
  </span>
157
157
  </button>
@@ -159,7 +159,7 @@ export function ProvidersConfigPage() {
159
159
  <button
160
160
  key={template.providerType}
161
161
  type="button"
162
- className="flex min-h-20 w-full flex-col items-start gap-2 rounded-lg border border-gray-200 bg-white px-3 py-2 text-left hover:border-primary/40 hover:bg-gray-50"
162
+ className="flex min-h-20 w-full flex-col items-start gap-2 rounded-lg border border-border bg-card px-3 py-2 text-left transition-colors hover:border-primary/40 hover:bg-accent/70"
163
163
  onClick={async () => {
164
164
  try {
165
165
  const result = await createProvider.mutateAsync({ data: { providerType: template.providerType } });
@@ -175,10 +175,10 @@ export function ProvidersConfigPage() {
175
175
  <LogoBadge
176
176
  name={template.providerType}
177
177
  src={template.logo ? `/logos/${template.logo}` : null}
178
- className="h-8 w-8 rounded-lg border border-gray-200 bg-white"
178
+ className="h-8 w-8 rounded-lg border border-border bg-background"
179
179
  imgClassName="h-4 w-4 object-contain"
180
180
  />
181
- <span className="line-clamp-2 min-w-0 text-xs font-semibold leading-4 text-gray-800">
181
+ <span className="line-clamp-2 min-w-0 text-xs font-semibold leading-4 text-foreground">
182
182
  {template.displayName || template.providerType}
183
183
  </span>
184
184
  </button>
@@ -188,9 +188,9 @@ export function ProvidersConfigPage() {
188
188
  </Popover>
189
189
  </ConfigSplitPaneHeader>
190
190
 
191
- <div className="border-b border-gray-100 px-4 py-3">
191
+ <div className="border-b border-border/70 px-4 py-3">
192
192
  <div className="relative">
193
- <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
193
+ <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground/70" />
194
194
  <Input
195
195
  value={query}
196
196
  onChange={(event) => setQuery(event.target.value)}
@@ -223,8 +223,8 @@ export function ProvidersConfigPage() {
223
223
  className={cn(
224
224
  'w-full rounded-xl border p-2.5 text-left transition-all',
225
225
  resolvedSelectedProvider === provider.providerId
226
- ? 'border-primary/30 bg-primary-50/40 shadow-sm'
227
- : 'border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70',
226
+ ? 'border-primary/35 bg-primary-50/45 text-foreground shadow-sm'
227
+ : 'border-border bg-card text-muted-foreground hover:border-primary/35 hover:bg-accent/70 hover:text-accent-foreground',
228
228
  )}
229
229
  >
230
230
  <div className="relative min-h-10">
@@ -234,15 +234,15 @@ export function ProvidersConfigPage() {
234
234
  src={template?.logo ? `/logos/${template.logo}` : null}
235
235
  className={cn(
236
236
  'h-10 w-10 rounded-lg border',
237
- isReady ? 'border-primary/30 bg-white' : 'border-gray-200/70 bg-white',
237
+ isReady ? 'border-primary/35 bg-background' : 'border-border bg-background',
238
238
  )}
239
239
  imgClassName="h-5 w-5 object-contain"
240
- fallback={<span className="text-sm font-semibold uppercase text-gray-500">{provider.providerId[0]}</span>}
240
+ fallback={<span className="text-sm font-semibold uppercase text-muted-foreground">{provider.providerId[0]}</span>}
241
241
  />
242
242
  <div className="min-w-0">
243
- <p className="truncate text-sm font-semibold text-gray-900">{providerLabel}</p>
244
- <p className="truncate font-mono text-[10px] text-gray-400">{provider.providerId}</p>
245
- <p className="line-clamp-1 text-[11px] text-gray-500">
243
+ <p className="truncate text-sm font-semibold text-foreground">{providerLabel}</p>
244
+ <p className="truncate font-mono text-[10px] text-muted-foreground/65">{provider.providerId}</p>
245
+ <p className="line-clamp-1 text-[11px] text-muted-foreground">
246
246
  {description} · {provider.models?.length ?? 0}
247
247
  </p>
248
248
  </div>
@@ -268,7 +268,7 @@ export function ProvidersConfigPage() {
268
268
  <PopoverTrigger asChild>
269
269
  <button
270
270
  type="button"
271
- className="inline-flex h-7 w-7 items-center justify-center rounded-lg text-gray-400 hover:bg-gray-100 hover:text-gray-700"
271
+ className="inline-flex h-7 w-7 items-center justify-center rounded-lg text-muted-foreground/70 hover:bg-accent hover:text-accent-foreground"
272
272
  onClick={(event) => event.stopPropagation()}
273
273
  title={t('more')}
274
274
  >
@@ -3,7 +3,7 @@ import { ArrowLeft, type LucideIcon } from "lucide-react";
3
3
  import { t } from "@/shared/lib/i18n";
4
4
  import { cn } from "@/shared/lib/utils";
5
5
 
6
- const CARD_CLASS = "min-w-0 overflow-hidden rounded-2xl border border-gray-200/70 bg-white shadow-card xl:h-[calc(100vh-180px)] xl:max-h-[860px]";
6
+ const CARD_CLASS = "min-w-0 overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-card xl:h-[calc(100vh-180px)] xl:max-h-[860px]";
7
7
  type DivProps = HTMLAttributes<HTMLDivElement>; type SectionProps = HTMLAttributes<HTMLElement>;
8
8
 
9
9
  function ConfigSplitPane({ className, ...props }: SectionProps) {
@@ -37,7 +37,7 @@ export function ConfigSplitPage({
37
37
  <button
38
38
  type="button"
39
39
  onClick={onMobileBack}
40
- className="inline-flex items-center gap-2 rounded-full border border-gray-200 bg-white px-3 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 hover:text-gray-900"
40
+ className="inline-flex items-center gap-2 rounded-full border border-border bg-card px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"
41
41
  >
42
42
  <ArrowLeft className="h-4 w-4" />
43
43
  <span>{mobileListLabel ?? t("backToMain")}</span>
@@ -81,7 +81,7 @@ export function ConfigSplitEmptyPane({ className, ...props }: SectionProps) {
81
81
  }
82
82
 
83
83
  export function ConfigSplitPaneHeader({ className, ...props }: DivProps) {
84
- return <div className={cn("shrink-0 border-b border-gray-100", className)} {...props} />;
84
+ return <div className={cn("shrink-0 border-b border-border/70", className)} {...props} />;
85
85
  }
86
86
 
87
87
  export function ConfigSplitPaneBody({
@@ -102,7 +102,7 @@ export function ConfigSplitPaneBody({
102
102
  }
103
103
 
104
104
  export function ConfigSplitPaneFooter({ className, ...props }: DivProps) {
105
- return <div className={cn("shrink-0 border-t border-gray-100", className)} {...props} />;
105
+ return <div className={cn("shrink-0 border-t border-border/70", className)} {...props} />;
106
106
  }
107
107
 
108
108
  export function ConfigSelectionCard({
@@ -117,8 +117,8 @@ export function ConfigSelectionCard({
117
117
  className={cn(
118
118
  "w-full rounded-xl border p-2.5 text-left transition-all",
119
119
  active
120
- ? "border-primary/30 bg-primary-50/40 shadow-sm"
121
- : "border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70",
120
+ ? "border-primary/35 bg-primary-50/45 text-foreground shadow-sm"
121
+ : "border-border bg-card text-muted-foreground hover:border-primary/35 hover:bg-accent/70 hover:text-accent-foreground",
122
122
  className,
123
123
  )}
124
124
  {...props}
@@ -140,16 +140,16 @@ export function ConfigSplitEmptyState({
140
140
  return (
141
141
  <div
142
142
  className={cn(
143
- "flex min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 px-4 py-10 text-center",
143
+ "flex min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-muted/60 px-4 py-10 text-center",
144
144
  className,
145
145
  )}
146
146
  {...props}
147
147
  >
148
- <div className="mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white">
149
- <Icon className="h-5 w-5 text-gray-300" />
148
+ <div className="mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-card">
149
+ <Icon className="h-5 w-5 text-muted-foreground/45" />
150
150
  </div>
151
- <p className="text-sm font-medium text-gray-700">{title}</p>
152
- {description ? <p className="mt-2 text-xs text-gray-500">{description}</p> : null}
151
+ <p className="text-sm font-medium text-foreground">{title}</p>
152
+ {description ? <p className="mt-2 text-xs text-muted-foreground">{description}</p> : null}
153
153
  </div>
154
154
  );
155
155
  }
@@ -5,10 +5,10 @@ export function DocBrowserHomePage() {
5
5
  return (
6
6
  <div className="flex h-full items-center justify-center bg-background px-5 py-6">
7
7
  <div className="flex max-w-[260px] flex-col items-center gap-3 text-center">
8
- <span className="flex h-12 w-12 items-center justify-center rounded-lg border border-gray-100 bg-gray-50 text-gray-600 shadow-[0_1px_2px_rgba(30,20,10,0.04)]">
8
+ <span className="flex h-12 w-12 items-center justify-center rounded-lg border border-border bg-muted text-muted-foreground shadow-[0_1px_2px_rgba(30,20,10,0.04)]">
9
9
  <Boxes className="h-5 w-5" />
10
10
  </span>
11
- <span className="text-sm font-medium text-gray-800">{t('docBrowserHomeTitle')}</span>
11
+ <span className="text-sm font-medium text-foreground">{t('docBrowserHomeTitle')}</span>
12
12
  </div>
13
13
  </div>
14
14
  );