@nextclaw/ui 0.26.3 → 0.26.4

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 (170) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/.vite/manifest.json +329 -329
  3. package/dist/assets/{account-panel-DIdHjKG-.js → account-panel-DVi_jhkG.js} +1 -1
  4. package/dist/assets/{api-DkLJrSCd.js → api-BZvNpFOS.js} +1 -1
  5. package/dist/assets/app-presenter-provider-BcYL-VNe.js +124 -0
  6. package/dist/assets/{appearance-settings-page-DI8aDY2G.js → appearance-settings-page-AZNBzLmT.js} +1 -1
  7. package/dist/assets/{book-open-BPMkKSci.js → book-open-CmRdT3N1.js} +1 -1
  8. package/dist/assets/card-CdRBL1E0.js +1 -0
  9. package/dist/assets/{channels-list-page-CCIaTQu7.js → channels-list-page-eZN74FN3.js} +2 -2
  10. package/dist/assets/{circle-dashed-B48a0t6p.js → circle-dashed-HOgt3gIJ.js} +1 -1
  11. package/dist/assets/{client-imrVphQb.js → client-DKKbdJ6Q.js} +1 -1
  12. package/dist/assets/config-split-page-BA3V6b3Q.js +1 -0
  13. package/dist/assets/{confirm-dialog-10Qb3dpZ.js → confirm-dialog-8vqYZ0wy.js} +1 -1
  14. package/dist/assets/{context-menu-CRqH2SEk.js → context-menu-DHVVdHzN.js} +1 -1
  15. package/dist/assets/{createLucideIcon-B4xj2I2g.js → createLucideIcon-DE0sB9Nu.js} +1 -1
  16. package/dist/assets/{desktop-capabilities-page-CFcT2g8-.js → desktop-capabilities-page-B9-B9k1A.js} +1 -1
  17. package/dist/assets/{desktop-update-config-CRJd_An1.js → desktop-update-config-Cfr3IRUe.js} +1 -1
  18. package/dist/assets/{dialog-BgL3vKJQ.js → dialog-BUfWO8hr.js} +1 -1
  19. package/dist/assets/{doc-browser-context-DH4aWvkS.js → doc-browser-context-ClLgMbxd.js} +1 -1
  20. package/dist/assets/doc-browser-w8q1j0jL.js +1 -0
  21. package/dist/assets/{download-Cr337h4W.js → download-CKqS1Ksj.js} +1 -1
  22. package/dist/assets/{es2015-D-CRf3_Z.js → es2015-BiB05Sav.js} +1 -1
  23. package/dist/assets/{extensions-CsmJPz7g.js → extensions-vPD4dGqt.js} +1 -1
  24. package/dist/assets/{eye-DrQRSAfJ.js → eye-bKzylu3p.js} +1 -1
  25. package/dist/assets/{form-actions-BEeWTGUZ.js → form-actions-CCoxz33Q.js} +1 -1
  26. package/dist/assets/{keyboard-shortcuts-settings-page-DQU56SrW.js → keyboard-shortcuts-settings-page-D8rosOVh.js} +1 -1
  27. package/dist/assets/loader-circle-Clq1Gtb1.js +1 -0
  28. package/dist/assets/{login-page-sgivRYG1.js → login-page-BT3GV3Sb.js} +1 -1
  29. package/dist/assets/login-page-DKId3By8.js +1 -0
  30. package/dist/assets/{main-B-oxUq-o.js → main-bEWCGDHr.js} +2 -2
  31. package/dist/assets/main-kqMRTwOs.css +1 -0
  32. package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +1 -0
  33. package/dist/assets/{model-config-page-CDQBhmVr.js → model-config-page-D21a-BO0.js} +1 -1
  34. package/dist/assets/{navigation-link-D3pzNHeA.js → navigation-link-DC-Pku0Y.js} +1 -1
  35. package/dist/assets/panelStandalone-BRg7B1EI.css +1 -0
  36. package/dist/assets/{panelStandalone-CGkYeMK5.js → panelStandalone-CX8X2hjh.js} +2 -2
  37. package/dist/assets/{privacy-settings-page-CjoAkoDt.js → privacy-settings-page-e0LFHZJm.js} +1 -1
  38. package/dist/assets/{projects-C7Zxpcoi.js → projects-Rki7Fmth.js} +1 -1
  39. package/dist/assets/provider-models-DFQgF4hS.js +1 -0
  40. package/dist/assets/provider-scoped-model-input-DaONL0j_.js +1 -0
  41. package/dist/assets/providers-config-page-CEOhQlMe.js +1 -0
  42. package/dist/assets/{puzzle--RLCeYML.js → puzzle-D_TiFXOv.js} +1 -1
  43. package/dist/assets/{pwa-DcizGowz.js → pwa-C9ac_1dg.js} +1 -1
  44. package/dist/assets/{refresh-cw-syCVj_nw.js → refresh-cw-BG8VfcdA.js} +1 -1
  45. package/dist/assets/remote-DkSx5x4R.js +1 -0
  46. package/dist/assets/{rotate-cw-BlH9El3x.js → rotate-cw-DPEegUU2.js} +1 -1
  47. package/dist/assets/{runtime-config-page-Cco9dS73.js → runtime-config-page-DDT1dVLt.js} +1 -1
  48. package/dist/assets/{save-BWynuRQ2.js → save-CPlctBjT.js} +1 -1
  49. package/dist/assets/{search-config-page-Cc74_SAU.js → search-config-page-CDwmd6eX.js} +1 -1
  50. package/dist/assets/{secrets-config-page-raYDzlFC.js → secrets-config-page-1OvgmwPv.js} +1 -1
  51. package/dist/assets/security-config-Pv4CM-kw.js +1 -0
  52. package/dist/assets/{select-6Uq4chZW.js → select-Y9IEbx9x.js} +1 -1
  53. package/dist/assets/service-apps-panel-DPrLeF3N.js +1 -0
  54. package/dist/assets/{settings-2-COvVf1XX.js → settings-2-CrGx9_De.js} +1 -1
  55. package/dist/assets/{status-dot-DZlxa5zW.js → status-dot-Cb8ewlUr.js} +1 -1
  56. package/dist/assets/{tag-chip-DXHtZ8AS.js → tag-chip-D-6aPuuh.js} +1 -1
  57. package/dist/assets/{theme-provider-C5PCDBPB.js → theme-provider-BjF1Eowc.js} +1 -1
  58. package/dist/assets/{trash-2-DazgBvmJ.js → trash-2-DER2EJKK.js} +1 -1
  59. package/dist/assets/{use-config-DRRGF9Zb.js → use-config-BM5jC65L.js} +1 -1
  60. package/dist/assets/{use-desktop-capabilities-CdfOUjdE.js → use-desktop-capabilities-ezKJwKqg.js} +1 -1
  61. package/dist/assets/{use-viewport-layout-DdxVnCYc.js → use-viewport-layout-vmbQUNT6.js} +1 -1
  62. package/dist/assets/x-DSz9cGhy.js +1 -0
  63. package/dist/index.html +33 -33
  64. package/dist/panel-standalone.html +10 -10
  65. package/package.json +4 -4
  66. package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +2 -2
  67. package/src/app/components/layout/sidebar-rail.styles.ts +3 -3
  68. package/src/app/styles/charcoal-theme.css +0 -3
  69. package/src/app/styles/design-system.css +12 -6
  70. package/src/app/styles/island-theme.css +2 -15
  71. package/src/features/app-data/components/app-data-removal-choice.tsx +1 -1
  72. package/src/features/channels/pages/channels-list-page.tsx +1 -1
  73. package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +1 -1
  74. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +28 -16
  75. package/src/features/chat/components/conversation/chat-conversation-content.tsx +8 -2
  76. package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +6 -4
  77. package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +22 -1
  78. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +10 -14
  79. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +38 -7
  80. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +4 -4
  81. package/src/features/chat/components/layout/chat-sidebar.tsx +2 -2
  82. package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +1 -1
  83. package/src/features/chat/features/message/components/chat-message-list.container.tsx +12 -1
  84. package/src/features/chat/features/message/components/chat-tool-call-stress-harness.tsx +32 -2
  85. package/src/features/chat/features/message/hooks/__tests__/use-chat-message-virtualizer.test.tsx +7 -5
  86. package/src/features/chat/features/message/hooks/use-chat-message-virtualizer.ts +7 -3
  87. package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +1 -1
  88. package/src/features/chat/features/session/components/chat-mobile-session-row.tsx +1 -1
  89. package/src/features/chat/features/session/components/chat-sidebar-context-card.tsx +1 -1
  90. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
  91. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +7 -5
  92. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +45 -10
  93. package/src/features/chat/features/session/components/session-header/chat-session-more-actions-menu.tsx +3 -0
  94. package/src/features/chat/features/session/components/session-header/chat-session-switcher-groups.tsx +6 -6
  95. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +5 -4
  96. package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +1 -1
  97. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +0 -1
  98. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
  99. package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +1 -1
  100. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +1 -1
  101. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +2 -2
  102. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +2 -2
  103. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +1 -1
  104. package/src/features/chat/features/workspace/components/child-sessions/chat-session-child-sessions.tsx +2 -2
  105. package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +2 -2
  106. package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +3 -3
  107. package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +1 -1
  108. package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +4 -3
  109. package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +2 -1
  110. package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +3 -3
  111. package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +2 -2
  112. package/src/features/chat/features/workspace/components/workspace-markdown-outline.tsx +1 -1
  113. package/src/features/cron/components/cron-config.tsx +2 -2
  114. package/src/features/cron/components/cron-job-detail-dialog.tsx +1 -1
  115. package/src/features/cron/components/cron-job-row.tsx +3 -3
  116. package/src/features/cron/components/cron-task-discovery.tsx +1 -1
  117. package/src/features/inbox/pages/inbox-page.tsx +1 -1
  118. package/src/features/marketplace/components/curated-shelves/marketplace-curated-shelves.tsx +2 -2
  119. package/src/features/marketplace/components/curated-shelves/marketplace-shelf-card.tsx +2 -2
  120. package/src/features/marketplace/components/marketplace-list-card.tsx +4 -4
  121. package/src/features/marketplace/components/marketplace-page.tsx +2 -2
  122. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
  123. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +3 -3
  124. package/src/features/panel-apps/components/panel-app-list-item.tsx +3 -3
  125. package/src/features/pwa/components/pwa-install-entry.tsx +1 -1
  126. package/src/features/right-panel-resources/components/__tests__/page-resource-sidebar-nav.test.tsx +9 -1
  127. package/src/features/right-panel-resources/components/page-resource-sidebar-nav.tsx +1 -1
  128. package/src/features/right-panel-resources/components/right-panel-resource-home-page.tsx +1 -1
  129. package/src/features/service-apps/components/service-action-row.tsx +3 -3
  130. package/src/features/service-apps/components/service-app-list-item.tsx +4 -4
  131. package/src/features/service-apps/components/service-apps-panel.tsx +1 -1
  132. package/src/features/settings/components/config/provider-model-list.tsx +5 -5
  133. package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +4 -4
  134. package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
  135. package/src/features/settings/pages/appearance-settings-page.tsx +2 -2
  136. package/src/features/settings/pages/providers-config-page.tsx +6 -6
  137. package/src/features/side-dock/components/side-dock.tsx +4 -4
  138. package/src/index.css +4 -0
  139. package/src/platforms/desktop/components/desktop-window-chrome.tsx +1 -1
  140. package/src/platforms/mobile/components/mobile-bottom-nav.tsx +3 -3
  141. package/src/shared/components/common/brand-header.tsx +1 -1
  142. package/src/shared/components/common/searchable-model-input.tsx +2 -2
  143. package/src/shared/components/config-split-page.tsx +3 -3
  144. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
  145. package/src/shared/components/path-picker/server-path-picker-locations.tsx +1 -1
  146. package/src/shared/components/ui/button.tsx +2 -2
  147. package/src/shared/components/ui/card.tsx +1 -1
  148. package/src/shared/components/ui/context-menu/context-menu-items.tsx +3 -3
  149. package/src/shared/components/ui/input.tsx +7 -3
  150. package/src/shared/components/ui/overlays/sheet.tsx +1 -1
  151. package/src/shared/components/ui/popover.tsx +1 -1
  152. package/src/shared/components/ui/select.tsx +2 -2
  153. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +3 -3
  154. package/src/shared/components/ui/tabs.tsx +1 -1
  155. package/dist/assets/app-presenter-provider-Co8uKOyW.js +0 -124
  156. package/dist/assets/card-Bqu8zWLq.js +0 -1
  157. package/dist/assets/config-split-page-Bd-bGKsw.js +0 -1
  158. package/dist/assets/doc-browser-52t2_rSF.js +0 -1
  159. package/dist/assets/loader-circle-DbOQWT9C.js +0 -1
  160. package/dist/assets/login-page-DW1AZXqX.js +0 -1
  161. package/dist/assets/main-BpL6OjwM.css +0 -1
  162. package/dist/assets/mcp-marketplace-page-DSLRpJEB.js +0 -1
  163. package/dist/assets/panelStandalone-D-mhAGNa.css +0 -1
  164. package/dist/assets/provider-models-YW7rIeOD.js +0 -1
  165. package/dist/assets/provider-scoped-model-input-axJ-pTEu.js +0 -1
  166. package/dist/assets/providers-config-page-_QhBXQ4M.js +0 -1
  167. package/dist/assets/remote-BLQU7aY5.js +0 -1
  168. package/dist/assets/security-config-aE_jOwy-.js +0 -1
  169. package/dist/assets/service-apps-panel-jBWAa4qZ.js +0 -1
  170. package/dist/assets/x-CQIp_nJT.js +0 -1
@@ -61,7 +61,7 @@ export function ChatWelcomeSessionTypePicker({
61
61
  </PopoverTrigger>
62
62
  <ChatPopoverContent
63
63
  align="start"
64
- className="flex w-[min(16rem,calc(100vw-1rem))] flex-col overflow-hidden rounded-2xl border border-border bg-popover p-1.5 text-popover-foreground shadow-[0_24px_60px_-28px_rgba(15,23,42,0.38)]"
64
+ className="flex w-[min(16rem,calc(100vw-1rem))] flex-col overflow-hidden p-1.5"
65
65
  style={{ maxHeight: SESSION_TYPE_PICKER_MAX_HEIGHT }}
66
66
  >
67
67
  <div className="min-h-0 flex-1 overflow-y-auto">
@@ -70,7 +70,7 @@ export function WorkspaceBreadcrumbBrowser({
70
70
  <Fragment key={breadcrumb.path}>
71
71
  <button
72
72
  type="button"
73
- className="h-5 rounded-sm px-1 text-left hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
73
+ className="h-5 rounded-sm px-1 text-left hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
74
74
  onClick={() => onBrowsePathChange(breadcrumb.path)}
75
75
  >
76
76
  {breadcrumb.label}
@@ -100,7 +100,7 @@ export function WorkspaceBreadcrumbBrowser({
100
100
  key={entry.path}
101
101
  type="button"
102
102
  className={cn(
103
- "flex h-6 w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-[11px] text-gray-700 transition-colors hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
103
+ "flex h-6 w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-[11px] text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
104
104
  entry.hidden ? "opacity-65" : null,
105
105
  )}
106
106
  onClick={() => openEntry(entry)}
@@ -43,9 +43,9 @@ function WorkspaceBreadcrumbSegmentButton({
43
43
  type="button"
44
44
  aria-current={segment.isCurrent ? 'page' : undefined}
45
45
  className={cn(
46
- 'inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-sm px-1 text-[11px] leading-none transition-colors hover:bg-gray-200/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border',
46
+ 'inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-sm px-1 text-[11px] leading-none transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border',
47
47
  segment.kind === 'workspace'
48
- ? 'bg-primary/8 text-primary hover:bg-primary/12'
48
+ ? 'bg-[var(--interaction-selection)] text-foreground hover:bg-[var(--interaction-selection)]'
49
49
  : segment.isCurrent
50
50
  ? 'bg-gray-200/70 text-gray-900'
51
51
  : 'text-gray-500',
@@ -66,7 +66,7 @@ function WorkspaceOverviewEntry({
66
66
  return (
67
67
  <button
68
68
  type="button"
69
- className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
69
+ className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
70
70
  onClick={onClick}
71
71
  >
72
72
  <span className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
@@ -27,7 +27,7 @@ export function ChatSessionChildSessions({
27
27
  </div>
28
28
  <button
29
29
  type="button"
30
- className="inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-2.5 py-1.5 text-xs font-semibold text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25 disabled:cursor-not-allowed disabled:opacity-50"
30
+ className="inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-2.5 py-1.5 text-xs font-semibold text-primary-foreground transition-colors hover:bg-[hsl(var(--primary-hover))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25 disabled:cursor-not-allowed disabled:opacity-50"
31
31
  disabled={!sessionKey}
32
32
  onClick={() => presenter.chatThreadManager.openSideChatDraft(sessionKey)}
33
33
  >
@@ -42,7 +42,7 @@ export function ChatSessionChildSessions({
42
42
  {childSessionTabs.map((tab) => (
43
43
  <div
44
44
  key={tab.sessionKey}
45
- className="group relative flex w-full items-center rounded-lg border border-gray-200/80 bg-white transition-colors hover:border-gray-300 hover:bg-gray-50"
45
+ className="group relative flex w-full items-center rounded-lg border border-gray-200/80 bg-white transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)]"
46
46
  >
47
47
  <button
48
48
  type="button"
@@ -121,8 +121,8 @@ export function WorkspaceSpreadsheetPreview({
121
121
  className={cn(
122
122
  "h-7 shrink-0 rounded-md px-2.5 text-xs transition-colors",
123
123
  sheet.name === activeSheet?.name
124
- ? "bg-accent font-medium text-accent-foreground"
125
- : "text-muted-foreground hover:bg-muted hover:text-foreground",
124
+ ? "bg-[var(--interaction-selection)] font-medium text-foreground"
125
+ : "text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground",
126
126
  )}
127
127
  onClick={() => setSelectedSheetName(sheet.name)}
128
128
  >
@@ -96,7 +96,7 @@ function ObservationRow({
96
96
  type="button"
97
97
  data-testid={`observation-${item.id}-${toggleAction}`}
98
98
  disabled={isPending}
99
- className="inline-flex items-center gap-1.5 rounded-md border border-gray-200 px-2.5 py-1.5 text-xs font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50"
99
+ className="inline-flex items-center gap-1.5 rounded-md border border-gray-200 px-2.5 py-1.5 text-xs font-medium text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] disabled:cursor-not-allowed disabled:opacity-50"
100
100
  onClick={() => onAction(toggleAction)}
101
101
  >
102
102
  {toggleAction === 'pause' ? <Pause className="h-3.5 w-3.5" /> : <Play className="h-3.5 w-3.5" />}
@@ -107,7 +107,7 @@ function ObservationRow({
107
107
  type="button"
108
108
  data-testid={`observation-${item.id}-remove`}
109
109
  disabled={isPending}
110
- className="inline-flex items-center gap-1.5 rounded-md border border-rose-200 px-2.5 py-1.5 text-xs font-medium text-rose-700 transition-colors hover:bg-rose-50 disabled:cursor-not-allowed disabled:opacity-50"
110
+ className="inline-flex items-center gap-1.5 rounded-md border border-rose-200 px-2.5 py-1.5 text-xs font-medium text-rose-700 transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50"
111
111
  onClick={() => onAction('remove')}
112
112
  >
113
113
  <Trash2 className="h-3.5 w-3.5" />
@@ -179,7 +179,7 @@ export function ChatSessionContinuousAttention({ sessionKey }: { sessionKey: str
179
179
  type="button"
180
180
  role="tab"
181
181
  aria-selected={activeGroup === group}
182
- className={cn('flex-1 rounded-md px-3 py-2 text-xs font-medium transition-colors', activeGroup === group ? 'bg-gray-100 text-gray-900' : 'text-gray-500 hover:text-gray-700')}
182
+ className={cn('flex-1 rounded-md px-3 py-2 text-xs font-medium transition-colors', activeGroup === group ? 'bg-[var(--interaction-selection)] text-foreground' : 'text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground')}
183
183
  onClick={() => setActiveGroup(group)}
184
184
  >
185
185
  {getGroupLabel(group)} <span className="ml-1 tabular-nums text-gray-400">{count}</span>
@@ -90,7 +90,7 @@ export function ChatSessionTokenUsage({ sessionKey }: { sessionKey: string | nul
90
90
  <span>{t('chatWorkspaceTokenUsageLoadFailed')}</span>
91
91
  <button
92
92
  type="button"
93
- className="shrink-0 rounded px-1.5 py-1 font-semibold text-gray-700 hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
93
+ className="shrink-0 rounded px-1.5 py-1 font-semibold text-gray-700 hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
94
94
  onClick={() => void usageQuery.refetch()}
95
95
  >
96
96
  {t('chatWorkspaceTokenUsageRetry')}
@@ -355,8 +355,8 @@ export function WorkspaceDirectoryTreeEntry({
355
355
  ref={rowRef}
356
356
  data-workspace-tree-entry=""
357
357
  className={cn(
358
- 'group flex h-[26px] w-full min-w-0 items-center text-gray-700 transition-colors hover:bg-gray-100 focus-within:bg-gray-100',
359
- selected ? 'bg-primary/10' : null,
358
+ 'group flex h-[26px] w-full min-w-0 items-center text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]',
359
+ selected ? 'bg-[var(--interaction-selection)] hover:bg-[var(--interaction-selection)] focus-within:bg-[var(--interaction-selection)]' : null,
360
360
  entry.hidden ? 'opacity-65' : null,
361
361
  )}
362
362
  style={{ paddingLeft: `${6 + level * 12}px` }}
@@ -371,9 +371,10 @@ export function WorkspaceDirectoryTreeEntry({
371
371
  }}
372
372
  >
373
373
  <Input
374
+ density="compact"
374
375
  autoFocus
375
376
  aria-label={t('chatWorkspaceRenameName')}
376
- className="h-6 min-w-0 flex-1 px-1.5 text-xs"
377
+ className="h-6 min-w-0 flex-1 px-1.5"
377
378
  value={rename.name}
378
379
  onChange={(event) => rename.updateName(event.target.value)}
379
380
  onKeyDown={(event) => {
@@ -67,9 +67,10 @@ export function WorkspaceNewFolderTreeItem({
67
67
  <Folder className="h-4 w-4 shrink-0 text-amber-500" />
68
68
  )}
69
69
  <Input
70
+ density="compact"
70
71
  ref={inputRef}
71
72
  aria-label={t(kind === 'file' ? 'chatWorkspaceFileName' : 'chatWorkspaceFolderName')}
72
- className="h-7 min-w-0 flex-1 rounded-md px-2 text-xs"
73
+ className="h-7 min-w-0 flex-1 rounded-md px-2"
73
74
  disabled={isCreating}
74
75
  placeholder={t(kind === 'file' ? 'chatWorkspaceFileNamePlaceholder' : 'chatWorkspaceFolderNamePlaceholder')}
75
76
  value={name}
@@ -83,7 +83,7 @@ function SessionCronJobCard({
83
83
  const jobLabel = job.name || job.id;
84
84
 
85
85
  return (
86
- <article className="rounded-2xl border border-border/60 bg-background px-3.5 py-3 shadow-sm transition-colors hover:bg-muted/20 focus-within:bg-muted/20">
86
+ <article className="rounded-2xl border border-border/60 bg-background px-3.5 py-3 shadow-sm transition-colors hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]">
87
87
  <div className="flex items-start gap-3">
88
88
  <span
89
89
  className={cn(
@@ -189,7 +189,7 @@ function SessionCronJobCard({
189
189
  setMenuOpen(false);
190
190
  void cronActions.runJob(job);
191
191
  }}
192
- className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50"
192
+ className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-[var(--interaction-hover)] disabled:cursor-not-allowed disabled:opacity-50"
193
193
  >
194
194
  <Play className="h-3.5 w-3.5 text-muted-foreground" />
195
195
  {t("cronRunNow")}
@@ -201,7 +201,7 @@ function SessionCronJobCard({
201
201
  setMenuOpen(false);
202
202
  void cronActions.deleteJob(job);
203
203
  }}
204
- className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-50"
204
+ className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50"
205
205
  >
206
206
  {t("delete")}
207
207
  </button>
@@ -105,7 +105,7 @@ function WorkspaceUnsupportedContent({
105
105
  <a
106
106
  href={contentUrl}
107
107
  download={label}
108
- className="inline-flex h-8 items-center rounded-lg border border-border bg-card px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted"
108
+ className="inline-flex h-8 items-center rounded-lg border border-border bg-card px-3 text-xs font-medium text-foreground transition-colors hover:bg-[var(--interaction-hover)]"
109
109
  >
110
110
  {t("chatWorkspacePreviewDownload")}
111
111
  </a>
@@ -113,7 +113,7 @@ function WorkspaceUnsupportedContent({
113
113
  href={contentUrl}
114
114
  target="_blank"
115
115
  rel="noreferrer"
116
- className="inline-flex h-8 items-center rounded-lg bg-primary px-3 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90"
116
+ className="inline-flex h-8 items-center rounded-lg bg-primary px-3 text-xs font-medium text-primary-foreground transition-colors hover:bg-[hsl(var(--primary-hover))]"
117
117
  >
118
118
  {t("chatWorkspacePreviewOpenExternally")}
119
119
  </a>
@@ -137,7 +137,7 @@ export function WorkspaceMarkdownOutline({
137
137
  <li key={item.index}>
138
138
  <button
139
139
  type="button"
140
- className="block w-full truncate rounded-md py-1.5 pr-2 text-left text-xs leading-4 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-950 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border active:bg-gray-200"
140
+ className="block w-full truncate rounded-md py-1.5 pr-2 text-left text-xs leading-4 text-gray-600 transition-colors hover:bg-[var(--interaction-hover)] hover:text-gray-950 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border active:bg-[var(--interaction-hover)]"
141
141
  style={{
142
142
  paddingInlineStart: `${0.5 + item.depth * 0.75}rem`,
143
143
  }}
@@ -308,8 +308,8 @@ export function CronConfig() {
308
308
  handlePageChange(0);
309
309
  }}
310
310
  className={cn(
311
- "rounded-lg px-2.5 py-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
312
- status === value && "bg-muted text-foreground",
311
+ "rounded-lg px-2.5 py-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground",
312
+ status === value && "bg-[var(--interaction-selection)] hover:bg-[var(--interaction-selection)] text-foreground",
313
313
  )}
314
314
  >
315
315
  {t(label)}
@@ -206,7 +206,7 @@ export function CronJobDetailDialog({
206
206
  <SheetFooter className="shrink-0 border-t border-border/60 bg-background px-5 py-4 sm:px-7">
207
207
  <Button
208
208
  variant="ghost"
209
- className="text-red-600 hover:bg-red-50 hover:text-red-700"
209
+ className="text-red-600 hover:bg-destructive/10 hover:text-red-700"
210
210
  onClick={() => onDelete(job)}
211
211
  >
212
212
  <Trash2 className="mr-2 h-4 w-4" />
@@ -105,7 +105,7 @@ export function CronJobRow({
105
105
  return (
106
106
  <div
107
107
  className={cn(
108
- "group relative rounded-xl border-b border-border/55 transition-colors duration-150 last:border-b-0 hover:bg-muted/35 focus-within:bg-muted/35",
108
+ "group relative rounded-xl border-b border-border/55 transition-colors duration-150 last:border-b-0 hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]",
109
109
  expanded && "bg-muted/35",
110
110
  )}
111
111
  >
@@ -206,7 +206,7 @@ export function CronJobRow({
206
206
  setMenuOpen(false);
207
207
  onRun(job);
208
208
  }}
209
- className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-muted"
209
+ className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-[var(--interaction-hover)]"
210
210
  >
211
211
  <Play className="h-3.5 w-3.5 text-muted-foreground" />
212
212
  {t("cronRunNow")}
@@ -217,7 +217,7 @@ export function CronJobRow({
217
217
  setMenuOpen(false);
218
218
  onDelete(job);
219
219
  }}
220
- className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-red-50"
220
+ className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-destructive/10"
221
221
  >
222
222
  <Trash2 className="h-3.5 w-3.5" />
223
223
  {t("delete")}
@@ -133,7 +133,7 @@ export function CronTemplateGallery({
133
133
  onClick={() => onSelect(t(template.promptKey))}
134
134
  className="group grid min-h-24 grid-cols-[38px_minmax(0,1fr)] items-center gap-3 rounded-2xl border border-border/60 bg-card px-4 py-4 text-left transition-all hover:-translate-y-0.5 hover:border-primary/20 hover:shadow-[0_12px_30px_rgba(30,45,52,0.08)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
135
135
  >
136
- <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-muted text-muted-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary">
136
+ <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-muted text-muted-foreground transition-colors group-hover:bg-[var(--interaction-hover)] group-hover:text-primary">
137
137
  <Icon className="h-4 w-4" aria-hidden="true" />
138
138
  </span>
139
139
  <span className="min-w-0">
@@ -120,7 +120,7 @@ function InboxListPane({
120
120
  {filteredDeliveries.map((delivery) => (
121
121
  <li key={delivery.id} className={cn(
122
122
  "group/page-row relative rounded-lg hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)] has-[[data-context-menu-open]]:bg-[var(--interaction-hover)]",
123
- activeDeliveryId === delivery.id && "bg-[var(--interaction-selection)]",
123
+ activeDeliveryId === delivery.id && "bg-[var(--interaction-selection)] hover:bg-[var(--interaction-selection)] focus-within:bg-[var(--interaction-selection)] has-[[data-context-menu-open]]:bg-[var(--interaction-selection)]",
124
124
  )}>
125
125
  <Link
126
126
  to={`/inbox/${encodeURIComponent(delivery.id)}`}
@@ -131,7 +131,7 @@ function GoalCard(props: {
131
131
  type="button"
132
132
  onClick={() => onSelect(scene.scene)}
133
133
  className={cn(
134
- "group flex min-h-[74px] flex-col justify-center rounded-lg border px-3 py-2.5 text-left shadow-sm transition-colors hover:border-gray-300 hover:bg-gray-50/70",
134
+ "group flex min-h-[74px] flex-col justify-center rounded-lg border px-3 py-2.5 text-left shadow-sm transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)]",
135
135
  tone.card,
136
136
  )}
137
137
  >
@@ -194,7 +194,7 @@ export function MarketplaceCuratedSceneView(props: {
194
194
  <button
195
195
  type="button"
196
196
  onClick={onBack}
197
- className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900"
197
+ className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-gray-600 transition-colors hover:bg-[var(--interaction-hover)] hover:text-gray-900"
198
198
  aria-label={readLocalized({ zh: "返回", en: "Back" }, language)}
199
199
  >
200
200
  <ArrowLeft className="h-4 w-4" />
@@ -42,7 +42,7 @@ export function SkillShelfCard(props: {
42
42
  <article
43
43
  onClick={() => onOpen(entry)}
44
44
  className={cn(
45
- "group flex min-h-[166px] cursor-pointer flex-col justify-between rounded-xl border border-gray-200/70 bg-white p-3 shadow-sm transition-colors hover:border-gray-300 hover:bg-gray-50/60",
45
+ "group flex min-h-[166px] cursor-pointer flex-col justify-between rounded-xl border border-gray-200/70 bg-white p-3 shadow-sm transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)]",
46
46
  layout === "rail" ? "w-[260px] shrink-0" : "w-full min-w-0",
47
47
  )}
48
48
  >
@@ -81,7 +81,7 @@ export function SkillShelfCard(props: {
81
81
  event.stopPropagation();
82
82
  onInstall(item);
83
83
  }}
84
- className="inline-flex h-7 items-center gap-1.5 rounded-md border border-gray-200 bg-white px-2 text-[11px] font-semibold text-gray-700 transition-colors hover:border-gray-300 hover:bg-gray-50 disabled:opacity-50"
84
+ className="inline-flex h-7 items-center gap-1.5 rounded-md border border-gray-200 bg-white px-2 text-[11px] font-semibold text-gray-700 transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)] disabled:opacity-50"
85
85
  >
86
86
  <Download className="h-3.5 w-3.5" />
87
87
  {isInstalling ? t("marketplaceInstalling") : t("marketplaceInstall")}
@@ -125,7 +125,7 @@ function MarketplaceListCardActionButtons(props: MarketplaceListCardActionProps)
125
125
  onInstall(item);
126
126
  }}
127
127
  disabled={isInstalling}
128
- className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md bg-primary px-2 text-[11px] font-medium text-white transition-colors hover:bg-primary-600 disabled:opacity-50"
128
+ className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md bg-primary px-2 text-[11px] font-medium text-white transition-colors hover:bg-[hsl(var(--primary-hover))] disabled:opacity-50"
129
129
  >
130
130
  <Download className="h-3 w-3" />
131
131
  {isInstalling ? t("marketplaceInstalling") : t("marketplaceInstall")}
@@ -139,7 +139,7 @@ function MarketplaceListCardActionButtons(props: MarketplaceListCardActionProps)
139
139
  event.stopPropagation();
140
140
  onManage("update", record);
141
141
  }}
142
- className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md border border-blue-200/80 bg-white px-2 text-[11px] font-medium text-blue-600 transition-colors hover:border-blue-300 hover:bg-blue-50 disabled:opacity-50"
142
+ className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md border border-blue-200/80 bg-white px-2 text-[11px] font-medium text-blue-600 transition-colors hover:border-blue-300 hover:bg-[var(--interaction-hover)] disabled:opacity-50"
143
143
  >
144
144
  <RefreshCw className="h-3 w-3" />
145
145
  {busyAction === "update"
@@ -155,7 +155,7 @@ function MarketplaceListCardActionButtons(props: MarketplaceListCardActionProps)
155
155
  event.stopPropagation();
156
156
  onManage("uninstall", record);
157
157
  }}
158
- className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md border border-gray-200/80 bg-white px-2 text-[11px] font-medium text-gray-500 transition-colors hover:border-rose-200 hover:bg-rose-50 hover:text-rose-600 disabled:opacity-50"
158
+ className="inline-flex h-6 items-center gap-1 whitespace-nowrap rounded-md border border-gray-200/80 bg-white px-2 text-[11px] font-medium text-gray-500 transition-colors hover:border-rose-200 hover:bg-destructive/10 hover:text-rose-600 disabled:opacity-50"
159
159
  >
160
160
  <Trash2 className="h-3 w-3" />
161
161
  {busyAction === "uninstall"
@@ -263,7 +263,7 @@ export function MarketplaceListCard(props: {
263
263
  return (
264
264
  <article
265
265
  onClick={onOpen}
266
- className="group flex h-full min-h-[156px] cursor-pointer flex-col rounded-xl border border-gray-200/60 bg-white p-3.5 shadow-sm transition-colors hover:border-gray-300 hover:bg-gray-50/60"
266
+ className="group flex h-full min-h-[156px] cursor-pointer flex-col rounded-xl border border-gray-200/60 bg-white p-3.5 shadow-sm transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)]"
267
267
  >
268
268
  <div className="flex min-w-0 items-start gap-2.5">
269
269
  <MarketplaceItemIcon
@@ -150,13 +150,13 @@ export function MarketplacePage({
150
150
  <TabsList className="mb-0 h-auto flex-1 justify-start gap-4 sm:gap-6 rounded-none border-b-0 bg-transparent p-0 text-muted-foreground">
151
151
  <TabsTrigger
152
152
  value="all"
153
- className="rounded-none border-b-2 border-transparent bg-transparent px-0 pb-3 pt-0 shadow-none hover:bg-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-gray-950 data-[state=active]:shadow-none"
153
+ className="rounded-none border-b-2 border-transparent bg-transparent px-0 pb-3 pt-0 shadow-none hover:bg-[var(--interaction-hover)] data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-gray-950 data-[state=active]:shadow-none"
154
154
  >
155
155
  {t("marketplaceTabMarketplaceSkills")}
156
156
  </TabsTrigger>
157
157
  <TabsTrigger
158
158
  value="installed"
159
- className="gap-1.5 rounded-none border-b-2 border-transparent bg-transparent px-0 pb-3 pt-0 shadow-none hover:bg-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-gray-950 data-[state=active]:shadow-none"
159
+ className="gap-1.5 rounded-none border-b-2 border-transparent bg-transparent px-0 pb-3 pt-0 shadow-none hover:bg-[var(--interaction-hover)] data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-gray-950 data-[state=active]:shadow-none"
160
160
  >
161
161
  {t("marketplaceTabInstalledSkills")}
162
162
  <span className="text-[11px] font-medium text-gray-500">
@@ -98,7 +98,7 @@ export function McpMarketplaceCard(props: {
98
98
  type="button"
99
99
  size="sm"
100
100
  variant="outline"
101
- className="rounded-xl border-blue-200 text-blue-700 hover:border-blue-300 hover:bg-blue-50 hover:text-blue-700"
101
+ className="rounded-xl border-blue-200 text-blue-700 hover:border-blue-300 hover:bg-[var(--interaction-hover)] hover:text-blue-700"
102
102
  onClick={(event) => {
103
103
  event.stopPropagation();
104
104
  onDoctor();
@@ -112,7 +112,7 @@ export function McpMarketplaceCard(props: {
112
112
  type="button"
113
113
  size="sm"
114
114
  variant="outline"
115
- className="rounded-xl border-rose-200 text-rose-600 hover:border-rose-300 hover:bg-rose-50 hover:text-rose-600"
115
+ className="rounded-xl border-rose-200 text-rose-600 hover:border-rose-300 hover:bg-destructive/10 hover:text-rose-600"
116
116
  onClick={(event) => {
117
117
  event.stopPropagation();
118
118
  onRemove();
@@ -288,8 +288,8 @@ export function McpMarketplacePage() {
288
288
  className={cn(
289
289
  "relative flex min-w-0 items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
290
290
  isActive
291
- ? "bg-card text-foreground shadow-sm"
292
- : "text-muted-foreground hover:bg-card/60 hover:text-foreground"
291
+ ? "bg-[var(--interaction-selection)] text-foreground"
292
+ : "text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground"
293
293
  )}
294
294
  >
295
295
  <Icon className="h-4 w-4 shrink-0" />
@@ -297,7 +297,7 @@ export function McpMarketplacePage() {
297
297
  {tab.id === 'installed' && typeof tab.count === 'number' && (
298
298
  <span className={cn(
299
299
  "flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[11px] font-semibold",
300
- isActive ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"
300
+ isActive ? "bg-[var(--interaction-selection)] text-foreground" : "bg-muted text-muted-foreground"
301
301
  )}>
302
302
  {tab.count}
303
303
  </span>
@@ -40,7 +40,7 @@ export function PanelAppListItem({
40
40
  setIsDeleteDialogOpen(true);
41
41
  };
42
42
  return (
43
- <div className="group w-full min-w-0 rounded-lg border border-border/60 bg-card px-2.5 py-2.5 transition-colors hover:bg-muted/40">
43
+ <div className="group w-full min-w-0 rounded-lg border border-border/60 bg-card px-2.5 py-2.5 transition-colors hover:bg-[var(--interaction-hover)]">
44
44
  <div className="flex min-w-0 items-start gap-2">
45
45
  <button type="button" onClick={onOpen} className="min-w-0 flex-1 text-left">
46
46
  <span className="flex min-w-0 items-center gap-2">
@@ -59,7 +59,7 @@ export function PanelAppListItem({
59
59
  type="button"
60
60
  onClick={handleFavorite}
61
61
  disabled={favoritePending}
62
- className="rounded-md p-1.5 text-muted-foreground/70 transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50"
62
+ className="rounded-md p-1.5 text-muted-foreground/70 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground disabled:opacity-50"
63
63
  title={favoriteLabel}
64
64
  aria-label={favoriteLabel}
65
65
  >
@@ -69,7 +69,7 @@ export function PanelAppListItem({
69
69
  <PopoverTrigger asChild>
70
70
  <button
71
71
  type="button"
72
- className="rounded-md p-1.5 text-muted-foreground/70 transition-colors hover:bg-muted hover:text-foreground"
72
+ className="rounded-md p-1.5 text-muted-foreground/70 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground"
73
73
  aria-label={t('panelAppsMoreActions')}
74
74
  disabled={deletePending}
75
75
  >
@@ -122,7 +122,7 @@ export function PwaInstallBanner() {
122
122
  <button
123
123
  type='button'
124
124
  aria-label={t('pwaInstallDismiss')}
125
- className='rounded-full p-1 text-gray-400 transition hover:bg-gray-100 hover:text-gray-600'
125
+ className='rounded-full p-1 text-gray-400 transition hover:bg-[var(--interaction-hover)] hover:text-gray-600'
126
126
  onClick={() => {
127
127
  pwaInstallManager.dismissInstallPrompt();
128
128
  }}
@@ -110,7 +110,15 @@ describe("shared left pages", () => {
110
110
  it("preserves the collapsed group preference", async () => {
111
111
  mocks.entries = [createEntry({ mainSidebar: true })];
112
112
  renderNav();
113
- await userEvent.click(screen.getByRole("button", { name: "Pages 1" }));
113
+ const groupTrigger = screen.getByRole("button", { name: "Pages 1" });
114
+ expect(groupTrigger.className).toContain(
115
+ "hover:bg-[var(--sidebar-interaction-hover)]",
116
+ );
117
+ expect(groupTrigger.className).toContain(
118
+ "active:bg-[var(--sidebar-interaction-selection)]",
119
+ );
120
+ expect(groupTrigger.className).toContain("focus-visible:ring-1");
121
+ await userEvent.click(groupTrigger);
114
122
  expect(screen.queryByRole("link")).toBeNull();
115
123
  expect(
116
124
  useViewportLayoutStore.getState().isMainSidebarAppGroupCollapsed,
@@ -105,7 +105,7 @@ export function PageResourceSidebarNav({
105
105
  type="button"
106
106
  aria-expanded={!groupCollapsed}
107
107
  onClick={viewportLayoutManager.toggleMainSidebarAppGroupCollapsed}
108
- className="flex w-full items-center gap-2 px-2.5 py-1.5 text-[13px] text-muted-foreground"
108
+ className={`flex w-full items-center gap-2 px-2.5 py-1.5 text-[13px] ${SIDEBAR_RAIL_SURFACE_CLASS}`}
109
109
  >
110
110
  <ChevronDown
111
111
  className={`h-3.5 w-3.5 ${groupCollapsed ? "-rotate-90" : ""}`}
@@ -52,7 +52,7 @@ const HOME_ITEM_VIEW_BY_ID: Record<string, RightPanelResourceHomeItem> = {
52
52
  function resolveHomeItemView(item: RightPanelResourceHomeNavigationItem): RightPanelResourceHomeItem {
53
53
  return HOME_ITEM_VIEW_BY_ID[item.id] ?? {
54
54
  accentClassName: 'bg-gray-50 text-gray-700',
55
- hoverAccentClassName: 'group-hover:bg-gray-100',
55
+ hoverAccentClassName: 'group-hover:bg-[var(--interaction-hover)]',
56
56
  icon: <Boxes className="h-5 w-5" />,
57
57
  };
58
58
  }
@@ -66,7 +66,7 @@ export function ServiceActionRow({
66
66
  <button
67
67
  type="button"
68
68
  disabled={grantAgentPending || availableAgents.length === 0}
69
- className="ml-1 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-40"
69
+ className="ml-1 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-40"
70
70
  title={t("serviceAppsGrantToAgent")}
71
71
  aria-label={t("serviceAppsGrantToAgent")}
72
72
  >
@@ -85,7 +85,7 @@ export function ServiceActionRow({
85
85
  onGrantAgent(action.id, agent.id);
86
86
  setAgentMenuOpen(false);
87
87
  }}
88
- className="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-left text-xs text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
88
+ className="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-left text-xs text-foreground transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
89
89
  >
90
90
  <Bot className="h-3.5 w-3.5 text-muted-foreground" />
91
91
  <span className="min-w-0 truncate">
@@ -111,7 +111,7 @@ export function ServiceActionRow({
111
111
  <button
112
112
  type="button"
113
113
  onClick={() => onRevoke(grant)}
114
- className="rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted hover:text-rose-600 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
114
+ className="rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-[var(--interaction-hover)] hover:text-rose-600 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
115
115
  title={t("serviceAppsRevokeGrant")}
116
116
  aria-label={t("serviceAppsRevokeGrant")}
117
117
  >
@@ -99,7 +99,7 @@ export function ServiceAppListItem({
99
99
  };
100
100
  return (
101
101
  <TooltipProvider delayDuration={250}>
102
- <section className="group bg-card transition-colors hover:bg-muted/25">
102
+ <section className="group bg-card transition-colors hover:bg-[var(--interaction-hover)]">
103
103
  <div className="flex items-start gap-3 px-4 py-3.5">
104
104
  <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
105
105
  <Server className="h-4 w-4" />
@@ -155,7 +155,7 @@ export function ServiceAppListItem({
155
155
  <PopoverTrigger asChild>
156
156
  <button
157
157
  type="button"
158
- className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:opacity-50"
158
+ className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:opacity-50"
159
159
  aria-label={t("serviceAppsMoreActions")}
160
160
  disabled={deletePending}
161
161
  >
@@ -208,7 +208,7 @@ export function ServiceAppListItem({
208
208
  <button
209
209
  type="button"
210
210
  onClick={() => onActionsOpenChange(!actionsOpen)}
211
- className="flex min-w-0 flex-1 items-center justify-between gap-2 px-4 py-2 text-left text-xs text-muted-foreground transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border"
211
+ className="flex min-w-0 flex-1 items-center justify-between gap-2 px-4 py-2 text-left text-xs text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border"
212
212
  aria-expanded={actionsOpen}
213
213
  >
214
214
  <div className="flex min-w-0 items-center gap-2">
@@ -228,7 +228,7 @@ export function ServiceAppListItem({
228
228
  <button
229
229
  type="button"
230
230
  onClick={() => setIsDiagnosticsOpen((open) => !open)}
231
- className="flex shrink-0 items-center gap-1 border-l border-border/60 px-3 text-xs text-muted-foreground transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border"
231
+ className="flex shrink-0 items-center gap-1 border-l border-border/60 px-3 text-xs text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border"
232
232
  aria-expanded={isDiagnosticsOpen}
233
233
  >
234
234
  <span>{t("serviceAppsDetails")}</span>
@@ -110,7 +110,7 @@ export function ServiceAppsPanel({
110
110
  <TooltipTrigger asChild>
111
111
  <button
112
112
  type="button"
113
- className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
113
+ className="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
114
114
  aria-label={t("serviceAppsRefresh")}
115
115
  onClick={refetch}
116
116
  >