@puredesktop/puredesktop-ui-bridge 2.1.4 → 2.1.7

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 (183) hide show
  1. package/package.json +19 -1
  2. package/src/agents/runtime/mapAgentSnapshot.test.ts +1 -3
  3. package/src/agents/runtime/mapAgentSnapshot.ts +8 -4
  4. package/src/agents/runtime/mergeUsageTurn.ts +1 -2
  5. package/src/agents/runtime/pendingToolCalls.test.ts +1 -3
  6. package/src/agents/runtime/unresolvedToolCalls.ts +1 -2
  7. package/src/bridge/agentModelTiers.ts +9 -4
  8. package/src/bridge/agents.mjs +3 -1
  9. package/src/bridge/calendarDraftIntent.ts +12 -4
  10. package/src/bridge/calendarInviteIntent.ts +18 -5
  11. package/src/bridge/client.mjs +45 -45
  12. package/src/bridge/dialog.d.mts +8 -8
  13. package/src/bridge/dialog.mjs +40 -40
  14. package/src/bridge/dialog.test.ts +73 -73
  15. package/src/bridge/fs.d.mts +41 -41
  16. package/src/bridge/fs.mjs +56 -56
  17. package/src/bridge/fs.test.ts +83 -83
  18. package/src/bridge/fs.ts +28 -28
  19. package/src/bridge/googleAuth.ts +3 -1
  20. package/src/bridge/methods.d.mts +6 -0
  21. package/src/bridge/methods.mjs +7 -0
  22. package/src/bridge/network.d.mts +17 -17
  23. package/src/bridge/network.mjs +22 -22
  24. package/src/bridge/pureRender/base.css +324 -76
  25. package/src/bridge/pureRender/compiler.ts +1 -1
  26. package/src/bridge/pureRender/document.test.ts +2 -2
  27. package/src/bridge/pureRender/extraction.test.ts +24 -12
  28. package/src/bridge/pureRender/extraction.ts +10 -7
  29. package/src/bridge/pureRender/flow.css +17 -3
  30. package/src/bridge/pureRender/normalize.ts +28 -26
  31. package/src/bridge/pureRender/presets.ts +7 -7
  32. package/src/bridge/pureRender/profiles/book.css +122 -19
  33. package/src/bridge/pureRender/profiles/manuscript.css +57 -11
  34. package/src/bridge/pureRender/profiles/writer.css +48 -10
  35. package/src/bridge/pureRender/reset.css +20 -5
  36. package/src/bridge/pureRender/theme.ts +37 -9
  37. package/src/bridge/pureRender/tokens/default.css +45 -33
  38. package/src/bridge/react/usePlatformAgentRunLiveState.tsx +4 -1
  39. package/src/bridge/react/usePlatformAgentSessionDrive.tsx +13 -4
  40. package/src/bridge/screenAnnotation.test.ts +4 -1
  41. package/src/bridge/screenAnnotation.ts +6 -2
  42. package/src/bridge/storage.d.mts +26 -24
  43. package/src/bridge/storage.mjs +18 -18
  44. package/src/bridge/storage.test.ts +45 -45
  45. package/src/bridge/types.ts +62 -58
  46. package/src/bridge/window.d.mts +3 -1
  47. package/src/bridge/workspace.d.mts +7 -0
  48. package/src/bridge/workspace.mjs +8 -0
  49. package/src/bridge/workspace.ts +1 -0
  50. package/src/commitments/commitments.test.ts +10 -3
  51. package/src/commitments/commitments.ts +18 -4
  52. package/src/components/accessibility/AccessibilityReviewDialog.tsx +7 -2
  53. package/src/components/accessibility/accessibilityReview.test.ts +11 -4
  54. package/src/components/accessibility/accessibilityReview.ts +18 -10
  55. package/src/components/agent-feedback/ScreenAnnotationAgentDialog.tsx +9 -2
  56. package/src/components/agents/AgentContextUsageBar.tsx +5 -3
  57. package/src/components/agents/AgentDrawerPanel.test.tsx +15 -3
  58. package/src/components/agents/AgentMessageBubble.tsx +1 -3
  59. package/src/components/agents/AgentQuestionPromptList.tsx +3 -3
  60. package/src/components/agents/AgentToolApprovalActions.tsx +1 -3
  61. package/src/components/agents/agentPanelStyles.ts +1 -3
  62. package/src/components/agents/agentToolDisplay.ts +4 -1
  63. package/src/components/assets/asset-library/AssetLibraryDialog.tsx +2 -0
  64. package/src/components/assets/asset-library/AssetLibraryWorkspace.tsx +2 -0
  65. package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.test.tsx +40 -0
  66. package/src/components/assets/asset-library/detail/AssetLibraryDetailHeader.tsx +7 -3
  67. package/src/components/assets/asset-library/detail/AssetLibraryDetailPreview.tsx +8 -8
  68. package/src/components/assets/asset-library/hooks/useAssetLibraryDialog.ts +13 -2
  69. package/src/components/assets/asset-library/hooks/useAssetLibraryMutations.ts +18 -1
  70. package/src/components/assets/asset-library/sidebar/AssetLibraryListRow.tsx +9 -6
  71. package/src/components/assets/asset-library/sidebar/AssetLibrarySidebarToolbar.tsx +3 -1
  72. package/src/components/assets/asset-library/sidebar/AssetListThumbnail.tsx +1 -1
  73. package/src/components/assets/asset-library/types.ts +6 -0
  74. package/src/components/chrome/OverlayActionCapsule.tsx +2 -2
  75. package/src/components/chrome/PanelTabStrip.tsx +3 -2
  76. package/src/components/chrome/PureAppWordmark.tsx +15 -15
  77. package/src/components/chrome/WorkspaceTabStrip.tsx +19 -14
  78. package/src/components/chrome/documentChromePolicy.test.ts +34 -0
  79. package/src/components/chrome/documentChromePolicy.ts +15 -0
  80. package/src/components/chrome/index.ts +4 -0
  81. package/src/components/chrome/workspaceTabTypes.ts +2 -0
  82. package/src/components/common/buttons/Button.tsx +60 -10
  83. package/src/components/common/buttons/ChoiceChip.tsx +2 -2
  84. package/src/components/common/buttons/IconButton.tsx +26 -0
  85. package/src/components/common/buttons/SegmentedControl.tsx +23 -7
  86. package/src/components/common/canvas/CanvasElementFrame.tsx +37 -28
  87. package/src/components/common/canvas/canvasGeometry.test.ts +4 -5
  88. package/src/components/common/canvas/canvasGeometry.ts +1 -4
  89. package/src/components/common/canvas/useCanvasDragResize.test.tsx +10 -10
  90. package/src/components/common/canvas/useCanvasDragResize.ts +1 -4
  91. package/src/components/common/cards/OpenReviewCard.tsx +6 -6
  92. package/src/components/common/chat/ChatBox.test.tsx +9 -1
  93. package/src/components/common/chat/ChatBox.tsx +3 -4
  94. package/src/components/common/chat/ChatMarkdown.tsx +1 -1
  95. package/src/components/common/chat/ChatModelMenu.tsx +1 -1
  96. package/src/components/common/chat/ChatThinkingIndicator.tsx +1 -1
  97. package/src/components/common/chat/ChatThread.tsx +2 -1
  98. package/src/components/common/chat/ChatToolRow.tsx +2 -2
  99. package/src/components/common/chat/ChatUserBubble.tsx +1 -1
  100. package/src/components/common/connections/ConnectionSetup.tsx +6 -6
  101. package/src/components/common/containers/AppFrame.test.tsx +37 -36
  102. package/src/components/common/containers/AppFrame.tsx +15 -0
  103. package/src/components/common/containers/AppHeader.tsx +6 -3
  104. package/src/components/common/containers/SurfacePanel.tsx +1 -0
  105. package/src/components/common/containers/useOpacityPresence.ts +10 -15
  106. package/src/components/common/context/ContextSelector.tsx +10 -10
  107. package/src/components/common/desk/CreationDesk.tsx +23 -11
  108. package/src/components/common/desk/DailyBrief.tsx +18 -7
  109. package/src/components/common/desk/DeskCard.tsx +11 -6
  110. package/src/components/common/dropdown/MenuButtonDropdown.tsx +58 -6
  111. package/src/components/common/dropdown/MenuDropdownItem.tsx +23 -3
  112. package/src/components/common/dropdown/MenuPanel.tsx +8 -8
  113. package/src/components/common/dropdown/SelectMenu.tsx +8 -3
  114. package/src/components/common/dropdown/menuTypes.ts +2 -1
  115. package/src/components/common/evidence/StructuredEvidenceView.tsx +9 -5
  116. package/src/components/common/feedback/Badge.tsx +19 -5
  117. package/src/components/common/feedback/CapabilityPills.tsx +1 -1
  118. package/src/components/common/feedback/InfoHint.tsx +2 -2
  119. package/src/components/common/feedback/PlatformChip.tsx +9 -9
  120. package/src/components/common/feedback/QuietPill.tsx +5 -8
  121. package/src/components/common/feedback/WorkProgressPanel.tsx +14 -14
  122. package/src/components/common/files/FileTable.tsx +8 -2
  123. package/src/components/common/inputs/Checkbox.tsx +1 -1
  124. package/src/components/common/inputs/EditableSecretField.tsx +1 -3
  125. package/src/components/common/inputs/InlineComposer.tsx +2 -2
  126. package/src/components/common/inputs/PaletteDropdown.tsx +33 -23
  127. package/src/components/common/inputs/SurfacePalettePicker.tsx +1 -1
  128. package/src/components/common/inputs/ToggleSwitch.tsx +2 -2
  129. package/src/components/common/inputs/WorkspacePicker.tsx +3 -3
  130. package/src/components/common/lists/listRowStyles.ts +4 -2
  131. package/src/components/common/lists/quiet-ledger/index.ts +1 -4
  132. package/src/components/common/lists/reorderable/DragHandle.tsx +1 -1
  133. package/src/components/common/lists/reorderable/ReorderableSections.tsx +2 -1
  134. package/src/components/common/media/ImageReferencePicker.tsx +22 -14
  135. package/src/components/common/narrative/NarrativeMention.tsx +15 -9
  136. package/src/components/common/navigation/NavigationCardRow.tsx +2 -2
  137. package/src/components/common/navigation/UnderlineTabs.tsx +1 -0
  138. package/src/components/common/overlays/Modal.tsx +52 -3
  139. package/src/components/common/overlays/ObjectActionStrip.tsx +2 -2
  140. package/src/components/common/people/AutoUpdateReviewList.tsx +2 -2
  141. package/src/components/common/people/EntityList.tsx +7 -3
  142. package/src/components/common/people/EntityPortrait.tsx +6 -1
  143. package/src/components/common/people/LinkedDossierList.tsx +3 -1
  144. package/src/components/common/people/RelationshipMap.tsx +3 -9
  145. package/src/components/common/research/EvidenceDossier.tsx +24 -20
  146. package/src/components/common/tiles/CatalogCard.tsx +1 -1
  147. package/src/components/credentials/CredentialsPanel.tsx +2 -6
  148. package/src/components/data/DataChart.tsx +119 -94
  149. package/src/components/data/dataTable.ts +4 -1
  150. package/src/components/editor/DocumentAppChrome.tsx +172 -0
  151. package/src/components/editor/EditorCommentPromptDialog.tsx +1 -1
  152. package/src/components/editor/EditorLinkPromptDialog.tsx +1 -1
  153. package/src/components/print-design/PrintDesignPanel.test.tsx +8 -6
  154. package/src/components/print-design/PrintDesignPanel.tsx +18 -25
  155. package/src/components/proofing/PagedProofDialog.tsx +17 -4
  156. package/src/editor/EditorViewModeToggle.tsx +6 -2
  157. package/src/editor/index.ts +6 -0
  158. package/src/theme/ThemeProvider.tsx +5 -2
  159. package/src/theme/appAccents.test.ts +51 -0
  160. package/src/theme/appAccents.ts +151 -88
  161. package/src/theme/appIdentityCss.mjs +256 -0
  162. package/src/theme/appIdentityCss.ts +256 -0
  163. package/src/theme/composePlatformTheme.test.ts +43 -14
  164. package/src/theme/platformFont.d.mts +2 -2
  165. package/src/theme/platformFont.mjs +4 -3
  166. package/src/theme/reportsShellChromeSelectors.ts +14 -132
  167. package/src/theme/surfaceCss.mjs +37 -0
  168. package/src/theme/surfaceCss.ts +37 -0
  169. package/src/theme/surfacePalettes.ts +120 -79
  170. package/src/theme/surfaceRoleSelectors.ts +135 -71
  171. package/src/theme/themes/dark.ts +44 -43
  172. package/src/theme/themes/light.ts +40 -38
  173. package/src/theme/themes/palette.ts +32 -30
  174. package/src/theme/themes/shared.ts +17 -17
  175. package/src/theme/utils/GlobalStyles.ts +10 -6
  176. package/src/theme/utils/appFrameDocumentStyles.mjs +6 -1
  177. package/src/theme/utils/cssVariables.ts +169 -0
  178. package/src/writing/DraftAssistantDialog.tsx +85 -85
  179. package/src/writing/WritingStyleManager.tsx +6 -3
  180. package/src/writing/draftTextWithAgent.ts +47 -50
  181. package/src/writing/styleStore.ts +4 -3
  182. package/src/writing/writingStyle.test.ts +8 -2
  183. package/src/writing/writingStyle.ts +19 -8
@@ -22,11 +22,13 @@ const Wrap = styled.div<{ $variant: 'standalone' | 'embedded' }>`
22
22
  gap: 10px;
23
23
  padding-top: ${({ $variant }) => ($variant === 'embedded' ? '0' : '14px')};
24
24
  border-top: ${({ $variant }) =>
25
- $variant === 'embedded' ? '0' : '1px solid rgb(127 127 127 / 16%)'};
25
+ $variant === 'embedded'
26
+ ? '0'
27
+ : '1px solid var(--platform-colors-border, #e7e4dd)'};
26
28
  outline: none;
27
29
 
28
30
  &:focus-within {
29
- border-top-color: rgb(127 127 127 / 34%);
31
+ border-top-color: var(--platform-colors-border-strong, #bdb8ad);
30
32
  }
31
33
  `
32
34
 
@@ -37,11 +39,13 @@ const Head = styled.div<{ $variant: 'standalone' | 'embedded' }>`
37
39
  gap: 14px;
38
40
  padding-top: ${({ $variant }) => ($variant === 'embedded' ? '10px' : '0')};
39
41
  border-top: ${({ $variant }) =>
40
- $variant === 'embedded' ? '1px solid rgb(127 127 127 / 12%)' : '0'};
42
+ $variant === 'embedded'
43
+ ? '1px solid var(--platform-colors-divider, #f0ede7)'
44
+ : '0'};
41
45
  `
42
46
 
43
47
  const Label = styled.div`
44
- color: rgb(104 112 123);
48
+ color: var(--platform-colors-text-secondary, #6b665e);
45
49
  font-size: 12px;
46
50
  font-weight: 800;
47
51
  letter-spacing: 0.06em;
@@ -51,7 +55,7 @@ const Label = styled.div`
51
55
  const Description = styled.p`
52
56
  margin: 0;
53
57
  max-width: 560px;
54
- color: rgb(104 112 123);
58
+ color: var(--platform-colors-text-secondary, #6b665e);
55
59
  font-size: 12.5px;
56
60
  line-height: 1.45;
57
61
  `
@@ -74,15 +78,19 @@ const Grid = styled.div`
74
78
  const PasteTarget = styled.div`
75
79
  min-height: 58px;
76
80
  padding: 11px 13px;
77
- border: 1px dashed rgb(127 127 127 / 28%);
78
- border-radius: 7px;
79
- color: rgb(104 112 123);
81
+ border: 1px dashed var(--platform-colors-border-strong, #bdb8ad);
82
+ border-radius: var(--platform-radius-sm, 0px);
83
+ color: var(--platform-colors-text-secondary, #6b665e);
80
84
  font-size: 13px;
81
85
  line-height: 1.45;
82
- background: rgb(255 255 255 / 26%);
86
+ background: color-mix(
87
+ in srgb,
88
+ var(--platform-colors-surface, #ffffff) 72%,
89
+ transparent
90
+ );
83
91
 
84
92
  &:focus {
85
- border-color: rgb(127 127 127 / 48%);
93
+ border-color: var(--platform-colors-focus, #1c1a17);
86
94
  outline: none;
87
95
  }
88
96
  `
@@ -98,9 +106,9 @@ const Thumb = styled.img`
98
106
  width: 100%;
99
107
  aspect-ratio: 16 / 10;
100
108
  object-fit: cover;
101
- border: 1px solid rgb(127 127 127 / 18%);
102
- border-radius: 3px;
103
- background: rgb(127 127 127 / 8%);
109
+ border: 1px solid var(--platform-colors-border, #e7e4dd);
110
+ border-radius: var(--platform-radius-sm, 0px);
111
+ background: var(--platform-colors-surface-hover, #f0ede7);
104
112
  `
105
113
 
106
114
  const Caption = styled.figcaption`
@@ -108,7 +116,7 @@ const Caption = styled.figcaption`
108
116
  align-items: center;
109
117
  justify-content: space-between;
110
118
  gap: 8px;
111
- color: rgb(79 88 100);
119
+ color: var(--platform-colors-text-secondary, #6b665e);
112
120
  font-size: 12px;
113
121
  line-height: 1.25;
114
122
 
@@ -19,10 +19,13 @@ export const MentionButton = styled.button<{ $dim?: boolean }>`
19
19
  display: inline;
20
20
  padding: 0;
21
21
  border: 0;
22
- border-bottom: 1px solid var(--narrative-underline, rgba(127, 127, 127, 0.4));
22
+ border-bottom: 1px solid
23
+ var(--narrative-underline, var(--platform-colors-border-strong, #bdb8ad));
23
24
  background: transparent;
24
25
  color: ${({ $dim }) =>
25
- $dim ? 'var(--narrative-faint, #9aa2ad)' : 'var(--narrative-ink, inherit)'};
26
+ $dim
27
+ ? 'var(--narrative-faint, var(--platform-colors-text-tertiary, #8f897f))'
28
+ : 'var(--narrative-ink, inherit)'};
26
29
  font: inherit;
27
30
  font-weight: 500;
28
31
  cursor: pointer;
@@ -41,10 +44,12 @@ export const MentionHoverCard = styled.span`
41
44
  min-width: 240px;
42
45
  max-width: 330px;
43
46
  padding: 12px 14px;
44
- border: 1px solid rgba(127, 127, 127, 0.28);
45
- border-radius: 6px;
46
- background: var(--narrative-card, #fff);
47
- box-shadow: 0 14px 34px rgba(38, 46, 55, 0.14);
47
+ border: 1px solid
48
+ var(--narrative-border, var(--platform-colors-border, #e7e4dd));
49
+ border-radius: var(--platform-radius-sm, 0px);
50
+ background: var(--narrative-card, var(--platform-colors-surface, #ffffff));
51
+ box-shadow: 0 14px 34px
52
+ color-mix(in srgb, var(--platform-colors-text, #1c1a17) 14%, transparent);
48
53
  font-size: 12px;
49
54
  font-weight: 400;
50
55
  line-height: 1.55;
@@ -61,14 +66,15 @@ export const MentionHoverTitle = styled.span`
61
66
  export const MentionHoverLine = styled.span`
62
67
  display: block;
63
68
  margin-top: 3px;
64
- color: var(--narrative-muted, #737b86);
69
+ color: var(--narrative-muted, var(--platform-colors-text-secondary, #6b665e));
65
70
  `
66
71
 
67
72
  export const MentionHoverNote = styled.span`
68
73
  display: block;
69
74
  margin-top: 8px;
70
75
  padding-left: 8px;
71
- border-left: 2px solid var(--narrative-accent, #525a65);
72
- color: var(--narrative-muted, #737b86);
76
+ border-left: 2px solid
77
+ var(--narrative-accent, var(--platform-colors-accent, #1c1a17));
78
+ color: var(--narrative-muted, var(--platform-colors-text-secondary, #6b665e));
73
79
  font-style: italic;
74
80
  `
@@ -26,14 +26,14 @@ const StyledRow = styled.button<{ $active?: boolean }>`
26
26
  border: 1px solid
27
27
  ${({ $active }) =>
28
28
  $active
29
- ? 'color-mix(in srgb, var(--platform-colors-focus, #0f766e) 72%, var(--platform-colors-border, #d8dfde))'
29
+ ? 'color-mix(in srgb, var(--platform-colors-focus, var(--platform-colors-accent, #1c1a17)) 72%, var(--platform-colors-border, #e7e4dd))'
30
30
  : 'var(--platform-colors-border-subtle, #ebeeee)'};
31
31
  border-radius: var(--platform-radius-sm, 8px);
32
32
  padding: var(--platform-spacing-sm, 8px);
33
33
  color: var(--platform-colors-text, #20272b);
34
34
  background: ${({ $active }) =>
35
35
  $active
36
- ? 'color-mix(in srgb, var(--platform-colors-focus, #0f766e) 8%, var(--platform-colors-surface, #fff))'
36
+ ? 'color-mix(in srgb, var(--platform-colors-focus, var(--platform-colors-accent, #1c1a17)) 8%, var(--platform-colors-surface, #ffffff))'
37
37
  : 'var(--platform-colors-surface, #fff)'};
38
38
  text-align: left;
39
39
  cursor: pointer;
@@ -65,6 +65,7 @@ export function UnderlineTabs({
65
65
  const active = item.id === activeId
66
66
  return (
67
67
  <StyledTab
68
+ key={item.id}
68
69
  type="button"
69
70
  $active={active}
70
71
  aria-current={active}
@@ -9,8 +9,10 @@ import {
9
9
  type ReactNode,
10
10
  } from 'react'
11
11
  import { createPortal } from 'react-dom'
12
+ import { X } from 'lucide-react'
12
13
  import { keyframes, styled } from 'styled-components'
13
14
  import { zi } from '../../../theme/themeVars.js'
15
+ import { PlatformIcon } from '../../chrome/PlatformIcon.js'
14
16
  import { ModalChromeHeader } from './ModalChromeHeader.js'
15
17
 
16
18
  export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen'
@@ -93,6 +95,10 @@ const StyledBackdrop = styled.div<{ $fullscreen: boolean }>`
93
95
  justify-content: ${({ $fullscreen }) => ($fullscreen ? 'stretch' : 'center')};
94
96
  padding: ${({ $fullscreen }) =>
95
97
  $fullscreen ? '0' : 'var(--platform-spacing-md)'};
98
+ background: ${({ $fullscreen }) =>
99
+ $fullscreen
100
+ ? 'transparent'
101
+ : 'var(--platform-colors-scrim, rgba(28, 26, 23, 0.42))'};
96
102
  animation: ${fadeIn} var(--platform-transition-fast);
97
103
 
98
104
  @media (prefers-reduced-motion: reduce) {
@@ -133,7 +139,7 @@ const StyledDialog = styled.div<{ $size: ModalSize; $chrome: boolean }>`
133
139
  color: var(--platform-colors-text);
134
140
  border: ${({ $size }) =>
135
141
  $size === 'fullscreen' ? '0' : '1px solid var(--platform-colors-border)'};
136
- border-radius: ${({ $size }) => ($size === 'fullscreen' ? '0' : '1rem')};
142
+ border-radius: 0;
137
143
  box-shadow: ${({ $size }) =>
138
144
  $size === 'fullscreen' ? 'none' : 'var(--platform-shadow-md)'};
139
145
  animation: ${fadeIn} var(--platform-transition-fast);
@@ -147,15 +153,48 @@ const StyledDialog = styled.div<{ $size: ModalSize; $chrome: boolean }>`
147
153
  }
148
154
  `
149
155
 
156
+ const StyledPlainHeader = styled.header`
157
+ display: flex;
158
+ flex: 0 0 auto;
159
+ align-items: center;
160
+ justify-content: space-between;
161
+ gap: var(--platform-spacing-md);
162
+ padding: var(--platform-modal-inset);
163
+ border-bottom: 1px solid var(--platform-colors-border);
164
+ `
165
+
150
166
  const StyledTitle = styled.h2`
151
167
  flex: 0 0 auto;
152
168
  margin: 0;
153
- padding: var(--platform-modal-inset);
154
169
  font-size: var(--platform-typography-font-size-lg);
155
170
  font-weight: var(--platform-typography-font-weight-bold);
156
171
  line-height: var(--platform-typography-line-height-tight);
157
172
  `
158
173
 
174
+ const StyledPlainClose = styled.button`
175
+ display: inline-flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ width: 28px;
179
+ height: 28px;
180
+ flex: 0 0 auto;
181
+ border: 0;
182
+ border-radius: 0;
183
+ background: transparent;
184
+ color: var(--platform-colors-text-secondary);
185
+ cursor: pointer;
186
+
187
+ &:hover {
188
+ background: var(--platform-colors-surface-hover);
189
+ color: var(--platform-colors-text);
190
+ }
191
+
192
+ &:focus-visible {
193
+ outline: 1px solid var(--platform-colors-focus);
194
+ outline-offset: 2px;
195
+ }
196
+ `
197
+
159
198
  const StyledBody = styled.div<{ $fullscreen: boolean }>`
160
199
  display: flex;
161
200
  flex-direction: column;
@@ -280,7 +319,17 @@ export function Modal({
280
319
  trailing={chromeTrailing}
281
320
  />
282
321
  ) : title ? (
283
- <StyledTitle id={titleId}>{title}</StyledTitle>
322
+ <StyledPlainHeader>
323
+ <StyledTitle id={titleId}>{title}</StyledTitle>
324
+ <StyledPlainClose
325
+ type="button"
326
+ aria-label="Close"
327
+ title="Close"
328
+ onClick={onClose}
329
+ >
330
+ <PlatformIcon icon={X} size={16} strokeWidth={1.75} />
331
+ </StyledPlainClose>
332
+ </StyledPlainHeader>
284
333
  ) : null}
285
334
  <StyledBody className={bodyClassName} $fullscreen={fullscreen}>
286
335
  {children}
@@ -20,7 +20,7 @@ const Strip = styled.div`
20
20
  align-items: center;
21
21
  padding: 3px 4px;
22
22
  border: 1px solid rgb(35 40 45 / 12%);
23
- border-radius: 999px;
23
+ border-radius: var(--platform-radius-sm);
24
24
  background: rgb(255 255 255 / 72%);
25
25
  color: rgb(35 40 45 / 68%);
26
26
  box-shadow: 0 6px 18px rgb(20 26 33 / 6%);
@@ -30,7 +30,7 @@ const Strip = styled.div`
30
30
  const Action = styled.button`
31
31
  appearance: none;
32
32
  border: 0;
33
- border-radius: 999px;
33
+ border-radius: var(--platform-radius-sm);
34
34
  background: transparent;
35
35
  color: inherit;
36
36
  font: inherit;
@@ -30,7 +30,7 @@ const Card = styled.div`
30
30
  display: grid;
31
31
  gap: 10px;
32
32
  padding: 14px 16px;
33
- border-radius: 8px;
33
+ border-radius: var(--platform-radius-md, 0px);
34
34
  background: color-mix(
35
35
  in srgb,
36
36
  var(--platform-colors-accent-muted) 46%,
@@ -55,7 +55,7 @@ const Badge = styled.span`
55
55
  width: fit-content;
56
56
  padding: 2px 7px;
57
57
  border: 1px solid var(--platform-colors-border);
58
- border-radius: var(--platform-radius-full);
58
+ border-radius: var(--platform-radius-sm);
59
59
  background: var(--platform-colors-surface);
60
60
  color: var(--platform-colors-text);
61
61
  font-size: 10px;
@@ -30,14 +30,18 @@ const Row = styled.button<{ $active?: boolean }>`
30
30
  width: 100%;
31
31
  padding: 10px 0 10px 12px;
32
32
  border: 0;
33
- border-left: 2px solid
33
+ border-left: 3px solid
34
34
  ${({ $active }) =>
35
- $active ? 'var(--platform-colors-text)' : 'transparent'};
35
+ $active ? 'var(--app-acc, var(--platform-colors-text))' : 'transparent'};
36
36
  border-radius: 0;
37
37
  background: ${({ $active }) =>
38
38
  $active
39
- ? 'color-mix(in srgb, var(--platform-colors-surface-hover) 62%, transparent)'
39
+ ? 'color-mix(in srgb, var(--app-bg, var(--platform-colors-surface-hover)) 28%, transparent)'
40
40
  : 'transparent'};
41
+ box-shadow: ${({ $active }) =>
42
+ $active
43
+ ? 'inset 3px 0 0 var(--app-acc, var(--platform-colors-text))'
44
+ : 'none'};
41
45
  color: inherit;
42
46
  font: inherit;
43
47
  text-align: left;
@@ -48,7 +48,12 @@ export function EntityPortrait({
48
48
  aria-label={`${kind} image for ${name}`}
49
49
  >
50
50
  {imageUrl ? (
51
- <Image src={imageUrl} alt="" loading="lazy" referrerPolicy="no-referrer" />
51
+ <Image
52
+ src={imageUrl}
53
+ alt=""
54
+ loading="lazy"
55
+ referrerPolicy="no-referrer"
56
+ />
52
57
  ) : (
53
58
  initials(name)
54
59
  )}
@@ -81,7 +81,9 @@ export function LinkedDossierList({
81
81
  <Meta>{dossier.appSlug}</Meta>
82
82
  </Head>
83
83
  {dossier.summary ? <Summary>{dossier.summary}</Summary> : null}
84
- {dossier.updatedAt ? <Meta>{formatDate(dossier.updatedAt)}</Meta> : null}
84
+ {dossier.updatedAt ? (
85
+ <Meta>{formatDate(dossier.updatedAt)}</Meta>
86
+ ) : null}
85
87
  </Item>
86
88
  ))}
87
89
  </List>
@@ -62,9 +62,7 @@ const GraphSvg = styled.svg`
62
62
 
63
63
  const EdgeLine = styled.line<{ $active?: boolean }>`
64
64
  stroke: ${({ $active }) =>
65
- $active
66
- ? 'var(--platform-colors-text)'
67
- : 'var(--platform-colors-border)'};
65
+ $active ? 'var(--platform-colors-text)' : 'var(--platform-colors-border)'};
68
66
  stroke-width: ${({ $active }) => ($active ? 2 : 1.2)};
69
67
  opacity: ${({ $active }) => ($active ? 0.54 : 0.82)};
70
68
  `
@@ -93,9 +91,7 @@ const NodeShape = styled.circle<{
93
91
  $active?: boolean
94
92
  }>`
95
93
  fill: ${({ $active }) =>
96
- $active
97
- ? 'var(--platform-colors-text)'
98
- : 'var(--platform-colors-surface)'};
94
+ $active ? 'var(--platform-colors-text)' : 'var(--platform-colors-surface)'};
99
95
  stroke: ${({ $active, $kind }) =>
100
96
  $active
101
97
  ? 'var(--platform-colors-text)'
@@ -312,9 +308,7 @@ function layoutNodes(
312
308
  return (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0)
313
309
  })
314
310
  const active = sorted.find(node => node.active)
315
- const outer = active
316
- ? sorted.filter(node => node.id !== active.id)
317
- : sorted
311
+ const outer = active ? sorted.filter(node => node.id !== active.id) : sorted
318
312
  const ringRadiusX = outer.length > 5 ? 245 : 215
319
313
  const ringRadiusY = outer.length > 5 ? 116 : 104
320
314
 
@@ -85,12 +85,16 @@ function formatUpdatedAt(value?: string): string | null {
85
85
  if (!value) return null
86
86
  const date = new Date(value)
87
87
  if (Number.isNaN(date.getTime())) return value
88
- return new Intl.DateTimeFormat(undefined, {
88
+ const monthDayYear = new Intl.DateTimeFormat('en-US', {
89
89
  month: 'short',
90
90
  day: 'numeric',
91
+ year: 'numeric',
92
+ }).format(date)
93
+ const time = new Intl.DateTimeFormat('en-US', {
91
94
  hour: 'numeric',
92
95
  minute: '2-digit',
93
96
  }).format(date)
97
+ return `${monthDayYear} · ${time}`
94
98
  }
95
99
 
96
100
  function normalizeEvidenceSource(
@@ -159,7 +163,7 @@ const Dossier = styled.article`
159
163
  gap: 24px;
160
164
  min-width: 0;
161
165
  position: relative;
162
- color: var(--platform-colors-text, #2e3338);
166
+ color: var(--platform-colors-text, #1c1a17);
163
167
  `
164
168
 
165
169
  const Header = styled.header`
@@ -187,7 +191,7 @@ const ModeSwitch = styled.div`
187
191
  gap: 4px;
188
192
  padding: 3px;
189
193
  border: 1px solid var(--platform-colors-border, rgb(46 51 56 / 10%));
190
- border-radius: 999px;
194
+ border-radius: var(--platform-radius-sm);
191
195
  background: var(--platform-colors-surface, rgb(255 254 250 / 86%));
192
196
  box-shadow: var(--platform-shadows-sm, 0 10px 30px rgb(46 51 56 / 8%));
193
197
  backdrop-filter: blur(10px);
@@ -210,13 +214,13 @@ const ModeDescription = styled.div`
210
214
  const ModeButton = styled.button<{ $active: boolean }>`
211
215
  min-height: 26px;
212
216
  border: 0;
213
- border-radius: 999px;
217
+ border-radius: var(--platform-radius-sm);
214
218
  background: ${({ $active }) =>
215
219
  $active ? 'var(--platform-colors-surface-hover)' : 'transparent'};
216
220
  padding: 0 10px;
217
221
  color: ${({ $active }) =>
218
222
  $active
219
- ? 'var(--platform-colors-text, #2e3338)'
223
+ ? 'var(--platform-colors-text, #1c1a17)'
220
224
  : 'var(--platform-colors-text-secondary, #8f98a4)'};
221
225
  font: inherit;
222
226
  font-size: 12px;
@@ -225,7 +229,7 @@ const ModeButton = styled.button<{ $active: boolean }>`
225
229
  `
226
230
 
227
231
  const Kicker = styled.div`
228
- color: var(--platform-colors-text-secondary, #9aa2ad);
232
+ color: var(--platform-colors-text-secondary, #8f897f);
229
233
  font-size: 11px;
230
234
  font-weight: 800;
231
235
  letter-spacing: 0.08em;
@@ -271,13 +275,13 @@ const TitleInput = styled.textarea`
271
275
 
272
276
  const Question = styled.div`
273
277
  max-width: 72ch;
274
- color: var(--platform-colors-text-secondary, #68717c);
278
+ color: var(--platform-colors-text-secondary, #6b665e);
275
279
  font-size: 14px;
276
280
  line-height: 1.55;
277
281
  `
278
282
 
279
283
  const UpdatedStamp = styled.div`
280
- color: var(--platform-colors-text-secondary, #9aa2ad);
284
+ color: var(--platform-colors-text-secondary, #8f897f);
281
285
  font-size: 11px;
282
286
  font-weight: 750;
283
287
  letter-spacing: 0.05em;
@@ -294,7 +298,7 @@ const Narrative = styled.section`
294
298
 
295
299
  const Lead = styled.div`
296
300
  margin: 0;
297
- color: var(--platform-colors-text, #2e3338);
301
+ color: var(--platform-colors-text, #1c1a17);
298
302
  font-size: clamp(18px, 1.6vw, 22px);
299
303
  line-height: 1.58;
300
304
  `
@@ -320,7 +324,7 @@ const Finding = styled.article`
320
324
  `
321
325
 
322
326
  const FindingNumber = styled.div`
323
- color: var(--platform-colors-text-secondary, #9aa2ad);
327
+ color: var(--platform-colors-text-secondary, #8f897f);
324
328
  font-size: 13px;
325
329
  font-weight: 800;
326
330
  letter-spacing: 0.05em;
@@ -367,7 +371,7 @@ const DeleteAction = styled.button`
367
371
  padding: 0;
368
372
  border: 0;
369
373
  background: transparent;
370
- color: var(--platform-colors-text-secondary, #9aa2ad);
374
+ color: var(--platform-colors-text-secondary, #8f897f);
371
375
  font: inherit;
372
376
  font-size: 11px;
373
377
  font-weight: 800;
@@ -395,7 +399,7 @@ const Confidence = styled.span<{ $strength: EvidenceStrength }>`
395
399
  ? '#3d6b4a'
396
400
  : $strength === 'weak'
397
401
  ? '#9a694f'
398
- : 'var(--platform-colors-text-secondary, #68717c)'};
402
+ : 'var(--platform-colors-text-secondary, #6b665e)'};
399
403
  font-size: 11px;
400
404
  font-weight: 800;
401
405
  letter-spacing: 0.05em;
@@ -405,7 +409,7 @@ const Confidence = styled.span<{ $strength: EvidenceStrength }>`
405
409
  const Claim = styled.p`
406
410
  max-width: 76ch;
407
411
  margin: 0;
408
- color: var(--platform-colors-text, #2e3338);
412
+ color: var(--platform-colors-text, #1c1a17);
409
413
  font-size: 14.5px;
410
414
  line-height: 1.72;
411
415
  `
@@ -418,7 +422,7 @@ const Annotation = styled.aside`
418
422
  max-width: 72ch;
419
423
  border-left: 3px solid rgb(82 90 101 / 36%);
420
424
  padding: 4px 0 4px 14px;
421
- color: var(--platform-colors-text-secondary, #68717c);
425
+ color: var(--platform-colors-text-secondary, #6b665e);
422
426
  font-size: 13px;
423
427
  line-height: 1.55;
424
428
  `
@@ -445,7 +449,7 @@ const EvidenceHandle = styled.button<{ $strength: EvidenceStrength }>`
445
449
  ? '#3d6b4a'
446
450
  : $strength === 'weak'
447
451
  ? '#9a694f'
448
- : 'var(--platform-colors-text-secondary, #68717c)'};
452
+ : 'var(--platform-colors-text-secondary, #6b665e)'};
449
453
  font: inherit;
450
454
  font-size: 0.78em;
451
455
  font-weight: 750;
@@ -485,7 +489,7 @@ const AuditList = styled.section`
485
489
 
486
490
  const AuditIntro = styled.div`
487
491
  max-width: 70ch;
488
- color: var(--platform-colors-text-secondary, #68717c);
492
+ color: var(--platform-colors-text-secondary, #6b665e);
489
493
  font-size: 13px;
490
494
  line-height: 1.55;
491
495
  `
@@ -500,7 +504,7 @@ const EvidenceCard = styled.div`
500
504
  gap: 8px;
501
505
  min-width: 0;
502
506
  border: 1px solid var(--platform-colors-border, rgb(46 51 56 / 10%));
503
- border-radius: 8px;
507
+ border-radius: var(--platform-radius-md, 0px);
504
508
  background: var(--platform-colors-surface, rgb(255 255 255 / 56%));
505
509
  padding: 12px 13px;
506
510
  `
@@ -523,7 +527,7 @@ const EvidenceLabel = styled.span`
523
527
  const EvidenceTitle = styled.a`
524
528
  min-width: 0;
525
529
  overflow: hidden;
526
- color: var(--platform-colors-text, #2e3338);
530
+ color: var(--platform-colors-text, #1c1a17);
527
531
  font-size: 14px;
528
532
  font-weight: 750;
529
533
  line-height: 1.3;
@@ -541,7 +545,7 @@ const EvidenceTitle = styled.a`
541
545
  `
542
546
 
543
547
  const EvidenceNote = styled.div`
544
- color: var(--platform-colors-text-secondary, #68717c);
548
+ color: var(--platform-colors-text-secondary, #6b665e);
545
549
  font-size: 13px;
546
550
  line-height: 1.45;
547
551
  `
@@ -579,7 +583,7 @@ const QuietListItems = styled.div`
579
583
  `
580
584
 
581
585
  const QuietListItem = styled.div`
582
- color: var(--platform-colors-text-secondary, #68717c);
586
+ color: var(--platform-colors-text-secondary, #6b665e);
583
587
  font-size: 14px;
584
588
  line-height: 1.55;
585
589
  `
@@ -59,7 +59,7 @@ const StyledStatusBadge = styled.span<{ $active: boolean }>`
59
59
  flex: 0 0 auto;
60
60
  align-self: flex-start;
61
61
  padding: 2px var(--platform-spacing-sm);
62
- border-radius: var(--platform-radius-full);
62
+ border-radius: var(--platform-radius-sm);
63
63
  background: ${({ $active }) =>
64
64
  $active
65
65
  ? 'var(--platform-colors-accent)'
@@ -177,9 +177,7 @@ export function CredentialsPanel({
177
177
  loading={loading}
178
178
  busy={busyId === entry.id}
179
179
  storageBlocked={storageBlocked}
180
- onSave={value =>
181
- run(entry.id, () => onSave(entry.id, value))
182
- }
180
+ onSave={value => run(entry.id, () => onSave(entry.id, value))}
183
181
  onDelete={() => run(entry.id, () => onDelete(entry.id))}
184
182
  />
185
183
  ))}
@@ -219,9 +217,7 @@ export function CredentialsPanel({
219
217
  disabled={loading || storageBlocked}
220
218
  busy={busy}
221
219
  aria-label={`${entry.label} API key`}
222
- onSave={value =>
223
- run(entry.id, () => onSave(entry.id, value))
224
- }
220
+ onSave={value => run(entry.id, () => onSave(entry.id, value))}
225
221
  onRemove={
226
222
  entry.configured
227
223
  ? () => run(entry.id, () => onDelete(entry.id))