@striae-org/striae 4.0.3 → 4.2.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 (118) hide show
  1. package/.env.example +8 -0
  2. package/app/components/actions/case-export/core-export.ts +14 -8
  3. package/app/components/actions/case-export/data-processing.ts +1 -0
  4. package/app/components/actions/case-export/download-handlers.ts +7 -0
  5. package/app/components/actions/case-export/metadata-helpers.ts +2 -1
  6. package/app/components/actions/case-import/confirmation-import.ts +12 -2
  7. package/app/components/actions/case-import/orchestrator.ts +78 -32
  8. package/app/components/actions/case-import/storage-operations.ts +97 -8
  9. package/app/components/actions/case-import/zip-processing.ts +159 -86
  10. package/app/components/actions/case-manage.ts +430 -8
  11. package/app/components/actions/confirm-export.ts +13 -4
  12. package/app/components/actions/generate-pdf.ts +10 -2
  13. package/app/components/actions/image-manage.ts +77 -44
  14. package/app/components/audit/user-audit-viewer.tsx +137 -945
  15. package/app/components/audit/user-audit.module.css +41 -0
  16. package/app/components/audit/viewer/audit-activity-summary.tsx +52 -0
  17. package/app/components/audit/viewer/audit-entries-list.tsx +207 -0
  18. package/app/components/audit/viewer/audit-filters-panel.tsx +307 -0
  19. package/app/components/audit/viewer/audit-user-info-card.tsx +44 -0
  20. package/app/components/audit/viewer/audit-viewer-header.tsx +55 -0
  21. package/app/components/audit/viewer/audit-viewer-utils.ts +123 -0
  22. package/app/components/audit/viewer/types.ts +1 -0
  23. package/app/components/audit/viewer/use-audit-viewer-data.ts +186 -0
  24. package/app/components/audit/viewer/use-audit-viewer-export.ts +176 -0
  25. package/app/components/audit/viewer/use-audit-viewer-filters.ts +141 -0
  26. package/app/components/auth/mfa-enrollment.module.css +13 -5
  27. package/app/components/auth/mfa-verification.module.css +13 -5
  28. package/app/components/canvas/box-annotations/box-annotations.module.css +22 -18
  29. package/app/components/canvas/box-annotations/box-annotations.tsx +15 -0
  30. package/app/components/canvas/canvas.module.css +64 -54
  31. package/app/components/canvas/canvas.tsx +17 -16
  32. package/app/components/canvas/confirmation/confirmation.module.css +1 -0
  33. package/app/components/canvas/confirmation/confirmation.tsx +17 -47
  34. package/app/components/navbar/case-modals/archive-case-modal.module.css +110 -0
  35. package/app/components/navbar/case-modals/archive-case-modal.tsx +129 -0
  36. package/app/components/navbar/case-modals/open-case-modal.module.css +81 -0
  37. package/app/components/navbar/case-modals/open-case-modal.tsx +120 -0
  38. package/app/components/navbar/case-modals/rename-case-modal.module.css +81 -0
  39. package/app/components/navbar/case-modals/rename-case-modal.tsx +107 -0
  40. package/app/components/navbar/navbar.module.css +447 -0
  41. package/app/components/navbar/navbar.tsx +377 -0
  42. package/app/components/public-signing-key-modal/public-signing-key-modal.module.css +2 -0
  43. package/app/components/public-signing-key-modal/public-signing-key-modal.tsx +21 -51
  44. package/app/components/sidebar/case-export/case-export.module.css +1 -0
  45. package/app/components/sidebar/case-export/case-export.tsx +14 -77
  46. package/app/components/sidebar/case-import/case-import.module.css +25 -0
  47. package/app/components/sidebar/case-import/case-import.tsx +64 -40
  48. package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +20 -1
  49. package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +15 -0
  50. package/app/components/sidebar/cases/case-sidebar.tsx +25 -519
  51. package/app/components/sidebar/cases/cases-modal.module.css +45 -9
  52. package/app/components/sidebar/cases/cases-modal.tsx +16 -16
  53. package/app/components/sidebar/cases/cases.module.css +62 -21
  54. package/app/components/sidebar/files/files-modal.module.css +46 -10
  55. package/app/components/sidebar/files/files-modal.tsx +22 -23
  56. package/app/components/sidebar/notes/notes-editor-modal.module.css +49 -0
  57. package/app/components/sidebar/notes/notes-editor-modal.tsx +66 -0
  58. package/app/components/sidebar/notes/notes-modal.tsx +18 -17
  59. package/app/components/sidebar/notes/notes-sidebar.tsx +199 -113
  60. package/app/components/sidebar/notes/notes.module.css +155 -0
  61. package/app/components/sidebar/sidebar-container.tsx +15 -28
  62. package/app/components/sidebar/sidebar.module.css +7 -71
  63. package/app/components/sidebar/sidebar.tsx +24 -125
  64. package/app/components/sidebar/upload/image-upload-zone.module.css +13 -13
  65. package/app/components/toast/toast.module.css +2 -1
  66. package/app/components/toast/toast.tsx +16 -11
  67. package/app/components/user/delete-account.tsx +10 -31
  68. package/app/components/user/inactivity-warning.module.css +9 -6
  69. package/app/components/user/inactivity-warning.tsx +15 -2
  70. package/app/components/user/manage-profile.module.css +2 -0
  71. package/app/components/user/manage-profile.tsx +108 -40
  72. package/app/hooks/useOverlayDismiss.ts +116 -0
  73. package/app/routes/auth/login.example.tsx +19 -8
  74. package/app/routes/auth/login.tsx +785 -774
  75. package/app/routes/auth/passwordReset.module.css +23 -13
  76. package/app/routes/striae/striae.module.css +10 -3
  77. package/app/routes/striae/striae.tsx +477 -31
  78. package/app/routes.ts +7 -0
  79. package/app/services/audit/audit-export-csv.ts +2 -0
  80. package/app/services/audit/audit.service.ts +202 -32
  81. package/app/services/audit/builders/audit-entry-builder.ts +2 -1
  82. package/app/services/audit/builders/audit-event-builders-case-file.ts +43 -0
  83. package/app/services/audit/builders/audit-event-builders-user-security.ts +4 -2
  84. package/app/services/audit/builders/audit-event-builders-workflow.ts +8 -0
  85. package/app/services/audit/builders/index.ts +1 -0
  86. package/app/types/audit.ts +5 -2
  87. package/app/types/case.ts +29 -0
  88. package/app/types/import.ts +3 -0
  89. package/app/types/user.ts +1 -0
  90. package/app/utils/data/permissions.ts +17 -1
  91. package/app/utils/forensics/audit-export-signature.ts +5 -1
  92. package/app/utils/forensics/confirmation-signature.ts +3 -0
  93. package/app/utils/forensics/export-verification.ts +497 -22
  94. package/functions/api/pdf/[[path]].ts +32 -1
  95. package/load-context.ts +9 -0
  96. package/package.json +6 -2
  97. package/primershear.emails.example +6 -0
  98. package/scripts/deploy-pages-secrets.sh +6 -0
  99. package/scripts/deploy-primershear-emails.sh +167 -0
  100. package/worker-configuration.d.ts +7493 -7491
  101. package/workers/audit-worker/worker-configuration.d.ts +7448 -11323
  102. package/workers/audit-worker/wrangler.jsonc.example +1 -1
  103. package/workers/data-worker/worker-configuration.d.ts +7448 -11323
  104. package/workers/data-worker/wrangler.jsonc.example +1 -1
  105. package/workers/image-worker/worker-configuration.d.ts +7447 -11322
  106. package/workers/image-worker/wrangler.jsonc.example +1 -1
  107. package/workers/keys-worker/worker-configuration.d.ts +7447 -11322
  108. package/workers/keys-worker/wrangler.jsonc.example +1 -1
  109. package/workers/pdf-worker/src/formats/format-striae.ts +8 -7
  110. package/workers/pdf-worker/src/pdf-worker.example.ts +3 -0
  111. package/workers/pdf-worker/src/report-types.ts +3 -0
  112. package/workers/pdf-worker/worker-configuration.d.ts +7448 -11323
  113. package/workers/pdf-worker/wrangler.jsonc.example +1 -1
  114. package/workers/user-worker/src/user-worker.example.ts +6 -1
  115. package/workers/user-worker/worker-configuration.d.ts +7448 -11323
  116. package/workers/user-worker/wrangler.jsonc.example +1 -1
  117. package/wrangler.toml.example +1 -1
  118. package/public/.well-known/keybase.txt +0 -56
@@ -0,0 +1,107 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { useOverlayDismiss } from '~/hooks/useOverlayDismiss';
3
+ import styles from './rename-case-modal.module.css';
4
+
5
+ interface RenameCaseModalProps {
6
+ isOpen: boolean;
7
+ currentCase: string;
8
+ isSubmitting?: boolean;
9
+ onClose: () => void;
10
+ onSubmit: (newCaseName: string) => Promise<void>;
11
+ }
12
+
13
+ export const RenameCaseModal = ({
14
+ isOpen,
15
+ currentCase,
16
+ isSubmitting = false,
17
+ onClose,
18
+ onSubmit,
19
+ }: RenameCaseModalProps) => {
20
+ const [newCaseName, setNewCaseName] = useState('');
21
+ const inputRef = useRef<HTMLInputElement>(null);
22
+ const isCloseBlocked = isSubmitting;
23
+
24
+ const handleClose = () => {
25
+ setNewCaseName('');
26
+ onClose();
27
+ };
28
+
29
+ const {
30
+ requestClose,
31
+ overlayProps,
32
+ getCloseButtonProps,
33
+ } = useOverlayDismiss({
34
+ isOpen,
35
+ onClose: handleClose,
36
+ canDismiss: !isCloseBlocked,
37
+ });
38
+
39
+ useEffect(() => {
40
+ if (!isOpen) {
41
+ return;
42
+ }
43
+
44
+ const focusId = window.requestAnimationFrame(() => {
45
+ inputRef.current?.focus();
46
+ });
47
+
48
+ return () => {
49
+ window.cancelAnimationFrame(focusId);
50
+ };
51
+ }, [isOpen]);
52
+
53
+ if (!isOpen) return null;
54
+
55
+ const handleSubmit = async () => {
56
+ await onSubmit(newCaseName.trim());
57
+ setNewCaseName('');
58
+ };
59
+
60
+ return (
61
+ <div
62
+ className={styles.overlay}
63
+ aria-label="Close rename case dialog"
64
+ {...overlayProps}
65
+ >
66
+ <div className={styles.modal} role="dialog" aria-modal="true" aria-label="Rename Case">
67
+ <button {...getCloseButtonProps({ ariaLabel: 'Close rename case dialog' })}>
68
+ ×
69
+ </button>
70
+ <h3 className={styles.title}>Rename Case</h3>
71
+ <p className={styles.subtitle}>Current case: {currentCase}</p>
72
+ <input
73
+ ref={inputRef}
74
+ type="text"
75
+ value={newCaseName}
76
+ onChange={(event) => setNewCaseName(event.target.value)}
77
+ className={styles.input}
78
+ placeholder="New case number"
79
+ disabled={isSubmitting}
80
+ onKeyDown={(event) => {
81
+ if (event.key === 'Enter' && newCaseName.trim() && !isSubmitting) {
82
+ void handleSubmit();
83
+ }
84
+ }}
85
+ />
86
+ <div className={styles.actions}>
87
+ <button
88
+ type="button"
89
+ className={styles.cancelButton}
90
+ onClick={requestClose}
91
+ disabled={isCloseBlocked}
92
+ >
93
+ Cancel
94
+ </button>
95
+ <button
96
+ type="button"
97
+ className={styles.confirmButton}
98
+ onClick={() => void handleSubmit()}
99
+ disabled={isSubmitting || !newCaseName.trim()}
100
+ >
101
+ {isSubmitting ? 'Renaming...' : 'Rename Case'}
102
+ </button>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ );
107
+ };
@@ -0,0 +1,447 @@
1
+ .navbar {
2
+ height: 60px;
3
+ width: 100%;
4
+ flex-shrink: 0;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ padding: 0 var(--spaceL);
9
+ box-sizing: border-box;
10
+ background-color: #f8f9fa;
11
+ border-bottom: 1px solid #dee2e6;
12
+ z-index: 35;
13
+ position: relative;
14
+ gap: var(--spaceL);
15
+ }
16
+
17
+ .companyLabelContainer {
18
+ display: flex;
19
+ align-items: center;
20
+ overflow-x: auto;
21
+ overflow-y: hidden;
22
+ max-width: calc(100% - 500px);
23
+ flex-shrink: 1;
24
+ min-width: 150px;
25
+ scroll-behavior: smooth;
26
+ }
27
+
28
+ .companyLabelContainer::-webkit-scrollbar {
29
+ height: 4px;
30
+ }
31
+
32
+ .companyLabelContainer::-webkit-scrollbar-track {
33
+ background: transparent;
34
+ }
35
+
36
+ .companyLabelContainer::-webkit-scrollbar-thumb {
37
+ background: #adb5bd;
38
+ border-radius: 2px;
39
+ }
40
+
41
+ .companyLabelContainer::-webkit-scrollbar-thumb:hover {
42
+ background: #868e96;
43
+ }
44
+
45
+ .companyLabel {
46
+ color: #495057;
47
+ font-size: var(--fontSizeBodyM);
48
+ font-weight: var(--fontWeightMedium);
49
+ white-space: nowrap;
50
+ flex-shrink: 0;
51
+ padding-right: var(--spaceM);
52
+ }
53
+
54
+ .navbar a {
55
+ text-decoration: none;
56
+ }
57
+
58
+ .navbar a:hover,
59
+ .navbar a:focus,
60
+ .navbar a:active,
61
+ .navbar a:visited {
62
+ text-decoration: none;
63
+ }
64
+
65
+ .navCenterTrack {
66
+ position: absolute;
67
+ left: calc(var(--spaceL) + 300px);
68
+ right: var(--spaceL);
69
+ display: flex;
70
+ justify-content: center;
71
+ pointer-events: none;
72
+ }
73
+
74
+ .navCentral {
75
+ display: flex;
76
+ align-items: center;
77
+ gap: var(--spaceS);
78
+ margin: 0;
79
+ flex-shrink: 0;
80
+ padding: 0.4rem;
81
+ border: 1px solid #dde3e9;
82
+ border-radius: 999px;
83
+ background: rgba(255, 255, 255, 0.78);
84
+ box-shadow: 0 1px 3px rgba(33, 37, 41, 0.06);
85
+ pointer-events: auto;
86
+ }
87
+
88
+ .navActions {
89
+ display: flex;
90
+ align-items: center;
91
+ gap: var(--spaceM);
92
+ flex-shrink: 0;
93
+ }
94
+
95
+ .navTextButton {
96
+ border: none;
97
+ background: transparent;
98
+ padding: 0;
99
+ margin: 0;
100
+ color: #495057;
101
+ font-size: var(--fontSizeBodyS);
102
+ font-weight: var(--fontWeightMedium);
103
+ cursor: pointer;
104
+ text-decoration: none;
105
+ }
106
+
107
+ .navTextButton:hover {
108
+ color: #212529;
109
+ text-decoration: none;
110
+ }
111
+
112
+ .navTextButton:focus,
113
+ .navTextButton:active,
114
+ .navTextButton:visited {
115
+ text-decoration: none;
116
+ }
117
+
118
+ .navTextButton:disabled {
119
+ color: #adb5bd;
120
+ cursor: not-allowed;
121
+ text-decoration: none;
122
+ }
123
+
124
+ .navSectionButton {
125
+ border: 1px solid transparent;
126
+ background: transparent;
127
+ padding: 0.5rem 0.9rem;
128
+ margin: 0;
129
+ color: #495057;
130
+ font-size: var(--fontSizeBodyS);
131
+ font-weight: var(--fontWeightMedium);
132
+ line-height: 1;
133
+ border-radius: 999px;
134
+ cursor: pointer;
135
+ text-decoration: none;
136
+ transition:
137
+ color var(--durationS) var(--bezierFastoutSlowin),
138
+ background-color var(--durationS) var(--bezierFastoutSlowin),
139
+ border-color var(--durationS) var(--bezierFastoutSlowin),
140
+ box-shadow var(--durationS) var(--bezierFastoutSlowin);
141
+ }
142
+
143
+ .navSectionButton:hover {
144
+ color: #212529;
145
+ background: rgba(73, 80, 87, 0.08);
146
+ border-color: rgba(73, 80, 87, 0.12);
147
+ }
148
+
149
+ .navSectionButtonActive {
150
+ color: #0f5132;
151
+ background: rgba(25, 135, 84, 0.16);
152
+ border-color: rgba(25, 135, 84, 0.28);
153
+ box-shadow: inset 0 0 0 1px rgba(25, 135, 84, 0.08);
154
+ }
155
+
156
+ .navSectionButtonActive:hover {
157
+ color: #0b3d28;
158
+ background: rgba(25, 135, 84, 0.22);
159
+ border-color: rgba(25, 135, 84, 0.34);
160
+ }
161
+
162
+ .navSectionButton:focus,
163
+ .navSectionButton:active,
164
+ .navSectionButton:visited {
165
+ text-decoration: none;
166
+ }
167
+
168
+ .navSectionButton:disabled {
169
+ color: #adb5bd;
170
+ background: rgba(173, 181, 189, 0.12);
171
+ border-color: transparent;
172
+ cursor: not-allowed;
173
+ opacity: 0.9;
174
+ }
175
+
176
+ .navPrimaryButton {
177
+ background: rgba(25, 135, 84, 0.12);
178
+ border-color: rgba(25, 135, 84, 0.2);
179
+ color: #146c43;
180
+ }
181
+
182
+ .navPrimaryButton:hover {
183
+ background: rgba(25, 135, 84, 0.18);
184
+ border-color: rgba(25, 135, 84, 0.3);
185
+ color: #0f5132;
186
+ }
187
+
188
+ .navPrimaryButton:disabled {
189
+ color: #adb5bd;
190
+ background: rgba(173, 181, 189, 0.12);
191
+ border-color: transparent;
192
+ }
193
+
194
+ .caseMenuContainer {
195
+ position: relative;
196
+ }
197
+
198
+ .fileMenuContainer {
199
+ position: relative;
200
+ }
201
+
202
+ .caseMenu {
203
+ position: absolute;
204
+ top: calc(100% + 0.5rem);
205
+ left: 0;
206
+ min-width: 220px;
207
+ display: flex;
208
+ flex-direction: column;
209
+ gap: 0.3rem;
210
+ padding: 0.45rem;
211
+ background: #ffffff;
212
+ border: 1px solid #dde3e9;
213
+ border-radius: 12px;
214
+ box-shadow: 0 10px 26px rgba(0, 0, 0, 0.14);
215
+ z-index: 60;
216
+ }
217
+
218
+ .fileMenu {
219
+ position: absolute;
220
+ top: calc(100% + 0.5rem);
221
+ left: 0;
222
+ min-width: 220px;
223
+ display: flex;
224
+ flex-direction: column;
225
+ gap: 0.3rem;
226
+ padding: 0.45rem;
227
+ background: #ffffff;
228
+ border: 1px solid #dde3e9;
229
+ border-radius: 12px;
230
+ box-shadow: 0 10px 26px rgba(0, 0, 0, 0.14);
231
+ z-index: 60;
232
+ }
233
+
234
+ .caseMenuItem {
235
+ width: 100%;
236
+ border: 1px solid transparent;
237
+ background: #f8f9fa;
238
+ color: #343a40;
239
+ border-radius: 8px;
240
+ padding: 0.5rem 0.7rem;
241
+ font-size: var(--fontSizeBodyS);
242
+ font-weight: var(--fontWeightMedium);
243
+ text-align: left;
244
+ cursor: pointer;
245
+ transition: all var(--durationS) var(--bezierFastoutSlowin);
246
+ }
247
+
248
+ .fileMenuItem {
249
+ width: 100%;
250
+ border: 1px solid transparent;
251
+ background: #f8f9fa;
252
+ color: #343a40;
253
+ border-radius: 8px;
254
+ padding: 0.5rem 0.7rem;
255
+ font-size: var(--fontSizeBodyS);
256
+ font-weight: var(--fontWeightMedium);
257
+ text-align: left;
258
+ cursor: pointer;
259
+ transition: all var(--durationS) var(--bezierFastoutSlowin);
260
+ }
261
+
262
+ .caseMenuItem:hover {
263
+ background: #eef1f4;
264
+ border-color: #d6dce2;
265
+ }
266
+
267
+ .fileMenuItem:hover {
268
+ background: #eef1f4;
269
+ border-color: #d6dce2;
270
+ }
271
+
272
+ .caseMenuItem:disabled {
273
+ color: #adb5bd;
274
+ background: rgba(173, 181, 189, 0.14);
275
+ border-color: transparent;
276
+ cursor: not-allowed;
277
+ }
278
+
279
+ .fileMenuItem:disabled {
280
+ color: #adb5bd;
281
+ background: rgba(173, 181, 189, 0.14);
282
+ border-color: transparent;
283
+ cursor: not-allowed;
284
+ }
285
+
286
+ .fileMenuItemViewAll {
287
+ background: color-mix(in lab, #4a90e2 16%, #ffffff);
288
+ color: #1f5fa7;
289
+ border-color: color-mix(in lab, #4a90e2 30%, transparent);
290
+ }
291
+
292
+ .fileMenuItemViewAll:hover {
293
+ background: color-mix(in lab, #4a90e2 22%, #ffffff);
294
+ }
295
+
296
+ .fileMenuItemDelete {
297
+ background: color-mix(in lab, #dc3545 15%, #ffffff);
298
+ color: #b02a37;
299
+ border-color: color-mix(in lab, #dc3545 28%, transparent);
300
+ }
301
+
302
+ .fileMenuItemDelete:hover {
303
+ background: color-mix(in lab, #dc3545 21%, #ffffff);
304
+ }
305
+
306
+ .caseMenuItemOpen {
307
+ background: color-mix(in lab, #4a90e2 16%, #ffffff);
308
+ color: #1f5fa7;
309
+ border-color: color-mix(in lab, #4a90e2 30%, transparent);
310
+ }
311
+
312
+ .caseMenuItemOpen:hover {
313
+ background: color-mix(in lab, #4a90e2 22%, #ffffff);
314
+ }
315
+
316
+ .caseMenuItemList {
317
+ background: color-mix(in lab, #0d6efd 20%, #ffffff);
318
+ color: #0a4fad;
319
+ border-color: color-mix(in lab, #0d6efd 34%, transparent);
320
+ }
321
+
322
+ .caseMenuItemList:hover {
323
+ background: color-mix(in lab, #0d6efd 26%, #ffffff);
324
+ }
325
+
326
+ .caseMenuItemExport {
327
+ background: color-mix(in lab, #198754 16%, #ffffff);
328
+ color: #146c43;
329
+ border-color: color-mix(in lab, #198754 30%, transparent);
330
+ }
331
+
332
+ .caseMenuItemExport:hover {
333
+ background: color-mix(in lab, #198754 22%, #ffffff);
334
+ }
335
+
336
+ .caseMenuItemAudit {
337
+ background: color-mix(in lab, #6f42c1 16%, #ffffff);
338
+ color: #5a359a;
339
+ border-color: color-mix(in lab, #6f42c1 30%, transparent);
340
+ }
341
+
342
+ .caseMenuItemAudit:hover {
343
+ background: color-mix(in lab, #6f42c1 22%, #ffffff);
344
+ }
345
+
346
+ .caseMenuItemRename {
347
+ background: color-mix(in lab, #ffc107 16%, #ffffff);
348
+ color: #7a5a00;
349
+ border-color: color-mix(in lab, #ffc107 30%, transparent);
350
+ }
351
+
352
+ .caseMenuItemRename:hover {
353
+ background: color-mix(in lab, #ffc107 22%, #ffffff);
354
+ border-color: color-mix(in lab, #ffc107 36%, transparent);
355
+ }
356
+
357
+ .caseMenuItemDelete {
358
+ background: color-mix(in lab, #dc3545 15%, #ffffff);
359
+ color: #b02a37;
360
+ border-color: color-mix(in lab, #dc3545 28%, transparent);
361
+ }
362
+
363
+ .caseMenuItemDelete:hover {
364
+ background: color-mix(in lab, #dc3545 21%, #ffffff);
365
+ }
366
+
367
+ .caseMenuItemArchive {
368
+ background: color-mix(in lab, #6c757d 15%, #ffffff);
369
+ color: #495057;
370
+ border-color: color-mix(in lab, #6c757d 28%, transparent);
371
+ }
372
+
373
+ .caseMenuItemArchive:hover {
374
+ background: color-mix(in lab, #6c757d 21%, #ffffff);
375
+ }
376
+
377
+ .caseMenuItemKey {
378
+ background: color-mix(in lab, #0d9488 14%, #ffffff);
379
+ color: #0f766e;
380
+ border-color: color-mix(in lab, #0d9488 28%, transparent);
381
+ }
382
+
383
+ .caseMenuItemKey:hover {
384
+ background: color-mix(in lab, #0d9488 20%, #ffffff);
385
+ }
386
+
387
+ .caseMenuCaption {
388
+ margin-top: 0.25rem;
389
+ padding: 0.3rem 0.45rem 0.1rem;
390
+ border-top: 1px solid #e9ecef;
391
+ color: #6c757d;
392
+ font-size: 0.72rem;
393
+ font-weight: 500;
394
+ }
395
+
396
+ .caseArchiveDetails {
397
+ margin-top: 0.3rem;
398
+ padding: 0.45rem;
399
+ border-top: 1px solid #e9ecef;
400
+ border-radius: 8px;
401
+ background: color-mix(in lab, #0d9488 8%, #ffffff);
402
+ display: flex;
403
+ flex-direction: column;
404
+ gap: 0.2rem;
405
+ color: #0f766e;
406
+ font-size: 0.72rem;
407
+ }
408
+
409
+ .caseArchiveDetails strong {
410
+ font-size: 0.74rem;
411
+ color: #0b5f59;
412
+ }
413
+
414
+ .caseMenuSectionLabel {
415
+ margin-top: 0.2rem;
416
+ padding: 0.32rem 0.45rem 0.15rem;
417
+ border-top: 1px solid #e9ecef;
418
+ color: #6c757d;
419
+ font-size: 0.68rem;
420
+ font-weight: 600;
421
+ letter-spacing: 0.03em;
422
+ text-transform: uppercase;
423
+ }
424
+
425
+ .fileMenuCaption {
426
+ margin-top: 0.25rem;
427
+ padding: 0.3rem 0.45rem 0.1rem;
428
+ border-top: 1px solid #e9ecef;
429
+ color: #6c757d;
430
+ font-size: 0.72rem;
431
+ font-weight: 500;
432
+ max-width: 240px;
433
+ white-space: nowrap;
434
+ overflow: hidden;
435
+ text-overflow: ellipsis;
436
+ }
437
+
438
+ .fileMenuSectionLabel {
439
+ margin-top: 0.2rem;
440
+ padding: 0.32rem 0.45rem 0.15rem;
441
+ border-top: 1px solid #e9ecef;
442
+ color: #6c757d;
443
+ font-size: 0.68rem;
444
+ font-weight: 600;
445
+ letter-spacing: 0.03em;
446
+ text-transform: uppercase;
447
+ }