nexus-shared 3.1.0 → 4.0.0

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 (234) hide show
  1. package/CHANGELOG.md +2268 -446
  2. package/LICENSE +21 -21
  3. package/README.md +1705 -1084
  4. package/dist/Client.Index.d.ts +17 -0
  5. package/dist/Client.Index.js +17 -0
  6. package/dist/Components/Documents/DocumentFrame.d.ts +50 -0
  7. package/dist/Components/Documents/DocumentFrame.js +83 -0
  8. package/dist/Components/Documents/Menu.d.ts +4 -0
  9. package/dist/Components/Documents/Menu.js +40 -24
  10. package/dist/Components/Documents/PrintDocument.d.ts +95 -0
  11. package/dist/Components/Documents/PrintDocument.js +62 -0
  12. package/dist/Components/Documents/Tabs.d.ts +59 -0
  13. package/dist/Components/Documents/Tabs.js +70 -0
  14. package/dist/Components/Forms/ApiForm.js +19 -2
  15. package/dist/Components/Forms/Crud.d.ts +2 -2
  16. package/dist/Components/Forms/Crud.js +871 -377
  17. package/dist/Components/Forms/CrudActions.d.ts +136 -0
  18. package/dist/Components/Forms/CrudActions.js +184 -0
  19. package/dist/Components/Forms/CrudHistory.d.ts +66 -0
  20. package/dist/Components/Forms/CrudHistory.js +140 -0
  21. package/dist/Components/Forms/CrudNarrowPicker.d.ts +31 -0
  22. package/dist/Components/Forms/CrudNarrowPicker.js +180 -0
  23. package/dist/Components/Forms/CrudParts.d.ts +30 -2
  24. package/dist/Components/Forms/CrudParts.js +56 -5
  25. package/dist/Components/Forms/CrudRowForms.d.ts +26 -0
  26. package/dist/Components/Forms/CrudRowForms.js +114 -0
  27. package/dist/Components/Forms/CrudScopes.d.ts +28 -0
  28. package/dist/Components/Forms/CrudScopes.js +76 -0
  29. package/dist/Components/Forms/CrudTree.d.ts +90 -0
  30. package/dist/Components/Forms/CrudTree.js +363 -0
  31. package/dist/Components/Forms/CrudWorkspace.d.ts +63 -0
  32. package/dist/Components/Forms/CrudWorkspace.js +169 -0
  33. package/dist/Components/Forms/ExcelImport.js +3 -3
  34. package/dist/Components/Forms/Form.d.ts +4 -4
  35. package/dist/Components/Forms/Form.js +125 -16
  36. package/dist/Components/Forms/FormLeaveGuard.d.ts +44 -0
  37. package/dist/Components/Forms/FormLeaveGuard.js +65 -0
  38. package/dist/Components/Forms/RecordFlows.d.ts +50 -0
  39. package/dist/Components/Forms/RecordFlows.js +282 -0
  40. package/dist/Components/Forms/SubmitForm.d.ts +37 -2
  41. package/dist/Components/Forms/SubmitForm.js +195 -10
  42. package/dist/Components/Inputs/CheckBox.js +1 -1
  43. package/dist/Components/Inputs/ChoiceField.d.ts +21 -1
  44. package/dist/Components/Inputs/ChoiceField.js +28 -2
  45. package/dist/Components/Inputs/CodeBox.d.ts +69 -0
  46. package/dist/Components/Inputs/CodeBox.js +316 -0
  47. package/dist/Components/Inputs/DatePicker.js +4 -1
  48. package/dist/Components/Inputs/DateRangePicker.js +4 -1
  49. package/dist/Components/Inputs/DateTimePicker.js +4 -1
  50. package/dist/Components/Inputs/Dropdown.d.ts +13 -0
  51. package/dist/Components/Inputs/Dropdown.js +8 -5
  52. package/dist/Components/Inputs/DropdownParts.d.ts +3 -1
  53. package/dist/Components/Inputs/DropdownParts.js +16 -4
  54. package/dist/Components/Inputs/Field.d.ts +7 -1
  55. package/dist/Components/Inputs/Field.js +2 -2
  56. package/dist/Components/Inputs/GroupForm.d.ts +6 -6
  57. package/dist/Components/Inputs/GroupForm.js +10 -11
  58. package/dist/Components/Inputs/InputRenderer.d.ts +9 -6
  59. package/dist/Components/Inputs/InputRenderer.js +39 -31
  60. package/dist/Components/Inputs/NumberBox.js +4 -2
  61. package/dist/Components/Inputs/PictureInput.d.ts +41 -0
  62. package/dist/Components/Inputs/PictureInput.js +70 -0
  63. package/dist/Components/Inputs/RadioGroup.d.ts +16 -3
  64. package/dist/Components/Inputs/RadioGroup.js +8 -3
  65. package/dist/Components/Inputs/RowsInput.d.ts +1 -1
  66. package/dist/Components/Inputs/RowsInput.js +18 -3
  67. package/dist/Components/Inputs/TabularForm.d.ts +5 -5
  68. package/dist/Components/Inputs/TabularForm.js +29 -29
  69. package/dist/Components/Inputs/TextArea.d.ts +6 -0
  70. package/dist/Components/Inputs/TextArea.js +14 -2
  71. package/dist/Components/Inputs/TextBox.js +4 -1
  72. package/dist/Components/Inputs/TextBoxTypes.d.ts +6 -0
  73. package/dist/Components/Inputs/TextBoxTypes.js +17 -0
  74. package/dist/Components/Inputs/TimePicker.js +4 -1
  75. package/dist/Components/Inputs/TreeView.d.ts +107 -6
  76. package/dist/Components/Inputs/TreeView.js +513 -30
  77. package/dist/Components/Layouts/MessageBox.d.ts +15 -2
  78. package/dist/Components/Layouts/MessageBox.js +56 -7
  79. package/dist/Components/Layouts/Popup.d.ts +13 -6
  80. package/dist/Components/Layouts/Popup.js +37 -9
  81. package/dist/Components/Layouts/PopupDock.d.ts +3 -1
  82. package/dist/Components/Layouts/PopupDock.js +2 -1
  83. package/dist/Components/Layouts/PopupHost.js +5 -4
  84. package/dist/Components/Layouts/ThemePicker.d.ts +3 -2
  85. package/dist/Components/Layouts/ThemePicker.js +16 -4
  86. package/dist/Components/Viewers/DataTable.js +205 -61
  87. package/dist/Components/Viewers/DataTableFilters.d.ts +1 -1
  88. package/dist/Components/Viewers/DataTableFilters.js +17 -2
  89. package/dist/Components/Viewers/DataTableParts.d.ts +46 -12
  90. package/dist/Components/Viewers/DataTableParts.js +62 -21
  91. package/dist/Components/Viewers/OwnerFiles.d.ts +175 -0
  92. package/dist/Components/Viewers/OwnerFiles.js +589 -0
  93. package/dist/Components/Viewers/QrCodeImage.d.ts +22 -0
  94. package/dist/Components/Viewers/QrCodeImage.js +15 -0
  95. package/dist/Components/Viewers/RecordCards.d.ts +16 -0
  96. package/dist/Components/Viewers/RecordCards.js +509 -0
  97. package/dist/Helpers/ApiModules.d.ts +3 -34
  98. package/dist/Helpers/ApiModules.js +3 -3
  99. package/dist/Helpers/ApiRoutes.d.ts +68 -26
  100. package/dist/Helpers/ApiRoutes.js +31 -27
  101. package/dist/Helpers/ArrayHelpers.d.ts +0 -0
  102. package/dist/Helpers/ArrayHelpers.js +2 -0
  103. package/dist/Helpers/BusyHooks.d.ts +6 -0
  104. package/dist/Helpers/BusyHooks.js +39 -0
  105. package/dist/Helpers/CodeHelpers.d.ts +97 -0
  106. package/dist/Helpers/CodeHelpers.js +332 -0
  107. package/dist/Helpers/CrudBackend.d.ts +114 -6
  108. package/dist/Helpers/CrudBackend.js +214 -11
  109. package/dist/Helpers/CrudColumns.d.ts +98 -0
  110. package/dist/Helpers/CrudColumns.js +160 -0
  111. package/dist/Helpers/CrudDetailsTabs.d.ts +58 -0
  112. package/dist/Helpers/CrudDetailsTabs.js +126 -0
  113. package/dist/Helpers/CrudHelpers.d.ts +130 -6
  114. package/dist/Helpers/CrudHelpers.js +304 -12
  115. package/dist/Helpers/CrudNarrowPick.d.ts +83 -0
  116. package/dist/Helpers/CrudNarrowPick.js +157 -0
  117. package/dist/Helpers/CrudRowForms.d.ts +15 -0
  118. package/dist/Helpers/CrudRowForms.js +43 -0
  119. package/dist/Helpers/CrudScopes.d.ts +32 -0
  120. package/dist/Helpers/CrudScopes.js +79 -0
  121. package/dist/Helpers/DropdownHelpers.d.ts +3 -1
  122. package/dist/Helpers/DropdownHelpers.js +6 -2
  123. package/dist/Helpers/ExcelHelpers.d.ts +1 -1
  124. package/dist/Helpers/ExcelHelpers.js +12 -11
  125. package/dist/Helpers/FileAdapter.d.ts +78 -0
  126. package/dist/Helpers/FileAdapter.js +102 -0
  127. package/dist/Helpers/FilePrimaries.d.ts +48 -0
  128. package/dist/Helpers/FilePrimaries.js +138 -0
  129. package/dist/Helpers/FormConfirm.d.ts +32 -0
  130. package/dist/Helpers/FormConfirm.js +40 -0
  131. package/dist/Helpers/FormStore.d.ts +90 -5
  132. package/dist/Helpers/FormStore.js +318 -22
  133. package/dist/Helpers/InputConditions.d.ts +50 -0
  134. package/dist/Helpers/InputConditions.js +168 -0
  135. package/dist/Helpers/InputMemory.d.ts +106 -0
  136. package/dist/Helpers/InputMemory.js +385 -0
  137. package/dist/Helpers/InputNarrowing.d.ts +18 -0
  138. package/dist/Helpers/InputNarrowing.js +67 -0
  139. package/dist/Helpers/InputParamsHelpers.d.ts +44 -1
  140. package/dist/Helpers/InputParamsHelpers.js +162 -71
  141. package/dist/Helpers/MessageBuilder.js +2 -0
  142. package/dist/Helpers/NexusDriveAdapter.d.ts +55 -0
  143. package/dist/Helpers/NexusDriveAdapter.js +207 -0
  144. package/dist/Helpers/NexusHelpers.d.ts +0 -0
  145. package/dist/Helpers/NexusHelpers.js +1 -0
  146. package/dist/Helpers/NumberHelpers.d.ts +95 -0
  147. package/dist/Helpers/NumberHelpers.js +126 -0
  148. package/dist/Helpers/Permissions.js +2 -1
  149. package/dist/Helpers/QrCode.d.ts +26 -0
  150. package/dist/Helpers/QrCode.js +463 -0
  151. package/dist/Helpers/RecordCards.d.ts +205 -0
  152. package/dist/Helpers/RecordCards.js +378 -0
  153. package/dist/Helpers/RequestCache.d.ts +47 -0
  154. package/dist/Helpers/RequestCache.js +132 -0
  155. package/dist/Helpers/RowsStore.d.ts +37 -2
  156. package/dist/Helpers/RowsStore.js +128 -10
  157. package/dist/Helpers/ServerPreview.d.ts +69 -0
  158. package/dist/Helpers/ServerPreview.js +99 -0
  159. package/dist/Helpers/TableColumns.js +4 -3
  160. package/dist/Helpers/TableExport.d.ts +7 -1
  161. package/dist/Helpers/TableExport.js +21 -15
  162. package/dist/Helpers/TableFilters.d.ts +1 -1
  163. package/dist/Helpers/TableFilters.js +24 -23
  164. package/dist/Helpers/TableHelpers.d.ts +24 -3
  165. package/dist/Helpers/TableHelpers.js +58 -12
  166. package/dist/Helpers/TableJoins.d.ts +83 -0
  167. package/dist/Helpers/TableJoins.js +284 -0
  168. package/dist/Helpers/TableStore.d.ts +26 -1
  169. package/dist/Helpers/TableStore.js +73 -7
  170. package/dist/Helpers/TreeStore.d.ts +306 -11
  171. package/dist/Helpers/TreeStore.js +1048 -90
  172. package/dist/Helpers/UserPreferences.d.ts +8 -0
  173. package/dist/Helpers/UserPreferences.js +17 -0
  174. package/dist/Interfaces/CrudInterfaces.d.ts +512 -14
  175. package/dist/Interfaces/FileInterfaces.d.ts +162 -0
  176. package/dist/Interfaces/FileInterfaces.js +4 -0
  177. package/dist/Interfaces/FormInterfaces.d.ts +393 -29
  178. package/dist/Interfaces/FormInterfaces.js +79 -1
  179. package/dist/Interfaces/InputInterfaces.d.ts +39 -3
  180. package/dist/Interfaces/MessageInterfaces.d.ts +1 -1
  181. package/dist/Interfaces/PreferenceInterfaces.d.ts +8 -0
  182. package/dist/Interfaces/PreferenceInterfaces.js +2 -5
  183. package/dist/Interfaces/RecordInterfaces.d.ts +367 -0
  184. package/dist/Interfaces/RecordInterfaces.js +1 -0
  185. package/dist/Interfaces/TableInterfaces.d.ts +160 -5
  186. package/dist/Services/ApiProxy.d.ts +36 -1
  187. package/dist/Services/ApiProxy.js +182 -52
  188. package/dist/Services/ApiProxyRules.d.ts +203 -0
  189. package/dist/Services/ApiProxyRules.js +426 -0
  190. package/dist/Services/ExcelApi.js +5 -0
  191. package/dist/Services/FileApi.d.ts +13 -0
  192. package/dist/Services/FileApi.js +29 -0
  193. package/dist/Services/ImageEditorLoader.d.ts +14 -0
  194. package/dist/Services/ImageEditorLoader.js +51 -0
  195. package/dist/Services/JoinSources.d.ts +80 -0
  196. package/dist/Services/JoinSources.js +150 -0
  197. package/dist/Services/ModuleImport.d.ts +7 -0
  198. package/dist/Services/ModuleImport.js +22 -0
  199. package/dist/Services/ServerApi.d.ts +13 -2
  200. package/dist/Services/ServerApi.js +8 -3
  201. package/dist/Shared.Index.d.ts +20 -0
  202. package/dist/Shared.Index.js +20 -0
  203. package/package.json +92 -85
  204. package/src/Styles/Nexus.Avatar.css +80 -79
  205. package/src/Styles/Nexus.Base.css +117 -117
  206. package/src/Styles/Nexus.Button.css +186 -180
  207. package/src/Styles/Nexus.Calendar.css +273 -273
  208. package/src/Styles/Nexus.Chat.css +1443 -1443
  209. package/src/Styles/Nexus.Choice.css +359 -343
  210. package/src/Styles/Nexus.Crud.css +542 -168
  211. package/src/Styles/Nexus.DateTime.css +81 -81
  212. package/src/Styles/Nexus.Dropdown.css +733 -725
  213. package/src/Styles/Nexus.Editor.css +295 -295
  214. package/src/Styles/Nexus.Excel.css +389 -389
  215. package/src/Styles/Nexus.Files.css +410 -0
  216. package/src/Styles/Nexus.Form.css +282 -279
  217. package/src/Styles/Nexus.Index.css +41 -37
  218. package/src/Styles/Nexus.Input.css +238 -4
  219. package/src/Styles/Nexus.Markdown.css +237 -237
  220. package/src/Styles/Nexus.Menu.css +246 -237
  221. package/src/Styles/Nexus.Popup.css +800 -724
  222. package/src/Styles/Nexus.Print.css +288 -0
  223. package/src/Styles/Nexus.QrCode.css +12 -0
  224. package/src/Styles/Nexus.Record.css +430 -0
  225. package/src/Styles/Nexus.Rows.css +637 -637
  226. package/src/Styles/Nexus.Slider.css +276 -276
  227. package/src/Styles/Nexus.Tab.Buttons.css +497 -432
  228. package/src/Styles/Nexus.Table.css +98 -35
  229. package/src/Styles/Nexus.Theme.Picker.css +59 -3
  230. package/src/Styles/Nexus.Themes.css +200 -194
  231. package/src/Styles/Nexus.Time.css +144 -144
  232. package/src/Styles/Nexus.Toast.css +263 -263
  233. package/src/Styles/Nexus.Tokens.css +94 -89
  234. package/src/Styles/Nexus.Tree.css +530 -431
@@ -1,1443 +1,1443 @@
1
- @layer nexus.components {
2
- /*
3
- * The chat: the trigger icon, the conversation, and the composer.
4
- *
5
- * The trigger has three looks and one size. Quiet is a subtle outline; a conversation with messages takes the accent
6
- * on its soft tint; unread takes the solid accent with the count in a badge over the corner. The badge is laid over
7
- * the box, never beside it, so a column of these in a table does not move as the counts arrive.
8
- *
9
- * Everything is drawn from the theme tokens, so all seven themes in light and dark follow without a line of their own.
10
- */
11
-
12
- /* The trigger */
13
-
14
- .nx-chat-btn {
15
- position: relative;
16
- display: inline-grid;
17
- flex-shrink: 0;
18
- place-items: center;
19
- width: var(--nx-control-md);
20
- height: var(--nx-control-md);
21
- padding: 0;
22
- border: 1px solid transparent;
23
- border-radius: var(--nx-radius);
24
- background: none;
25
- color: var(--nx-text-subtle);
26
- font: inherit;
27
- cursor: pointer;
28
- transition:
29
- background-color var(--nx-duration) linear,
30
- color var(--nx-duration) linear,
31
- border-color var(--nx-duration) linear;
32
- }
33
-
34
- .nx-chat-btn--sm {
35
- width: var(--nx-control-sm);
36
- height: var(--nx-control-sm);
37
- }
38
-
39
- .nx-chat-btn .nx-icon {
40
- width: 18px;
41
- height: 18px;
42
- vertical-align: 0;
43
- }
44
-
45
- .nx-chat-btn--sm .nx-icon {
46
- width: 16px;
47
- height: 16px;
48
- }
49
-
50
- .nx-chat-btn:hover:not(:disabled) {
51
- background: var(--nx-surface-hover);
52
- color: var(--nx-text);
53
- }
54
-
55
- .nx-chat-btn:focus-visible {
56
- outline: none;
57
- box-shadow: var(--nx-focus-ring);
58
- }
59
-
60
- .nx-chat-btn:disabled {
61
- cursor: not-allowed;
62
- opacity: 0.55;
63
- }
64
-
65
- /* Has messages: the accent on its soft tint. */
66
- .nx-chat-btn[data-chat="active"] {
67
- border-color: color-mix(in oklab, var(--nx-primary) 28%, transparent);
68
- background: var(--nx-primary-soft);
69
- color: var(--nx-primary);
70
- }
71
-
72
- .nx-chat-btn[data-chat="active"]:hover:not(:disabled) {
73
- border-color: var(--nx-primary);
74
- background: color-mix(in oklab, var(--nx-primary) 22%, var(--nx-surface));
75
- color: var(--nx-primary);
76
- }
77
-
78
- /* Unread: the strongest step, so one glance down a list finds it. */
79
- .nx-chat-btn[data-chat="unread"] {
80
- border-color: var(--nx-primary-solid);
81
- background: var(--nx-primary-solid);
82
- color: var(--nx-primary-text);
83
- }
84
-
85
- .nx-chat-btn[data-chat="unread"]:hover:not(:disabled) {
86
- background: var(--nx-primary-hover);
87
- color: var(--nx-primary-text);
88
- }
89
-
90
- /* The number of unread messages, over the corner of the box so the box keeps its size. */
91
- .nx-chat-btn__badge {
92
- position: absolute;
93
- top: -5px;
94
- right: -5px;
95
- display: grid;
96
- place-items: center;
97
- min-width: 16px;
98
- height: 16px;
99
- padding: 0 4px;
100
- border: 1px solid var(--nx-surface);
101
- border-radius: var(--nx-radius-full);
102
- background: var(--nx-danger-solid);
103
- color: var(--nx-danger-text);
104
- font-size: 10px;
105
- font-weight: 700;
106
- font-variant-numeric: tabular-nums;
107
- line-height: 1;
108
- pointer-events: none;
109
- }
110
-
111
- /* The panel */
112
-
113
- .nx-chat-panel {
114
- --nx-chat-height: min(60vh, 520px);
115
- --nx-avatar-size: 28px;
116
-
117
- container-type: inline-size;
118
- display: flex;
119
- flex-direction: column;
120
- height: var(--nx-chat-height);
121
- min-height: 240px;
122
- overflow: hidden;
123
- background: var(--nx-surface);
124
- color: var(--nx-text);
125
- font-size: var(--nx-text-md);
126
- }
127
-
128
- /* A low bar, as a window has: the name at the start, the buttons flush in the corner. */
129
- .nx-chat-panel__bar {
130
- display: flex;
131
- flex-shrink: 0;
132
- align-items: center;
133
- gap: var(--nx-space-2);
134
- min-height: 36px;
135
- padding: 0 var(--nx-space-2) 0 var(--nx-space-3);
136
- border-bottom: 1px solid var(--nx-border);
137
- background: var(--nx-surface-2);
138
- }
139
-
140
- .nx-chat-panel__heading {
141
- display: flex;
142
- flex: 1 1 auto;
143
- gap: var(--nx-space-2);
144
- align-items: baseline;
145
- min-width: 0;
146
- }
147
-
148
- .nx-chat-panel__title {
149
- overflow: hidden;
150
- font-weight: 600;
151
- white-space: nowrap;
152
- text-overflow: ellipsis;
153
- }
154
-
155
- .nx-chat-panel__description {
156
- overflow: hidden;
157
- color: var(--nx-text-muted);
158
- font-size: var(--nx-text-sm);
159
- white-space: nowrap;
160
- text-overflow: ellipsis;
161
- }
162
-
163
- .nx-chat-panel__people {
164
- display: inline-flex;
165
- flex-shrink: 0;
166
- gap: 4px;
167
- align-items: center;
168
- height: 26px;
169
- margin: 0;
170
- padding: 0 6px;
171
- border: 1px solid transparent;
172
- border-radius: var(--nx-radius-sm);
173
- background: none;
174
- color: var(--nx-text-muted);
175
- font: inherit;
176
- font-size: var(--nx-text-sm);
177
- font-variant-numeric: tabular-nums;
178
- cursor: pointer;
179
- }
180
-
181
- .nx-chat-panel__people:hover,
182
- .nx-chat-panel__people.is-open {
183
- background: var(--nx-surface-hover);
184
- color: var(--nx-text);
185
- }
186
-
187
- .nx-chat-panel__people:focus-visible {
188
- outline: none;
189
- box-shadow: var(--nx-focus-ring);
190
- }
191
-
192
- .nx-chat-panel__people .nx-icon {
193
- width: 16px;
194
- height: 16px;
195
- vertical-align: 0;
196
- }
197
-
198
- .nx-chat-panel__body {
199
- display: flex;
200
- flex: 1 1 auto;
201
- min-height: 0;
202
- }
203
-
204
- .nx-chat-panel__footer {
205
- display: flex;
206
- flex-shrink: 0;
207
- gap: var(--nx-space-2);
208
- justify-content: flex-end;
209
- padding: var(--nx-space-2) var(--nx-space-3);
210
- border-top: 1px solid var(--nx-border);
211
- }
212
-
213
- /* The people, in a column beside the thread: a dividing line, not a panel inside a panel. */
214
- .nx-chat-panel__aside {
215
- display: flex;
216
- flex: 0 0 220px;
217
- flex-direction: column;
218
- min-width: 0;
219
- overflow-y: auto;
220
- border-left: 1px solid var(--nx-border);
221
- }
222
-
223
- .nx-chat-aside__bar {
224
- display: flex;
225
- align-items: center;
226
- justify-content: space-between;
227
- padding: var(--nx-space-2) var(--nx-space-2) var(--nx-space-2) var(--nx-space-3);
228
- color: var(--nx-text-muted);
229
- font-size: var(--nx-text-sm);
230
- font-weight: 600;
231
- }
232
-
233
- .nx-chat-aside__bar button {
234
- display: grid;
235
- place-items: center;
236
- width: 22px;
237
- height: 22px;
238
- padding: 0;
239
- border: 0;
240
- border-radius: var(--nx-radius-sm);
241
- background: none;
242
- color: var(--nx-text-subtle);
243
- cursor: pointer;
244
- }
245
-
246
- .nx-chat-aside__bar button:hover {
247
- background: var(--nx-surface-hover);
248
- color: var(--nx-text);
249
- }
250
-
251
- .nx-chat-aside__bar button:focus-visible {
252
- outline: none;
253
- box-shadow: var(--nx-focus-ring);
254
- }
255
-
256
- .nx-chat-aside__bar .nx-icon {
257
- width: 14px;
258
- height: 14px;
259
- vertical-align: 0;
260
- }
261
-
262
- .nx-chat-aside__empty {
263
- margin: 0;
264
- padding: 0 var(--nx-space-3) var(--nx-space-3);
265
- color: var(--nx-text-muted);
266
- font-size: var(--nx-text-sm);
267
- }
268
-
269
- .nx-chat-aside__add {
270
- display: flex;
271
- flex-direction: column;
272
- gap: var(--nx-space-2);
273
- margin-top: auto;
274
- padding: var(--nx-space-3);
275
- border-top: 1px solid var(--nx-border);
276
- }
277
-
278
- /* The thread */
279
-
280
- .nx-chat-thread {
281
- position: relative;
282
- display: flex;
283
- flex: 1 1 auto;
284
- flex-direction: column;
285
- min-width: 0;
286
- }
287
-
288
- .nx-chat-thread__list {
289
- display: flex;
290
- flex: 1 1 auto;
291
- flex-direction: column;
292
- gap: var(--nx-space-2);
293
- padding: var(--nx-space-3);
294
- overflow-y: auto;
295
- overscroll-behavior: contain;
296
- scrollbar-gutter: stable;
297
- }
298
-
299
- .nx-chat-thread__list:focus-visible {
300
- outline: none;
301
- box-shadow: inset var(--nx-focus-ring);
302
- }
303
-
304
- .nx-chat-thread__day {
305
- display: flex;
306
- flex-direction: column;
307
- gap: var(--nx-space-2);
308
- }
309
-
310
- .nx-chat-thread__older {
311
- display: flex;
312
- justify-content: center;
313
- }
314
-
315
- /* Down to the newest, with how many arrived while the reader was elsewhere. */
316
- .nx-chat-thread__jump {
317
- position: absolute;
318
- right: var(--nx-space-3);
319
- bottom: var(--nx-space-3);
320
- display: grid;
321
- place-items: center;
322
- width: 32px;
323
- height: 32px;
324
- padding: 0;
325
- border: 1px solid var(--nx-border);
326
- border-radius: var(--nx-radius-full);
327
- background: var(--nx-surface);
328
- color: var(--nx-text);
329
- cursor: pointer;
330
- box-shadow: var(--nx-shadow-sm);
331
- }
332
-
333
- .nx-chat-thread__jump:hover {
334
- border-color: var(--nx-border-strong);
335
- background: var(--nx-surface-hover);
336
- }
337
-
338
- .nx-chat-thread__jump:focus-visible {
339
- outline: none;
340
- box-shadow: var(--nx-focus-ring);
341
- }
342
-
343
- .nx-chat-thread__jump .nx-icon {
344
- width: 16px;
345
- height: 16px;
346
- vertical-align: 0;
347
- }
348
-
349
- .nx-chat-thread__jump-count {
350
- position: absolute;
351
- top: -5px;
352
- right: -5px;
353
- display: grid;
354
- place-items: center;
355
- min-width: 16px;
356
- height: 16px;
357
- padding: 0 4px;
358
- border: 1px solid var(--nx-surface);
359
- border-radius: var(--nx-radius-full);
360
- background: var(--nx-danger-solid);
361
- color: var(--nx-danger-text);
362
- font-size: 10px;
363
- font-weight: 700;
364
- line-height: 1;
365
- }
366
-
367
- /* The lines that break a thread up */
368
-
369
- .nx-chat-day,
370
- .nx-chat-unread-line {
371
- display: flex;
372
- gap: var(--nx-space-2);
373
- align-items: center;
374
- font-size: var(--nx-text-xs);
375
- text-transform: none;
376
- }
377
-
378
- .nx-chat-day::before,
379
- .nx-chat-day::after,
380
- .nx-chat-unread-line::before,
381
- .nx-chat-unread-line::after {
382
- flex: 1 1 auto;
383
- height: 1px;
384
- background: var(--nx-border);
385
- content: "";
386
- }
387
-
388
- .nx-chat-day > span {
389
- color: var(--nx-text-muted);
390
- font-weight: 600;
391
- white-space: nowrap;
392
- }
393
-
394
- .nx-chat-unread-line::before,
395
- .nx-chat-unread-line::after {
396
- background: color-mix(in oklab, var(--nx-primary) 45%, transparent);
397
- }
398
-
399
- .nx-chat-unread-line {
400
- margin: var(--nx-space-1) 0;
401
- }
402
-
403
- .nx-chat-unread-line > span {
404
- padding: 2px 8px;
405
- border-radius: var(--nx-radius-full);
406
- background: var(--nx-primary-soft);
407
- color: var(--nx-primary);
408
- font-weight: 600;
409
- white-space: nowrap;
410
- }
411
-
412
- /* A run of messages by one author */
413
-
414
- .nx-chat-run {
415
- display: flex;
416
- gap: var(--nx-space-2);
417
- align-items: flex-end;
418
- }
419
-
420
- .nx-chat-run--mine {
421
- justify-content: flex-end;
422
- }
423
-
424
- .nx-chat-run--system {
425
- flex-direction: column;
426
- gap: var(--nx-space-1);
427
- }
428
-
429
- .nx-chat-run__avatar {
430
- flex-shrink: 0;
431
- }
432
-
433
- .nx-chat-run__messages {
434
- display: flex;
435
- flex-direction: column;
436
- gap: 2px;
437
- min-width: 0;
438
- max-width: min(82%, 46ch);
439
- }
440
-
441
- .nx-chat-run--mine .nx-chat-run__messages {
442
- align-items: flex-end;
443
- }
444
-
445
- /* One message */
446
-
447
- .nx-chat-msg {
448
- display: flex;
449
- flex-direction: column;
450
- gap: 2px;
451
- min-width: 0;
452
- max-width: 100%;
453
- }
454
-
455
- .nx-chat-msg__bubble {
456
- position: relative;
457
- min-width: 0;
458
- padding: 6px var(--nx-space-3) 6px;
459
- border: 1px solid var(--nx-border);
460
- border-radius: var(--nx-radius-lg);
461
- line-height: 1.45;
462
- }
463
-
464
- .nx-chat-msg--theirs .nx-chat-msg__bubble {
465
- background: var(--nx-surface-2);
466
- }
467
-
468
- .nx-chat-msg--mine .nx-chat-msg__bubble {
469
- border-color: color-mix(in oklab, var(--nx-primary) 24%, transparent);
470
- background: var(--nx-primary-soft);
471
- }
472
-
473
- /* A run reads as one block: only its outer corners are fully round. */
474
- .nx-chat-msg--theirs:not(.nx-chat-msg--first) .nx-chat-msg__bubble {
475
- border-top-left-radius: var(--nx-radius-sm);
476
- }
477
-
478
- .nx-chat-msg--theirs:not(.nx-chat-msg--last) .nx-chat-msg__bubble {
479
- border-bottom-left-radius: var(--nx-radius-sm);
480
- }
481
-
482
- .nx-chat-msg--mine:not(.nx-chat-msg--first) .nx-chat-msg__bubble {
483
- border-top-right-radius: var(--nx-radius-sm);
484
- }
485
-
486
- .nx-chat-msg--mine:not(.nx-chat-msg--last) .nx-chat-msg__bubble {
487
- border-bottom-right-radius: var(--nx-radius-sm);
488
- }
489
-
490
- .nx-chat-msg--failed .nx-chat-msg__bubble {
491
- border-color: color-mix(in oklab, var(--nx-danger) 45%, transparent);
492
- background: var(--nx-danger-soft);
493
- }
494
-
495
- .nx-chat-msg__author {
496
- display: block;
497
- color: var(--nx-primary);
498
- font-size: var(--nx-text-sm);
499
- font-weight: 600;
500
- }
501
-
502
- /*
503
- * A message is Markdown. Inside a bubble it keeps the bubble's rhythm rather than a document's: nothing above the
504
- * first block or below the last, a tighter gap between blocks, headings that do not tower over a line of text, and
505
- * code and tables that scroll inside the bubble instead of widening it.
506
- */
507
- .nx-chat-msg__body {
508
- overflow-wrap: anywhere;
509
- }
510
-
511
- .nx-chat-msg__body > :first-child {
512
- margin-top: 0;
513
- }
514
-
515
- .nx-chat-msg__body > :last-child {
516
- margin-bottom: 0;
517
- }
518
-
519
- .nx-chat-msg__body > * + * {
520
- margin-top: var(--nx-space-2);
521
- }
522
-
523
- .nx-chat-msg__body :is(h1, h2, h3, h4, h5, h6) {
524
- font-size: var(--nx-text-lg);
525
- }
526
-
527
- .nx-chat-msg__body :is(ul, ol) {
528
- padding-left: var(--nx-space-5);
529
- }
530
-
531
- .nx-chat-msg__body :is(pre, table) {
532
- max-width: 100%;
533
- overflow-x: auto;
534
- }
535
-
536
- .nx-chat-msg__meta {
537
- display: flex;
538
- gap: 4px;
539
- align-items: center;
540
- justify-content: flex-end;
541
- color: var(--nx-text-muted);
542
- font-size: var(--nx-text-xs);
543
- font-variant-numeric: tabular-nums;
544
- }
545
-
546
- .nx-chat-msg__edited {
547
- font-style: italic;
548
- }
549
-
550
- /* Sending, sent, delivered, read — one mark, one size, in the place the time sits. */
551
- .nx-chat-mark {
552
- display: inline-grid;
553
- flex-shrink: 0;
554
- place-items: center;
555
- width: 14px;
556
- height: 14px;
557
- color: var(--nx-text-subtle);
558
- }
559
-
560
- .nx-chat-mark .nx-icon {
561
- width: 14px;
562
- height: 14px;
563
- vertical-align: 0;
564
- }
565
-
566
- /* Read: the accent, so a glance down your own messages finds what has landed. */
567
- .nx-chat-mark--seen {
568
- color: var(--nx-primary);
569
- }
570
-
571
- .nx-chat-mark--failed {
572
- color: var(--nx-danger);
573
- }
574
-
575
- /*
576
- * The actions of a message: over its top corner, and shown only on hover or keyboard focus. They are laid over the
577
- * bubble rather than taking a place in it, so nothing in the thread moves as the pointer travels down it.
578
- */
579
- .nx-chat-msg__actions {
580
- position: absolute;
581
- top: -12px;
582
- display: none;
583
- gap: 2px;
584
- padding: 2px;
585
- border: 1px solid var(--nx-border);
586
- border-radius: var(--nx-radius);
587
- background: var(--nx-surface);
588
- box-shadow: var(--nx-shadow-sm);
589
- }
590
-
591
- .nx-chat-msg--theirs .nx-chat-msg__actions {
592
- right: var(--nx-space-2);
593
- }
594
-
595
- .nx-chat-msg--mine .nx-chat-msg__actions {
596
- left: var(--nx-space-2);
597
- }
598
-
599
- .nx-chat-msg:hover .nx-chat-msg__actions,
600
- .nx-chat-msg:focus-within .nx-chat-msg__actions {
601
- display: flex;
602
- }
603
-
604
- .nx-chat-msg__action {
605
- display: grid;
606
- place-items: center;
607
- width: 22px;
608
- height: 22px;
609
- padding: 0;
610
- border: 0;
611
- border-radius: var(--nx-radius-sm);
612
- background: none;
613
- color: var(--nx-text-muted);
614
- cursor: pointer;
615
- }
616
-
617
- .nx-chat-msg__action:hover {
618
- background: var(--nx-surface-hover);
619
- color: var(--nx-text);
620
- }
621
-
622
- .nx-chat-msg__action--danger:hover {
623
- background: var(--nx-danger-soft);
624
- color: var(--nx-danger);
625
- }
626
-
627
- .nx-chat-msg__action:focus-visible {
628
- outline: none;
629
- box-shadow: var(--nx-focus-ring);
630
- }
631
-
632
- .nx-chat-msg__action .nx-icon {
633
- width: 14px;
634
- height: 14px;
635
- vertical-align: 0;
636
- }
637
-
638
- /* A message that did not arrive: it stays, with why and what can be done. */
639
- .nx-chat-msg__failure {
640
- display: flex;
641
- flex-wrap: wrap;
642
- gap: 6px;
643
- align-items: center;
644
- color: var(--nx-danger);
645
- font-size: var(--nx-text-xs);
646
- }
647
-
648
- .nx-chat-msg__failure .nx-icon {
649
- width: 14px;
650
- height: 14px;
651
- vertical-align: 0;
652
- }
653
-
654
- .nx-chat-msg__failure button {
655
- display: inline-flex;
656
- gap: 3px;
657
- align-items: center;
658
- padding: 0;
659
- border: 0;
660
- background: none;
661
- color: var(--nx-danger);
662
- font: inherit;
663
- font-weight: 600;
664
- text-decoration: underline;
665
- cursor: pointer;
666
- }
667
-
668
- .nx-chat-msg__failure button:focus-visible {
669
- outline: none;
670
- box-shadow: var(--nx-focus-ring);
671
- }
672
-
673
- /* A quoted message, in the bubble that answers it and in the composer */
674
-
675
- .nx-chat-quote {
676
- display: flex;
677
- flex-direction: column;
678
- gap: 1px;
679
- width: 100%;
680
- margin: 2px 0 4px;
681
- padding: 2px 0 2px var(--nx-space-2);
682
- border: 0;
683
- border-left: 2px solid color-mix(in oklab, var(--nx-primary) 60%, transparent);
684
- background: none;
685
- color: var(--nx-text-muted);
686
- font: inherit;
687
- font-size: var(--nx-text-sm);
688
- text-align: start;
689
- cursor: pointer;
690
- }
691
-
692
- .nx-chat-quote--gone {
693
- border-left-color: var(--nx-border-strong);
694
- font-style: italic;
695
- cursor: default;
696
- }
697
-
698
- .nx-chat-quote:focus-visible {
699
- outline: none;
700
- box-shadow: var(--nx-focus-ring);
701
- }
702
-
703
- .nx-chat-quote__author {
704
- color: var(--nx-primary);
705
- font-weight: 600;
706
- }
707
-
708
- .nx-chat-quote__body {
709
- display: block;
710
- overflow: hidden;
711
- white-space: nowrap;
712
- text-overflow: ellipsis;
713
- }
714
-
715
- /* Files on a message */
716
-
717
- .nx-chat-files {
718
- display: flex;
719
- flex-direction: column;
720
- gap: 2px;
721
- margin: 4px 0 2px;
722
- padding: 0;
723
- list-style: none;
724
- }
725
-
726
- .nx-chat-file > a,
727
- .nx-chat-file > span {
728
- display: inline-flex;
729
- gap: 6px;
730
- align-items: center;
731
- max-width: 100%;
732
- padding: 3px 6px;
733
- border: 1px solid color-mix(in oklab, var(--nx-text) 18%, transparent);
734
- border-radius: var(--nx-radius-sm);
735
- background: none;
736
- color: var(--nx-text);
737
- font-size: var(--nx-text-sm);
738
- text-decoration: none;
739
- }
740
-
741
- .nx-chat-file > a:hover {
742
- border-color: var(--nx-primary);
743
- background: color-mix(in oklab, var(--nx-primary) 10%, transparent);
744
- color: var(--nx-primary);
745
- }
746
-
747
- .nx-chat-file > a:focus-visible {
748
- outline: none;
749
- box-shadow: var(--nx-focus-ring);
750
- }
751
-
752
- .nx-chat-file .nx-icon {
753
- width: 14px;
754
- height: 14px;
755
- flex-shrink: 0;
756
- vertical-align: 0;
757
- }
758
-
759
- .nx-chat-file__name {
760
- overflow: hidden;
761
- white-space: nowrap;
762
- text-overflow: ellipsis;
763
- }
764
-
765
- .nx-chat-file__size {
766
- flex-shrink: 0;
767
- color: var(--nx-text-muted);
768
- font-variant-numeric: tabular-nums;
769
- }
770
-
771
- /* A note the system wrote */
772
-
773
- .nx-chat-note {
774
- display: flex;
775
- gap: 6px;
776
- align-items: baseline;
777
- align-self: center;
778
- justify-content: center;
779
- max-width: 90%;
780
- padding: 2px 10px;
781
- border-radius: var(--nx-radius-full);
782
- background: var(--nx-surface-2);
783
- color: var(--nx-text-muted);
784
- font-size: var(--nx-text-xs);
785
- text-align: center;
786
- }
787
-
788
- /* The people */
789
-
790
- .nx-chat-people {
791
- display: flex;
792
- flex-direction: column;
793
- gap: 2px;
794
- margin: 0;
795
- padding: 0 var(--nx-space-2) var(--nx-space-2);
796
- list-style: none;
797
- }
798
-
799
- .nx-chat-person {
800
- display: flex;
801
- gap: var(--nx-space-2);
802
- align-items: center;
803
- padding: 4px var(--nx-space-2);
804
- border-radius: var(--nx-radius-sm);
805
- }
806
-
807
- .nx-chat-person--inactive {
808
- opacity: 0.6;
809
- }
810
-
811
- .nx-chat-person__text {
812
- display: flex;
813
- flex-direction: column;
814
- min-width: 0;
815
- }
816
-
817
- .nx-chat-person__name {
818
- display: flex;
819
- gap: 4px;
820
- align-items: baseline;
821
- overflow: hidden;
822
- font-size: var(--nx-text-sm);
823
- font-weight: 500;
824
- white-space: nowrap;
825
- text-overflow: ellipsis;
826
- }
827
-
828
- .nx-chat-person__you {
829
- color: var(--nx-text-subtle);
830
- font-size: var(--nx-text-xs);
831
- font-weight: 400;
832
- }
833
-
834
- .nx-chat-person__role {
835
- overflow: hidden;
836
- color: var(--nx-text-muted);
837
- font-size: var(--nx-text-xs);
838
- white-space: nowrap;
839
- text-overflow: ellipsis;
840
- }
841
-
842
- /* Empty, loading, and failed */
843
-
844
- .nx-chat-empty {
845
- display: flex;
846
- flex: 1 1 auto;
847
- flex-direction: column;
848
- gap: 4px;
849
- align-items: center;
850
- justify-content: center;
851
- padding: var(--nx-space-6) var(--nx-space-4);
852
- color: var(--nx-text-muted);
853
- text-align: center;
854
- }
855
-
856
- .nx-chat-empty p {
857
- margin: 0;
858
- }
859
-
860
- .nx-chat-empty__hint {
861
- display: inline-flex;
862
- gap: 6px;
863
- align-items: center;
864
- color: var(--nx-text-subtle);
865
- font-size: var(--nx-text-sm);
866
- }
867
-
868
- .nx-chat-empty .nx-icon {
869
- width: 15px;
870
- height: 15px;
871
- vertical-align: 0;
872
- }
873
-
874
- .nx-chat-loading {
875
- display: flex;
876
- gap: 6px;
877
- align-items: center;
878
- align-self: center;
879
- color: var(--nx-text-muted);
880
- font-size: var(--nx-text-sm);
881
- }
882
-
883
- .nx-chat-loading .nx-icon,
884
- .nx-chat-failure .nx-icon {
885
- width: 15px;
886
- height: 15px;
887
- vertical-align: 0;
888
- }
889
-
890
- .nx-chat-failure {
891
- display: flex;
892
- flex-wrap: wrap;
893
- gap: 6px;
894
- align-items: center;
895
- padding: var(--nx-space-2) var(--nx-space-3);
896
- border: 1px solid color-mix(in oklab, var(--nx-danger) 35%, transparent);
897
- border-radius: var(--nx-radius);
898
- background: var(--nx-danger-soft);
899
- color: var(--nx-danger);
900
- font-size: var(--nx-text-sm);
901
- }
902
-
903
- .nx-chat-failure button {
904
- display: inline-flex;
905
- gap: 3px;
906
- align-items: center;
907
- padding: 0;
908
- border: 0;
909
- background: none;
910
- color: var(--nx-danger);
911
- font: inherit;
912
- font-weight: 600;
913
- text-decoration: underline;
914
- cursor: pointer;
915
- }
916
-
917
- .nx-chat-failure button:focus-visible {
918
- outline: none;
919
- box-shadow: var(--nx-focus-ring);
920
- }
921
-
922
- /* The composer */
923
-
924
- .nx-chat-composer {
925
- display: flex;
926
- flex-shrink: 0;
927
- flex-direction: column;
928
- gap: var(--nx-space-2);
929
- padding: var(--nx-space-2) var(--nx-space-3);
930
- border-top: 1px solid var(--nx-border);
931
- background: var(--nx-surface);
932
- }
933
-
934
- .nx-chat-composer--readonly p {
935
- display: flex;
936
- gap: 6px;
937
- align-items: center;
938
- justify-content: center;
939
- margin: 0;
940
- padding: var(--nx-space-1) 0;
941
- color: var(--nx-text-muted);
942
- font-size: var(--nx-text-sm);
943
- text-align: center;
944
- }
945
-
946
- /* The editor is the whole writing area, so the row under it carries only the hint and the buttons. */
947
- .nx-chat-composer__row {
948
- display: flex;
949
- gap: var(--nx-space-2);
950
- align-items: center;
951
- }
952
-
953
- .nx-chat-composer__hint {
954
- flex: 1 1 auto;
955
- min-width: 0;
956
- overflow: hidden;
957
- color: var(--nx-text-subtle);
958
- font-size: var(--nx-text-xs);
959
- white-space: nowrap;
960
- text-overflow: ellipsis;
961
- }
962
-
963
- .nx-chat-composer__attach,
964
- .nx-chat-composer__send {
965
- display: inline-grid;
966
- flex-shrink: 0;
967
- grid-auto-flow: column;
968
- gap: 6px;
969
- place-items: center;
970
- width: 30px;
971
- height: 30px;
972
- padding: 0;
973
- border: 0;
974
- border-radius: var(--nx-radius);
975
- background: none;
976
- color: var(--nx-text-muted);
977
- font: inherit;
978
- cursor: pointer;
979
- }
980
-
981
- .nx-chat-composer__attach:hover {
982
- background: var(--nx-surface-hover);
983
- color: var(--nx-text);
984
- }
985
-
986
- .nx-chat-composer__send {
987
- width: auto;
988
- padding: 0 10px;
989
- background: var(--nx-primary-solid);
990
- color: var(--nx-primary-text);
991
- font-size: var(--nx-text-sm);
992
- font-weight: 600;
993
- }
994
-
995
- .nx-chat-composer__send:hover:not(:disabled) {
996
- background: var(--nx-primary-hover);
997
- }
998
-
999
- .nx-chat-composer__send:disabled {
1000
- background: var(--nx-surface-hover);
1001
- color: var(--nx-text-subtle);
1002
- cursor: not-allowed;
1003
- }
1004
-
1005
- .nx-chat-composer__attach:focus-visible,
1006
- .nx-chat-composer__send:focus-visible {
1007
- outline: none;
1008
- box-shadow: var(--nx-focus-ring);
1009
- }
1010
-
1011
- .nx-chat-composer__attach .nx-icon,
1012
- .nx-chat-composer__send .nx-icon {
1013
- width: 16px;
1014
- height: 16px;
1015
- vertical-align: 0;
1016
- }
1017
-
1018
- .nx-chat-composer__reply {
1019
- display: flex;
1020
- gap: var(--nx-space-2);
1021
- align-items: center;
1022
- padding: var(--nx-space-1) var(--nx-space-2);
1023
- border-left: 2px solid var(--nx-primary);
1024
- border-radius: 0 var(--nx-radius-sm) var(--nx-radius-sm) 0;
1025
- background: var(--nx-surface-2);
1026
- font-size: var(--nx-text-sm);
1027
- }
1028
-
1029
- .nx-chat-composer__reply-text {
1030
- display: flex;
1031
- flex: 1 1 auto;
1032
- gap: 6px;
1033
- min-width: 0;
1034
- color: var(--nx-text-muted);
1035
- }
1036
-
1037
- .nx-chat-composer__reply-text > span:last-child {
1038
- overflow: hidden;
1039
- white-space: nowrap;
1040
- text-overflow: ellipsis;
1041
- }
1042
-
1043
- .nx-chat-composer__reply-author {
1044
- flex-shrink: 0;
1045
- color: var(--nx-primary);
1046
- font-weight: 600;
1047
- }
1048
-
1049
- .nx-chat-composer__reply button,
1050
- .nx-chat-composer__files button {
1051
- display: grid;
1052
- flex-shrink: 0;
1053
- place-items: center;
1054
- width: 20px;
1055
- height: 20px;
1056
- padding: 0;
1057
- border: 0;
1058
- border-radius: var(--nx-radius-sm);
1059
- background: none;
1060
- color: var(--nx-text-subtle);
1061
- cursor: pointer;
1062
- }
1063
-
1064
- .nx-chat-composer__reply button:hover,
1065
- .nx-chat-composer__files button:hover {
1066
- background: var(--nx-surface-hover);
1067
- color: var(--nx-text);
1068
- }
1069
-
1070
- .nx-chat-composer__reply button:focus-visible,
1071
- .nx-chat-composer__files button:focus-visible {
1072
- outline: none;
1073
- box-shadow: var(--nx-focus-ring);
1074
- }
1075
-
1076
- .nx-chat-composer__reply .nx-icon,
1077
- .nx-chat-composer__files .nx-icon {
1078
- width: 13px;
1079
- height: 13px;
1080
- vertical-align: 0;
1081
- }
1082
-
1083
- .nx-chat-composer__files {
1084
- display: flex;
1085
- flex-wrap: wrap;
1086
- gap: var(--nx-space-1);
1087
- margin: 0;
1088
- padding: 0;
1089
- list-style: none;
1090
- }
1091
-
1092
- .nx-chat-composer__files li {
1093
- display: inline-flex;
1094
- gap: 6px;
1095
- align-items: center;
1096
- max-width: 100%;
1097
- padding: 2px 4px 2px 8px;
1098
- border: 1px solid var(--nx-border);
1099
- border-radius: var(--nx-radius-full);
1100
- background: var(--nx-surface-2);
1101
- font-size: var(--nx-text-xs);
1102
- }
1103
-
1104
- .nx-chat-composer__file-name {
1105
- overflow: hidden;
1106
- white-space: nowrap;
1107
- text-overflow: ellipsis;
1108
- }
1109
-
1110
- .nx-chat-composer__file-size {
1111
- color: var(--nx-text-muted);
1112
- font-variant-numeric: tabular-nums;
1113
- }
1114
-
1115
-
1116
- /*
1117
- * The conversation list and the New chat form: the panel's other two views. They sit where the thread sits, with
1118
- * the same bar above them, so the panel never grows a second frame inside itself.
1119
- */
1120
-
1121
- .nx-chat-list {
1122
- display: flex;
1123
- flex: 1 1 auto;
1124
- flex-direction: column;
1125
- min-width: 0;
1126
- padding: var(--nx-space-2);
1127
- overflow-y: auto;
1128
- }
1129
-
1130
- .nx-chat-list__items {
1131
- display: flex;
1132
- flex: 1 1 auto;
1133
- flex-direction: column;
1134
- gap: 2px;
1135
- margin: 0;
1136
- padding: 0;
1137
- list-style: none;
1138
- }
1139
-
1140
- .nx-chat-list__item {
1141
- display: flex;
1142
- gap: var(--nx-space-2);
1143
- align-items: center;
1144
- width: 100%;
1145
- padding: var(--nx-space-2);
1146
- border: 1px solid transparent;
1147
- border-radius: var(--nx-radius);
1148
- background: none;
1149
- color: var(--nx-text);
1150
- font: inherit;
1151
- text-align: start;
1152
- cursor: pointer;
1153
- }
1154
-
1155
- .nx-chat-list__item:hover {
1156
- background: var(--nx-surface-hover);
1157
- }
1158
-
1159
- .nx-chat-list__item:focus-visible {
1160
- outline: none;
1161
- box-shadow: var(--nx-focus-ring);
1162
- }
1163
-
1164
- /* The one open now: the accent tint, so the list says where you are without a word for it. */
1165
- .nx-chat-list__item.is-current {
1166
- border-color: color-mix(in oklab, var(--nx-primary) 28%, transparent);
1167
- background: var(--nx-primary-soft);
1168
- }
1169
-
1170
- .nx-chat-list__group {
1171
- display: grid;
1172
- flex-shrink: 0;
1173
- place-items: center;
1174
- width: var(--nx-avatar-size, 28px);
1175
- height: var(--nx-avatar-size, 28px);
1176
- border-radius: 50%;
1177
- background: var(--nx-surface-2);
1178
- color: var(--nx-text-muted);
1179
- }
1180
-
1181
- .nx-chat-list__group .nx-icon {
1182
- width: 15px;
1183
- height: 15px;
1184
- vertical-align: 0;
1185
- }
1186
-
1187
- .nx-chat-list__text {
1188
- display: flex;
1189
- flex: 1 1 auto;
1190
- flex-direction: column;
1191
- gap: 1px;
1192
- min-width: 0;
1193
- }
1194
-
1195
- .nx-chat-list__line {
1196
- display: flex;
1197
- gap: var(--nx-space-2);
1198
- align-items: baseline;
1199
- justify-content: space-between;
1200
- min-width: 0;
1201
- }
1202
-
1203
- .nx-chat-list__name {
1204
- overflow: hidden;
1205
- font-weight: 600;
1206
- white-space: nowrap;
1207
- text-overflow: ellipsis;
1208
- }
1209
-
1210
- .nx-chat-list__when {
1211
- flex-shrink: 0;
1212
- color: var(--nx-text-subtle);
1213
- font-size: var(--nx-text-xs);
1214
- white-space: nowrap;
1215
- }
1216
-
1217
- .nx-chat-list__last {
1218
- overflow: hidden;
1219
- color: var(--nx-text-muted);
1220
- font-size: var(--nx-text-sm);
1221
- white-space: nowrap;
1222
- text-overflow: ellipsis;
1223
- }
1224
-
1225
- .nx-chat-list__badge {
1226
- display: grid;
1227
- flex-shrink: 0;
1228
- place-items: center;
1229
- min-width: 18px;
1230
- height: 18px;
1231
- padding: 0 5px;
1232
- border-radius: var(--nx-radius-full);
1233
- background: var(--nx-danger-solid);
1234
- color: var(--nx-danger-text);
1235
- font-size: 11px;
1236
- font-weight: 700;
1237
- font-variant-numeric: tabular-nums;
1238
- line-height: 1;
1239
- }
1240
-
1241
- .nx-chat-list__new {
1242
- flex-shrink: 0;
1243
- padding-top: var(--nx-space-2);
1244
- margin-top: var(--nx-space-2);
1245
- border-top: 1px solid var(--nx-border);
1246
- }
1247
-
1248
- /* New chat */
1249
-
1250
- .nx-chat-new {
1251
- display: flex;
1252
- flex: 1 1 auto;
1253
- flex-direction: column;
1254
- min-width: 0;
1255
- padding: var(--nx-space-3);
1256
- overflow-y: auto;
1257
- }
1258
-
1259
- .nx-chat-new__fields {
1260
- display: flex;
1261
- flex: 1 1 auto;
1262
- flex-direction: column;
1263
- gap: var(--nx-space-3);
1264
- }
1265
-
1266
- .nx-chat-new__kind {
1267
- display: flex;
1268
- gap: 6px;
1269
- align-items: center;
1270
- margin: 0;
1271
- color: var(--nx-text-muted);
1272
- font-size: var(--nx-text-sm);
1273
- }
1274
-
1275
- .nx-chat-new__kind .nx-icon {
1276
- width: 15px;
1277
- height: 15px;
1278
- flex-shrink: 0;
1279
- vertical-align: 0;
1280
- }
1281
-
1282
- .nx-chat-new__actions {
1283
- display: flex;
1284
- flex-shrink: 0;
1285
- gap: var(--nx-space-2);
1286
- justify-content: flex-end;
1287
- padding-top: var(--nx-space-3);
1288
- }
1289
-
1290
- .nx-chat-new__note {
1291
- margin: var(--nx-space-1) 0 0;
1292
- color: var(--nx-text-subtle);
1293
- font-size: var(--nx-text-xs);
1294
- text-align: end;
1295
- }
1296
-
1297
- /* The bar's switch between conversations */
1298
-
1299
- .nx-chat-panel__switch {
1300
- display: inline-flex;
1301
- gap: 4px;
1302
- align-items: center;
1303
- min-width: 0;
1304
- margin: 0;
1305
- padding: 2px 6px;
1306
- border: 0;
1307
- border-radius: var(--nx-radius-sm);
1308
- background: none;
1309
- color: inherit;
1310
- font: inherit;
1311
- cursor: pointer;
1312
- }
1313
-
1314
- .nx-chat-panel__switch:hover {
1315
- background: var(--nx-surface-hover);
1316
- }
1317
-
1318
- .nx-chat-panel__switch:focus-visible {
1319
- outline: none;
1320
- box-shadow: var(--nx-focus-ring);
1321
- }
1322
-
1323
- .nx-chat-panel__switch .nx-icon {
1324
- width: 14px;
1325
- height: 14px;
1326
- flex-shrink: 0;
1327
- vertical-align: 0;
1328
- }
1329
-
1330
- .nx-chat-panel__of {
1331
- flex-shrink: 0;
1332
- color: var(--nx-text-subtle);
1333
- font-size: var(--nx-text-xs);
1334
- font-weight: 400;
1335
- }
1336
-
1337
- .nx-chat-panel__back {
1338
- display: grid;
1339
- flex-shrink: 0;
1340
- place-items: center;
1341
- width: 24px;
1342
- height: 24px;
1343
- margin-left: calc(var(--nx-space-2) * -1);
1344
- padding: 0;
1345
- border: 0;
1346
- border-radius: var(--nx-radius-sm);
1347
- background: none;
1348
- color: var(--nx-text-muted);
1349
- cursor: pointer;
1350
- }
1351
-
1352
- .nx-chat-panel__back:hover {
1353
- background: var(--nx-surface-hover);
1354
- color: var(--nx-text);
1355
- }
1356
-
1357
- .nx-chat-panel__back:focus-visible {
1358
- outline: none;
1359
- box-shadow: var(--nx-focus-ring);
1360
- }
1361
-
1362
- .nx-chat-panel__back .nx-icon {
1363
- width: 15px;
1364
- height: 15px;
1365
- vertical-align: 0;
1366
- }
1367
-
1368
- /*
1369
- * The people an `@` offers. It opens above the composer, because the composer is at the bottom of the panel and a
1370
- * list under it would fall outside. The highlighted row is the one Enter puts in.
1371
- */
1372
- .nx-chat-mentions {
1373
- display: flex;
1374
- flex-direction: column;
1375
- gap: 1px;
1376
- max-height: 200px;
1377
- margin: 0;
1378
- padding: var(--nx-space-1);
1379
- overflow-y: auto;
1380
- border: 1px solid var(--nx-border);
1381
- border-radius: var(--nx-radius);
1382
- background: var(--nx-surface);
1383
- list-style: none;
1384
- box-shadow: var(--nx-shadow-sm);
1385
- }
1386
-
1387
- .nx-chat-mentions__item {
1388
- display: flex;
1389
- gap: var(--nx-space-2);
1390
- align-items: center;
1391
- width: 100%;
1392
- padding: 4px var(--nx-space-2);
1393
- border: 0;
1394
- border-radius: var(--nx-radius-sm);
1395
- background: none;
1396
- color: var(--nx-text);
1397
- font: inherit;
1398
- font-size: var(--nx-text-sm);
1399
- text-align: start;
1400
- cursor: pointer;
1401
- }
1402
-
1403
- .nx-chat-mentions__item.is-at {
1404
- background: var(--nx-primary-soft);
1405
- color: var(--nx-primary);
1406
- }
1407
-
1408
- .nx-chat-mentions__name {
1409
- overflow: hidden;
1410
- font-weight: 500;
1411
- white-space: nowrap;
1412
- text-overflow: ellipsis;
1413
- }
1414
-
1415
- .nx-chat-mentions__role {
1416
- margin-left: auto;
1417
- overflow: hidden;
1418
- color: var(--nx-text-muted);
1419
- font-size: var(--nx-text-xs);
1420
- white-space: nowrap;
1421
- }
1422
-
1423
- /*
1424
- * A narrow panel: the people cover the thread rather than squeezing it. Measured, not guessed — at 520px the column
1425
- * would leave the thread under 300px, which is narrower than the bubbles want.
1426
- */
1427
- @container (max-width: 520px) {
1428
- .nx-chat-panel__body {
1429
- position: relative;
1430
- }
1431
-
1432
- .nx-chat-panel__aside {
1433
- position: absolute;
1434
- inset: 0;
1435
- flex-basis: auto;
1436
- background: var(--nx-surface);
1437
- }
1438
- }
1439
-
1440
- [data-nx-motion="reduce"] .nx-chat-btn {
1441
- transition: none;
1442
- }
1443
- }
1
+ @layer nexus.components {
2
+ /*
3
+ * The chat: the trigger icon, the conversation, and the composer.
4
+ *
5
+ * The trigger has three looks and one size. Quiet is a subtle outline; a conversation with messages takes the accent
6
+ * on its soft tint; unread takes the solid accent with the count in a badge over the corner. The badge is laid over
7
+ * the box, never beside it, so a column of these in a table does not move as the counts arrive.
8
+ *
9
+ * Everything is drawn from the theme tokens, so all seven themes in light and dark follow without a line of their own.
10
+ */
11
+
12
+ /* The trigger */
13
+
14
+ .nx-chat-btn {
15
+ position: relative;
16
+ display: inline-grid;
17
+ flex-shrink: 0;
18
+ place-items: center;
19
+ width: var(--nx-control-md);
20
+ height: var(--nx-control-md);
21
+ padding: 0;
22
+ border: 1px solid transparent;
23
+ border-radius: var(--nx-radius);
24
+ background: none;
25
+ color: var(--nx-text-subtle);
26
+ font: inherit;
27
+ cursor: pointer;
28
+ transition:
29
+ background-color var(--nx-duration) linear,
30
+ color var(--nx-duration) linear,
31
+ border-color var(--nx-duration) linear;
32
+ }
33
+
34
+ .nx-chat-btn--sm {
35
+ width: var(--nx-control-sm);
36
+ height: var(--nx-control-sm);
37
+ }
38
+
39
+ .nx-chat-btn .nx-icon {
40
+ width: 18px;
41
+ height: 18px;
42
+ vertical-align: 0;
43
+ }
44
+
45
+ .nx-chat-btn--sm .nx-icon {
46
+ width: 16px;
47
+ height: 16px;
48
+ }
49
+
50
+ .nx-chat-btn:hover:not(:disabled) {
51
+ background: var(--nx-surface-hover);
52
+ color: var(--nx-text);
53
+ }
54
+
55
+ .nx-chat-btn:focus-visible {
56
+ outline: none;
57
+ box-shadow: var(--nx-focus-ring);
58
+ }
59
+
60
+ .nx-chat-btn:disabled {
61
+ cursor: not-allowed;
62
+ opacity: 0.55;
63
+ }
64
+
65
+ /* Has messages: the accent on its soft tint. */
66
+ .nx-chat-btn[data-chat="active"] {
67
+ border-color: color-mix(in oklab, var(--nx-primary) 28%, transparent);
68
+ background: var(--nx-primary-soft);
69
+ color: var(--nx-primary);
70
+ }
71
+
72
+ .nx-chat-btn[data-chat="active"]:hover:not(:disabled) {
73
+ border-color: var(--nx-primary);
74
+ background: color-mix(in oklab, var(--nx-primary) 22%, var(--nx-surface));
75
+ color: var(--nx-primary);
76
+ }
77
+
78
+ /* Unread: the strongest step, so one glance down a list finds it. */
79
+ .nx-chat-btn[data-chat="unread"] {
80
+ border-color: var(--nx-primary-solid);
81
+ background: var(--nx-primary-solid);
82
+ color: var(--nx-primary-text);
83
+ }
84
+
85
+ .nx-chat-btn[data-chat="unread"]:hover:not(:disabled) {
86
+ background: var(--nx-primary-hover);
87
+ color: var(--nx-primary-text);
88
+ }
89
+
90
+ /* The number of unread messages, over the corner of the box so the box keeps its size. */
91
+ .nx-chat-btn__badge {
92
+ position: absolute;
93
+ top: -5px;
94
+ right: -5px;
95
+ display: grid;
96
+ place-items: center;
97
+ min-width: 16px;
98
+ height: 16px;
99
+ padding: 0 4px;
100
+ border: 1px solid var(--nx-surface);
101
+ border-radius: var(--nx-radius-full);
102
+ background: var(--nx-danger-solid);
103
+ color: var(--nx-danger-text);
104
+ font-size: 10px;
105
+ font-weight: 700;
106
+ font-variant-numeric: tabular-nums;
107
+ line-height: 1;
108
+ pointer-events: none;
109
+ }
110
+
111
+ /* The panel */
112
+
113
+ .nx-chat-panel {
114
+ --nx-chat-height: min(60vh, 520px);
115
+ --nx-avatar-size: 28px;
116
+
117
+ container-type: inline-size;
118
+ display: flex;
119
+ flex-direction: column;
120
+ height: var(--nx-chat-height);
121
+ min-height: 240px;
122
+ overflow: hidden;
123
+ background: var(--nx-surface);
124
+ color: var(--nx-text);
125
+ font-size: var(--nx-text-md);
126
+ }
127
+
128
+ /* A low bar, as a window has: the name at the start, the buttons flush in the corner. */
129
+ .nx-chat-panel__bar {
130
+ display: flex;
131
+ flex-shrink: 0;
132
+ align-items: center;
133
+ gap: var(--nx-space-2);
134
+ min-height: 36px;
135
+ padding: 0 var(--nx-space-2) 0 var(--nx-space-3);
136
+ border-bottom: 1px solid var(--nx-border);
137
+ background: var(--nx-surface-2);
138
+ }
139
+
140
+ .nx-chat-panel__heading {
141
+ display: flex;
142
+ flex: 1 1 auto;
143
+ gap: var(--nx-space-2);
144
+ align-items: baseline;
145
+ min-width: 0;
146
+ }
147
+
148
+ .nx-chat-panel__title {
149
+ overflow: hidden;
150
+ font-weight: 600;
151
+ white-space: nowrap;
152
+ text-overflow: ellipsis;
153
+ }
154
+
155
+ .nx-chat-panel__description {
156
+ overflow: hidden;
157
+ color: var(--nx-text-muted);
158
+ font-size: var(--nx-text-sm);
159
+ white-space: nowrap;
160
+ text-overflow: ellipsis;
161
+ }
162
+
163
+ .nx-chat-panel__people {
164
+ display: inline-flex;
165
+ flex-shrink: 0;
166
+ gap: 4px;
167
+ align-items: center;
168
+ height: 26px;
169
+ margin: 0;
170
+ padding: 0 6px;
171
+ border: 1px solid transparent;
172
+ border-radius: var(--nx-radius-sm);
173
+ background: none;
174
+ color: var(--nx-text-muted);
175
+ font: inherit;
176
+ font-size: var(--nx-text-sm);
177
+ font-variant-numeric: tabular-nums;
178
+ cursor: pointer;
179
+ }
180
+
181
+ .nx-chat-panel__people:hover,
182
+ .nx-chat-panel__people.is-open {
183
+ background: var(--nx-surface-hover);
184
+ color: var(--nx-text);
185
+ }
186
+
187
+ .nx-chat-panel__people:focus-visible {
188
+ outline: none;
189
+ box-shadow: var(--nx-focus-ring);
190
+ }
191
+
192
+ .nx-chat-panel__people .nx-icon {
193
+ width: 16px;
194
+ height: 16px;
195
+ vertical-align: 0;
196
+ }
197
+
198
+ .nx-chat-panel__body {
199
+ display: flex;
200
+ flex: 1 1 auto;
201
+ min-height: 0;
202
+ }
203
+
204
+ .nx-chat-panel__footer {
205
+ display: flex;
206
+ flex-shrink: 0;
207
+ gap: var(--nx-space-2);
208
+ justify-content: flex-end;
209
+ padding: var(--nx-space-2) var(--nx-space-3);
210
+ border-top: 1px solid var(--nx-border);
211
+ }
212
+
213
+ /* The people, in a column beside the thread: a dividing line, not a panel inside a panel. */
214
+ .nx-chat-panel__aside {
215
+ display: flex;
216
+ flex: 0 0 220px;
217
+ flex-direction: column;
218
+ min-width: 0;
219
+ overflow-y: auto;
220
+ border-left: 1px solid var(--nx-border);
221
+ }
222
+
223
+ .nx-chat-aside__bar {
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: space-between;
227
+ padding: var(--nx-space-2) var(--nx-space-2) var(--nx-space-2) var(--nx-space-3);
228
+ color: var(--nx-text-muted);
229
+ font-size: var(--nx-text-sm);
230
+ font-weight: 600;
231
+ }
232
+
233
+ .nx-chat-aside__bar button {
234
+ display: grid;
235
+ place-items: center;
236
+ width: 22px;
237
+ height: 22px;
238
+ padding: 0;
239
+ border: 0;
240
+ border-radius: var(--nx-radius-sm);
241
+ background: none;
242
+ color: var(--nx-text-subtle);
243
+ cursor: pointer;
244
+ }
245
+
246
+ .nx-chat-aside__bar button:hover {
247
+ background: var(--nx-surface-hover);
248
+ color: var(--nx-text);
249
+ }
250
+
251
+ .nx-chat-aside__bar button:focus-visible {
252
+ outline: none;
253
+ box-shadow: var(--nx-focus-ring);
254
+ }
255
+
256
+ .nx-chat-aside__bar .nx-icon {
257
+ width: 14px;
258
+ height: 14px;
259
+ vertical-align: 0;
260
+ }
261
+
262
+ .nx-chat-aside__empty {
263
+ margin: 0;
264
+ padding: 0 var(--nx-space-3) var(--nx-space-3);
265
+ color: var(--nx-text-muted);
266
+ font-size: var(--nx-text-sm);
267
+ }
268
+
269
+ .nx-chat-aside__add {
270
+ display: flex;
271
+ flex-direction: column;
272
+ gap: var(--nx-space-2);
273
+ margin-top: auto;
274
+ padding: var(--nx-space-3);
275
+ border-top: 1px solid var(--nx-border);
276
+ }
277
+
278
+ /* The thread */
279
+
280
+ .nx-chat-thread {
281
+ position: relative;
282
+ display: flex;
283
+ flex: 1 1 auto;
284
+ flex-direction: column;
285
+ min-width: 0;
286
+ }
287
+
288
+ .nx-chat-thread__list {
289
+ display: flex;
290
+ flex: 1 1 auto;
291
+ flex-direction: column;
292
+ gap: var(--nx-space-2);
293
+ padding: var(--nx-space-3);
294
+ overflow-y: auto;
295
+ overscroll-behavior: contain;
296
+ scrollbar-gutter: stable;
297
+ }
298
+
299
+ .nx-chat-thread__list:focus-visible {
300
+ outline: none;
301
+ box-shadow: inset var(--nx-focus-ring);
302
+ }
303
+
304
+ .nx-chat-thread__day {
305
+ display: flex;
306
+ flex-direction: column;
307
+ gap: var(--nx-space-2);
308
+ }
309
+
310
+ .nx-chat-thread__older {
311
+ display: flex;
312
+ justify-content: center;
313
+ }
314
+
315
+ /* Down to the newest, with how many arrived while the reader was elsewhere. */
316
+ .nx-chat-thread__jump {
317
+ position: absolute;
318
+ right: var(--nx-space-3);
319
+ bottom: var(--nx-space-3);
320
+ display: grid;
321
+ place-items: center;
322
+ width: 32px;
323
+ height: 32px;
324
+ padding: 0;
325
+ border: 1px solid var(--nx-border);
326
+ border-radius: var(--nx-radius-full);
327
+ background: var(--nx-surface);
328
+ color: var(--nx-text);
329
+ cursor: pointer;
330
+ box-shadow: var(--nx-shadow-sm);
331
+ }
332
+
333
+ .nx-chat-thread__jump:hover {
334
+ border-color: var(--nx-border-strong);
335
+ background: var(--nx-surface-hover);
336
+ }
337
+
338
+ .nx-chat-thread__jump:focus-visible {
339
+ outline: none;
340
+ box-shadow: var(--nx-focus-ring);
341
+ }
342
+
343
+ .nx-chat-thread__jump .nx-icon {
344
+ width: 16px;
345
+ height: 16px;
346
+ vertical-align: 0;
347
+ }
348
+
349
+ .nx-chat-thread__jump-count {
350
+ position: absolute;
351
+ top: -5px;
352
+ right: -5px;
353
+ display: grid;
354
+ place-items: center;
355
+ min-width: 16px;
356
+ height: 16px;
357
+ padding: 0 4px;
358
+ border: 1px solid var(--nx-surface);
359
+ border-radius: var(--nx-radius-full);
360
+ background: var(--nx-danger-solid);
361
+ color: var(--nx-danger-text);
362
+ font-size: 10px;
363
+ font-weight: 700;
364
+ line-height: 1;
365
+ }
366
+
367
+ /* The lines that break a thread up */
368
+
369
+ .nx-chat-day,
370
+ .nx-chat-unread-line {
371
+ display: flex;
372
+ gap: var(--nx-space-2);
373
+ align-items: center;
374
+ font-size: var(--nx-text-xs);
375
+ text-transform: none;
376
+ }
377
+
378
+ .nx-chat-day::before,
379
+ .nx-chat-day::after,
380
+ .nx-chat-unread-line::before,
381
+ .nx-chat-unread-line::after {
382
+ flex: 1 1 auto;
383
+ height: 1px;
384
+ background: var(--nx-border);
385
+ content: "";
386
+ }
387
+
388
+ .nx-chat-day > span {
389
+ color: var(--nx-text-muted);
390
+ font-weight: 600;
391
+ white-space: nowrap;
392
+ }
393
+
394
+ .nx-chat-unread-line::before,
395
+ .nx-chat-unread-line::after {
396
+ background: color-mix(in oklab, var(--nx-primary) 45%, transparent);
397
+ }
398
+
399
+ .nx-chat-unread-line {
400
+ margin: var(--nx-space-1) 0;
401
+ }
402
+
403
+ .nx-chat-unread-line > span {
404
+ padding: 2px 8px;
405
+ border-radius: var(--nx-radius-full);
406
+ background: var(--nx-primary-soft);
407
+ color: var(--nx-primary);
408
+ font-weight: 600;
409
+ white-space: nowrap;
410
+ }
411
+
412
+ /* A run of messages by one author */
413
+
414
+ .nx-chat-run {
415
+ display: flex;
416
+ gap: var(--nx-space-2);
417
+ align-items: flex-end;
418
+ }
419
+
420
+ .nx-chat-run--mine {
421
+ justify-content: flex-end;
422
+ }
423
+
424
+ .nx-chat-run--system {
425
+ flex-direction: column;
426
+ gap: var(--nx-space-1);
427
+ }
428
+
429
+ .nx-chat-run__avatar {
430
+ flex-shrink: 0;
431
+ }
432
+
433
+ .nx-chat-run__messages {
434
+ display: flex;
435
+ flex-direction: column;
436
+ gap: 2px;
437
+ min-width: 0;
438
+ max-width: min(82%, 46ch);
439
+ }
440
+
441
+ .nx-chat-run--mine .nx-chat-run__messages {
442
+ align-items: flex-end;
443
+ }
444
+
445
+ /* One message */
446
+
447
+ .nx-chat-msg {
448
+ display: flex;
449
+ flex-direction: column;
450
+ gap: 2px;
451
+ min-width: 0;
452
+ max-width: 100%;
453
+ }
454
+
455
+ .nx-chat-msg__bubble {
456
+ position: relative;
457
+ min-width: 0;
458
+ padding: 6px var(--nx-space-3) 6px;
459
+ border: 1px solid var(--nx-border);
460
+ border-radius: var(--nx-radius-lg);
461
+ line-height: 1.45;
462
+ }
463
+
464
+ .nx-chat-msg--theirs .nx-chat-msg__bubble {
465
+ background: var(--nx-surface-2);
466
+ }
467
+
468
+ .nx-chat-msg--mine .nx-chat-msg__bubble {
469
+ border-color: color-mix(in oklab, var(--nx-primary) 24%, transparent);
470
+ background: var(--nx-primary-soft);
471
+ }
472
+
473
+ /* A run reads as one block: only its outer corners are fully round. */
474
+ .nx-chat-msg--theirs:not(.nx-chat-msg--first) .nx-chat-msg__bubble {
475
+ border-top-left-radius: var(--nx-radius-sm);
476
+ }
477
+
478
+ .nx-chat-msg--theirs:not(.nx-chat-msg--last) .nx-chat-msg__bubble {
479
+ border-bottom-left-radius: var(--nx-radius-sm);
480
+ }
481
+
482
+ .nx-chat-msg--mine:not(.nx-chat-msg--first) .nx-chat-msg__bubble {
483
+ border-top-right-radius: var(--nx-radius-sm);
484
+ }
485
+
486
+ .nx-chat-msg--mine:not(.nx-chat-msg--last) .nx-chat-msg__bubble {
487
+ border-bottom-right-radius: var(--nx-radius-sm);
488
+ }
489
+
490
+ .nx-chat-msg--failed .nx-chat-msg__bubble {
491
+ border-color: color-mix(in oklab, var(--nx-danger) 45%, transparent);
492
+ background: var(--nx-danger-soft);
493
+ }
494
+
495
+ .nx-chat-msg__author {
496
+ display: block;
497
+ color: var(--nx-primary);
498
+ font-size: var(--nx-text-sm);
499
+ font-weight: 600;
500
+ }
501
+
502
+ /*
503
+ * A message is Markdown. Inside a bubble it keeps the bubble's rhythm rather than a document's: nothing above the
504
+ * first block or below the last, a tighter gap between blocks, headings that do not tower over a line of text, and
505
+ * code and tables that scroll inside the bubble instead of widening it.
506
+ */
507
+ .nx-chat-msg__body {
508
+ overflow-wrap: anywhere;
509
+ }
510
+
511
+ .nx-chat-msg__body > :first-child {
512
+ margin-top: 0;
513
+ }
514
+
515
+ .nx-chat-msg__body > :last-child {
516
+ margin-bottom: 0;
517
+ }
518
+
519
+ .nx-chat-msg__body > * + * {
520
+ margin-top: var(--nx-space-2);
521
+ }
522
+
523
+ .nx-chat-msg__body :is(h1, h2, h3, h4, h5, h6) {
524
+ font-size: var(--nx-text-lg);
525
+ }
526
+
527
+ .nx-chat-msg__body :is(ul, ol) {
528
+ padding-left: var(--nx-space-5);
529
+ }
530
+
531
+ .nx-chat-msg__body :is(pre, table) {
532
+ max-width: 100%;
533
+ overflow-x: auto;
534
+ }
535
+
536
+ .nx-chat-msg__meta {
537
+ display: flex;
538
+ gap: 4px;
539
+ align-items: center;
540
+ justify-content: flex-end;
541
+ color: var(--nx-text-muted);
542
+ font-size: var(--nx-text-xs);
543
+ font-variant-numeric: tabular-nums;
544
+ }
545
+
546
+ .nx-chat-msg__edited {
547
+ font-style: italic;
548
+ }
549
+
550
+ /* Sending, sent, delivered, read — one mark, one size, in the place the time sits. */
551
+ .nx-chat-mark {
552
+ display: inline-grid;
553
+ flex-shrink: 0;
554
+ place-items: center;
555
+ width: 14px;
556
+ height: 14px;
557
+ color: var(--nx-text-subtle);
558
+ }
559
+
560
+ .nx-chat-mark .nx-icon {
561
+ width: 14px;
562
+ height: 14px;
563
+ vertical-align: 0;
564
+ }
565
+
566
+ /* Read: the accent, so a glance down your own messages finds what has landed. */
567
+ .nx-chat-mark--seen {
568
+ color: var(--nx-primary);
569
+ }
570
+
571
+ .nx-chat-mark--failed {
572
+ color: var(--nx-danger);
573
+ }
574
+
575
+ /*
576
+ * The actions of a message: over its top corner, and shown only on hover or keyboard focus. They are laid over the
577
+ * bubble rather than taking a place in it, so nothing in the thread moves as the pointer travels down it.
578
+ */
579
+ .nx-chat-msg__actions {
580
+ position: absolute;
581
+ top: -12px;
582
+ display: none;
583
+ gap: 2px;
584
+ padding: 2px;
585
+ border: 1px solid var(--nx-border);
586
+ border-radius: var(--nx-radius);
587
+ background: var(--nx-surface);
588
+ box-shadow: var(--nx-shadow-sm);
589
+ }
590
+
591
+ .nx-chat-msg--theirs .nx-chat-msg__actions {
592
+ right: var(--nx-space-2);
593
+ }
594
+
595
+ .nx-chat-msg--mine .nx-chat-msg__actions {
596
+ left: var(--nx-space-2);
597
+ }
598
+
599
+ .nx-chat-msg:hover .nx-chat-msg__actions,
600
+ .nx-chat-msg:focus-within .nx-chat-msg__actions {
601
+ display: flex;
602
+ }
603
+
604
+ .nx-chat-msg__action {
605
+ display: grid;
606
+ place-items: center;
607
+ width: 22px;
608
+ height: 22px;
609
+ padding: 0;
610
+ border: 0;
611
+ border-radius: var(--nx-radius-sm);
612
+ background: none;
613
+ color: var(--nx-text-muted);
614
+ cursor: pointer;
615
+ }
616
+
617
+ .nx-chat-msg__action:hover {
618
+ background: var(--nx-surface-hover);
619
+ color: var(--nx-text);
620
+ }
621
+
622
+ .nx-chat-msg__action--danger:hover {
623
+ background: var(--nx-danger-soft);
624
+ color: var(--nx-danger);
625
+ }
626
+
627
+ .nx-chat-msg__action:focus-visible {
628
+ outline: none;
629
+ box-shadow: var(--nx-focus-ring);
630
+ }
631
+
632
+ .nx-chat-msg__action .nx-icon {
633
+ width: 14px;
634
+ height: 14px;
635
+ vertical-align: 0;
636
+ }
637
+
638
+ /* A message that did not arrive: it stays, with why and what can be done. */
639
+ .nx-chat-msg__failure {
640
+ display: flex;
641
+ flex-wrap: wrap;
642
+ gap: 6px;
643
+ align-items: center;
644
+ color: var(--nx-danger);
645
+ font-size: var(--nx-text-xs);
646
+ }
647
+
648
+ .nx-chat-msg__failure .nx-icon {
649
+ width: 14px;
650
+ height: 14px;
651
+ vertical-align: 0;
652
+ }
653
+
654
+ .nx-chat-msg__failure button {
655
+ display: inline-flex;
656
+ gap: 3px;
657
+ align-items: center;
658
+ padding: 0;
659
+ border: 0;
660
+ background: none;
661
+ color: var(--nx-danger);
662
+ font: inherit;
663
+ font-weight: 600;
664
+ text-decoration: underline;
665
+ cursor: pointer;
666
+ }
667
+
668
+ .nx-chat-msg__failure button:focus-visible {
669
+ outline: none;
670
+ box-shadow: var(--nx-focus-ring);
671
+ }
672
+
673
+ /* A quoted message, in the bubble that answers it and in the composer */
674
+
675
+ .nx-chat-quote {
676
+ display: flex;
677
+ flex-direction: column;
678
+ gap: 1px;
679
+ width: 100%;
680
+ margin: 2px 0 4px;
681
+ padding: 2px 0 2px var(--nx-space-2);
682
+ border: 0;
683
+ border-left: 2px solid color-mix(in oklab, var(--nx-primary) 60%, transparent);
684
+ background: none;
685
+ color: var(--nx-text-muted);
686
+ font: inherit;
687
+ font-size: var(--nx-text-sm);
688
+ text-align: start;
689
+ cursor: pointer;
690
+ }
691
+
692
+ .nx-chat-quote--gone {
693
+ border-left-color: var(--nx-border-strong);
694
+ font-style: italic;
695
+ cursor: default;
696
+ }
697
+
698
+ .nx-chat-quote:focus-visible {
699
+ outline: none;
700
+ box-shadow: var(--nx-focus-ring);
701
+ }
702
+
703
+ .nx-chat-quote__author {
704
+ color: var(--nx-primary);
705
+ font-weight: 600;
706
+ }
707
+
708
+ .nx-chat-quote__body {
709
+ display: block;
710
+ overflow: hidden;
711
+ white-space: nowrap;
712
+ text-overflow: ellipsis;
713
+ }
714
+
715
+ /* Files on a message */
716
+
717
+ .nx-chat-files {
718
+ display: flex;
719
+ flex-direction: column;
720
+ gap: 2px;
721
+ margin: 4px 0 2px;
722
+ padding: 0;
723
+ list-style: none;
724
+ }
725
+
726
+ .nx-chat-file > a,
727
+ .nx-chat-file > span {
728
+ display: inline-flex;
729
+ gap: 6px;
730
+ align-items: center;
731
+ max-width: 100%;
732
+ padding: 3px 6px;
733
+ border: 1px solid color-mix(in oklab, var(--nx-text) 18%, transparent);
734
+ border-radius: var(--nx-radius-sm);
735
+ background: none;
736
+ color: var(--nx-text);
737
+ font-size: var(--nx-text-sm);
738
+ text-decoration: none;
739
+ }
740
+
741
+ .nx-chat-file > a:hover {
742
+ border-color: var(--nx-primary);
743
+ background: color-mix(in oklab, var(--nx-primary) 10%, transparent);
744
+ color: var(--nx-primary);
745
+ }
746
+
747
+ .nx-chat-file > a:focus-visible {
748
+ outline: none;
749
+ box-shadow: var(--nx-focus-ring);
750
+ }
751
+
752
+ .nx-chat-file .nx-icon {
753
+ width: 14px;
754
+ height: 14px;
755
+ flex-shrink: 0;
756
+ vertical-align: 0;
757
+ }
758
+
759
+ .nx-chat-file__name {
760
+ overflow: hidden;
761
+ white-space: nowrap;
762
+ text-overflow: ellipsis;
763
+ }
764
+
765
+ .nx-chat-file__size {
766
+ flex-shrink: 0;
767
+ color: var(--nx-text-muted);
768
+ font-variant-numeric: tabular-nums;
769
+ }
770
+
771
+ /* A note the system wrote */
772
+
773
+ .nx-chat-note {
774
+ display: flex;
775
+ gap: 6px;
776
+ align-items: baseline;
777
+ align-self: center;
778
+ justify-content: center;
779
+ max-width: 90%;
780
+ padding: 2px 10px;
781
+ border-radius: var(--nx-radius-full);
782
+ background: var(--nx-surface-2);
783
+ color: var(--nx-text-muted);
784
+ font-size: var(--nx-text-xs);
785
+ text-align: center;
786
+ }
787
+
788
+ /* The people */
789
+
790
+ .nx-chat-people {
791
+ display: flex;
792
+ flex-direction: column;
793
+ gap: 2px;
794
+ margin: 0;
795
+ padding: 0 var(--nx-space-2) var(--nx-space-2);
796
+ list-style: none;
797
+ }
798
+
799
+ .nx-chat-person {
800
+ display: flex;
801
+ gap: var(--nx-space-2);
802
+ align-items: center;
803
+ padding: 4px var(--nx-space-2);
804
+ border-radius: var(--nx-radius-sm);
805
+ }
806
+
807
+ .nx-chat-person--inactive {
808
+ opacity: 0.6;
809
+ }
810
+
811
+ .nx-chat-person__text {
812
+ display: flex;
813
+ flex-direction: column;
814
+ min-width: 0;
815
+ }
816
+
817
+ .nx-chat-person__name {
818
+ display: flex;
819
+ gap: 4px;
820
+ align-items: baseline;
821
+ overflow: hidden;
822
+ font-size: var(--nx-text-sm);
823
+ font-weight: 500;
824
+ white-space: nowrap;
825
+ text-overflow: ellipsis;
826
+ }
827
+
828
+ .nx-chat-person__you {
829
+ color: var(--nx-text-subtle);
830
+ font-size: var(--nx-text-xs);
831
+ font-weight: 400;
832
+ }
833
+
834
+ .nx-chat-person__role {
835
+ overflow: hidden;
836
+ color: var(--nx-text-muted);
837
+ font-size: var(--nx-text-xs);
838
+ white-space: nowrap;
839
+ text-overflow: ellipsis;
840
+ }
841
+
842
+ /* Empty, loading, and failed */
843
+
844
+ .nx-chat-empty {
845
+ display: flex;
846
+ flex: 1 1 auto;
847
+ flex-direction: column;
848
+ gap: 4px;
849
+ align-items: center;
850
+ justify-content: center;
851
+ padding: var(--nx-space-6) var(--nx-space-4);
852
+ color: var(--nx-text-muted);
853
+ text-align: center;
854
+ }
855
+
856
+ .nx-chat-empty p {
857
+ margin: 0;
858
+ }
859
+
860
+ .nx-chat-empty__hint {
861
+ display: inline-flex;
862
+ gap: 6px;
863
+ align-items: center;
864
+ color: var(--nx-text-subtle);
865
+ font-size: var(--nx-text-sm);
866
+ }
867
+
868
+ .nx-chat-empty .nx-icon {
869
+ width: 15px;
870
+ height: 15px;
871
+ vertical-align: 0;
872
+ }
873
+
874
+ .nx-chat-loading {
875
+ display: flex;
876
+ gap: 6px;
877
+ align-items: center;
878
+ align-self: center;
879
+ color: var(--nx-text-muted);
880
+ font-size: var(--nx-text-sm);
881
+ }
882
+
883
+ .nx-chat-loading .nx-icon,
884
+ .nx-chat-failure .nx-icon {
885
+ width: 15px;
886
+ height: 15px;
887
+ vertical-align: 0;
888
+ }
889
+
890
+ .nx-chat-failure {
891
+ display: flex;
892
+ flex-wrap: wrap;
893
+ gap: 6px;
894
+ align-items: center;
895
+ padding: var(--nx-space-2) var(--nx-space-3);
896
+ border: 1px solid color-mix(in oklab, var(--nx-danger) 35%, transparent);
897
+ border-radius: var(--nx-radius);
898
+ background: var(--nx-danger-soft);
899
+ color: var(--nx-danger);
900
+ font-size: var(--nx-text-sm);
901
+ }
902
+
903
+ .nx-chat-failure button {
904
+ display: inline-flex;
905
+ gap: 3px;
906
+ align-items: center;
907
+ padding: 0;
908
+ border: 0;
909
+ background: none;
910
+ color: var(--nx-danger);
911
+ font: inherit;
912
+ font-weight: 600;
913
+ text-decoration: underline;
914
+ cursor: pointer;
915
+ }
916
+
917
+ .nx-chat-failure button:focus-visible {
918
+ outline: none;
919
+ box-shadow: var(--nx-focus-ring);
920
+ }
921
+
922
+ /* The composer */
923
+
924
+ .nx-chat-composer {
925
+ display: flex;
926
+ flex-shrink: 0;
927
+ flex-direction: column;
928
+ gap: var(--nx-space-2);
929
+ padding: var(--nx-space-2) var(--nx-space-3);
930
+ border-top: 1px solid var(--nx-border);
931
+ background: var(--nx-surface);
932
+ }
933
+
934
+ .nx-chat-composer--readonly p {
935
+ display: flex;
936
+ gap: 6px;
937
+ align-items: center;
938
+ justify-content: center;
939
+ margin: 0;
940
+ padding: var(--nx-space-1) 0;
941
+ color: var(--nx-text-muted);
942
+ font-size: var(--nx-text-sm);
943
+ text-align: center;
944
+ }
945
+
946
+ /* The editor is the whole writing area, so the row under it carries only the hint and the buttons. */
947
+ .nx-chat-composer__row {
948
+ display: flex;
949
+ gap: var(--nx-space-2);
950
+ align-items: center;
951
+ }
952
+
953
+ .nx-chat-composer__hint {
954
+ flex: 1 1 auto;
955
+ min-width: 0;
956
+ overflow: hidden;
957
+ color: var(--nx-text-subtle);
958
+ font-size: var(--nx-text-xs);
959
+ white-space: nowrap;
960
+ text-overflow: ellipsis;
961
+ }
962
+
963
+ .nx-chat-composer__attach,
964
+ .nx-chat-composer__send {
965
+ display: inline-grid;
966
+ flex-shrink: 0;
967
+ grid-auto-flow: column;
968
+ gap: 6px;
969
+ place-items: center;
970
+ width: 30px;
971
+ height: 30px;
972
+ padding: 0;
973
+ border: 0;
974
+ border-radius: var(--nx-radius);
975
+ background: none;
976
+ color: var(--nx-text-muted);
977
+ font: inherit;
978
+ cursor: pointer;
979
+ }
980
+
981
+ .nx-chat-composer__attach:hover {
982
+ background: var(--nx-surface-hover);
983
+ color: var(--nx-text);
984
+ }
985
+
986
+ .nx-chat-composer__send {
987
+ width: auto;
988
+ padding: 0 10px;
989
+ background: var(--nx-primary-solid);
990
+ color: var(--nx-primary-text);
991
+ font-size: var(--nx-text-sm);
992
+ font-weight: 600;
993
+ }
994
+
995
+ .nx-chat-composer__send:hover:not(:disabled) {
996
+ background: var(--nx-primary-hover);
997
+ }
998
+
999
+ .nx-chat-composer__send:disabled {
1000
+ background: var(--nx-surface-hover);
1001
+ color: var(--nx-text-subtle);
1002
+ cursor: not-allowed;
1003
+ }
1004
+
1005
+ .nx-chat-composer__attach:focus-visible,
1006
+ .nx-chat-composer__send:focus-visible {
1007
+ outline: none;
1008
+ box-shadow: var(--nx-focus-ring);
1009
+ }
1010
+
1011
+ .nx-chat-composer__attach .nx-icon,
1012
+ .nx-chat-composer__send .nx-icon {
1013
+ width: 16px;
1014
+ height: 16px;
1015
+ vertical-align: 0;
1016
+ }
1017
+
1018
+ .nx-chat-composer__reply {
1019
+ display: flex;
1020
+ gap: var(--nx-space-2);
1021
+ align-items: center;
1022
+ padding: var(--nx-space-1) var(--nx-space-2);
1023
+ border-left: 2px solid var(--nx-primary);
1024
+ border-radius: 0 var(--nx-radius-sm) var(--nx-radius-sm) 0;
1025
+ background: var(--nx-surface-2);
1026
+ font-size: var(--nx-text-sm);
1027
+ }
1028
+
1029
+ .nx-chat-composer__reply-text {
1030
+ display: flex;
1031
+ flex: 1 1 auto;
1032
+ gap: 6px;
1033
+ min-width: 0;
1034
+ color: var(--nx-text-muted);
1035
+ }
1036
+
1037
+ .nx-chat-composer__reply-text > span:last-child {
1038
+ overflow: hidden;
1039
+ white-space: nowrap;
1040
+ text-overflow: ellipsis;
1041
+ }
1042
+
1043
+ .nx-chat-composer__reply-author {
1044
+ flex-shrink: 0;
1045
+ color: var(--nx-primary);
1046
+ font-weight: 600;
1047
+ }
1048
+
1049
+ .nx-chat-composer__reply button,
1050
+ .nx-chat-composer__files button {
1051
+ display: grid;
1052
+ flex-shrink: 0;
1053
+ place-items: center;
1054
+ width: 20px;
1055
+ height: 20px;
1056
+ padding: 0;
1057
+ border: 0;
1058
+ border-radius: var(--nx-radius-sm);
1059
+ background: none;
1060
+ color: var(--nx-text-subtle);
1061
+ cursor: pointer;
1062
+ }
1063
+
1064
+ .nx-chat-composer__reply button:hover,
1065
+ .nx-chat-composer__files button:hover {
1066
+ background: var(--nx-surface-hover);
1067
+ color: var(--nx-text);
1068
+ }
1069
+
1070
+ .nx-chat-composer__reply button:focus-visible,
1071
+ .nx-chat-composer__files button:focus-visible {
1072
+ outline: none;
1073
+ box-shadow: var(--nx-focus-ring);
1074
+ }
1075
+
1076
+ .nx-chat-composer__reply .nx-icon,
1077
+ .nx-chat-composer__files .nx-icon {
1078
+ width: 13px;
1079
+ height: 13px;
1080
+ vertical-align: 0;
1081
+ }
1082
+
1083
+ .nx-chat-composer__files {
1084
+ display: flex;
1085
+ flex-wrap: wrap;
1086
+ gap: var(--nx-space-1);
1087
+ margin: 0;
1088
+ padding: 0;
1089
+ list-style: none;
1090
+ }
1091
+
1092
+ .nx-chat-composer__files li {
1093
+ display: inline-flex;
1094
+ gap: 6px;
1095
+ align-items: center;
1096
+ max-width: 100%;
1097
+ padding: 2px 4px 2px 8px;
1098
+ border: 1px solid var(--nx-border);
1099
+ border-radius: var(--nx-radius-full);
1100
+ background: var(--nx-surface-2);
1101
+ font-size: var(--nx-text-xs);
1102
+ }
1103
+
1104
+ .nx-chat-composer__file-name {
1105
+ overflow: hidden;
1106
+ white-space: nowrap;
1107
+ text-overflow: ellipsis;
1108
+ }
1109
+
1110
+ .nx-chat-composer__file-size {
1111
+ color: var(--nx-text-muted);
1112
+ font-variant-numeric: tabular-nums;
1113
+ }
1114
+
1115
+
1116
+ /*
1117
+ * The conversation list and the New chat form: the panel's other two views. They sit where the thread sits, with
1118
+ * the same bar above them, so the panel never grows a second frame inside itself.
1119
+ */
1120
+
1121
+ .nx-chat-list {
1122
+ display: flex;
1123
+ flex: 1 1 auto;
1124
+ flex-direction: column;
1125
+ min-width: 0;
1126
+ padding: var(--nx-space-2);
1127
+ overflow-y: auto;
1128
+ }
1129
+
1130
+ .nx-chat-list__items {
1131
+ display: flex;
1132
+ flex: 1 1 auto;
1133
+ flex-direction: column;
1134
+ gap: 2px;
1135
+ margin: 0;
1136
+ padding: 0;
1137
+ list-style: none;
1138
+ }
1139
+
1140
+ .nx-chat-list__item {
1141
+ display: flex;
1142
+ gap: var(--nx-space-2);
1143
+ align-items: center;
1144
+ width: 100%;
1145
+ padding: var(--nx-space-2);
1146
+ border: 1px solid transparent;
1147
+ border-radius: var(--nx-radius);
1148
+ background: none;
1149
+ color: var(--nx-text);
1150
+ font: inherit;
1151
+ text-align: start;
1152
+ cursor: pointer;
1153
+ }
1154
+
1155
+ .nx-chat-list__item:hover {
1156
+ background: var(--nx-surface-hover);
1157
+ }
1158
+
1159
+ .nx-chat-list__item:focus-visible {
1160
+ outline: none;
1161
+ box-shadow: var(--nx-focus-ring);
1162
+ }
1163
+
1164
+ /* The one open now: the accent tint, so the list says where you are without a word for it. */
1165
+ .nx-chat-list__item.is-current {
1166
+ border-color: color-mix(in oklab, var(--nx-primary) 28%, transparent);
1167
+ background: var(--nx-primary-soft);
1168
+ }
1169
+
1170
+ .nx-chat-list__group {
1171
+ display: grid;
1172
+ flex-shrink: 0;
1173
+ place-items: center;
1174
+ width: var(--nx-avatar-size, 28px);
1175
+ height: var(--nx-avatar-size, 28px);
1176
+ border-radius: 50%;
1177
+ background: var(--nx-surface-2);
1178
+ color: var(--nx-text-muted);
1179
+ }
1180
+
1181
+ .nx-chat-list__group .nx-icon {
1182
+ width: 15px;
1183
+ height: 15px;
1184
+ vertical-align: 0;
1185
+ }
1186
+
1187
+ .nx-chat-list__text {
1188
+ display: flex;
1189
+ flex: 1 1 auto;
1190
+ flex-direction: column;
1191
+ gap: 1px;
1192
+ min-width: 0;
1193
+ }
1194
+
1195
+ .nx-chat-list__line {
1196
+ display: flex;
1197
+ gap: var(--nx-space-2);
1198
+ align-items: baseline;
1199
+ justify-content: space-between;
1200
+ min-width: 0;
1201
+ }
1202
+
1203
+ .nx-chat-list__name {
1204
+ overflow: hidden;
1205
+ font-weight: 600;
1206
+ white-space: nowrap;
1207
+ text-overflow: ellipsis;
1208
+ }
1209
+
1210
+ .nx-chat-list__when {
1211
+ flex-shrink: 0;
1212
+ color: var(--nx-text-subtle);
1213
+ font-size: var(--nx-text-xs);
1214
+ white-space: nowrap;
1215
+ }
1216
+
1217
+ .nx-chat-list__last {
1218
+ overflow: hidden;
1219
+ color: var(--nx-text-muted);
1220
+ font-size: var(--nx-text-sm);
1221
+ white-space: nowrap;
1222
+ text-overflow: ellipsis;
1223
+ }
1224
+
1225
+ .nx-chat-list__badge {
1226
+ display: grid;
1227
+ flex-shrink: 0;
1228
+ place-items: center;
1229
+ min-width: 18px;
1230
+ height: 18px;
1231
+ padding: 0 5px;
1232
+ border-radius: var(--nx-radius-full);
1233
+ background: var(--nx-danger-solid);
1234
+ color: var(--nx-danger-text);
1235
+ font-size: 11px;
1236
+ font-weight: 700;
1237
+ font-variant-numeric: tabular-nums;
1238
+ line-height: 1;
1239
+ }
1240
+
1241
+ .nx-chat-list__new {
1242
+ flex-shrink: 0;
1243
+ padding-top: var(--nx-space-2);
1244
+ margin-top: var(--nx-space-2);
1245
+ border-top: 1px solid var(--nx-border);
1246
+ }
1247
+
1248
+ /* New chat */
1249
+
1250
+ .nx-chat-new {
1251
+ display: flex;
1252
+ flex: 1 1 auto;
1253
+ flex-direction: column;
1254
+ min-width: 0;
1255
+ padding: var(--nx-space-3);
1256
+ overflow-y: auto;
1257
+ }
1258
+
1259
+ .nx-chat-new__fields {
1260
+ display: flex;
1261
+ flex: 1 1 auto;
1262
+ flex-direction: column;
1263
+ gap: var(--nx-space-3);
1264
+ }
1265
+
1266
+ .nx-chat-new__kind {
1267
+ display: flex;
1268
+ gap: 6px;
1269
+ align-items: center;
1270
+ margin: 0;
1271
+ color: var(--nx-text-muted);
1272
+ font-size: var(--nx-text-sm);
1273
+ }
1274
+
1275
+ .nx-chat-new__kind .nx-icon {
1276
+ width: 15px;
1277
+ height: 15px;
1278
+ flex-shrink: 0;
1279
+ vertical-align: 0;
1280
+ }
1281
+
1282
+ .nx-chat-new__actions {
1283
+ display: flex;
1284
+ flex-shrink: 0;
1285
+ gap: var(--nx-space-2);
1286
+ justify-content: flex-end;
1287
+ padding-top: var(--nx-space-3);
1288
+ }
1289
+
1290
+ .nx-chat-new__note {
1291
+ margin: var(--nx-space-1) 0 0;
1292
+ color: var(--nx-text-subtle);
1293
+ font-size: var(--nx-text-xs);
1294
+ text-align: end;
1295
+ }
1296
+
1297
+ /* The bar's switch between conversations */
1298
+
1299
+ .nx-chat-panel__switch {
1300
+ display: inline-flex;
1301
+ gap: 4px;
1302
+ align-items: center;
1303
+ min-width: 0;
1304
+ margin: 0;
1305
+ padding: 2px 6px;
1306
+ border: 0;
1307
+ border-radius: var(--nx-radius-sm);
1308
+ background: none;
1309
+ color: inherit;
1310
+ font: inherit;
1311
+ cursor: pointer;
1312
+ }
1313
+
1314
+ .nx-chat-panel__switch:hover {
1315
+ background: var(--nx-surface-hover);
1316
+ }
1317
+
1318
+ .nx-chat-panel__switch:focus-visible {
1319
+ outline: none;
1320
+ box-shadow: var(--nx-focus-ring);
1321
+ }
1322
+
1323
+ .nx-chat-panel__switch .nx-icon {
1324
+ width: 14px;
1325
+ height: 14px;
1326
+ flex-shrink: 0;
1327
+ vertical-align: 0;
1328
+ }
1329
+
1330
+ .nx-chat-panel__of {
1331
+ flex-shrink: 0;
1332
+ color: var(--nx-text-subtle);
1333
+ font-size: var(--nx-text-xs);
1334
+ font-weight: 400;
1335
+ }
1336
+
1337
+ .nx-chat-panel__back {
1338
+ display: grid;
1339
+ flex-shrink: 0;
1340
+ place-items: center;
1341
+ width: 24px;
1342
+ height: 24px;
1343
+ margin-left: calc(var(--nx-space-2) * -1);
1344
+ padding: 0;
1345
+ border: 0;
1346
+ border-radius: var(--nx-radius-sm);
1347
+ background: none;
1348
+ color: var(--nx-text-muted);
1349
+ cursor: pointer;
1350
+ }
1351
+
1352
+ .nx-chat-panel__back:hover {
1353
+ background: var(--nx-surface-hover);
1354
+ color: var(--nx-text);
1355
+ }
1356
+
1357
+ .nx-chat-panel__back:focus-visible {
1358
+ outline: none;
1359
+ box-shadow: var(--nx-focus-ring);
1360
+ }
1361
+
1362
+ .nx-chat-panel__back .nx-icon {
1363
+ width: 15px;
1364
+ height: 15px;
1365
+ vertical-align: 0;
1366
+ }
1367
+
1368
+ /*
1369
+ * The people an `@` offers. It opens above the composer, because the composer is at the bottom of the panel and a
1370
+ * list under it would fall outside. The highlighted row is the one Enter puts in.
1371
+ */
1372
+ .nx-chat-mentions {
1373
+ display: flex;
1374
+ flex-direction: column;
1375
+ gap: 1px;
1376
+ max-height: 200px;
1377
+ margin: 0;
1378
+ padding: var(--nx-space-1);
1379
+ overflow-y: auto;
1380
+ border: 1px solid var(--nx-border);
1381
+ border-radius: var(--nx-radius);
1382
+ background: var(--nx-surface);
1383
+ list-style: none;
1384
+ box-shadow: var(--nx-shadow-sm);
1385
+ }
1386
+
1387
+ .nx-chat-mentions__item {
1388
+ display: flex;
1389
+ gap: var(--nx-space-2);
1390
+ align-items: center;
1391
+ width: 100%;
1392
+ padding: 4px var(--nx-space-2);
1393
+ border: 0;
1394
+ border-radius: var(--nx-radius-sm);
1395
+ background: none;
1396
+ color: var(--nx-text);
1397
+ font: inherit;
1398
+ font-size: var(--nx-text-sm);
1399
+ text-align: start;
1400
+ cursor: pointer;
1401
+ }
1402
+
1403
+ .nx-chat-mentions__item.is-at {
1404
+ background: var(--nx-primary-soft);
1405
+ color: var(--nx-primary);
1406
+ }
1407
+
1408
+ .nx-chat-mentions__name {
1409
+ overflow: hidden;
1410
+ font-weight: 500;
1411
+ white-space: nowrap;
1412
+ text-overflow: ellipsis;
1413
+ }
1414
+
1415
+ .nx-chat-mentions__role {
1416
+ margin-left: auto;
1417
+ overflow: hidden;
1418
+ color: var(--nx-text-muted);
1419
+ font-size: var(--nx-text-xs);
1420
+ white-space: nowrap;
1421
+ }
1422
+
1423
+ /*
1424
+ * A narrow panel: the people cover the thread rather than squeezing it. Measured, not guessed — at 520px the column
1425
+ * would leave the thread under 300px, which is narrower than the bubbles want.
1426
+ */
1427
+ @container (max-width: 520px) {
1428
+ .nx-chat-panel__body {
1429
+ position: relative;
1430
+ }
1431
+
1432
+ .nx-chat-panel__aside {
1433
+ position: absolute;
1434
+ inset: 0;
1435
+ flex-basis: auto;
1436
+ background: var(--nx-surface);
1437
+ }
1438
+ }
1439
+
1440
+ [data-nx-motion="reduce"] .nx-chat-btn {
1441
+ transition: none;
1442
+ }
1443
+ }