@visns-studio/visns-components 6.17.2 → 6.20.1

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 (83) hide show
  1. package/package.json +10 -7
  2. package/src/components/AssociationManager.jsx +344 -177
  3. package/src/components/AsyncSelect.jsx +2 -2
  4. package/src/components/Autocomplete.jsx +57 -12
  5. package/src/components/Breadcrumb.jsx +23 -4
  6. package/src/components/ClientAssociationManager.jsx +321 -145
  7. package/src/components/DataGrid.jsx +625 -20
  8. package/src/components/DropZone.jsx +4 -1
  9. package/src/components/Form.jsx +233 -6
  10. package/src/components/MultiSelect.jsx +2 -2
  11. package/src/components/Navigation.jsx +39 -23
  12. package/src/components/TableFilter.jsx +172 -12
  13. package/src/components/UniversalSearch.jsx +390 -0
  14. package/src/components/auth/Login.jsx +164 -8
  15. package/src/components/auth/Profile.jsx +209 -22
  16. package/src/components/auth/authEndpoints.js +4 -0
  17. package/src/components/auth/webauthn.js +194 -0
  18. package/src/components/columns/ColumnRenderers.jsx +6 -1
  19. package/src/components/controls/DataGridSearch.jsx +11 -5
  20. package/src/components/generic/GenericAuth.jsx +6 -0
  21. package/src/components/generic/GenericDashboard.jsx +93 -36
  22. package/src/components/generic/GenericDetail.jsx +146 -61
  23. package/src/components/generic/GenericIndex.jsx +142 -38
  24. package/src/components/generic/GenericSettings.jsx +220 -0
  25. package/src/components/generic/StandardModal.jsx +165 -8
  26. package/src/components/generic/dashboardChartDefaults.js +230 -0
  27. package/src/components/generic/shared/indexLayout.js +38 -0
  28. package/src/components/settings/IntegrationsManager.jsx +474 -0
  29. package/src/components/sms/SmsLineSettings.jsx +16 -12
  30. package/src/components/styles/AssociationManager.module.scss +4 -363
  31. package/src/components/styles/AuditLog.module.scss +6 -6
  32. package/src/components/styles/AuditLogs.module.scss +3 -3
  33. package/src/components/styles/Autocomplete.module.scss +7 -7
  34. package/src/components/styles/BusinessCardOcr.module.scss +6 -1
  35. package/src/components/styles/CallQueueSettings.module.scss +4 -1
  36. package/src/components/styles/CameraPlacement.module.scss +19 -19
  37. package/src/components/styles/CategorizedDropZone.module.scss +6 -1
  38. package/src/components/styles/ClientAssociationManager.module.scss +5 -289
  39. package/src/components/styles/ClientAuth.module.scss +1 -1
  40. package/src/components/styles/DataGrid.module.scss +455 -8
  41. package/src/components/styles/Field.module.scss +32 -24
  42. package/src/components/styles/Form.module.scss +123 -3
  43. package/src/components/styles/GenericDashboard.module.scss +612 -825
  44. package/src/components/styles/GenericDetail.module.scss +406 -61
  45. package/src/components/styles/GenericDynamic.module.scss +25 -25
  46. package/src/components/styles/GenericEditableTable.module.scss +33 -33
  47. package/src/components/styles/GenericFormBuilder.module.scss +119 -119
  48. package/src/components/styles/GenericIndex.module.scss +483 -38
  49. package/src/components/styles/GenericMain.module.scss +6 -3
  50. package/src/components/styles/GenericQuote.module.scss +399 -81
  51. package/src/components/styles/GenericReport.module.scss +8 -8
  52. package/src/components/styles/GenericSettings.module.scss +209 -0
  53. package/src/components/styles/GenericSort.module.scss +9 -9
  54. package/src/components/styles/Integrations.module.scss +321 -0
  55. package/src/components/styles/List.module.scss +4 -4
  56. package/src/components/styles/Login.module.scss +57 -0
  57. package/src/components/styles/MultiSelect.module.scss +4 -4
  58. package/src/components/styles/Navigation.module.scss +12 -12
  59. package/src/components/styles/Notification.module.scss +12 -8
  60. package/src/components/styles/NotificationList.module.scss +5 -5
  61. package/src/components/styles/Profile.module.scss +5 -5
  62. package/src/components/styles/QrCode.module.scss +4 -4
  63. package/src/components/styles/QuickAction.module.scss +20 -20
  64. package/src/components/styles/SortableQuoteItems.module.scss +4 -4
  65. package/src/components/styles/TableFilter.module.scss +128 -17
  66. package/src/components/styles/TicketConversation.module.scss +497 -0
  67. package/src/components/styles/UniversalSearch.module.scss +229 -0
  68. package/src/components/styles/Vault.module.scss +413 -0
  69. package/src/components/styles/_associationManager.scss +467 -0
  70. package/src/components/styles/_authBrandPanel.scss +15 -9
  71. package/src/components/styles/_controls.scss +43 -39
  72. package/src/components/styles/global-datagrid.css +196 -0
  73. package/src/components/styles/global.css +168 -17
  74. package/src/components/tickets/TicketConversation.jsx +455 -0
  75. package/src/components/utils/rowActionSettings.js +117 -0
  76. package/src/components/vault/VaultClientPicker.jsx +183 -0
  77. package/src/components/vault/VaultEntryForm.jsx +23 -0
  78. package/src/components/vault/VaultManager.jsx +382 -34
  79. package/src/components/vault/VaultShareModal.jsx +454 -0
  80. package/src/components/vault/vaultEndpoints.js +16 -2
  81. package/src/components/vault/vaultShares.js +247 -0
  82. package/src/index.js +35 -0
  83. package/src/utils/fetchUtil.js +38 -14
@@ -1,364 +1,5 @@
1
- .container {
2
- padding: 20px;
3
- background: var(--bg-color);
4
- border-radius: var(--radius);
5
- box-shadow: var(--box-shadow-small);
6
- }
1
+ // The whole definition lives in `_associationManager.scss` and is shared with
2
+ // ClientAssociationManager.module.scss — see the note at the top of that file.
3
+ @use 'associationManager' as *;
7
4
 
8
- .header {
9
- margin-bottom: 30px;
10
- border-bottom: 1px solid rgba(var(--paragraph-rgb), 0.15);
11
- padding-bottom: 15px;
12
-
13
- h3 {
14
- margin: 0 0 5px 0;
15
- color: var(--primary-color);
16
- font-size: 1.4em;
17
- font-weight: 600;
18
- }
19
-
20
- p {
21
- margin: 0;
22
- color: var(--paragraph-color);
23
- font-size: 0.9em;
24
- opacity: 0.8;
25
- }
26
- }
27
-
28
- .loading {
29
- text-align: center;
30
- padding: 40px;
31
- color: var(--paragraph-color);
32
- opacity: 0.7;
33
- }
34
-
35
- /* Multiple Primary Warning */
36
- .multiplePrimaryWarning {
37
- display: flex;
38
- align-items: flex-start;
39
- gap: 12px;
40
- padding: 16px;
41
- margin-bottom: 24px;
42
- background: rgba(255, 193, 7, 0.1);
43
- border: 1px solid rgba(255, 193, 7, 0.3);
44
- border-left: 4px solid rgba(255, 193, 7, 1);
45
- border-radius: var(--radius);
46
- color: #856404;
47
-
48
- .warningContent {
49
- flex: 1;
50
-
51
- strong {
52
- display: block;
53
- margin-bottom: 4px;
54
- font-size: 0.95em;
55
- }
56
-
57
- p {
58
- margin: 0 0 12px 0;
59
- font-size: 0.85em;
60
- line-height: 1.4;
61
- opacity: 0.9;
62
- }
63
- }
64
- }
65
-
66
- .clearAllPrimaryBtn {
67
- padding: 6px 12px;
68
- background: rgba(255, 193, 7, 1);
69
- color: #fff;
70
- border: none;
71
- border-radius: var(--radius);
72
- font-size: 0.8em;
73
- font-weight: 500;
74
- cursor: pointer;
75
- transition: all 0.2s ease;
76
-
77
- &:hover {
78
- background: rgba(255, 173, 7, 1);
79
- transform: translateY(-1px);
80
- }
81
- }
82
-
83
- /* Existing Associations */
84
- .existingAssociations {
85
- margin-bottom: 40px;
86
-
87
- h4 {
88
- margin: 0 0 15px 0;
89
- color: var(--secondary-color);
90
- font-size: 1.1em;
91
- font-weight: 500;
92
- }
93
- }
94
-
95
- .noAssociations {
96
- padding: 20px;
97
- text-align: center;
98
- color: var(--paragraph-color);
99
- background: rgba(var(--paragraph-rgb), 0.05);
100
- border-radius: var(--radius);
101
- font-style: italic;
102
- opacity: 0.8;
103
- }
104
-
105
- .associationsList {
106
- display: flex;
107
- flex-direction: column;
108
- gap: 12px;
109
- }
110
-
111
- .associationItem {
112
- display: flex;
113
- justify-content: space-between;
114
- align-items: center;
115
- padding: 15px;
116
- border: 1px solid rgba(var(--paragraph-rgb), 0.15);
117
- border-radius: var(--radius);
118
- background: var(--tertiary-color);
119
- transition: all 0.2s ease;
120
-
121
- &:hover {
122
- background: rgba(var(--paragraph-rgb), 0.05);
123
- border-color: rgba(var(--paragraph-rgb), 0.25);
124
- }
125
-
126
- &.primary {
127
- border-color: var(--primary-color);
128
- background: rgba(var(--primary-rgb), 0.1);
129
-
130
- &:hover {
131
- background: rgba(var(--primary-rgb), 0.15);
132
- }
133
- }
134
- }
135
-
136
- .associationInfo {
137
- flex: 1;
138
-
139
- .entityName {
140
- font-weight: 600;
141
- color: var(--secondary-color);
142
- margin-bottom: 4px;
143
- display: flex;
144
- align-items: center;
145
- gap: 8px;
146
- }
147
-
148
- .primaryBadge {
149
- background: var(--primary-color);
150
- color: var(--bg-color);
151
- padding: 2px 6px;
152
- border-radius: var(--radius);
153
- font-size: 0.75em;
154
- font-weight: 500;
155
- text-transform: uppercase;
156
- }
157
-
158
- .relationshipInfo {
159
- margin-bottom: 4px;
160
-
161
- .relationshipType {
162
- color: var(--paragraph-color);
163
- font-weight: 500;
164
- text-transform: capitalize;
165
- }
166
-
167
- .notes {
168
- color: var(--paragraph-color);
169
- font-size: 0.9em;
170
- opacity: 0.7;
171
- }
172
- }
173
-
174
- .associatedAt {
175
- color: var(--paragraph-color);
176
- font-size: 0.8em;
177
- opacity: 0.6;
178
- }
179
- }
180
-
181
- .associationActions {
182
- display: flex;
183
- gap: 8px;
184
- align-items: center;
185
- }
186
-
187
- .setPrimaryBtn,
188
- .removePrimaryBtn,
189
- .removeBtn,
190
- .associateBtn {
191
- padding: 6px 12px;
192
- border: none;
193
- border-radius: var(--radius);
194
- font-size: 0.85em;
195
- cursor: pointer;
196
- transition: all 0.2s ease;
197
- font-weight: 500;
198
-
199
- &:disabled {
200
- opacity: 0.6;
201
- cursor: not-allowed;
202
- }
203
- }
204
-
205
- .setPrimaryBtn {
206
- background: var(--highlight-color);
207
- color: #ffffff;
208
-
209
- &:hover:not(:disabled) {
210
- background: #0056b3;
211
- color: #ffffff;
212
- transform: translateY(-1px);
213
- }
214
- }
215
-
216
- .removePrimaryBtn {
217
- background: rgba(108, 117, 125, 1);
218
- color: var(--bg-color);
219
-
220
- &:hover:not(:disabled) {
221
- background: rgba(90, 98, 104, 1);
222
- transform: translateY(-1px);
223
- }
224
- }
225
-
226
- .removeBtn {
227
- background: rgba(220, 53, 69, 1);
228
- color: var(--bg-color);
229
-
230
- &:hover:not(:disabled) {
231
- background: rgba(200, 35, 51, 1);
232
- transform: translateY(-1px);
233
- }
234
- }
235
-
236
- .associateBtn {
237
- background: var(--primary-color);
238
- color: var(--bg-color);
239
- padding: 10px 20px;
240
- font-size: 0.9em;
241
-
242
- &:hover:not(:disabled) {
243
- background: rgba(var(--primary-rgb), 0.9);
244
- transform: translateY(-1px);
245
- }
246
- }
247
-
248
- /* New Association Form */
249
- .newAssociation {
250
- border-top: 1px solid rgba(var(--paragraph-rgb), 0.15);
251
- padding-top: 30px;
252
-
253
- h4 {
254
- margin: 0 0 20px 0;
255
- color: var(--secondary-color);
256
- font-size: 1.1em;
257
- font-weight: 500;
258
- }
259
- }
260
-
261
- .associationForm {
262
- background: rgba(var(--paragraph-rgb), 0.05);
263
- padding: 20px;
264
- border-radius: var(--radius);
265
- border: 1px solid rgba(var(--paragraph-rgb), 0.1);
266
- }
267
-
268
- .formRow {
269
- display: flex;
270
- gap: 20px;
271
- margin-bottom: 20px;
272
-
273
- &:last-child {
274
- margin-bottom: 0;
275
- }
276
-
277
- @media (max-width: 768px) {
278
- flex-direction: column;
279
- gap: 15px;
280
- }
281
- }
282
-
283
- .formField {
284
- flex: 1;
285
-
286
- label {
287
- display: block;
288
- margin-bottom: 5px;
289
- color: var(--secondary-color);
290
- font-weight: 500;
291
- font-size: 0.9em;
292
-
293
- input[type="checkbox"] {
294
- margin-right: 8px;
295
- }
296
- }
297
- }
298
-
299
- .selectField,
300
- .textField {
301
- width: 100%;
302
- padding: 8px 12px;
303
- border: 1px solid rgba(var(--paragraph-rgb), 0.25);
304
- border-radius: var(--radius);
305
- background: var(--bg-color);
306
- font-size: 0.9em;
307
- color: var(--paragraph-color);
308
- transition: all 0.2s ease;
309
-
310
- &:focus {
311
- outline: none;
312
- border-color: var(--primary-color);
313
- box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.25);
314
- }
315
- }
316
-
317
- .textareaField {
318
- width: 100%;
319
- padding: 8px 12px;
320
- border: 1px solid rgba(var(--paragraph-rgb), 0.25);
321
- border-radius: var(--radius);
322
- background: var(--bg-color);
323
- font-size: 0.9em;
324
- color: var(--paragraph-color);
325
- resize: vertical;
326
- min-height: 60px;
327
- transition: all 0.2s ease;
328
-
329
- &:focus {
330
- outline: none;
331
- border-color: var(--primary-color);
332
- box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.25);
333
- }
334
- }
335
-
336
- .formActions {
337
- margin-top: 20px;
338
- text-align: right;
339
- }
340
-
341
- /* Responsive Design */
342
- @media (max-width: 768px) {
343
- .container {
344
- padding: 15px;
345
- }
346
-
347
- .associationItem {
348
- flex-direction: column;
349
- align-items: flex-start;
350
- gap: 15px;
351
- }
352
-
353
- .associationActions {
354
- align-self: flex-end;
355
- }
356
-
357
- .formActions {
358
- text-align: center;
359
- }
360
-
361
- .associateBtn {
362
- width: 100%;
363
- }
364
- }
5
+ @include association-manager;
@@ -28,19 +28,19 @@
28
28
  width: 100%;
29
29
  background: var(--item-color);
30
30
  border-radius: var(--br);
31
- border: 1px solid rgba(var(--item-color-rgb), 1.15);
31
+ border: 1px solid rgba(var(--item-color-rgb, 255, 255, 255), 1);
32
32
  box-sizing: border-box;
33
33
  overflow: visible;
34
34
  position: relative;
35
35
  padding: 2px;
36
36
  margin: 8px 0;
37
- box-shadow: 0 10px 50px rgba(var(--primary-rgb), 0.05);
37
+ box-shadow: 0 10px 50px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
38
38
  }
39
39
 
40
40
  .gridtxt__header {
41
41
  width: 100%;
42
42
  display: block;
43
- background: rgba(var(--item-color-rgb), 1.05);
43
+ background: rgba(var(--item-color-rgb, 255, 255, 255), 1);
44
44
  box-sizing: border-box;
45
45
  padding: 10px 20px;
46
46
  border-radius: 0;
@@ -70,9 +70,9 @@
70
70
  flex: 0 0 calc(50% - 10px);
71
71
  padding: 0.85rem;
72
72
  box-sizing: border-box;
73
- border: 1px solid rgba(var(--primary-rgb), 0.15);
73
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
74
74
  color: var(--paragraph-color);
75
- background: rgba(var(--tertiary-color-rgb), 0.95);
75
+ background: rgba(var(--tertiary-color-rgb, 255, 255, 255), 0.95);
76
76
  margin: 5px;
77
77
  border-radius: var(--br);
78
78
  line-height: 1.45;
@@ -101,7 +101,7 @@
101
101
  width: 49%;
102
102
  padding: 1em;
103
103
  box-sizing: border-box;
104
- border: 1px solid rgba(var(--primary-rgb), 0.15);
104
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
105
105
  color: var(--paragraph-color);
106
106
  background: rgba(#f4f4f4, 0.65);
107
107
  margin: 5px;
@@ -20,13 +20,13 @@
20
20
  width: 100%;
21
21
  background: var(--item-color);
22
22
  border-radius: var(--br);
23
- border: 1px solid rgba(var(--item-color-rgb), 1.15);
23
+ border: 1px solid rgba(var(--item-color-rgb, 255, 255, 255), 1);
24
24
  box-sizing: border-box;
25
25
  overflow: visible;
26
26
  position: relative;
27
27
  padding: 2px;
28
28
  margin: 8px 0;
29
- box-shadow: 0 10px 50px rgba(var(--primary-rgb), 0.05);
29
+ box-shadow: 0 10px 50px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
30
30
  }
31
31
 
32
32
  .titleInfo {
@@ -37,5 +37,5 @@
37
37
 
38
38
  .titleInfo span {
39
39
  font-size: 0.875em;
40
- color: rgba(var(--paragraph-color-rgb), 0.65);
40
+ color: rgba(var(--paragraph-color-rgb, 43, 43, 43), 0.65);
41
41
  }
@@ -33,14 +33,14 @@
33
33
  padding: 0.65rem 3rem 0.65rem 2.25rem !important;
34
34
  height: 38px;
35
35
  width: 100%;
36
- border: 1px solid rgba(var(--primary-rgb), 0.2);
36
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.2);
37
37
  border-radius: 4px;
38
38
  outline: none;
39
39
  font-size: 0.9rem;
40
40
 
41
41
  &:focus {
42
- border-color: rgba(var(--primary-rgb), 0.5);
43
- box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.1);
42
+ border-color: rgba(var(--primary-rgb, 27, 57, 51), 0.5);
43
+ box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 27, 57, 51), 0.1);
44
44
  }
45
45
  }
46
46
 
@@ -53,7 +53,7 @@
53
53
  margin: 0;
54
54
  padding: 0;
55
55
  background-color: #fff;
56
- border: 1px solid rgba(var(--primary-rgb), 0.2);
56
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.2);
57
57
  border-radius: 4px;
58
58
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
59
59
  max-height: 250px;
@@ -65,7 +65,7 @@
65
65
 
66
66
  .AutocompletePlace-items {
67
67
  list-style: none;
68
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
68
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
69
69
  cursor: pointer;
70
70
  padding: 8px 12px;
71
71
  font-size: 0.9rem;
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  &:hover {
78
- background-color: rgba(var(--primary-rgb), 0.05);
78
+ background-color: rgba(var(--primary-rgb, 27, 57, 51), 0.05);
79
79
  }
80
80
  }
81
81
 
@@ -97,7 +97,7 @@
97
97
 
98
98
  .AutocompletePlace-itemSecondary {
99
99
  font-size: 0.8rem;
100
- color: rgba(var(--paragraph-rgb), 0.7);
100
+ color: rgba(var(--paragraph-rgb, 43, 43, 43), 0.7);
101
101
  white-space: nowrap;
102
102
  overflow: hidden;
103
103
  text-overflow: ellipsis;
@@ -1020,7 +1020,12 @@
1020
1020
  }
1021
1021
 
1022
1022
  // Dark mode support (if project supports it)
1023
- @media (prefers-color-scheme: dark) {
1023
+ // The app ships a single light theme. These dark overrides used to fire
1024
+ // straight off the OS setting, which left the app half-dark at night: only 4
1025
+ // of 72 stylesheets carry dark rules, so dark surfaces ended up wearing
1026
+ // light-theme text. They now apply only when `data-theme="dark"` is opted
1027
+ // into explicitly, so the work survives for a real theme toggle later.
1028
+ :root[data-theme='dark'] {
1024
1029
  .captureGuide {
1025
1030
  background: rgba(255, 255, 255, 0.1);
1026
1031
  color: white;
@@ -31,8 +31,11 @@ $cqsettings-mono: 'SFMono-Regular', 'Menlo', 'Consolas', monospace;
31
31
 
32
32
  // Full-width layout: the queue-name column absorbs the slack so the
33
33
  // control cluster keeps its size and sits at the row's end.
34
+ // Vertical padding only: horizontal gutters belong to whatever page hosts
35
+ // this (the settings shell aligns panel bodies flush with the panel
36
+ // header, and this element sits too deep for the shell to flatten).
34
37
  width: 100%;
35
- padding: 1rem 1.5rem 2rem;
38
+ padding: 1rem 0 2rem;
36
39
 
37
40
  // The CRM relied on a global `spin` keyframe from main.scss; this library
38
41
  // has none, so the animation is defined at the bottom of this module and
@@ -15,7 +15,7 @@
15
15
  background: var(--primary-color);
16
16
  padding: 16px 32px;
17
17
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
18
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.7);
18
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.7);
19
19
  z-index: 100;
20
20
  position: relative;
21
21
  min-width: 1060px;
@@ -298,17 +298,17 @@
298
298
 
299
299
 
300
300
  &.dragOver {
301
- background: rgba(var(--primary-rgb), 0.05);
302
- border: 2px dashed rgba(var(--primary-rgb), 0.3);
301
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.05);
302
+ border: 2px dashed rgba(var(--primary-rgb, 27, 57, 51), 0.3);
303
303
 
304
304
  .uploadPlaceholder {
305
- background: rgba(var(--primary-rgb), 0.1);
305
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.1);
306
306
  transform: scale(1.02);
307
307
  transition: all 0.2s ease;
308
308
 
309
309
  .dragDropHint {
310
- background: rgba(var(--primary-rgb), 0.2);
311
- border-color: rgba(var(--primary-rgb), 0.5);
310
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.2);
311
+ border-color: rgba(var(--primary-rgb, 27, 57, 51), 0.5);
312
312
  }
313
313
  }
314
314
  }
@@ -374,18 +374,18 @@
374
374
  transition: all 0.2s ease;
375
375
 
376
376
  &:hover {
377
- background: rgba(var(--primary-rgb), 0.8);
377
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.8);
378
378
  transform: translateY(-1px);
379
- box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.3);
379
+ box-shadow: 0 4px 12px rgba(var(--primary-rgb, 27, 57, 51), 0.3);
380
380
  }
381
381
  }
382
382
 
383
383
  .dragDropHint {
384
384
  margin-top: 20px;
385
385
  padding: 12px 20px;
386
- background: rgba(var(--primary-rgb), 0.1);
386
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.1);
387
387
  border-radius: var(--br, 8px);
388
- border: 1px dashed rgba(var(--primary-rgb), 0.3);
388
+ border: 1px dashed rgba(var(--primary-rgb, 27, 57, 51), 0.3);
389
389
  display: flex;
390
390
  align-items: center;
391
391
  gap: 8px;
@@ -881,12 +881,12 @@
881
881
  opacity: 1;
882
882
  cursor: grab;
883
883
  transform: scale(1.25);
884
- background: rgba(var(--primary-rgb), 0.8);
885
- box-shadow: 0 3px 10px rgba(var(--primary-rgb), 0.6);
884
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.8);
885
+ box-shadow: 0 3px 10px rgba(var(--primary-rgb, 27, 57, 51), 0.6);
886
886
  }
887
887
 
888
888
  &:active {
889
- background: rgba(var(--primary-rgb), 0.7);
889
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.7);
890
890
  transform: scale(1.1);
891
891
  }
892
892
 
@@ -916,8 +916,8 @@
916
916
  &:hover .rotationHandle {
917
917
  opacity: 1;
918
918
  transform: scale(1.15);
919
- background: rgba(var(--primary-rgb), 0.8);
920
- box-shadow: 0 4px 16px rgba(var(--primary-rgb), 0.5);
919
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.8);
920
+ box-shadow: 0 4px 16px rgba(var(--primary-rgb, 27, 57, 51), 0.5);
921
921
  }
922
922
 
923
923
  &.rotating {
@@ -929,8 +929,8 @@
929
929
  .rotationHandle {
930
930
  opacity: 1 !important;
931
931
  transform: scale(1.3) !important;
932
- background: rgba(var(--primary-rgb), 0.9) !important;
933
- box-shadow: 0 8px 24px rgba(var(--primary-rgb), 0.6) !important;
932
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.9) !important;
933
+ box-shadow: 0 8px 24px rgba(var(--primary-rgb, 27, 57, 51), 0.6) !important;
934
934
  cursor: grabbing !important;
935
935
  z-index: 1002 !important;
936
936
  }
@@ -1097,7 +1097,7 @@
1097
1097
  &:focus {
1098
1098
  outline: none;
1099
1099
  border-color: var(--primary-color);
1100
- box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1);
1100
+ box-shadow: 0 0 0 3px rgba(var(--primary-rgb, 27, 57, 51), 0.1);
1101
1101
  }
1102
1102
  }
1103
1103
 
@@ -1152,7 +1152,7 @@
1152
1152
  color: white;
1153
1153
 
1154
1154
  &:hover {
1155
- background: rgba(var(--primary-rgb), 0.8);
1155
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.8);
1156
1156
  }
1157
1157
  }
1158
1158
 
@@ -169,7 +169,12 @@
169
169
  }
170
170
 
171
171
  // Dark theme support
172
- @media (prefers-color-scheme: dark) {
172
+ // The app ships a single light theme. These dark overrides used to fire
173
+ // straight off the OS setting, which left the app half-dark at night: only 4
174
+ // of 72 stylesheets carry dark rules, so dark surfaces ended up wearing
175
+ // light-theme text. They now apply only when `data-theme="dark"` is opted
176
+ // into explicitly, so the work survives for a real theme toggle later.
177
+ :root[data-theme='dark'] {
173
178
  .categoryTabs {
174
179
  background-color: #343a40;
175
180
  border-color: #495057;