@naviyra/cloud-panel 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.env.example +40 -0
  2. package/README.md +145 -2
  3. package/apps/agent/package.json +13 -0
  4. package/apps/agent/src/cloudflare.mjs +733 -0
  5. package/apps/agent/src/native-worker.mjs +52 -0
  6. package/apps/agent/src/native.mjs +457 -0
  7. package/apps/agent/src/runtime.mjs +760 -0
  8. package/apps/agent/src/server.mjs +195 -0
  9. package/apps/agent/src/static-server.mjs +53 -0
  10. package/apps/panel/AGENTS.md +9 -0
  11. package/apps/panel/CLAUDE.md +1 -0
  12. package/apps/panel/app/api/[...path]/route.js +445 -0
  13. package/apps/panel/app/globals.css +2057 -0
  14. package/apps/panel/app/icon.png +0 -0
  15. package/apps/panel/app/layout.jsx +18 -0
  16. package/apps/panel/app/login/page.jsx +108 -0
  17. package/apps/panel/app/page.jsx +33 -0
  18. package/apps/panel/app/ui/cloudflare.jsx +926 -0
  19. package/apps/panel/app/ui/dashboard.jsx +1487 -0
  20. package/apps/panel/app/ui/databases.jsx +293 -0
  21. package/apps/panel/app/ui/skeleton.jsx +196 -0
  22. package/apps/panel/app/ui/theme.jsx +35 -0
  23. package/apps/panel/lib/agent.mjs +83 -0
  24. package/apps/panel/lib/auth.mjs +48 -0
  25. package/apps/panel/lib/database-runtime.mjs +243 -0
  26. package/apps/panel/lib/databases.mjs +292 -0
  27. package/apps/panel/lib/db.mjs +6 -0
  28. package/apps/panel/next.config.mjs +8 -0
  29. package/apps/panel/package.json +22 -0
  30. package/apps/panel/public/naviyra-logo.png +0 -0
  31. package/bin/naviyra.mjs +215 -0
  32. package/db/001_init.sql +28 -0
  33. package/db/002_native_runtimes.sql +3 -0
  34. package/db/003_databases.sql +8 -0
  35. package/db/004_database_engines.sql +4 -0
  36. package/deploy/naviyra-agent.service +17 -0
  37. package/docker-compose.yml +18 -0
  38. package/docs/managed-runtime.md +52 -0
  39. package/docs/native-hosts.md +48 -0
  40. package/package.json +61 -4
  41. package/packages/runtime/artifacts.json +32 -0
  42. package/packages/runtime/index.cjs +526 -0
  43. package/packages/runtime/index.mjs +10 -0
  44. package/packages/runtime/package.json +6 -0
  45. package/packages/shared/index.mjs +85 -0
  46. package/packages/shared/package.json +9 -0
  47. package/scripts/migrate.mjs +18 -0
  48. package/scripts/panel-control.mjs +195 -0
  49. package/scripts/postgres-local.mjs +97 -0
  50. package/scripts/runtime-download-manifest.mjs +30 -0
  51. package/scripts/runtime.mjs +20 -0
  52. package/scripts/seed.mjs +35 -0
  53. package/scripts/service-supervisor.mjs +164 -0
  54. package/scripts/setup-local.mjs +215 -0
  55. package/scripts/start-naviyra.mjs +303 -0
  56. package/scripts/windows-boot.mjs +259 -0
@@ -0,0 +1,2057 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;450;500;550;600;650;700&family=Manrope:wght@400;500;600;650;700;750;800&display=swap");
2
+ :root {
3
+ --bg: #f6f8fa;
4
+ --surface: #ffffff;
5
+ --ink: #192b36;
6
+ --muted: #849098;
7
+ --line: #e7ecee;
8
+ --green: #138576;
9
+ --green-dark: #116d63;
10
+ --green-light: #e7f5ef;
11
+ --sidebar: 246px;
12
+ --skeleton: #e4eaec;
13
+ --skeleton-shine: #f7f9fa;
14
+ color-scheme: light;
15
+ }
16
+ .menu-button,
17
+ .mobile-nav {
18
+ display: none;
19
+ }
20
+ @media (max-width: 580px) {
21
+ .menu-button {
22
+ display: inline-flex;
23
+ width: 34px;
24
+ height: 34px;
25
+ margin-right: 4px;
26
+ padding: 0;
27
+ border: 1px solid var(--line);
28
+ border-radius: 8px;
29
+ background: var(--surface);
30
+ color: var(--ink);
31
+ }
32
+ }
33
+ * {
34
+ box-sizing: border-box;
35
+ }
36
+ body {
37
+ margin: 0;
38
+ background: var(--bg);
39
+ color: var(--ink);
40
+ font-family: "DM Sans", Arial, sans-serif;
41
+ font-size: 13px;
42
+ }
43
+ button,
44
+ input,
45
+ select {
46
+ font: inherit;
47
+ }
48
+ button,
49
+ a,
50
+ input,
51
+ select {
52
+ outline-color: var(--green);
53
+ }
54
+ button {
55
+ cursor: pointer;
56
+ transition:
57
+ background 0.16s,
58
+ transform 0.16s;
59
+ }
60
+ button:disabled {
61
+ cursor: not-allowed;
62
+ opacity: 0.5;
63
+ }
64
+ a {
65
+ color: inherit;
66
+ text-decoration: none;
67
+ }
68
+ button svg,
69
+ a svg {
70
+ flex-shrink: 0;
71
+ }
72
+ button {
73
+ display: inline-flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ gap: 8px;
77
+ border: 0;
78
+ }
79
+ button:hover:not(:disabled) {
80
+ filter: brightness(0.97);
81
+ }
82
+ .brand {
83
+ display: flex;
84
+ align-items: center;
85
+ }
86
+ .brand-logo {
87
+ display: block;
88
+ width: 168px;
89
+ height: auto;
90
+ }
91
+ .login-story .brand-logo {
92
+ width: 220px;
93
+ }
94
+ .sidebar {
95
+ position: fixed;
96
+ inset: 0 auto 0 0;
97
+ width: var(--sidebar);
98
+ background: var(--surface);
99
+ border-right: 1px solid var(--line);
100
+ padding: 18px 16px 0;
101
+ display: flex;
102
+ flex-direction: column;
103
+ }
104
+ .sidebar .brand {
105
+ padding-left: 9px;
106
+ }
107
+ .profile small {
108
+ display: block;
109
+ font-size: 10px;
110
+ font-weight: 400;
111
+ color: var(--muted);
112
+ margin-top: 4px;
113
+ }
114
+ .nav-label {
115
+ font-size: 9px;
116
+ letter-spacing: 1.5px;
117
+ color: #9da6ad;
118
+ font-weight: 600;
119
+ margin: 16px 12px 10px;
120
+ }
121
+ .nav-item {
122
+ width: 100%;
123
+ padding: 13px 14px;
124
+ justify-content: flex-start;
125
+ color: #7d8892;
126
+ background: transparent;
127
+ border-radius: 7px;
128
+ margin-bottom: 5px;
129
+ font-weight: 500;
130
+ gap: 12px;
131
+ }
132
+ .nav-item.active {
133
+ color: #147f70;
134
+ background: #eaf5f1;
135
+ }
136
+ .nav-item span {
137
+ margin-left: auto;
138
+ font-size: 10px;
139
+ background: var(--surface);
140
+ min-width: 22px;
141
+ border-radius: 4px;
142
+ padding: 3px 6px;
143
+ }
144
+ .sidebar-bottom {
145
+ margin-top: auto;
146
+ }
147
+ .profile {
148
+ width: 100%;
149
+ border-top: 1px solid var(--line);
150
+ background: var(--surface);
151
+ padding: 21px 4px;
152
+ text-align: left;
153
+ justify-content: flex-start;
154
+ gap: 10px;
155
+ font-size: 12px;
156
+ }
157
+ .profile > svg {
158
+ margin-left: auto;
159
+ color: var(--muted);
160
+ }
161
+ .avatar {
162
+ width: 33px;
163
+ height: 33px;
164
+ border-radius: 50%;
165
+ display: grid;
166
+ place-items: center;
167
+ font-size: 12px;
168
+ font-weight: 600;
169
+ background: #efeee8;
170
+ color: #797460;
171
+ border: 3px solid var(--surface);
172
+ box-shadow: 0 0 0 1px #e9e9e4;
173
+ }
174
+ .avatar.small {
175
+ width: 30px;
176
+ height: 30px;
177
+ font-size: 10px;
178
+ }
179
+ .main-shell {
180
+ margin-left: var(--sidebar);
181
+ min-height: 100vh;
182
+ }
183
+ .topbar {
184
+ height: 52px;
185
+ display: flex;
186
+ align-items: center;
187
+ justify-content: space-between;
188
+ padding: 0 42px;
189
+ border-bottom: 1px solid var(--line);
190
+ background: var(--surface);
191
+ font-size: 11px;
192
+ }
193
+ .topbar > div {
194
+ display: flex;
195
+ align-items: center;
196
+ gap: 15px;
197
+ color: var(--muted);
198
+ }
199
+ .topbar strong {
200
+ font-weight: 500;
201
+ color: #34444e;
202
+ }
203
+ .topbar-right {
204
+ gap: 24px !important;
205
+ }
206
+ .connection {
207
+ display: flex;
208
+ align-items: center;
209
+ gap: 7px;
210
+ color: #60736b;
211
+ font-size: 10px;
212
+ }
213
+ .connection i,
214
+ .green-dot {
215
+ display: inline-block;
216
+ width: 6px;
217
+ height: 6px;
218
+ border-radius: 50%;
219
+ background: #33aa84;
220
+ }
221
+ .connection.offline i {
222
+ background: #d17564;
223
+ }
224
+ .content {
225
+ padding: 8px 32px 0;
226
+ max-width: 1660px;
227
+ margin: auto;
228
+ }
229
+ .page-heading {
230
+ display: flex;
231
+ justify-content: space-between;
232
+ align-items: center;
233
+ margin: 4px 0 14px;
234
+ flex-wrap: wrap;
235
+ gap: 15px;
236
+ }
237
+ .eyebrow {
238
+ font-size: 9px;
239
+ font-weight: 600;
240
+ letter-spacing: 1.8px;
241
+ color: var(--muted);
242
+ margin-bottom: 4px;
243
+ }
244
+ h1,
245
+ h2,
246
+ h3,
247
+ p {
248
+ margin-top: 0;
249
+ }
250
+ h1,
251
+ h2,
252
+ h3 {
253
+ font-family: Manrope, Arial, sans-serif;
254
+ }
255
+ h1 {
256
+ font-size: 32px;
257
+ font-weight: 750;
258
+ letter-spacing: -1.2px;
259
+ margin-bottom: 4px;
260
+ line-height: 1.2;
261
+ }
262
+ .title-dot {
263
+ color: var(--green);
264
+ }
265
+ .page-heading p {
266
+ color: var(--muted);
267
+ font-size: 12px;
268
+ margin: 0;
269
+ }
270
+ .primary,
271
+ .secondary,
272
+ .danger {
273
+ border-radius: 6px;
274
+ padding: 11px 16px;
275
+ min-height: 38px;
276
+ font-size: 11px;
277
+ font-weight: 550;
278
+ white-space: nowrap;
279
+ }
280
+ .primary {
281
+ color: white;
282
+ background: var(--green);
283
+ box-shadow: 0 2px 3px #0a625d12;
284
+ }
285
+ .secondary {
286
+ color: #43515c;
287
+ background: var(--surface);
288
+ border: 1px solid #dfe5e8;
289
+ }
290
+ .danger {
291
+ background: var(--surface);
292
+ border: 1px solid #efdcda;
293
+ color: #b65c58;
294
+ }
295
+ .stats {
296
+ display: grid;
297
+ grid-template-columns: repeat(4, minmax(0, 1fr));
298
+ gap: 12px;
299
+ margin-bottom: 16px;
300
+ }
301
+ .stat {
302
+ background: var(--surface);
303
+ border: 1px solid var(--line);
304
+ border-radius: 9px;
305
+ padding: 14px 16px 12px;
306
+ }
307
+ .stat > div {
308
+ display: flex;
309
+ align-items: center;
310
+ justify-content: space-between;
311
+ color: #7c8891;
312
+ font-size: 10px;
313
+ font-weight: 500;
314
+ gap: 6px;
315
+ }
316
+ .stat > div svg {
317
+ color: #9aa7ac;
318
+ }
319
+ .stat > strong {
320
+ display: block;
321
+ font-family: Manrope, sans-serif;
322
+ font-size: 29px;
323
+ font-weight: 650;
324
+ letter-spacing: -0.6px;
325
+ margin: 8px 0 4px;
326
+ overflow-wrap: anywhere;
327
+ }
328
+ .stat > small {
329
+ display: flex;
330
+ align-items: center;
331
+ gap: 6px;
332
+ color: #9aa3aa;
333
+ font-size: 9px;
334
+ }
335
+ .stat.accent > div svg,
336
+ .stat.accent > strong {
337
+ color: var(--green);
338
+ }
339
+ .stat.warning > strong {
340
+ color: #b65c58;
341
+ }
342
+ .panel {
343
+ background: var(--surface);
344
+ border: 1px solid var(--line);
345
+ border-radius: 9px;
346
+ overflow: hidden;
347
+ }
348
+ .section-heading {
349
+ display: flex;
350
+ align-items: center;
351
+ justify-content: space-between;
352
+ gap: 15px;
353
+ padding: 14px 18px;
354
+ border-bottom: 1px solid var(--line);
355
+ color: #8a979f;
356
+ }
357
+ .section-heading h2 {
358
+ color: #293c46;
359
+ font-size: 13px;
360
+ font-weight: 700;
361
+ margin: 0;
362
+ display: flex;
363
+ align-items: center;
364
+ gap: 9px;
365
+ }
366
+ .title-row {
367
+ display: flex;
368
+ align-items: center;
369
+ gap: 10px;
370
+ }
371
+ .title-row h1 {
372
+ margin-bottom: 8px;
373
+ }
374
+ .count {
375
+ font-size: 9px;
376
+ background: #f0f3f5;
377
+ color: #8d989f;
378
+ padding: 3px 7px;
379
+ border-radius: 4px;
380
+ }
381
+ .icon-button {
382
+ width: 28px;
383
+ height: 28px;
384
+ background: transparent;
385
+ color: #8c999f;
386
+ border-radius: 5px;
387
+ }
388
+ .toolbar {
389
+ padding: 10px 18px;
390
+ display: flex;
391
+ align-items: center;
392
+ gap: 12px;
393
+ }
394
+ .search {
395
+ display: flex;
396
+ align-items: center;
397
+ gap: 8px;
398
+ border: 1px solid var(--line);
399
+ border-radius: 6px;
400
+ padding: 0 11px;
401
+ height: 34px;
402
+ color: #929da5;
403
+ max-width: 290px;
404
+ flex: 1;
405
+ }
406
+ .search input {
407
+ border: 0;
408
+ background: transparent;
409
+ padding: 0;
410
+ font-size: 10px;
411
+ min-width: 0;
412
+ width: 100%;
413
+ outline: 0;
414
+ }
415
+ input::placeholder {
416
+ color: #a3acb1;
417
+ }
418
+ .toolbar select {
419
+ border: 1px solid var(--line);
420
+ border-radius: 6px;
421
+ background: var(--surface);
422
+ padding: 8px 11px;
423
+ color: #71818b;
424
+ font-size: 10px;
425
+ }
426
+ .toolbar-count {
427
+ margin-left: auto;
428
+ font-size: 10px;
429
+ color: #9fa8ae;
430
+ }
431
+ .table-wrap {
432
+ overflow-x: auto;
433
+ }
434
+ table {
435
+ width: 100%;
436
+ border-collapse: collapse;
437
+ text-align: left;
438
+ white-space: nowrap;
439
+ }
440
+ th {
441
+ background: #fafbfc;
442
+ color: #98a2a9;
443
+ font-size: 8px;
444
+ font-weight: 500;
445
+ letter-spacing: 1px;
446
+ padding: 10px 14px;
447
+ border-top: 1px solid var(--line);
448
+ border-bottom: 1px solid var(--line);
449
+ }
450
+ th:first-child,
451
+ td:first-child {
452
+ padding-left: 23px;
453
+ }
454
+ td {
455
+ font-size: 11px;
456
+ padding: 12px 14px;
457
+ border-bottom: 1px solid #edf0f2;
458
+ }
459
+ tbody tr {
460
+ cursor: pointer;
461
+ }
462
+ tbody tr:hover {
463
+ background: #fcfdfd;
464
+ }
465
+ tbody tr:last-child td {
466
+ border-bottom: 0;
467
+ }
468
+ .project-name {
469
+ display: flex;
470
+ gap: 12px;
471
+ align-items: center;
472
+ }
473
+ .project-icon {
474
+ display: flex;
475
+ align-items: center;
476
+ justify-content: center;
477
+ width: 37px;
478
+ height: 37px;
479
+ border: 1px solid #e4ede8;
480
+ background: #f1f7f3;
481
+ border-radius: 9px;
482
+ color: #5b8c72;
483
+ flex-shrink: 0;
484
+ }
485
+ .name-button {
486
+ padding: 0;
487
+ background: transparent;
488
+ font-size: 12px;
489
+ font-weight: 600;
490
+ color: #31454e;
491
+ }
492
+ .project-name small {
493
+ display: flex;
494
+ align-items: center;
495
+ gap: 5px;
496
+ font-size: 9px;
497
+ color: #9aa5ac;
498
+ margin-top: 6px;
499
+ }
500
+ .badge {
501
+ display: inline-flex;
502
+ align-items: center;
503
+ gap: 5px;
504
+ border-radius: 4px;
505
+ padding: 5px 7px;
506
+ background: #f1f3f5;
507
+ color: #82929c;
508
+ font-size: 9px;
509
+ text-transform: capitalize;
510
+ white-space: nowrap;
511
+ }
512
+ .badge i {
513
+ width: 5px;
514
+ height: 5px;
515
+ border-radius: 50%;
516
+ background: currentColor;
517
+ }
518
+ .badge.running {
519
+ background: #eaf6ef;
520
+ color: #258766;
521
+ }
522
+ .badge.failed {
523
+ background: #fcefeb;
524
+ color: #c6765d;
525
+ }
526
+ .badge.deploying,
527
+ .badge.queued {
528
+ background: #fdf5e5;
529
+ color: #ad873a;
530
+ }
531
+ .domain {
532
+ display: inline-flex;
533
+ align-items: center;
534
+ gap: 6px;
535
+ color: #7c8b96;
536
+ font-size: 10px;
537
+ }
538
+ .mono {
539
+ font-family: Consolas, monospace;
540
+ font-size: 11px;
541
+ }
542
+ .muted {
543
+ color: var(--muted);
544
+ }
545
+ .unreachable {
546
+ display: block;
547
+ color: #b17455;
548
+ font-size: 9px;
549
+ margin-top: 5px;
550
+ }
551
+ .table-footer {
552
+ padding: 14px 23px;
553
+ border-top: 1px solid var(--line);
554
+ display: flex;
555
+ align-items: center;
556
+ justify-content: space-between;
557
+ color: #9aa5ab;
558
+ font-size: 9px;
559
+ background: #fdfefe;
560
+ }
561
+ .table-footer > span:first-child {
562
+ display: flex;
563
+ align-items: center;
564
+ gap: 6px;
565
+ }
566
+ .empty {
567
+ padding: 28px 16px 24px;
568
+ display: flex;
569
+ flex-direction: column;
570
+ align-items: center;
571
+ text-align: center;
572
+ }
573
+ .empty-icon {
574
+ color: var(--green);
575
+ width: 66px;
576
+ height: 66px;
577
+ background: #eef6f2;
578
+ border: 1px solid #e4eee8;
579
+ border-radius: 17px;
580
+ display: grid;
581
+ place-items: center;
582
+ margin-bottom: 20px;
583
+ transform: rotate(-5deg);
584
+ }
585
+ .empty h3 {
586
+ font-size: 17px;
587
+ margin-bottom: 10px;
588
+ }
589
+ .empty p {
590
+ font-size: 11px;
591
+ color: var(--muted);
592
+ max-width: 330px;
593
+ line-height: 1.8;
594
+ margin-bottom: 20px;
595
+ }
596
+ .empty .primary {
597
+ font-size: 10px;
598
+ padding: 10px 13px;
599
+ }
600
+ .loading {
601
+ padding: 28px;
602
+ text-align: center;
603
+ color: var(--muted);
604
+ }
605
+ .load-progress {
606
+ height: 3px;
607
+ overflow: hidden;
608
+ background: #e7eeec;
609
+ }
610
+ .load-progress i {
611
+ display: block;
612
+ width: 35%;
613
+ height: 100%;
614
+ background: var(--green);
615
+ animation: load-slide 1.1s ease-in-out infinite;
616
+ }
617
+ @keyframes load-slide {
618
+ 0% {
619
+ transform: translateX(-120%);
620
+ }
621
+ 100% {
622
+ transform: translateX(320%);
623
+ }
624
+ }
625
+ .dns-table-wrap {
626
+ overflow: hidden;
627
+ }
628
+ .dns-table {
629
+ table-layout: fixed;
630
+ }
631
+ .dns-table th:nth-child(1),
632
+ .dns-table td:nth-child(1) {
633
+ width: 72px;
634
+ }
635
+ .dns-table th:nth-child(2),
636
+ .dns-table td:nth-child(2) {
637
+ width: 22%;
638
+ }
639
+ .dns-table th:nth-child(4),
640
+ .dns-table td:nth-child(4) {
641
+ width: 96px;
642
+ }
643
+ .dns-table th:nth-child(5),
644
+ .dns-table td:nth-child(5) {
645
+ width: 72px;
646
+ }
647
+ .dns-table th:nth-child(6),
648
+ .dns-table td:nth-child(6) {
649
+ width: 88px;
650
+ }
651
+ .dns-table td,
652
+ .dns-table th {
653
+ overflow: hidden;
654
+ text-overflow: ellipsis;
655
+ }
656
+ .dns-table td:last-child,
657
+ .dns-table th:last-child {
658
+ overflow: visible;
659
+ text-overflow: clip;
660
+ }
661
+ .skeleton {
662
+ display: block;
663
+ height: 10px;
664
+ max-width: 100%;
665
+ border-radius: 5px;
666
+ background: linear-gradient(
667
+ 90deg,
668
+ var(--skeleton) 0%,
669
+ var(--skeleton-shine) 45%,
670
+ var(--skeleton) 100%
671
+ );
672
+ background-size: 220% 100%;
673
+ animation: skeleton-shimmer 1.35s ease-in-out infinite;
674
+ }
675
+ .skeleton-row td:nth-child(1) .skeleton {
676
+ width: 36px;
677
+ }
678
+ .skeleton-row td:nth-child(2) .skeleton {
679
+ width: 62%;
680
+ }
681
+ .skeleton-row td:nth-child(3) .skeleton {
682
+ width: 78%;
683
+ }
684
+ .skeleton-row td:nth-child(4) .skeleton {
685
+ width: 48px;
686
+ }
687
+ .skeleton-row td:nth-child(5) .skeleton {
688
+ width: 34px;
689
+ }
690
+ .skeleton-row:nth-child(3n) td:nth-child(2) .skeleton {
691
+ width: 44%;
692
+ }
693
+ .skeleton-row:nth-child(2n) td:nth-child(3) .skeleton {
694
+ width: 54%;
695
+ }
696
+ .skeleton-row:nth-child(3n + 1) td:nth-child(3) .skeleton {
697
+ width: 88%;
698
+ }
699
+ @keyframes skeleton-shimmer {
700
+ 0% {
701
+ background-position: 100% 0;
702
+ }
703
+ 100% {
704
+ background-position: -100% 0;
705
+ }
706
+ }
707
+ .skeleton-table-wrap {
708
+ overflow: hidden;
709
+ }
710
+ .skeleton-card {
711
+ display: grid;
712
+ align-content: center;
713
+ gap: 10px;
714
+ min-height: 88px;
715
+ }
716
+ .skeleton-card .skeleton:nth-child(1) {
717
+ width: 42%;
718
+ }
719
+ .skeleton-card .skeleton:nth-child(2) {
720
+ width: 58%;
721
+ height: 16px;
722
+ }
723
+ .skeleton-card .skeleton:nth-child(3) {
724
+ width: 72%;
725
+ }
726
+ .skeleton.title {
727
+ width: 220px;
728
+ height: 28px;
729
+ }
730
+ .skeleton.button {
731
+ width: 112px;
732
+ height: 36px;
733
+ }
734
+ .skeleton-line {
735
+ display: flex;
736
+ align-items: center;
737
+ gap: 16px;
738
+ padding: 16px 23px;
739
+ border-bottom: 1px solid var(--line);
740
+ }
741
+ .skeleton-line:last-child {
742
+ border-bottom: 0;
743
+ }
744
+ .skeleton.sq {
745
+ width: 32px;
746
+ height: 32px;
747
+ border-radius: 8px;
748
+ flex-shrink: 0;
749
+ }
750
+ .skeleton.grow {
751
+ width: 28%;
752
+ }
753
+ .skeleton.mid {
754
+ width: 14%;
755
+ margin-left: auto;
756
+ }
757
+ .skeleton-status {
758
+ display: flex;
759
+ align-items: center;
760
+ justify-content: space-between;
761
+ gap: 16px;
762
+ padding: 18px 23px;
763
+ }
764
+ .skeleton-status .skeleton {
765
+ width: 140px;
766
+ height: 14px;
767
+ }
768
+ .skeleton-status .skeleton:last-child {
769
+ width: 120px;
770
+ height: 34px;
771
+ }
772
+ @media (prefers-reduced-motion: reduce) {
773
+ .skeleton {
774
+ animation: none;
775
+ }
776
+ }
777
+ .dns-detail dd {
778
+ overflow-wrap: anywhere;
779
+ min-width: 0;
780
+ }
781
+ .dns-edit {
782
+ padding: 8px 23px 24px;
783
+ }
784
+ .dns-edit textarea,
785
+ .dns-edit select {
786
+ display: block;
787
+ width: 100%;
788
+ margin-top: 8px;
789
+ padding: 11px 12px;
790
+ border: 1px solid #dde4e7;
791
+ border-radius: 6px;
792
+ background: var(--surface);
793
+ color: var(--ink);
794
+ font: inherit;
795
+ }
796
+ .dns-edit textarea {
797
+ min-height: 88px;
798
+ resize: vertical;
799
+ overflow-wrap: anywhere;
800
+ }
801
+ .check-line {
802
+ display: flex;
803
+ align-items: center;
804
+ gap: 8px;
805
+ }
806
+ .check-line input {
807
+ width: auto;
808
+ margin: 0;
809
+ }
810
+ .bottom-grid {
811
+ display: grid;
812
+ grid-template-columns: 1fr 1fr;
813
+ gap: 20px;
814
+ margin-top: 25px;
815
+ }
816
+ .server-card .section-heading {
817
+ padding: 17px 21px;
818
+ border: 0;
819
+ }
820
+ .tiny-label {
821
+ font-size: 8px;
822
+ letter-spacing: 1px;
823
+ color: #a0aab0;
824
+ }
825
+ .host-details {
826
+ display: flex;
827
+ align-items: center;
828
+ justify-content: space-between;
829
+ padding: 4px 21px 19px;
830
+ }
831
+ .host-details > div {
832
+ display: flex;
833
+ align-items: center;
834
+ gap: 11px;
835
+ }
836
+ .server-avatar {
837
+ display: grid;
838
+ place-items: center;
839
+ background: #f6f8f9;
840
+ border: 1px solid #e8edef;
841
+ color: #84969d;
842
+ border-radius: 7px;
843
+ width: 39px;
844
+ height: 39px;
845
+ }
846
+ .host-details strong {
847
+ font-size: 11px;
848
+ }
849
+ .host-details small {
850
+ display: block;
851
+ font-size: 9px;
852
+ color: #9aa5ad;
853
+ margin-top: 5px;
854
+ }
855
+ .memory-line {
856
+ display: flex;
857
+ justify-content: space-between;
858
+ gap: 10px;
859
+ margin: 0 21px 10px;
860
+ font-size: 9px;
861
+ color: #8e9ba3;
862
+ }
863
+ .memory-line strong {
864
+ font-weight: 500;
865
+ color: #70828b;
866
+ }
867
+ .progress {
868
+ height: 4px;
869
+ background: #edf3f0;
870
+ border-radius: 3px;
871
+ margin: 0 21px;
872
+ overflow: hidden;
873
+ }
874
+ .progress i {
875
+ display: block;
876
+ height: 100%;
877
+ background: #79b49d;
878
+ }
879
+ .text-button {
880
+ background: transparent;
881
+ color: var(--green);
882
+ font-size: 10px;
883
+ font-weight: 550;
884
+ padding: 0;
885
+ gap: 7px;
886
+ }
887
+ .server-card > .text-button {
888
+ margin: 19px 21px;
889
+ }
890
+ .quick-start {
891
+ border: 1px solid #dcece4;
892
+ background: linear-gradient(110deg, #eef7f1, #f6faf7);
893
+ border-radius: 9px;
894
+ display: flex;
895
+ align-items: center;
896
+ gap: 23px;
897
+ padding: 28px;
898
+ }
899
+ .quick-art {
900
+ position: relative;
901
+ min-width: 70px;
902
+ width: 70px;
903
+ height: 76px;
904
+ border-radius: 15px;
905
+ border: 1px solid #d6e9db;
906
+ background: #e2f0e5;
907
+ display: grid;
908
+ place-items: center;
909
+ color: #70a082;
910
+ transform: rotate(-6deg);
911
+ }
912
+ .quick-art > span {
913
+ position: absolute;
914
+ bottom: -5px;
915
+ right: -5px;
916
+ display: grid;
917
+ place-items: center;
918
+ width: 25px;
919
+ height: 25px;
920
+ border-radius: 8px;
921
+ background: var(--green);
922
+ color: white;
923
+ border: 3px solid #f2f8f3;
924
+ }
925
+ .quick-start .eyebrow {
926
+ font-size: 8px;
927
+ color: #83a58e;
928
+ letter-spacing: 1.2px;
929
+ }
930
+ .quick-start h2 {
931
+ font-size: 17px;
932
+ letter-spacing: -0.4px;
933
+ margin-bottom: 10px;
934
+ }
935
+ .quick-start p {
936
+ font-size: 10px;
937
+ color: #8ca096;
938
+ line-height: 1.9;
939
+ }
940
+ .quick-start .text-button {
941
+ margin-top: 5px;
942
+ }
943
+ footer {
944
+ display: flex;
945
+ justify-content: space-between;
946
+ align-items: center;
947
+ gap: 20px;
948
+ padding: 16px 0 14px;
949
+ color: #a0aab1;
950
+ font-size: 9px;
951
+ }
952
+ footer > span:last-child {
953
+ display: flex;
954
+ align-items: center;
955
+ gap: 6px;
956
+ }
957
+ .footer-dot {
958
+ padding: 0 6px;
959
+ }
960
+ .error,
961
+ .notice {
962
+ padding: 12px 15px;
963
+ font-size: 12px;
964
+ border-radius: 6px;
965
+ margin: 15px 0;
966
+ line-height: 1.7;
967
+ overflow-wrap: anywhere;
968
+ }
969
+ .error {
970
+ background: #fff0ed;
971
+ color: #b85243;
972
+ border: 1px solid #f3d9d4;
973
+ }
974
+ .notice {
975
+ background: #eaf7ef;
976
+ color: #227757;
977
+ border: 1px solid #d6eadc;
978
+ }
979
+ .dismissible {
980
+ display: flex;
981
+ justify-content: space-between;
982
+ gap: 12px;
983
+ }
984
+ .dismissible button {
985
+ background: transparent;
986
+ color: inherit;
987
+ padding: 0;
988
+ }
989
+ .back {
990
+ background: transparent;
991
+ color: var(--muted);
992
+ font-size: 11px;
993
+ padding: 8px 0;
994
+ }
995
+ .actions {
996
+ display: flex;
997
+ gap: 10px;
998
+ }
999
+ .page-heading p a {
1000
+ display: inline-flex;
1001
+ align-items: center;
1002
+ gap: 5px;
1003
+ color: var(--green);
1004
+ }
1005
+ .separator {
1006
+ padding: 0 10px;
1007
+ color: #bcc5c9;
1008
+ }
1009
+ .detail-stats .stat strong {
1010
+ font-size: 24px;
1011
+ }
1012
+ .tabs {
1013
+ display: flex;
1014
+ gap: 25px;
1015
+ border-bottom: 1px solid #dce4e7;
1016
+ margin-bottom: 22px;
1017
+ }
1018
+ .tabs button {
1019
+ background: transparent;
1020
+ padding: 13px 2px;
1021
+ font-size: 12px;
1022
+ color: var(--muted);
1023
+ border-bottom: 2px solid transparent;
1024
+ }
1025
+ .tabs button.active {
1026
+ color: var(--green);
1027
+ border-color: var(--green);
1028
+ }
1029
+ .detail-grid {
1030
+ display: grid;
1031
+ grid-template-columns: 1fr 1fr;
1032
+ gap: 20px;
1033
+ }
1034
+ dl {
1035
+ display: grid;
1036
+ grid-template-columns: 120px minmax(0, 1fr);
1037
+ gap: 19px 15px;
1038
+ padding: 24px;
1039
+ margin: 0;
1040
+ font-size: 11px;
1041
+ }
1042
+ dt {
1043
+ color: var(--muted);
1044
+ }
1045
+ dd {
1046
+ margin: 0;
1047
+ overflow-wrap: anywhere;
1048
+ color: #4c616d;
1049
+ }
1050
+ .logs {
1051
+ white-space: pre-wrap;
1052
+ overflow-wrap: anywhere;
1053
+ background: #17282d;
1054
+ color: #a9c7be;
1055
+ padding: 24px;
1056
+ line-height: 1.85;
1057
+ font-size: 11px;
1058
+ max-height: 600px;
1059
+ min-height: 240px;
1060
+ overflow: auto;
1061
+ margin: 0;
1062
+ font-family: Consolas, monospace;
1063
+ }
1064
+ .logs.compact {
1065
+ height: 275px;
1066
+ min-height: 0;
1067
+ margin: 16px;
1068
+ border-radius: 6px;
1069
+ }
1070
+ .detail-grid .text-button {
1071
+ margin: 0 20px 20px;
1072
+ }
1073
+ .danger-zone {
1074
+ display: flex;
1075
+ justify-content: space-between;
1076
+ align-items: center;
1077
+ border-top: 1px solid var(--line);
1078
+ margin-top: 35px;
1079
+ padding-top: 24px;
1080
+ gap: 20px;
1081
+ }
1082
+ .danger-zone strong {
1083
+ font-size: 12px;
1084
+ }
1085
+ .danger-zone p {
1086
+ font-size: 11px;
1087
+ color: var(--muted);
1088
+ margin: 7px 0;
1089
+ }
1090
+ .deployment,
1091
+ .activity-row {
1092
+ display: flex;
1093
+ gap: 16px;
1094
+ align-items: center;
1095
+ padding: 20px 24px;
1096
+ border-bottom: 1px solid var(--line);
1097
+ width: 100%;
1098
+ background: var(--surface);
1099
+ text-align: left;
1100
+ justify-content: flex-start;
1101
+ }
1102
+ .deployment > div,
1103
+ .activity-row > div {
1104
+ flex: 1;
1105
+ }
1106
+ .deployment small,
1107
+ .activity-row small {
1108
+ display: block;
1109
+ color: var(--muted);
1110
+ font-size: 10px;
1111
+ margin-top: 5px;
1112
+ overflow-wrap: anywhere;
1113
+ }
1114
+ .compact-empty {
1115
+ padding: 35px;
1116
+ }
1117
+ .modal-backdrop {
1118
+ position: fixed;
1119
+ inset: 0;
1120
+ z-index: 50;
1121
+ background: #142f3c55;
1122
+ backdrop-filter: blur(4px);
1123
+ display: flex;
1124
+ align-items: center;
1125
+ justify-content: center;
1126
+ padding: 25px;
1127
+ overflow: auto;
1128
+ }
1129
+ .modal {
1130
+ background: var(--surface);
1131
+ border-radius: 14px;
1132
+ padding: 28px 32px;
1133
+ width: 490px;
1134
+ max-width: 100%;
1135
+ max-height: calc(100vh - 50px);
1136
+ overflow: auto;
1137
+ box-shadow: 0 25px 90px #142a3940;
1138
+ }
1139
+ .modal-heading {
1140
+ display: flex;
1141
+ align-items: center;
1142
+ justify-content: space-between;
1143
+ margin-bottom: 22px;
1144
+ }
1145
+ .modal h2 {
1146
+ font-size: 23px;
1147
+ letter-spacing: -0.8px;
1148
+ margin-bottom: 9px;
1149
+ }
1150
+ .modal > p {
1151
+ font-size: 12px;
1152
+ margin-bottom: 25px;
1153
+ }
1154
+ fieldset {
1155
+ border: 0;
1156
+ padding: 0;
1157
+ margin: 0;
1158
+ min-width: 0;
1159
+ }
1160
+ label {
1161
+ display: block;
1162
+ font-size: 11px;
1163
+ font-weight: 550;
1164
+ margin-bottom: 18px;
1165
+ }
1166
+ input {
1167
+ display: block;
1168
+ width: 100%;
1169
+ background: var(--surface);
1170
+ border: 1px solid #dde4e7;
1171
+ border-radius: 6px;
1172
+ padding: 11px 12px;
1173
+ font-size: 12px;
1174
+ color: #3e5360;
1175
+ margin-top: 8px;
1176
+ }
1177
+ label small {
1178
+ display: block;
1179
+ font-size: 10px;
1180
+ color: #96a1a8;
1181
+ font-weight: 400;
1182
+ margin-top: 7px;
1183
+ }
1184
+ .input-icon {
1185
+ position: relative;
1186
+ }
1187
+ .input-icon svg {
1188
+ position: absolute;
1189
+ top: 11px;
1190
+ left: 11px;
1191
+ color: #98a5aa;
1192
+ }
1193
+ .input-icon input {
1194
+ padding-left: 35px;
1195
+ }
1196
+ .runtime-option {
1197
+ display: flex;
1198
+ align-items: center;
1199
+ gap: 10px;
1200
+ padding: 12px;
1201
+ margin-top: 8px;
1202
+ border: 1px solid #d7e6df;
1203
+ border-radius: 6px;
1204
+ color: var(--green);
1205
+ background: #f4f9f6;
1206
+ }
1207
+ .runtime-option strong {
1208
+ font-weight: 550;
1209
+ }
1210
+ .runtime-option span {
1211
+ margin-left: auto;
1212
+ font-size: 9px;
1213
+ color: #92a59c;
1214
+ }
1215
+ .source-options {
1216
+ display: flex;
1217
+ gap: 10px;
1218
+ margin-top: -7px;
1219
+ margin-bottom: 19px;
1220
+ }
1221
+ .source-options button {
1222
+ flex: 1;
1223
+ border: 1px solid var(--line);
1224
+ background: var(--surface);
1225
+ border-radius: 6px;
1226
+ padding: 12px;
1227
+ color: #89969e;
1228
+ font-size: 11px;
1229
+ }
1230
+ .source-options button.selected {
1231
+ border-color: #92beaa;
1232
+ background: #f0f8f3;
1233
+ color: var(--green);
1234
+ }
1235
+ .upload {
1236
+ border: 1px dashed #c6d9d0;
1237
+ border-radius: 8px;
1238
+ background: #f8fbf9;
1239
+ padding: 23px;
1240
+ display: flex;
1241
+ flex-direction: column;
1242
+ align-items: center;
1243
+ color: var(--green);
1244
+ gap: 9px;
1245
+ }
1246
+ .upload input {
1247
+ font-size: 10px;
1248
+ }
1249
+ .upload small {
1250
+ margin: 0;
1251
+ }
1252
+ .upload.replacement {
1253
+ margin: 0 22px 22px;
1254
+ align-items: flex-start;
1255
+ gap: 8px;
1256
+ padding: 15px;
1257
+ }
1258
+ .info {
1259
+ display: flex;
1260
+ align-items: flex-start;
1261
+ gap: 9px;
1262
+ background: #f6f8fa;
1263
+ padding: 12px;
1264
+ border-radius: 6px;
1265
+ color: #85959d;
1266
+ }
1267
+ .info svg {
1268
+ flex-shrink: 0;
1269
+ }
1270
+ .info p {
1271
+ font-size: 10px;
1272
+ line-height: 1.7;
1273
+ margin: 0;
1274
+ }
1275
+ .modal-actions {
1276
+ border-top: 1px solid var(--line);
1277
+ display: flex;
1278
+ justify-content: flex-end;
1279
+ gap: 10px;
1280
+ margin-top: 24px;
1281
+ padding-top: 20px;
1282
+ }
1283
+ .login {
1284
+ min-height: 100vh;
1285
+ display: grid;
1286
+ grid-template-columns: 1fr 1fr;
1287
+ background: var(--surface);
1288
+ }
1289
+ .login-story {
1290
+ background: #edf5f0;
1291
+ padding: 50px 65px;
1292
+ display: flex;
1293
+ flex-direction: column;
1294
+ justify-content: space-between;
1295
+ min-height: 100vh;
1296
+ border-right: 1px solid #deebe3;
1297
+ }
1298
+ .login-story > div {
1299
+ margin: 60px 0;
1300
+ }
1301
+ .login-story h1 {
1302
+ font-size: 54px;
1303
+ line-height: 1.13;
1304
+ letter-spacing: -2.2px;
1305
+ margin: 18px 0 25px;
1306
+ }
1307
+ .login-story p {
1308
+ max-width: 350px;
1309
+ color: #849b8e;
1310
+ font-size: 14px;
1311
+ line-height: 1.9;
1312
+ }
1313
+ .login-features {
1314
+ display: flex;
1315
+ flex-direction: column;
1316
+ gap: 16px;
1317
+ margin-top: 30px;
1318
+ font-size: 12px;
1319
+ color: #5b8973;
1320
+ }
1321
+ .login-features span {
1322
+ display: flex;
1323
+ align-items: center;
1324
+ gap: 10px;
1325
+ }
1326
+ .login-story > small {
1327
+ color: #91a799;
1328
+ font-size: 10px;
1329
+ display: flex;
1330
+ justify-content: space-between;
1331
+ }
1332
+ .login-form {
1333
+ position: relative;
1334
+ display: flex;
1335
+ align-items: center;
1336
+ justify-content: center;
1337
+ padding: 50px;
1338
+ }
1339
+ .login-form > div {
1340
+ width: 330px;
1341
+ max-width: 100%;
1342
+ }
1343
+ .login-form h2 {
1344
+ font-size: 29px;
1345
+ letter-spacing: -1px;
1346
+ margin: 14px 0;
1347
+ }
1348
+ .login-form form {
1349
+ margin-top: 32px;
1350
+ }
1351
+ .login-form label {
1352
+ margin-bottom: 22px;
1353
+ }
1354
+ .login-form .primary {
1355
+ width: 100%;
1356
+ justify-content: space-between;
1357
+ margin-top: 7px;
1358
+ }
1359
+ .login-note {
1360
+ margin-top: 30px;
1361
+ font-size: 10px;
1362
+ line-height: 1.8;
1363
+ color: #a0aaaf;
1364
+ }
1365
+ .login-note svg {
1366
+ float: left;
1367
+ margin-right: 7px;
1368
+ margin-top: 2px;
1369
+ }
1370
+ @media (max-width: 1150px) {
1371
+ :root {
1372
+ --sidebar: 210px;
1373
+ }
1374
+ .sidebar {
1375
+ padding: 18px 13px 0;
1376
+ }
1377
+ .content {
1378
+ padding: 8px 20px 0;
1379
+ }
1380
+ .topbar {
1381
+ padding: 0 25px;
1382
+ }
1383
+ .stats {
1384
+ gap: 12px;
1385
+ }
1386
+ .stat {
1387
+ padding: 17px 14px;
1388
+ }
1389
+ .quick-start {
1390
+ padding: 22px;
1391
+ gap: 15px;
1392
+ }
1393
+ .quick-art {
1394
+ display: none;
1395
+ }
1396
+ .stat small {
1397
+ font-size: 8px;
1398
+ }
1399
+ .login-story {
1400
+ padding: 40px;
1401
+ }
1402
+ .login-story h1 {
1403
+ font-size: 43px;
1404
+ }
1405
+ }
1406
+ @media (max-width: 850px) {
1407
+ :root {
1408
+ --sidebar: 74px;
1409
+ }
1410
+ .sidebar {
1411
+ padding: 25px 10px 0;
1412
+ }
1413
+ .sidebar .brand {
1414
+ padding: 0;
1415
+ justify-content: center;
1416
+ }
1417
+ .sidebar .brand-logo {
1418
+ width: 46px;
1419
+ height: 46px;
1420
+ object-fit: cover;
1421
+ object-position: center 28%;
1422
+ }
1423
+ .sidebar .nav-label,
1424
+ .sidebar .profile > span:not(.avatar),
1425
+ .sidebar .profile > svg {
1426
+ display: none;
1427
+ }
1428
+ .sidebar nav {
1429
+ margin-top: 40px;
1430
+ }
1431
+ .sidebar .nav-item {
1432
+ font-size: 0;
1433
+ gap: 0;
1434
+ justify-content: center;
1435
+ padding: 14px 0;
1436
+ }
1437
+ .sidebar .nav-item span {
1438
+ display: none;
1439
+ }
1440
+ .sidebar .profile {
1441
+ justify-content: center;
1442
+ }
1443
+ .stats {
1444
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1445
+ }
1446
+ .bottom-grid,
1447
+ .detail-grid {
1448
+ grid-template-columns: 1fr;
1449
+ }
1450
+ .quick-art {
1451
+ display: grid;
1452
+ }
1453
+ .login-story {
1454
+ padding: 30px;
1455
+ }
1456
+ .login-story h1 {
1457
+ font-size: 35px;
1458
+ }
1459
+ .login-form {
1460
+ padding: 30px;
1461
+ }
1462
+ footer {
1463
+ font-size: 8px;
1464
+ }
1465
+ .detail-stats {
1466
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1467
+ }
1468
+ }
1469
+ @media (max-width: 580px) {
1470
+ :root {
1471
+ --sidebar: 0px;
1472
+ }
1473
+ .sidebar {
1474
+ display: none;
1475
+ }
1476
+ .topbar {
1477
+ height: 61px;
1478
+ padding: 0 18px;
1479
+ }
1480
+ .content {
1481
+ padding: 14px 16px 0;
1482
+ }
1483
+ .topbar-right {
1484
+ gap: 12px !important;
1485
+ }
1486
+ .topbar > div {
1487
+ gap: 8px;
1488
+ }
1489
+ .connection {
1490
+ font-size: 8px;
1491
+ }
1492
+ .page-heading {
1493
+ margin: 4px 0 12px;
1494
+ }
1495
+ .page-heading h1 {
1496
+ font-size: 28px;
1497
+ }
1498
+ .page-heading p {
1499
+ font-size: 11px;
1500
+ line-height: 1.6;
1501
+ }
1502
+ .eyebrow {
1503
+ font-size: 8px;
1504
+ }
1505
+ .page-heading > .primary {
1506
+ margin-top: 3px;
1507
+ }
1508
+ .stat {
1509
+ padding: 17px 14px;
1510
+ }
1511
+ .stat strong {
1512
+ font-size: 26px;
1513
+ }
1514
+ .toolbar {
1515
+ padding: 14px;
1516
+ gap: 8px;
1517
+ }
1518
+ .toolbar-count {
1519
+ display: none;
1520
+ }
1521
+ .section-heading {
1522
+ padding: 17px;
1523
+ }
1524
+ .table-footer > span:last-child {
1525
+ display: none;
1526
+ }
1527
+ .table-footer {
1528
+ padding: 13px;
1529
+ font-size: 8px;
1530
+ }
1531
+ .bottom-grid {
1532
+ margin-top: 18px;
1533
+ }
1534
+ .quick-start {
1535
+ padding: 23px;
1536
+ }
1537
+ footer {
1538
+ flex-direction: column;
1539
+ gap: 10px;
1540
+ align-items: flex-start;
1541
+ padding: 23px 0;
1542
+ }
1543
+ .modal-backdrop {
1544
+ padding: 12px;
1545
+ }
1546
+ .modal {
1547
+ padding: 22px;
1548
+ max-height: calc(100dvh - 24px);
1549
+ }
1550
+ .modal h2 {
1551
+ font-size: 21px;
1552
+ }
1553
+ .modal-actions .primary {
1554
+ font-size: 10px;
1555
+ }
1556
+ .login {
1557
+ display: block;
1558
+ }
1559
+ .login-story {
1560
+ min-height: 0;
1561
+ padding: 26px;
1562
+ }
1563
+ .login-story > div,
1564
+ .login-story > small {
1565
+ display: none;
1566
+ }
1567
+ .login-form {
1568
+ padding: 50px 28px;
1569
+ }
1570
+ .danger-zone {
1571
+ align-items: flex-start;
1572
+ }
1573
+ .danger-zone .danger {
1574
+ font-size: 10px;
1575
+ padding: 10px;
1576
+ }
1577
+ .activity-row {
1578
+ gap: 8px;
1579
+ padding: 15px;
1580
+ }
1581
+ .activity-row > .muted {
1582
+ display: none;
1583
+ }
1584
+ .detail-stats .stat strong {
1585
+ font-size: 22px;
1586
+ }
1587
+ dl {
1588
+ grid-template-columns: 90px minmax(0, 1fr);
1589
+ padding: 20px;
1590
+ gap: 17px 12px;
1591
+ }
1592
+ }
1593
+ .connect-panel {
1594
+ max-width: 720px;
1595
+ }
1596
+ .connect-body {
1597
+ padding: 8px 23px 28px;
1598
+ }
1599
+ .connect-body > p {
1600
+ color: #60727c;
1601
+ line-height: 1.6;
1602
+ max-width: 58ch;
1603
+ }
1604
+ .connect-steps {
1605
+ list-style: none;
1606
+ margin: 18px 0;
1607
+ padding: 0;
1608
+ display: grid;
1609
+ gap: 10px;
1610
+ }
1611
+ .connect-steps li {
1612
+ display: flex;
1613
+ align-items: center;
1614
+ gap: 8px;
1615
+ color: #8b989f;
1616
+ }
1617
+ .connect-steps li.done {
1618
+ color: var(--green-dark);
1619
+ }
1620
+ .connect-log {
1621
+ background: #142028;
1622
+ color: #d7e7e1;
1623
+ border-radius: 8px;
1624
+ padding: 14px;
1625
+ font-family: Consolas, monospace;
1626
+ font-size: 11px;
1627
+ line-height: 1.5;
1628
+ white-space: pre-wrap;
1629
+ max-height: 220px;
1630
+ overflow: auto;
1631
+ margin-bottom: 16px;
1632
+ }
1633
+ .connect-link {
1634
+ display: inline-flex;
1635
+ width: fit-content;
1636
+ margin: 0 0 14px;
1637
+ text-decoration: none;
1638
+ }
1639
+ .stack {
1640
+ display: grid;
1641
+ gap: 14px;
1642
+ }
1643
+ .inline-form {
1644
+ display: grid;
1645
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
1646
+ gap: 14px 16px;
1647
+ align-items: end;
1648
+ padding: 18px 23px 20px;
1649
+ }
1650
+ .inline-form label {
1651
+ margin-bottom: 0;
1652
+ min-width: 0;
1653
+ }
1654
+ .inline-form input,
1655
+ .inline-form select {
1656
+ height: 40px;
1657
+ margin-top: 8px;
1658
+ box-sizing: border-box;
1659
+ }
1660
+ .inline-form > button {
1661
+ justify-self: start;
1662
+ width: auto;
1663
+ height: 40px;
1664
+ min-height: 0;
1665
+ align-self: end;
1666
+ margin: 0;
1667
+ }
1668
+ .credential {
1669
+ display: grid;
1670
+ gap: 10px;
1671
+ padding: 18px 20px;
1672
+ border: 1px solid var(--line);
1673
+ border-radius: 10px;
1674
+ background: var(--surface);
1675
+ }
1676
+ .credential .text-button {
1677
+ justify-content: flex-start;
1678
+ width: fit-content;
1679
+ }
1680
+ .credential p {
1681
+ margin: 0;
1682
+ color: var(--muted);
1683
+ font-size: 12px;
1684
+ }
1685
+ .credential-row {
1686
+ display: flex;
1687
+ align-items: center;
1688
+ gap: 8px;
1689
+ }
1690
+ .credential-row input {
1691
+ margin-top: 0;
1692
+ flex: 1;
1693
+ min-width: 0;
1694
+ }
1695
+ .credential-row .secondary {
1696
+ height: 40px;
1697
+ }
1698
+ .row-actions {
1699
+ display: flex;
1700
+ justify-content: flex-end;
1701
+ gap: 14px;
1702
+ }
1703
+ .danger-text {
1704
+ color: #b42318;
1705
+ }
1706
+ html[data-theme="dark"] .danger-text {
1707
+ color: #ffb4ab;
1708
+ }
1709
+ .database-screen {
1710
+ margin-bottom: 10px;
1711
+ }
1712
+ .database-create {
1713
+ display: flex;
1714
+ flex-wrap: wrap;
1715
+ align-items: flex-end;
1716
+ gap: 12px 16px;
1717
+ padding: 18px 23px 20px;
1718
+ }
1719
+ .database-create label {
1720
+ flex: 1 1 220px;
1721
+ max-width: 460px;
1722
+ margin-bottom: 0;
1723
+ }
1724
+ .database-create small {
1725
+ margin-top: 4px;
1726
+ }
1727
+ .database-create input {
1728
+ height: 40px;
1729
+ margin-top: 8px;
1730
+ }
1731
+ .database-create .primary {
1732
+ height: 40px;
1733
+ }
1734
+ .mail-address {
1735
+ display: flex;
1736
+ align-items: center;
1737
+ gap: 8px;
1738
+ margin-top: 8px;
1739
+ }
1740
+ .mail-address input,
1741
+ .mail-address select {
1742
+ margin-top: 0;
1743
+ height: 40px;
1744
+ }
1745
+ .mail-address input[name="local"] {
1746
+ flex: 1;
1747
+ min-width: 0;
1748
+ }
1749
+ .mail-address select {
1750
+ width: auto;
1751
+ min-width: 140px;
1752
+ }
1753
+ .domain-suffix {
1754
+ color: var(--ink);
1755
+ font-size: 13px;
1756
+ font-weight: 550;
1757
+ white-space: nowrap;
1758
+ }
1759
+ .address-form {
1760
+ grid-template-columns: minmax(220px, 1fr) auto;
1761
+ }
1762
+ @media (max-width: 720px) {
1763
+ .address-form {
1764
+ grid-template-columns: 1fr;
1765
+ }
1766
+ }
1767
+ .rules-form > button {
1768
+ grid-column: 1 / -1;
1769
+ }
1770
+ .inline-form select {
1771
+ display: block;
1772
+ width: 100%;
1773
+ padding: 0 12px;
1774
+ border: 1px solid #dde4e7;
1775
+ border-radius: 6px;
1776
+ background: var(--surface);
1777
+ color: var(--ink);
1778
+ }
1779
+ .email-status {
1780
+ display: flex;
1781
+ align-items: center;
1782
+ justify-content: space-between;
1783
+ gap: 16px;
1784
+ padding: 18px 23px;
1785
+ }
1786
+ .email-status > div {
1787
+ display: flex;
1788
+ align-items: center;
1789
+ gap: 12px;
1790
+ }
1791
+ .email-status small {
1792
+ display: block;
1793
+ color: var(--muted);
1794
+ margin-top: 4px;
1795
+ }
1796
+ .selected-row {
1797
+ background: #f4faf7;
1798
+ }
1799
+ .row-actions {
1800
+ display: inline-flex;
1801
+ align-items: center;
1802
+ justify-content: flex-end;
1803
+ gap: 8px;
1804
+ width: 100%;
1805
+ }
1806
+ .email-table th:last-child,
1807
+ .email-table td:last-child {
1808
+ width: 1%;
1809
+ text-align: right;
1810
+ padding-right: 23px;
1811
+ }
1812
+ .danger-text {
1813
+ color: #b56a55;
1814
+ }
1815
+ .runtime-select {
1816
+ display: block;
1817
+ width: 100%;
1818
+ padding: 11px 12px;
1819
+ border: 1px solid #dde4e7;
1820
+ border-radius: 6px;
1821
+ background: var(--surface);
1822
+ color: var(--ink);
1823
+ margin-top: 8px;
1824
+ font: inherit;
1825
+ }
1826
+ .theme-toggle {
1827
+ width: 32px;
1828
+ height: 32px;
1829
+ padding: 0;
1830
+ border: 1px solid var(--line);
1831
+ border-radius: 8px;
1832
+ background: var(--surface);
1833
+ color: var(--ink);
1834
+ }
1835
+ .theme-toggle .theme-sun {
1836
+ display: none;
1837
+ }
1838
+ html[data-theme="dark"] .theme-toggle .theme-moon {
1839
+ display: none;
1840
+ }
1841
+ html[data-theme="dark"] .theme-toggle .theme-sun {
1842
+ display: block;
1843
+ }
1844
+ .drawer-root {
1845
+ position: fixed;
1846
+ inset: 0;
1847
+ z-index: 60;
1848
+ }
1849
+ .drawer-backdrop {
1850
+ position: absolute;
1851
+ inset: 0;
1852
+ border: 0;
1853
+ background: #142f3c66;
1854
+ }
1855
+ .drawer {
1856
+ position: absolute;
1857
+ top: 0;
1858
+ bottom: 0;
1859
+ left: 0;
1860
+ width: min(300px, 86vw);
1861
+ display: flex;
1862
+ flex-direction: column;
1863
+ gap: 8px;
1864
+ padding: 22px 16px 16px;
1865
+ background: var(--surface);
1866
+ box-shadow: 12px 0 40px #142a3926;
1867
+ animation: drawer-in 0.18s ease;
1868
+ }
1869
+ .drawer-head {
1870
+ display: flex;
1871
+ align-items: flex-start;
1872
+ justify-content: space-between;
1873
+ gap: 12px;
1874
+ margin-bottom: 12px;
1875
+ }
1876
+ .drawer-head .brand-logo {
1877
+ width: 148px;
1878
+ }
1879
+ .drawer-head > button {
1880
+ width: 34px;
1881
+ height: 34px;
1882
+ padding: 0;
1883
+ border: 1px solid var(--line);
1884
+ border-radius: 8px;
1885
+ background: var(--surface);
1886
+ color: var(--ink);
1887
+ }
1888
+ .drawer nav {
1889
+ display: flex;
1890
+ flex-direction: column;
1891
+ }
1892
+ .drawer .nav-item {
1893
+ font-size: 13px;
1894
+ gap: 12px;
1895
+ justify-content: flex-start;
1896
+ padding: 13px 14px;
1897
+ }
1898
+ .drawer .profile {
1899
+ margin-top: auto;
1900
+ justify-content: flex-start;
1901
+ }
1902
+ .drawer .profile > span:not(.avatar),
1903
+ .drawer .profile > svg {
1904
+ display: revert;
1905
+ }
1906
+ @keyframes drawer-in {
1907
+ from {
1908
+ transform: translateX(-100%);
1909
+ }
1910
+ to {
1911
+ transform: translateX(0);
1912
+ }
1913
+ }
1914
+ @media (prefers-reduced-motion: reduce) {
1915
+ .drawer {
1916
+ animation: none;
1917
+ }
1918
+ }
1919
+ .login-theme {
1920
+ position: absolute;
1921
+ top: 22px;
1922
+ right: 22px;
1923
+ }
1924
+ html[data-theme="dark"] {
1925
+ color-scheme: dark;
1926
+ --bg: #0e1518;
1927
+ --surface: #172126;
1928
+ --ink: #e7eef1;
1929
+ --muted: #93a3ab;
1930
+ --line: #2c3b43;
1931
+ --green: #2fbfa6;
1932
+ --green-dark: #8ee0d0;
1933
+ --green-light: #17342e;
1934
+ --skeleton: #243036;
1935
+ --skeleton-shine: #35444c;
1936
+ }
1937
+ html[data-theme="dark"] :is(
1938
+ h1,
1939
+ h2,
1940
+ h3,
1941
+ td,
1942
+ dd,
1943
+ .topbar strong,
1944
+ .name-button,
1945
+ .section-heading h2,
1946
+ .secondary,
1947
+ .profile,
1948
+ .stat strong,
1949
+ .login-story h1,
1950
+ .login-form h2,
1951
+ .host-details strong,
1952
+ .connection
1953
+ ) {
1954
+ color: var(--ink);
1955
+ }
1956
+ html[data-theme="dark"] :is(input, select, textarea) {
1957
+ background: var(--surface);
1958
+ color: var(--ink);
1959
+ border-color: var(--line);
1960
+ }
1961
+ html[data-theme="dark"] .search input {
1962
+ background: transparent;
1963
+ }
1964
+ html[data-theme="dark"] :is(
1965
+ .nav-item.active,
1966
+ th,
1967
+ tbody tr:hover,
1968
+ .selected-row,
1969
+ .count,
1970
+ .project-icon,
1971
+ .badge,
1972
+ .table-footer,
1973
+ .empty-icon,
1974
+ .server-avatar,
1975
+ .quick-start,
1976
+ .quick-art,
1977
+ .runtime-option,
1978
+ .upload,
1979
+ .info,
1980
+ .login-story,
1981
+ .avatar
1982
+ ) {
1983
+ background: #1b282e;
1984
+ border-color: var(--line);
1985
+ color: var(--ink);
1986
+ }
1987
+ html[data-theme="dark"] .source-options button.selected {
1988
+ background: #1c3a34;
1989
+ border-color: var(--line);
1990
+ color: var(--ink);
1991
+ }
1992
+ html[data-theme="dark"] .nav-item {
1993
+ color: #a9b7be;
1994
+ }
1995
+ html[data-theme="dark"] .nav-item.active {
1996
+ background: #1c3a34;
1997
+ color: #d7f3ec;
1998
+ }
1999
+ html[data-theme="dark"] .nav-item span,
2000
+ html[data-theme="dark"] .avatar {
2001
+ background: #243038;
2002
+ color: var(--ink);
2003
+ }
2004
+ html[data-theme="dark"] .badge.running {
2005
+ background: #17352c;
2006
+ color: #8ee0d0;
2007
+ }
2008
+ html[data-theme="dark"] .badge.failed,
2009
+ html[data-theme="dark"] .error {
2010
+ background: #3a2422;
2011
+ color: #f0b2a8;
2012
+ border-color: #5a332e;
2013
+ }
2014
+ html[data-theme="dark"] .badge.deploying,
2015
+ html[data-theme="dark"] .badge.queued {
2016
+ background: #3a321c;
2017
+ color: #efd392;
2018
+ }
2019
+ html[data-theme="dark"] .notice {
2020
+ background: #17352c;
2021
+ color: #b7efe4;
2022
+ border-color: #245246;
2023
+ }
2024
+ html[data-theme="dark"] .quick-start {
2025
+ background: linear-gradient(110deg, #17342e, #172126);
2026
+ }
2027
+ html[data-theme="dark"] .quick-art {
2028
+ background: #1c3a34;
2029
+ color: #8ee0d0;
2030
+ }
2031
+ html[data-theme="dark"] .login-story {
2032
+ background: #12201c;
2033
+ }
2034
+ html[data-theme="dark"] .login-features,
2035
+ html[data-theme="dark"] .quick-start p,
2036
+ html[data-theme="dark"] .quick-start .eyebrow,
2037
+ html[data-theme="dark"] .domain {
2038
+ color: var(--muted);
2039
+ }
2040
+ html[data-theme="dark"] .primary,
2041
+ html[data-theme="dark"] .quick-art > span {
2042
+ color: white;
2043
+ }
2044
+ html[data-theme="dark"] th,
2045
+ html[data-theme="dark"] .section-heading {
2046
+ color: var(--muted);
2047
+ }
2048
+ html[data-theme="dark"] th {
2049
+ background: transparent;
2050
+ border-color: var(--line);
2051
+ }
2052
+ html[data-theme="dark"] td,
2053
+ html[data-theme="dark"] .secondary,
2054
+ html[data-theme="dark"] .stat,
2055
+ html[data-theme="dark"] .panel {
2056
+ border-color: var(--line);
2057
+ }