omni-notify-mcp 1.3.14 → 1.3.21

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.
@@ -1,794 +1,793 @@
1
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2
-
3
- :root {
4
- --bg: #0d0f12;
5
- --surface: #14171c;
6
- --border: #242832;
7
- --text: #e6e8ec;
8
- --text-2: #9aa3b2;
9
- --text-3: #5a6478;
10
- --accent: #4ea3ff; /* bright blue — readable, distinctly "interactive" */
11
- --accent-h:#6fb6ff;
12
- --accent-d:#1a3a5c; /* dark variant for backgrounds */
13
- --success: #4ade80;
14
- --danger: #f87171;
15
- --warn: #d4a857; /* muted amber, was glaring orange */
16
- --r: 8px;
17
- }
18
-
19
- html, body { height: 100%; }
20
-
21
- body {
22
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
23
- background: var(--bg);
24
- color: var(--text);
25
- font-size: 13px;
26
- line-height: 1.5;
27
- display: flex;
28
- flex-direction: column;
29
- }
30
-
31
- /* ── Header ──────────────────────────────────────────────────────────────── */
32
-
33
- header {
34
- display: flex;
35
- align-items: center;
36
- gap: 14px;
37
- padding: 0 20px;
38
- height: 48px;
39
- flex-shrink: 0;
40
- background: var(--surface);
41
- border-bottom: 1px solid var(--border);
42
- }
43
-
44
- .logo {
45
- display: flex;
46
- align-items: center;
47
- gap: 7px;
48
- font-size: 14px;
49
- font-weight: 700;
50
- color: var(--accent);
51
- white-space: nowrap;
52
- }
53
-
54
- .subtitle {
55
- color: var(--text-3);
56
- font-size: 12px;
57
- white-space: nowrap;
58
- }
59
-
60
- .header-link {
61
- color: var(--accent);
62
- background: var(--accent-d);
63
- border: 1px solid var(--accent);
64
- font-size: 12px;
65
- font-weight: 600;
66
- text-decoration: none;
67
- padding: 5px 12px;
68
- border-radius: 6px;
69
- transition: background .15s, color .15s;
70
- white-space: nowrap;
71
- }
72
- .header-link:hover {
73
- background: var(--accent);
74
- color: white;
75
- }
76
-
77
- .os-tag {
78
- font-size: 11px;
79
- color: var(--warn);
80
- background: #1c1500;
81
- border: 1px solid #3a2e00;
82
- border-radius: 5px;
83
- padding: 1px 7px;
84
- white-space: nowrap;
85
- }
86
-
87
- /* ── Main ────────────────────────────────────────────────────────────────── */
88
-
89
- main {
90
- flex: 1;
91
- padding: 14px 18px;
92
- min-height: 0;
93
- overflow: hidden;
94
- display: flex;
95
- flex-direction: column;
96
- gap: 14px;
97
- }
98
-
99
- /* ── Card list (left column) ─────────────────────────────────────────────── */
100
-
101
- .card-list {
102
- flex: 1;
103
- min-height: 0;
104
- height: 100%;
105
- overflow: auto;
106
- display: grid;
107
- grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
108
- grid-auto-rows: min-content;
109
- align-content: start;
110
- gap: 12px;
111
- }
112
-
113
- /* Top half: single Configuration panel with two side-by-side subsections.
114
- Bottom half: full-width activity log. */
115
- .config-panel {
116
- display: flex;
117
- flex-direction: row;
118
- flex-shrink: 0;
119
- /* Take ~60% of the vertical space so the log gets a real chunk too */
120
- height: 62%;
121
- min-height: 0;
122
- border-radius: var(--r);
123
- border: 1px solid var(--border);
124
- background: var(--surface);
125
- overflow: hidden;
126
- }
127
-
128
- .section {
129
- display: flex;
130
- flex-direction: column;
131
- gap: 10px;
132
- padding: 12px 14px 14px;
133
- min-width: 0;
134
- height: 100%;
135
- overflow: hidden;
136
- }
137
-
138
- /* ── Master kill switch ──────────────────────────────────────────────────── */
139
-
140
- .mute-all-bar {
141
- display: flex;
142
- align-items: center;
143
- justify-content: space-between;
144
- gap: 12px;
145
- flex-shrink: 0;
146
- padding: 9px 14px;
147
- border-radius: var(--r);
148
- border: 1px solid var(--border);
149
- background: var(--surface);
150
- }
151
- .mute-all-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
152
- .mute-all-icon { font-size: 18px; line-height: 1; flex-shrink: 0; }
153
- .mute-all-text { display: flex; flex-direction: column; min-width: 0; }
154
- .mute-all-title { font-weight: 700; font-size: 13px; }
155
- .mute-all-sub { color: var(--text-2); font-size: 11px; }
156
- .mute-all-bar.muted {
157
- border-color: var(--danger);
158
- background: linear-gradient(0deg, rgba(248,113,113,.12), rgba(248,113,113,.12)), var(--surface);
159
- box-shadow: inset 0 0 0 1px rgba(248,113,113,.4);
160
- }
161
- .mute-all-bar.muted .mute-all-title,
162
- .mute-all-bar.muted .mute-all-sub { color: var(--danger); }
163
- body.all-muted .config-panel { opacity: .6; }
164
-
165
- /* Channels has 4 cards → needs ~3× the room of Policies (which has 2 cards). */
166
- .section-channels { flex: 3 1 0; }
167
- .section-policies { flex: 2 1 0; }
168
-
169
- /* Divider between the two subsections — owned by the panel, not the sections */
170
- .section + .section {
171
- border-left: 1px solid var(--border);
172
- }
173
-
174
- /* Subtle accent strip at the top of each subsection — color carries the
175
- role, so the title text stays bright/legible (don't tint text). */
176
- .section-channels { box-shadow: inset 0 3px 0 0 #4ea3ff; } /* bright blue */
177
- .section-policies { box-shadow: inset 0 3px 0 0 #d4a857; } /* muted amber */
178
-
179
- .section-hd {
180
- display: flex;
181
- align-items: baseline;
182
- gap: 8px;
183
- padding: 4px 2px 10px;
184
- border-bottom: 1px solid var(--border);
185
- }
186
-
187
- .section-hd-title {
188
- font-size: 11px;
189
- font-weight: 700;
190
- letter-spacing: 0.12em;
191
- text-transform: uppercase;
192
- color: var(--text);
193
- }
194
-
195
- .section-hd-sub {
196
- font-size: 11px;
197
- color: var(--text-2);
198
- margin-left: auto;
199
- }
200
-
201
- /* ── Log section (right, fills remaining width) ──────────────────────────── */
202
-
203
- .log-section {
204
- flex: 1;
205
- min-width: 0;
206
- display: flex;
207
- flex-direction: column;
208
- background: var(--surface);
209
- border: 1px solid var(--border);
210
- border-radius: var(--r);
211
- overflow: hidden;
212
- }
213
-
214
- .log-header {
215
- display: flex;
216
- align-items: center;
217
- justify-content: space-between;
218
- padding: 6px 12px;
219
- border-bottom: 1px solid var(--border);
220
- flex-shrink: 0;
221
- }
222
-
223
- /* Collapsible activity-log section (collapsed by default). */
224
- .log-collapse {
225
- background: transparent; border: none; cursor: pointer; padding: 2px;
226
- color: var(--text-3); display: inline-flex; align-items: center; flex-shrink: 0;
227
- }
228
- .log-collapse:hover { color: var(--text); }
229
- .log-chevron { width: 16px; height: 16px; transition: transform .2s; }
230
- .log-section.collapsed .log-chevron { transform: rotate(-90deg); }
231
- .log-section.collapsed { flex: 0 0 auto; }
232
- .log-section.collapsed .log-header { border-bottom: none; }
233
- .log-section.collapsed .log-panel,
234
- .log-section.collapsed .clients-panel { display: none !important; }
235
- /* When the log is collapsed, let the config panel grow into the freed space.
236
- Keep flex-basis = its 62% height so the height:100% chain on .section /
237
- .card-list stays resolvable (height:auto here collapsed the cards to 0). */
238
- main:has(.log-section.collapsed) .config-panel { flex: 1 1 auto; }
239
-
240
- .log-title {
241
- display: flex;
242
- align-items: center;
243
- gap: 7px;
244
- font-size: 11px;
245
- font-weight: 700;
246
- color: var(--text-3);
247
- text-transform: uppercase;
248
- letter-spacing: .5px;
249
- }
250
-
251
- .log-tabs { display: flex; gap: 2px; flex-shrink: 0; }
252
- .log-tab {
253
- font: inherit; font-size: 11px; font-weight: 700;
254
- text-transform: uppercase; letter-spacing: .5px;
255
- padding: 4px 10px; border: none; background: transparent;
256
- color: var(--text-3); cursor: pointer;
257
- display: inline-flex; align-items: center; gap: 7px;
258
- border-bottom: 2px solid transparent;
259
- }
260
- .log-tab:hover { color: var(--text); }
261
- .log-tab-active { color: var(--text); border-bottom-color: var(--accent); }
262
-
263
- .clients-panel { flex: 1; overflow-y: auto; padding: 8px 12px; }
264
- .client-row {
265
- display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap;
266
- padding: 8px 10px; margin-bottom: 6px;
267
- border: 1px solid var(--border); border-radius: 8px;
268
- }
269
- .client-tag {
270
- font-family: monospace; font-weight: 700; color: var(--text);
271
- white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
272
- min-width: 0; flex: 1 1 auto;
273
- }
274
- .client-kinds { display: flex; gap: 4px; flex-shrink: 0; }
275
- .client-kind {
276
- font-size: 9px; text-transform: uppercase; letter-spacing: .4px;
277
- padding: 2px 6px; border-radius: 6px;
278
- background: var(--border); color: var(--text-2);
279
- }
280
- .client-actions { display: flex; gap: 4px; flex-shrink: 0; margin-left: auto; }
281
- .client-actions .btn-sm { padding: 3px 9px; font-size: 11px; }
282
- .client-meta { flex-basis: 100%; color: var(--text-3); font-size: 11px; }
283
- .clients-empty { color: var(--text-3); text-align: center; padding: 24px 12px; font-size: 12px; }
284
-
285
- .session-pills {
286
- display: flex;
287
- align-items: center;
288
- gap: 6px;
289
- flex: 1;
290
- justify-content: center;
291
- flex-wrap: wrap;
292
- overflow: hidden;
293
- }
294
- .pill {
295
- font: inherit;
296
- font-size: 11px;
297
- padding: 3px 10px;
298
- border-radius: 12px;
299
- border: 1px solid var(--border);
300
- background: transparent;
301
- color: var(--text-2);
302
- cursor: pointer;
303
- transition: background .15s, color .15s, border-color .15s;
304
- white-space: nowrap;
305
- }
306
- .pill:hover { border-color: var(--accent); color: var(--text); }
307
- .pill-active {
308
- background: var(--accent);
309
- border-color: var(--accent);
310
- color: #fff;
311
- }
312
- .pill { display: inline-flex; align-items: center; gap: 5px; }
313
- .pill-dot {
314
- width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
315
- }
316
- .pill-dot-live { background: #4ade80; }
317
- .pill-dot-idle { background: #facc15; }
318
- .pill-dot-stale { background: #f87171; }
319
- .pill-dismiss {
320
- margin-left: 1px; font-size: 13px; line-height: 1;
321
- opacity: .6; cursor: pointer;
322
- }
323
- .pill-dismiss:hover { opacity: 1; }
324
-
325
- /* ── Cards ───────────────────────────────────────────────────────────────── */
326
-
327
- .card {
328
- width: auto;
329
- max-width: 100%;
330
- min-width: 0;
331
- background: var(--surface);
332
- border: 2px solid #4a4a5a;
333
- border-radius: var(--r);
334
- display: flex;
335
- flex-direction: column;
336
- overflow: hidden;
337
- box-shadow: 0 0 0 1px rgba(255,255,255,0.04), 0 2px 8px rgba(0,0,0,0.4);
338
- }
339
-
340
- .card-hd {
341
- display: flex;
342
- align-items: center;
343
- justify-content: space-between;
344
- padding: 10px 14px;
345
- gap: 8px;
346
- flex-shrink: 0;
347
- cursor: pointer;
348
- user-select: none;
349
- transition: background .1s;
350
- }
351
- .card-hd:hover { background: rgba(255,255,255,0.03); }
352
- .card.expanded .card-hd { border-bottom: 2px solid #4a4a5a; }
353
- .ch-meta {
354
- display: flex;
355
- align-items: center;
356
- gap: 8px;
357
- }
358
- .ch-name { font-size: 14px; font-weight: 600; }
359
-
360
- .card-chevron {
361
- width: 14px;
362
- height: 14px;
363
- flex-shrink: 0;
364
- color: var(--text-3);
365
- transition: transform .2s;
366
- }
367
- .card.expanded .card-chevron { transform: rotate(180deg); }
368
-
369
- .card-body {
370
- padding: 12px 14px;
371
- display: none;
372
- flex-direction: column;
373
- gap: 10px;
374
- flex: 1;
375
- }
376
- .card.expanded .card-body { display: flex; }
377
-
378
- /* ── Channel icons ───────────────────────────────────────────────────────── */
379
-
380
- .channel-icon {
381
- width: 26px; height: 26px;
382
- border-radius: 6px;
383
- display: flex; align-items: center; justify-content: center;
384
- flex-shrink: 0;
385
- }
386
- .desktop-icon { background: #0d1a2e; color: #60a5fa; }
387
- .gmail-icon { background: #2e0d0d; color: #f87171; }
388
- .telegram-icon { background: #0d1e2e; color: #38bdf8; }
389
- .whatsapp-icon { background: #0d2e1a; color: #4ade80; }
390
- .sms-icon { background: #1e0d2e; color: #c084fc; }
391
- .ntfy-icon { background: #1a2e0d; color: #86efac; }
392
- .discord-icon { background: #0d0d2e; color: #a5b4fc; }
393
- .slack-icon { background: #2e2a0d; color: #fbbf24; }
394
- .teams-icon { background: #0d1e2e; color: #7dd3fc; }
395
-
396
- /* ── Tags & badges ───────────────────────────────────────────────────────── */
397
-
398
- .tag {
399
- font-size: 10px;
400
- font-weight: 500;
401
- background: #1a1a24;
402
- border: 1px solid var(--border);
403
- color: var(--text-3);
404
- padding: 1px 6px;
405
- border-radius: 20px;
406
- }
407
-
408
- .badge {
409
- font-size: 10px;
410
- font-weight: 600;
411
- padding: 2px 8px;
412
- border-radius: 20px;
413
- white-space: nowrap;
414
- flex-shrink: 0;
415
- }
416
- .badge-idle { background: #1e1e24; color: var(--text-3); }
417
- .badge-ok { background: #0d2e22; color: #34d399; }
418
- .badge-error { background: #2e0d0d; color: #f87171; }
419
- .badge-warn { background: #2e200d; color: #fbbf24; }
420
-
421
- /* ── Setup guides ────────────────────────────────────────────────────────── */
422
-
423
- .guide {
424
- background: #0d0d18;
425
- border: 1px solid #252538;
426
- border-radius: 7px;
427
- overflow: hidden;
428
- flex-shrink: 0;
429
- }
430
- .guide summary {
431
- padding: 7px 11px;
432
- cursor: pointer;
433
- font-weight: 600;
434
- font-size: 11px;
435
- color: var(--accent);
436
- list-style: none;
437
- user-select: none;
438
- display: flex;
439
- align-items: center;
440
- gap: 5px;
441
- }
442
- .guide summary::-webkit-details-marker { display: none; }
443
- .guide summary::before { content: "▶"; font-size: 8px; transition: transform .15s; }
444
- .guide[open] summary::before { transform: rotate(90deg); }
445
- .guide ol {
446
- padding: 0 11px 10px 26px;
447
- font-size: 11px;
448
- color: var(--text-2);
449
- display: flex;
450
- flex-direction: column;
451
- gap: 4px;
452
- line-height: 1.5;
453
- }
454
- .guide a { color: var(--accent); }
455
-
456
- code.cp {
457
- display: inline-block;
458
- background: #1a1a2e;
459
- border: 1px solid var(--border);
460
- border-radius: 4px;
461
- padding: 1px 6px;
462
- font-family: monospace;
463
- font-size: 10px;
464
- cursor: pointer;
465
- }
466
- code.cp:hover { background: #22223a; }
467
- code.cp::after { content: " 📋"; font-size: 9px; }
468
-
469
- /* ── Form fields ─────────────────────────────────────────────────────────── */
470
-
471
- .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
472
- .fg { display: flex; flex-direction: column; gap: 4px; }
473
-
474
- .fg label, label.lbl {
475
- font-size: 11px;
476
- font-weight: 600;
477
- color: var(--text-3);
478
- text-transform: uppercase;
479
- letter-spacing: .4px;
480
- }
481
-
482
- input[type="text"],
483
- input[type="email"],
484
- input[type="tel"],
485
- input[type="password"],
486
- input[type="number"],
487
- input[type="time"] {
488
- width: 100%;
489
- padding: 8px 11px;
490
- border: 2px solid #7a7a95;
491
- border-radius: 7px;
492
- font-size: 14px;
493
- font-weight: 500;
494
- color: #ffffff;
495
- background: #55556a;
496
- outline: none;
497
- transition: border-color .15s, box-shadow .15s;
498
- color-scheme: dark;
499
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
500
- }
501
- input::placeholder { color: #cdcdda; opacity: 1; }
502
-
503
- select {
504
- width: 100%;
505
- max-width: 100%;
506
- box-sizing: border-box;
507
- padding: 8px 11px;
508
- border: 2px solid #7a7a95;
509
- border-radius: 7px;
510
- font-size: 14px;
511
- font-weight: 500;
512
- color: #ffffff;
513
- background: #55556a;
514
- outline: none;
515
- transition: border-color .15s, box-shadow .15s;
516
- color-scheme: dark;
517
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
518
- cursor: pointer;
519
- text-overflow: ellipsis;
520
- }
521
- select:hover { border-color: #9a9ab5; }
522
- select:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(124,109,250,.15); }
523
- input[type="text"]:hover,
524
- input[type="email"]:hover,
525
- input[type="tel"]:hover,
526
- input[type="password"]:hover,
527
- input[type="number"]:hover,
528
- input[type="time"]:hover {
529
- border-color: #9a9ab5;
530
- }
531
- input:focus {
532
- border-color: var(--accent);
533
- box-shadow: 0 0 0 2px rgba(124,109,250,.15);
534
- }
535
-
536
- /* Day-of-week + other inline checkbox labels (e.g. DND days selector) */
537
- #dnd-days label,
538
- .day-pick label {
539
- display: inline-flex;
540
- align-items: center;
541
- gap: 6px;
542
- padding: 6px 10px;
543
- border: 2px solid #7a7a95;
544
- border-radius: 6px;
545
- font-size: 12px;
546
- color: #ffffff;
547
- background: #55556a;
548
- cursor: pointer;
549
- user-select: none;
550
- transition: background .15s, border-color .15s;
551
- box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
552
- }
553
- #dnd-days label:hover,
554
- .day-pick label:hover {
555
- background: #6a6a82;
556
- border-color: var(--accent);
557
- }
558
- #dnd-days input[type="checkbox"],
559
- .day-pick input[type="checkbox"] {
560
- accent-color: var(--accent);
561
- width: 16px;
562
- height: 16px;
563
- margin: 0;
564
- }
565
-
566
- /* Hint text next to threshold inputs */
567
- p.hint {
568
- color: #888;
569
- font-size: 12px;
570
- margin: 4px 0 0 0;
571
- line-height: 1.4;
572
- }
573
- p.hint code {
574
- background: #55556a;
575
- padding: 2px 6px;
576
- border-radius: 4px;
577
- font-size: 11px;
578
- color: #ffffff;
579
- border: 1px solid #7a7a95;
580
- }
581
-
582
- /* ── Toggle ──────────────────────────────────────────────────────────────── */
583
-
584
- .toggle-wrap {
585
- display: inline-flex;
586
- align-items: center;
587
- cursor: pointer;
588
- user-select: none;
589
- }
590
- .toggle-wrap input { display: none; }
591
- .toggle {
592
- width: 34px; height: 19px;
593
- background: var(--border);
594
- border-radius: 20px;
595
- position: relative;
596
- transition: background .15s;
597
- flex-shrink: 0;
598
- }
599
- .toggle::after {
600
- content: "";
601
- position: absolute;
602
- width: 13px; height: 13px;
603
- background: #fff;
604
- border-radius: 50%;
605
- top: 3px; left: 3px;
606
- transition: transform .15s;
607
- box-shadow: 0 1px 2px rgba(0,0,0,.3);
608
- }
609
- .toggle-wrap input:checked + .toggle { background: var(--accent); }
610
- .toggle-wrap input:checked + .toggle::after { transform: translateX(15px); }
611
- .toggle-lbl { font-size: 12px; color: var(--text-2); margin-left: 6px; }
612
-
613
- /* ── Buttons ─────────────────────────────────────────────────────────────── */
614
-
615
- .actions {
616
- display: flex;
617
- align-items: center;
618
- gap: 7px;
619
- flex-wrap: wrap;
620
- padding-bottom: 4px;
621
- }
622
-
623
- .btn {
624
- padding: 7px 14px;
625
- border-radius: 7px;
626
- font-size: 13px;
627
- font-weight: 600;
628
- border: none;
629
- cursor: pointer;
630
- display: inline-flex;
631
- align-items: center;
632
- gap: 5px;
633
- white-space: nowrap;
634
- transition: all .15s;
635
- }
636
- .btn-sm { padding: 6px 12px; font-size: 12px; }
637
- .btn:disabled { opacity: .4; cursor: not-allowed; }
638
-
639
- .btn-primary { background: var(--accent); color: #fff; }
640
- .btn-primary:hover:not(:disabled) { background: var(--accent-h); }
641
-
642
- .btn-ghost { background: #1a1a22; color: var(--text-2); border: 1px solid var(--border); }
643
- .btn-ghost:hover:not(:disabled) { background: #222230; }
644
-
645
- .btn-danger { background: transparent; color: #f87171; border: 1px solid #3d1515; }
646
- .btn-danger:hover:not(:disabled) { background: #2e0d0d; }
647
-
648
- .btn-google { background: #1a1a22; color: var(--text); border: 1px solid var(--border); }
649
- .btn-google:hover:not(:disabled) { background: #222230; }
650
-
651
- /* ── Connected banner ────────────────────────────────────────────────────── */
652
-
653
- .ok-banner {
654
- display: flex;
655
- align-items: center;
656
- gap: 7px;
657
- background: #0d2e22;
658
- border: 1px solid #134e35;
659
- border-radius: 7px;
660
- padding: 8px 12px;
661
- font-size: 13px;
662
- color: #34d399;
663
- }
664
-
665
- /* ── gcloud panel ────────────────────────────────────────────────────────── */
666
-
667
- .gcloud-row {
668
- display: flex;
669
- align-items: center;
670
- gap: 8px;
671
- padding: 8px 11px;
672
- border-radius: 7px;
673
- font-size: 12px;
674
- border: 1px solid var(--border);
675
- background: #111118;
676
- }
677
- .gcloud-row .status-text { flex: 1; color: var(--text-2); }
678
- .gcloud-row .status-account { font-weight: 600; }
679
-
680
- .dot {
681
- width: 7px; height: 7px;
682
- border-radius: 50%;
683
- flex-shrink: 0;
684
- }
685
- .dot-ok { background: var(--success); box-shadow: 0 0 5px var(--success); }
686
- .dot-warn { background: var(--warn); box-shadow: 0 0 5px var(--warn); }
687
- .dot-idle { background: var(--text-3); }
688
- .dot-spin {
689
- background: transparent;
690
- border: 2px solid var(--accent);
691
- border-top-color: transparent;
692
- animation: spin .7s linear infinite;
693
- }
694
- @keyframes spin { to { transform: rotate(360deg); } }
695
-
696
- .log-panel {
697
- flex: 1;
698
- overflow-y: auto;
699
- padding: 6px 12px;
700
- font-family: monospace;
701
- font-size: 11px;
702
- line-height: 1.7;
703
- }
704
-
705
- .log-entry { display: flex; gap: 8px; align-items: baseline; }
706
- .log-ts { color: var(--text-3); white-space: nowrap; flex-shrink: 0; }
707
- .log-client { color: var(--accent); font-weight: 700; white-space: nowrap; flex-shrink: 0; }
708
- .log-dir-out { color: #38bdf8; flex-shrink: 0; }
709
- .log-dir-in { color: #4ade80; flex-shrink: 0; }
710
- .log-dir-info { color: var(--text-3); flex-shrink: 0; }
711
- .log-channel { color: #fbbf24; white-space: nowrap; flex-shrink: 0; }
712
- .log-msg { color: var(--text-2); word-break: break-word; }
713
-
714
- /* ── Toast ───────────────────────────────────────────────────────────────── */
715
-
716
- .toast {
717
- position: fixed;
718
- bottom: 20px;
719
- left: 50%;
720
- transform: translateX(-50%);
721
- background: #1a202c;
722
- color: #fff;
723
- padding: 9px 18px;
724
- border-radius: 8px;
725
- font-size: 12px;
726
- font-weight: 500;
727
- box-shadow: 0 4px 20px rgba(0,0,0,.5);
728
- z-index: 1000;
729
- transition: opacity .2s, transform .2s;
730
- }
731
- .toast.toast-ok { background: #065f46; }
732
- .toast.toast-error { background: #7f1d1d; }
733
- .toast.hidden { opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(8px); }
734
-
735
- .hidden { display: none !important; }
736
-
737
- /* ── Multi-destination chips + checklist pickers ─────────────────────────── */
738
-
739
- .chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 22px; align-items: center; }
740
- .chip {
741
- display: inline-flex; align-items: center; gap: 6px;
742
- background: var(--accent-d); border: 1px solid var(--accent);
743
- color: var(--text); font-size: 12px; font-weight: 600;
744
- padding: 3px 7px 3px 10px; border-radius: 14px; max-width: 100%;
745
- }
746
- .chip-x { cursor: pointer; font-size: 15px; line-height: 1; opacity: .65; }
747
- .chip-x:hover { opacity: 1; }
748
- .chip-empty { color: var(--text-3); font-size: 12px; font-style: italic; }
749
-
750
- .dest-add { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
751
-
752
- .picker {
753
- border: 1px solid var(--border); border-radius: 7px;
754
- background: #0d0d18; padding: 5px; max-height: 190px; overflow-y: auto;
755
- display: flex; flex-direction: column; gap: 2px;
756
- }
757
- .picker-item {
758
- display: flex; align-items: center; gap: 8px;
759
- padding: 5px 8px; border-radius: 5px; cursor: pointer; font-size: 12px;
760
- color: var(--text);
761
- }
762
- .picker-item:hover { background: rgba(255,255,255,0.05); }
763
- .picker-item input { accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; }
764
- .picker-actions {
765
- display: flex; gap: 6px; padding: 6px 2px 2px;
766
- position: sticky; bottom: 0; background: #0d0d18;
767
- }
768
- .picker-empty { color: var(--text-3); font-size: 12px; padding: 8px; }
769
- .picker-note { color: var(--text-2); font-size: 11px; padding: 6px 8px; line-height: 1.45; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
770
- .picker-note a { color: var(--accent); font-weight: 600; }
771
- .picker-note code { background: #1a1a2e; padding: 1px 5px; border-radius: 4px; }
772
-
773
- /* ── Compact layout — narrow widths (VS Code activity-bar panel) ──────────── */
774
- /* The same UI is embedded as-is in the VS Code extension webview. At a narrow
775
- width it collapses to a single scrolling column so it fits the side panel. */
776
-
777
- @media (max-width: 620px) {
778
- html, body { height: auto; }
779
- body { font-size: 12px; }
780
-
781
- header { padding: 0 12px; min-height: 44px; gap: 8px; flex-wrap: wrap; }
782
- .subtitle { display: none; }
783
-
784
- main { padding: 8px; gap: 8px; overflow: visible; }
785
-
786
- .config-panel { flex-direction: column; height: auto; overflow: visible; }
787
- .section { height: auto; overflow: visible; padding: 10px 10px 12px; }
788
- .section + .section { border-left: none; border-top: 1px solid var(--border); }
789
-
790
- .card-list { grid-template-columns: 1fr; height: auto; overflow: visible; gap: 8px; }
791
- .row2 { grid-template-columns: 1fr; }
792
-
793
- .log-section { min-height: 220px; }
794
- }
1
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2
+
3
+ :root {
4
+ --bg: #0d0f12;
5
+ --surface: #14171c;
6
+ --border: #242832;
7
+ --text: #e6e8ec;
8
+ --text-2: #9aa3b2;
9
+ --text-3: #5a6478;
10
+ --accent: #4ea3ff; /* bright blue — readable, distinctly "interactive" */
11
+ --accent-h:#6fb6ff;
12
+ --accent-d:#1a3a5c; /* dark variant for backgrounds */
13
+ --success: #4ade80;
14
+ --danger: #f87171;
15
+ --warn: #d4a857; /* muted amber, was glaring orange */
16
+ --r: 8px;
17
+ }
18
+
19
+ html, body { height: 100%; }
20
+
21
+ body {
22
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
23
+ background: var(--bg);
24
+ color: var(--text);
25
+ font-size: 13px;
26
+ line-height: 1.5;
27
+ display: flex;
28
+ flex-direction: column;
29
+ }
30
+
31
+ /* ── Header ──────────────────────────────────────────────────────────────── */
32
+
33
+ header {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 14px;
37
+ padding: 0 20px;
38
+ height: 48px;
39
+ flex-shrink: 0;
40
+ background: var(--surface);
41
+ border-bottom: 1px solid var(--border);
42
+ }
43
+
44
+ .logo {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 7px;
48
+ font-size: 14px;
49
+ font-weight: 700;
50
+ color: var(--accent);
51
+ white-space: nowrap;
52
+ }
53
+
54
+ .subtitle {
55
+ color: var(--text-3);
56
+ font-size: 12px;
57
+ white-space: nowrap;
58
+ }
59
+
60
+ .header-link {
61
+ color: var(--accent);
62
+ background: var(--accent-d);
63
+ border: 1px solid var(--accent);
64
+ font-size: 12px;
65
+ font-weight: 600;
66
+ text-decoration: none;
67
+ padding: 5px 12px;
68
+ border-radius: 6px;
69
+ transition: background .15s, color .15s;
70
+ white-space: nowrap;
71
+ }
72
+ .header-link:hover {
73
+ background: var(--accent);
74
+ color: white;
75
+ }
76
+
77
+ .os-tag {
78
+ font-size: 11px;
79
+ color: var(--warn);
80
+ background: #1c1500;
81
+ border: 1px solid #3a2e00;
82
+ border-radius: 5px;
83
+ padding: 1px 7px;
84
+ white-space: nowrap;
85
+ }
86
+
87
+ /* ── Main ────────────────────────────────────────────────────────────────── */
88
+
89
+ main {
90
+ flex: 1;
91
+ padding: 14px 18px;
92
+ min-height: 0;
93
+ overflow: hidden;
94
+ display: flex;
95
+ flex-direction: column;
96
+ gap: 14px;
97
+ }
98
+
99
+ /* ── Card list (left column) ─────────────────────────────────────────────── */
100
+
101
+ .card-list {
102
+ flex: 1;
103
+ min-height: 0;
104
+ height: 100%;
105
+ overflow: auto;
106
+ display: grid;
107
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
108
+ grid-auto-rows: min-content;
109
+ align-content: start;
110
+ gap: 12px;
111
+ }
112
+
113
+ /* Top half: single Configuration panel with two side-by-side subsections.
114
+ Bottom half: full-width activity log. */
115
+ .config-panel {
116
+ display: flex;
117
+ flex-direction: row;
118
+ flex-shrink: 0;
119
+ /* Take ~60% of the vertical space so the log gets a real chunk too */
120
+ height: 62%;
121
+ min-height: 0;
122
+ border-radius: var(--r);
123
+ border: 1px solid var(--border);
124
+ background: var(--surface);
125
+ overflow: hidden;
126
+ }
127
+
128
+ .section {
129
+ display: flex;
130
+ flex-direction: column;
131
+ gap: 10px;
132
+ padding: 12px 14px 14px;
133
+ min-width: 0;
134
+ height: 100%;
135
+ overflow: hidden;
136
+ }
137
+
138
+ /* ── Master kill switch ──────────────────────────────────────────────────── */
139
+
140
+ .mute-all-bar {
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: space-between;
144
+ gap: 12px;
145
+ flex-shrink: 0;
146
+ padding: 9px 14px;
147
+ border-radius: var(--r);
148
+ border: 1px solid var(--border);
149
+ background: var(--surface);
150
+ }
151
+ .mute-all-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
152
+ .mute-all-icon { font-size: 18px; line-height: 1; flex-shrink: 0; }
153
+ .mute-all-text { display: flex; flex-direction: column; min-width: 0; }
154
+ .mute-all-title { font-weight: 700; font-size: 13px; }
155
+ .mute-all-sub { color: var(--text-2); font-size: 11px; }
156
+ .mute-all-bar.muted {
157
+ border-color: var(--danger);
158
+ background: linear-gradient(0deg, rgba(248,113,113,.12), rgba(248,113,113,.12)), var(--surface);
159
+ box-shadow: inset 0 0 0 1px rgba(248,113,113,.4);
160
+ }
161
+ .mute-all-bar.muted .mute-all-title,
162
+ .mute-all-bar.muted .mute-all-sub { color: var(--danger); }
163
+ body.all-muted .config-panel { opacity: .6; }
164
+
165
+ /* Channels has 4 cards → needs ~3× the room of Policies (which has 2 cards). */
166
+ .section-channels { flex: 3 1 0; }
167
+ .section-policies { flex: 2 1 0; }
168
+
169
+ /* Divider between the two subsections — owned by the panel, not the sections */
170
+ .section + .section {
171
+ border-left: 1px solid var(--border);
172
+ }
173
+
174
+ /* Subtle accent strip at the top of each subsection — color carries the
175
+ role, so the title text stays bright/legible (don't tint text). */
176
+ .section-channels { box-shadow: inset 0 3px 0 0 #4ea3ff; } /* bright blue */
177
+ .section-policies { box-shadow: inset 0 3px 0 0 #d4a857; } /* muted amber */
178
+
179
+ .section-hd {
180
+ display: flex;
181
+ align-items: baseline;
182
+ gap: 8px;
183
+ padding: 4px 2px 10px;
184
+ border-bottom: 1px solid var(--border);
185
+ }
186
+
187
+ .section-hd-title {
188
+ font-size: 11px;
189
+ font-weight: 700;
190
+ letter-spacing: 0.12em;
191
+ text-transform: uppercase;
192
+ color: var(--text);
193
+ }
194
+
195
+ .section-hd-sub {
196
+ font-size: 11px;
197
+ color: var(--text-2);
198
+ margin-left: auto;
199
+ }
200
+
201
+ /* ── Log section (right, fills remaining width) ──────────────────────────── */
202
+
203
+ .log-section {
204
+ flex: 1;
205
+ min-width: 0;
206
+ display: flex;
207
+ flex-direction: column;
208
+ background: var(--surface);
209
+ border: 1px solid var(--border);
210
+ border-radius: var(--r);
211
+ overflow: hidden;
212
+ }
213
+
214
+ .log-header {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: space-between;
218
+ padding: 6px 12px;
219
+ border-bottom: 1px solid var(--border);
220
+ flex-shrink: 0;
221
+ }
222
+
223
+ /* Collapsible activity-log section (collapsed by default). */
224
+ .log-collapse {
225
+ background: transparent; border: none; cursor: pointer; padding: 2px;
226
+ color: var(--text-3); display: inline-flex; align-items: center; flex-shrink: 0;
227
+ }
228
+ .log-collapse:hover { color: var(--text); }
229
+ .log-chevron { width: 16px; height: 16px; transition: transform .2s; }
230
+ .log-section.collapsed .log-chevron { transform: rotate(-90deg); }
231
+ .log-section.collapsed { flex: 0 0 auto; }
232
+ .log-section.collapsed .log-header { border-bottom: none; }
233
+ .log-section.collapsed .log-panel,
234
+ .log-section.collapsed .clients-panel { display: none !important; }
235
+ /* When the log is collapsed, let the config panel grow into the freed space.
236
+ Keep flex-basis = its 62% height so the height:100% chain on .section /
237
+ .card-list stays resolvable (height:auto here collapsed the cards to 0). */
238
+ main:has(.log-section.collapsed) .config-panel { flex: 1 1 auto; }
239
+
240
+ .log-title {
241
+ display: flex;
242
+ align-items: center;
243
+ gap: 7px;
244
+ font-size: 11px;
245
+ font-weight: 700;
246
+ color: var(--text-3);
247
+ text-transform: uppercase;
248
+ letter-spacing: .5px;
249
+ }
250
+
251
+ .log-tabs { display: flex; gap: 2px; flex-shrink: 0; }
252
+ .log-tab {
253
+ font: inherit; font-size: 11px; font-weight: 700;
254
+ text-transform: uppercase; letter-spacing: .5px;
255
+ padding: 4px 10px; border: none; background: transparent;
256
+ color: var(--text-3); cursor: pointer;
257
+ display: inline-flex; align-items: center; gap: 7px;
258
+ border-bottom: 2px solid transparent;
259
+ }
260
+ .log-tab:hover { color: var(--text); }
261
+ .log-tab-active { color: var(--text); border-bottom-color: var(--accent); }
262
+
263
+ .clients-panel { flex: 1; overflow-y: auto; padding: 8px 12px; }
264
+ .client-row {
265
+ display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap;
266
+ padding: 8px 10px; margin-bottom: 6px;
267
+ border: 1px solid var(--border); border-radius: 8px;
268
+ }
269
+ .client-tag {
270
+ font-family: monospace; font-weight: 700; color: var(--text);
271
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
272
+ min-width: 0; flex: 1 1 auto;
273
+ }
274
+ .client-kinds { display: flex; gap: 4px; flex-shrink: 0; }
275
+ .client-kind {
276
+ font-size: 9px; text-transform: uppercase; letter-spacing: .4px;
277
+ padding: 2px 6px; border-radius: 6px;
278
+ background: var(--border); color: var(--text-2);
279
+ }
280
+ .client-actions { display: flex; gap: 4px; flex-shrink: 0; margin-left: auto; }
281
+ .client-actions .btn-sm { padding: 3px 9px; font-size: 11px; }
282
+ .client-meta { flex-basis: 100%; color: var(--text-3); font-size: 11px; }
283
+ .clients-empty { color: var(--text-3); text-align: center; padding: 24px 12px; font-size: 12px; }
284
+
285
+ .session-pills {
286
+ display: flex;
287
+ align-items: center;
288
+ gap: 6px;
289
+ flex: 1;
290
+ justify-content: center;
291
+ flex-wrap: wrap;
292
+ overflow: hidden;
293
+ }
294
+ .pill {
295
+ font: inherit;
296
+ font-size: 11px;
297
+ padding: 3px 10px;
298
+ border-radius: 12px;
299
+ border: 1px solid var(--border);
300
+ background: transparent;
301
+ color: var(--text-2);
302
+ cursor: pointer;
303
+ transition: background .15s, color .15s, border-color .15s;
304
+ white-space: nowrap;
305
+ }
306
+ .pill:hover { border-color: var(--accent); color: var(--text); }
307
+ .pill-active {
308
+ background: var(--accent);
309
+ border-color: var(--accent);
310
+ color: #fff;
311
+ }
312
+ .pill { display: inline-flex; align-items: center; gap: 5px; }
313
+ .pill-dot {
314
+ width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
315
+ }
316
+ .pill-dot-live { background: #4ade80; }
317
+ .pill-dot-idle { background: #facc15; }
318
+ .pill-dot-stale { background: #f87171; }
319
+ .pill-dismiss {
320
+ margin-left: 1px; font-size: 13px; line-height: 1;
321
+ opacity: .6; cursor: pointer;
322
+ }
323
+ .pill-dismiss:hover { opacity: 1; }
324
+
325
+ /* ── Cards ───────────────────────────────────────────────────────────────── */
326
+
327
+ .card {
328
+ width: auto;
329
+ max-width: 100%;
330
+ min-width: 0;
331
+ background: var(--surface);
332
+ border: 2px solid #4a4a5a;
333
+ border-radius: var(--r);
334
+ display: flex;
335
+ flex-direction: column;
336
+ overflow: hidden;
337
+ box-shadow: 0 0 0 1px rgba(255,255,255,0.04), 0 2px 8px rgba(0,0,0,0.4);
338
+ }
339
+
340
+ .card-hd {
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: space-between;
344
+ padding: 10px 14px;
345
+ gap: 8px;
346
+ flex-shrink: 0;
347
+ cursor: pointer;
348
+ user-select: none;
349
+ transition: background .1s;
350
+ }
351
+ .card-hd:hover { background: rgba(255,255,255,0.03); }
352
+ .card.expanded .card-hd { border-bottom: 2px solid #4a4a5a; }
353
+ .ch-meta {
354
+ display: flex;
355
+ align-items: center;
356
+ gap: 8px;
357
+ }
358
+ .ch-name { font-size: 14px; font-weight: 600; }
359
+
360
+ .card-chevron {
361
+ width: 14px;
362
+ height: 14px;
363
+ flex-shrink: 0;
364
+ color: var(--text-3);
365
+ transition: transform .2s;
366
+ }
367
+ .card.expanded .card-chevron { transform: rotate(180deg); }
368
+
369
+ .card-body {
370
+ padding: 12px 14px;
371
+ display: none;
372
+ flex-direction: column;
373
+ gap: 10px;
374
+ flex: 1;
375
+ }
376
+ .card.expanded .card-body { display: flex; }
377
+
378
+ /* ── Channel icons ───────────────────────────────────────────────────────── */
379
+
380
+ .channel-icon {
381
+ width: 26px; height: 26px;
382
+ border-radius: 6px;
383
+ display: flex; align-items: center; justify-content: center;
384
+ flex-shrink: 0;
385
+ }
386
+ .desktop-icon { background: #0d1a2e; color: #60a5fa; }
387
+ .gmail-icon { background: #2e0d0d; color: #f87171; }
388
+ .telegram-icon { background: #0d1e2e; color: #38bdf8; }
389
+ .sms-icon { background: #1e0d2e; color: #c084fc; }
390
+ .ntfy-icon { background: #1a2e0d; color: #86efac; }
391
+ .discord-icon { background: #0d0d2e; color: #a5b4fc; }
392
+ .slack-icon { background: #2e2a0d; color: #fbbf24; }
393
+ .teams-icon { background: #0d1e2e; color: #7dd3fc; }
394
+
395
+ /* ── Tags & badges ───────────────────────────────────────────────────────── */
396
+
397
+ .tag {
398
+ font-size: 10px;
399
+ font-weight: 500;
400
+ background: #1a1a24;
401
+ border: 1px solid var(--border);
402
+ color: var(--text-3);
403
+ padding: 1px 6px;
404
+ border-radius: 20px;
405
+ }
406
+
407
+ .badge {
408
+ font-size: 10px;
409
+ font-weight: 600;
410
+ padding: 2px 8px;
411
+ border-radius: 20px;
412
+ white-space: nowrap;
413
+ flex-shrink: 0;
414
+ }
415
+ .badge-idle { background: #1e1e24; color: var(--text-3); }
416
+ .badge-ok { background: #0d2e22; color: #34d399; }
417
+ .badge-error { background: #2e0d0d; color: #f87171; }
418
+ .badge-warn { background: #2e200d; color: #fbbf24; }
419
+
420
+ /* ── Setup guides ────────────────────────────────────────────────────────── */
421
+
422
+ .guide {
423
+ background: #0d0d18;
424
+ border: 1px solid #252538;
425
+ border-radius: 7px;
426
+ overflow: hidden;
427
+ flex-shrink: 0;
428
+ }
429
+ .guide summary {
430
+ padding: 7px 11px;
431
+ cursor: pointer;
432
+ font-weight: 600;
433
+ font-size: 11px;
434
+ color: var(--accent);
435
+ list-style: none;
436
+ user-select: none;
437
+ display: flex;
438
+ align-items: center;
439
+ gap: 5px;
440
+ }
441
+ .guide summary::-webkit-details-marker { display: none; }
442
+ .guide summary::before { content: "▶"; font-size: 8px; transition: transform .15s; }
443
+ .guide[open] summary::before { transform: rotate(90deg); }
444
+ .guide ol {
445
+ padding: 0 11px 10px 26px;
446
+ font-size: 11px;
447
+ color: var(--text-2);
448
+ display: flex;
449
+ flex-direction: column;
450
+ gap: 4px;
451
+ line-height: 1.5;
452
+ }
453
+ .guide a { color: var(--accent); }
454
+
455
+ code.cp {
456
+ display: inline-block;
457
+ background: #1a1a2e;
458
+ border: 1px solid var(--border);
459
+ border-radius: 4px;
460
+ padding: 1px 6px;
461
+ font-family: monospace;
462
+ font-size: 10px;
463
+ cursor: pointer;
464
+ }
465
+ code.cp:hover { background: #22223a; }
466
+ code.cp::after { content: " 📋"; font-size: 9px; }
467
+
468
+ /* ── Form fields ─────────────────────────────────────────────────────────── */
469
+
470
+ .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
471
+ .fg { display: flex; flex-direction: column; gap: 4px; }
472
+
473
+ .fg label, label.lbl {
474
+ font-size: 11px;
475
+ font-weight: 600;
476
+ color: var(--text-3);
477
+ text-transform: uppercase;
478
+ letter-spacing: .4px;
479
+ }
480
+
481
+ input[type="text"],
482
+ input[type="email"],
483
+ input[type="tel"],
484
+ input[type="password"],
485
+ input[type="number"],
486
+ input[type="time"] {
487
+ width: 100%;
488
+ padding: 8px 11px;
489
+ border: 2px solid #7a7a95;
490
+ border-radius: 7px;
491
+ font-size: 14px;
492
+ font-weight: 500;
493
+ color: #ffffff;
494
+ background: #55556a;
495
+ outline: none;
496
+ transition: border-color .15s, box-shadow .15s;
497
+ color-scheme: dark;
498
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
499
+ }
500
+ input::placeholder { color: #cdcdda; opacity: 1; }
501
+
502
+ select {
503
+ width: 100%;
504
+ max-width: 100%;
505
+ box-sizing: border-box;
506
+ padding: 8px 11px;
507
+ border: 2px solid #7a7a95;
508
+ border-radius: 7px;
509
+ font-size: 14px;
510
+ font-weight: 500;
511
+ color: #ffffff;
512
+ background: #55556a;
513
+ outline: none;
514
+ transition: border-color .15s, box-shadow .15s;
515
+ color-scheme: dark;
516
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
517
+ cursor: pointer;
518
+ text-overflow: ellipsis;
519
+ }
520
+ select:hover { border-color: #9a9ab5; }
521
+ select:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(124,109,250,.15); }
522
+ input[type="text"]:hover,
523
+ input[type="email"]:hover,
524
+ input[type="tel"]:hover,
525
+ input[type="password"]:hover,
526
+ input[type="number"]:hover,
527
+ input[type="time"]:hover {
528
+ border-color: #9a9ab5;
529
+ }
530
+ input:focus {
531
+ border-color: var(--accent);
532
+ box-shadow: 0 0 0 2px rgba(124,109,250,.15);
533
+ }
534
+
535
+ /* Day-of-week + other inline checkbox labels (e.g. DND days selector) */
536
+ #dnd-days label,
537
+ .day-pick label {
538
+ display: inline-flex;
539
+ align-items: center;
540
+ gap: 6px;
541
+ padding: 6px 10px;
542
+ border: 2px solid #7a7a95;
543
+ border-radius: 6px;
544
+ font-size: 12px;
545
+ color: #ffffff;
546
+ background: #55556a;
547
+ cursor: pointer;
548
+ user-select: none;
549
+ transition: background .15s, border-color .15s;
550
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
551
+ }
552
+ #dnd-days label:hover,
553
+ .day-pick label:hover {
554
+ background: #6a6a82;
555
+ border-color: var(--accent);
556
+ }
557
+ #dnd-days input[type="checkbox"],
558
+ .day-pick input[type="checkbox"] {
559
+ accent-color: var(--accent);
560
+ width: 16px;
561
+ height: 16px;
562
+ margin: 0;
563
+ }
564
+
565
+ /* Hint text next to threshold inputs */
566
+ p.hint {
567
+ color: #888;
568
+ font-size: 12px;
569
+ margin: 4px 0 0 0;
570
+ line-height: 1.4;
571
+ }
572
+ p.hint code {
573
+ background: #55556a;
574
+ padding: 2px 6px;
575
+ border-radius: 4px;
576
+ font-size: 11px;
577
+ color: #ffffff;
578
+ border: 1px solid #7a7a95;
579
+ }
580
+
581
+ /* ── Toggle ──────────────────────────────────────────────────────────────── */
582
+
583
+ .toggle-wrap {
584
+ display: inline-flex;
585
+ align-items: center;
586
+ cursor: pointer;
587
+ user-select: none;
588
+ }
589
+ .toggle-wrap input { display: none; }
590
+ .toggle {
591
+ width: 34px; height: 19px;
592
+ background: var(--border);
593
+ border-radius: 20px;
594
+ position: relative;
595
+ transition: background .15s;
596
+ flex-shrink: 0;
597
+ }
598
+ .toggle::after {
599
+ content: "";
600
+ position: absolute;
601
+ width: 13px; height: 13px;
602
+ background: #fff;
603
+ border-radius: 50%;
604
+ top: 3px; left: 3px;
605
+ transition: transform .15s;
606
+ box-shadow: 0 1px 2px rgba(0,0,0,.3);
607
+ }
608
+ .toggle-wrap input:checked + .toggle { background: var(--accent); }
609
+ .toggle-wrap input:checked + .toggle::after { transform: translateX(15px); }
610
+ .toggle-lbl { font-size: 12px; color: var(--text-2); margin-left: 6px; }
611
+
612
+ /* ── Buttons ─────────────────────────────────────────────────────────────── */
613
+
614
+ .actions {
615
+ display: flex;
616
+ align-items: center;
617
+ gap: 7px;
618
+ flex-wrap: wrap;
619
+ padding-bottom: 4px;
620
+ }
621
+
622
+ .btn {
623
+ padding: 7px 14px;
624
+ border-radius: 7px;
625
+ font-size: 13px;
626
+ font-weight: 600;
627
+ border: none;
628
+ cursor: pointer;
629
+ display: inline-flex;
630
+ align-items: center;
631
+ gap: 5px;
632
+ white-space: nowrap;
633
+ transition: all .15s;
634
+ }
635
+ .btn-sm { padding: 6px 12px; font-size: 12px; }
636
+ .btn:disabled { opacity: .4; cursor: not-allowed; }
637
+
638
+ .btn-primary { background: var(--accent); color: #fff; }
639
+ .btn-primary:hover:not(:disabled) { background: var(--accent-h); }
640
+
641
+ .btn-ghost { background: #1a1a22; color: var(--text-2); border: 1px solid var(--border); }
642
+ .btn-ghost:hover:not(:disabled) { background: #222230; }
643
+
644
+ .btn-danger { background: transparent; color: #f87171; border: 1px solid #3d1515; }
645
+ .btn-danger:hover:not(:disabled) { background: #2e0d0d; }
646
+
647
+ .btn-google { background: #1a1a22; color: var(--text); border: 1px solid var(--border); }
648
+ .btn-google:hover:not(:disabled) { background: #222230; }
649
+
650
+ /* ── Connected banner ────────────────────────────────────────────────────── */
651
+
652
+ .ok-banner {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 7px;
656
+ background: #0d2e22;
657
+ border: 1px solid #134e35;
658
+ border-radius: 7px;
659
+ padding: 8px 12px;
660
+ font-size: 13px;
661
+ color: #34d399;
662
+ }
663
+
664
+ /* ── gcloud panel ────────────────────────────────────────────────────────── */
665
+
666
+ .gcloud-row {
667
+ display: flex;
668
+ align-items: center;
669
+ gap: 8px;
670
+ padding: 8px 11px;
671
+ border-radius: 7px;
672
+ font-size: 12px;
673
+ border: 1px solid var(--border);
674
+ background: #111118;
675
+ }
676
+ .gcloud-row .status-text { flex: 1; color: var(--text-2); }
677
+ .gcloud-row .status-account { font-weight: 600; }
678
+
679
+ .dot {
680
+ width: 7px; height: 7px;
681
+ border-radius: 50%;
682
+ flex-shrink: 0;
683
+ }
684
+ .dot-ok { background: var(--success); box-shadow: 0 0 5px var(--success); }
685
+ .dot-warn { background: var(--warn); box-shadow: 0 0 5px var(--warn); }
686
+ .dot-idle { background: var(--text-3); }
687
+ .dot-spin {
688
+ background: transparent;
689
+ border: 2px solid var(--accent);
690
+ border-top-color: transparent;
691
+ animation: spin .7s linear infinite;
692
+ }
693
+ @keyframes spin { to { transform: rotate(360deg); } }
694
+
695
+ .log-panel {
696
+ flex: 1;
697
+ overflow-y: auto;
698
+ padding: 6px 12px;
699
+ font-family: monospace;
700
+ font-size: 11px;
701
+ line-height: 1.7;
702
+ }
703
+
704
+ .log-entry { display: flex; gap: 8px; align-items: baseline; }
705
+ .log-ts { color: var(--text-3); white-space: nowrap; flex-shrink: 0; }
706
+ .log-client { color: var(--accent); font-weight: 700; white-space: nowrap; flex-shrink: 0; }
707
+ .log-dir-out { color: #38bdf8; flex-shrink: 0; }
708
+ .log-dir-in { color: #4ade80; flex-shrink: 0; }
709
+ .log-dir-info { color: var(--text-3); flex-shrink: 0; }
710
+ .log-channel { color: #fbbf24; white-space: nowrap; flex-shrink: 0; }
711
+ .log-msg { color: var(--text-2); word-break: break-word; }
712
+
713
+ /* ── Toast ───────────────────────────────────────────────────────────────── */
714
+
715
+ .toast {
716
+ position: fixed;
717
+ bottom: 20px;
718
+ left: 50%;
719
+ transform: translateX(-50%);
720
+ background: #1a202c;
721
+ color: #fff;
722
+ padding: 9px 18px;
723
+ border-radius: 8px;
724
+ font-size: 12px;
725
+ font-weight: 500;
726
+ box-shadow: 0 4px 20px rgba(0,0,0,.5);
727
+ z-index: 1000;
728
+ transition: opacity .2s, transform .2s;
729
+ }
730
+ .toast.toast-ok { background: #065f46; }
731
+ .toast.toast-error { background: #7f1d1d; }
732
+ .toast.hidden { opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(8px); }
733
+
734
+ .hidden { display: none !important; }
735
+
736
+ /* ── Multi-destination chips + checklist pickers ─────────────────────────── */
737
+
738
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 22px; align-items: center; }
739
+ .chip {
740
+ display: inline-flex; align-items: center; gap: 6px;
741
+ background: var(--accent-d); border: 1px solid var(--accent);
742
+ color: var(--text); font-size: 12px; font-weight: 600;
743
+ padding: 3px 7px 3px 10px; border-radius: 14px; max-width: 100%;
744
+ }
745
+ .chip-x { cursor: pointer; font-size: 15px; line-height: 1; opacity: .65; }
746
+ .chip-x:hover { opacity: 1; }
747
+ .chip-empty { color: var(--text-3); font-size: 12px; font-style: italic; }
748
+
749
+ .dest-add { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
750
+
751
+ .picker {
752
+ border: 1px solid var(--border); border-radius: 7px;
753
+ background: #0d0d18; padding: 5px; max-height: 190px; overflow-y: auto;
754
+ display: flex; flex-direction: column; gap: 2px;
755
+ }
756
+ .picker-item {
757
+ display: flex; align-items: center; gap: 8px;
758
+ padding: 5px 8px; border-radius: 5px; cursor: pointer; font-size: 12px;
759
+ color: var(--text);
760
+ }
761
+ .picker-item:hover { background: rgba(255,255,255,0.05); }
762
+ .picker-item input { accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; }
763
+ .picker-actions {
764
+ display: flex; gap: 6px; padding: 6px 2px 2px;
765
+ position: sticky; bottom: 0; background: #0d0d18;
766
+ }
767
+ .picker-empty { color: var(--text-3); font-size: 12px; padding: 8px; }
768
+ .picker-note { color: var(--text-2); font-size: 11px; padding: 6px 8px; line-height: 1.45; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
769
+ .picker-note a { color: var(--accent); font-weight: 600; }
770
+ .picker-note code { background: #1a1a2e; padding: 1px 5px; border-radius: 4px; }
771
+
772
+ /* ── Compact layout — narrow widths (VS Code activity-bar panel) ──────────── */
773
+ /* The same UI is embedded as-is in the VS Code extension webview. At a narrow
774
+ width it collapses to a single scrolling column so it fits the side panel. */
775
+
776
+ @media (max-width: 620px) {
777
+ html, body { height: auto; }
778
+ body { font-size: 12px; }
779
+
780
+ header { padding: 0 12px; min-height: 44px; gap: 8px; flex-wrap: wrap; }
781
+ .subtitle { display: none; }
782
+
783
+ main { padding: 8px; gap: 8px; overflow: visible; }
784
+
785
+ .config-panel { flex-direction: column; height: auto; overflow: visible; }
786
+ .section { height: auto; overflow: visible; padding: 10px 10px 12px; }
787
+ .section + .section { border-left: none; border-top: 1px solid var(--border); }
788
+
789
+ .card-list { grid-template-columns: 1fr; height: auto; overflow: visible; gap: 8px; }
790
+ .row2 { grid-template-columns: 1fr; }
791
+
792
+ .log-section { min-height: 220px; }
793
+ }