jira-pat 1.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 (95) hide show
  1. package/AGENTS.md +218 -0
  2. package/README.md +64 -0
  3. package/backend/.env.example +1 -0
  4. package/backend/__tests__/getJiraClient.test.js +57 -0
  5. package/backend/__tests__/issues.test.js +565 -0
  6. package/backend/__tests__/jiraService.test.js +1127 -0
  7. package/backend/__tests__/projects.test.js +256 -0
  8. package/backend/coverage/clover.xml +426 -0
  9. package/backend/coverage/coverage-final.json +4 -0
  10. package/backend/coverage/lcov-report/base.css +224 -0
  11. package/backend/coverage/lcov-report/block-navigation.js +87 -0
  12. package/backend/coverage/lcov-report/favicon.png +0 -0
  13. package/backend/coverage/lcov-report/index.html +131 -0
  14. package/backend/coverage/lcov-report/prettify.css +1 -0
  15. package/backend/coverage/lcov-report/prettify.js +2 -0
  16. package/backend/coverage/lcov-report/routes/index.html +131 -0
  17. package/backend/coverage/lcov-report/routes/issues.js.html +823 -0
  18. package/backend/coverage/lcov-report/routes/projects.js.html +190 -0
  19. package/backend/coverage/lcov-report/service/index.html +116 -0
  20. package/backend/coverage/lcov-report/service/jiraService.js.html +1663 -0
  21. package/backend/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  22. package/backend/coverage/lcov-report/sorter.js +210 -0
  23. package/backend/coverage/lcov.info +707 -0
  24. package/backend/index.js +38 -0
  25. package/backend/jest.config.js +11 -0
  26. package/backend/package-lock.json +5636 -0
  27. package/backend/package.json +28 -0
  28. package/backend/routes/issues.js +246 -0
  29. package/backend/routes/projects.js +35 -0
  30. package/backend/service/jiraService.js +526 -0
  31. package/bin/jira.js +92 -0
  32. package/frontend/.env.example +1 -0
  33. package/frontend/coverage/base.css +224 -0
  34. package/frontend/coverage/block-navigation.js +87 -0
  35. package/frontend/coverage/clover.xml +559 -0
  36. package/frontend/coverage/components/CreateIssueModal.jsx.html +592 -0
  37. package/frontend/coverage/components/IssueDetailPanel.jsx.html +1633 -0
  38. package/frontend/coverage/components/IssueDrawer.jsx.html +550 -0
  39. package/frontend/coverage/components/IssueTable.jsx.html +571 -0
  40. package/frontend/coverage/components/SkeletonComponents.jsx.html +223 -0
  41. package/frontend/coverage/components/ToastContainer.jsx.html +142 -0
  42. package/frontend/coverage/components/index.html +191 -0
  43. package/frontend/coverage/coverage-final.json +14 -0
  44. package/frontend/coverage/favicon.png +0 -0
  45. package/frontend/coverage/hooks/index.html +161 -0
  46. package/frontend/coverage/hooks/useFocusTrap.js.html +262 -0
  47. package/frontend/coverage/hooks/useIssueDrawer.js.html +1000 -0
  48. package/frontend/coverage/hooks/useIssuesList.js.html +175 -0
  49. package/frontend/coverage/hooks/useToasts.js.html +142 -0
  50. package/frontend/coverage/index.html +161 -0
  51. package/frontend/coverage/prettify.css +1 -0
  52. package/frontend/coverage/prettify.js +2 -0
  53. package/frontend/coverage/services/api.js.html +547 -0
  54. package/frontend/coverage/services/index.html +116 -0
  55. package/frontend/coverage/sort-arrow-sprite.png +0 -0
  56. package/frontend/coverage/sorter.js +210 -0
  57. package/frontend/coverage/utils/index.html +131 -0
  58. package/frontend/coverage/utils/issueHelpers.jsx.html +334 -0
  59. package/frontend/coverage/utils/sanitize.js.html +166 -0
  60. package/frontend/index.html +13 -0
  61. package/frontend/package-lock.json +3436 -0
  62. package/frontend/package.json +30 -0
  63. package/frontend/src/App.jsx +447 -0
  64. package/frontend/src/__tests__/components/CreateIssueModal.test.jsx +375 -0
  65. package/frontend/src/__tests__/components/IssueDetailPanel.test.jsx +962 -0
  66. package/frontend/src/__tests__/components/IssueDrawer.test.jsx +240 -0
  67. package/frontend/src/__tests__/components/IssueTable.test.jsx +423 -0
  68. package/frontend/src/__tests__/components/ToastContainer.test.jsx +196 -0
  69. package/frontend/src/__tests__/hooks/useFocusTrap.test.js +197 -0
  70. package/frontend/src/__tests__/hooks/useIssueDrawer.test.js +1053 -0
  71. package/frontend/src/__tests__/hooks/useIssuesList.test.js +175 -0
  72. package/frontend/src/__tests__/hooks/useToasts.test.js +110 -0
  73. package/frontend/src/__tests__/services/api.test.js +568 -0
  74. package/frontend/src/__tests__/setup.js +54 -0
  75. package/frontend/src/__tests__/utils/issueHelpers.test.jsx +336 -0
  76. package/frontend/src/__tests__/utils/sanitize.test.js +238 -0
  77. package/frontend/src/components/CreateIssueModal.jsx +169 -0
  78. package/frontend/src/components/ErrorBoundary.jsx +52 -0
  79. package/frontend/src/components/IssueDetailPanel.jsx +517 -0
  80. package/frontend/src/components/IssueDrawer.jsx +155 -0
  81. package/frontend/src/components/IssueTable.jsx +162 -0
  82. package/frontend/src/components/SkeletonComponents.jsx +46 -0
  83. package/frontend/src/components/StandaloneIssuePage.jsx +176 -0
  84. package/frontend/src/components/ToastContainer.jsx +19 -0
  85. package/frontend/src/hooks/useFocusTrap.js +59 -0
  86. package/frontend/src/hooks/useIssueDrawer.js +305 -0
  87. package/frontend/src/hooks/useIssuesList.js +30 -0
  88. package/frontend/src/hooks/useToasts.js +19 -0
  89. package/frontend/src/index.css +2070 -0
  90. package/frontend/src/main.jsx +13 -0
  91. package/frontend/src/services/api.js +154 -0
  92. package/frontend/src/utils/issueHelpers.jsx +84 -0
  93. package/frontend/src/utils/sanitize.js +27 -0
  94. package/frontend/vite.config.js +15 -0
  95. package/package.json +19 -0
@@ -0,0 +1,2070 @@
1
+ :root {
2
+ --primary: #0052cc;
3
+ --primary-hover: #0047b3;
4
+ --primary-light: rgba(0, 82, 204, 0.1);
5
+ --bg-color: #f4f5f7;
6
+ --surface: #ffffff;
7
+ --text-main: #172b4d;
8
+ --text-muted: #6b778c;
9
+ --border: #dfe1e6;
10
+ --hover-bg: #ebecf0;
11
+ --sidebar-bg: #fafbfc;
12
+ --section-divider: #ebecf0;
13
+
14
+ --status-todo-bg: #f4f5f7;
15
+ --status-todo-color: #42526e;
16
+ --status-inprogress-bg: #deebff;
17
+ --status-inprogress-color: #0052cc;
18
+ --status-done-bg: #e3fcef;
19
+ --status-done-color: #00875a;
20
+ --status-closed-bg: #091e42;
21
+ --status-closed-color: #ffffff;
22
+
23
+ --priority-highest: #ff5630;
24
+ --priority-high: #ff5630;
25
+ --priority-medium: #ffab00;
26
+ --priority-low: #36b37e;
27
+ --priority-lowest: #36b37e;
28
+
29
+ --severity-critical: #ff5630;
30
+ --severity-major: #ff8b00;
31
+ --severity-minor: #ffab00;
32
+ --severity-blocker: #de350b;
33
+ --severity-trivial: #36b37e;
34
+
35
+ --shadow-sm: 0 1px 2px rgba(9, 30, 66, 0.08);
36
+ --shadow-md: 0 1px 3px rgba(9, 30, 66, 0.1), 0 0 0 1px rgba(9, 30, 66, 0.02);
37
+ --shadow-lg: 0 4px 8px rgba(9, 30, 66, 0.12), 0 0 0 1px rgba(9, 30, 66, 0.04);
38
+ --shadow-inset: inset 0 1px 2px rgba(9, 30, 66, 0.05);
39
+ --shadow-comment: 0 1px 2px rgba(0, 0, 0, 0.05);
40
+ --shadow-drawer: -4px 0 16px rgba(9, 30, 66, 0.12);
41
+
42
+ --radius-sm: 3px;
43
+ --radius-md: 4px;
44
+ --radius-lg: 8px;
45
+ --radius-pill: 12px;
46
+
47
+ --space-1: 8px;
48
+ --space-2: 16px;
49
+ --space-3: 24px;
50
+ --space-4: 32px;
51
+
52
+ --transition-fast: 150ms ease;
53
+ --transition-normal: 200ms ease;
54
+ }
55
+
56
+ [data-theme="dark"] {
57
+ --primary: #388bfd;
58
+ --primary-hover: #58a6ff;
59
+ --primary-light: rgba(56, 139, 253, 0.15);
60
+ --bg-color: #0d1117;
61
+ --surface: #161b22;
62
+ --text-main: #c9d1d9;
63
+ --text-muted: #8b949e;
64
+ --border: #30363d;
65
+ --hover-bg: #21262d;
66
+ --sidebar-bg: #161b22;
67
+ --section-divider: #21262d;
68
+
69
+ --status-todo-bg: #21262d;
70
+ --status-todo-color: #8b949e;
71
+ --status-inprogress-bg: rgba(56, 139, 253, 0.15);
72
+ --status-inprogress-color: #388bfd;
73
+ --status-done-bg: rgba(35, 134, 54, 0.15);
74
+ --status-done-color: #3fb950;
75
+ --status-closed-bg: #21262d;
76
+ --status-closed-color: #8b949e;
77
+
78
+ --priority-highest: #f85149;
79
+ --priority-high: #f85149;
80
+ --priority-medium: #d29922;
81
+ --priority-low: #3fb950;
82
+ --priority-lowest: #3fb950;
83
+
84
+ --severity-critical: #f85149;
85
+ --severity-major: #ff8b00;
86
+ --severity-minor: #d29922;
87
+ --severity-blocker: #f85149;
88
+ --severity-trivial: #3fb950;
89
+
90
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
91
+ --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.1);
92
+ --shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(0, 0, 0, 0.1);
93
+ --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.2);
94
+ --shadow-comment: 0 1px 2px rgba(0, 0, 0, 0.2);
95
+ --shadow-drawer: -4px 0 16px rgba(0, 0, 0, 0.4);
96
+
97
+ --radius-sm: 3px;
98
+ --radius-md: 4px;
99
+ --radius-lg: 8px;
100
+ --radius-pill: 12px;
101
+
102
+ --space-1: 8px;
103
+ --space-2: 16px;
104
+ --space-3: 24px;
105
+ --space-4: 32px;
106
+
107
+ --transition-fast: 150ms ease;
108
+ --transition-normal: 200ms ease;
109
+ }
110
+
111
+ [data-theme="dark"] body {
112
+ background-color: var(--bg-color);
113
+ }
114
+
115
+ [data-theme="dark"] .issue-table th {
116
+ background-color: #21262d;
117
+ }
118
+
119
+ [data-theme="dark"] .issue-table tbody tr:hover {
120
+ background-color: #21262d;
121
+ }
122
+
123
+ [data-theme="dark"] .empty-state-icon {
124
+ color: #30363d;
125
+ }
126
+
127
+ [data-theme="dark"] .label-tag {
128
+ background: #21262d;
129
+ color: #c9d1d9;
130
+ }
131
+
132
+ [data-theme="dark"] .drawer-overlay {
133
+ background: rgba(0, 0, 0, 0.7);
134
+ }
135
+
136
+ [data-theme="dark"] .modal-overlay {
137
+ background: rgba(0, 0, 0, 0.7);
138
+ }
139
+
140
+ [data-theme="dark"] .version-select {
141
+ background: #21262d;
142
+ color: #c9d1d9;
143
+ }
144
+
145
+ [data-theme="dark"] .modal-footer {
146
+ background: #21262d;
147
+ }
148
+
149
+ [data-theme="dark"] .add-label-input:focus {
150
+ background: #21262d;
151
+ color: #c9d1d9;
152
+ }
153
+
154
+ [data-theme="dark"] .label-suggestions-dropdown {
155
+ background: #161b22;
156
+ }
157
+
158
+ [data-theme="dark"] .label-suggestion-item {
159
+ color: #c9d1d9;
160
+ }
161
+
162
+ [data-theme="dark"] .severity-badge.critical,
163
+ [data-theme="dark"] .severity-badge.blocker,
164
+ [data-theme="dark"] .severity-badge.sev-1 {
165
+ background: rgba(248, 81, 73, 0.15);
166
+ }
167
+
168
+ [data-theme="dark"] .severity-badge.major,
169
+ [data-theme="dark"] .severity-badge.sev-2 {
170
+ background: rgba(255, 139, 0, 0.15);
171
+ }
172
+
173
+ [data-theme="dark"] .severity-badge.minor,
174
+ [data-theme="dark"] .severity-badge.sev-3 {
175
+ background: rgba(210, 153, 34, 0.15);
176
+ }
177
+
178
+ [data-theme="dark"] .severity-badge.trivial,
179
+ [data-theme="dark"] .severity-badge.sev-4,
180
+ [data-theme="dark"] .severity-badge.sev-5 {
181
+ background: rgba(63, 185, 80, 0.15);
182
+ }
183
+
184
+ [data-theme="dark"] .error {
185
+ background: rgba(248, 81, 73, 0.15);
186
+ border-color: rgba(248, 81, 73, 0.3);
187
+ color: #f85149;
188
+ }
189
+
190
+ .theme-toggle {
191
+ display: flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ width: 36px;
195
+ height: 36px;
196
+ padding: 0;
197
+ background: var(--surface);
198
+ border: 1px solid var(--border);
199
+ border-radius: var(--radius-md);
200
+ color: var(--text-muted);
201
+ cursor: pointer;
202
+ transition: all var(--transition-fast);
203
+ }
204
+
205
+ .theme-toggle:hover {
206
+ background: var(--hover-bg);
207
+ color: var(--text-main);
208
+ border-color: var(--primary);
209
+ }
210
+
211
+ * {
212
+ box-sizing: border-box;
213
+ }
214
+
215
+ body {
216
+ margin: 0;
217
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
218
+ background-color: var(--bg-color);
219
+ color: var(--text-main);
220
+ -webkit-font-smoothing: antialiased;
221
+ -moz-osx-font-smoothing: grayscale;
222
+ line-height: 1.5;
223
+ }
224
+
225
+ .dashboard-container {
226
+ max-width: 1280px;
227
+ margin: 0 auto;
228
+ padding: 2rem;
229
+ }
230
+
231
+ .header {
232
+ margin-bottom: 2rem;
233
+ display: flex;
234
+ justify-content: space-between;
235
+ align-items: center;
236
+ }
237
+
238
+ .header h1 {
239
+ margin: 0;
240
+ font-size: 1.75rem;
241
+ font-weight: 600;
242
+ color: var(--text-main);
243
+ letter-spacing: -0.01em;
244
+ }
245
+
246
+ .header-actions {
247
+ display: flex;
248
+ align-items: center;
249
+ gap: 1rem;
250
+ }
251
+
252
+ .jump-to-issue {
253
+ position: relative;
254
+ display: flex;
255
+ align-items: center;
256
+ }
257
+
258
+ .jump-to-issue .text-input {
259
+ width: 220px;
260
+ padding-right: 2rem;
261
+ font-size: 0.875rem;
262
+ }
263
+
264
+ .jump-to-issue .search-clear-btn {
265
+ position: absolute;
266
+ right: 8px;
267
+ background: none;
268
+ border: none;
269
+ cursor: pointer;
270
+ color: var(--text-muted);
271
+ padding: 2px;
272
+ display: flex;
273
+ align-items: center;
274
+ }
275
+
276
+ .jump-to-issue .search-clear-btn:hover {
277
+ color: var(--text-main);
278
+ }
279
+
280
+ .keyboard-hint {
281
+ font-size: 0.75rem;
282
+ color: var(--text-muted);
283
+ background: var(--surface);
284
+ padding: 0.25rem 0.5rem;
285
+ border-radius: var(--radius-sm);
286
+ border: 1px solid var(--border);
287
+ }
288
+
289
+ .controls {
290
+ display: flex;
291
+ gap: 1rem;
292
+ margin-bottom: 1rem;
293
+ flex-wrap: wrap;
294
+ align-items: flex-end;
295
+ overflow: visible;
296
+ }
297
+
298
+ .controls-main {
299
+ display: flex;
300
+ gap: 1rem;
301
+ flex-wrap: wrap;
302
+ flex: 1;
303
+ overflow: visible;
304
+ }
305
+
306
+ .controls-secondary {
307
+ display: flex;
308
+ gap: 0.5rem;
309
+ flex-wrap: wrap;
310
+ }
311
+
312
+ .input-group {
313
+ display: flex;
314
+ flex-direction: column;
315
+ gap: 0.375rem;
316
+ min-width: 180px;
317
+ }
318
+
319
+ .input-group.search-group {
320
+ flex: 1;
321
+ min-width: 250px;
322
+ overflow: visible;
323
+ }
324
+
325
+ .input-label {
326
+ font-size: 0.75rem;
327
+ font-weight: 600;
328
+ color: var(--text-muted);
329
+ text-transform: uppercase;
330
+ letter-spacing: 0.04em;
331
+ }
332
+
333
+ .text-input, .select-input {
334
+ padding: 0.625rem 0.75rem;
335
+ border: 2px solid var(--border);
336
+ border-radius: var(--radius-md);
337
+ font-size: 0.95rem;
338
+ color: var(--text-main);
339
+ background: var(--surface);
340
+ min-width: 180px;
341
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
342
+ }
343
+
344
+ .text-input:focus, .select-input:focus {
345
+ outline: none;
346
+ border-color: var(--primary);
347
+ box-shadow: 0 0 0 3px var(--primary-light);
348
+ }
349
+
350
+ .text-input::placeholder {
351
+ color: var(--text-muted);
352
+ }
353
+
354
+ .search-input-wrapper {
355
+ position: relative;
356
+ display: flex;
357
+ align-items: center;
358
+ flex: 1;
359
+ overflow: visible;
360
+ }
361
+
362
+ .search-input-wrapper .text-input {
363
+ padding-left: 2.5rem;
364
+ padding-right: 2.5rem;
365
+ width: 100%;
366
+ }
367
+
368
+ .search-input-wrapper .search-icon {
369
+ position: absolute;
370
+ left: 0.75rem;
371
+ color: var(--text-muted);
372
+ pointer-events: none;
373
+ }
374
+
375
+ .search-clear-btn {
376
+ position: absolute;
377
+ right: 0.5rem;
378
+ background: none;
379
+ border: none;
380
+ padding: 0.25rem;
381
+ cursor: pointer;
382
+ color: var(--text-muted);
383
+ display: flex;
384
+ align-items: center;
385
+ justify-content: center;
386
+ border-radius: var(--radius-sm);
387
+ transition: color var(--transition-fast), background-color var(--transition-fast);
388
+ }
389
+
390
+ .search-clear-btn:hover {
391
+ color: var(--text-main);
392
+ background-color: var(--hover-bg);
393
+ }
394
+
395
+ .search-suggestions-dropdown {
396
+ position: absolute;
397
+ top: 100%;
398
+ left: 0;
399
+ right: 0;
400
+ margin-top: 0.5rem;
401
+ background: var(--surface);
402
+ border: 2px solid var(--primary);
403
+ border-radius: var(--radius-md);
404
+ box-shadow: var(--shadow-lg);
405
+ max-height: 300px;
406
+ overflow-y: auto;
407
+ z-index: 1000;
408
+ }
409
+
410
+ .search-suggestion-item {
411
+ display: flex;
412
+ align-items: center;
413
+ gap: 0.75rem;
414
+ padding: 0.625rem 0.75rem;
415
+ cursor: pointer;
416
+ border-bottom: 1px solid var(--border);
417
+ transition: background-color var(--transition-fast);
418
+ }
419
+
420
+ .search-suggestion-item:last-child {
421
+ border-bottom: none;
422
+ }
423
+
424
+ .search-suggestion-item:hover,
425
+ .search-suggestion-item.selected {
426
+ background-color: var(--primary-light);
427
+ }
428
+
429
+ .suggestion-key {
430
+ font-weight: 600;
431
+ color: var(--primary);
432
+ white-space: nowrap;
433
+ flex-shrink: 0;
434
+ }
435
+
436
+ .suggestion-summary {
437
+ color: var(--text-main);
438
+ white-space: nowrap;
439
+ overflow: hidden;
440
+ text-overflow: ellipsis;
441
+ font-size: 0.9rem;
442
+ }
443
+
444
+ .filter-chips {
445
+ display: flex;
446
+ gap: 0.5rem;
447
+ margin-bottom: 1.5rem;
448
+ flex-wrap: wrap;
449
+ }
450
+
451
+ .filter-chip {
452
+ padding: 0.375rem 0.875rem;
453
+ border: 2px solid var(--border);
454
+ border-radius: 20px;
455
+ background: var(--surface);
456
+ font-size: 0.85rem;
457
+ font-weight: 500;
458
+ color: var(--text-muted);
459
+ cursor: pointer;
460
+ transition: all var(--transition-fast);
461
+ display: flex;
462
+ align-items: center;
463
+ gap: 0.375rem;
464
+ }
465
+
466
+ .filter-chip:hover {
467
+ border-color: var(--primary);
468
+ color: var(--primary);
469
+ }
470
+
471
+ .filter-chip.active {
472
+ background: var(--primary);
473
+ border-color: var(--primary);
474
+ color: white;
475
+ }
476
+
477
+ .filter-chip .count {
478
+ font-size: 0.75rem;
479
+ opacity: 0.8;
480
+ }
481
+
482
+ .loading, .error, .empty-state {
483
+ text-align: center;
484
+ padding: 3rem;
485
+ color: var(--text-muted);
486
+ font-size: 1rem;
487
+ }
488
+
489
+ .error {
490
+ color: #de350b;
491
+ background: #ffebe6;
492
+ border-radius: var(--radius-md);
493
+ border: 1px solid #ffbdad;
494
+ padding: 1rem 1.5rem;
495
+ margin-bottom: 1rem;
496
+ }
497
+
498
+ .empty-state {
499
+ padding: 4rem 2rem;
500
+ background: var(--surface);
501
+ border-radius: var(--radius-lg);
502
+ box-shadow: var(--shadow-md);
503
+ }
504
+
505
+ .empty-state-icon {
506
+ margin-bottom: 1rem;
507
+ color: var(--border);
508
+ }
509
+
510
+ .empty-state h3 {
511
+ margin: 0 0 0.5rem 0;
512
+ color: var(--text-main);
513
+ font-size: 1.1rem;
514
+ }
515
+
516
+ .empty-state p {
517
+ margin: 0;
518
+ color: var(--text-muted);
519
+ font-size: 0.9rem;
520
+ }
521
+
522
+ .skeleton {
523
+ background: linear-gradient(90deg, var(--border) 25%, var(--hover-bg) 50%, var(--border) 75%);
524
+ background-size: 200% 100%;
525
+ animation: shimmer 1.5s infinite;
526
+ border-radius: var(--radius-sm);
527
+ }
528
+
529
+ @keyframes shimmer {
530
+ 0% { background-position: 200% 0; }
531
+ 100% { background-position: -200% 0; }
532
+ }
533
+
534
+ .skeleton-row {
535
+ display: flex;
536
+ align-items: center;
537
+ padding: 1rem;
538
+ border-bottom: 1px solid var(--border);
539
+ gap: 1rem;
540
+ }
541
+
542
+ .skeleton-cell {
543
+ height: 1rem;
544
+ flex: 1;
545
+ }
546
+
547
+ .skeleton-cell:first-child {
548
+ max-width: 100px;
549
+ flex: none;
550
+ }
551
+
552
+ .skeleton-cell:last-child {
553
+ max-width: 80px;
554
+ flex: none;
555
+ }
556
+
557
+ .skeleton-avatar {
558
+ width: 32px;
559
+ height: 32px;
560
+ border-radius: 50%;
561
+ flex-shrink: 0;
562
+ }
563
+
564
+ .skeleton-title {
565
+ height: 24px;
566
+ width: 60%;
567
+ margin-bottom: 1rem;
568
+ }
569
+
570
+ .skeleton-line {
571
+ height: 14px;
572
+ margin-bottom: 0.75rem;
573
+ }
574
+
575
+ .skeleton-line:last-child {
576
+ width: 60%;
577
+ }
578
+
579
+ .skeleton-chip {
580
+ height: 24px;
581
+ width: 80px;
582
+ border-radius: 12px;
583
+ flex-shrink: 0;
584
+ }
585
+
586
+ .skeleton-sidebar-item {
587
+ padding: 0.5rem 0;
588
+ }
589
+
590
+ .drawer-skeleton {
591
+ padding: 1.5rem;
592
+ display: flex;
593
+ flex-direction: column;
594
+ }
595
+
596
+ .drawer-skeleton-header {
597
+ margin-bottom: 1.5rem;
598
+ }
599
+
600
+ .drawer-skeleton-description {
601
+ margin-bottom: 2rem;
602
+ }
603
+
604
+ .drawer-skeleton-sidebar {
605
+ display: grid;
606
+ grid-template-columns: 1fr 1fr;
607
+ gap: 1rem;
608
+ padding: 1rem;
609
+ background: var(--sidebar-bg);
610
+ border-radius: var(--radius-md);
611
+ }
612
+
613
+ .suggestions-skeleton {
614
+ padding: 0.75rem;
615
+ display: flex;
616
+ flex-direction: column;
617
+ gap: 0.5rem;
618
+ }
619
+
620
+ .table-container {
621
+ background: var(--surface);
622
+ border-radius: var(--radius-lg);
623
+ box-shadow: var(--shadow-md);
624
+ overflow-x: auto;
625
+ }
626
+
627
+ .issue-table {
628
+ width: 100%;
629
+ border-collapse: collapse;
630
+ text-align: left;
631
+ }
632
+
633
+ .issue-table th {
634
+ background-color: #fafbfc;
635
+ padding: 1rem;
636
+ font-weight: 600;
637
+ font-size: 0.8rem;
638
+ text-transform: uppercase;
639
+ letter-spacing: 0.04em;
640
+ color: var(--text-muted);
641
+ border-bottom: 2px solid var(--border);
642
+ white-space: nowrap;
643
+ }
644
+
645
+ .issue-table td {
646
+ padding: 1rem;
647
+ border-bottom: 1px solid var(--border);
648
+ color: var(--text-main);
649
+ vertical-align: middle;
650
+ }
651
+
652
+ .issue-table tbody tr {
653
+ transition: background-color var(--transition-fast);
654
+ }
655
+
656
+ .issue-table tbody tr:hover {
657
+ background-color: #fafbfc;
658
+ }
659
+
660
+ .issue-table tbody tr:last-child td {
661
+ border-bottom: none;
662
+ }
663
+
664
+ .pagination-bar {
665
+ display: flex;
666
+ justify-content: space-between;
667
+ align-items: center;
668
+ padding: 1rem;
669
+ border-top: 1px solid var(--border);
670
+ }
671
+
672
+ .pagination-info {
673
+ font-size: 0.875rem;
674
+ color: var(--text-muted);
675
+ }
676
+
677
+ .pagination-controls {
678
+ display: flex;
679
+ gap: 0.5rem;
680
+ align-items: center;
681
+ }
682
+
683
+ .pagination-btn {
684
+ padding: 0.375rem 0.75rem;
685
+ border: 1px solid var(--border);
686
+ border-radius: var(--radius-md);
687
+ background: var(--surface);
688
+ cursor: pointer;
689
+ font-size: 0.875rem;
690
+ color: var(--text-main);
691
+ transition: all var(--transition-fast);
692
+ }
693
+
694
+ .pagination-btn:hover:not(:disabled) {
695
+ border-color: var(--primary);
696
+ color: var(--primary);
697
+ }
698
+
699
+ .pagination-btn:disabled {
700
+ opacity: 0.5;
701
+ cursor: not-allowed;
702
+ }
703
+
704
+ .pagination-page {
705
+ font-size: 0.875rem;
706
+ color: var(--text-muted);
707
+ padding: 0 0.5rem;
708
+ }
709
+
710
+ .issue-key {
711
+ color: var(--primary);
712
+ font-weight: 600;
713
+ text-decoration: none;
714
+ font-size: 0.9rem;
715
+ display: inline-flex;
716
+ align-items: center;
717
+ gap: 0.375rem;
718
+ }
719
+
720
+ .issue-key:hover {
721
+ text-decoration: underline;
722
+ }
723
+
724
+ .issue-summary {
725
+ max-width: 400px;
726
+ overflow: hidden;
727
+ text-overflow: ellipsis;
728
+ white-space: nowrap;
729
+ }
730
+
731
+ .status-badge {
732
+ display: inline-flex;
733
+ align-items: center;
734
+ gap: 0.375rem;
735
+ padding: 0.25rem 0.625rem;
736
+ border-radius: 20px;
737
+ font-size: 0.75rem;
738
+ font-weight: 600;
739
+ white-space: nowrap;
740
+ }
741
+
742
+ .status-badge.todo {
743
+ background: var(--status-todo-bg);
744
+ color: var(--status-todo-color);
745
+ }
746
+
747
+ .status-badge.in-progress {
748
+ background: var(--status-inprogress-bg);
749
+ color: var(--status-inprogress-color);
750
+ }
751
+
752
+ .status-badge.done {
753
+ background: var(--status-done-bg);
754
+ color: var(--status-done-color);
755
+ }
756
+
757
+ .status-badge.closed {
758
+ background: var(--status-closed-bg);
759
+ color: var(--status-closed-color);
760
+ }
761
+
762
+ .priority-badge {
763
+ display: inline-flex;
764
+ align-items: center;
765
+ gap: 0.25rem;
766
+ font-size: 0.85rem;
767
+ }
768
+
769
+ .priority-badge svg {
770
+ flex-shrink: 0;
771
+ }
772
+
773
+ .priority-badge.highest,
774
+ .priority-badge.high {
775
+ color: var(--priority-high);
776
+ }
777
+
778
+ .priority-badge.medium {
779
+ color: var(--priority-medium);
780
+ }
781
+
782
+ .priority-badge.low,
783
+ .priority-badge.lowest {
784
+ color: var(--priority-low);
785
+ }
786
+
787
+ .severity-badge {
788
+ display: inline-flex;
789
+ align-items: center;
790
+ gap: 0.35rem;
791
+ font-size: 13px;
792
+ padding: 4px 10px;
793
+ border-radius: 4px;
794
+ font-weight: 500;
795
+ white-space: nowrap;
796
+ width: fit-content;
797
+ }
798
+
799
+ .severity-badge.critical,
800
+ .severity-badge.blocker,
801
+ .severity-badge.sev-1 {
802
+ background: rgba(255, 86, 48, 0.12);
803
+ color: var(--severity-critical);
804
+ }
805
+
806
+ .severity-badge.major,
807
+ .severity-badge.sev-2 {
808
+ background: rgba(255, 139, 0, 0.12);
809
+ color: var(--severity-major);
810
+ }
811
+
812
+ .severity-badge.minor,
813
+ .severity-badge.sev-3 {
814
+ background: rgba(255, 171, 0, 0.12);
815
+ color: var(--severity-minor);
816
+ }
817
+
818
+ .severity-badge.trivial,
819
+ .severity-badge.sev-4,
820
+ .severity-badge.sev-5 {
821
+ background: rgba(54, 179, 126, 0.12);
822
+ color: var(--severity-trivial);
823
+ }
824
+
825
+ .assignee-cell {
826
+ display: flex;
827
+ align-items: center;
828
+ gap: 0.5rem;
829
+ }
830
+
831
+ .avatar {
832
+ width: 28px;
833
+ height: 28px;
834
+ border-radius: 50%;
835
+ background: var(--primary);
836
+ color: white;
837
+ display: flex;
838
+ align-items: center;
839
+ justify-content: center;
840
+ font-size: 0.7rem;
841
+ font-weight: 600;
842
+ text-transform: uppercase;
843
+ flex-shrink: 0;
844
+ }
845
+
846
+ .avatar.large {
847
+ width: 40px;
848
+ height: 40px;
849
+ font-size: 0.9rem;
850
+ }
851
+
852
+ .avatar.placeholder {
853
+ background: var(--border);
854
+ color: var(--text-muted);
855
+ }
856
+
857
+ .avatar.small {
858
+ width: 24px;
859
+ height: 24px;
860
+ font-size: 0.65rem;
861
+ }
862
+
863
+ .issue-type-icon {
864
+ display: inline-flex;
865
+ align-items: center;
866
+ justify-content: center;
867
+ width: 20px;
868
+ height: 20px;
869
+ }
870
+
871
+ .drawer-overlay {
872
+ position: fixed;
873
+ top: 0; left: 0; right: 0; bottom: 0;
874
+ background: rgba(9, 30, 66, 0.54);
875
+ backdrop-filter: blur(2px);
876
+ z-index: 100;
877
+ display: flex;
878
+ align-items: flex-start;
879
+ justify-content: center;
880
+ padding-top: 5vh;
881
+ animation: fadeIn 0.2s ease-out;
882
+ }
883
+
884
+ @keyframes fadeIn {
885
+ from { opacity: 0; }
886
+ to { opacity: 1; }
887
+ }
888
+
889
+ .drawer {
890
+ width: 750px;
891
+ max-width: calc(100vw - 4rem);
892
+ max-height: 90vh;
893
+ background: var(--surface);
894
+ border-radius: var(--radius-lg);
895
+ box-shadow: var(--shadow-lg), 0 0 0 1px rgba(9, 30, 66, 0.08);
896
+ display: flex;
897
+ flex-direction: column;
898
+ animation: modalPop 0.25s ease-out;
899
+ overflow: hidden;
900
+ transition: width 0.2s ease, max-height 0.2s ease, height 0.2s ease, border-radius 0.2s ease;
901
+ }
902
+
903
+ .drawer.expanded {
904
+ width: calc(100vw - 64px);
905
+ max-width: none;
906
+ height: calc(100vh - 32px);
907
+ max-height: none;
908
+ border-radius: var(--radius-lg);
909
+ }
910
+
911
+ .drawer.expanded .drawer-sidebar {
912
+ width: 300px;
913
+ }
914
+
915
+ @keyframes modalPop {
916
+ from {
917
+ opacity: 0;
918
+ transform: scale(0.97) translateY(-10px);
919
+ }
920
+ to {
921
+ opacity: 1;
922
+ transform: scale(1) translateY(0);
923
+ }
924
+ }
925
+
926
+ .drawer-header {
927
+ padding: var(--space-2);
928
+ border-bottom: 1px solid var(--border);
929
+ display: flex;
930
+ align-items: center;
931
+ gap: var(--space-2);
932
+ background: var(--surface);
933
+ flex-shrink: 0;
934
+ }
935
+
936
+ .drawer-header-content {
937
+ flex: 1;
938
+ min-width: 0;
939
+ }
940
+
941
+ .drawer-breadcrumb {
942
+ display: flex;
943
+ align-items: center;
944
+ gap: 6px;
945
+ font-size: 0.8rem;
946
+ color: var(--text-muted);
947
+ margin-bottom: 4px;
948
+ }
949
+
950
+ .drawer-breadcrumb-project {
951
+ color: var(--primary);
952
+ font-weight: 500;
953
+ }
954
+
955
+ .drawer-header h2 {
956
+ margin: 0;
957
+ font-size: 1.1rem;
958
+ font-weight: 600;
959
+ color: var(--text-main);
960
+ line-height: 1.3;
961
+ }
962
+
963
+ .drawer-header-actions {
964
+ display: flex;
965
+ align-items: center;
966
+ gap: 4px;
967
+ }
968
+
969
+ .action-btn {
970
+ background: none;
971
+ border: none;
972
+ cursor: pointer;
973
+ color: var(--text-muted);
974
+ padding: 6px;
975
+ border-radius: var(--radius-md);
976
+ display: flex;
977
+ align-items: center;
978
+ justify-content: center;
979
+ transition: all var(--transition-fast);
980
+ }
981
+
982
+ .action-btn:hover {
983
+ color: var(--text-main);
984
+ background-color: var(--hover-bg);
985
+ }
986
+
987
+ .close-btn {
988
+ background: none;
989
+ border: none;
990
+ cursor: pointer;
991
+ color: var(--text-muted);
992
+ padding: 6px;
993
+ border-radius: var(--radius-md);
994
+ display: flex;
995
+ align-items: center;
996
+ justify-content: center;
997
+ transition: all var(--transition-fast);
998
+ margin-left: 4px;
999
+ }
1000
+
1001
+ .close-btn:hover {
1002
+ color: var(--text-main);
1003
+ background-color: var(--hover-bg);
1004
+ }
1005
+
1006
+ .drawer-body {
1007
+ flex: 1;
1008
+ display: flex;
1009
+ overflow: hidden;
1010
+ }
1011
+
1012
+ .drawer-main {
1013
+ flex: 1;
1014
+ min-width: 0;
1015
+ overflow-y: auto;
1016
+ padding: var(--space-2);
1017
+ background: var(--surface);
1018
+ }
1019
+
1020
+ .drawer-sidebar {
1021
+ width: 300px;
1022
+ flex-shrink: 0;
1023
+ background: var(--sidebar-bg);
1024
+ border-left: 1px solid var(--border);
1025
+ overflow-y: auto;
1026
+ padding: var(--space-2);
1027
+ }
1028
+
1029
+ .sidebar-section {
1030
+ padding-bottom: var(--space-2);
1031
+ margin-bottom: var(--space-2);
1032
+ border-bottom: 1px solid var(--section-divider);
1033
+ }
1034
+
1035
+ .sidebar-section:last-child {
1036
+ border-bottom: none;
1037
+ margin-bottom: 0;
1038
+ padding-bottom: 0;
1039
+ }
1040
+
1041
+ .sidebar-label {
1042
+ font-size: 11px;
1043
+ font-weight: 700;
1044
+ color: var(--text-muted);
1045
+ text-transform: uppercase;
1046
+ letter-spacing: 0.05em;
1047
+ margin-bottom: 6px;
1048
+ }
1049
+
1050
+ .sidebar-value {
1051
+ font-size: 14px;
1052
+ color: var(--text-main);
1053
+ display: flex;
1054
+ align-items: center;
1055
+ gap: 8px;
1056
+ }
1057
+
1058
+ .sidebar-value svg {
1059
+ color: var(--text-muted);
1060
+ flex-shrink: 0;
1061
+ }
1062
+
1063
+ .drawer-footer {
1064
+ padding: var(--space-2);
1065
+ border-top: 1px solid var(--border);
1066
+ background: var(--sidebar-bg);
1067
+ flex-shrink: 0;
1068
+ }
1069
+
1070
+ .detail-section {
1071
+ margin-bottom: var(--space-3);
1072
+ padding-bottom: var(--space-3);
1073
+ border-bottom: 1px solid var(--section-divider);
1074
+ }
1075
+
1076
+ .detail-section:last-child {
1077
+ border-bottom: none;
1078
+ margin-bottom: 0;
1079
+ padding-bottom: 0;
1080
+ }
1081
+
1082
+ .detail-section h3 {
1083
+ margin: 0 0 var(--space-2) 0;
1084
+ font-size: 0.85rem;
1085
+ font-weight: 600;
1086
+ color: var(--text-main);
1087
+ text-transform: uppercase;
1088
+ letter-spacing: 0.04em;
1089
+ }
1090
+
1091
+ .main-content-section {
1092
+ padding-bottom: var(--space-2);
1093
+ margin-bottom: var(--space-2);
1094
+ border-bottom: 1px solid var(--section-divider);
1095
+ }
1096
+
1097
+ .main-content-section:last-child {
1098
+ border-bottom: none;
1099
+ margin-bottom: 0;
1100
+ padding-bottom: 0;
1101
+ }
1102
+
1103
+ .main-content-section h3 {
1104
+ margin: 0 0 var(--space-2) 0;
1105
+ font-size: 14px;
1106
+ font-weight: 600;
1107
+ color: var(--text-main);
1108
+ }
1109
+
1110
+ .meta-grid {
1111
+ display: none;
1112
+ }
1113
+
1114
+ .meta-item {
1115
+ display: none;
1116
+ }
1117
+
1118
+ .meta-label {
1119
+ display: none;
1120
+ }
1121
+
1122
+ .meta-value {
1123
+ display: none;
1124
+ }
1125
+
1126
+ .management-grid {
1127
+ display: none;
1128
+ }
1129
+
1130
+ .management-item {
1131
+ display: none;
1132
+ }
1133
+
1134
+ .status-sidebar {
1135
+ display: flex;
1136
+ flex-direction: column;
1137
+ gap: var(--space-1);
1138
+ }
1139
+
1140
+ .status-sidebar .status-badge {
1141
+ align-self: flex-start;
1142
+ margin-bottom: 6px;
1143
+ }
1144
+
1145
+ .transition-control {
1146
+ display: flex;
1147
+ gap: 6px;
1148
+ }
1149
+
1150
+ .transition-control .select-input {
1151
+ flex: 1;
1152
+ min-width: 0;
1153
+ padding: 6px 8px;
1154
+ font-size: 12px;
1155
+ }
1156
+
1157
+ .btn-sm {
1158
+ padding: 6px 12px;
1159
+ font-size: 12px;
1160
+ }
1161
+
1162
+ .assignee-sidebar {
1163
+ display: flex;
1164
+ flex-direction: column;
1165
+ gap: 6px;
1166
+ }
1167
+
1168
+ .assignee-sidebar .user-info {
1169
+ display: flex;
1170
+ align-items: center;
1171
+ gap: 8px;
1172
+ margin-bottom: 0;
1173
+ }
1174
+
1175
+ .assignee-sidebar .text-input {
1176
+ padding: 6px 10px;
1177
+ font-size: 12px;
1178
+ min-width: 0;
1179
+ width: 100%;
1180
+ }
1181
+
1182
+ .assignee-control-wrapper {
1183
+ position: relative;
1184
+ display: flex;
1185
+ flex-direction: column;
1186
+ gap: 6px;
1187
+ width: 100%;
1188
+ }
1189
+
1190
+ .assignee-suggestions-dropdown {
1191
+ position: absolute;
1192
+ top: 100%;
1193
+ left: 0;
1194
+ right: 0;
1195
+ background: var(--surface);
1196
+ border: 1px solid var(--primary);
1197
+ border-radius: var(--radius-md);
1198
+ box-shadow: var(--shadow-lg);
1199
+ max-height: 200px;
1200
+ overflow-y: auto;
1201
+ z-index: 1010;
1202
+ margin-top: 4px;
1203
+ animation: slideInDown 0.15s ease-out;
1204
+ }
1205
+
1206
+ @keyframes slideInDown {
1207
+ from { transform: translateY(-5px); opacity: 0; }
1208
+ to { transform: translateY(0); opacity: 1; }
1209
+ }
1210
+
1211
+ .assignee-suggestion-item {
1212
+ display: flex;
1213
+ align-items: center;
1214
+ gap: 8px;
1215
+ padding: 8px 10px;
1216
+ cursor: pointer;
1217
+ border-bottom: 1px solid var(--border);
1218
+ transition: background-color var(--transition-fast);
1219
+ }
1220
+
1221
+ .assignee-suggestion-item:last-child {
1222
+ border-bottom: none;
1223
+ }
1224
+
1225
+ .assignee-suggestion-item:hover {
1226
+ background-color: var(--primary-light);
1227
+ }
1228
+
1229
+ .assignee-suggestion-item .avatar.small {
1230
+ width: 24px;
1231
+ height: 24px;
1232
+ font-size: 0.65rem;
1233
+ }
1234
+
1235
+ .assignee-suggestion-item .user-name {
1236
+ font-size: 13px;
1237
+ color: var(--text-main);
1238
+ }
1239
+
1240
+ .assignee-actions {
1241
+ display: flex;
1242
+ gap: 6px;
1243
+ align-items: center;
1244
+ }
1245
+
1246
+ .assignee-actions .btn-primary {
1247
+ padding: 6px 12px;
1248
+ font-size: 12px;
1249
+ }
1250
+
1251
+ .assignee-actions .btn-secondary {
1252
+ padding: 6px 12px;
1253
+ font-size: 12px;
1254
+ }
1255
+
1256
+ .unassigned-text {
1257
+ color: var(--text-muted);
1258
+ font-style: italic;
1259
+ font-size: 13px;
1260
+ }
1261
+
1262
+ .user-info {
1263
+ display: flex;
1264
+ align-items: center;
1265
+ gap: 8px;
1266
+ }
1267
+
1268
+ .description-content {
1269
+ padding: var(--space-2);
1270
+ background: var(--sidebar-bg);
1271
+ border-radius: var(--radius-md);
1272
+ font-size: 14px;
1273
+ line-height: 1.6;
1274
+ }
1275
+
1276
+ .description-content img {
1277
+ max-width: 100%;
1278
+ height: auto;
1279
+ border-radius: var(--radius-sm);
1280
+ }
1281
+
1282
+ .subtask-list,
1283
+ .linked-list {
1284
+ display: flex;
1285
+ flex-direction: column;
1286
+ gap: 6px;
1287
+ }
1288
+
1289
+ .subtask-item,
1290
+ .linked-item {
1291
+ display: flex;
1292
+ align-items: center;
1293
+ gap: var(--space-1);
1294
+ padding: 10px;
1295
+ background: var(--sidebar-bg);
1296
+ border: 1px solid var(--border);
1297
+ border-radius: var(--radius-md);
1298
+ font-size: 13px;
1299
+ cursor: pointer;
1300
+ transition: all var(--transition-fast);
1301
+ }
1302
+
1303
+ .subtask-item:hover,
1304
+ .linked-item:hover {
1305
+ border-color: var(--primary);
1306
+ box-shadow: var(--shadow-sm);
1307
+ }
1308
+
1309
+ .subtask-item .link-type,
1310
+ .linked-item .link-type {
1311
+ font-style: italic;
1312
+ color: var(--text-muted);
1313
+ font-size: 11px;
1314
+ min-width: 60px;
1315
+ }
1316
+
1317
+ .subtask-item .issue-key,
1318
+ .linked-item .issue-key {
1319
+ font-weight: 600;
1320
+ font-size: 12px;
1321
+ color: var(--primary);
1322
+ }
1323
+
1324
+ .subtask-item .summary,
1325
+ .linked-item .summary {
1326
+ flex: 1;
1327
+ overflow: hidden;
1328
+ text-overflow: ellipsis;
1329
+ white-space: nowrap;
1330
+ }
1331
+
1332
+ .attachments-list {
1333
+ display: flex;
1334
+ flex-direction: column;
1335
+ gap: 6px;
1336
+ margin-bottom: var(--space-2);
1337
+ }
1338
+
1339
+ .attachment-item {
1340
+ display: flex;
1341
+ align-items: center;
1342
+ gap: 8px;
1343
+ padding: 8px 10px;
1344
+ background: var(--sidebar-bg);
1345
+ border-radius: var(--radius-sm);
1346
+ font-size: 13px;
1347
+ }
1348
+
1349
+ .attachment-item a {
1350
+ flex: 1;
1351
+ color: var(--primary);
1352
+ text-decoration: none;
1353
+ overflow: hidden;
1354
+ text-overflow: ellipsis;
1355
+ white-space: nowrap;
1356
+ }
1357
+
1358
+ .attachment-item a:hover {
1359
+ text-decoration: underline;
1360
+ }
1361
+
1362
+ .attachment-item .size {
1363
+ color: var(--text-muted);
1364
+ font-size: 11px;
1365
+ }
1366
+
1367
+ .upload-zone {
1368
+ padding: var(--space-2);
1369
+ border: 2px dashed var(--border);
1370
+ border-radius: var(--radius-md);
1371
+ background: var(--sidebar-bg);
1372
+ text-align: center;
1373
+ transition: all var(--transition-fast);
1374
+ }
1375
+
1376
+ .upload-zone:hover {
1377
+ border-color: var(--primary);
1378
+ background: var(--primary-light);
1379
+ }
1380
+
1381
+ .upload-zone input[type="file"] {
1382
+ margin-bottom: 6px;
1383
+ }
1384
+
1385
+ .upload-message {
1386
+ margin-top: 8px;
1387
+ font-size: 12px;
1388
+ }
1389
+
1390
+ .upload-message.success {
1391
+ color: #00875a;
1392
+ }
1393
+
1394
+ .upload-message.error {
1395
+ color: #de350b;
1396
+ }
1397
+
1398
+ .comments-list {
1399
+ display: flex;
1400
+ flex-direction: column;
1401
+ gap: var(--space-2);
1402
+ }
1403
+
1404
+ .comment-item {
1405
+ padding: var(--space-2);
1406
+ background: var(--surface);
1407
+ border: 1px solid var(--border);
1408
+ border-radius: var(--radius-md);
1409
+ box-shadow: var(--shadow-comment);
1410
+ }
1411
+
1412
+ .comment-header {
1413
+ display: flex;
1414
+ align-items: center;
1415
+ gap: 8px;
1416
+ margin-bottom: 8px;
1417
+ }
1418
+
1419
+ .comment-author {
1420
+ font-weight: 600;
1421
+ font-size: 13px;
1422
+ }
1423
+
1424
+ .comment-date {
1425
+ font-size: 11px;
1426
+ color: var(--text-muted);
1427
+ }
1428
+
1429
+ .comment-body {
1430
+ font-size: 14px;
1431
+ line-height: 1.5;
1432
+ white-space: pre-wrap;
1433
+ }
1434
+
1435
+ .comment-body img {
1436
+ max-width: 100%;
1437
+ height: auto;
1438
+ border-radius: var(--radius-sm);
1439
+ }
1440
+
1441
+ .comment-composer {
1442
+ display: flex;
1443
+ flex-direction: column;
1444
+ gap: 8px;
1445
+ padding: 16px;
1446
+ background: var(--sidebar-bg);
1447
+ border-radius: var(--radius-md);
1448
+ border: 1px solid var(--border);
1449
+ }
1450
+
1451
+ .comment-composer .btn-primary {
1452
+ align-self: flex-end;
1453
+ }
1454
+
1455
+ .comment-box {
1456
+ width: 100%;
1457
+ min-height: 80px;
1458
+ padding: 10px 12px;
1459
+ border: 1px solid var(--border);
1460
+ border-radius: var(--radius-md);
1461
+ resize: vertical;
1462
+ font-family: inherit;
1463
+ font-size: 14px;
1464
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
1465
+ background: var(--surface);
1466
+ }
1467
+
1468
+ .comment-box:focus {
1469
+ outline: none;
1470
+ border-color: var(--primary);
1471
+ box-shadow: 0 0 0 3px var(--primary-light);
1472
+ }
1473
+
1474
+ .sidebar-labels {
1475
+ display: flex;
1476
+ flex-wrap: wrap;
1477
+ gap: 6px;
1478
+ }
1479
+
1480
+ .label-tag {
1481
+ background: #e9ebf0;
1482
+ color: #42526e;
1483
+ padding: 4px 10px;
1484
+ border-radius: var(--radius-pill);
1485
+ font-size: 12px;
1486
+ display: inline-flex;
1487
+ align-items: center;
1488
+ gap: 6px;
1489
+ font-weight: 500;
1490
+ }
1491
+
1492
+ .label-remove {
1493
+ cursor: pointer;
1494
+ display: flex;
1495
+ align-items: center;
1496
+ color: #6b778c;
1497
+ transition: color var(--transition-fast);
1498
+ background: none;
1499
+ border: none;
1500
+ padding: 0;
1501
+ }
1502
+
1503
+ .label-remove:hover {
1504
+ color: #de350b;
1505
+ }
1506
+
1507
+ .add-label-wrapper {
1508
+ display: flex;
1509
+ align-items: center;
1510
+ gap: 6px;
1511
+ }
1512
+
1513
+ .add-label-input {
1514
+ border: 1px dashed var(--border);
1515
+ background: transparent;
1516
+ padding: 4px 8px;
1517
+ font-size: 12px;
1518
+ border-radius: var(--radius-pill);
1519
+ width: 100px;
1520
+ outline: none;
1521
+ transition: all var(--transition-fast);
1522
+ }
1523
+
1524
+ .add-label-input:focus {
1525
+ border-style: solid;
1526
+ border-color: var(--primary);
1527
+ width: 140px;
1528
+ background: white;
1529
+ }
1530
+
1531
+ .label-suggestions-dropdown {
1532
+ position: absolute;
1533
+ top: 100%;
1534
+ left: 0;
1535
+ width: 180px;
1536
+ max-height: 200px;
1537
+ overflow-y: auto;
1538
+ background: white;
1539
+ border: 1px solid var(--border);
1540
+ border-radius: var(--radius-md);
1541
+ box-shadow: var(--shadow-lg);
1542
+ z-index: 1000;
1543
+ margin-top: 4px;
1544
+ }
1545
+
1546
+ .label-suggestion-item {
1547
+ padding: 8px 10px;
1548
+ cursor: pointer;
1549
+ font-size: 12px;
1550
+ color: #42526e;
1551
+ border-bottom: 1px solid var(--border);
1552
+ text-align: left;
1553
+ transition: all 0.2s;
1554
+ }
1555
+
1556
+ .label-suggestion-item:last-child {
1557
+ border-bottom: none;
1558
+ }
1559
+
1560
+ .label-suggestion-item:hover {
1561
+ background: var(--hover-bg);
1562
+ color: var(--primary);
1563
+ }
1564
+
1565
+ .version-select {
1566
+ width: 100%;
1567
+ padding: 6px 8px;
1568
+ border-radius: var(--radius-sm);
1569
+ border: 1px solid var(--border);
1570
+ background: white;
1571
+ font-size: 12px;
1572
+ }
1573
+
1574
+ .version-select:hover {
1575
+ border-color: var(--primary);
1576
+ }
1577
+
1578
+ .sidebar-date {
1579
+ font-size: 13px;
1580
+ color: var(--text-main);
1581
+ display: flex;
1582
+ align-items: center;
1583
+ gap: 8px;
1584
+ }
1585
+
1586
+ .sidebar-date svg {
1587
+ color: var(--text-muted);
1588
+ }
1589
+
1590
+ .btn-primary {
1591
+ background: var(--primary);
1592
+ color: white;
1593
+ border: none;
1594
+ padding: 0.625rem 1.25rem;
1595
+ border-radius: var(--radius-md);
1596
+ cursor: pointer;
1597
+ font-weight: 500;
1598
+ font-size: 0.95rem;
1599
+ display: inline-flex;
1600
+ align-items: center;
1601
+ justify-content: center;
1602
+ gap: 0.5rem;
1603
+ transition: all var(--transition-fast);
1604
+ }
1605
+
1606
+ .btn-primary:hover {
1607
+ background: var(--primary-hover);
1608
+ }
1609
+
1610
+ .btn-primary:focus {
1611
+ outline: none;
1612
+ box-shadow: 0 0 0 3px var(--primary-light);
1613
+ }
1614
+
1615
+ .btn-primary:disabled {
1616
+ opacity: 0.6;
1617
+ cursor: not-allowed;
1618
+ }
1619
+
1620
+ .btn-primary .spinner {
1621
+ animation: spin 1s linear infinite;
1622
+ }
1623
+
1624
+ @keyframes spin {
1625
+ from { transform: rotate(0deg); }
1626
+ to { transform: rotate(360deg); }
1627
+ }
1628
+
1629
+ .inline-spinner {
1630
+ display: inline-block;
1631
+ width: 12px;
1632
+ height: 12px;
1633
+ border: 2px solid currentColor;
1634
+ border-right-color: transparent;
1635
+ border-radius: 50%;
1636
+ animation: spin 0.6s linear infinite;
1637
+ margin-left: 0.375rem;
1638
+ opacity: 0.7;
1639
+ vertical-align: middle;
1640
+ }
1641
+
1642
+ .btn-secondary {
1643
+ background: var(--surface);
1644
+ color: var(--text-main);
1645
+ border: 2px solid var(--border);
1646
+ padding: 0.625rem 1.25rem;
1647
+ border-radius: var(--radius-md);
1648
+ cursor: pointer;
1649
+ font-weight: 500;
1650
+ font-size: 0.95rem;
1651
+ transition: all var(--transition-fast);
1652
+ }
1653
+
1654
+ .btn-secondary:hover {
1655
+ background: var(--hover-bg);
1656
+ border-color: var(--text-muted);
1657
+ }
1658
+
1659
+ .btn-icon {
1660
+ background: none;
1661
+ border: none;
1662
+ padding: 0.5rem;
1663
+ border-radius: var(--radius-md);
1664
+ cursor: pointer;
1665
+ color: var(--text-muted);
1666
+ display: inline-flex;
1667
+ align-items: center;
1668
+ justify-content: center;
1669
+ transition: all var(--transition-fast);
1670
+ }
1671
+
1672
+ .btn-icon:hover {
1673
+ color: var(--text-main);
1674
+ background-color: var(--hover-bg);
1675
+ }
1676
+
1677
+ .clickable-row {
1678
+ cursor: pointer;
1679
+ }
1680
+
1681
+ .modal-overlay {
1682
+ position: fixed;
1683
+ top: 0; left: 0; right: 0; bottom: 0;
1684
+ background: rgba(9, 30, 66, 0.5);
1685
+ backdrop-filter: blur(4px);
1686
+ z-index: 100;
1687
+ display: flex;
1688
+ align-items: center;
1689
+ justify-content: center;
1690
+ padding: 1rem;
1691
+ animation: fadeIn 0.2s ease-out;
1692
+ }
1693
+
1694
+ .modal {
1695
+ width: 540px;
1696
+ background: var(--surface);
1697
+ border-radius: var(--radius-lg);
1698
+ box-shadow: var(--shadow-lg);
1699
+ display: flex;
1700
+ flex-direction: column;
1701
+ max-width: 90vw;
1702
+ max-height: 90vh;
1703
+ animation: modalSlideIn 0.3s ease-out;
1704
+ }
1705
+
1706
+ @keyframes modalSlideIn {
1707
+ from {
1708
+ opacity: 0;
1709
+ transform: scale(0.95) translateY(-10px);
1710
+ }
1711
+ to {
1712
+ opacity: 1;
1713
+ transform: scale(1) translateY(0);
1714
+ }
1715
+ }
1716
+
1717
+ .modal-header {
1718
+ padding: 1.5rem;
1719
+ border-bottom: 1px solid var(--border);
1720
+ display: flex;
1721
+ justify-content: space-between;
1722
+ align-items: center;
1723
+ }
1724
+
1725
+ .modal-header h2 {
1726
+ margin: 0;
1727
+ font-size: 1.25rem;
1728
+ font-weight: 600;
1729
+ }
1730
+
1731
+ .modal-body {
1732
+ padding: 1.5rem;
1733
+ overflow-y: auto;
1734
+ flex: 1;
1735
+ }
1736
+
1737
+ .modal-footer {
1738
+ padding: 1.5rem;
1739
+ border-top: 1px solid var(--border);
1740
+ display: flex;
1741
+ justify-content: flex-end;
1742
+ gap: 0.75rem;
1743
+ background: #fafbfc;
1744
+ border-radius: 0 0 var(--radius-lg) var(--radius-lg);
1745
+ }
1746
+
1747
+ .modal-footer .btn-secondary {
1748
+ padding: 0.625rem 1.25rem;
1749
+ }
1750
+
1751
+ .toast-container {
1752
+ position: fixed;
1753
+ bottom: 1.5rem;
1754
+ right: 1.5rem;
1755
+ z-index: 200;
1756
+ display: flex;
1757
+ flex-direction: column;
1758
+ gap: 0.75rem;
1759
+ }
1760
+
1761
+ .toast {
1762
+ padding: 1rem 1.25rem;
1763
+ border-radius: var(--radius-md);
1764
+ background: var(--text-main);
1765
+ color: white;
1766
+ font-size: 0.9rem;
1767
+ font-weight: 500;
1768
+ box-shadow: var(--shadow-lg);
1769
+ display: flex;
1770
+ align-items: center;
1771
+ gap: 0.75rem;
1772
+ animation: toastSlideIn 0.3s ease-out;
1773
+ max-width: 360px;
1774
+ }
1775
+
1776
+ @keyframes toastSlideIn {
1777
+ from {
1778
+ opacity: 0;
1779
+ transform: translateX(100%);
1780
+ }
1781
+ to {
1782
+ opacity: 1;
1783
+ transform: translateX(0);
1784
+ }
1785
+ }
1786
+
1787
+ .toast.success {
1788
+ background: #00875a;
1789
+ }
1790
+
1791
+ .toast.error {
1792
+ background: #de350b;
1793
+ }
1794
+
1795
+ .toast.info {
1796
+ background: var(--primary);
1797
+ }
1798
+
1799
+ .toast-close {
1800
+ margin-left: auto;
1801
+ background: none;
1802
+ border: none;
1803
+ color: white;
1804
+ cursor: pointer;
1805
+ padding: 0.25rem;
1806
+ opacity: 0.8;
1807
+ transition: opacity var(--transition-fast);
1808
+ }
1809
+
1810
+ .toast-close:hover {
1811
+ opacity: 1;
1812
+ }
1813
+
1814
+ @media (max-width: 768px) {
1815
+ .dashboard-container {
1816
+ padding: 1rem;
1817
+ }
1818
+
1819
+ .header {
1820
+ flex-direction: column;
1821
+ align-items: flex-start;
1822
+ gap: 1rem;
1823
+ }
1824
+
1825
+ .controls {
1826
+ flex-direction: column;
1827
+ }
1828
+
1829
+ .controls-main {
1830
+ flex-direction: column;
1831
+ width: 100%;
1832
+ }
1833
+
1834
+ .input-group {
1835
+ width: 100%;
1836
+ min-width: 0;
1837
+ }
1838
+
1839
+ .text-input, .select-input {
1840
+ width: 100%;
1841
+ min-width: 0;
1842
+ }
1843
+
1844
+ .search-input-wrapper {
1845
+ width: 100%;
1846
+ }
1847
+
1848
+ .meta-grid {
1849
+ display: none;
1850
+ }
1851
+
1852
+ .drawer {
1853
+ width: calc(100vw - 2rem);
1854
+ max-height: 100vh;
1855
+ border-radius: var(--radius-lg);
1856
+ }
1857
+
1858
+ .drawer.expanded {
1859
+ width: calc(100vw - 1rem);
1860
+ height: calc(100vh - 1rem);
1861
+ border-radius: var(--radius-lg);
1862
+ }
1863
+
1864
+ .drawer-body {
1865
+ flex-direction: column;
1866
+ }
1867
+
1868
+ .drawer.expanded .drawer-body {
1869
+ flex-direction: row;
1870
+ }
1871
+
1872
+ .drawer.expanded .drawer-sidebar {
1873
+ width: 280px;
1874
+ }
1875
+
1876
+ .drawer-sidebar {
1877
+ width: 100%;
1878
+ border-left: none;
1879
+ border-top: 1px solid var(--border);
1880
+ }
1881
+
1882
+ .modal {
1883
+ width: 100%;
1884
+ max-height: 100vh;
1885
+ border-radius: 0;
1886
+ }
1887
+
1888
+ .keyboard-hint {
1889
+ display: none;
1890
+ }
1891
+ }
1892
+
1893
+ /* Standalone Issue Page - Full Width */
1894
+ .standalone-page {
1895
+ min-height: 100vh;
1896
+ background: var(--bg-color);
1897
+ padding: 8px;
1898
+ }
1899
+
1900
+ .standalone-issue-container {
1901
+ height: calc(100vh - 16px);
1902
+ background: var(--surface);
1903
+ border-radius: var(--radius-lg);
1904
+ box-shadow: var(--shadow-md);
1905
+ overflow: hidden;
1906
+ display: flex;
1907
+ flex-direction: column;
1908
+ }
1909
+
1910
+ .standalone-header {
1911
+ padding: 8px 16px;
1912
+ border-bottom: 1px solid var(--border);
1913
+ display: flex;
1914
+ justify-content: space-between;
1915
+ align-items: center;
1916
+ background: var(--surface);
1917
+ flex-shrink: 0;
1918
+ }
1919
+
1920
+ .standalone-back-btn {
1921
+ display: flex;
1922
+ align-items: center;
1923
+ gap: 4px;
1924
+ color: var(--text-muted);
1925
+ text-decoration: none;
1926
+ font-size: 12px;
1927
+ padding: 4px 8px;
1928
+ border-radius: var(--radius-sm);
1929
+ transition: all var(--transition-fast);
1930
+ }
1931
+
1932
+ .standalone-back-btn:hover {
1933
+ color: var(--primary);
1934
+ background: var(--hover-bg);
1935
+ }
1936
+
1937
+ .standalone-issue-container .drawer {
1938
+ width: 100%;
1939
+ max-width: none;
1940
+ height: 100%;
1941
+ max-height: none;
1942
+ border-radius: 0;
1943
+ box-shadow: none;
1944
+ flex: 1;
1945
+ }
1946
+
1947
+ .standalone-issue-container .drawer-body {
1948
+ flex: 1;
1949
+ }
1950
+
1951
+ .standalone-issue-container .drawer-main {
1952
+ padding: var(--space-2);
1953
+ }
1954
+
1955
+ .standalone-issue-container .drawer-sidebar {
1956
+ padding: var(--space-2);
1957
+ }
1958
+
1959
+ .standalone-issue-container .drawer-header {
1960
+ padding: 8px 16px;
1961
+ }
1962
+
1963
+ .standalone-issue-container .drawer-footer {
1964
+ display: none;
1965
+ }
1966
+
1967
+ .standalone-toast-container {
1968
+ position: fixed;
1969
+ bottom: var(--space-3);
1970
+ right: var(--space-3);
1971
+ z-index: 200;
1972
+ display: flex;
1973
+ flex-direction: column;
1974
+ gap: var(--space-1);
1975
+ }
1976
+
1977
+ .standalone-toast {
1978
+ padding: 12px 16px;
1979
+ border-radius: var(--radius-md);
1980
+ background: var(--text-main);
1981
+ color: white;
1982
+ font-size: 14px;
1983
+ font-weight: 500;
1984
+ box-shadow: var(--shadow-lg);
1985
+ display: flex;
1986
+ align-items: center;
1987
+ gap: 10px;
1988
+ animation: toastSlideIn 0.3s ease-out;
1989
+ max-width: 360px;
1990
+ }
1991
+
1992
+ .standalone-toast.success {
1993
+ background: #00875a;
1994
+ }
1995
+
1996
+ .standalone-toast.error {
1997
+ background: #de350b;
1998
+ }
1999
+
2000
+ .standalone-toast.info {
2001
+ background: var(--primary);
2002
+ }
2003
+
2004
+ .error-boundary-container {
2005
+ display: flex;
2006
+ flex-direction: column;
2007
+ align-items: center;
2008
+ justify-content: center;
2009
+ min-height: 100vh;
2010
+ padding: 2rem;
2011
+ text-align: center;
2012
+ background: var(--bg-color);
2013
+ }
2014
+
2015
+ .error-boundary-icon {
2016
+ color: #de350b;
2017
+ margin-bottom: 1.5rem;
2018
+ }
2019
+
2020
+ .error-boundary-title {
2021
+ font-size: 1.5rem;
2022
+ font-weight: 600;
2023
+ color: var(--text-main);
2024
+ margin: 0 0 1rem;
2025
+ }
2026
+
2027
+ .error-boundary-message {
2028
+ color: #de350b;
2029
+ margin: 0 0 0.5rem;
2030
+ font-size: 0.95rem;
2031
+ }
2032
+
2033
+ .error-boundary-stack {
2034
+ background: var(--surface);
2035
+ border: 1px solid var(--border);
2036
+ border-radius: var(--radius-md);
2037
+ padding: 1rem;
2038
+ font-size: 0.75rem;
2039
+ color: var(--text-muted);
2040
+ text-align: left;
2041
+ max-width: 100%;
2042
+ overflow-x: auto;
2043
+ margin: 0.5rem 0 1.5rem;
2044
+ max-height: 300px;
2045
+ overflow-y: auto;
2046
+ }
2047
+
2048
+ .error-boundary-fallback {
2049
+ color: var(--text-muted);
2050
+ margin: 0 0 1.5rem;
2051
+ }
2052
+
2053
+ .error-boundary-reload {
2054
+ display: flex;
2055
+ align-items: center;
2056
+ gap: 0.5rem;
2057
+ padding: 0.625rem 1.25rem;
2058
+ background: var(--primary);
2059
+ color: white;
2060
+ border: none;
2061
+ border-radius: var(--radius-md);
2062
+ font-size: 0.95rem;
2063
+ font-weight: 500;
2064
+ cursor: pointer;
2065
+ transition: background var(--transition-fast);
2066
+ }
2067
+
2068
+ .error-boundary-reload:hover {
2069
+ background: var(--primary-hover);
2070
+ }