elspais 0.9.3__py3-none-any.whl → 0.11.1__py3-none-any.whl

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 (73) hide show
  1. elspais/cli.py +141 -10
  2. elspais/commands/hash_cmd.py +72 -26
  3. elspais/commands/reformat_cmd.py +458 -0
  4. elspais/commands/trace.py +157 -3
  5. elspais/commands/validate.py +44 -16
  6. elspais/core/models.py +2 -0
  7. elspais/core/parser.py +68 -24
  8. elspais/reformat/__init__.py +50 -0
  9. elspais/reformat/detector.py +119 -0
  10. elspais/reformat/hierarchy.py +246 -0
  11. elspais/reformat/line_breaks.py +220 -0
  12. elspais/reformat/prompts.py +123 -0
  13. elspais/reformat/transformer.py +264 -0
  14. elspais/sponsors/__init__.py +432 -0
  15. elspais/trace_view/__init__.py +54 -0
  16. elspais/trace_view/coverage.py +183 -0
  17. elspais/trace_view/generators/__init__.py +12 -0
  18. elspais/trace_view/generators/base.py +329 -0
  19. elspais/trace_view/generators/csv.py +122 -0
  20. elspais/trace_view/generators/markdown.py +175 -0
  21. elspais/trace_view/html/__init__.py +31 -0
  22. elspais/trace_view/html/generator.py +1006 -0
  23. elspais/trace_view/html/templates/base.html +283 -0
  24. elspais/trace_view/html/templates/components/code_viewer_modal.html +14 -0
  25. elspais/trace_view/html/templates/components/file_picker_modal.html +20 -0
  26. elspais/trace_view/html/templates/components/legend_modal.html +69 -0
  27. elspais/trace_view/html/templates/components/review_panel.html +118 -0
  28. elspais/trace_view/html/templates/partials/review/help/help-panel.json +244 -0
  29. elspais/trace_view/html/templates/partials/review/help/onboarding.json +77 -0
  30. elspais/trace_view/html/templates/partials/review/help/tooltips.json +237 -0
  31. elspais/trace_view/html/templates/partials/review/review-comments.js +928 -0
  32. elspais/trace_view/html/templates/partials/review/review-data.js +961 -0
  33. elspais/trace_view/html/templates/partials/review/review-help.js +679 -0
  34. elspais/trace_view/html/templates/partials/review/review-init.js +177 -0
  35. elspais/trace_view/html/templates/partials/review/review-line-numbers.js +429 -0
  36. elspais/trace_view/html/templates/partials/review/review-packages.js +1029 -0
  37. elspais/trace_view/html/templates/partials/review/review-position.js +540 -0
  38. elspais/trace_view/html/templates/partials/review/review-resize.js +115 -0
  39. elspais/trace_view/html/templates/partials/review/review-status.js +659 -0
  40. elspais/trace_view/html/templates/partials/review/review-sync.js +992 -0
  41. elspais/trace_view/html/templates/partials/review-styles.css +2238 -0
  42. elspais/trace_view/html/templates/partials/scripts.js +1741 -0
  43. elspais/trace_view/html/templates/partials/styles.css +1756 -0
  44. elspais/trace_view/models.py +353 -0
  45. elspais/trace_view/review/__init__.py +60 -0
  46. elspais/trace_view/review/branches.py +1149 -0
  47. elspais/trace_view/review/models.py +1205 -0
  48. elspais/trace_view/review/position.py +609 -0
  49. elspais/trace_view/review/server.py +1056 -0
  50. elspais/trace_view/review/status.py +470 -0
  51. elspais/trace_view/review/storage.py +1367 -0
  52. elspais/trace_view/scanning.py +213 -0
  53. elspais/trace_view/specs/README.md +84 -0
  54. elspais/trace_view/specs/tv-d00001-template-architecture.md +36 -0
  55. elspais/trace_view/specs/tv-d00002-css-extraction.md +37 -0
  56. elspais/trace_view/specs/tv-d00003-js-extraction.md +43 -0
  57. elspais/trace_view/specs/tv-d00004-build-embedding.md +40 -0
  58. elspais/trace_view/specs/tv-d00005-test-format.md +78 -0
  59. elspais/trace_view/specs/tv-d00010-review-data-models.md +33 -0
  60. elspais/trace_view/specs/tv-d00011-review-storage.md +33 -0
  61. elspais/trace_view/specs/tv-d00012-position-resolution.md +33 -0
  62. elspais/trace_view/specs/tv-d00013-git-branches.md +31 -0
  63. elspais/trace_view/specs/tv-d00014-review-api-server.md +31 -0
  64. elspais/trace_view/specs/tv-d00015-status-modifier.md +27 -0
  65. elspais/trace_view/specs/tv-d00016-js-integration.md +33 -0
  66. elspais/trace_view/specs/tv-p00001-html-generator.md +33 -0
  67. elspais/trace_view/specs/tv-p00002-review-system.md +29 -0
  68. {elspais-0.9.3.dist-info → elspais-0.11.1.dist-info}/METADATA +36 -18
  69. elspais-0.11.1.dist-info/RECORD +101 -0
  70. elspais-0.9.3.dist-info/RECORD +0 -40
  71. {elspais-0.9.3.dist-info → elspais-0.11.1.dist-info}/WHEEL +0 -0
  72. {elspais-0.9.3.dist-info → elspais-0.11.1.dist-info}/entry_points.txt +0 -0
  73. {elspais-0.9.3.dist-info → elspais-0.11.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,2238 @@
1
+ /* IMPLEMENTS REQUIREMENTS:
2
+ * REQ-tv-d00016: Review JavaScript Integration
3
+ *
4
+ * Spec Review System Styles
5
+ * Ported from feature-spec-reviews branch
6
+ */
7
+
8
+
9
+ /* ============================================
10
+ Spec Review System Styles
11
+ ============================================ */
12
+
13
+ /* Review mode toggle */
14
+ .review-mode-toggle {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 8px;
18
+ margin-left: 16px;
19
+ }
20
+
21
+ .review-mode-toggle label {
22
+ font-weight: 500;
23
+ color: var(--text-secondary, #666);
24
+ }
25
+
26
+ .review-mode-toggle input[type="checkbox"] {
27
+ width: 20px;
28
+ height: 20px;
29
+ cursor: pointer;
30
+ }
31
+
32
+ /* ============================================
33
+ 3-Column Layout for Review Mode
34
+ ============================================ */
35
+
36
+ /* Review column base class (REQ-d00092) */
37
+ .review-column {
38
+ display: flex;
39
+ flex-direction: column;
40
+ width: 350px;
41
+ min-width: 250px;
42
+ max-width: 50vw;
43
+ height: 100vh;
44
+ overflow: hidden;
45
+ position: relative;
46
+ background: #fff;
47
+ border-left: 1px solid #dee2e6;
48
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
49
+ }
50
+
51
+ /* Review Column Hidden State (REQ-d00092) */
52
+ .review-column.hidden {
53
+ display: none !important;
54
+ }
55
+
56
+ /* Review Resize Handle (REQ-d00092) */
57
+ .review-resize-handle {
58
+ position: absolute;
59
+ left: 0;
60
+ top: 0;
61
+ bottom: 0;
62
+ width: 4px;
63
+ cursor: col-resize;
64
+ background: transparent;
65
+ transition: background-color 0.2s;
66
+ z-index: 10;
67
+ }
68
+
69
+ .review-resize-handle:hover {
70
+ background-color: #1976d2;
71
+ }
72
+
73
+ /* Review mode active: show review panel as third column */
74
+ body.review-mode-active .app-layout {
75
+ display: flex;
76
+ }
77
+
78
+ body.review-mode-active .main-content {
79
+ flex: 1;
80
+ min-width: 0;
81
+ }
82
+
83
+ /* Review panel column styling */
84
+ body.review-mode-active .review-panel {
85
+ width: 380px;
86
+ min-width: 300px;
87
+ max-width: 500px;
88
+ border-left: 1px solid #dee2e6;
89
+ background: #fff;
90
+ flex-shrink: 0;
91
+ overflow-y: auto;
92
+ height: 100vh;
93
+ }
94
+
95
+ /* Hidden state for review panel */
96
+ .review-panel.hidden {
97
+ display: none;
98
+ }
99
+
100
+ /* Mode Toggle Group Container (REQ-d00092) */
101
+ .mode-toggle-group {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 4px;
105
+ }
106
+
107
+ /* Mode toggle button styles (REQ-d00092) */
108
+ .mode-toggle-btn {
109
+ position: relative;
110
+ padding: 6px 12px;
111
+ border: 1px solid #ddd;
112
+ border-radius: 4px;
113
+ background: #f8f9fa;
114
+ color: #333;
115
+ cursor: pointer;
116
+ font-size: 13px;
117
+ transition: all 0.2s;
118
+ }
119
+
120
+ .mode-toggle-btn:hover {
121
+ background: #e9ecef;
122
+ border-color: #0066cc;
123
+ }
124
+
125
+ .mode-toggle-btn.active {
126
+ background: #0066cc;
127
+ color: #fff;
128
+ border-color: #0066cc;
129
+ }
130
+
131
+ .mode-toggle-btn.active:hover {
132
+ background: #0052a3;
133
+ }
134
+
135
+ /* ============================================
136
+ Packages Panel
137
+ ============================================ */
138
+
139
+ .rs-packages-panel {
140
+ background: #f8f9fa;
141
+ border: 1px solid #dee2e6;
142
+ border-radius: 4px;
143
+ margin-bottom: 16px;
144
+ padding: 12px;
145
+ }
146
+
147
+ .rs-packages-header {
148
+ display: flex;
149
+ justify-content: space-between;
150
+ align-items: center;
151
+ margin-bottom: 10px;
152
+ }
153
+
154
+ .rs-packages-title {
155
+ font-weight: 600;
156
+ font-size: 14px;
157
+ color: #2c3e50;
158
+ }
159
+
160
+ .rs-packages-actions {
161
+ display: flex;
162
+ gap: 8px;
163
+ }
164
+
165
+ .rs-packages-list {
166
+ display: flex;
167
+ flex-wrap: wrap;
168
+ gap: 8px;
169
+ }
170
+
171
+ .rs-no-packages {
172
+ color: #6c757d;
173
+ font-size: 13px;
174
+ font-style: italic;
175
+ }
176
+
177
+ .rs-package-item {
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 6px;
181
+ padding: 6px 10px;
182
+ background: #fff;
183
+ border: 1px solid #dee2e6;
184
+ border-radius: 4px;
185
+ font-size: 13px;
186
+ }
187
+
188
+ .rs-package-item.active {
189
+ border-color: #0066cc;
190
+ background: #e7f0ff;
191
+ }
192
+
193
+ .rs-package-item .package-name {
194
+ font-weight: 500;
195
+ }
196
+
197
+ .rs-package-item .package-stats {
198
+ font-size: 11px;
199
+ color: #6c757d;
200
+ }
201
+
202
+ .btn-small {
203
+ padding: 4px 10px;
204
+ font-size: 12px;
205
+ }
206
+
207
+ /* Review badge on requirements */
208
+ .rs-has-comments {
209
+ border-left: 3px solid var(--primary-color, #0066cc);
210
+ }
211
+
212
+ .rs-req-badges {
213
+ display: inline-flex;
214
+ gap: 4px;
215
+ margin-left: 8px;
216
+ }
217
+
218
+ .rs-badge {
219
+ display: inline-block;
220
+ padding: 2px 6px;
221
+ border-radius: 3px;
222
+ font-size: 11px;
223
+ font-weight: 500;
224
+ }
225
+
226
+ .rs-badge-flagged {
227
+ background: #fff3cd;
228
+ color: #856404;
229
+ }
230
+
231
+ .rs-badge-comments {
232
+ background: #d1ecf1;
233
+ color: #0c5460;
234
+ }
235
+
236
+ .rs-badge-pending {
237
+ background: #f8d7da;
238
+ color: #721c24;
239
+ }
240
+
241
+ .rs-badge-resolved {
242
+ background: #d4edda;
243
+ color: #155724;
244
+ }
245
+
246
+ /* Position highlighting */
247
+ .rs-highlight-exact {
248
+ background-color: rgba(255, 235, 59, 0.3);
249
+ border-bottom: 2px solid #ffc107;
250
+ }
251
+
252
+ .rs-highlight-approximate {
253
+ background-color: rgba(255, 193, 7, 0.2);
254
+ border-bottom: 2px dashed #ffc107;
255
+ }
256
+
257
+ .rs-highlight-unanchored {
258
+ background-color: rgba(158, 158, 158, 0.1);
259
+ }
260
+
261
+ .rs-highlight-active {
262
+ background-color: rgba(33, 150, 243, 0.3) !important;
263
+ border-bottom: 2px solid #2196f3 !important;
264
+ }
265
+
266
+ /* Position Confidence Classes (REQ-d00092, REQ-d00087) */
267
+ .rs-confidence-exact {
268
+ color: #2e7d32;
269
+ font-weight: 600;
270
+ }
271
+
272
+ .rs-confidence-approximate {
273
+ color: #f57c00;
274
+ font-weight: 500;
275
+ }
276
+
277
+ .rs-confidence-unanchored {
278
+ color: #757575;
279
+ font-style: italic;
280
+ }
281
+
282
+ /* Position label active state (REQ-d00092: Click-to-Highlight) */
283
+ .rs-position-label.rs-position-active {
284
+ background: #e3f2fd;
285
+ border-color: #1976d2;
286
+ font-weight: 600;
287
+ }
288
+
289
+ /* Card-level highlight for GENERAL position (REQ-d00092) */
290
+ .rs-card-highlight {
291
+ outline: 2px solid #1976d2;
292
+ outline-offset: 2px;
293
+ }
294
+
295
+ /* Review Panel Combined View (REQ-d00092) */
296
+ .review-panel-combined {
297
+ display: flex;
298
+ flex-direction: column;
299
+ gap: 16px;
300
+ padding: 12px;
301
+ }
302
+
303
+ /* Section Header (REQ-d00092) */
304
+ .rs-section-header {
305
+ display: flex;
306
+ justify-content: space-between;
307
+ align-items: center;
308
+ padding: 8px 12px;
309
+ border-bottom: 1px solid var(--border-color, #ddd);
310
+ background: var(--bg-secondary, #f8f9fa);
311
+ }
312
+
313
+ .rs-section-header h4 {
314
+ margin: 0;
315
+ font-size: 14px;
316
+ font-weight: 600;
317
+ color: var(--text-primary, #333);
318
+ }
319
+
320
+ /* Section Divider (REQ-d00092) */
321
+ .rs-section-divider {
322
+ height: 1px;
323
+ background: var(--border-color, #dee2e6);
324
+ margin: 0;
325
+ }
326
+
327
+ /* Thread list */
328
+ .rs-thread-list {
329
+ border: 1px solid var(--border-color, #ddd);
330
+ border-radius: 4px;
331
+ margin: 16px 0;
332
+ background: var(--bg-secondary, #f8f9fa);
333
+ }
334
+
335
+ .rs-thread-list-header {
336
+ display: flex;
337
+ justify-content: space-between;
338
+ align-items: center;
339
+ padding: 12px;
340
+ border-bottom: 1px solid var(--border-color, #ddd);
341
+ background: var(--bg-tertiary, #e9ecef);
342
+ }
343
+
344
+ .rs-thread-list-header h4 {
345
+ margin: 0;
346
+ font-size: 14px;
347
+ }
348
+
349
+ .rs-thread-list-content {
350
+ padding: 8px;
351
+ }
352
+
353
+ .rs-no-threads {
354
+ color: var(--text-muted, #999);
355
+ text-align: center;
356
+ padding: 16px;
357
+ font-style: italic;
358
+ }
359
+
360
+ /* Thread */
361
+ .rs-thread {
362
+ background: var(--bg-primary, #fff);
363
+ border: 1px solid var(--border-color, #ddd);
364
+ border-radius: 4px;
365
+ margin-bottom: 8px;
366
+ }
367
+
368
+ .rs-thread-resolved {
369
+ opacity: 0.7;
370
+ }
371
+
372
+ .rs-thread-resolved .rs-thread-header {
373
+ background: #d4edda;
374
+ }
375
+
376
+ .rs-thread-header {
377
+ display: flex;
378
+ justify-content: space-between;
379
+ align-items: center;
380
+ padding: 8px 12px;
381
+ background: var(--bg-secondary, #f8f9fa);
382
+ border-bottom: 1px solid var(--border-color, #eee);
383
+ }
384
+
385
+ .rs-thread-meta {
386
+ display: flex;
387
+ align-items: center;
388
+ gap: 8px;
389
+ font-size: 12px;
390
+ }
391
+
392
+ .rs-position-label {
393
+ font-weight: 600;
394
+ color: var(--primary-color, #0066cc);
395
+ cursor: pointer;
396
+ }
397
+
398
+ .rs-position-label:hover {
399
+ text-decoration: underline;
400
+ }
401
+
402
+ .rs-author {
403
+ font-weight: 600;
404
+ }
405
+
406
+ .rs-time {
407
+ color: var(--text-muted, #999);
408
+ }
409
+
410
+ .rs-position-indicator {
411
+ font-size: 14px;
412
+ }
413
+
414
+ .rs-thread-actions {
415
+ display: flex;
416
+ gap: 4px;
417
+ }
418
+
419
+ .rs-thread-body {
420
+ padding: 12px;
421
+ }
422
+
423
+ /* Comment */
424
+ .rs-comment {
425
+ padding: 8px 0;
426
+ border-bottom: 1px solid var(--border-color, #eee);
427
+ }
428
+
429
+ .rs-comment:last-child {
430
+ border-bottom: none;
431
+ }
432
+
433
+ .rs-comment-header {
434
+ font-size: 12px;
435
+ margin-bottom: 4px;
436
+ }
437
+
438
+ .rs-comment-body {
439
+ font-size: 14px;
440
+ line-height: 1.5;
441
+ }
442
+
443
+ .rs-comment-body code {
444
+ background: var(--bg-code, #f4f4f4);
445
+ padding: 2px 4px;
446
+ border-radius: 2px;
447
+ }
448
+
449
+ /* Reply form */
450
+ .rs-reply-form {
451
+ margin-top: 12px;
452
+ padding-top: 12px;
453
+ border-top: 1px solid var(--border-color, #eee);
454
+ }
455
+
456
+ .rs-reply-input {
457
+ width: 100%;
458
+ min-height: 60px;
459
+ padding: 8px;
460
+ border: 1px solid var(--border-color, #ddd);
461
+ border-radius: 4px;
462
+ font-size: 14px;
463
+ resize: vertical;
464
+ }
465
+
466
+ .rs-reply-actions {
467
+ margin-top: 8px;
468
+ display: flex;
469
+ gap: 8px;
470
+ }
471
+
472
+ /* New comment form */
473
+ .rs-new-comment-form {
474
+ background: var(--bg-primary, #fff);
475
+ border: 1px solid var(--primary-color, #0066cc);
476
+ border-radius: 4px;
477
+ padding: 16px;
478
+ margin-bottom: 16px;
479
+ }
480
+
481
+ .rs-new-comment-form h4 {
482
+ margin: 0 0 12px 0;
483
+ color: var(--primary-color, #0066cc);
484
+ }
485
+
486
+ .rs-form-group {
487
+ margin-bottom: 12px;
488
+ }
489
+
490
+ .rs-form-group label {
491
+ display: block;
492
+ font-weight: 500;
493
+ margin-bottom: 4px;
494
+ font-size: 12px;
495
+ }
496
+
497
+ .rs-form-group select,
498
+ .rs-form-group input,
499
+ .rs-form-group textarea {
500
+ width: 100%;
501
+ padding: 8px;
502
+ border: 1px solid var(--border-color, #ddd);
503
+ border-radius: 4px;
504
+ font-size: 14px;
505
+ }
506
+
507
+ .rs-position-options {
508
+ background: var(--bg-secondary, #f8f9fa);
509
+ padding: 12px;
510
+ border-radius: 4px;
511
+ margin: 8px 0;
512
+ }
513
+
514
+ .rs-form-actions {
515
+ display: flex;
516
+ gap: 8px;
517
+ margin-top: 12px;
518
+ }
519
+
520
+ /* Status panel */
521
+ .rs-status-panel {
522
+ border: 1px solid var(--border-color, #ddd);
523
+ border-radius: 4px;
524
+ margin: 16px 0;
525
+ }
526
+
527
+ .rs-status-header {
528
+ display: flex;
529
+ justify-content: space-between;
530
+ align-items: center;
531
+ padding: 12px;
532
+ border-bottom: 1px solid var(--border-color, #ddd);
533
+ background: var(--bg-tertiary, #e9ecef);
534
+ }
535
+
536
+ .rs-status-content {
537
+ padding: 12px;
538
+ }
539
+
540
+ .rs-status-actions {
541
+ padding: 12px;
542
+ border-top: 1px solid var(--border-color, #ddd);
543
+ }
544
+
545
+ /* Quick actions for status toggle */
546
+ .rs-quick-actions {
547
+ padding: 12px;
548
+ background: var(--bg-secondary, #f8f9fa);
549
+ border-bottom: 1px solid var(--border-color, #ddd);
550
+ display: flex;
551
+ gap: 8px;
552
+ }
553
+
554
+ .rs-quick-toggle {
555
+ flex: 1;
556
+ }
557
+
558
+ /* Clickable status badges in review mode */
559
+ body.review-mode-active .status-badge.status-draft {
560
+ cursor: pointer;
561
+ transition: opacity 0.2s;
562
+ }
563
+
564
+ body.review-mode-active .status-badge.status-draft:hover {
565
+ opacity: 0.8;
566
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
567
+ }
568
+
569
+ /* Request card */
570
+ .rs-request-card {
571
+ background: var(--bg-primary, #fff);
572
+ border: 1px solid var(--border-color, #ddd);
573
+ border-radius: 4px;
574
+ padding: 12px;
575
+ margin-bottom: 8px;
576
+ }
577
+
578
+ .rs-request-header {
579
+ display: flex;
580
+ justify-content: space-between;
581
+ align-items: center;
582
+ margin-bottom: 8px;
583
+ }
584
+
585
+ .rs-request-transition {
586
+ font-weight: 600;
587
+ }
588
+
589
+ .rs-request-state {
590
+ text-transform: uppercase;
591
+ font-size: 10px;
592
+ }
593
+
594
+ .rs-badge-pending { background: #fff3cd; color: #856404; }
595
+ .rs-badge-approved { background: #d4edda; color: #155724; }
596
+ .rs-badge-rejected { background: #f8d7da; color: #721c24; }
597
+ .rs-badge-applied { background: #cce5ff; color: #004085; }
598
+
599
+ .rs-request-meta {
600
+ font-size: 12px;
601
+ color: var(--text-muted, #666);
602
+ margin-bottom: 8px;
603
+ }
604
+
605
+ .rs-request-justification {
606
+ padding: 8px;
607
+ background: var(--bg-secondary, #f8f9fa);
608
+ border-radius: 4px;
609
+ margin-bottom: 8px;
610
+ }
611
+
612
+ .rs-approval-progress {
613
+ display: flex;
614
+ align-items: center;
615
+ gap: 8px;
616
+ margin-bottom: 8px;
617
+ }
618
+
619
+ .rs-progress-bar {
620
+ flex: 1;
621
+ height: 8px;
622
+ background: var(--bg-tertiary, #e9ecef);
623
+ border-radius: 4px;
624
+ overflow: hidden;
625
+ }
626
+
627
+ .rs-progress-fill {
628
+ height: 100%;
629
+ background: var(--success-color, #28a745);
630
+ transition: width 0.3s;
631
+ }
632
+
633
+ .rs-progress-label {
634
+ font-size: 12px;
635
+ color: var(--text-muted, #666);
636
+ }
637
+
638
+ .rs-approvers {
639
+ display: flex;
640
+ flex-wrap: wrap;
641
+ gap: 4px;
642
+ }
643
+
644
+ .rs-approver {
645
+ padding: 2px 6px;
646
+ border-radius: 3px;
647
+ font-size: 11px;
648
+ }
649
+
650
+ .rs-approver-pending { background: #f8f9fa; color: #666; }
651
+ .rs-approver-approved { background: #d4edda; color: #155724; }
652
+ .rs-approver-rejected { background: #f8d7da; color: #721c24; }
653
+
654
+ .rs-approval-actions {
655
+ display: flex;
656
+ gap: 8px;
657
+ align-items: center;
658
+ margin-top: 8px;
659
+ padding-top: 8px;
660
+ border-top: 1px solid var(--border-color, #eee);
661
+ }
662
+
663
+ .rs-approval-comment {
664
+ flex: 1;
665
+ padding: 4px 8px;
666
+ border: 1px solid var(--border-color, #ddd);
667
+ border-radius: 4px;
668
+ }
669
+
670
+ /* Buttons */
671
+ .rs-btn {
672
+ display: inline-block;
673
+ padding: 6px 12px;
674
+ border: 1px solid transparent;
675
+ border-radius: 4px;
676
+ font-size: 13px;
677
+ cursor: pointer;
678
+ background: var(--bg-secondary, #f8f9fa);
679
+ color: var(--text-primary, #333);
680
+ }
681
+
682
+ .rs-btn:hover {
683
+ background: var(--bg-tertiary, #e9ecef);
684
+ }
685
+
686
+ .rs-btn-sm {
687
+ padding: 4px 8px;
688
+ font-size: 11px;
689
+ }
690
+
691
+ .rs-btn-primary {
692
+ background: #0066cc !important;
693
+ color: #fff !important;
694
+ border-color: #0066cc !important;
695
+ }
696
+
697
+ .rs-btn-primary:hover {
698
+ background: #0052a3;
699
+ }
700
+
701
+ .rs-btn-secondary {
702
+ background: var(--bg-secondary, #6c757d);
703
+ color: #fff;
704
+ }
705
+
706
+ .rs-btn-success {
707
+ background: var(--success-color, #28a745);
708
+ color: #fff;
709
+ }
710
+
711
+ .rs-btn-danger {
712
+ background: var(--danger-color, #dc3545);
713
+ color: #fff;
714
+ }
715
+
716
+ .rs-btn-link {
717
+ background: transparent;
718
+ color: var(--primary-color, #0066cc);
719
+ }
720
+
721
+ /* Sync indicator */
722
+ .rs-sync-indicator {
723
+ position: fixed;
724
+ bottom: 16px;
725
+ right: 16px;
726
+ padding: 8px 16px;
727
+ border-radius: 4px;
728
+ background: #333;
729
+ color: #fff;
730
+ font-size: 12px;
731
+ z-index: 1000;
732
+ display: none;
733
+ }
734
+
735
+ .rs-sync-success { background: #28a745; }
736
+ .rs-sync-error { background: #dc3545; }
737
+
738
+ /* Conflict dialog */
739
+ .rs-conflict-overlay {
740
+ position: fixed;
741
+ inset: 0;
742
+ background: rgba(0, 0, 0, 0.5);
743
+ display: flex;
744
+ align-items: center;
745
+ justify-content: center;
746
+ z-index: 2000;
747
+ }
748
+
749
+ .rs-conflict-dialog {
750
+ background: #fff;
751
+ padding: 24px;
752
+ border-radius: 8px;
753
+ max-width: 400px;
754
+ text-align: center;
755
+ }
756
+
757
+ .rs-conflict-options {
758
+ display: flex;
759
+ gap: 8px;
760
+ justify-content: center;
761
+ margin-top: 16px;
762
+ }
763
+
764
+ /* Review panel - now in dedicated third column */
765
+ .review-panel {
766
+ padding: 16px;
767
+ height: 100%;
768
+ display: flex;
769
+ flex-direction: column;
770
+ }
771
+
772
+ .review-panel-header {
773
+ padding: 15px 16px;
774
+ margin: -16px -16px 16px -16px;
775
+ background: #f8f9fa;
776
+ border-bottom: 1px solid #dee2e6;
777
+ font-weight: 600;
778
+ font-size: 14px;
779
+ }
780
+
781
+ .review-panel-title {
782
+ color: #2c3e50;
783
+ }
784
+
785
+ .review-panel-req-header {
786
+ background: var(--primary-color, #0066cc);
787
+ color: #fff;
788
+ padding: 10px 12px;
789
+ margin: 0 -16px 16px -16px;
790
+ font-size: 14px;
791
+ font-weight: 600;
792
+ display: flex;
793
+ align-items: center;
794
+ gap: 8px;
795
+ }
796
+
797
+ .review-panel-req-header .req-id-badge {
798
+ background: rgba(255,255,255,0.2);
799
+ padding: 4px 8px;
800
+ border-radius: 4px;
801
+ font-family: monospace;
802
+ }
803
+
804
+ .review-panel-req-header .req-title-text {
805
+ flex: 1;
806
+ white-space: nowrap;
807
+ overflow: hidden;
808
+ text-overflow: ellipsis;
809
+ font-weight: 400;
810
+ opacity: 0.9;
811
+ }
812
+
813
+ .review-panel-no-selection {
814
+ text-align: center;
815
+ padding: 40px 20px;
816
+ color: var(--text-muted, #666);
817
+ }
818
+
819
+ .review-panel-no-selection .icon {
820
+ font-size: 48px;
821
+ margin-bottom: 16px;
822
+ opacity: 0.5;
823
+ }
824
+
825
+ .review-panel-no-selection p {
826
+ margin: 0 0 8px 0;
827
+ }
828
+
829
+ /* Status bar - compact inline display */
830
+ .rs-status-bar {
831
+ background: var(--bg-secondary, #f8f9fa);
832
+ border: 1px solid var(--border-color, #ddd);
833
+ border-radius: 4px;
834
+ padding: 8px 12px;
835
+ margin-bottom: 12px;
836
+ }
837
+
838
+ .rs-status-bar-content {
839
+ display: flex;
840
+ justify-content: space-between;
841
+ align-items: center;
842
+ gap: 8px;
843
+ }
844
+
845
+ .rs-status-bar-left {
846
+ display: flex;
847
+ align-items: center;
848
+ gap: 8px;
849
+ }
850
+
851
+ .rs-status-label {
852
+ font-size: 12px;
853
+ color: var(--text-muted, #666);
854
+ }
855
+
856
+ .rs-status-bar-right {
857
+ display: flex;
858
+ align-items: center;
859
+ gap: 4px;
860
+ }
861
+
862
+ .rs-status-bar .status-badge {
863
+ font-size: 11px;
864
+ padding: 2px 8px;
865
+ }
866
+
867
+ /* Status change dialog */
868
+ .rs-status-dialog {
869
+ background: var(--bg-primary, #fff);
870
+ border: 1px solid var(--primary-color, #0066cc);
871
+ border-radius: 4px;
872
+ margin-bottom: 12px;
873
+ overflow: hidden;
874
+ }
875
+
876
+ .rs-dialog-header {
877
+ display: flex;
878
+ justify-content: space-between;
879
+ align-items: center;
880
+ padding: 8px 12px;
881
+ background: var(--primary-color, #0066cc);
882
+ color: #fff;
883
+ font-weight: 500;
884
+ font-size: 13px;
885
+ }
886
+
887
+ .rs-dialog-close {
888
+ background: transparent;
889
+ border: none;
890
+ color: #fff;
891
+ font-size: 18px;
892
+ cursor: pointer;
893
+ padding: 0 4px;
894
+ line-height: 1;
895
+ }
896
+
897
+ .rs-dialog-close:hover {
898
+ opacity: 0.8;
899
+ }
900
+
901
+ .rs-dialog-content {
902
+ padding: 0;
903
+ }
904
+
905
+ .rs-dialog-content .rs-status-panel {
906
+ border: none;
907
+ margin: 0;
908
+ }
909
+
910
+ /* Comment highlight in REQ card */
911
+ .rs-comment-highlight {
912
+ background-color: rgba(255, 235, 59, 0.4) !important;
913
+ outline: 2px solid #ffc107;
914
+ outline-offset: -1px;
915
+ }
916
+
917
+ /* Comments section */
918
+ .rs-comments-section {
919
+ flex: 1;
920
+ }
921
+
922
+ .review-panel-content {
923
+ flex: 1;
924
+ overflow-y: auto;
925
+ min-height: 200px;
926
+ }
927
+
928
+ .review-panel-sections {
929
+ padding: 0 16px 16px 16px;
930
+ }
931
+
932
+ .rs-status-section {
933
+ margin-bottom: 16px;
934
+ padding-bottom: 16px;
935
+ border-bottom: 1px solid #dee2e6;
936
+ }
937
+
938
+ /* User selector */
939
+ .rs-user-selector {
940
+ margin-bottom: 16px;
941
+ }
942
+
943
+ .rs-user-selector label {
944
+ font-size: 12px;
945
+ font-weight: 500;
946
+ margin-right: 8px;
947
+ }
948
+
949
+ .rs-user-selector input {
950
+ padding: 6px 10px;
951
+ border: 1px solid var(--border-color, #ddd);
952
+ border-radius: 4px;
953
+ width: 150px;
954
+ }
955
+
956
+ /* Line numbers for requirement body */
957
+ .rs-line-numbers-container {
958
+ font-family: inherit;
959
+ font-size: 13px;
960
+ line-height: 1.6;
961
+ margin: 8px 0;
962
+ background: var(--bg-primary, #fff);
963
+ }
964
+
965
+ /* Use table layout for perfect line number alignment with wrapped text */
966
+ .rs-lines-table {
967
+ display: table;
968
+ width: 100%;
969
+ border-collapse: collapse;
970
+ }
971
+
972
+ .rs-line-row {
973
+ display: table-row;
974
+ }
975
+
976
+ .rs-line-row:hover {
977
+ background: rgba(0, 102, 204, 0.05);
978
+ }
979
+
980
+ .rs-line-row.selected {
981
+ background: rgba(255, 235, 59, 0.3);
982
+ }
983
+
984
+ .rs-line-number {
985
+ display: table-cell;
986
+ padding: 2px 8px 2px 6px;
987
+ text-align: right;
988
+ color: var(--text-muted, #999);
989
+ background: var(--bg-tertiary, #e9ecef);
990
+ border-right: 1px solid var(--border-color, #ddd);
991
+ user-select: none;
992
+ vertical-align: top; /* Align to top of wrapped content */
993
+ min-width: 28px;
994
+ width: 28px;
995
+ cursor: pointer;
996
+ font-size: 11px;
997
+ }
998
+
999
+ .rs-line-number:hover {
1000
+ background: rgba(0, 102, 204, 0.15);
1001
+ color: var(--primary-color, #0066cc);
1002
+ }
1003
+
1004
+ .rs-line-row.selected .rs-line-number {
1005
+ background: rgba(0, 102, 204, 0.2);
1006
+ color: var(--primary-color, #0066cc);
1007
+ font-weight: 600;
1008
+ }
1009
+
1010
+ .rs-line-text {
1011
+ display: table-cell;
1012
+ padding: 2px 10px;
1013
+ vertical-align: top;
1014
+ word-break: break-word;
1015
+ white-space: normal;
1016
+ }
1017
+
1018
+ /* Remove margins from rendered markdown elements inside line text */
1019
+ .rs-line-text p,
1020
+ .rs-line-text ul,
1021
+ .rs-line-text ol,
1022
+ .rs-line-text blockquote,
1023
+ .rs-line-text pre {
1024
+ margin: 0;
1025
+ padding: 0;
1026
+ }
1027
+
1028
+ .rs-line-text ul,
1029
+ .rs-line-text ol {
1030
+ padding-left: 1.5em;
1031
+ }
1032
+
1033
+ /* ============================================
1034
+ Markdown-it Line Numbers (via data-source-line)
1035
+ ============================================ */
1036
+
1037
+ /* Container for markdown with line numbers */
1038
+ .rs-markdown-with-lines {
1039
+ position: relative;
1040
+ padding-left: 45px; /* Space for line numbers */
1041
+ font-family: inherit; /* Use same font as rest of page */
1042
+ font-size: inherit;
1043
+ line-height: 1.5;
1044
+ }
1045
+
1046
+ /* Ensure markdown formatting is visible */
1047
+ .rs-markdown-with-lines strong,
1048
+ .rs-markdown-with-lines b {
1049
+ font-weight: 700;
1050
+ }
1051
+
1052
+ .rs-markdown-with-lines em,
1053
+ .rs-markdown-with-lines i {
1054
+ font-style: italic;
1055
+ }
1056
+
1057
+ .rs-markdown-with-lines code {
1058
+ background: rgba(0, 0, 0, 0.05);
1059
+ padding: 0.1em 0.3em;
1060
+ border-radius: 3px;
1061
+ font-family: monospace;
1062
+ font-size: 0.9em;
1063
+ }
1064
+
1065
+ .rs-markdown-with-lines a {
1066
+ color: var(--primary-color, #0066cc);
1067
+ text-decoration: none;
1068
+ }
1069
+
1070
+ .rs-markdown-with-lines a:hover {
1071
+ text-decoration: underline;
1072
+ }
1073
+
1074
+ /* Style all block elements with source line numbers */
1075
+ .rs-markdown-with-lines [data-source-line] {
1076
+ position: relative;
1077
+ min-height: 1.4em;
1078
+ }
1079
+
1080
+ /* Display line number via ::before pseudo-element */
1081
+ /* Uses data-display-line which is 1-based (converted from 0-based data-source-line via JS) */
1082
+ /* Uses --line-indent-offset to counteract nesting indentation and keep line numbers aligned */
1083
+ .rs-markdown-with-lines [data-display-line]::before {
1084
+ content: attr(data-display-line);
1085
+ position: absolute;
1086
+ left: calc(-45px - var(--line-indent-offset, 0px));
1087
+ width: 35px;
1088
+ text-align: right;
1089
+ padding-right: 8px;
1090
+ color: var(--text-muted, #999);
1091
+ font-size: 11px;
1092
+ font-family: monospace;
1093
+ user-select: none;
1094
+ border-right: 1px solid var(--border-color, #e0e0e0);
1095
+ }
1096
+
1097
+ /* Hover effect in review mode */
1098
+ .review-mode-active .rs-markdown-with-lines [data-source-line]:hover {
1099
+ background: rgba(0, 102, 204, 0.05);
1100
+ cursor: pointer;
1101
+ }
1102
+
1103
+ /* Selected line highlight */
1104
+ .rs-markdown-with-lines .rs-line-selected {
1105
+ background: rgba(255, 235, 59, 0.3) !important;
1106
+ outline: 2px solid #ffc107;
1107
+ outline-offset: -1px;
1108
+ }
1109
+
1110
+ /* Comment highlight on lines */
1111
+ .rs-markdown-with-lines .rs-comment-highlight {
1112
+ background: rgba(255, 235, 59, 0.4) !important;
1113
+ outline: 2px solid #ffc107;
1114
+ outline-offset: -1px;
1115
+ }
1116
+
1117
+ /* Markdown element spacing */
1118
+ .rs-markdown-with-lines p,
1119
+ .rs-markdown-with-lines blockquote {
1120
+ margin-top: 0.25em;
1121
+ margin-bottom: 0.25em;
1122
+ }
1123
+
1124
+ /* List styling - ensure bullets are visible */
1125
+ .rs-markdown-with-lines ul {
1126
+ list-style-type: disc;
1127
+ list-style-position: inside;
1128
+ margin: 0.25em 0;
1129
+ padding-left: 0;
1130
+ }
1131
+
1132
+ .rs-markdown-with-lines ol {
1133
+ list-style-type: decimal;
1134
+ list-style-position: inside;
1135
+ margin: 0.25em 0;
1136
+ padding-left: 0;
1137
+ }
1138
+
1139
+ .rs-markdown-with-lines li {
1140
+ display: list-item;
1141
+ margin: 0.1em 0;
1142
+ padding-left: 0.5em;
1143
+ }
1144
+
1145
+ /* Legacy line-row styles (for fallback) */
1146
+ .rs-line-row {
1147
+ cursor: text;
1148
+ }
1149
+
1150
+ /* Disable text selection in review mode for clean drag selection */
1151
+ .review-mode-active .rs-line-numbers-container {
1152
+ user-select: none;
1153
+ -webkit-user-select: none;
1154
+ -moz-user-select: none;
1155
+ -ms-user-select: none;
1156
+ }
1157
+
1158
+ .review-mode-active .rs-line-row {
1159
+ cursor: crosshair;
1160
+ }
1161
+
1162
+ .review-mode-active .rs-line-row:active {
1163
+ cursor: grabbing;
1164
+ }
1165
+
1166
+ /* Selected position indicator */
1167
+ .rs-selected-position {
1168
+ background: var(--bg-secondary, #f8f9fa);
1169
+ border: 1px solid var(--border-color, #ddd);
1170
+ border-radius: 4px;
1171
+ padding: 8px 12px;
1172
+ margin-bottom: 12px;
1173
+ font-size: 12px;
1174
+ display: flex;
1175
+ justify-content: space-between;
1176
+ align-items: center;
1177
+ }
1178
+
1179
+ .rs-selected-position .label {
1180
+ color: var(--text-muted, #666);
1181
+ }
1182
+
1183
+ .rs-selected-position .value {
1184
+ font-weight: 600;
1185
+ color: var(--primary-color, #0066cc);
1186
+ }
1187
+
1188
+ .rs-selected-position .clear-btn {
1189
+ background: none;
1190
+ border: none;
1191
+ color: var(--text-muted, #999);
1192
+ cursor: pointer;
1193
+ font-size: 16px;
1194
+ }
1195
+
1196
+ .rs-selected-position .clear-btn:hover {
1197
+ color: var(--danger-color, #dc3545);
1198
+ }
1199
+
1200
+ /* Line numbers in REQ card body (integrated view - always active) */
1201
+ .req-card-content.rs-with-line-numbers {
1202
+ padding: 0;
1203
+ }
1204
+
1205
+ .req-card-content.rs-with-line-numbers .rs-lines-table {
1206
+ margin: 0;
1207
+ border: none;
1208
+ border-radius: 0;
1209
+ max-height: none;
1210
+ }
1211
+
1212
+ /* Hint bar only shown in review mode (for line selection) */
1213
+ .rs-line-numbers-hint {
1214
+ display: none; /* Hidden by default */
1215
+ font-size: 11px;
1216
+ color: var(--text-muted, #888);
1217
+ padding: 4px 8px;
1218
+ background: var(--bg-tertiary, #e9ecef);
1219
+ border-bottom: 1px solid var(--border-color, #ddd);
1220
+ justify-content: space-between;
1221
+ align-items: center;
1222
+ }
1223
+
1224
+ .review-mode-active .rs-line-numbers-hint {
1225
+ display: flex; /* Show in review mode */
1226
+ }
1227
+
1228
+ .rs-line-numbers-hint .hint-text {
1229
+ font-style: italic;
1230
+ }
1231
+
1232
+ .rs-line-numbers-hint .selected-lines {
1233
+ font-weight: 600;
1234
+ color: var(--primary-color, #0066cc);
1235
+ }
1236
+
1237
+ /* ============================================
1238
+ Review Packages Panel
1239
+ ============================================ */
1240
+
1241
+ .review-packages-panel {
1242
+ background: var(--bg-primary, #fff);
1243
+ border: 1px solid var(--border-color, #ddd);
1244
+ border-radius: 8px;
1245
+ margin-bottom: 16px;
1246
+ display: none; /* Hidden until review mode is active */
1247
+ }
1248
+
1249
+ body.review-mode-active .review-packages-panel {
1250
+ display: block;
1251
+ }
1252
+
1253
+ .review-packages-panel.collapsed .packages-content {
1254
+ display: none;
1255
+ }
1256
+
1257
+ .packages-header {
1258
+ display: flex;
1259
+ align-items: center;
1260
+ gap: 8px;
1261
+ padding: 12px 16px;
1262
+ background: var(--bg-tertiary, #e9ecef);
1263
+ border-radius: 8px 8px 0 0;
1264
+ cursor: pointer;
1265
+ user-select: none;
1266
+ }
1267
+
1268
+ .review-packages-panel.collapsed .packages-header {
1269
+ border-radius: 8px;
1270
+ }
1271
+
1272
+ .packages-header .collapse-icon {
1273
+ font-size: 12px;
1274
+ color: var(--text-muted, #666);
1275
+ transition: transform 0.2s;
1276
+ }
1277
+
1278
+ .packages-header h3 {
1279
+ margin: 0;
1280
+ font-size: 14px;
1281
+ flex: 1;
1282
+ }
1283
+
1284
+ .packages-header .create-btn {
1285
+ padding: 4px 12px;
1286
+ font-size: 12px;
1287
+ background: #fff;
1288
+ color: #0066cc;
1289
+ border: 1px solid #0066cc;
1290
+ }
1291
+
1292
+ .packages-header .create-btn:hover {
1293
+ background: #f0f7ff;
1294
+ }
1295
+
1296
+ /* Filter toggle button in packages header */
1297
+ .rs-filter-toggle {
1298
+ padding: 4px 12px;
1299
+ font-size: 12px;
1300
+ background: var(--bg-secondary, #f0f0f0);
1301
+ border: 1px solid var(--border-color, #ddd);
1302
+ color: var(--text-secondary, #666);
1303
+ transition: all 0.2s;
1304
+ }
1305
+
1306
+ .rs-filter-toggle:hover {
1307
+ background: var(--bg-tertiary, #e9ecef);
1308
+ border-color: var(--primary, #0066cc);
1309
+ }
1310
+
1311
+ .rs-filter-toggle.active {
1312
+ background: var(--primary, #0066cc);
1313
+ color: white;
1314
+ border-color: var(--primary, #0066cc);
1315
+ }
1316
+
1317
+ .packages-content {
1318
+ padding: 12px;
1319
+ }
1320
+
1321
+ .package-list {
1322
+ display: flex;
1323
+ flex-direction: column;
1324
+ gap: 4px;
1325
+ }
1326
+
1327
+ .package-item {
1328
+ display: flex;
1329
+ align-items: center;
1330
+ gap: 8px;
1331
+ padding: 8px 12px;
1332
+ border-radius: 4px;
1333
+ cursor: pointer;
1334
+ background: var(--bg-secondary, #f8f9fa);
1335
+ transition: background 0.2s;
1336
+ }
1337
+
1338
+ .package-item:hover {
1339
+ background: var(--bg-tertiary, #e9ecef);
1340
+ }
1341
+
1342
+ .package-item.active {
1343
+ background: rgba(0, 102, 204, 0.1);
1344
+ border: 1px solid var(--primary-color, #0066cc);
1345
+ }
1346
+
1347
+ .package-item.default {
1348
+ font-style: italic;
1349
+ }
1350
+
1351
+ .package-item input[type="radio"] {
1352
+ margin: 0;
1353
+ flex-shrink: 0;
1354
+ }
1355
+
1356
+ .package-info {
1357
+ flex: 1;
1358
+ min-width: 0;
1359
+ display: flex;
1360
+ flex-direction: column;
1361
+ gap: 2px;
1362
+ }
1363
+
1364
+ .package-name {
1365
+ font-weight: 500;
1366
+ font-size: 13px;
1367
+ white-space: nowrap;
1368
+ overflow: hidden;
1369
+ text-overflow: ellipsis;
1370
+ }
1371
+
1372
+ .package-desc {
1373
+ font-size: 11px;
1374
+ color: var(--text-muted, #666);
1375
+ white-space: nowrap;
1376
+ overflow: hidden;
1377
+ text-overflow: ellipsis;
1378
+ }
1379
+
1380
+ .package-count {
1381
+ background: var(--bg-tertiary, #e9ecef);
1382
+ color: var(--text-secondary, #666);
1383
+ padding: 2px 8px;
1384
+ border-radius: 12px;
1385
+ font-size: 11px;
1386
+ font-weight: 600;
1387
+ flex-shrink: 0;
1388
+ }
1389
+
1390
+ .package-count::after {
1391
+ content: " REQs";
1392
+ }
1393
+
1394
+ .package-actions {
1395
+ display: flex;
1396
+ gap: 4px;
1397
+ opacity: 0;
1398
+ transition: opacity 0.2s;
1399
+ }
1400
+
1401
+ .package-item:hover .package-actions {
1402
+ opacity: 1;
1403
+ }
1404
+
1405
+ /* Package REQ list - expandable list of REQs in active package */
1406
+ .package-req-list {
1407
+ margin-top: 8px;
1408
+ padding-top: 8px;
1409
+ border-top: 1px solid var(--border-color, #e0e0e0);
1410
+ display: flex;
1411
+ flex-direction: column;
1412
+ gap: 4px;
1413
+ }
1414
+
1415
+ .package-req-item {
1416
+ display: flex;
1417
+ align-items: center;
1418
+ justify-content: space-between;
1419
+ padding: 4px 8px;
1420
+ background: var(--bg-secondary, #f5f5f5);
1421
+ border-radius: 4px;
1422
+ font-size: 12px;
1423
+ }
1424
+
1425
+ .package-req-id {
1426
+ color: var(--primary-color, #0066cc);
1427
+ cursor: pointer;
1428
+ font-family: var(--mono-font, 'JetBrains Mono', monospace);
1429
+ font-weight: 500;
1430
+ }
1431
+
1432
+ .package-req-id:hover {
1433
+ text-decoration: underline;
1434
+ }
1435
+
1436
+ .package-req-remove {
1437
+ padding: 2px 6px;
1438
+ font-size: 14px;
1439
+ line-height: 1;
1440
+ border-radius: 3px;
1441
+ opacity: 0.6;
1442
+ transition: opacity 0.2s;
1443
+ }
1444
+
1445
+ .package-req-item:hover .package-req-remove {
1446
+ opacity: 1;
1447
+ }
1448
+
1449
+ #packageFilterIndicator {
1450
+ display: none;
1451
+ margin-left: 8px;
1452
+ padding: 4px 8px;
1453
+ background: rgba(0, 102, 204, 0.1);
1454
+ border-radius: 4px;
1455
+ font-size: 12px;
1456
+ color: var(--primary-color, #0066cc);
1457
+ }
1458
+
1459
+ /* Package context styling (context selector, not filter) */
1460
+ body.review-mode-active [data-req-id].in-active-package {
1461
+ background: rgba(0, 102, 204, 0.08);
1462
+ border-left: 3px solid var(--primary-color, #0066cc);
1463
+ }
1464
+
1465
+ /* Toast notification - positioned near packages panel */
1466
+ .rs-toast {
1467
+ position: absolute;
1468
+ padding: 10px 16px;
1469
+ background: #1a73e8;
1470
+ color: white;
1471
+ border-radius: 6px;
1472
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1473
+ z-index: 10000;
1474
+ display: flex;
1475
+ align-items: center;
1476
+ gap: 10px;
1477
+ font-size: 13px;
1478
+ font-weight: 500;
1479
+ opacity: 0;
1480
+ transform: scale(0.9);
1481
+ transition: opacity 0.15s, transform 0.15s;
1482
+ pointer-events: none;
1483
+ white-space: nowrap;
1484
+ }
1485
+
1486
+ .rs-toast.visible {
1487
+ opacity: 1;
1488
+ transform: scale(1);
1489
+ pointer-events: auto;
1490
+ }
1491
+
1492
+ .rs-toast-spinner {
1493
+ width: 14px;
1494
+ height: 14px;
1495
+ border: 2px solid rgba(255, 255, 255, 0.3);
1496
+ border-top-color: white;
1497
+ border-radius: 50%;
1498
+ animation: rs-spin 0.8s linear infinite;
1499
+ }
1500
+
1501
+ @keyframes rs-spin {
1502
+ to { transform: rotate(360deg); }
1503
+ }
1504
+
1505
+ body.review-mode-active [data-req-id].in-other-package {
1506
+ opacity: 0.7;
1507
+ border-left: 3px solid #999;
1508
+ }
1509
+
1510
+ body.review-mode-active [data-req-id].in-other-package::after {
1511
+ content: "(other pkg)";
1512
+ font-size: 10px;
1513
+ color: #999;
1514
+ margin-left: 8px;
1515
+ }
1516
+
1517
+ /* Hide REQs not in active package when filtering */
1518
+ body.review-mode-active [data-req-id].package-filtered {
1519
+ display: none !important;
1520
+ }
1521
+
1522
+ body.review-mode-active [data-req-id].not-in-package {
1523
+ /* No special styling - normal appearance */
1524
+ }
1525
+
1526
+ /* Help System */
1527
+ .rs-help-btn {
1528
+ width: 28px;
1529
+ height: 28px;
1530
+ border-radius: 50%;
1531
+ font-weight: bold;
1532
+ background: #f5f5f5;
1533
+ border: 1px solid #ddd;
1534
+ }
1535
+
1536
+ .rs-help-btn:hover {
1537
+ background: #e3f2fd;
1538
+ border-color: #2196f3;
1539
+ }
1540
+
1541
+ .rs-help-indicator {
1542
+ display: inline-flex;
1543
+ align-items: center;
1544
+ justify-content: center;
1545
+ width: 16px;
1546
+ height: 16px;
1547
+ margin-left: 4px;
1548
+ font-size: 10px;
1549
+ border-radius: 50%;
1550
+ background: #e0e0e0;
1551
+ color: #616161;
1552
+ cursor: help;
1553
+ }
1554
+
1555
+ /* Help Menu Dropdown */
1556
+ .rs-help-menu-container {
1557
+ position: relative;
1558
+ display: inline-block;
1559
+ margin-left: 8px;
1560
+ }
1561
+
1562
+ .rs-help-menu-btn {
1563
+ display: inline-flex;
1564
+ align-items: center;
1565
+ gap: 6px;
1566
+ padding: 6px 12px;
1567
+ background: #0066cc;
1568
+ color: white;
1569
+ border: none;
1570
+ border-radius: 4px;
1571
+ font-size: 14px;
1572
+ cursor: pointer;
1573
+ transition: background 0.15s;
1574
+ }
1575
+
1576
+ .rs-help-menu-btn:hover {
1577
+ background: #0052a3;
1578
+ }
1579
+
1580
+ .rs-help-menu-btn .rs-menu-arrow {
1581
+ font-size: 10px;
1582
+ transition: transform 0.2s;
1583
+ }
1584
+
1585
+ .rs-help-menu-btn.open .rs-menu-arrow {
1586
+ transform: rotate(180deg);
1587
+ }
1588
+
1589
+ .rs-help-menu-dropdown {
1590
+ position: absolute;
1591
+ top: calc(100% + 4px);
1592
+ right: 0;
1593
+ background: white;
1594
+ border: 1px solid #ddd;
1595
+ border-radius: 6px;
1596
+ min-width: 220px;
1597
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1598
+ z-index: 1001;
1599
+ display: none;
1600
+ overflow: hidden;
1601
+ }
1602
+
1603
+ .rs-help-menu-dropdown.open {
1604
+ display: block;
1605
+ }
1606
+
1607
+ .rs-help-menu-section {
1608
+ padding: 4px 0;
1609
+ border-bottom: 1px solid #eee;
1610
+ }
1611
+
1612
+ .rs-help-menu-section:last-child {
1613
+ border-bottom: none;
1614
+ }
1615
+
1616
+ .rs-help-menu-section-label {
1617
+ padding: 6px 16px 4px;
1618
+ font-size: 11px;
1619
+ font-weight: 600;
1620
+ color: #888;
1621
+ text-transform: uppercase;
1622
+ letter-spacing: 0.5px;
1623
+ }
1624
+
1625
+ .rs-help-menu-item {
1626
+ display: flex;
1627
+ align-items: center;
1628
+ gap: 10px;
1629
+ padding: 10px 16px;
1630
+ color: #333;
1631
+ text-decoration: none;
1632
+ cursor: pointer;
1633
+ transition: background 0.1s;
1634
+ border: none;
1635
+ background: none;
1636
+ width: 100%;
1637
+ font-size: 14px;
1638
+ text-align: left;
1639
+ }
1640
+
1641
+ .rs-help-menu-item:hover {
1642
+ background: #f5f5f5;
1643
+ color: #0066cc;
1644
+ }
1645
+
1646
+ .rs-help-menu-item .rs-menu-icon {
1647
+ font-size: 16px;
1648
+ width: 20px;
1649
+ text-align: center;
1650
+ }
1651
+
1652
+ .rs-help-menu-item .rs-menu-label {
1653
+ flex: 1;
1654
+ }
1655
+
1656
+ .rs-help-menu-item .rs-menu-shortcut {
1657
+ font-size: 11px;
1658
+ color: #999;
1659
+ }
1660
+
1661
+ /* Help Panel */
1662
+ .rs-help-panel {
1663
+ position: fixed;
1664
+ right: 16px;
1665
+ top: 64px;
1666
+ width: 360px;
1667
+ max-height: calc(100vh - 80px);
1668
+ background: white;
1669
+ border: 1px solid #ddd;
1670
+ border-radius: 8px;
1671
+ box-shadow: 0 4px 16px rgba(0,0,0,0.15);
1672
+ z-index: 1000;
1673
+ display: flex;
1674
+ flex-direction: column;
1675
+ overflow: hidden;
1676
+ }
1677
+
1678
+ .rs-help-panel.hidden {
1679
+ display: none;
1680
+ }
1681
+
1682
+ .rs-help-panel-header {
1683
+ display: flex;
1684
+ justify-content: space-between;
1685
+ align-items: center;
1686
+ padding: 12px 16px;
1687
+ background: #f5f5f5;
1688
+ border-bottom: 1px solid #ddd;
1689
+ }
1690
+
1691
+ .rs-help-panel-header h3 {
1692
+ margin: 0;
1693
+ font-size: 1.1em;
1694
+ }
1695
+
1696
+ .rs-help-search {
1697
+ padding: 12px 16px;
1698
+ border-bottom: 1px solid #eee;
1699
+ }
1700
+
1701
+ .rs-help-search-input {
1702
+ width: 100%;
1703
+ padding: 8px 12px;
1704
+ border: 1px solid #ddd;
1705
+ border-radius: 4px;
1706
+ font-size: 0.9em;
1707
+ }
1708
+
1709
+ .rs-help-sections {
1710
+ flex: 1;
1711
+ overflow-y: auto;
1712
+ padding: 8px 0;
1713
+ }
1714
+
1715
+ .rs-help-section {
1716
+ border-bottom: 1px solid #eee;
1717
+ }
1718
+
1719
+ .rs-help-section:last-child {
1720
+ border-bottom: none;
1721
+ }
1722
+
1723
+ .rs-help-section-header {
1724
+ display: flex;
1725
+ justify-content: space-between;
1726
+ align-items: center;
1727
+ padding: 12px 16px;
1728
+ margin: 0;
1729
+ font-size: 0.95em;
1730
+ font-weight: 600;
1731
+ background: #fafafa;
1732
+ }
1733
+
1734
+ .rs-help-section-header:hover {
1735
+ background: #f0f0f0;
1736
+ }
1737
+
1738
+ .rs-help-section-content {
1739
+ padding: 0 16px 12px;
1740
+ }
1741
+
1742
+ .rs-help-item {
1743
+ margin-top: 12px;
1744
+ }
1745
+
1746
+ .rs-help-question {
1747
+ font-weight: 500;
1748
+ color: #1976d2;
1749
+ margin-bottom: 4px;
1750
+ }
1751
+
1752
+ .rs-help-answer {
1753
+ font-size: 0.9em;
1754
+ color: #555;
1755
+ line-height: 1.5;
1756
+ }
1757
+
1758
+ .rs-help-answer code {
1759
+ background: #f5f5f5;
1760
+ padding: 1px 4px;
1761
+ border-radius: 2px;
1762
+ font-size: 0.9em;
1763
+ }
1764
+
1765
+ .rs-help-footer {
1766
+ padding: 12px 16px;
1767
+ background: #f5f5f5;
1768
+ border-top: 1px solid #ddd;
1769
+ font-size: 0.85em;
1770
+ color: #666;
1771
+ }
1772
+
1773
+ .rs-help-links {
1774
+ margin-top: 8px;
1775
+ display: flex;
1776
+ gap: 12px;
1777
+ }
1778
+
1779
+ .rs-help-link {
1780
+ color: #1976d2;
1781
+ text-decoration: none;
1782
+ }
1783
+
1784
+ .rs-help-link:hover {
1785
+ text-decoration: underline;
1786
+ }
1787
+
1788
+ /* Onboarding Wizard */
1789
+ .rs-onboarding-overlay {
1790
+ position: fixed;
1791
+ inset: 0;
1792
+ background: rgba(0, 0, 0, 0.6);
1793
+ z-index: 2000;
1794
+ display: flex;
1795
+ align-items: center;
1796
+ justify-content: center;
1797
+ }
1798
+
1799
+ .rs-onboarding-modal {
1800
+ background: white;
1801
+ border-radius: 12px;
1802
+ padding: 24px;
1803
+ max-width: 480px;
1804
+ width: 90%;
1805
+ box-shadow: 0 8px 32px rgba(0,0,0,0.3);
1806
+ }
1807
+
1808
+ .rs-onboarding-header {
1809
+ display: flex;
1810
+ justify-content: space-between;
1811
+ align-items: center;
1812
+ margin-bottom: 16px;
1813
+ }
1814
+
1815
+ .rs-onboarding-step-indicator {
1816
+ font-size: 0.85em;
1817
+ color: #666;
1818
+ }
1819
+
1820
+ .rs-onboarding-title {
1821
+ margin: 0 0 12px;
1822
+ font-size: 1.3em;
1823
+ color: #333;
1824
+ }
1825
+
1826
+ .rs-onboarding-content {
1827
+ font-size: 0.95em;
1828
+ line-height: 1.6;
1829
+ color: #555;
1830
+ margin-bottom: 20px;
1831
+ }
1832
+
1833
+ .rs-onboarding-actions {
1834
+ display: flex;
1835
+ justify-content: flex-end;
1836
+ gap: 12px;
1837
+ }
1838
+
1839
+ .rs-onboarding-highlight {
1840
+ outline: 3px solid #1976d2 !important;
1841
+ outline-offset: 2px;
1842
+ position: relative;
1843
+ z-index: 1999;
1844
+ }
1845
+
1846
+ /* =============================================================================
1847
+ ARCHIVE STYLES (REQ-d00097, REQ-d00099)
1848
+ Package archival UI components and read-only mode styling
1849
+ ============================================================================= */
1850
+
1851
+ /* Archive Section in Packages Panel */
1852
+ .archive-section {
1853
+ margin-top: 16px;
1854
+ border-top: 1px solid #e0e0e0;
1855
+ padding-top: 12px;
1856
+ }
1857
+
1858
+ .archive-header {
1859
+ display: flex;
1860
+ align-items: center;
1861
+ gap: 8px;
1862
+ padding: 8px 12px;
1863
+ background: #f5f5f5;
1864
+ border-radius: 4px;
1865
+ cursor: pointer;
1866
+ user-select: none;
1867
+ transition: background-color 0.15s ease;
1868
+ }
1869
+
1870
+ .archive-header:hover {
1871
+ background: #eeeeee;
1872
+ }
1873
+
1874
+ .archive-header .collapse-icon {
1875
+ font-size: 10px;
1876
+ color: #666;
1877
+ transition: transform 0.2s ease;
1878
+ }
1879
+
1880
+ .archive-header.collapsed .collapse-icon {
1881
+ transform: rotate(-90deg);
1882
+ }
1883
+
1884
+ .archive-header h4 {
1885
+ margin: 0;
1886
+ font-size: 13px;
1887
+ font-weight: 600;
1888
+ color: #666;
1889
+ flex: 1;
1890
+ }
1891
+
1892
+ .archive-count {
1893
+ font-size: 11px;
1894
+ color: #999;
1895
+ background: #e0e0e0;
1896
+ padding: 2px 6px;
1897
+ border-radius: 10px;
1898
+ }
1899
+
1900
+ /* Archive List */
1901
+ .archive-list {
1902
+ max-height: 200px;
1903
+ overflow-y: auto;
1904
+ margin-top: 8px;
1905
+ }
1906
+
1907
+ .archive-list.collapsed {
1908
+ display: none;
1909
+ }
1910
+
1911
+ .archive-item {
1912
+ display: flex;
1913
+ align-items: center;
1914
+ gap: 8px;
1915
+ padding: 8px 12px;
1916
+ border-radius: 4px;
1917
+ cursor: pointer;
1918
+ transition: background-color 0.15s ease;
1919
+ }
1920
+
1921
+ .archive-item:hover {
1922
+ background: #f5f5f5;
1923
+ }
1924
+
1925
+ .archive-item-name {
1926
+ flex: 1;
1927
+ font-size: 13px;
1928
+ color: #555;
1929
+ white-space: nowrap;
1930
+ overflow: hidden;
1931
+ text-overflow: ellipsis;
1932
+ }
1933
+
1934
+ .archive-item-date {
1935
+ font-size: 11px;
1936
+ color: #999;
1937
+ }
1938
+
1939
+ .archive-item-reason {
1940
+ font-size: 10px;
1941
+ padding: 2px 6px;
1942
+ border-radius: 3px;
1943
+ text-transform: uppercase;
1944
+ font-weight: 500;
1945
+ }
1946
+
1947
+ /* Archive Reason Badges */
1948
+ .rs-badge-resolved {
1949
+ background: #e8f5e9;
1950
+ color: #2e7d32;
1951
+ }
1952
+
1953
+ .rs-badge-deleted {
1954
+ background: #fce4ec;
1955
+ color: #c62828;
1956
+ }
1957
+
1958
+ .rs-badge-manual {
1959
+ background: #e3f2fd;
1960
+ color: #1565c0;
1961
+ }
1962
+
1963
+ /* Archive Viewer Modal */
1964
+ .archive-viewer {
1965
+ position: fixed;
1966
+ top: 0;
1967
+ left: 0;
1968
+ right: 0;
1969
+ bottom: 0;
1970
+ background: rgba(0, 0, 0, 0.5);
1971
+ z-index: 2000;
1972
+ display: flex;
1973
+ align-items: center;
1974
+ justify-content: center;
1975
+ animation: fadeIn 0.2s ease;
1976
+ }
1977
+
1978
+ @keyframes fadeIn {
1979
+ from { opacity: 0; }
1980
+ to { opacity: 1; }
1981
+ }
1982
+
1983
+ .archive-viewer-content {
1984
+ background: #fff;
1985
+ border-radius: 8px;
1986
+ width: 90%;
1987
+ max-width: 800px;
1988
+ max-height: 85vh;
1989
+ display: flex;
1990
+ flex-direction: column;
1991
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
1992
+ animation: slideUp 0.2s ease;
1993
+ }
1994
+
1995
+ @keyframes slideUp {
1996
+ from {
1997
+ opacity: 0;
1998
+ transform: translateY(20px);
1999
+ }
2000
+ to {
2001
+ opacity: 1;
2002
+ transform: translateY(0);
2003
+ }
2004
+ }
2005
+
2006
+ .archive-viewer-header {
2007
+ display: flex;
2008
+ align-items: center;
2009
+ gap: 12px;
2010
+ padding: 16px 20px;
2011
+ border-bottom: 1px solid #e0e0e0;
2012
+ background: #fafafa;
2013
+ border-radius: 8px 8px 0 0;
2014
+ }
2015
+
2016
+ .archive-viewer-header h3 {
2017
+ margin: 0;
2018
+ font-size: 18px;
2019
+ color: #333;
2020
+ flex: 1;
2021
+ }
2022
+
2023
+ .archive-badge {
2024
+ background: #ff9800;
2025
+ color: white;
2026
+ font-size: 10px;
2027
+ font-weight: 600;
2028
+ padding: 3px 8px;
2029
+ border-radius: 3px;
2030
+ text-transform: uppercase;
2031
+ letter-spacing: 0.5px;
2032
+ }
2033
+
2034
+ .archive-viewer-close {
2035
+ background: none;
2036
+ border: none;
2037
+ font-size: 24px;
2038
+ color: #666;
2039
+ cursor: pointer;
2040
+ padding: 4px 8px;
2041
+ line-height: 1;
2042
+ border-radius: 4px;
2043
+ transition: all 0.15s ease;
2044
+ }
2045
+
2046
+ .archive-viewer-close:hover {
2047
+ background: #e0e0e0;
2048
+ color: #333;
2049
+ }
2050
+
2051
+ /* Archive Metadata Section */
2052
+ .archive-viewer-meta {
2053
+ padding: 16px 20px;
2054
+ background: #f9f9f9;
2055
+ border-bottom: 1px solid #e0e0e0;
2056
+ }
2057
+
2058
+ .archive-meta-row {
2059
+ display: flex;
2060
+ gap: 24px;
2061
+ margin-bottom: 8px;
2062
+ }
2063
+
2064
+ .archive-meta-row:last-child {
2065
+ margin-bottom: 0;
2066
+ }
2067
+
2068
+ .archive-meta-item {
2069
+ display: flex;
2070
+ align-items: baseline;
2071
+ gap: 8px;
2072
+ }
2073
+
2074
+ .archive-meta-label {
2075
+ font-size: 11px;
2076
+ text-transform: uppercase;
2077
+ color: #888;
2078
+ font-weight: 500;
2079
+ letter-spacing: 0.3px;
2080
+ }
2081
+
2082
+ .archive-meta-value {
2083
+ font-size: 13px;
2084
+ color: #333;
2085
+ }
2086
+
2087
+ .archive-meta-value.commit-hash {
2088
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
2089
+ font-size: 12px;
2090
+ background: #f0f0f0;
2091
+ padding: 2px 6px;
2092
+ border-radius: 3px;
2093
+ }
2094
+
2095
+ .archive-meta-warning {
2096
+ font-size: 11px;
2097
+ color: #ff9800;
2098
+ font-style: italic;
2099
+ }
2100
+
2101
+ /* Archive Viewer Body */
2102
+ .archive-viewer-body {
2103
+ flex: 1;
2104
+ overflow-y: auto;
2105
+ padding: 20px;
2106
+ }
2107
+
2108
+ .archive-viewer-section {
2109
+ margin-bottom: 24px;
2110
+ }
2111
+
2112
+ .archive-viewer-section:last-child {
2113
+ margin-bottom: 0;
2114
+ }
2115
+
2116
+ .archive-viewer-section h4 {
2117
+ margin: 0 0 12px;
2118
+ font-size: 14px;
2119
+ color: #666;
2120
+ text-transform: uppercase;
2121
+ letter-spacing: 0.5px;
2122
+ }
2123
+
2124
+ /* REQ List in Archive Viewer */
2125
+ .archive-req-list {
2126
+ display: flex;
2127
+ flex-wrap: wrap;
2128
+ gap: 8px;
2129
+ }
2130
+
2131
+ .archive-req-tag {
2132
+ background: #e3f2fd;
2133
+ color: #1565c0;
2134
+ font-size: 12px;
2135
+ padding: 4px 10px;
2136
+ border-radius: 4px;
2137
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
2138
+ }
2139
+
2140
+ /* Thread Summary in Archive Viewer */
2141
+ .archive-thread-summary {
2142
+ background: #f5f5f5;
2143
+ border-radius: 6px;
2144
+ padding: 12px 16px;
2145
+ margin-bottom: 12px;
2146
+ }
2147
+
2148
+ .archive-thread-summary:last-child {
2149
+ margin-bottom: 0;
2150
+ }
2151
+
2152
+ .archive-thread-header {
2153
+ display: flex;
2154
+ align-items: center;
2155
+ gap: 8px;
2156
+ margin-bottom: 8px;
2157
+ }
2158
+
2159
+ .archive-thread-req {
2160
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
2161
+ font-size: 12px;
2162
+ color: #1565c0;
2163
+ }
2164
+
2165
+ .archive-thread-status {
2166
+ font-size: 11px;
2167
+ padding: 2px 6px;
2168
+ border-radius: 3px;
2169
+ }
2170
+
2171
+ .archive-thread-status.resolved {
2172
+ background: #e8f5e9;
2173
+ color: #2e7d32;
2174
+ }
2175
+
2176
+ .archive-thread-status.open {
2177
+ background: #fff3e0;
2178
+ color: #ef6c00;
2179
+ }
2180
+
2181
+ .archive-thread-preview {
2182
+ font-size: 13px;
2183
+ color: #555;
2184
+ line-height: 1.5;
2185
+ }
2186
+
2187
+ .archive-thread-meta {
2188
+ margin-top: 8px;
2189
+ font-size: 11px;
2190
+ color: #888;
2191
+ }
2192
+
2193
+ /* Read-Only Mode Indicator */
2194
+ .rs-readonly-notice {
2195
+ display: inline-flex;
2196
+ align-items: center;
2197
+ gap: 4px;
2198
+ font-size: 11px;
2199
+ color: #ff9800;
2200
+ background: #fff3e0;
2201
+ padding: 4px 10px;
2202
+ border-radius: 4px;
2203
+ font-weight: 500;
2204
+ }
2205
+
2206
+ .rs-readonly-notice::before {
2207
+ content: '🔒';
2208
+ font-size: 10px;
2209
+ }
2210
+
2211
+ /* Archive Mode Thread Styling */
2212
+ .rs-archive-mode .rs-thread {
2213
+ opacity: 0.9;
2214
+ }
2215
+
2216
+ .rs-archive-mode .rs-thread-actions,
2217
+ .rs-archive-mode .rs-reply-form {
2218
+ display: none !important;
2219
+ }
2220
+
2221
+ .rs-archive-mode .rs-add-comment-btn {
2222
+ display: none;
2223
+ }
2224
+
2225
+ /* Empty Archive State */
2226
+ .archive-empty {
2227
+ text-align: center;
2228
+ padding: 24px;
2229
+ color: #888;
2230
+ font-size: 13px;
2231
+ }
2232
+
2233
+ .archive-empty-icon {
2234
+ font-size: 32px;
2235
+ margin-bottom: 8px;
2236
+ opacity: 0.5;
2237
+ }
2238
+