@hmduc16031996/claude-mb-bridge 2.0.0 → 2.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.
@@ -0,0 +1,1970 @@
1
+ /* Claude Code Remote - Functional Terminal Interface */
2
+
3
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap');
4
+
5
+ :root {
6
+ /* GitHub Dark Theme Base */
7
+ --bg-deep: #262624;
8
+ --bg-primary: #30302E;
9
+ --bg-elevated: #3c3c3a;
10
+ --bg-surface: #464644;
11
+ --bg-hover: #525250;
12
+
13
+ /* Text hierarchy */
14
+ --text-primary: #f0f6fc;
15
+ --text-secondary: #8b949e;
16
+ --text-muted: #6e7681;
17
+
18
+ /* Accent - Surgical use only */
19
+ --accent: #58a6ff;
20
+ --accent-hover: #79c0ff;
21
+ --accent-soft: rgba(88, 166, 255, 0.15);
22
+
23
+ /* Semantic colors */
24
+ --success: #3fb950;
25
+ --error: #f85149;
26
+ --warning: #d29922;
27
+
28
+ /* Borders & Shadows */
29
+ --border: rgba(240, 246, 252, 0.1);
30
+ --shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
31
+
32
+ /* Typography */
33
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
34
+ --font-mono: 'JetBrains Mono', 'SF Mono', Menlo, Monaco, monospace;
35
+
36
+ /* Sizing */
37
+ --radius: 6px;
38
+
39
+ /* Transitions - functional only */
40
+ --transition: 150ms ease;
41
+ }
42
+
43
+ /* Reset & Base */
44
+ *, *::before, *::after {
45
+ box-sizing: border-box;
46
+ margin: 0;
47
+ padding: 0;
48
+ }
49
+
50
+ html, body {
51
+ height: 100%;
52
+ overflow: hidden;
53
+ }
54
+
55
+ body {
56
+ font-family: var(--font-sans);
57
+ background: var(--bg-deep);
58
+ color: var(--text-primary);
59
+ -webkit-font-smoothing: antialiased;
60
+ -moz-osx-font-smoothing: grayscale;
61
+ line-height: 1.5;
62
+ }
63
+
64
+ #app {
65
+ width: 100%;
66
+ height: 100%;
67
+ display: flex;
68
+ flex-direction: column;
69
+ position: relative;
70
+ z-index: 1;
71
+ }
72
+
73
+ /* ===== SCREENS ===== */
74
+ .screen {
75
+ display: none;
76
+ width: 100%;
77
+ height: 100%;
78
+ min-height: 0;
79
+ flex-direction: column;
80
+ }
81
+
82
+ .screen.active {
83
+ display: flex;
84
+ flex: 1;
85
+ }
86
+
87
+ /* ===== AUTH SCREEN ===== */
88
+ #auth-screen {
89
+ justify-content: center;
90
+ align-items: center;
91
+ min-height: 100vh;
92
+ padding: 1.5rem;
93
+ background: var(--bg-deep);
94
+ }
95
+
96
+ .auth-container {
97
+ width: 100%;
98
+ max-width: 380px;
99
+ text-align: center;
100
+ }
101
+
102
+ /* Auth Logo */
103
+ .auth-logo {
104
+ margin-bottom: 1.5rem;
105
+ }
106
+
107
+ .auth-container h1 {
108
+ font-size: 1.75rem;
109
+ font-weight: 600;
110
+ margin-bottom: 0.5rem;
111
+ color: var(--text-primary);
112
+ letter-spacing: -0.01em;
113
+ }
114
+
115
+ .auth-container .subtitle {
116
+ color: var(--text-secondary);
117
+ font-size: 0.9375rem;
118
+ margin-bottom: 2rem;
119
+ line-height: 1.5;
120
+ }
121
+
122
+ /* Auth Input */
123
+ .auth-container input {
124
+ width: 100%;
125
+ padding: 0.75rem 1rem;
126
+ font-size: 0.9375rem;
127
+ font-family: var(--font-mono);
128
+ letter-spacing: 0.05em;
129
+ background: var(--bg-surface);
130
+ color: var(--text-primary);
131
+ border: 1px solid var(--border);
132
+ border-radius: var(--radius);
133
+ margin-bottom: 1rem;
134
+ text-align: center;
135
+ transition: border-color var(--transition), box-shadow var(--transition);
136
+ }
137
+
138
+ .auth-container input::placeholder {
139
+ color: var(--text-muted);
140
+ letter-spacing: 0;
141
+ }
142
+
143
+ .auth-container input:focus {
144
+ outline: none;
145
+ border-color: var(--accent);
146
+ box-shadow: 0 0 0 2px var(--accent-soft);
147
+ }
148
+
149
+ .auth-container .error {
150
+ color: var(--error);
151
+ font-size: 0.875rem;
152
+ margin-top: 1rem;
153
+ min-height: 1.5rem;
154
+ padding: 0.5rem;
155
+ border-radius: var(--radius);
156
+ background: rgba(248, 81, 73, 0.1);
157
+ }
158
+
159
+ .auth-container .error:empty {
160
+ display: none;
161
+ }
162
+
163
+ /* ===== BUTTONS ===== */
164
+ .btn-primary {
165
+ width: 100%;
166
+ padding: 0.75rem 1.25rem;
167
+ font-size: 0.9375rem;
168
+ font-weight: 500;
169
+ font-family: var(--font-sans);
170
+ background: var(--accent);
171
+ color: var(--bg-deep);
172
+ border: none;
173
+ border-radius: var(--radius);
174
+ cursor: pointer;
175
+ transition: background var(--transition);
176
+ }
177
+
178
+ .btn-primary:hover:not(:disabled) {
179
+ background: var(--accent-hover);
180
+ }
181
+
182
+ .btn-primary:active:not(:disabled) {
183
+ transform: translateY(1px);
184
+ }
185
+
186
+ .btn-primary:disabled {
187
+ opacity: 0.5;
188
+ cursor: not-allowed;
189
+ }
190
+
191
+ /* Button loading state */
192
+ .btn-primary .btn-text,
193
+ .btn-primary .btn-loading {
194
+ display: inline-flex;
195
+ align-items: center;
196
+ justify-content: center;
197
+ }
198
+
199
+ .btn-primary .btn-loading {
200
+ display: none;
201
+ }
202
+
203
+ .btn-primary.loading .btn-text {
204
+ display: none;
205
+ }
206
+
207
+ .btn-primary.loading .btn-loading {
208
+ display: inline-flex;
209
+ }
210
+
211
+ .btn-primary .spinner {
212
+ animation: spin 1s linear infinite;
213
+ }
214
+
215
+ @keyframes spin {
216
+ from {
217
+ transform: rotate(0deg);
218
+ }
219
+ to {
220
+ transform: rotate(360deg);
221
+ }
222
+ }
223
+
224
+ .btn-secondary {
225
+ padding: 0.625rem 1rem;
226
+ font-size: 0.875rem;
227
+ font-family: var(--font-sans);
228
+ background: var(--bg-surface);
229
+ color: var(--text-primary);
230
+ border: 1px solid var(--border);
231
+ border-radius: var(--radius);
232
+ cursor: pointer;
233
+ transition: background var(--transition);
234
+ }
235
+
236
+ .btn-secondary:hover {
237
+ background: var(--bg-hover);
238
+ }
239
+
240
+ .btn-icon {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ justify-content: center;
244
+ width: 36px;
245
+ height: 36px;
246
+ padding: 0;
247
+ background: transparent;
248
+ color: var(--text-secondary);
249
+ border: 1px solid var(--border);
250
+ border-radius: var(--radius);
251
+ cursor: pointer;
252
+ transition: all var(--transition);
253
+ flex-shrink: 0;
254
+ }
255
+
256
+ .btn-icon:hover {
257
+ color: var(--text-primary);
258
+ background: rgba(240, 246, 252, 0.05);
259
+ border-color: var(--text-muted);
260
+ }
261
+
262
+ .btn-icon:active {
263
+ transform: scale(0.96);
264
+ }
265
+
266
+ .btn-icon-minimal {
267
+ display: inline-flex;
268
+ align-items: center;
269
+ justify-content: center;
270
+ width: 32px;
271
+ height: 32px;
272
+ padding: 0;
273
+ background: transparent;
274
+ color: var(--text-secondary);
275
+ border: none;
276
+ border-radius: var(--radius);
277
+ cursor: pointer;
278
+ transition: all var(--transition);
279
+ flex-shrink: 0;
280
+ }
281
+
282
+ .btn-icon-minimal:hover {
283
+ color: var(--text-primary);
284
+ background: rgba(240, 246, 252, 0.05);
285
+ }
286
+
287
+ .btn-icon-minimal:active {
288
+ transform: scale(0.96);
289
+ }
290
+
291
+ /* Chevron rotation for toggle button */
292
+ .btn-icon .chevron-icon,
293
+ .btn-icon-minimal .chevron-icon {
294
+ transition: transform var(--transition);
295
+ }
296
+
297
+ .btn-icon[aria-expanded="false"] .chevron-icon,
298
+ .btn-icon-minimal[aria-expanded="false"] .chevron-icon {
299
+ transform: rotate(180deg);
300
+ }
301
+
302
+
303
+ /* ===== MAIN SCREEN ===== */
304
+ #main-screen {
305
+ background: var(--bg-deep);
306
+ }
307
+
308
+ #main-screen header {
309
+ display: flex;
310
+ justify-content: space-between;
311
+ align-items: center;
312
+ padding: 0.875rem 1.25rem;
313
+ padding-top: max(0.875rem, env(safe-area-inset-top));
314
+ background: var(--bg-primary);
315
+ border-bottom: 1px solid var(--border);
316
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
317
+ flex-shrink: 0;
318
+ transition: transform var(--transition), opacity var(--transition);
319
+ z-index: 10;
320
+ min-height: 56px;
321
+ }
322
+
323
+ #main-screen header.collapsed {
324
+ position: absolute;
325
+ top: 0;
326
+ left: 0;
327
+ right: 0;
328
+ transform: translateY(-100%);
329
+ opacity: 0;
330
+ pointer-events: none;
331
+ }
332
+
333
+ /* Floating expand button */
334
+ .floating-btn {
335
+ position: absolute;
336
+ top: max(0.5rem, env(safe-area-inset-top));
337
+ right: max(0.5rem, env(safe-area-inset-right));
338
+ z-index: 5;
339
+ background: var(--bg-elevated);
340
+ border: 1px solid var(--border);
341
+ box-shadow: var(--shadow);
342
+ }
343
+
344
+ /* Reconnect Indicator */
345
+ .reconnect-indicator {
346
+ display: flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ color: var(--text-muted);
350
+ opacity: 0.7;
351
+ }
352
+
353
+ .reconnect-indicator svg {
354
+ animation: spin 1s linear infinite;
355
+ }
356
+
357
+ @keyframes spin {
358
+ from { transform: rotate(0deg); }
359
+ to { transform: rotate(360deg); }
360
+ }
361
+
362
+ .btn-small {
363
+ padding: 0.5rem 1rem;
364
+ font-size: 0.8125rem;
365
+ }
366
+
367
+ .header-left, .header-right {
368
+ display: flex;
369
+ gap: 0.75rem;
370
+ align-items: center;
371
+ }
372
+
373
+ .header-left-actions {
374
+ display: flex;
375
+ align-items: center;
376
+ gap: 0.375rem;
377
+ margin-left: 0.25rem;
378
+ }
379
+
380
+ /* Session Select (Mobile) */
381
+ #session-select {
382
+ padding: 0.5rem 2rem 0.5rem 0.75rem;
383
+ font-size: 0.8125rem;
384
+ font-family: var(--font-mono);
385
+ background: var(--bg-surface);
386
+ color: var(--text-primary);
387
+ border: 1px solid var(--border);
388
+ border-radius: var(--radius);
389
+ min-width: 140px;
390
+ max-width: 200px;
391
+ cursor: pointer;
392
+ transition: border-color var(--transition);
393
+ appearance: none;
394
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b949e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
395
+ background-repeat: no-repeat;
396
+ background-position: right 0.625rem center;
397
+ }
398
+
399
+ #session-select:hover {
400
+ border-color: var(--text-muted);
401
+ }
402
+
403
+ #session-select:focus {
404
+ outline: none;
405
+ border-color: var(--accent);
406
+ box-shadow: 0 0 0 2px var(--accent-soft);
407
+ }
408
+
409
+ /* Session Tabs (Desktop) */
410
+ .session-tabs {
411
+ display: flex;
412
+ gap: 0.375rem;
413
+ align-items: center;
414
+ overflow: visible;
415
+ max-width: 50vw;
416
+ }
417
+
418
+ .session-tabs::-webkit-scrollbar {
419
+ display: none;
420
+ }
421
+
422
+ .session-tab {
423
+ display: inline-flex;
424
+ align-items: center;
425
+ gap: 0.5rem;
426
+ padding: 0.5rem 0.875rem;
427
+ font-size: 0.8125rem;
428
+ font-family: var(--font-mono);
429
+ background: transparent;
430
+ color: var(--text-secondary);
431
+ border: 1px solid var(--border);
432
+ border-radius: var(--radius);
433
+ cursor: pointer;
434
+ transition: all var(--transition);
435
+ white-space: nowrap;
436
+ flex-shrink: 0;
437
+ position: relative;
438
+ }
439
+
440
+ .session-tab:hover {
441
+ color: var(--text-primary);
442
+ background: rgba(240, 246, 252, 0.03);
443
+ }
444
+
445
+ .session-tab[aria-selected="true"] {
446
+ color: var(--text-primary);
447
+ background: rgba(88, 166, 255, 0.1);
448
+ border-color: var(--accent);
449
+ }
450
+
451
+ .session-tab:active {
452
+ transform: scale(0.98);
453
+ }
454
+
455
+ .session-tab-name {
456
+ max-width: 140px;
457
+ overflow: hidden;
458
+ text-overflow: ellipsis;
459
+ }
460
+
461
+ .session-tab-close {
462
+ display: inline-flex;
463
+ align-items: center;
464
+ justify-content: center;
465
+ width: 18px;
466
+ height: 18px;
467
+ font-size: 0.875rem;
468
+ line-height: 1;
469
+ color: var(--text-muted);
470
+ border-radius: 3px;
471
+ transition: all var(--transition);
472
+ margin-left: 0.375rem;
473
+ margin-right: -0.25rem;
474
+ opacity: 0.6;
475
+ }
476
+
477
+ .session-tab:hover .session-tab-close {
478
+ opacity: 1;
479
+ }
480
+
481
+ .session-tab-close:hover {
482
+ background: rgba(248, 81, 73, 0.15);
483
+ color: var(--error);
484
+ }
485
+
486
+ .session-tab-empty {
487
+ padding: 0.5rem 0.875rem;
488
+ font-size: 0.8125rem;
489
+ color: var(--text-muted);
490
+ font-style: italic;
491
+ background: transparent;
492
+ border: none;
493
+ }
494
+
495
+ /* Activity Status Indicators */
496
+ .activity-indicator {
497
+ font-size: 0.625rem;
498
+ line-height: 1;
499
+ flex-shrink: 0;
500
+ width: 1em;
501
+ text-align: center;
502
+ transition: color var(--transition);
503
+ }
504
+
505
+ .activity-indicator[data-status="busy"] {
506
+ color: var(--success);
507
+ }
508
+
509
+ .activity-indicator[data-status="idle"] {
510
+ color: var(--text-muted);
511
+ }
512
+
513
+ .activity-indicator[data-status="unknown"] {
514
+ color: var(--text-muted);
515
+ opacity: 0.5;
516
+ }
517
+
518
+ /* Highlight busy sessions in the dropdown */
519
+ #session-select option[data-status="busy"] {
520
+ color: var(--success);
521
+ }
522
+
523
+ /* External Sessions Button */
524
+ .external-sessions-btn {
525
+ display: inline-flex;
526
+ align-items: center;
527
+ gap: 0.375rem;
528
+ padding: 0.5rem 0.75rem;
529
+ font-size: 0.75rem;
530
+ font-family: var(--font-sans);
531
+ background: transparent;
532
+ color: var(--text-muted);
533
+ border: 1px solid var(--border);
534
+ border-radius: var(--radius);
535
+ cursor: pointer;
536
+ transition: all var(--transition);
537
+ white-space: nowrap;
538
+ flex-shrink: 0;
539
+ position: relative;
540
+ }
541
+
542
+ .external-sessions-btn:hover {
543
+ color: var(--text-primary);
544
+ background: rgba(240, 246, 252, 0.03);
545
+ }
546
+
547
+ .external-sessions-badge {
548
+ display: inline-flex;
549
+ align-items: center;
550
+ justify-content: center;
551
+ min-width: 18px;
552
+ height: 18px;
553
+ padding: 0 0.25rem;
554
+ font-size: 0.6875rem;
555
+ font-weight: 600;
556
+ background: var(--accent);
557
+ color: white;
558
+ border-radius: 9px;
559
+ line-height: 1;
560
+ }
561
+
562
+ /* External Sessions Dropdown */
563
+ .external-sessions-dropdown {
564
+ position: absolute;
565
+ top: calc(100% + 0.5rem);
566
+ left: 0;
567
+ min-width: 240px;
568
+ max-width: 320px;
569
+ background: var(--bg-elevated);
570
+ border: 1px solid var(--border);
571
+ border-radius: var(--radius);
572
+ box-shadow: var(--shadow);
573
+ z-index: 100;
574
+ opacity: 0;
575
+ visibility: hidden;
576
+ transform: translateY(-0.5rem);
577
+ transition: all var(--transition);
578
+ }
579
+
580
+ .external-sessions-dropdown.visible {
581
+ opacity: 1;
582
+ visibility: visible;
583
+ transform: translateY(0);
584
+ }
585
+
586
+ .external-session-item {
587
+ display: flex;
588
+ align-items: center;
589
+ gap: 0.5rem;
590
+ padding: 0.75rem 1rem;
591
+ font-size: 0.8125rem;
592
+ font-family: var(--font-mono);
593
+ color: var(--text-primary);
594
+ cursor: pointer;
595
+ transition: background var(--transition);
596
+ border-bottom: 1px solid var(--border);
597
+ }
598
+
599
+ .external-session-item .activity-indicator {
600
+ font-size: 0.75rem;
601
+ }
602
+
603
+ .external-session-item:last-child {
604
+ border-bottom: none;
605
+ }
606
+
607
+ .external-session-item:hover {
608
+ background: rgba(240, 246, 252, 0.05);
609
+ }
610
+
611
+ .external-session-info {
612
+ flex: 1;
613
+ min-width: 0;
614
+ }
615
+
616
+ .external-session-name {
617
+ overflow: hidden;
618
+ text-overflow: ellipsis;
619
+ white-space: nowrap;
620
+ margin-bottom: 0.25rem;
621
+ }
622
+
623
+ .external-session-path {
624
+ font-size: 0.6875rem;
625
+ color: var(--text-muted);
626
+ overflow: hidden;
627
+ text-overflow: ellipsis;
628
+ white-space: nowrap;
629
+ }
630
+
631
+ .external-session-pid {
632
+ display: none;
633
+ border-radius: 3px;
634
+ margin-left: 0.75rem;
635
+ flex-shrink: 0;
636
+ }
637
+
638
+ /* Responsive: Mobile/Desktop visibility */
639
+ .mobile-only {
640
+ display: block;
641
+ }
642
+
643
+ .desktop-only {
644
+ display: none;
645
+ }
646
+
647
+ @media (min-width: 768px) {
648
+ .mobile-only {
649
+ display: none;
650
+ }
651
+
652
+ .desktop-only {
653
+ display: flex;
654
+ }
655
+ }
656
+
657
+ /* ===== TERMINAL CONTAINER ===== */
658
+ #terminal-container {
659
+ flex: 1;
660
+ overflow: hidden;
661
+ background: var(--bg-deep);
662
+ position: relative;
663
+ /* Create stacking context so overlay z-index is contained within */
664
+ z-index: 0;
665
+ }
666
+
667
+ /* Terminal top separator */
668
+ #terminal-container::before {
669
+ content: '';
670
+ position: absolute;
671
+ top: 0;
672
+ left: 0;
673
+ right: 0;
674
+ height: 1px;
675
+ background: var(--border);
676
+ pointer-events: none;
677
+ z-index: 1;
678
+ opacity: 0.5;
679
+ }
680
+
681
+ #terminal-container .xterm {
682
+ height: 100%;
683
+ padding: 8px 12px;
684
+ }
685
+
686
+ #terminal-container .xterm-viewport {
687
+ overflow-y: auto !important;
688
+ -webkit-overflow-scrolling: touch;
689
+ }
690
+
691
+ #terminal-container .xterm-viewport::-webkit-scrollbar {
692
+ width: 8px;
693
+ }
694
+
695
+ #terminal-container .xterm-viewport::-webkit-scrollbar-track {
696
+ background: transparent;
697
+ }
698
+
699
+ #terminal-container .xterm-viewport::-webkit-scrollbar-thumb {
700
+ background: var(--bg-hover);
701
+ border-radius: 4px;
702
+ }
703
+
704
+ #terminal-container .xterm-viewport::-webkit-scrollbar-thumb:hover {
705
+ background: var(--text-muted);
706
+ }
707
+
708
+ /* ===== PREVIEW SCREEN ===== */
709
+ #preview-screen {
710
+ background: var(--bg-deep);
711
+ }
712
+
713
+ #preview-screen header {
714
+ display: flex;
715
+ gap: 0.75rem;
716
+ padding: 0.75rem 1rem;
717
+ padding-top: max(0.75rem, env(safe-area-inset-top));
718
+ background: var(--bg-primary);
719
+ border-bottom: 1px solid var(--border);
720
+ flex-shrink: 0;
721
+ }
722
+
723
+ #port-select {
724
+ flex: 1;
725
+ padding: 0.5rem 2rem 0.5rem 0.75rem;
726
+ font-size: 0.8125rem;
727
+ font-family: var(--font-mono);
728
+ background: var(--bg-surface);
729
+ color: var(--text-primary);
730
+ border: 1px solid var(--border);
731
+ border-radius: var(--radius);
732
+ cursor: pointer;
733
+ transition: border-color var(--transition);
734
+ appearance: none;
735
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b949e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
736
+ background-repeat: no-repeat;
737
+ background-position: right 0.625rem center;
738
+ }
739
+
740
+ #port-select:hover {
741
+ border-color: var(--text-muted);
742
+ }
743
+
744
+ #port-select:focus {
745
+ outline: none;
746
+ border-color: var(--accent);
747
+ box-shadow: 0 0 0 2px var(--accent-soft);
748
+ }
749
+
750
+ #port-input {
751
+ width: 80px;
752
+ padding: 0.5rem 0.625rem;
753
+ font-size: 0.8125rem;
754
+ font-family: var(--font-mono);
755
+ background: var(--bg-surface);
756
+ color: var(--text-primary);
757
+ border: 1px solid var(--border);
758
+ border-radius: var(--radius);
759
+ transition: border-color var(--transition);
760
+ -moz-appearance: textfield;
761
+ }
762
+
763
+ #port-input::-webkit-outer-spin-button,
764
+ #port-input::-webkit-inner-spin-button {
765
+ -webkit-appearance: none;
766
+ margin: 0;
767
+ }
768
+
769
+ #port-input:hover {
770
+ border-color: var(--text-muted);
771
+ }
772
+
773
+ #port-input:focus {
774
+ outline: none;
775
+ border-color: var(--accent);
776
+ box-shadow: 0 0 0 2px var(--accent-soft);
777
+ }
778
+
779
+ #port-input::placeholder {
780
+ color: var(--text-muted);
781
+ }
782
+
783
+ /* Address Bar */
784
+ .preview-address-bar {
785
+ display: flex;
786
+ gap: 0.5rem;
787
+ padding: 0.5rem 1rem;
788
+ background: var(--bg-deep);
789
+ border-bottom: 1px solid var(--border);
790
+ flex-shrink: 0;
791
+ }
792
+
793
+ #address-input {
794
+ flex: 1;
795
+ padding: 0.5rem 0.75rem;
796
+ font-size: 0.8125rem;
797
+ font-family: var(--font-mono);
798
+ background: var(--bg-surface);
799
+ color: var(--text-primary);
800
+ border: 1px solid var(--border);
801
+ border-radius: var(--radius);
802
+ transition: border-color var(--transition);
803
+ }
804
+
805
+ #address-input:hover {
806
+ border-color: var(--text-muted);
807
+ }
808
+
809
+ #address-input:focus {
810
+ outline: none;
811
+ border-color: var(--accent);
812
+ box-shadow: 0 0 0 2px var(--accent-soft);
813
+ }
814
+
815
+ #address-input::placeholder {
816
+ color: var(--text-muted);
817
+ }
818
+
819
+ #preview-frame {
820
+ flex: 1;
821
+ width: 100%;
822
+ border: none;
823
+ background: #fff;
824
+ border-radius: 0;
825
+ }
826
+
827
+ /* ===== MODAL ===== */
828
+ .modal {
829
+ position: fixed;
830
+ inset: 0;
831
+ display: flex;
832
+ align-items: center;
833
+ justify-content: center;
834
+ padding: 1rem;
835
+ background: rgba(13, 17, 23, 0.8);
836
+ z-index: 100;
837
+ }
838
+
839
+ .modal.hidden {
840
+ display: none;
841
+ }
842
+
843
+ .modal-content {
844
+ width: 100%;
845
+ max-width: 400px;
846
+ padding: 1.5rem;
847
+ background: var(--bg-elevated);
848
+ border: 1px solid var(--border);
849
+ border-radius: var(--radius);
850
+ box-shadow: var(--shadow);
851
+ }
852
+
853
+ .modal-content h2 {
854
+ margin-bottom: 0.5rem;
855
+ font-size: 1.125rem;
856
+ font-weight: 600;
857
+ color: var(--text-primary);
858
+ }
859
+
860
+ .modal-description {
861
+ color: var(--text-secondary);
862
+ font-size: 0.875rem;
863
+ margin-bottom: 1rem;
864
+ line-height: 1.5;
865
+ }
866
+
867
+ .modal-content input {
868
+ width: 100%;
869
+ padding: 0.625rem 0.75rem;
870
+ font-size: 0.875rem;
871
+ font-family: var(--font-mono);
872
+ background: var(--bg-surface);
873
+ color: var(--text-primary);
874
+ border: 1px solid var(--border);
875
+ border-radius: var(--radius);
876
+ margin-bottom: 1rem;
877
+ transition: border-color var(--transition), box-shadow var(--transition);
878
+ }
879
+
880
+ .modal-content input::placeholder {
881
+ color: var(--text-muted);
882
+ }
883
+
884
+ .modal-content input:focus {
885
+ outline: none;
886
+ border-color: var(--accent);
887
+ box-shadow: 0 0 0 2px var(--accent-soft);
888
+ }
889
+
890
+ .modal-actions {
891
+ display: flex;
892
+ gap: 0.75rem;
893
+ justify-content: flex-end;
894
+ }
895
+
896
+ .modal-actions .btn-secondary {
897
+ flex: 1;
898
+ max-width: 120px;
899
+ }
900
+
901
+ .modal-actions .btn-primary {
902
+ flex: 1;
903
+ max-width: 140px;
904
+ }
905
+
906
+ /* Autocomplete */
907
+ .autocomplete-wrapper {
908
+ position: relative;
909
+ margin-bottom: 1.25rem;
910
+ }
911
+
912
+ .autocomplete-wrapper input {
913
+ margin-bottom: 0;
914
+ }
915
+
916
+ .suggestions {
917
+ position: absolute;
918
+ top: 100%;
919
+ left: 0;
920
+ right: 0;
921
+ margin-top: 0.25rem;
922
+ padding: 0.375rem 0;
923
+ list-style: none;
924
+ background: var(--bg-surface);
925
+ border: 1px solid var(--border);
926
+ border-radius: var(--radius);
927
+ box-shadow: var(--shadow);
928
+ max-height: 200px;
929
+ overflow-y: auto;
930
+ z-index: 10;
931
+ }
932
+
933
+ .suggestions li {
934
+ padding: 0.5rem 0.75rem;
935
+ font-family: var(--font-mono);
936
+ font-size: 0.8125rem;
937
+ color: var(--text-primary);
938
+ cursor: pointer;
939
+ transition: background var(--transition);
940
+ }
941
+
942
+ .suggestions li:hover,
943
+ .suggestions li.selected {
944
+ background: var(--bg-hover);
945
+ }
946
+
947
+ .suggestions li .dir-name {
948
+ color: var(--text-primary);
949
+ }
950
+
951
+ .suggestions li .dir-path {
952
+ color: var(--text-muted);
953
+ font-size: 0.75rem;
954
+ margin-left: 0.5rem;
955
+ }
956
+
957
+ /* ===== SETTINGS MODAL ===== */
958
+ .settings-content {
959
+ max-width: 380px;
960
+ }
961
+
962
+ .modal-header {
963
+ display: flex;
964
+ justify-content: space-between;
965
+ align-items: center;
966
+ margin-bottom: 1.5rem;
967
+ }
968
+
969
+ .modal-header h2 {
970
+ margin-bottom: 0;
971
+ }
972
+
973
+ .setting-row {
974
+ display: flex;
975
+ justify-content: space-between;
976
+ align-items: center;
977
+ gap: 1rem;
978
+ padding: 0.75rem 0;
979
+ }
980
+
981
+ .setting-info {
982
+ flex: 1;
983
+ }
984
+
985
+ .setting-info label {
986
+ display: block;
987
+ font-weight: 500;
988
+ color: var(--text-primary);
989
+ margin-bottom: 0.25rem;
990
+ }
991
+
992
+ .setting-description {
993
+ font-size: 0.8125rem;
994
+ color: var(--text-muted);
995
+ margin: 0;
996
+ line-height: 1.4;
997
+ }
998
+
999
+ /* Toggle Switch */
1000
+ .toggle {
1001
+ position: relative;
1002
+ width: 44px;
1003
+ height: 24px;
1004
+ padding: 0;
1005
+ background: none;
1006
+ border: none;
1007
+ cursor: pointer;
1008
+ flex-shrink: 0;
1009
+ }
1010
+
1011
+ .toggle-track {
1012
+ position: absolute;
1013
+ inset: 0;
1014
+ background: var(--bg-hover);
1015
+ border: 1px solid var(--border);
1016
+ border-radius: 12px;
1017
+ transition: background var(--transition), border-color var(--transition);
1018
+ }
1019
+
1020
+ .toggle-thumb {
1021
+ position: absolute;
1022
+ top: 2px;
1023
+ left: 2px;
1024
+ width: 18px;
1025
+ height: 18px;
1026
+ background: var(--text-secondary);
1027
+ border-radius: 50%;
1028
+ transition: transform var(--transition), background var(--transition);
1029
+ }
1030
+
1031
+ .toggle[aria-checked="true"] .toggle-track {
1032
+ background: var(--accent);
1033
+ border-color: var(--accent);
1034
+ }
1035
+
1036
+ .toggle[aria-checked="true"] .toggle-thumb {
1037
+ transform: translateX(20px);
1038
+ background: white;
1039
+ }
1040
+
1041
+ .toggle:hover .toggle-track {
1042
+ border-color: var(--text-muted);
1043
+ }
1044
+
1045
+ .toggle[aria-checked="true"]:hover .toggle-track {
1046
+ background: var(--accent-hover);
1047
+ border-color: var(--accent-hover);
1048
+ }
1049
+
1050
+ .toggle:focus-visible .toggle-track {
1051
+ box-shadow: 0 0 0 2px var(--accent-soft);
1052
+ }
1053
+
1054
+ /* ===== UTILITIES ===== */
1055
+ .hidden {
1056
+ display: none !important;
1057
+ }
1058
+
1059
+ /* ===== RESPONSIVE DESIGN ===== */
1060
+
1061
+ /* Large phones and up */
1062
+ @media (min-width: 390px) {
1063
+ .auth-container h1 {
1064
+ font-size: 2rem;
1065
+ }
1066
+
1067
+ .auth-container .subtitle {
1068
+ font-size: 1rem;
1069
+ }
1070
+ }
1071
+
1072
+ /* Mobile phones */
1073
+ @media (max-width: 600px) {
1074
+ .preview-address-bar {
1075
+ padding: 0.375rem 0.75rem;
1076
+ }
1077
+
1078
+ #address-input {
1079
+ font-size: 0.75rem;
1080
+ padding: 0.375rem 0.625rem;
1081
+ }
1082
+
1083
+ #main-screen header {
1084
+ flex-wrap: wrap;
1085
+ gap: 0.375rem;
1086
+ padding: 0.5rem 0.75rem;
1087
+ padding-top: max(0.5rem, env(safe-area-inset-top));
1088
+ }
1089
+
1090
+ /* Row 1: Session selector + actions on right */
1091
+ .header-left {
1092
+ order: 1;
1093
+ width: 100%;
1094
+ gap: 0.25rem;
1095
+ }
1096
+
1097
+ #session-select {
1098
+ flex: 1;
1099
+ min-width: 0;
1100
+ max-width: none;
1101
+ padding: 0.5rem 1.75rem 0.5rem 0.625rem;
1102
+ font-size: 0.8125rem;
1103
+ }
1104
+
1105
+ .header-left-actions {
1106
+ margin-left: auto;
1107
+ }
1108
+
1109
+ /* Row 2: Action buttons */
1110
+ .header-right {
1111
+ order: 2;
1112
+ width: 100%;
1113
+ justify-content: flex-start;
1114
+ gap: 0.5rem;
1115
+ }
1116
+
1117
+ .btn-icon {
1118
+ min-width: 36px;
1119
+ height: 36px;
1120
+ padding: 0 0.5rem;
1121
+ }
1122
+
1123
+ .btn-icon svg {
1124
+ width: 16px;
1125
+ height: 16px;
1126
+ }
1127
+ }
1128
+
1129
+ /* Small phones */
1130
+ @media (max-width: 389px) {
1131
+ #main-screen header {
1132
+ padding: 0.375rem 0.5rem;
1133
+ padding-top: max(0.375rem, env(safe-area-inset-top));
1134
+ }
1135
+
1136
+ .header-left {
1137
+ gap: 0.25rem;
1138
+ }
1139
+
1140
+ .header-right {
1141
+ gap: 0.125rem;
1142
+ }
1143
+
1144
+ #session-select {
1145
+ font-size: 0.75rem;
1146
+ padding: 0.375rem 1.5rem 0.375rem 0.5rem;
1147
+ background-position: right 0.5rem center;
1148
+ }
1149
+
1150
+ .btn-icon {
1151
+ min-width: 32px;
1152
+ height: 32px;
1153
+ padding: 0 0.375rem;
1154
+ }
1155
+
1156
+ .btn-icon svg {
1157
+ width: 14px;
1158
+ height: 14px;
1159
+ }
1160
+
1161
+ .auth-container {
1162
+ max-width: 320px;
1163
+ }
1164
+
1165
+ .modal-content {
1166
+ padding: 1.25rem;
1167
+ }
1168
+ }
1169
+
1170
+ /* Tablet and up */
1171
+ @media (min-width: 768px) {
1172
+ .auth-container {
1173
+ max-width: 400px;
1174
+ }
1175
+
1176
+ .auth-container h1 {
1177
+ font-size: 2.25rem;
1178
+ }
1179
+
1180
+ #main-screen header {
1181
+ padding: 0.875rem 1.5rem;
1182
+ }
1183
+
1184
+ #terminal-container .xterm {
1185
+ padding: 12px 16px;
1186
+ }
1187
+ }
1188
+
1189
+ /* Landscape orientation adjustments */
1190
+ @media (orientation: landscape) and (max-height: 500px) {
1191
+ #auth-screen {
1192
+ padding: 1rem;
1193
+ }
1194
+
1195
+ .auth-container h1 {
1196
+ font-size: 1.5rem;
1197
+ margin-bottom: 0.25rem;
1198
+ }
1199
+
1200
+ .auth-container .subtitle {
1201
+ margin-bottom: 1rem;
1202
+ }
1203
+
1204
+ .auth-container input {
1205
+ padding: 0.75rem 1rem;
1206
+ }
1207
+
1208
+ .btn-primary {
1209
+ padding: 0.75rem 1.25rem;
1210
+ }
1211
+ }
1212
+
1213
+ /* Prevent iOS zoom on input focus */
1214
+ @media screen and (-webkit-min-device-pixel-ratio: 0) {
1215
+ input, select, textarea {
1216
+ font-size: 16px;
1217
+ }
1218
+ }
1219
+
1220
+ /* Touch-friendly terminal */
1221
+ @media (pointer: coarse) {
1222
+ .btn-icon {
1223
+ min-width: 44px;
1224
+ height: 44px;
1225
+ }
1226
+ }
1227
+
1228
+ /* When touch scroll is active, disable native scrolling on xterm elements
1229
+ This applies regardless of pointer type since we detect touch capability in JS
1230
+ The .touch-scroll-active class is added by TouchScrollManager */
1231
+ #terminal-container.touch-scroll-active .xterm-screen {
1232
+ touch-action: none;
1233
+ }
1234
+
1235
+ #terminal-container.touch-scroll-active .xterm-viewport {
1236
+ -webkit-overflow-scrolling: auto;
1237
+ overflow-y: hidden !important;
1238
+ }
1239
+
1240
+ /* ===== TOUCH SCROLL OVERLAY ===== */
1241
+ /* CRITICAL: This overlay captures touch events for momentum scrolling on mobile.
1242
+ DO NOT lower the z-index below 9999 or mobile scrolling will break.
1243
+ The overlay must sit above ALL other positioned elements including:
1244
+ - External sessions dropdown (z-index: 100)
1245
+ - Modals (z-index: 100)
1246
+ - Tooltips (z-index: 1000)
1247
+ - Any future UI elements
1248
+
1249
+ Regression history:
1250
+ - 96cebff: Original momentum scrolling implementation
1251
+ - f47d40c: Fixed touch-action CSS
1252
+ - e1a8508: Raised z-index from 10 to 1000 (dropdown interference)
1253
+ - Current: Raised to 9999 with CSS class for reliability
1254
+ */
1255
+ .touch-scroll-overlay {
1256
+ position: absolute;
1257
+ top: 0;
1258
+ left: 0;
1259
+ right: 0;
1260
+ bottom: 0;
1261
+ z-index: 9999;
1262
+ touch-action: none;
1263
+ /* Invisible but captures all touch events */
1264
+ background: transparent;
1265
+ }
1266
+
1267
+ /* Safe area support for notched devices */
1268
+ @supports (padding: max(0px)) {
1269
+ #main-screen header,
1270
+ #preview-screen header {
1271
+ padding-left: max(1rem, env(safe-area-inset-left));
1272
+ padding-right: max(1rem, env(safe-area-inset-right));
1273
+ }
1274
+
1275
+ .preview-address-bar {
1276
+ padding-left: max(1rem, env(safe-area-inset-left));
1277
+ padding-right: max(1rem, env(safe-area-inset-right));
1278
+ }
1279
+
1280
+ #terminal-container {
1281
+ padding-bottom: env(safe-area-inset-bottom);
1282
+ }
1283
+ }
1284
+
1285
+ /* ===== FOCUS VISIBLE ===== */
1286
+ :focus-visible {
1287
+ outline: 2px solid var(--accent);
1288
+ outline-offset: 1px;
1289
+ }
1290
+
1291
+ button:focus-visible,
1292
+ input:focus-visible,
1293
+ select:focus-visible {
1294
+ outline: none;
1295
+ box-shadow: 0 0 0 2px var(--accent-soft);
1296
+ }
1297
+
1298
+ /* ===== REDUCED MOTION ===== */
1299
+ @media (prefers-reduced-motion: reduce) {
1300
+ *,
1301
+ *::before,
1302
+ *::after {
1303
+ animation-duration: 0.01ms !important;
1304
+ animation-iteration-count: 1 !important;
1305
+ transition-duration: 0.01ms !important;
1306
+ }
1307
+ }
1308
+
1309
+ /* ===== DARK MODE SCROLLBAR (non-terminal) ===== */
1310
+ ::-webkit-scrollbar {
1311
+ width: 10px;
1312
+ height: 10px;
1313
+ }
1314
+
1315
+ ::-webkit-scrollbar-track {
1316
+ background: var(--bg-deep);
1317
+ }
1318
+
1319
+ ::-webkit-scrollbar-thumb {
1320
+ background: var(--bg-hover);
1321
+ border-radius: 5px;
1322
+ border: 2px solid var(--bg-deep);
1323
+ }
1324
+
1325
+ ::-webkit-scrollbar-thumb:hover {
1326
+ background: var(--text-muted);
1327
+ }
1328
+
1329
+ /* ===== SELECTION ===== */
1330
+ ::selection {
1331
+ background: var(--accent-soft);
1332
+ color: var(--text-primary);
1333
+ }
1334
+
1335
+ /* ===== CONNECTION STATUS ===== */
1336
+ .connection-status {
1337
+ display: inline-flex;
1338
+ align-items: center;
1339
+ gap: 0.5rem;
1340
+ padding: 0.375rem 0.75rem;
1341
+ font-size: 0.75rem;
1342
+ background: rgba(63, 185, 80, 0.1);
1343
+ color: var(--success);
1344
+ border-radius: var(--radius);
1345
+ }
1346
+
1347
+ .connection-status::before {
1348
+ content: '';
1349
+ width: 6px;
1350
+ height: 6px;
1351
+ border-radius: 50%;
1352
+ background: currentColor;
1353
+ }
1354
+
1355
+ .connection-status.disconnected {
1356
+ background: rgba(248, 81, 73, 0.1);
1357
+ color: var(--error);
1358
+ }
1359
+
1360
+ /* ===== EMPTY STATE ===== */
1361
+ .empty-state {
1362
+ display: flex;
1363
+ flex-direction: column;
1364
+ align-items: center;
1365
+ justify-content: center;
1366
+ padding: 2rem;
1367
+ text-align: center;
1368
+ color: var(--text-muted);
1369
+ }
1370
+
1371
+ .empty-state svg {
1372
+ margin-bottom: 1rem;
1373
+ opacity: 0.5;
1374
+ }
1375
+
1376
+ .empty-state p {
1377
+ font-size: 0.9rem;
1378
+ max-width: 240px;
1379
+ }
1380
+
1381
+ /* ===== TOUCH FEEDBACK ===== */
1382
+ @media (pointer: coarse) {
1383
+ .btn-primary:active:not(:disabled),
1384
+ .btn-secondary:active,
1385
+ .btn-icon:active {
1386
+ opacity: 0.7;
1387
+ }
1388
+ }
1389
+
1390
+ /* ===== SKELETON LOADING ===== */
1391
+ .skeleton {
1392
+ background: var(--bg-surface);
1393
+ border-radius: var(--radius);
1394
+ }
1395
+
1396
+ /* ===== TOOLTIP ===== */
1397
+ [data-tooltip] {
1398
+ position: relative;
1399
+ }
1400
+
1401
+ [data-tooltip]::after {
1402
+ content: attr(data-tooltip);
1403
+ position: absolute;
1404
+ bottom: 100%;
1405
+ left: 50%;
1406
+ transform: translateX(-50%) translateY(-0.25rem);
1407
+ padding: 0.375rem 0.625rem;
1408
+ font-size: 0.75rem;
1409
+ white-space: nowrap;
1410
+ background: var(--bg-elevated);
1411
+ color: var(--text-primary);
1412
+ border: 1px solid var(--border);
1413
+ border-radius: var(--radius);
1414
+ opacity: 0;
1415
+ visibility: hidden;
1416
+ transition: opacity var(--transition), visibility var(--transition);
1417
+ pointer-events: none;
1418
+ z-index: 1000;
1419
+ }
1420
+
1421
+ [data-tooltip]:hover::after {
1422
+ opacity: 1;
1423
+ visibility: visible;
1424
+ }
1425
+
1426
+ /* ===== KEYBOARD SHORTCUT HINT ===== */
1427
+ kbd {
1428
+ display: inline-flex;
1429
+ align-items: center;
1430
+ justify-content: center;
1431
+ min-width: 1.5rem;
1432
+ height: 1.5rem;
1433
+ padding: 0 0.375rem;
1434
+ font-family: var(--font-mono);
1435
+ font-size: 0.6875rem;
1436
+ background: var(--bg-surface);
1437
+ color: var(--text-secondary);
1438
+ border: 1px solid var(--border);
1439
+ border-radius: 3px;
1440
+ }
1441
+
1442
+ /* ===== MOBILE CONTROL KEYS TOOLBAR ===== */
1443
+ /* CRITICAL: z-index must be higher than touch-scroll-overlay (9999) to receive taps.
1444
+ The overlay doesn't create a stacking context, so its 9999 z-index competes directly. */
1445
+ .mobile-keys {
1446
+ position: fixed;
1447
+ left: 0;
1448
+ right: 0;
1449
+ display: flex;
1450
+ justify-content: center;
1451
+ gap: 0.5rem;
1452
+ padding: 0.5rem;
1453
+ background: var(--bg-primary);
1454
+ border-top: 1px solid var(--border);
1455
+ z-index: 10000;
1456
+ opacity: 0;
1457
+ pointer-events: none;
1458
+ transition: opacity var(--transition);
1459
+ /* bottom is set dynamically by JS */
1460
+ }
1461
+
1462
+ .mobile-keys.visible {
1463
+ opacity: 1;
1464
+ pointer-events: auto;
1465
+ }
1466
+
1467
+ .mobile-key {
1468
+ display: inline-flex;
1469
+ align-items: center;
1470
+ justify-content: center;
1471
+ min-width: 48px;
1472
+ height: 40px;
1473
+ padding: 0 0.75rem;
1474
+ font-family: var(--font-mono);
1475
+ font-size: 0.8125rem;
1476
+ background: var(--bg-surface);
1477
+ color: var(--text-secondary);
1478
+ border: 1px solid var(--border);
1479
+ border-radius: var(--radius);
1480
+ cursor: pointer;
1481
+ touch-action: manipulation;
1482
+ -webkit-tap-highlight-color: transparent;
1483
+ transition: background var(--transition), color var(--transition);
1484
+ }
1485
+
1486
+ .mobile-key:active,
1487
+ .mobile-key.pressed {
1488
+ background: var(--bg-hover);
1489
+ }
1490
+
1491
+ /* Modifier key (Ctrl) - sticky toggle style */
1492
+ .mobile-key-modifier[aria-pressed="true"] {
1493
+ background: var(--accent);
1494
+ color: white;
1495
+ border-color: var(--accent);
1496
+ }
1497
+
1498
+ /* Only show on touch devices */
1499
+ @media (pointer: fine) {
1500
+ .mobile-keys {
1501
+ display: none !important;
1502
+ }
1503
+ }
1504
+
1505
+ /* Adjust terminal container when toolbar is visible */
1506
+ .mobile-keys.visible + .floating-btn,
1507
+ .mobile-keys.visible ~ .floating-btn {
1508
+ bottom: calc(56px + max(0.5rem, env(safe-area-inset-bottom)));
1509
+ }
1510
+
1511
+ /* When mobile keys are visible, add padding to terminal */
1512
+ #main-screen.mobile-keys-visible #terminal-container {
1513
+ padding-bottom: calc(56px + env(safe-area-inset-bottom));
1514
+ }
1515
+
1516
+ /* ===== SCROLL TO BOTTOM BUTTON ===== */
1517
+ .scroll-bottom-btn {
1518
+ position: fixed;
1519
+ bottom: max(1rem, env(safe-area-inset-bottom));
1520
+ right: 1rem;
1521
+ width: 36px;
1522
+ height: 36px;
1523
+ display: flex;
1524
+ align-items: center;
1525
+ justify-content: center;
1526
+ background: var(--bg-elevated);
1527
+ color: var(--text-secondary);
1528
+ border: 1px solid var(--border);
1529
+ border-radius: var(--radius);
1530
+ cursor: pointer;
1531
+ opacity: 0;
1532
+ transition: opacity var(--transition), color var(--transition);
1533
+ z-index: 40;
1534
+ box-shadow: var(--shadow);
1535
+ }
1536
+
1537
+ .scroll-bottom-btn:not(.hidden) {
1538
+ opacity: 0.9;
1539
+ }
1540
+
1541
+ .scroll-bottom-btn:hover {
1542
+ color: var(--text-primary);
1543
+ border-color: var(--text-muted);
1544
+ }
1545
+
1546
+ /* Hide when mobile keyboard is visible */
1547
+ #main-screen.mobile-keys-visible .scroll-bottom-btn {
1548
+ display: none;
1549
+ }
1550
+
1551
+ /* ===== SCHEDULES SCREEN ===== */
1552
+ #schedules-screen {
1553
+ background: var(--bg-deep);
1554
+ overflow-y: auto;
1555
+ /* Ensure screen covers terminal layer beneath */
1556
+ position: relative;
1557
+ z-index: 2;
1558
+ }
1559
+
1560
+ .schedules-header {
1561
+ display: flex;
1562
+ align-items: center;
1563
+ gap: 0.75rem;
1564
+ padding: 0.875rem 1.25rem;
1565
+ padding-top: max(0.875rem, env(safe-area-inset-top));
1566
+ background: var(--bg-primary);
1567
+ border-bottom: 1px solid var(--border);
1568
+ flex-shrink: 0;
1569
+ min-height: 56px;
1570
+ position: sticky;
1571
+ top: 0;
1572
+ z-index: 1;
1573
+ }
1574
+
1575
+ .schedules-header .btn-primary {
1576
+ width: auto;
1577
+ flex-shrink: 0;
1578
+ }
1579
+
1580
+ .schedules-title {
1581
+ font-size: 1rem;
1582
+ font-weight: 600;
1583
+ color: var(--text-primary);
1584
+ margin: 0;
1585
+ white-space: nowrap;
1586
+ }
1587
+
1588
+ .schedules-list {
1589
+ padding: 1rem;
1590
+ padding-bottom: env(safe-area-inset-bottom, 1rem);
1591
+ display: flex;
1592
+ flex-direction: column;
1593
+ gap: 0.75rem;
1594
+ }
1595
+
1596
+ /* Schedule Badge */
1597
+ .schedule-badge {
1598
+ display: inline-flex;
1599
+ align-items: center;
1600
+ justify-content: center;
1601
+ min-width: 20px;
1602
+ height: 20px;
1603
+ padding: 0 0.375rem;
1604
+ font-size: 0.6875rem;
1605
+ font-weight: 600;
1606
+ background: var(--accent);
1607
+ color: white;
1608
+ border-radius: 10px;
1609
+ line-height: 1;
1610
+ }
1611
+
1612
+ /* Schedule Tab Button */
1613
+ .schedule-tab-btn {
1614
+ display: inline-flex;
1615
+ align-items: center;
1616
+ gap: 0.5rem;
1617
+ padding: 0.5rem 0.875rem;
1618
+ font-size: 0.8125rem;
1619
+ font-family: var(--font-sans);
1620
+ background: transparent;
1621
+ color: var(--text-secondary);
1622
+ border: 1px solid var(--border);
1623
+ border-radius: var(--radius);
1624
+ cursor: pointer;
1625
+ transition: all var(--transition);
1626
+ white-space: nowrap;
1627
+ flex-shrink: 0;
1628
+ position: relative;
1629
+ }
1630
+
1631
+ .schedule-tab-btn:hover {
1632
+ color: var(--text-primary);
1633
+ background: rgba(240, 246, 252, 0.03);
1634
+ }
1635
+
1636
+ .schedule-tab-btn[aria-selected="true"] {
1637
+ color: var(--text-primary);
1638
+ background: rgba(88, 166, 255, 0.1);
1639
+ border-color: var(--accent);
1640
+ }
1641
+
1642
+ .schedule-tab-badge {
1643
+ display: inline-flex;
1644
+ align-items: center;
1645
+ justify-content: center;
1646
+ min-width: 16px;
1647
+ height: 16px;
1648
+ padding: 0 0.25rem;
1649
+ font-size: 0.625rem;
1650
+ font-weight: 600;
1651
+ background: var(--accent);
1652
+ color: white;
1653
+ border-radius: 8px;
1654
+ line-height: 1;
1655
+ }
1656
+
1657
+ /* Schedule Card */
1658
+ .schedule-card {
1659
+ background: var(--bg-primary);
1660
+ border: 1px solid var(--border);
1661
+ border-radius: var(--radius);
1662
+ overflow: hidden;
1663
+ }
1664
+
1665
+ .schedule-card-header {
1666
+ display: flex;
1667
+ align-items: center;
1668
+ gap: 0.75rem;
1669
+ padding: 0.875rem 1rem;
1670
+ }
1671
+
1672
+ .schedule-card-name {
1673
+ flex: 1;
1674
+ font-weight: 500;
1675
+ font-size: 0.9375rem;
1676
+ color: var(--text-primary);
1677
+ min-width: 0;
1678
+ overflow: hidden;
1679
+ text-overflow: ellipsis;
1680
+ white-space: nowrap;
1681
+ }
1682
+
1683
+ .schedule-card-actions {
1684
+ display: flex;
1685
+ align-items: center;
1686
+ gap: 0.5rem;
1687
+ flex-shrink: 0;
1688
+ }
1689
+
1690
+ .schedule-trigger-btn {
1691
+ display: inline-flex;
1692
+ align-items: center;
1693
+ justify-content: center;
1694
+ width: 28px;
1695
+ height: 28px;
1696
+ background: transparent;
1697
+ color: var(--text-muted);
1698
+ border: none;
1699
+ border-radius: var(--radius);
1700
+ cursor: pointer;
1701
+ transition: all var(--transition);
1702
+ padding: 0;
1703
+ }
1704
+
1705
+ .schedule-trigger-btn:hover {
1706
+ background: rgba(63, 185, 80, 0.15);
1707
+ color: var(--success);
1708
+ }
1709
+
1710
+ .schedule-delete-btn {
1711
+ display: inline-flex;
1712
+ align-items: center;
1713
+ justify-content: center;
1714
+ width: 28px;
1715
+ height: 28px;
1716
+ background: transparent;
1717
+ color: var(--text-muted);
1718
+ border: none;
1719
+ border-radius: var(--radius);
1720
+ cursor: pointer;
1721
+ transition: all var(--transition);
1722
+ padding: 0;
1723
+ }
1724
+
1725
+ .schedule-delete-btn:hover {
1726
+ background: rgba(248, 81, 73, 0.15);
1727
+ color: var(--error);
1728
+ }
1729
+
1730
+ .schedule-card-meta {
1731
+ padding: 0 1rem 0.875rem;
1732
+ display: flex;
1733
+ flex-direction: column;
1734
+ gap: 0.375rem;
1735
+ }
1736
+
1737
+ .schedule-meta-row {
1738
+ display: flex;
1739
+ align-items: baseline;
1740
+ gap: 0.5rem;
1741
+ font-size: 0.8125rem;
1742
+ color: var(--text-secondary);
1743
+ min-width: 0;
1744
+ }
1745
+
1746
+ .schedule-meta-label {
1747
+ color: var(--text-muted);
1748
+ flex-shrink: 0;
1749
+ font-size: 0.75rem;
1750
+ text-transform: uppercase;
1751
+ letter-spacing: 0.02em;
1752
+ }
1753
+
1754
+ .schedule-meta-value {
1755
+ overflow: hidden;
1756
+ text-overflow: ellipsis;
1757
+ white-space: nowrap;
1758
+ min-width: 0;
1759
+ }
1760
+
1761
+ .schedule-meta-value.prompt-value {
1762
+ font-family: var(--font-mono);
1763
+ font-size: 0.75rem;
1764
+ }
1765
+
1766
+ .schedule-last-run {
1767
+ display: flex;
1768
+ align-items: center;
1769
+ gap: 0.375rem;
1770
+ font-size: 0.75rem;
1771
+ }
1772
+
1773
+ .schedule-last-run .run-status {
1774
+ display: inline-block;
1775
+ width: 8px;
1776
+ height: 8px;
1777
+ border-radius: 50%;
1778
+ }
1779
+
1780
+ .schedule-last-run .run-status.success {
1781
+ background: var(--success);
1782
+ }
1783
+
1784
+ .schedule-last-run .run-status.failure {
1785
+ background: var(--error);
1786
+ }
1787
+
1788
+ .schedule-last-run .run-status.pending {
1789
+ background: var(--text-muted);
1790
+ }
1791
+
1792
+ /* Schedule Runs */
1793
+ .schedule-runs-toggle {
1794
+ display: block;
1795
+ width: 100%;
1796
+ padding: 0.5rem 1rem;
1797
+ font-size: 0.75rem;
1798
+ font-family: var(--font-sans);
1799
+ background: var(--bg-elevated);
1800
+ color: var(--text-muted);
1801
+ border: none;
1802
+ border-top: 1px solid var(--border);
1803
+ cursor: pointer;
1804
+ text-align: left;
1805
+ transition: color var(--transition);
1806
+ }
1807
+
1808
+ .schedule-runs-toggle:hover {
1809
+ color: var(--text-secondary);
1810
+ }
1811
+
1812
+ .schedule-runs-list {
1813
+ border-top: 1px solid var(--border);
1814
+ max-height: 200px;
1815
+ overflow-y: auto;
1816
+ }
1817
+
1818
+ .run-item {
1819
+ display: flex;
1820
+ align-items: center;
1821
+ gap: 0.5rem;
1822
+ padding: 0.5rem 1rem;
1823
+ font-size: 0.75rem;
1824
+ font-family: var(--font-mono);
1825
+ color: var(--text-secondary);
1826
+ cursor: pointer;
1827
+ transition: background var(--transition);
1828
+ border-bottom: 1px solid var(--border);
1829
+ }
1830
+
1831
+ .run-item:last-child {
1832
+ border-bottom: none;
1833
+ }
1834
+
1835
+ .run-item:hover {
1836
+ background: rgba(240, 246, 252, 0.03);
1837
+ }
1838
+
1839
+ .run-item-status {
1840
+ width: 6px;
1841
+ height: 6px;
1842
+ border-radius: 50%;
1843
+ flex-shrink: 0;
1844
+ }
1845
+
1846
+ .run-item-status.success {
1847
+ background: var(--success);
1848
+ }
1849
+
1850
+ .run-item-status.failure {
1851
+ background: var(--error);
1852
+ }
1853
+
1854
+ .run-item-status.running {
1855
+ background: var(--warning);
1856
+ }
1857
+
1858
+ .run-item-time {
1859
+ flex: 1;
1860
+ min-width: 0;
1861
+ overflow: hidden;
1862
+ text-overflow: ellipsis;
1863
+ white-space: nowrap;
1864
+ }
1865
+
1866
+ .run-item-duration {
1867
+ color: var(--text-muted);
1868
+ flex-shrink: 0;
1869
+ }
1870
+
1871
+ /* Schedule Form */
1872
+ .schedule-form {
1873
+ display: flex;
1874
+ flex-direction: column;
1875
+ gap: 0.75rem;
1876
+ margin-bottom: 1.25rem;
1877
+ }
1878
+
1879
+ .schedule-form input,
1880
+ .schedule-form textarea {
1881
+ width: 100%;
1882
+ padding: 0.625rem 0.75rem;
1883
+ font-size: 0.875rem;
1884
+ font-family: var(--font-mono);
1885
+ background: var(--bg-surface);
1886
+ color: var(--text-primary);
1887
+ border: 1px solid var(--border);
1888
+ border-radius: var(--radius);
1889
+ transition: border-color var(--transition), box-shadow var(--transition);
1890
+ margin-bottom: 0;
1891
+ }
1892
+
1893
+ .schedule-form textarea {
1894
+ resize: vertical;
1895
+ min-height: 60px;
1896
+ font-family: var(--font-mono);
1897
+ line-height: 1.5;
1898
+ }
1899
+
1900
+ .schedule-form input::placeholder,
1901
+ .schedule-form textarea::placeholder {
1902
+ color: var(--text-muted);
1903
+ }
1904
+
1905
+ .schedule-form input:focus,
1906
+ .schedule-form textarea:focus {
1907
+ outline: none;
1908
+ border-color: var(--accent);
1909
+ box-shadow: 0 0 0 2px var(--accent-soft);
1910
+ }
1911
+
1912
+
1913
+ .schedule-form .autocomplete-wrapper {
1914
+ margin-bottom: 0;
1915
+ }
1916
+
1917
+ /* Run Log Modal */
1918
+ .run-log-content {
1919
+ max-width: 640px;
1920
+ max-height: 80vh;
1921
+ display: flex;
1922
+ flex-direction: column;
1923
+ }
1924
+
1925
+ .run-log-pre {
1926
+ flex: 1;
1927
+ overflow: auto;
1928
+ padding: 1rem;
1929
+ background: var(--bg-deep);
1930
+ border: 1px solid var(--border);
1931
+ border-radius: var(--radius);
1932
+ font-family: var(--font-mono);
1933
+ font-size: 0.75rem;
1934
+ line-height: 1.6;
1935
+ color: var(--text-secondary);
1936
+ white-space: pre-wrap;
1937
+ word-break: break-all;
1938
+ max-height: 60vh;
1939
+ margin: 0;
1940
+ }
1941
+
1942
+ /* Responsive: Mobile schedule styles */
1943
+ @media (max-width: 600px) {
1944
+ .schedules-header {
1945
+ padding: 0.5rem 0.75rem;
1946
+ padding-top: max(0.5rem, env(safe-area-inset-top));
1947
+ gap: 0.5rem;
1948
+ }
1949
+
1950
+ .schedules-list {
1951
+ padding: 0.75rem;
1952
+ gap: 0.5rem;
1953
+ }
1954
+
1955
+ .schedule-card-header {
1956
+ padding: 0.75rem;
1957
+ }
1958
+
1959
+ .schedule-card-meta {
1960
+ padding: 0 0.75rem 0.75rem;
1961
+ }
1962
+
1963
+ .run-log-content {
1964
+ max-height: 90vh;
1965
+ }
1966
+
1967
+ .run-log-pre {
1968
+ max-height: 70vh;
1969
+ }
1970
+ }