@ycniuqton/devlens 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +164 -0
  2. package/bin/devlens.js +2 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +205 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/init.d.ts +3 -0
  7. package/dist/init.js +239 -0
  8. package/dist/init.js.map +1 -0
  9. package/dist/routes/diff.d.ts +1 -0
  10. package/dist/routes/diff.js +39 -0
  11. package/dist/routes/diff.js.map +1 -0
  12. package/dist/routes/integrations.d.ts +1 -0
  13. package/dist/routes/integrations.js +132 -0
  14. package/dist/routes/integrations.js.map +1 -0
  15. package/dist/routes/rules.d.ts +1 -0
  16. package/dist/routes/rules.js +115 -0
  17. package/dist/routes/rules.js.map +1 -0
  18. package/dist/routes/tasks.d.ts +4 -0
  19. package/dist/routes/tasks.js +360 -0
  20. package/dist/routes/tasks.js.map +1 -0
  21. package/dist/server.d.ts +7 -0
  22. package/dist/server.js +112 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/services/claudeTasks.d.ts +23 -0
  25. package/dist/services/claudeTasks.js +160 -0
  26. package/dist/services/claudeTasks.js.map +1 -0
  27. package/dist/services/config.d.ts +3 -0
  28. package/dist/services/config.js +25 -0
  29. package/dist/services/config.js.map +1 -0
  30. package/dist/services/git.d.ts +8 -0
  31. package/dist/services/git.js +90 -0
  32. package/dist/services/git.js.map +1 -0
  33. package/dist/services/jira.d.ts +11 -0
  34. package/dist/services/jira.js +52 -0
  35. package/dist/services/jira.js.map +1 -0
  36. package/dist/services/linear.d.ts +9 -0
  37. package/dist/services/linear.js +69 -0
  38. package/dist/services/linear.js.map +1 -0
  39. package/dist/services/rules.d.ts +14 -0
  40. package/dist/services/rules.js +133 -0
  41. package/dist/services/rules.js.map +1 -0
  42. package/dist/services/taskStore.d.ts +27 -0
  43. package/dist/services/taskStore.js +261 -0
  44. package/dist/services/taskStore.js.map +1 -0
  45. package/dist/services/tunnel.d.ts +8 -0
  46. package/dist/services/tunnel.js +152 -0
  47. package/dist/services/tunnel.js.map +1 -0
  48. package/dist/services/watcher.d.ts +2 -0
  49. package/dist/services/watcher.js +30 -0
  50. package/dist/services/watcher.js.map +1 -0
  51. package/dist/types/index.d.ts +87 -0
  52. package/dist/types/index.js +3 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/package.json +53 -0
  55. package/public/css/style.css +1613 -0
  56. package/public/index.html +395 -0
  57. package/public/js/app.js +104 -0
  58. package/public/js/diff.js +337 -0
  59. package/public/js/integrations.js +194 -0
  60. package/public/js/rules.js +174 -0
  61. package/public/js/tasks.js +301 -0
@@ -0,0 +1,1613 @@
1
+ /* ============================================================
2
+ Devlens — UI/UX Pro Max Design System
3
+ Dark OLED + Inter/JetBrains Mono + 8px Grid + WCAG AAA
4
+ ============================================================ */
5
+
6
+ :root {
7
+ /* Color Tokens — OLED Dark */
8
+ --color-bg: #000000;
9
+ --color-surface: #0a0a0f;
10
+ --color-surface-2: #111118;
11
+ --color-surface-3: #18181f;
12
+ --color-surface-hover: #1e1e26;
13
+ --color-card: #111118;
14
+ --color-card-hover: #16161e;
15
+
16
+ /* Borders */
17
+ --color-border: #1e1e28;
18
+ --color-border-subtle: #151520;
19
+ --color-border-focus: #2563eb;
20
+
21
+ /* Text — WCAG AAA contrast on #000 */
22
+ --color-text: #f0f0f5;
23
+ --color-text-secondary: #9395a5;
24
+ --color-text-muted: #5c5e6e;
25
+ --color-text-inverse: #000000;
26
+
27
+ /* Brand / Primary */
28
+ --color-primary: #2563eb;
29
+ --color-primary-hover: #3b82f6;
30
+ --color-primary-subtle: rgba(37, 99, 235, 0.12);
31
+ --color-primary-glow: rgba(37, 99, 235, 0.25);
32
+
33
+ /* Semantic */
34
+ --color-success: #22c55e;
35
+ --color-success-subtle: rgba(34, 197, 94, 0.12);
36
+ --color-warning: #eab308;
37
+ --color-warning-subtle: rgba(234, 179, 8, 0.12);
38
+ --color-danger: #ef4444;
39
+ --color-danger-subtle: rgba(239, 68, 68, 0.12);
40
+ --color-purple: #a78bfa;
41
+ --color-purple-subtle: rgba(167, 139, 250, 0.12);
42
+
43
+ /* Typography */
44
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
45
+ --font-mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
46
+ --text-xs: 0.75rem; /* 12px */
47
+ --text-sm: 0.8125rem; /* 13px */
48
+ --text-base: 0.875rem; /* 14px */
49
+ --text-md: 1rem; /* 16px */
50
+ --text-lg: 1.25rem; /* 20px */
51
+ --text-xl: 1.5rem; /* 24px */
52
+ --text-2xl: 1.75rem; /* 28px */
53
+ --leading-tight: 1.25;
54
+ --leading-normal: 1.6;
55
+
56
+ /* Spacing — 8px grid */
57
+ --sp-1: 4px;
58
+ --sp-2: 8px;
59
+ --sp-3: 12px;
60
+ --sp-4: 16px;
61
+ --sp-5: 20px;
62
+ --sp-6: 24px;
63
+ --sp-8: 32px;
64
+ --sp-10: 40px;
65
+ --sp-12: 48px;
66
+
67
+ /* Shapes */
68
+ --radius-sm: 6px;
69
+ --radius-md: 10px;
70
+ --radius-lg: 14px;
71
+ --radius-xl: 18px;
72
+ --radius-full: 999px;
73
+
74
+ /* Shadows */
75
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
76
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.5);
77
+ --shadow-lg: 0 8px 24px rgba(0,0,0,0.6);
78
+ --shadow-glow: 0 0 20px var(--color-primary-glow);
79
+
80
+ /* Transitions */
81
+ --ease: cubic-bezier(0.4, 0, 0.2, 1);
82
+ --duration-fast: 150ms;
83
+ --duration-base: 250ms;
84
+ --duration-slow: 400ms;
85
+
86
+ /* Layout */
87
+ --sidebar-width: 220px;
88
+ --sidebar-collapsed: 64px;
89
+ }
90
+
91
+ @media (prefers-reduced-motion: reduce) {
92
+ *, *::before, *::after {
93
+ animation-duration: 0.01ms !important;
94
+ transition-duration: 0.01ms !important;
95
+ }
96
+ }
97
+
98
+ /* ---- Reset ---- */
99
+ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
100
+
101
+ body {
102
+ font-family: var(--font-sans);
103
+ font-size: var(--text-base);
104
+ line-height: var(--leading-normal);
105
+ background: var(--color-bg);
106
+ color: var(--color-text);
107
+ min-height: 100vh;
108
+ display: flex;
109
+ -webkit-font-smoothing: antialiased;
110
+ -moz-osx-font-smoothing: grayscale;
111
+ }
112
+
113
+ ::selection {
114
+ background: var(--color-primary);
115
+ color: #fff;
116
+ }
117
+
118
+ /* ---- Scrollbar ---- */
119
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
120
+ ::-webkit-scrollbar-track { background: transparent; }
121
+ ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: var(--radius-full); }
122
+ ::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }
123
+
124
+ /* ============================================================
125
+ Sidebar
126
+ ============================================================ */
127
+ #sidebar {
128
+ width: var(--sidebar-width);
129
+ height: 100vh;
130
+ position: fixed;
131
+ left: 0;
132
+ top: 0;
133
+ background: var(--color-surface);
134
+ border-right: 1px solid var(--color-border);
135
+ display: flex;
136
+ flex-direction: column;
137
+ z-index: 100;
138
+ padding: var(--sp-4);
139
+ }
140
+
141
+ .sidebar-brand {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: var(--sp-3);
145
+ padding: var(--sp-2) var(--sp-2);
146
+ margin-bottom: var(--sp-8);
147
+ }
148
+
149
+ .brand-icon {
150
+ width: 36px;
151
+ height: 36px;
152
+ background: var(--color-primary);
153
+ border-radius: var(--radius-md);
154
+ display: flex;
155
+ align-items: center;
156
+ justify-content: center;
157
+ color: #fff;
158
+ box-shadow: var(--shadow-glow);
159
+ }
160
+
161
+ .brand-name {
162
+ font-size: var(--text-lg);
163
+ font-weight: 700;
164
+ letter-spacing: -0.5px;
165
+ color: var(--color-text);
166
+ }
167
+
168
+ .sidebar-nav {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: var(--sp-1);
172
+ flex: 1;
173
+ }
174
+
175
+ .nav-item {
176
+ display: flex;
177
+ align-items: center;
178
+ gap: var(--sp-3);
179
+ padding: var(--sp-3) var(--sp-3);
180
+ border: none;
181
+ background: transparent;
182
+ color: var(--color-text-secondary);
183
+ font-family: var(--font-sans);
184
+ font-size: var(--text-base);
185
+ font-weight: 500;
186
+ border-radius: var(--radius-md);
187
+ cursor: pointer;
188
+ transition: all var(--duration-fast) var(--ease);
189
+ min-height: 44px;
190
+ }
191
+
192
+ .nav-item:hover {
193
+ background: var(--color-surface-hover);
194
+ color: var(--color-text);
195
+ }
196
+
197
+ .nav-item.active {
198
+ background: var(--color-primary-subtle);
199
+ color: var(--color-primary-hover);
200
+ }
201
+
202
+ .nav-item.active svg { stroke: var(--color-primary-hover); }
203
+
204
+ .nav-item:focus-visible {
205
+ outline: 2px solid var(--color-border-focus);
206
+ outline-offset: 2px;
207
+ }
208
+
209
+ .sidebar-footer {
210
+ padding-top: var(--sp-4);
211
+ border-top: 1px solid var(--color-border);
212
+ }
213
+
214
+ .connection-status {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: var(--sp-2);
218
+ padding: var(--sp-2);
219
+ font-size: var(--text-xs);
220
+ color: var(--color-text-muted);
221
+ }
222
+
223
+ .status-indicator {
224
+ width: 8px;
225
+ height: 8px;
226
+ border-radius: var(--radius-full);
227
+ background: var(--color-danger);
228
+ transition: background var(--duration-base) var(--ease);
229
+ flex-shrink: 0;
230
+ }
231
+
232
+ .status-indicator.connected {
233
+ background: var(--color-success);
234
+ box-shadow: 0 0 8px var(--color-success-subtle);
235
+ }
236
+
237
+ /* ============================================================
238
+ Main Content — page body scrolls, sidebar/header/filelist fixed
239
+ ============================================================ */
240
+ #main-content {
241
+ margin-left: var(--sidebar-width);
242
+ min-height: 100vh;
243
+ width: calc(100vw - var(--sidebar-width));
244
+ }
245
+
246
+ .tab-content {
247
+ display: none;
248
+ flex-direction: column;
249
+ padding: var(--sp-8);
250
+ padding-top: 72px; /* space for fixed header */
251
+ min-height: 100vh;
252
+ }
253
+
254
+ .tab-content.active { display: flex; }
255
+
256
+ /* View Header — fixed at top */
257
+ .view-header {
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: space-between;
261
+ position: fixed;
262
+ top: 0;
263
+ left: var(--sidebar-width);
264
+ right: 0;
265
+ z-index: 20;
266
+ background: var(--color-bg);
267
+ padding: var(--sp-4) var(--sp-8);
268
+ border-bottom: 1px solid var(--color-border-subtle);
269
+ }
270
+
271
+ .view-header h1 {
272
+ font-size: var(--text-xl);
273
+ font-weight: 700;
274
+ letter-spacing: -0.3px;
275
+ line-height: var(--leading-tight);
276
+ }
277
+
278
+ .header-actions {
279
+ display: flex;
280
+ align-items: center;
281
+ gap: var(--sp-2);
282
+ }
283
+
284
+ .divider-v {
285
+ width: 1px;
286
+ height: 24px;
287
+ background: var(--color-border);
288
+ margin: 0 var(--sp-2);
289
+ }
290
+
291
+ /* ============================================================
292
+ Buttons
293
+ ============================================================ */
294
+ .btn svg, .nav-item svg, .card-actions svg { pointer-events: none; }
295
+
296
+ .btn {
297
+ display: inline-flex;
298
+ align-items: center;
299
+ justify-content: center;
300
+ gap: var(--sp-2);
301
+ padding: var(--sp-2) var(--sp-4);
302
+ font-family: var(--font-sans);
303
+ font-size: var(--text-sm);
304
+ font-weight: 500;
305
+ line-height: 1;
306
+ border: 1px solid var(--color-border);
307
+ border-radius: var(--radius-md);
308
+ background: var(--color-surface-2);
309
+ color: var(--color-text);
310
+ cursor: pointer;
311
+ transition: all var(--duration-fast) var(--ease);
312
+ min-height: 36px;
313
+ white-space: nowrap;
314
+ user-select: none;
315
+ }
316
+
317
+ .btn:hover { background: var(--color-surface-hover); border-color: var(--color-text-muted); }
318
+ .btn:active { transform: scale(0.97); }
319
+ .btn:focus-visible { outline: 2px solid var(--color-border-focus); outline-offset: 2px; }
320
+
321
+ .btn-ghost {
322
+ background: transparent;
323
+ border-color: transparent;
324
+ color: var(--color-text-secondary);
325
+ }
326
+ .btn-ghost:hover { background: var(--color-surface-hover); color: var(--color-text); border-color: transparent; }
327
+ .btn-ghost.active {
328
+ background: var(--color-surface-3);
329
+ color: var(--color-text);
330
+ border-color: var(--color-border);
331
+ }
332
+
333
+ .btn-primary {
334
+ background: var(--color-primary);
335
+ border-color: var(--color-primary);
336
+ color: #fff;
337
+ font-weight: 600;
338
+ }
339
+ .btn-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
340
+
341
+ .btn-icon {
342
+ padding: var(--sp-2);
343
+ background: transparent;
344
+ border: none;
345
+ color: var(--color-text-muted);
346
+ min-height: 36px;
347
+ min-width: 36px;
348
+ }
349
+ .btn-icon:hover { color: var(--color-text); background: var(--color-surface-hover); }
350
+
351
+ .btn-group {
352
+ display: flex;
353
+ gap: 2px;
354
+ background: var(--color-surface);
355
+ border-radius: var(--radius-md);
356
+ padding: 2px;
357
+ border: 1px solid var(--color-border-subtle);
358
+ }
359
+
360
+ .btn-group .btn-ghost {
361
+ border-radius: var(--radius-sm);
362
+ padding: 6px 12px;
363
+ }
364
+
365
+ /* ============================================================
366
+ Diff View
367
+ ============================================================ */
368
+ .diff-container {
369
+ display: flex;
370
+ gap: var(--sp-4);
371
+ flex: 1;
372
+ min-width: 0;
373
+ }
374
+
375
+ .file-list {
376
+ width: 240px;
377
+ position: fixed;
378
+ top: 68px; /* below fixed header */
379
+ bottom: var(--sp-8);
380
+ background: var(--color-surface);
381
+ border: 1px solid var(--color-border);
382
+ border-radius: var(--radius-lg);
383
+ display: flex;
384
+ flex-direction: column;
385
+ overflow: hidden;
386
+ z-index: 15;
387
+ }
388
+
389
+ .file-list-header {
390
+ display: flex;
391
+ align-items: center;
392
+ justify-content: space-between;
393
+ padding: var(--sp-3) var(--sp-4);
394
+ border-bottom: 1px solid var(--color-border-subtle);
395
+ }
396
+
397
+ .file-list-header h3 {
398
+ font-size: var(--text-xs);
399
+ font-weight: 600;
400
+ text-transform: uppercase;
401
+ letter-spacing: 0.08em;
402
+ color: var(--color-text-muted);
403
+ }
404
+
405
+ .file-list-actions {
406
+ display: flex;
407
+ align-items: center;
408
+ gap: var(--sp-1);
409
+ }
410
+
411
+ .file-list-divider {
412
+ width: 1px;
413
+ height: 16px;
414
+ background: var(--color-border);
415
+ margin: 0 var(--sp-1);
416
+ }
417
+
418
+ .btn-icon-sm {
419
+ padding: 4px;
420
+ min-height: 28px;
421
+ min-width: 28px;
422
+ border-radius: var(--radius-sm);
423
+ }
424
+
425
+ .btn-icon-sm.active { background: var(--color-surface-3); color: var(--color-text); }
426
+
427
+ .file-count {
428
+ font-size: var(--text-xs);
429
+ font-weight: 600;
430
+ color: var(--color-text-muted);
431
+ background: var(--color-surface-3);
432
+ padding: 2px 8px;
433
+ border-radius: var(--radius-full);
434
+ margin-left: var(--sp-1);
435
+ }
436
+
437
+ /* Tree view */
438
+ .tree-folder {
439
+ display: flex !important;
440
+ align-items: center;
441
+ gap: var(--sp-2);
442
+ color: var(--color-text-secondary) !important;
443
+ font-family: var(--font-sans) !important;
444
+ font-size: var(--text-sm) !important;
445
+ font-weight: 500;
446
+ cursor: default !important;
447
+ min-height: 32px !important;
448
+ }
449
+
450
+ .folder-name { color: var(--color-text-secondary); }
451
+
452
+ .file-list ul {
453
+ list-style: none;
454
+ overflow-y: auto;
455
+ padding: var(--sp-2);
456
+ flex: 1;
457
+ }
458
+
459
+ .file-list li {
460
+ padding: var(--sp-2) var(--sp-3);
461
+ border-radius: var(--radius-sm);
462
+ cursor: pointer;
463
+ font-size: var(--text-sm);
464
+ font-family: var(--font-mono);
465
+ color: var(--color-text-secondary);
466
+ white-space: nowrap;
467
+ overflow: hidden;
468
+ text-overflow: ellipsis;
469
+ transition: all var(--duration-fast) var(--ease);
470
+ min-height: 36px;
471
+ display: flex;
472
+ align-items: center;
473
+ }
474
+
475
+ .file-list li:hover {
476
+ background: var(--color-surface-hover);
477
+ color: var(--color-text);
478
+ }
479
+
480
+ .file-list li.selected {
481
+ background: var(--color-primary-subtle);
482
+ color: var(--color-primary-hover);
483
+ }
484
+
485
+ .file-list li .file-name {
486
+ overflow: hidden;
487
+ text-overflow: ellipsis;
488
+ flex: 1;
489
+ }
490
+
491
+ .file-list li .status-badge {
492
+ display: inline-block;
493
+ width: 8px;
494
+ height: 8px;
495
+ border-radius: var(--radius-full);
496
+ margin-right: var(--sp-3);
497
+ flex-shrink: 0;
498
+ }
499
+
500
+ .file-list li .status-badge.modified { background: var(--color-warning); box-shadow: 0 0 6px var(--color-warning-subtle); }
501
+ .file-list li .status-badge.added { background: var(--color-success); box-shadow: 0 0 6px var(--color-success-subtle); }
502
+ .file-list li .status-badge.deleted { background: var(--color-danger); box-shadow: 0 0 6px var(--color-danger-subtle); }
503
+ .file-list li .status-badge.untracked { background: var(--color-text-muted); }
504
+ .file-list li .status-badge.renamed { background: var(--color-purple); box-shadow: 0 0 6px var(--color-purple-subtle); }
505
+
506
+ .empty-state-inline {
507
+ color: var(--color-text-muted) !important;
508
+ font-family: var(--font-sans) !important;
509
+ cursor: default !important;
510
+ justify-content: center !important;
511
+ padding: var(--sp-6) !important;
512
+ }
513
+
514
+ .diff-output {
515
+ flex: 1;
516
+ margin-left: 256px; /* file-list width + gap */
517
+ overflow-x: hidden;
518
+ min-width: 0;
519
+ }
520
+
521
+ .empty-state {
522
+ display: flex;
523
+ flex-direction: column;
524
+ align-items: center;
525
+ justify-content: center;
526
+ padding: var(--sp-12);
527
+ height: 100%;
528
+ gap: var(--sp-3);
529
+ color: var(--color-text-muted);
530
+ }
531
+
532
+ .empty-state p {
533
+ font-size: var(--text-md);
534
+ font-weight: 600;
535
+ color: var(--color-text-secondary);
536
+ }
537
+
538
+ .empty-state span {
539
+ font-size: var(--text-sm);
540
+ }
541
+
542
+ /* ---- Per-file collapsible diff sections ---- */
543
+ .diff-file-section {
544
+ border: 1px solid var(--color-border);
545
+ border-radius: var(--radius-md);
546
+ margin-bottom: var(--sp-2);
547
+ overflow: hidden;
548
+ }
549
+
550
+ .diff-file-header {
551
+ display: flex;
552
+ align-items: center;
553
+ gap: var(--sp-3);
554
+ padding: var(--sp-3) var(--sp-4);
555
+ background: var(--color-surface-2);
556
+ cursor: pointer;
557
+ user-select: none;
558
+ transition: background var(--duration-fast) var(--ease);
559
+ min-height: 44px;
560
+ }
561
+
562
+ .diff-file-header:hover { background: var(--color-surface-3); }
563
+
564
+ .diff-file-header .chevron {
565
+ transition: transform var(--duration-fast) var(--ease);
566
+ flex-shrink: 0;
567
+ color: var(--color-text-muted);
568
+ }
569
+
570
+ .diff-file-section.expanded .chevron { transform: rotate(90deg); }
571
+
572
+ .diff-file-name {
573
+ font-family: var(--font-mono);
574
+ font-size: var(--text-sm);
575
+ color: var(--color-text);
576
+ overflow: hidden;
577
+ text-overflow: ellipsis;
578
+ white-space: nowrap;
579
+ }
580
+
581
+ .diff-file-badge {
582
+ margin-left: auto;
583
+ font-size: var(--text-xs);
584
+ color: var(--color-text-muted);
585
+ background: var(--color-surface-3);
586
+ padding: 2px 8px;
587
+ border-radius: var(--radius-full);
588
+ flex-shrink: 0;
589
+ }
590
+
591
+ .diff-file-body {
592
+ display: none;
593
+ overflow-x: auto;
594
+ }
595
+
596
+ .diff-file-section.expanded .diff-file-body { display: block; }
597
+
598
+ /* ---- diff2html — minimal overrides (native dark theme via colorScheme:'dark') ---- */
599
+ .d2h-file-list-wrapper { display: none !important; }
600
+ .d2h-file-header { display: none !important; }
601
+ .d2h-wrapper { background: transparent !important; }
602
+ .d2h-file-wrapper { border: none !important; margin: 0 !important; }
603
+ .d2h-code-line-ctn { font-family: var(--font-mono) !important; font-size: var(--text-sm) !important; }
604
+ /* Fix: diff2html sets position:absolute on line numbers — force static so they scroll with code */
605
+ .d2h-code-linenumber, .d2h-code-side-linenumber { position: static !important; display: table-cell !important; }
606
+ /* Word wrap toggle */
607
+ .diff-output.word-wrap .d2h-code-line-ctn { white-space: pre-wrap !important; word-break: break-all !important; }
608
+
609
+ /* ============================================================
610
+ Kanban Board
611
+ ============================================================ */
612
+ .kanban-board {
613
+ display: flex;
614
+ gap: var(--sp-4);
615
+ flex: 1;
616
+ overflow-x: auto;
617
+ }
618
+
619
+ .kanban-column {
620
+ flex: 1;
621
+ min-width: 300px;
622
+ background: var(--color-surface);
623
+ border: 1px solid var(--color-border);
624
+ border-radius: var(--radius-lg);
625
+ display: flex;
626
+ flex-direction: column;
627
+ max-height: calc(100vh - 120px);
628
+ }
629
+
630
+ .column-header {
631
+ display: flex;
632
+ justify-content: space-between;
633
+ align-items: center;
634
+ padding: var(--sp-4) var(--sp-5);
635
+ border-bottom: 1px solid var(--color-border-subtle);
636
+ }
637
+
638
+ .column-title {
639
+ display: flex;
640
+ align-items: center;
641
+ gap: var(--sp-3);
642
+ }
643
+
644
+ .column-dot {
645
+ width: 10px;
646
+ height: 10px;
647
+ border-radius: var(--radius-full);
648
+ }
649
+
650
+ .column-dot.pending { background: var(--color-warning); box-shadow: 0 0 8px var(--color-warning-subtle); }
651
+ .column-dot.in-progress { background: var(--color-primary); box-shadow: 0 0 8px var(--color-primary-subtle); }
652
+ .column-dot.completed { background: var(--color-success); box-shadow: 0 0 8px var(--color-success-subtle); }
653
+ .column-dot.archived { background: var(--color-text-muted); }
654
+
655
+ .column-archived { opacity: 0.7; }
656
+ .column-archived .task-card { opacity: 0.6; }
657
+
658
+ /* Session filter dropdown */
659
+ .session-filter { display: flex; align-items: center; }
660
+
661
+ .session-select {
662
+ background-color: var(--color-surface-2);
663
+ border: 1px solid var(--color-border);
664
+ border-radius: var(--radius-md);
665
+ color: var(--color-text);
666
+ font-family: var(--font-sans);
667
+ font-size: var(--text-sm);
668
+ padding: var(--sp-2) var(--sp-4);
669
+ padding-right: var(--sp-8);
670
+ min-height: 36px;
671
+ cursor: pointer;
672
+ appearance: none;
673
+ background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L5 5L9 1' stroke='%239395a5' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
674
+ background-repeat: no-repeat;
675
+ background-position: right 10px center;
676
+ color-scheme: dark;
677
+ }
678
+
679
+ .session-select option {
680
+ background: var(--color-surface-2);
681
+ color: var(--color-text);
682
+ }
683
+
684
+ .session-select:focus { outline: none; border-color: var(--color-primary); }
685
+
686
+ .column-header h3 {
687
+ font-size: var(--text-base);
688
+ font-weight: 600;
689
+ }
690
+
691
+ .count {
692
+ font-size: var(--text-xs);
693
+ font-weight: 600;
694
+ color: var(--color-text-muted);
695
+ background: var(--color-surface-3);
696
+ padding: 2px 10px;
697
+ border-radius: var(--radius-full);
698
+ min-width: 24px;
699
+ text-align: center;
700
+ }
701
+
702
+ .column-cards {
703
+ padding: var(--sp-3);
704
+ flex: 1;
705
+ overflow-y: auto;
706
+ min-height: 80px;
707
+ transition: background var(--duration-fast) var(--ease);
708
+ }
709
+
710
+ .column-cards.drag-over {
711
+ background: var(--color-primary-subtle);
712
+ border-radius: 0 0 var(--radius-lg) var(--radius-lg);
713
+ }
714
+
715
+ .task-card {
716
+ background: var(--color-card);
717
+ border: 1px solid var(--color-border);
718
+ border-radius: var(--radius-md);
719
+ padding: var(--sp-4);
720
+ margin-bottom: var(--sp-2);
721
+ cursor: grab;
722
+ transition: all var(--duration-fast) var(--ease);
723
+ position: relative;
724
+ overflow: hidden;
725
+ }
726
+
727
+ .task-card::before {
728
+ content: '';
729
+ position: absolute;
730
+ left: 0;
731
+ top: 0;
732
+ bottom: 0;
733
+ width: 3px;
734
+ background: var(--color-border);
735
+ border-radius: 3px 0 0 3px;
736
+ }
737
+
738
+ .task-card:hover {
739
+ background: var(--color-card-hover);
740
+ border-color: var(--color-text-muted);
741
+ box-shadow: var(--shadow-md);
742
+ transform: translateY(-1px);
743
+ }
744
+
745
+ .task-card:active { cursor: grabbing; }
746
+ .task-card.dragging { opacity: 0.35; transform: rotate(2deg); }
747
+
748
+ .task-card.priority-high::before { background: var(--color-danger); box-shadow: 0 0 8px var(--color-danger-subtle); }
749
+ .task-card.priority-medium::before { background: var(--color-warning); box-shadow: 0 0 8px var(--color-warning-subtle); }
750
+ .task-card.priority-low::before { background: var(--color-success); box-shadow: 0 0 8px var(--color-success-subtle); }
751
+
752
+ .task-card .task-title {
753
+ font-size: var(--text-base);
754
+ font-weight: 600;
755
+ margin-bottom: var(--sp-2);
756
+ padding-left: var(--sp-2);
757
+ }
758
+
759
+ .task-card .task-meta {
760
+ display: flex;
761
+ gap: var(--sp-2);
762
+ flex-wrap: wrap;
763
+ padding-left: var(--sp-2);
764
+ }
765
+
766
+ .tag {
767
+ font-size: var(--text-xs);
768
+ font-weight: 500;
769
+ padding: 2px 8px;
770
+ border-radius: var(--radius-full);
771
+ background: var(--color-surface-3);
772
+ color: var(--color-text-secondary);
773
+ border: 1px solid var(--color-border-subtle);
774
+ }
775
+
776
+ .task-card .task-deps {
777
+ font-size: var(--text-xs);
778
+ color: var(--color-text-muted);
779
+ margin-top: var(--sp-2);
780
+ padding-left: var(--sp-2);
781
+ }
782
+
783
+ .task-card .card-actions {
784
+ display: flex;
785
+ gap: var(--sp-1);
786
+ margin-top: var(--sp-3);
787
+ padding-left: var(--sp-2);
788
+ opacity: 0;
789
+ transition: opacity var(--duration-fast) var(--ease);
790
+ }
791
+
792
+ .task-card:hover .card-actions { opacity: 1; }
793
+
794
+ .card-actions button {
795
+ background: var(--color-surface-3);
796
+ border: 1px solid var(--color-border-subtle);
797
+ color: var(--color-text-muted);
798
+ cursor: pointer;
799
+ font-family: var(--font-sans);
800
+ font-size: var(--text-xs);
801
+ font-weight: 500;
802
+ padding: 4px 10px;
803
+ border-radius: var(--radius-sm);
804
+ transition: all var(--duration-fast) var(--ease);
805
+ min-height: 28px;
806
+ }
807
+
808
+ .card-actions button:hover { color: var(--color-text); background: var(--color-surface-hover); }
809
+ .card-actions button.delete:hover { color: var(--color-danger); background: var(--color-danger-subtle); border-color: rgba(239,68,68,0.3); }
810
+
811
+ /* ============================================================
812
+ Claude Panels (Todos + Sessions)
813
+ ============================================================ */
814
+ .claude-panel {
815
+ background: var(--color-surface);
816
+ border: 1px solid var(--color-border);
817
+ border-radius: var(--radius-lg);
818
+ margin-top: var(--sp-4);
819
+ overflow: hidden;
820
+ }
821
+
822
+ .claude-panel-header {
823
+ display: flex;
824
+ align-items: center;
825
+ justify-content: space-between;
826
+ padding: var(--sp-3) var(--sp-5);
827
+ border-bottom: 1px solid var(--color-border-subtle);
828
+ }
829
+
830
+ .claude-panel-title {
831
+ display: flex;
832
+ align-items: center;
833
+ gap: var(--sp-3);
834
+ }
835
+
836
+ .claude-panel-title h3 {
837
+ font-size: var(--text-base);
838
+ font-weight: 600;
839
+ }
840
+
841
+ .claude-panel-title svg { color: var(--color-text-muted); flex-shrink: 0; }
842
+
843
+ .live-badge {
844
+ font-size: 10px;
845
+ font-weight: 700;
846
+ letter-spacing: 0.08em;
847
+ color: var(--color-success);
848
+ background: var(--color-success-subtle);
849
+ padding: 2px 6px;
850
+ border-radius: var(--radius-full);
851
+ animation: pulse-glow 2s ease-in-out infinite;
852
+ }
853
+
854
+ @keyframes pulse-glow {
855
+ 0%, 100% { opacity: 1; }
856
+ 50% { opacity: 0.6; }
857
+ }
858
+
859
+ .claude-panel-body {
860
+ padding: var(--sp-3);
861
+ max-height: 300px;
862
+ overflow-y: auto;
863
+ }
864
+
865
+ .panel-empty {
866
+ color: var(--color-text-muted);
867
+ font-size: var(--text-sm);
868
+ text-align: center;
869
+ padding: var(--sp-6);
870
+ }
871
+
872
+ /* Todo card */
873
+ .todo-card {
874
+ display: flex;
875
+ align-items: flex-start;
876
+ gap: var(--sp-3);
877
+ padding: var(--sp-3) var(--sp-4);
878
+ border-radius: var(--radius-md);
879
+ margin-bottom: var(--sp-1);
880
+ transition: background var(--duration-fast) var(--ease);
881
+ }
882
+
883
+ .todo-card:hover { background: var(--color-surface-hover); }
884
+
885
+ .todo-status-icon {
886
+ width: 18px;
887
+ height: 18px;
888
+ border-radius: var(--radius-full);
889
+ border: 2px solid var(--color-text-muted);
890
+ flex-shrink: 0;
891
+ margin-top: 2px;
892
+ }
893
+
894
+ .todo-card.status-in_progress .todo-status-icon {
895
+ border-color: var(--color-primary);
896
+ background: var(--color-primary-subtle);
897
+ }
898
+
899
+ .todo-card.status-completed .todo-status-icon {
900
+ border-color: var(--color-success);
901
+ background: var(--color-success);
902
+ }
903
+
904
+ .todo-content {
905
+ flex: 1;
906
+ font-size: var(--text-sm);
907
+ color: var(--color-text);
908
+ line-height: var(--leading-normal);
909
+ }
910
+
911
+ .todo-card.status-completed .todo-content {
912
+ text-decoration: line-through;
913
+ color: var(--color-text-muted);
914
+ }
915
+
916
+ /* Session card */
917
+ .session-card {
918
+ display: flex;
919
+ align-items: center;
920
+ gap: var(--sp-3);
921
+ padding: var(--sp-3) var(--sp-4);
922
+ border-radius: var(--radius-md);
923
+ margin-bottom: var(--sp-1);
924
+ }
925
+
926
+ .session-card:hover { background: var(--color-surface-hover); }
927
+
928
+ .session-info { flex: 1; min-width: 0; }
929
+
930
+ .session-name {
931
+ font-size: var(--text-sm);
932
+ font-weight: 500;
933
+ color: var(--color-text);
934
+ white-space: nowrap;
935
+ overflow: hidden;
936
+ text-overflow: ellipsis;
937
+ }
938
+
939
+ .session-details {
940
+ display: flex;
941
+ align-items: center;
942
+ gap: var(--sp-2);
943
+ margin-top: 2px;
944
+ }
945
+
946
+ .session-id {
947
+ font-family: var(--font-mono);
948
+ font-size: var(--text-xs);
949
+ color: var(--color-text-muted);
950
+ }
951
+
952
+ .session-project {
953
+ font-size: var(--text-xs);
954
+ color: var(--color-text-secondary);
955
+ }
956
+
957
+ .session-project::before {
958
+ content: '/';
959
+ margin-right: var(--sp-1);
960
+ color: var(--color-text-muted);
961
+ }
962
+
963
+ .session-time {
964
+ font-size: var(--text-xs);
965
+ color: var(--color-text-muted);
966
+ }
967
+
968
+ .session-time::before {
969
+ content: '\00b7';
970
+ margin-right: var(--sp-1);
971
+ }
972
+
973
+ .session-meta {
974
+ display: flex;
975
+ align-items: center;
976
+ gap: var(--sp-3);
977
+ flex-shrink: 0;
978
+ }
979
+
980
+ .session-task-count {
981
+ font-size: var(--text-xs);
982
+ color: var(--color-text-muted);
983
+ font-family: var(--font-mono);
984
+ }
985
+
986
+ .session-active-tag {
987
+ color: var(--color-success) !important;
988
+ background: var(--color-success-subtle) !important;
989
+ border-color: transparent !important;
990
+ }
991
+
992
+ .session-active {
993
+ width: 8px;
994
+ height: 8px;
995
+ border-radius: var(--radius-full);
996
+ background: var(--color-success);
997
+ box-shadow: 0 0 6px var(--color-success-subtle);
998
+ flex-shrink: 0;
999
+ }
1000
+
1001
+ .session-inactive {
1002
+ width: 8px;
1003
+ height: 8px;
1004
+ border-radius: var(--radius-full);
1005
+ background: var(--color-text-muted);
1006
+ flex-shrink: 0;
1007
+ }
1008
+
1009
+ /* ============================================================
1010
+ Modal
1011
+ ============================================================ */
1012
+ .modal {
1013
+ position: fixed;
1014
+ inset: 0;
1015
+ z-index: 200;
1016
+ display: flex;
1017
+ align-items: center;
1018
+ justify-content: center;
1019
+ animation: fadeIn var(--duration-fast) var(--ease);
1020
+ }
1021
+
1022
+ .modal.hidden { display: none; }
1023
+
1024
+ .modal-backdrop {
1025
+ position: absolute;
1026
+ inset: 0;
1027
+ background: rgba(0, 0, 0, 0.7);
1028
+ backdrop-filter: blur(8px);
1029
+ }
1030
+
1031
+ .modal-content {
1032
+ position: relative;
1033
+ background: #1a1a24;
1034
+ border: 1px solid rgba(255, 255, 255, 0.1);
1035
+ border-radius: 16px;
1036
+ padding: 0;
1037
+ width: 1080px;
1038
+ max-width: 95vw;
1039
+ max-height: 92vh;
1040
+ display: flex;
1041
+ flex-direction: column;
1042
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.06);
1043
+ animation: slideUp var(--duration-base) var(--ease);
1044
+ overflow: hidden;
1045
+ }
1046
+
1047
+ .modal-header {
1048
+ display: flex;
1049
+ align-items: center;
1050
+ padding: var(--sp-4) var(--sp-6);
1051
+ border-bottom: 1px solid rgba(255, 255, 255, 0.07);
1052
+ background: #1e1e2a;
1053
+ flex-shrink: 0;
1054
+ gap: var(--sp-4);
1055
+ }
1056
+
1057
+ .modal-header h3 {
1058
+ font-size: var(--text-md);
1059
+ font-weight: 600;
1060
+ white-space: nowrap;
1061
+ }
1062
+
1063
+ .modal-header-center {
1064
+ flex: 1;
1065
+ display: flex;
1066
+ align-items: center;
1067
+ justify-content: center;
1068
+ gap: var(--sp-2);
1069
+ }
1070
+
1071
+ .modal-task-num {
1072
+ font-family: var(--font-mono);
1073
+ font-size: var(--text-xs);
1074
+ color: var(--color-text-muted);
1075
+ }
1076
+
1077
+ .modal-status-badge {
1078
+ font-size: 11px;
1079
+ font-weight: 600;
1080
+ padding: 2px 10px;
1081
+ border-radius: var(--radius-full);
1082
+ text-transform: capitalize;
1083
+ }
1084
+
1085
+ .modal-status-badge:empty { display: none; }
1086
+ .modal-status-badge.pending { background: var(--color-warning-subtle); color: var(--color-warning); }
1087
+ .modal-status-badge.in-progress { background: var(--color-primary-subtle); color: var(--color-primary-hover); }
1088
+ .modal-status-badge.completed { background: var(--color-success-subtle); color: var(--color-success); }
1089
+ .modal-status-badge.archived { background: rgba(255,255,255,0.05); color: var(--color-text-muted); }
1090
+
1091
+ .modal-body {
1092
+ overflow-y: auto;
1093
+ padding: var(--sp-5) var(--sp-6);
1094
+ flex: 1;
1095
+ }
1096
+
1097
+ .input-title {
1098
+ font-size: var(--text-md) !important;
1099
+ font-weight: 500 !important;
1100
+ border: none !important;
1101
+ background: transparent !important;
1102
+ padding: var(--sp-2) 0 !important;
1103
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
1104
+ border-radius: 0 !important;
1105
+ min-height: 38px !important;
1106
+ }
1107
+
1108
+ .input-title:focus {
1109
+ border-bottom-color: var(--color-primary) !important;
1110
+ box-shadow: none !important;
1111
+ }
1112
+
1113
+ .modal-row-3col {
1114
+ display: flex;
1115
+ gap: var(--sp-3);
1116
+ margin-bottom: var(--sp-4);
1117
+ }
1118
+
1119
+ .modal-row-3col .form-group { flex: 1; margin-bottom: 0; }
1120
+
1121
+ .modal-row-2col {
1122
+ display: grid;
1123
+ grid-template-columns: 1fr 1fr;
1124
+ gap: var(--sp-4);
1125
+ margin-bottom: var(--sp-4);
1126
+ }
1127
+
1128
+ .modal-row-2col .form-group { margin-bottom: 0; }
1129
+ .modal-row-2col > .form-group:only-child { grid-column: 1 / -1; }
1130
+
1131
+ .context-display.tall { min-height: 90px; }
1132
+
1133
+ .modal-session-hint {
1134
+ font-family: var(--font-mono);
1135
+ font-size: var(--text-xs);
1136
+ color: var(--color-text-muted);
1137
+ opacity: 0.6;
1138
+ }
1139
+
1140
+ @media (max-width: 600px) {
1141
+ .modal-row-3col { flex-direction: column; }
1142
+ .modal-row-2col { grid-template-columns: 1fr; }
1143
+ }
1144
+
1145
+ .form-group {
1146
+ margin-bottom: var(--sp-4);
1147
+ }
1148
+
1149
+ .form-group label {
1150
+ display: block;
1151
+ margin-bottom: var(--sp-2);
1152
+ font-size: var(--text-sm);
1153
+ font-weight: 500;
1154
+ color: var(--color-text-secondary);
1155
+ }
1156
+
1157
+ .form-group input,
1158
+ .form-group textarea,
1159
+ .form-group select {
1160
+ display: block;
1161
+ width: 100%;
1162
+ padding: var(--sp-2) var(--sp-3);
1163
+ background: rgba(255, 255, 255, 0.04);
1164
+ border: 1px solid rgba(255, 255, 255, 0.1);
1165
+ border-radius: var(--radius-sm);
1166
+ color: var(--color-text);
1167
+ font-size: var(--text-sm);
1168
+ font-family: var(--font-sans);
1169
+ min-height: 36px;
1170
+ transition: all var(--duration-fast) var(--ease);
1171
+ color-scheme: dark;
1172
+ }
1173
+
1174
+ .form-group select option {
1175
+ background: var(--color-surface-2);
1176
+ color: var(--color-text);
1177
+ }
1178
+
1179
+ .form-group input:hover,
1180
+ .form-group textarea:hover,
1181
+ .form-group select:hover {
1182
+ border-color: rgba(255, 255, 255, 0.18);
1183
+ background: rgba(255, 255, 255, 0.06);
1184
+ }
1185
+
1186
+ .form-group input::placeholder,
1187
+ .form-group textarea::placeholder {
1188
+ color: var(--color-text-muted);
1189
+ }
1190
+
1191
+ .form-group input:focus,
1192
+ .form-group textarea:focus,
1193
+ .form-group select:focus {
1194
+ outline: none;
1195
+ border-color: var(--color-primary);
1196
+ box-shadow: 0 0 0 3px var(--color-primary-subtle);
1197
+ }
1198
+
1199
+ .form-row {
1200
+ display: flex;
1201
+ gap: var(--sp-4);
1202
+ }
1203
+
1204
+ .form-row .form-group { flex: 1; }
1205
+
1206
+ .context-display.mono { font-family: var(--font-mono); font-size: var(--text-xs); }
1207
+
1208
+ .context-display {
1209
+ background: rgba(255, 255, 255, 0.03);
1210
+ border: 1px solid rgba(255, 255, 255, 0.06);
1211
+ border-radius: var(--radius-sm);
1212
+ padding: var(--sp-3) var(--sp-4);
1213
+ color: var(--color-text-secondary);
1214
+ font-size: var(--text-sm);
1215
+ line-height: 1.6;
1216
+ min-height: 140px;
1217
+ max-height: 220px;
1218
+ overflow-y: auto;
1219
+ white-space: pre-wrap;
1220
+ word-break: break-word;
1221
+ }
1222
+
1223
+ .context-display.tall { min-height: 160px; max-height: 260px; }
1224
+
1225
+ .modal-actions {
1226
+ display: flex;
1227
+ align-items: center;
1228
+ padding: var(--sp-3) var(--sp-6);
1229
+ border-top: 1px solid rgba(255, 255, 255, 0.07);
1230
+ background: #1e1e2a;
1231
+ flex-shrink: 0;
1232
+ }
1233
+
1234
+ .modal-actions-right {
1235
+ margin-left: auto;
1236
+ display: flex;
1237
+ gap: var(--sp-3);
1238
+ }
1239
+
1240
+ /* ============================================================
1241
+ Integrations
1242
+ ============================================================ */
1243
+ .integrations-container {
1244
+ max-width: 800px;
1245
+ width: 100%;
1246
+ }
1247
+
1248
+ .integration-section {
1249
+ background: var(--color-surface);
1250
+ border: 1px solid var(--color-border);
1251
+ border-radius: var(--radius-lg);
1252
+ padding: var(--sp-6);
1253
+ margin-bottom: var(--sp-6);
1254
+ }
1255
+
1256
+ .section-header {
1257
+ display: flex;
1258
+ align-items: center;
1259
+ gap: var(--sp-3);
1260
+ margin-bottom: var(--sp-2);
1261
+ }
1262
+
1263
+ .section-header svg { color: var(--color-text-muted); flex-shrink: 0; }
1264
+ .section-header h2 { font-size: var(--text-lg); font-weight: 600; }
1265
+
1266
+ .section-desc {
1267
+ color: var(--color-text-secondary);
1268
+ font-size: var(--text-sm);
1269
+ margin-bottom: var(--sp-5);
1270
+ line-height: var(--leading-normal);
1271
+ }
1272
+
1273
+ .section-hint {
1274
+ color: var(--color-text-muted);
1275
+ font-size: var(--text-xs);
1276
+ margin-top: var(--sp-3);
1277
+ }
1278
+
1279
+ .section-hint code {
1280
+ background: var(--color-surface-3);
1281
+ padding: 1px 5px;
1282
+ border-radius: var(--radius-sm);
1283
+ font-family: var(--font-mono);
1284
+ }
1285
+
1286
+ .tunnel-status-badge {
1287
+ margin-left: auto;
1288
+ font-size: var(--text-xs);
1289
+ font-weight: 600;
1290
+ padding: 3px 10px;
1291
+ border-radius: var(--radius-full);
1292
+ text-transform: uppercase;
1293
+ letter-spacing: 0.05em;
1294
+ background: var(--color-surface-3);
1295
+ color: var(--color-text-muted);
1296
+ }
1297
+
1298
+ .tunnel-status-badge.connected { background: var(--color-success-subtle); color: var(--color-success); }
1299
+ .tunnel-status-badge.connecting { background: var(--color-warning-subtle); color: var(--color-warning); }
1300
+ .tunnel-status-badge.error { background: var(--color-danger-subtle); color: var(--color-danger); }
1301
+
1302
+ .tunnel-buttons { display: flex; gap: var(--sp-3); }
1303
+
1304
+ .tunnel-active-card {
1305
+ display: flex;
1306
+ align-items: center;
1307
+ justify-content: space-between;
1308
+ background: var(--color-surface-2);
1309
+ border: 1px solid var(--color-border);
1310
+ border-radius: var(--radius-md);
1311
+ padding: var(--sp-4);
1312
+ margin-bottom: var(--sp-3);
1313
+ }
1314
+
1315
+ .tunnel-url-row { display: flex; align-items: center; gap: var(--sp-3); }
1316
+
1317
+ .tunnel-label {
1318
+ font-size: var(--text-xs);
1319
+ color: var(--color-text-muted);
1320
+ text-transform: uppercase;
1321
+ letter-spacing: 0.05em;
1322
+ }
1323
+
1324
+ .tunnel-url {
1325
+ font-family: var(--font-mono);
1326
+ font-size: var(--text-sm);
1327
+ color: var(--color-primary-hover);
1328
+ text-decoration: none;
1329
+ }
1330
+
1331
+ .tunnel-url:hover { text-decoration: underline; }
1332
+
1333
+ .integration-card {
1334
+ background: var(--color-surface);
1335
+ border: 1px solid var(--color-border);
1336
+ border-radius: var(--radius-lg);
1337
+ padding: var(--sp-6);
1338
+ margin-bottom: var(--sp-4);
1339
+ transition: border-color var(--duration-fast) var(--ease);
1340
+ }
1341
+
1342
+ .integration-card:hover { border-color: var(--color-text-muted); }
1343
+
1344
+ .integration-card h4 {
1345
+ font-size: var(--text-md);
1346
+ font-weight: 600;
1347
+ margin-bottom: var(--sp-3);
1348
+ display: flex;
1349
+ align-items: center;
1350
+ gap: var(--sp-3);
1351
+ }
1352
+
1353
+ .source-badge {
1354
+ font-size: var(--text-xs);
1355
+ font-weight: 700;
1356
+ padding: 3px 10px;
1357
+ border-radius: var(--radius-full);
1358
+ text-transform: uppercase;
1359
+ letter-spacing: 0.05em;
1360
+ }
1361
+
1362
+ .source-badge.jira { background: #1868db; color: #fff; }
1363
+ .source-badge.linear { background: #5e6ad2; color: #fff; }
1364
+
1365
+ /* ============================================================
1366
+ Toast
1367
+ ============================================================ */
1368
+ #toast-container {
1369
+ position: fixed;
1370
+ bottom: var(--sp-6);
1371
+ right: var(--sp-6);
1372
+ z-index: 300;
1373
+ display: flex;
1374
+ flex-direction: column;
1375
+ gap: var(--sp-2);
1376
+ }
1377
+
1378
+ .toast {
1379
+ background: var(--color-surface-2);
1380
+ border: 1px solid var(--color-border);
1381
+ border-radius: var(--radius-md);
1382
+ padding: var(--sp-3) var(--sp-5);
1383
+ font-size: var(--text-sm);
1384
+ font-weight: 500;
1385
+ color: var(--color-text);
1386
+ animation: slideIn var(--duration-base) var(--ease);
1387
+ max-width: 380px;
1388
+ box-shadow: var(--shadow-lg);
1389
+ }
1390
+
1391
+ .toast.error { border-left: 3px solid var(--color-danger); }
1392
+ .toast.success { border-left: 3px solid var(--color-success); }
1393
+ .toast.info { border-left: 3px solid var(--color-primary); }
1394
+
1395
+ /* ============================================================
1396
+ Animations
1397
+ ============================================================ */
1398
+ @keyframes fadeIn {
1399
+ from { opacity: 0; }
1400
+ to { opacity: 1; }
1401
+ }
1402
+
1403
+ @keyframes slideUp {
1404
+ from { opacity: 0; transform: translateY(16px) scale(0.97); }
1405
+ to { opacity: 1; transform: translateY(0) scale(1); }
1406
+ }
1407
+
1408
+ @keyframes slideIn {
1409
+ from { transform: translateX(100%); opacity: 0; }
1410
+ to { transform: translateX(0); opacity: 1; }
1411
+ }
1412
+
1413
+ /* ============================================================
1414
+ Tree Folder
1415
+ ============================================================ */
1416
+ .tree-folder { cursor: pointer !important; }
1417
+ .tree-folder:hover { background: var(--color-surface-hover) !important; }
1418
+
1419
+ .tree-chevron {
1420
+ flex-shrink: 0;
1421
+ color: var(--color-text-muted);
1422
+ transition: transform var(--duration-fast) var(--ease);
1423
+ }
1424
+
1425
+ .tree-chevron.expanded { transform: rotate(90deg); }
1426
+
1427
+ /* ============================================================
1428
+ File Status Labels
1429
+ ============================================================ */
1430
+ .status-label-tag {
1431
+ margin-left: auto;
1432
+ font-size: 10px;
1433
+ font-weight: 700;
1434
+ width: 18px;
1435
+ height: 18px;
1436
+ display: flex;
1437
+ align-items: center;
1438
+ justify-content: center;
1439
+ border-radius: var(--radius-sm);
1440
+ flex-shrink: 0;
1441
+ }
1442
+
1443
+ .status-label-tag.modified { color: var(--color-warning); background: var(--color-warning-subtle); }
1444
+ .status-label-tag.added { color: var(--color-success); background: var(--color-success-subtle); }
1445
+ .status-label-tag.deleted { color: var(--color-danger); background: var(--color-danger-subtle); }
1446
+ .status-label-tag.untracked { color: var(--color-text-secondary); background: var(--color-surface-3); }
1447
+ .status-label-tag.renamed { color: var(--color-purple); background: var(--color-purple-subtle); }
1448
+
1449
+ .file-status-deleted .file-name { text-decoration: line-through; color: var(--color-text-muted); }
1450
+ .file-status-untracked .file-name { color: var(--color-text-muted); font-style: italic; }
1451
+ .file-status-added .file-name { color: var(--color-success); }
1452
+
1453
+ /* ============================================================
1454
+ Rules Tab
1455
+ ============================================================ */
1456
+ .rules-container { max-width: 800px; width: 100%; }
1457
+
1458
+ .preset-rules {
1459
+ display: flex;
1460
+ align-items: center;
1461
+ flex-wrap: wrap;
1462
+ gap: var(--sp-2);
1463
+ margin-bottom: var(--sp-5);
1464
+ padding: var(--sp-3) var(--sp-4);
1465
+ background: var(--color-surface);
1466
+ border: 1px dashed var(--color-border);
1467
+ border-radius: var(--radius-md);
1468
+ }
1469
+
1470
+ .preset-label {
1471
+ font-size: var(--text-xs);
1472
+ color: var(--color-text-muted);
1473
+ text-transform: uppercase;
1474
+ letter-spacing: 0.05em;
1475
+ font-weight: 600;
1476
+ margin-right: var(--sp-2);
1477
+ }
1478
+
1479
+ .preset-btn { font-size: var(--text-xs) !important; }
1480
+
1481
+ .rules-list { display: flex; flex-direction: column; gap: var(--sp-2); }
1482
+
1483
+ .rule-card {
1484
+ display: flex;
1485
+ align-items: flex-start;
1486
+ gap: var(--sp-4);
1487
+ padding: var(--sp-4) var(--sp-5);
1488
+ background: var(--color-surface);
1489
+ border: 1px solid var(--color-border);
1490
+ border-radius: var(--radius-md);
1491
+ transition: all var(--duration-fast) var(--ease);
1492
+ }
1493
+
1494
+ .rule-card:hover { border-color: var(--color-text-muted); }
1495
+ .rule-card.inactive { opacity: 0.5; }
1496
+ .rule-card.inactive .rule-text { text-decoration: line-through; }
1497
+ .rule-card.protected { border-left: 3px solid var(--color-warning); }
1498
+
1499
+ .rule-toggle {
1500
+ position: relative;
1501
+ display: inline-block;
1502
+ width: 36px;
1503
+ height: 20px;
1504
+ flex-shrink: 0;
1505
+ margin-top: 2px;
1506
+ }
1507
+
1508
+ .rule-toggle input { opacity: 0; width: 0; height: 0; }
1509
+
1510
+ .rule-toggle-slider {
1511
+ position: absolute;
1512
+ cursor: pointer;
1513
+ inset: 0;
1514
+ background: var(--color-surface-3);
1515
+ border-radius: 20px;
1516
+ transition: background var(--duration-fast) var(--ease);
1517
+ }
1518
+
1519
+ .rule-toggle-slider::before {
1520
+ content: '';
1521
+ position: absolute;
1522
+ height: 14px;
1523
+ width: 14px;
1524
+ left: 3px;
1525
+ bottom: 3px;
1526
+ background: var(--color-text-muted);
1527
+ border-radius: 50%;
1528
+ transition: transform var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
1529
+ }
1530
+
1531
+ .rule-toggle input:checked + .rule-toggle-slider { background: var(--color-primary-subtle); }
1532
+ .rule-toggle input:checked + .rule-toggle-slider::before { transform: translateX(16px); background: var(--color-primary); }
1533
+
1534
+ .rule-content { flex: 1; min-width: 0; }
1535
+
1536
+ .rule-text {
1537
+ font-size: var(--text-sm);
1538
+ line-height: var(--leading-normal);
1539
+ color: var(--color-text);
1540
+ word-break: break-word;
1541
+ }
1542
+
1543
+ .rule-default-badge {
1544
+ display: inline-block;
1545
+ margin-top: var(--sp-2);
1546
+ font-size: 9px;
1547
+ font-weight: 700;
1548
+ letter-spacing: 0.08em;
1549
+ padding: 2px 6px;
1550
+ background: var(--color-warning-subtle);
1551
+ color: var(--color-warning);
1552
+ border-radius: var(--radius-sm);
1553
+ }
1554
+
1555
+ .rule-actions { flex-shrink: 0; display: flex; align-items: center; }
1556
+ .rule-lock { color: var(--color-warning); padding: var(--sp-2); display: inline-flex; }
1557
+ .rule-delete { color: var(--color-text-muted) !important; }
1558
+ .rule-delete:hover { color: var(--color-danger) !important; background: var(--color-danger-subtle) !important; }
1559
+
1560
+ .commit-approval-banner {
1561
+ display: flex;
1562
+ align-items: center;
1563
+ gap: var(--sp-4);
1564
+ padding: var(--sp-4) var(--sp-5);
1565
+ background: var(--color-warning-subtle);
1566
+ border: 1px solid var(--color-warning);
1567
+ border-radius: var(--radius-lg);
1568
+ margin-bottom: var(--sp-5);
1569
+ animation: pulse-warning 2s ease-in-out infinite;
1570
+ }
1571
+
1572
+ @keyframes pulse-warning {
1573
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(234, 179, 8, 0.4); }
1574
+ 50% { box-shadow: 0 0 0 8px rgba(234, 179, 8, 0); }
1575
+ }
1576
+
1577
+ .commit-approval-icon { color: var(--color-warning); flex-shrink: 0; display: inline-flex; }
1578
+ .commit-approval-body { flex: 1; min-width: 0; }
1579
+ .commit-approval-title { font-size: var(--text-base); font-weight: 600; color: var(--color-text); }
1580
+ .commit-approval-message { font-size: var(--text-sm); color: var(--color-text-secondary); margin-top: 2px; word-break: break-word; }
1581
+ .commit-approval-actions { display: flex; gap: var(--sp-2); flex-shrink: 0; }
1582
+
1583
+ .commit-approved-banner {
1584
+ display: flex;
1585
+ align-items: center;
1586
+ gap: var(--sp-3);
1587
+ padding: var(--sp-3) var(--sp-4);
1588
+ background: var(--color-success-subtle);
1589
+ border: 1px solid var(--color-success);
1590
+ border-radius: var(--radius-md);
1591
+ margin-bottom: var(--sp-4);
1592
+ color: var(--color-success);
1593
+ font-size: var(--text-sm);
1594
+ font-weight: 500;
1595
+ }
1596
+
1597
+ /* ============================================================
1598
+ Responsive
1599
+ ============================================================ */
1600
+ @media (max-width: 900px) {
1601
+ #sidebar { width: var(--sidebar-collapsed); padding: var(--sp-2); }
1602
+ .brand-name, .nav-item span, .status-label { display: none; }
1603
+ .sidebar-brand { justify-content: center; margin-bottom: var(--sp-4); }
1604
+ .nav-item { justify-content: center; padding: var(--sp-3); }
1605
+ #main-content { margin-left: var(--sidebar-collapsed); width: calc(100vw - var(--sidebar-collapsed)); }
1606
+ .view-header { left: var(--sidebar-collapsed); }
1607
+ .kanban-board { flex-direction: column; }
1608
+ .kanban-column { min-width: unset; max-height: none; }
1609
+ .diff-container { flex-direction: column; }
1610
+ .file-list { position: static; width: 100%; max-height: 200px; bottom: auto; }
1611
+ .diff-output { margin-left: 0; }
1612
+ .form-row { flex-direction: column; gap: 0; }
1613
+ }