nexus-shared 3.0.0 → 3.1.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 (121) hide show
  1. package/CHANGELOG.md +446 -262
  2. package/LICENSE +21 -21
  3. package/README.md +1084 -1000
  4. package/dist/Client.Index.d.ts +3 -0
  5. package/dist/Client.Index.js +3 -0
  6. package/dist/Components/Chats/ChatParts.d.ts +2 -2
  7. package/dist/Components/Chats/ChatParts.js +3 -7
  8. package/dist/Components/Chats/ChatThread.js +3 -3
  9. package/dist/Components/Documents/Button.d.ts +6 -1
  10. package/dist/Components/Documents/Button.js +2 -2
  11. package/dist/Components/Documents/Menu.js +21 -9
  12. package/dist/Components/Documents/SplitButton.d.ts +3 -1
  13. package/dist/Components/Documents/SplitButton.js +7 -5
  14. package/dist/Components/Documents/TabButtons.d.ts +5 -2
  15. package/dist/Components/Documents/TabButtons.js +2 -2
  16. package/dist/Components/Forms/ApiForm.d.ts +1 -1
  17. package/dist/Components/Forms/ApiForm.js +1 -1
  18. package/dist/Components/Forms/Crud.js +177 -58
  19. package/dist/Components/Forms/CrudParts.d.ts +5 -1
  20. package/dist/Components/Forms/CrudParts.js +37 -5
  21. package/dist/Components/Forms/ExcelImport.d.ts +23 -7
  22. package/dist/Components/Forms/ExcelImport.js +189 -60
  23. package/dist/Components/Forms/Form.js +5 -13
  24. package/dist/Components/Forms/SubmitForm.d.ts +11 -2
  25. package/dist/Components/Forms/SubmitForm.js +23 -12
  26. package/dist/Components/Inputs/DropdownParts.d.ts +1 -1
  27. package/dist/Components/Inputs/DropdownParts.js +4 -6
  28. package/dist/Components/Inputs/NumberBox.js +24 -2
  29. package/dist/Components/Inputs/RowsInput.js +2 -2
  30. package/dist/Components/Inputs/Slider.js +4 -1
  31. package/dist/Components/Inputs/TabularForm.js +42 -10
  32. package/dist/Components/Inputs/TimePanel.js +4 -3
  33. package/dist/Components/Layouts/Popup.js +1 -4
  34. package/dist/Components/Layouts/ThemePicker.d.ts +20 -3
  35. package/dist/Components/Layouts/ThemePicker.js +77 -6
  36. package/dist/Components/Layouts/ThemeScript.d.ts +4 -2
  37. package/dist/Components/Layouts/ThemeScript.js +4 -2
  38. package/dist/Components/Layouts/ThemeSwitcher.d.ts +6 -3
  39. package/dist/Components/Layouts/ThemeSwitcher.js +9 -8
  40. package/dist/Components/Viewers/Avatar.d.ts +21 -0
  41. package/dist/Components/Viewers/Avatar.js +21 -0
  42. package/dist/Components/Viewers/DataTable.js +192 -44
  43. package/dist/Components/Viewers/DataTableColumns.d.ts +7 -3
  44. package/dist/Components/Viewers/DataTableColumns.js +25 -68
  45. package/dist/Components/Viewers/DataTableFilters.d.ts +21 -0
  46. package/dist/Components/Viewers/DataTableFilters.js +68 -0
  47. package/dist/Components/Viewers/DataTableParts.d.ts +2 -2
  48. package/dist/Components/Viewers/DataTableParts.js +3 -3
  49. package/dist/Helpers/AnimationHelpers.d.ts +11 -0
  50. package/dist/Helpers/AnimationHelpers.js +20 -2
  51. package/dist/Helpers/CrudBackend.d.ts +7 -4
  52. package/dist/Helpers/CrudBackend.js +4 -2
  53. package/dist/Helpers/ExcelBackend.d.ts +3 -3
  54. package/dist/Helpers/ExcelBackend.js +8 -2
  55. package/dist/Helpers/ExcelHelpers.d.ts +36 -8
  56. package/dist/Helpers/ExcelHelpers.js +55 -13
  57. package/dist/Helpers/FormStore.d.ts +9 -5
  58. package/dist/Helpers/FormStore.js +25 -5
  59. package/dist/Helpers/MessageBuilder.js +1 -0
  60. package/dist/Helpers/NumberHelpers.d.ts +7 -1
  61. package/dist/Helpers/NumberHelpers.js +41 -3
  62. package/dist/Helpers/PopoverHelpers.d.ts +17 -5
  63. package/dist/Helpers/PopoverHelpers.js +52 -17
  64. package/dist/Helpers/PopoverHooks.d.ts +24 -0
  65. package/dist/Helpers/PopoverHooks.js +62 -0
  66. package/dist/Helpers/RowsStore.d.ts +7 -2
  67. package/dist/Helpers/RowsStore.js +15 -3
  68. package/dist/Helpers/TableExport.js +12 -12
  69. package/dist/Helpers/TableFilters.d.ts +25 -0
  70. package/dist/Helpers/TableFilters.js +162 -0
  71. package/dist/Helpers/TableHelpers.d.ts +6 -3
  72. package/dist/Helpers/TableHelpers.js +8 -4
  73. package/dist/Helpers/TableStore.d.ts +11 -3
  74. package/dist/Helpers/TableStore.js +16 -5
  75. package/dist/Helpers/ThemeHelpers.d.ts +21 -4
  76. package/dist/Helpers/ThemeHelpers.js +46 -9
  77. package/dist/Helpers/UserPreferences.d.ts +14 -0
  78. package/dist/Helpers/UserPreferences.js +99 -0
  79. package/dist/Interfaces/CrudInterfaces.d.ts +20 -1
  80. package/dist/Interfaces/ExcelInterfaces.d.ts +12 -0
  81. package/dist/Interfaces/FormInterfaces.d.ts +33 -5
  82. package/dist/Interfaces/PreferenceInterfaces.d.ts +43 -0
  83. package/dist/Interfaces/PreferenceInterfaces.js +28 -0
  84. package/dist/Interfaces/TableInterfaces.d.ts +59 -12
  85. package/dist/Interfaces/ThemeInterfaces.d.ts +25 -0
  86. package/dist/Interfaces/ThemeInterfaces.js +15 -0
  87. package/dist/Services/ExcelApi.d.ts +3 -1
  88. package/dist/Services/ExcelApi.js +1 -1
  89. package/dist/Services/ThemeService.d.ts +18 -2
  90. package/dist/Services/ThemeService.js +80 -16
  91. package/dist/Shared.Index.d.ts +2 -0
  92. package/dist/Shared.Index.js +2 -0
  93. package/package.json +85 -85
  94. package/src/Styles/Nexus.Avatar.css +79 -0
  95. package/src/Styles/Nexus.Base.css +117 -70
  96. package/src/Styles/Nexus.Button.css +180 -153
  97. package/src/Styles/Nexus.Calendar.css +273 -275
  98. package/src/Styles/Nexus.Chat.css +1443 -1489
  99. package/src/Styles/Nexus.Choice.css +343 -345
  100. package/src/Styles/Nexus.Crud.css +168 -161
  101. package/src/Styles/Nexus.DateTime.css +81 -81
  102. package/src/Styles/Nexus.Dropdown.css +725 -774
  103. package/src/Styles/Nexus.Editor.css +295 -297
  104. package/src/Styles/Nexus.Excel.css +389 -370
  105. package/src/Styles/Nexus.Form.css +279 -321
  106. package/src/Styles/Nexus.Index.css +37 -36
  107. package/src/Styles/Nexus.Input.css +602 -637
  108. package/src/Styles/Nexus.Markdown.css +237 -265
  109. package/src/Styles/Nexus.Menu.css +237 -259
  110. package/src/Styles/Nexus.Popup.css +724 -731
  111. package/src/Styles/Nexus.RichText.css +2 -32
  112. package/src/Styles/Nexus.Rows.css +637 -596
  113. package/src/Styles/Nexus.Slider.css +276 -278
  114. package/src/Styles/Nexus.Tab.Buttons.css +432 -419
  115. package/src/Styles/Nexus.Table.css +1386 -1296
  116. package/src/Styles/Nexus.Theme.Picker.css +286 -232
  117. package/src/Styles/Nexus.Themes.css +194 -194
  118. package/src/Styles/Nexus.Time.css +144 -147
  119. package/src/Styles/Nexus.Toast.css +263 -265
  120. package/src/Styles/Nexus.Tokens.css +89 -72
  121. package/src/Styles/Nexus.Tree.css +431 -435
@@ -1,370 +1,389 @@
1
- @layer nexus.components {
2
- /*
3
- * The spreadsheet import panel: the three steps, the file row, and the review as two collapsible editors.
4
- *
5
- * It adds no box of its own. It is shown inside a popup or a page panel, which already has one, and the editors
6
- * inside bring the only frame on the panel - so nothing here draws a border around something that has one. The
7
- * sections are told apart by a tint and a hairline above them, as the group form's sections are.
8
- */
9
- .nx-excel {
10
- --nx-excel-tint: color-mix(in oklab, var(--nx-text) 5%, var(--nx-surface));
11
- --nx-excel-hover: color-mix(in oklab, var(--nx-text) 8%, var(--nx-surface));
12
- display: flex;
13
- flex-direction: column;
14
- gap: var(--nx-space-4);
15
- min-width: 0;
16
- }
17
-
18
- /* The three steps, numbered, as one short paragraph each. */
19
- .nx-excel__steps {
20
- display: flex;
21
- flex-wrap: wrap;
22
- gap: var(--nx-space-2) var(--nx-space-5);
23
- margin: 0;
24
- padding: 0;
25
- list-style: none;
26
- counter-reset: nx-excel-step;
27
- color: var(--nx-text-muted);
28
- font-size: var(--nx-text-xs);
29
- line-height: 1.45;
30
- }
31
-
32
- .nx-excel__steps > li {
33
- display: flex;
34
- flex: 1 1 14rem;
35
- align-items: baseline;
36
- gap: var(--nx-space-2);
37
- counter-increment: nx-excel-step;
38
- }
39
-
40
- .nx-excel__steps > li::before {
41
- content: counter(nx-excel-step);
42
- flex: none;
43
- min-width: 17px;
44
- padding: 1px 0;
45
- border-radius: var(--nx-radius-full);
46
- background: var(--nx-excel-tint);
47
- color: var(--nx-text);
48
- font-size: var(--nx-text-xs);
49
- font-weight: 600;
50
- text-align: center;
51
- }
52
-
53
- /* Template, Choose file, the file's name, and the limit: one line that wraps as whole groups. */
54
- .nx-excel__pick {
55
- display: flex;
56
- flex-wrap: wrap;
57
- align-items: center;
58
- gap: var(--nx-space-2) var(--nx-space-3);
59
- }
60
-
61
- .nx-excel__file {
62
- flex: 1 1 12rem;
63
- min-width: 0;
64
- margin: 0;
65
- overflow-wrap: anywhere;
66
- color: var(--nx-text);
67
- font-size: var(--nx-text-sm);
68
- }
69
-
70
- .nx-excel__muted {
71
- color: var(--nx-text-muted);
72
- }
73
-
74
- .nx-excel__limits {
75
- margin: 0;
76
- color: var(--nx-text-muted);
77
- font-size: var(--nx-text-xs);
78
- white-space: nowrap;
79
- }
80
-
81
- .nx-excel__note {
82
- margin: 0;
83
- color: var(--nx-text);
84
- font-size: var(--nx-text-sm);
85
- }
86
-
87
- /* A refusal, and what the import could not write: a tint, with the words in the text color so they read on it. */
88
- .nx-excel__failure,
89
- .nx-excel__result {
90
- display: flex;
91
- gap: var(--nx-space-2);
92
- margin: 0;
93
- padding: var(--nx-space-3);
94
- border-radius: var(--nx-radius);
95
- background: var(--nx-danger-soft);
96
- color: var(--nx-text);
97
- font-size: var(--nx-text-sm);
98
- line-height: 1.45;
99
- }
100
-
101
- .nx-excel__failure .nx-icon,
102
- .nx-excel__result .nx-icon {
103
- flex: none;
104
- width: 18px;
105
- height: 18px;
106
- color: var(--nx-danger);
107
- }
108
-
109
- .nx-excel__result {
110
- flex-direction: column;
111
- gap: var(--nx-space-1);
112
- }
113
-
114
- .nx-excel__result--ok {
115
- background: var(--nx-success-soft);
116
- }
117
-
118
- .nx-excel__result--ok .nx-icon {
119
- color: var(--nx-success);
120
- }
121
-
122
- .nx-excel__result-head {
123
- display: flex;
124
- align-items: center;
125
- gap: var(--nx-space-2);
126
- margin: 0;
127
- }
128
-
129
- .nx-excel__result-note {
130
- margin: 0;
131
- }
132
-
133
- .nx-excel__review {
134
- display: flex;
135
- flex-direction: column;
136
- gap: var(--nx-space-3);
137
- min-width: 0;
138
- }
139
-
140
- /* One half of the review. The hairline above it is what separates the two, instead of a box around each. */
141
- .nx-excel__section {
142
- min-width: 0;
143
- padding-top: var(--nx-space-2);
144
- border-top: 1px solid var(--nx-border);
145
- }
146
-
147
- .nx-excel__section-head {
148
- margin: 0;
149
- font-size: var(--nx-text-md);
150
- font-weight: 400;
151
- }
152
-
153
- .nx-excel__toggle {
154
- display: flex;
155
- align-items: center;
156
- gap: var(--nx-space-2);
157
- width: 100%;
158
- min-height: 32px;
159
- padding: 4px 8px 4px 6px;
160
- border: 0;
161
- border-radius: var(--nx-radius);
162
- background: none;
163
- color: var(--nx-text);
164
- font: inherit;
165
- text-align: start;
166
- cursor: pointer;
167
- transition: background-color var(--nx-duration);
168
- }
169
-
170
- .nx-excel__toggle:hover {
171
- background: var(--nx-excel-hover);
172
- }
173
-
174
- .nx-excel__toggle:focus-visible {
175
- outline: 2px solid var(--nx-primary);
176
- outline-offset: 0;
177
- }
178
-
179
- .nx-excel__chevron {
180
- flex: none;
181
- width: 16px;
182
- height: 16px;
183
- color: var(--nx-text-muted);
184
- transition: transform var(--nx-duration);
185
- }
186
-
187
- .nx-excel__toggle[aria-expanded="false"] .nx-excel__chevron {
188
- transform: rotate(-90deg);
189
- }
190
-
191
- .nx-excel__title {
192
- flex: none;
193
- font-weight: 600;
194
- white-space: nowrap;
195
- }
196
-
197
- /* The count. On a tint, so it takes the text color rather than a muted one. */
198
- .nx-excel__tag {
199
- flex: none;
200
- padding: 0 7px;
201
- border-radius: var(--nx-radius-full);
202
- background: var(--nx-excel-tint);
203
- color: var(--nx-text);
204
- font-size: var(--nx-text-xs);
205
- font-variant-numeric: tabular-nums;
206
- font-weight: 600;
207
- }
208
-
209
- /*
210
- * The hint sits on a row that tints on hover, and muted text on a tint falls under 4.5:1 in several themes (measured:
211
- * 4.23 in Catppuccin light, 4.33 in Rose Pine dark). So it moves toward the text color, as rows that tint do.
212
- */
213
- .nx-excel__hint {
214
- min-width: 0;
215
- overflow: hidden;
216
- color: color-mix(in oklab, var(--nx-text) 35%, var(--nx-text-muted));
217
- font-size: var(--nx-text-xs);
218
- text-overflow: ellipsis;
219
- white-space: nowrap;
220
- }
221
-
222
- .nx-excel__section[data-tone="warning"] .nx-excel__tag {
223
- background: var(--nx-warning-soft);
224
- }
225
-
226
- .nx-excel__section-body {
227
- display: flex;
228
- flex-direction: column;
229
- gap: var(--nx-space-3);
230
- min-width: 0;
231
- padding-top: var(--nx-space-2);
232
- }
233
-
234
- /* What the server found wrong. The place and the sentence sit on one grid, so the sentences line up. */
235
- .nx-excel__problems {
236
- padding: var(--nx-space-3);
237
- border-radius: var(--nx-radius);
238
- background: var(--nx-warning-soft);
239
- color: var(--nx-text);
240
- font-size: var(--nx-text-xs);
241
- line-height: 1.5;
242
- }
243
-
244
- .nx-excel__problems--same {
245
- background: var(--nx-excel-tint);
246
- }
247
-
248
- .nx-excel__problems--same .nx-excel__problems-head .nx-icon {
249
- color: var(--nx-text-muted);
250
- }
251
-
252
- .nx-excel__problems-head {
253
- display: flex;
254
- align-items: center;
255
- gap: var(--nx-space-2);
256
- margin: 0 0 var(--nx-space-2);
257
- font-size: var(--nx-text-sm);
258
- font-weight: 600;
259
- }
260
-
261
- .nx-excel__problems-head .nx-icon {
262
- width: 16px;
263
- height: 16px;
264
- color: var(--nx-warning);
265
- }
266
-
267
- .nx-excel__problems ul,
268
- .nx-excel__refused {
269
- display: grid;
270
- gap: var(--nx-space-1);
271
- margin: 0;
272
- padding: 0;
273
- list-style: none;
274
- }
275
-
276
- .nx-excel__problems li,
277
- .nx-excel__refused li {
278
- display: grid;
279
- grid-template-columns: minmax(6rem, max-content) 1fr;
280
- gap: var(--nx-space-1) var(--nx-space-3);
281
- }
282
-
283
- .nx-excel__refused {
284
- font-size: var(--nx-text-xs);
285
- }
286
-
287
- .nx-excel__place {
288
- font-weight: 600;
289
- font-variant-numeric: tabular-nums;
290
- }
291
-
292
- /* The place is the way to the cell it names, so it is a button - with no box, since it sits in a line of text. */
293
- .nx-excel__go {
294
- padding: 0;
295
- border: 0;
296
- border-radius: 2px;
297
- background: none;
298
- color: inherit;
299
- font: inherit;
300
- font-weight: 600;
301
- text-align: start;
302
- text-decoration: underline;
303
- text-decoration-color: color-mix(in oklab, currentcolor 40%, transparent);
304
- text-underline-offset: 2px;
305
- cursor: pointer;
306
- }
307
-
308
- .nx-excel__go:hover {
309
- text-decoration-color: currentcolor;
310
- }
311
-
312
- .nx-excel__go:focus-visible {
313
- outline: 2px solid var(--nx-primary);
314
- outline-offset: 1px;
315
- }
316
-
317
- @media (width < 36rem) {
318
- .nx-excel__problems li,
319
- .nx-excel__refused li {
320
- grid-template-columns: 1fr;
321
- }
322
-
323
- /*
324
- * The hint is the reason the section exists ("Edit a row to add it as a new record instead"), and a reason cut at
325
- * the word that explains it is no reason at all. Where the line is too short for it, it drops under the title.
326
- */
327
- .nx-excel__toggle {
328
- flex-wrap: wrap;
329
- }
330
-
331
- .nx-excel__hint {
332
- flex: 1 0 100%;
333
- overflow: visible;
334
- padding-left: 24px;
335
- white-space: normal;
336
- }
337
- }
338
-
339
- /* The sentence about what will be sent, then the buttons. */
340
- .nx-excel__actions {
341
- display: flex;
342
- flex-wrap: wrap;
343
- align-items: center;
344
- gap: var(--nx-space-2) var(--nx-space-3);
345
- padding-top: var(--nx-space-2);
346
- border-top: 1px solid var(--nx-border);
347
- }
348
-
349
- .nx-excel__sending {
350
- flex: 1 1 14rem;
351
- min-width: 0;
352
- margin: 0;
353
- color: var(--nx-text-muted);
354
- font-size: var(--nx-text-xs);
355
- }
356
-
357
- .nx-excel__buttons {
358
- display: flex;
359
- flex-wrap: wrap;
360
- gap: var(--nx-space-2);
361
- margin-left: auto;
362
- }
363
-
364
- @media (prefers-reduced-motion: reduce) {
365
- .nx-excel__toggle,
366
- .nx-excel__chevron {
367
- transition: none;
368
- }
369
- }
370
- }
1
+ @layer nexus.components {
2
+ /*
3
+ * The spreadsheet import panel: the three steps, the file row, and the review as two collapsible editors.
4
+ *
5
+ * It adds no box of its own. It is shown inside a popup or a page panel, which already has one, and the editors
6
+ * inside bring the only frame on the panel - so nothing here draws a border around something that has one. The
7
+ * sections are told apart by a tint and a hairline above them, as the group form's sections are.
8
+ */
9
+ .nx-excel {
10
+ --nx-excel-tint: color-mix(in oklab, var(--nx-text) 5%, var(--nx-surface));
11
+ --nx-excel-hover: color-mix(in oklab, var(--nx-text) 8%, var(--nx-surface));
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: var(--nx-space-4);
15
+ min-width: 0;
16
+ }
17
+
18
+ /* The three steps, numbered, as one short paragraph each. */
19
+ .nx-excel__steps {
20
+ display: flex;
21
+ flex-wrap: wrap;
22
+ gap: var(--nx-space-2) var(--nx-space-5);
23
+ margin: 0;
24
+ padding: 0;
25
+ list-style: none;
26
+ counter-reset: nx-excel-step;
27
+ color: var(--nx-text-muted);
28
+ font-size: var(--nx-text-xs);
29
+ line-height: 1.45;
30
+ }
31
+
32
+ .nx-excel__steps > li {
33
+ display: flex;
34
+ flex: 1 1 14rem;
35
+ align-items: baseline;
36
+ gap: var(--nx-space-2);
37
+ counter-increment: nx-excel-step;
38
+ }
39
+
40
+ .nx-excel__steps > li::before {
41
+ content: counter(nx-excel-step);
42
+ flex: none;
43
+ min-width: 17px;
44
+ padding: 1px 0;
45
+ border-radius: var(--nx-radius-full);
46
+ background: var(--nx-excel-tint);
47
+ color: var(--nx-text);
48
+ font-size: var(--nx-text-xs);
49
+ font-weight: 600;
50
+ text-align: center;
51
+ }
52
+
53
+ /* Template, Choose file, the file's name, and the limit: one line that wraps as whole groups. */
54
+ .nx-excel__pick {
55
+ display: flex;
56
+ flex-wrap: wrap;
57
+ align-items: center;
58
+ gap: var(--nx-space-2) var(--nx-space-3);
59
+ }
60
+
61
+ .nx-excel__file {
62
+ flex: 1 1 12rem;
63
+ min-width: 0;
64
+ margin: 0;
65
+ overflow-wrap: anywhere;
66
+ color: var(--nx-text);
67
+ font-size: var(--nx-text-sm);
68
+ }
69
+
70
+ /* The picked file's icon, on the line of its name; the line stays text, so "Checking" keeps its space. */
71
+ .nx-excel__file > .nx-icon {
72
+ width: 16px;
73
+ height: 16px;
74
+ margin-right: 6px;
75
+ color: var(--nx-text-muted);
76
+ vertical-align: -3px;
77
+ }
78
+
79
+ .nx-excel__muted {
80
+ color: var(--nx-text-muted);
81
+ }
82
+
83
+ .nx-excel__limits {
84
+ margin: 0;
85
+ color: var(--nx-text-muted);
86
+ font-size: var(--nx-text-xs);
87
+ white-space: nowrap;
88
+ }
89
+
90
+ .nx-excel__note {
91
+ margin: 0;
92
+ color: var(--nx-text);
93
+ font-size: var(--nx-text-sm);
94
+ }
95
+
96
+ /* What the new records start as: one short choice, as wide as its words need and no wider. */
97
+ .nx-excel__status {
98
+ max-width: 18rem;
99
+ }
100
+
101
+ /* A refusal, and what the import could not write: a tint, with the words in the text color so they read on it. */
102
+ .nx-excel__failure,
103
+ .nx-excel__result {
104
+ display: flex;
105
+ gap: var(--nx-space-2);
106
+ margin: 0;
107
+ padding: var(--nx-space-3);
108
+ border-radius: var(--nx-radius);
109
+ background: var(--nx-danger-soft);
110
+ color: var(--nx-text);
111
+ font-size: var(--nx-text-sm);
112
+ line-height: 1.45;
113
+ }
114
+
115
+ .nx-excel__failure .nx-icon,
116
+ .nx-excel__result .nx-icon {
117
+ flex: none;
118
+ width: 18px;
119
+ height: 18px;
120
+ color: var(--nx-danger);
121
+ }
122
+
123
+ .nx-excel__result {
124
+ flex-direction: column;
125
+ gap: var(--nx-space-1);
126
+ }
127
+
128
+ .nx-excel__result--ok {
129
+ background: var(--nx-success-soft);
130
+ }
131
+
132
+ .nx-excel__result--ok .nx-icon {
133
+ color: var(--nx-success);
134
+ }
135
+
136
+ .nx-excel__result-head {
137
+ display: flex;
138
+ align-items: center;
139
+ gap: var(--nx-space-2);
140
+ margin: 0;
141
+ }
142
+
143
+ .nx-excel__result-note {
144
+ margin: 0;
145
+ }
146
+
147
+ .nx-excel__review {
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: var(--nx-space-3);
151
+ min-width: 0;
152
+ }
153
+
154
+ /* One half of the review. The hairline above it is what separates the two, instead of a box around each. */
155
+ .nx-excel__section {
156
+ min-width: 0;
157
+ padding-top: var(--nx-space-2);
158
+ border-top: 1px solid var(--nx-border);
159
+ }
160
+
161
+ .nx-excel__section-head {
162
+ margin: 0;
163
+ font-size: var(--nx-text-md);
164
+ font-weight: 400;
165
+ }
166
+
167
+ .nx-excel__toggle {
168
+ display: flex;
169
+ align-items: center;
170
+ gap: var(--nx-space-2);
171
+ width: 100%;
172
+ min-height: 32px;
173
+ padding: 4px 8px 4px 6px;
174
+ border: 0;
175
+ border-radius: var(--nx-radius);
176
+ background: none;
177
+ color: var(--nx-text);
178
+ font: inherit;
179
+ text-align: start;
180
+ cursor: pointer;
181
+ transition: background-color var(--nx-duration);
182
+ }
183
+
184
+ .nx-excel__toggle:hover {
185
+ background: var(--nx-excel-hover);
186
+ }
187
+
188
+ .nx-excel__toggle:focus-visible {
189
+ outline: 2px solid var(--nx-primary);
190
+ outline-offset: 0;
191
+ }
192
+
193
+ .nx-excel__chevron {
194
+ flex: none;
195
+ width: 16px;
196
+ height: 16px;
197
+ color: var(--nx-text-muted);
198
+ transition: transform var(--nx-duration);
199
+ }
200
+
201
+ .nx-excel__toggle[aria-expanded="false"] .nx-excel__chevron {
202
+ transform: rotate(-90deg);
203
+ }
204
+
205
+ /* The new rows' line, which does not fold: the same line as a toggle, with nothing to press. */
206
+ .nx-excel__toggle[data-fixed] {
207
+ cursor: default;
208
+ }
209
+
210
+ .nx-excel__toggle[data-fixed]:hover {
211
+ background: none;
212
+ }
213
+
214
+ .nx-excel__title {
215
+ flex: none;
216
+ font-weight: 600;
217
+ white-space: nowrap;
218
+ }
219
+
220
+ /* The count. On a tint, so it takes the text color rather than a muted one. */
221
+ .nx-excel__tag {
222
+ flex: none;
223
+ padding: 0 7px;
224
+ border-radius: var(--nx-radius-full);
225
+ background: var(--nx-excel-tint);
226
+ color: var(--nx-text);
227
+ font-size: var(--nx-text-xs);
228
+ font-variant-numeric: tabular-nums;
229
+ font-weight: 600;
230
+ }
231
+
232
+ /*
233
+ * The hint sits on a row that tints on hover, and muted text on a tint falls under 4.5:1 in several themes (measured:
234
+ * 4.23 in Catppuccin light, 4.33 in Rose Pine dark). So it moves toward the text color, as rows that tint do.
235
+ */
236
+ .nx-excel__hint {
237
+ min-width: 0;
238
+ overflow: hidden;
239
+ color: color-mix(in oklab, var(--nx-text) 35%, var(--nx-text-muted));
240
+ font-size: var(--nx-text-xs);
241
+ text-overflow: ellipsis;
242
+ white-space: nowrap;
243
+ }
244
+
245
+ .nx-excel__section[data-tone="warning"] .nx-excel__tag {
246
+ background: var(--nx-warning-soft);
247
+ }
248
+
249
+ .nx-excel__section-body {
250
+ display: flex;
251
+ flex-direction: column;
252
+ gap: var(--nx-space-3);
253
+ min-width: 0;
254
+ padding-top: var(--nx-space-2);
255
+ }
256
+
257
+ /* What the server found wrong. The place and the sentence sit on one grid, so the sentences line up. */
258
+ .nx-excel__problems {
259
+ padding: var(--nx-space-3);
260
+ border-radius: var(--nx-radius);
261
+ background: var(--nx-warning-soft);
262
+ color: var(--nx-text);
263
+ font-size: var(--nx-text-xs);
264
+ line-height: 1.5;
265
+ }
266
+
267
+ .nx-excel__problems--same {
268
+ background: var(--nx-excel-tint);
269
+ }
270
+
271
+ .nx-excel__problems--same .nx-excel__problems-head .nx-icon {
272
+ color: var(--nx-text-muted);
273
+ }
274
+
275
+ .nx-excel__problems-head {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: var(--nx-space-2);
279
+ margin: 0 0 var(--nx-space-2);
280
+ font-size: var(--nx-text-sm);
281
+ font-weight: 600;
282
+ }
283
+
284
+ .nx-excel__problems-head .nx-icon {
285
+ width: 16px;
286
+ height: 16px;
287
+ color: var(--nx-warning);
288
+ }
289
+
290
+ .nx-excel__problems ul {
291
+ display: grid;
292
+ gap: var(--nx-space-1);
293
+ margin: 0;
294
+ padding: 0;
295
+ list-style: none;
296
+ }
297
+
298
+ .nx-excel__problems li {
299
+ display: grid;
300
+ grid-template-columns: minmax(6rem, max-content) 1fr;
301
+ gap: var(--nx-space-1) var(--nx-space-3);
302
+ }
303
+
304
+ .nx-excel__place {
305
+ font-weight: 600;
306
+ font-variant-numeric: tabular-nums;
307
+ }
308
+
309
+ /* The place is the way to the cell it names, so it is a button - with no box, since it sits in a line of text. */
310
+ .nx-excel__go {
311
+ padding: 0;
312
+ border: 0;
313
+ border-radius: 2px;
314
+ background: none;
315
+ color: inherit;
316
+ font: inherit;
317
+ font-weight: 600;
318
+ text-align: start;
319
+ text-decoration: underline;
320
+ text-decoration-color: color-mix(in oklab, currentcolor 40%, transparent);
321
+ text-underline-offset: 2px;
322
+ cursor: pointer;
323
+ }
324
+
325
+ .nx-excel__go:hover {
326
+ text-decoration-color: currentcolor;
327
+ }
328
+
329
+ .nx-excel__go:focus-visible {
330
+ outline: 2px solid var(--nx-primary);
331
+ outline-offset: 1px;
332
+ }
333
+
334
+ @media (width < 36rem) {
335
+ .nx-excel__problems li {
336
+ grid-template-columns: 1fr;
337
+ }
338
+
339
+ /*
340
+ * The hint is the reason the section exists ("Edit a row to add it as a new record instead"), and a reason cut at
341
+ * the word that explains it is no reason at all. Where the line is too short for it, it drops under the title.
342
+ */
343
+ .nx-excel__toggle {
344
+ flex-wrap: wrap;
345
+ }
346
+
347
+ .nx-excel__hint {
348
+ flex: 1 0 100%;
349
+ overflow: visible;
350
+ padding-left: 24px;
351
+ white-space: normal;
352
+ }
353
+
354
+ /* Under the title, where the title starts: a line that does not fold has no chevron to clear. */
355
+ .nx-excel__toggle[data-fixed] .nx-excel__hint {
356
+ padding-left: 0;
357
+ }
358
+ }
359
+
360
+ /* The sentence about what will be sent, then the buttons. */
361
+ .nx-excel__actions {
362
+ display: flex;
363
+ flex-wrap: wrap;
364
+ align-items: center;
365
+ gap: var(--nx-space-2) var(--nx-space-3);
366
+ padding-top: var(--nx-space-2);
367
+ border-top: 1px solid var(--nx-border);
368
+ }
369
+
370
+ .nx-excel__sending {
371
+ flex: 1 1 14rem;
372
+ min-width: 0;
373
+ margin: 0;
374
+ color: var(--nx-text-muted);
375
+ font-size: var(--nx-text-xs);
376
+ }
377
+
378
+ .nx-excel__buttons {
379
+ display: flex;
380
+ flex-wrap: wrap;
381
+ gap: var(--nx-space-2);
382
+ margin-left: auto;
383
+ }
384
+
385
+ [data-nx-motion="reduce"] .nx-excel__toggle,
386
+ [data-nx-motion="reduce"] .nx-excel__chevron {
387
+ transition: none;
388
+ }
389
+ }