@swimmingliu/autovpn 1.8.0 → 2.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.
@@ -32,6 +32,7 @@
32
32
  --safe-area-left: env(safe-area-inset-left, 0px);
33
33
  }
34
34
 
35
+ /* Neutral surfaces follow the theme, including existing panels and drawers. */
35
36
  @font-face {
36
37
  font-family: "AutoVPN Visual Test";
37
38
  src: url("./assets/fonts/AutoVPNVisualTest-NotoSansSC.woff2") format("woff2");
@@ -64,7 +65,7 @@ body {
64
65
  color: var(--text);
65
66
  background:
66
67
  radial-gradient(circle at top left, rgba(91, 92, 226, 0.08), transparent 24%),
67
- linear-gradient(180deg, #fbfcff 0%, var(--bg) 100%);
68
+ linear-gradient(180deg, var(--surface-soft) 0%, var(--bg) 100%);
68
69
  }
69
70
 
70
71
  button,
@@ -87,7 +88,7 @@ textarea {
87
88
  min-height: 46px;
88
89
  border: 1px solid var(--border);
89
90
  border-radius: 14px;
90
- background: #fff;
91
+ background: var(--surface);
91
92
  color: var(--text);
92
93
  padding: 0 14px;
93
94
  outline: none;
@@ -126,7 +127,7 @@ body[data-runtime="web"] .app-frame {
126
127
  .window-titlebar {
127
128
  -webkit-app-region: drag;
128
129
  user-select: none;
129
- background: rgba(255, 255, 255, 0.78);
130
+ background: var(--surface);
130
131
  border-bottom: 1px solid rgba(207, 215, 239, 0.72);
131
132
  backdrop-filter: blur(16px);
132
133
  }
@@ -152,7 +153,7 @@ body[data-runtime="web"] .window-titlebar {
152
153
  grid-template-rows: auto minmax(0, 1fr);
153
154
  gap: 28px;
154
155
  padding: 24px 18px 20px;
155
- background: rgba(255, 255, 255, 0.88);
156
+ background: var(--surface);
156
157
  border-right: 1px solid var(--border);
157
158
  backdrop-filter: blur(16px);
158
159
  overflow: hidden;
@@ -244,7 +245,7 @@ body[data-runtime="web"] .window-titlebar {
244
245
  .page-header-card,
245
246
  .panel,
246
247
  .topbar {
247
- background: rgba(255, 255, 255, 0.94);
248
+ background: var(--surface);
248
249
  border: 1px solid var(--border);
249
250
  box-shadow: var(--shadow);
250
251
  }
@@ -387,7 +388,7 @@ body[data-runtime="web"] .window-titlebar {
387
388
 
388
389
  .btn-secondary {
389
390
  color: var(--text);
390
- background: #fff;
391
+ background: var(--surface);
391
392
  border: 1px solid var(--border);
392
393
  }
393
394
 
@@ -412,7 +413,7 @@ body[data-runtime="web"] .window-titlebar {
412
413
  }
413
414
 
414
415
  .badge.neutral {
415
- background: #eef2fb;
416
+ background: var(--surface-muted);
416
417
  color: var(--text-soft);
417
418
  }
418
419
 
@@ -572,12 +573,49 @@ body[data-page="logs"] .page-content {
572
573
  font-weight: 900;
573
574
  }
574
575
 
576
+ /* A running pipeline owns a green check only when it has finished; while it is
577
+ in flight the accent-tinted spinner says "working" at a glance. */
578
+ .status-hero-card.is-running h3 {
579
+ color: var(--accent);
580
+ }
581
+
582
+ .status-hero-card.is-running .status-orb {
583
+ background: var(--accent-soft);
584
+ color: var(--accent);
585
+ }
586
+
587
+ .status-orb-spinner {
588
+ width: 30px;
589
+ height: 30px;
590
+ border-radius: 999px;
591
+ border: 3px solid rgba(91, 92, 226, 0.22);
592
+ border-top-color: var(--accent);
593
+ animation: status-orb-spin 0.9s linear infinite;
594
+ }
595
+
596
+ @keyframes status-orb-spin {
597
+ to {
598
+ transform: rotate(360deg);
599
+ }
600
+ }
601
+
602
+ @media (prefers-reduced-motion: reduce) {
603
+ /* The global `*` reduced-motion rule below forces every animation to
604
+ 0.01ms with `!important`. A frozen ring reads as a broken image, so this
605
+ keeps the spinner turning (slowly) by matching that important with a more
606
+ specific selector. */
607
+ .status-orb-spinner {
608
+ animation-duration: 2.4s !important;
609
+ animation-iteration-count: infinite !important;
610
+ }
611
+ }
612
+
575
613
  .note-strip {
576
614
  display: flex;
577
615
  align-items: center;
578
616
  gap: 10px;
579
617
  flex-wrap: wrap;
580
- background: #fff9e8;
618
+ background: var(--warning-soft);
581
619
  }
582
620
 
583
621
  .design-note {
@@ -587,7 +625,7 @@ body[data-page="logs"] .page-content {
587
625
  padding: 0 12px;
588
626
  border-radius: 999px;
589
627
  background: rgba(255, 155, 47, 0.12);
590
- color: #9a5a08;
628
+ color: var(--warning);
591
629
  font-size: 13px;
592
630
  font-weight: 700;
593
631
  }
@@ -636,7 +674,7 @@ body[data-page="logs"] .page-content {
636
674
  border-radius: 50%;
637
675
  margin-bottom: 12px;
638
676
  border: 1px solid var(--border-strong);
639
- background: #fff;
677
+ background: var(--surface);
640
678
  font-size: 15px;
641
679
  font-weight: 800;
642
680
  }
@@ -797,7 +835,7 @@ body[data-page="logs"] .page-content {
797
835
  min-height: 24px;
798
836
  padding: 0 8px;
799
837
  border-radius: 999px;
800
- background: #fff;
838
+ background: var(--surface);
801
839
  border: 1px solid rgba(91, 92, 226, 0.14);
802
840
  color: var(--text-soft);
803
841
  font-size: 11px;
@@ -805,19 +843,19 @@ body[data-page="logs"] .page-content {
805
843
  }
806
844
 
807
845
  .metric-card.accent {
808
- background: linear-gradient(180deg, #f6f5ff 0%, #fff 100%);
846
+ background: linear-gradient(180deg, var(--accent-soft) 0%, var(--surface) 100%);
809
847
  }
810
848
 
811
849
  .metric-card.success {
812
- background: linear-gradient(180deg, #f1fff7 0%, #fff 100%);
850
+ background: linear-gradient(180deg, var(--success-soft) 0%, var(--surface) 100%);
813
851
  }
814
852
 
815
853
  .metric-card.warning {
816
- background: linear-gradient(180deg, #fff8ef 0%, #fff 100%);
854
+ background: linear-gradient(180deg, var(--warning-soft) 0%, var(--surface) 100%);
817
855
  }
818
856
 
819
857
  .metric-card.danger {
820
- background: linear-gradient(180deg, #fff2f4 0%, #fff 100%);
858
+ background: linear-gradient(180deg, var(--danger-soft) 0%, var(--surface) 100%);
821
859
  }
822
860
 
823
861
  .subscription-inline {
@@ -832,12 +870,22 @@ body[data-page="logs"] .page-content {
832
870
  display: block;
833
871
  }
834
872
 
873
+ /* The two run buttons belong to the page header's action group, so they take
874
+ the width of their labels and sit at the right edge instead of splitting the
875
+ full 1440px row 50/50. Below the desktop breakpoint the stacked mobile bar
876
+ (see the media query) still gives them a full-width thumb target. */
835
877
  .mobile-run-bar {
836
- display: grid;
837
- grid-template-columns: repeat(2, minmax(160px, 1fr));
878
+ display: flex;
879
+ justify-content: flex-end;
880
+ flex-wrap: wrap;
838
881
  grid-column: 1 / -1;
839
882
  align-self: start;
840
- gap: 14px;
883
+ gap: 12px;
884
+ }
885
+
886
+ .mobile-run-bar .run-big {
887
+ min-width: 168px;
888
+ padding-inline: 26px;
841
889
  }
842
890
 
843
891
  #runsWorkspace {
@@ -878,7 +926,7 @@ body[data-page="logs"] .page-content {
878
926
  padding: 0 12px;
879
927
  border-radius: 12px;
880
928
  border: 1px solid var(--border);
881
- background: #fff;
929
+ background: var(--surface);
882
930
  color: var(--text-main);
883
931
  }
884
932
 
@@ -893,7 +941,7 @@ body[data-page="logs"] .page-content {
893
941
  padding: 14px;
894
942
  border-radius: 14px;
895
943
  border: 1px solid var(--border);
896
- background: #fff;
944
+ background: var(--surface);
897
945
  }
898
946
 
899
947
  .retry-summary-head {
@@ -947,7 +995,7 @@ body[data-page="logs"] .page-content {
947
995
  padding: 12px 14px;
948
996
  border-radius: 14px;
949
997
  border: 1px solid var(--border);
950
- background: rgba(255, 255, 255, 0.96);
998
+ background: var(--surface);
951
999
  box-shadow: var(--shadow);
952
1000
  color: var(--text);
953
1001
  font-size: 14px;
@@ -1172,7 +1220,7 @@ body[data-page="logs"] #logCenterTable {
1172
1220
  }
1173
1221
 
1174
1222
  .subscription-tab-scroller .subtab.active {
1175
- background: #fff;
1223
+ background: var(--surface);
1176
1224
  box-shadow: 0 10px 22px rgba(91, 92, 226, 0.14);
1177
1225
  }
1178
1226
 
@@ -1215,7 +1263,7 @@ body[data-page="logs"] #logCenterTable {
1215
1263
  padding: 16px;
1216
1264
  border-radius: 18px;
1217
1265
  border: 1px solid var(--border);
1218
- background: linear-gradient(180deg, #f6f5ff 0%, #fff 100%);
1266
+ background: linear-gradient(180deg, var(--accent-soft) 0%, var(--surface) 100%);
1219
1267
  }
1220
1268
 
1221
1269
  .region-stat-card span {
@@ -1271,7 +1319,7 @@ body[data-page="logs"] #logCenterTable {
1271
1319
  width: 100%;
1272
1320
  border-collapse: collapse;
1273
1321
  min-width: 720px;
1274
- background: #fff;
1322
+ background: var(--surface);
1275
1323
  }
1276
1324
 
1277
1325
  .data-table th,
@@ -1285,7 +1333,7 @@ body[data-page="logs"] #logCenterTable {
1285
1333
  }
1286
1334
 
1287
1335
  .data-table thead th {
1288
- background: #f7f9ff;
1336
+ background: var(--surface-soft);
1289
1337
  color: var(--text-soft);
1290
1338
  font-size: 13px;
1291
1339
  font-weight: 700;
@@ -1297,9 +1345,72 @@ body[data-page="logs"] #logCenterTable {
1297
1345
  border-radius: 10px;
1298
1346
  }
1299
1347
 
1348
+ /* The selects share the row with 36px inputs; leaving them at the 46px base
1349
+ height makes the mode and platform controls sit visibly lower than the text
1350
+ fields beside them. They also drop the native control: macOS reserves an
1351
+ arrow area outside the padding box, so a select sized to fit its own text by
1352
+ measurement still renders "官网 +" clipped. A drawn chevron makes the space
1353
+ the same on every platform. */
1354
+ .settings-source-table select {
1355
+ min-height: 36px;
1356
+ padding: 0 28px 0 10px;
1357
+ border-radius: 10px;
1358
+ font-size: 13px;
1359
+ appearance: none;
1360
+ background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 6.5 8 10.5 12 6.5' fill='none' stroke='%23656d85' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
1361
+ background-repeat: no-repeat;
1362
+ background-position: right 8px center;
1363
+ background-size: 14px 14px;
1364
+ text-overflow: ellipsis;
1365
+ }
1366
+
1300
1367
  .settings-source-table,
1301
1368
  .availability-target-table {
1302
1369
  table-layout: fixed;
1370
+ /* The generic data table keeps a 720px floor so a dense table stays legible.
1371
+ Five columns of fixed width fit below that, so the drawer does not need the
1372
+ horizontal scrollbar the floor would otherwise force on a laptop window. */
1373
+ min-width: 0;
1374
+ }
1375
+
1376
+ /* Credential rows hold their fields inside the connection cell instead of in
1377
+ three columns of their own, which is what let the mode select shrink below
1378
+ the width of its own text. The site takes a full line, the three identity
1379
+ fields share the next, and the two round controls sit together below them. */
1380
+ .source-credential-fields {
1381
+ display: grid;
1382
+ gap: 8px;
1383
+ }
1384
+
1385
+ .source-credential-identity {
1386
+ display: grid;
1387
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
1388
+ gap: 8px;
1389
+ }
1390
+
1391
+ .source-credential-rounds {
1392
+ display: grid;
1393
+ grid-template-columns: repeat(2, minmax(72px, 1fr));
1394
+ gap: 8px;
1395
+ }
1396
+
1397
+ .source-field {
1398
+ display: grid;
1399
+ gap: 4px;
1400
+ min-width: 0;
1401
+ }
1402
+
1403
+ .source-field > span {
1404
+ color: var(--text-soft);
1405
+ font-size: 11px;
1406
+ font-weight: 700;
1407
+ line-height: 1;
1408
+ }
1409
+
1410
+ .source-field input,
1411
+ .source-field select {
1412
+ min-width: 0;
1413
+ text-overflow: ellipsis;
1303
1414
  }
1304
1415
 
1305
1416
  .settings-source-name {
@@ -1308,6 +1419,36 @@ body[data-page="logs"] #logCenterTable {
1308
1419
  font-size: 13px;
1309
1420
  }
1310
1421
 
1422
+ .settings-source-hint {
1423
+ display: block;
1424
+ margin-top: 3px;
1425
+ font-size: 11px;
1426
+ font-weight: 600;
1427
+ line-height: 1.3;
1428
+ color: var(--text-soft);
1429
+ }
1430
+
1431
+ .settings-source-hint.ready {
1432
+ color: var(--success);
1433
+ }
1434
+
1435
+ .settings-source-hint.empty {
1436
+ color: var(--warning);
1437
+ }
1438
+
1439
+ /* The row states its loop once, next to the controls that set it, so the
1440
+ summary line is readable instead of repeating two numbers in the header. */
1441
+ .source-round-summary {
1442
+ display: inline-block;
1443
+ color: var(--text-soft);
1444
+ font-size: 12px;
1445
+ line-height: 1.5;
1446
+ }
1447
+
1448
+ .notice-card.source-drawer-notice {
1449
+ margin: 0;
1450
+ }
1451
+
1311
1452
  .table-textarea {
1312
1453
  min-height: 72px;
1313
1454
  padding: 10px 12px;
@@ -1316,6 +1457,11 @@ body[data-page="logs"] #logCenterTable {
1316
1457
  resize: vertical;
1317
1458
  }
1318
1459
 
1460
+ /* Four columns: enable, brand, official site, and the loop controls. The table
1461
+ is fixed-layout inside a 1320px drawer, so a bare `auto` site column hands it
1462
+ every spare pixel (~870px for a 26-character URL) while the round inputs
1463
+ shrink to their spinner width (~54px). Sizing the two round boxes explicitly
1464
+ and capping the site column keeps the row readable instead of lopsided. */
1319
1465
  .settings-col-enabled,
1320
1466
  .availability-col-enabled {
1321
1467
  width: 78px;
@@ -1323,15 +1469,16 @@ body[data-page="logs"] #logCenterTable {
1323
1469
 
1324
1470
  .settings-col-name,
1325
1471
  .availability-col-name {
1326
- width: 142px;
1472
+ width: 132px;
1327
1473
  }
1328
1474
 
1329
- .settings-col-url {
1330
- width: 44%;
1475
+ .settings-col-connection {
1476
+ width: auto;
1477
+ min-width: 320px;
1331
1478
  }
1332
1479
 
1333
- .settings-col-key {
1334
- width: 28%;
1480
+ .settings-col-rounds {
1481
+ width: 196px;
1335
1482
  }
1336
1483
 
1337
1484
  .availability-col-url {
@@ -1344,10 +1491,285 @@ body[data-page="logs"] #logCenterTable {
1344
1491
 
1345
1492
  .source-drawer-settings {
1346
1493
  display: grid;
1347
- grid-template-columns: repeat(4, minmax(0, 1fr));
1348
1494
  gap: 12px;
1349
1495
  }
1350
1496
 
1497
+ .source-drawer-settings-copy {
1498
+ display: grid;
1499
+ gap: 4px;
1500
+ padding: 14px 16px;
1501
+ border: 1px solid var(--border);
1502
+ border-radius: 16px;
1503
+ background: linear-gradient(180deg, var(--surface) 0%, var(--surface-soft) 100%);
1504
+ }
1505
+
1506
+ .source-drawer-settings-copy strong {
1507
+ font-size: 13px;
1508
+ }
1509
+
1510
+ .source-drawer-settings-copy span {
1511
+ color: var(--text-soft);
1512
+ font-size: 12px;
1513
+ line-height: 1.6;
1514
+ }
1515
+
1516
+ .account-pool-panel {
1517
+ display: grid;
1518
+ gap: 16px;
1519
+ }
1520
+
1521
+ .account-pool-headline {
1522
+ align-items: flex-start;
1523
+ gap: 12px;
1524
+ flex-wrap: wrap;
1525
+ }
1526
+
1527
+ .account-pool-actions {
1528
+ display: flex;
1529
+ flex-wrap: wrap;
1530
+ gap: 8px;
1531
+ }
1532
+
1533
+ .account-pool-summary {
1534
+ display: grid;
1535
+ gap: 12px;
1536
+ padding: 18px;
1537
+ border: 1px solid var(--border);
1538
+ border-radius: 20px;
1539
+ background: linear-gradient(180deg, var(--surface) 0%, var(--surface-soft) 100%);
1540
+ }
1541
+
1542
+ .account-pool-total {
1543
+ display: flex;
1544
+ align-items: baseline;
1545
+ gap: 10px;
1546
+ }
1547
+
1548
+ .account-pool-total strong {
1549
+ font-size: 40px;
1550
+ line-height: 1;
1551
+ letter-spacing: -0.05em;
1552
+ font-variant-numeric: tabular-nums;
1553
+ }
1554
+
1555
+ .account-pool-total span {
1556
+ color: var(--text-soft);
1557
+ font-size: 13px;
1558
+ font-weight: 600;
1559
+ }
1560
+
1561
+ .account-pool-status-grid {
1562
+ display: grid;
1563
+ grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
1564
+ gap: 8px;
1565
+ }
1566
+
1567
+ .account-pool-stat {
1568
+ display: grid;
1569
+ gap: 2px;
1570
+ padding: 10px 12px;
1571
+ border-radius: 14px;
1572
+ background: var(--surface-muted);
1573
+ }
1574
+
1575
+ .account-pool-stat span {
1576
+ color: var(--text-soft);
1577
+ font-size: 12px;
1578
+ font-weight: 700;
1579
+ }
1580
+
1581
+ .account-pool-stat strong {
1582
+ font-size: 20px;
1583
+ line-height: 1.2;
1584
+ font-variant-numeric: tabular-nums;
1585
+ }
1586
+
1587
+ .account-pool-stat.success strong {
1588
+ color: var(--success);
1589
+ }
1590
+
1591
+ .account-pool-stat.warning strong {
1592
+ color: var(--warning);
1593
+ }
1594
+
1595
+ .account-pool-stat.danger strong {
1596
+ color: var(--danger);
1597
+ }
1598
+
1599
+ .account-pool-meter {
1600
+ display: flex;
1601
+ gap: 2px;
1602
+ height: 8px;
1603
+ border-radius: 999px;
1604
+ overflow: hidden;
1605
+ background: var(--surface-muted);
1606
+ }
1607
+
1608
+ .account-pool-meter span {
1609
+ display: block;
1610
+ min-width: 4px;
1611
+ }
1612
+
1613
+ .account-pool-meter span.success {
1614
+ background: var(--success);
1615
+ }
1616
+
1617
+ .account-pool-meter span.warning {
1618
+ background: var(--warning);
1619
+ }
1620
+
1621
+ .account-pool-meter span.danger {
1622
+ background: var(--danger);
1623
+ }
1624
+
1625
+ .account-pool-meter span.neutral {
1626
+ background: var(--border-strong);
1627
+ }
1628
+
1629
+ .account-pool-meter span.empty {
1630
+ flex: 1;
1631
+ background: var(--border-strong);
1632
+ opacity: 0.4;
1633
+ }
1634
+
1635
+ .account-pool-expiry {
1636
+ margin: 0;
1637
+ color: var(--text-soft);
1638
+ font-size: 12px;
1639
+ }
1640
+
1641
+ .account-pool-brands {
1642
+ display: flex;
1643
+ flex-wrap: wrap;
1644
+ gap: 8px;
1645
+ }
1646
+
1647
+ .account-brand-chip {
1648
+ display: inline-flex;
1649
+ align-items: baseline;
1650
+ gap: 6px;
1651
+ padding: 7px 12px;
1652
+ border-radius: 999px;
1653
+ border: 1px solid var(--border);
1654
+ background: var(--surface);
1655
+ color: var(--text-soft);
1656
+ font-size: 12px;
1657
+ }
1658
+
1659
+ .account-brand-chip strong {
1660
+ color: var(--text);
1661
+ font-size: 13px;
1662
+ }
1663
+
1664
+ .account-pool-toolbar {
1665
+ display: grid;
1666
+ grid-template-columns: minmax(180px, 1.4fr) repeat(3, minmax(120px, 1fr));
1667
+ gap: 10px;
1668
+ }
1669
+
1670
+ .account-pool-toolbar label {
1671
+ display: grid;
1672
+ gap: 4px;
1673
+ min-width: 0;
1674
+ }
1675
+
1676
+ .account-pool-toolbar label > span {
1677
+ color: var(--text-soft);
1678
+ font-size: 11px;
1679
+ font-weight: 700;
1680
+ }
1681
+
1682
+ .account-pool-toolbar input,
1683
+ .account-pool-toolbar select {
1684
+ min-height: 38px;
1685
+ border-radius: 10px;
1686
+ font-size: 13px;
1687
+ }
1688
+
1689
+ .account-pool-table {
1690
+ table-layout: fixed;
1691
+ min-width: 0;
1692
+ }
1693
+
1694
+ .account-col-account {
1695
+ width: auto;
1696
+ }
1697
+
1698
+ .account-col-brand {
1699
+ width: 92px;
1700
+ }
1701
+
1702
+ .account-col-status {
1703
+ width: 128px;
1704
+ }
1705
+
1706
+ .account-col-expiry {
1707
+ width: 110px;
1708
+ }
1709
+
1710
+ .account-col-usage {
1711
+ width: 132px;
1712
+ }
1713
+
1714
+ .account-col-actions {
1715
+ width: 92px;
1716
+ }
1717
+
1718
+ .account-pool-table td {
1719
+ vertical-align: middle;
1720
+ }
1721
+
1722
+ .account-mask {
1723
+ display: block;
1724
+ font-family: "SFMono-Regular", ui-monospace, Menlo, monospace;
1725
+ font-size: 13px;
1726
+ }
1727
+
1728
+ .account-note {
1729
+ display: block;
1730
+ margin-top: 3px;
1731
+ color: var(--text-soft);
1732
+ font-size: 11px;
1733
+ line-height: 1.4;
1734
+ }
1735
+
1736
+ .account-usage {
1737
+ display: block;
1738
+ font-size: 13px;
1739
+ font-weight: 700;
1740
+ font-variant-numeric: tabular-nums;
1741
+ }
1742
+
1743
+ .account-pool-count {
1744
+ margin: 0;
1745
+ color: var(--text-soft);
1746
+ font-size: 12px;
1747
+ }
1748
+
1749
+ .account-pool-empty {
1750
+ padding: 22px;
1751
+ border: 1px dashed var(--border-strong);
1752
+ border-radius: 16px;
1753
+ color: var(--text-soft);
1754
+ font-size: 13px;
1755
+ text-align: center;
1756
+ }
1757
+
1758
+ .account-pool-message {
1759
+ margin: 0;
1760
+ padding: 10px 12px;
1761
+ border-radius: 12px;
1762
+ background: var(--success-soft);
1763
+ color: var(--success);
1764
+ font-size: 12px;
1765
+ font-weight: 600;
1766
+ }
1767
+
1768
+ .account-pool-message.warning {
1769
+ background: var(--warning-soft);
1770
+ color: var(--warning);
1771
+ }
1772
+
1351
1773
  .settings-overview-panel {
1352
1774
  position: relative;
1353
1775
  }
@@ -1363,7 +1785,7 @@ body[data-page="logs"] #logCenterTable {
1363
1785
  padding: 18px;
1364
1786
  border-radius: 22px;
1365
1787
  border: 1px solid var(--border);
1366
- background: linear-gradient(180deg, #ffffff 0%, #f8faff 100%);
1788
+ background: linear-gradient(180deg, var(--surface) 0%, var(--surface-soft) 100%);
1367
1789
  text-align: left;
1368
1790
  display: grid;
1369
1791
  gap: 10px;
@@ -1431,7 +1853,7 @@ body[data-page="logs"] #logCenterTable {
1431
1853
  max-width: 1320px;
1432
1854
  max-height: min(88vh, 960px);
1433
1855
  padding: 26px 26px 24px;
1434
- background: #fff;
1856
+ background: var(--surface);
1435
1857
  border: 1px solid var(--border);
1436
1858
  border-radius: 26px;
1437
1859
  box-shadow: 0 16px 48px rgba(29, 39, 71, 0.16);
@@ -1450,6 +1872,14 @@ body[data-page="logs"] #logCenterTable {
1450
1872
  max-width: 960px;
1451
1873
  }
1452
1874
 
1875
+ /* The source table is four short columns. At 1320px the `auto` site column
1876
+ absorbed ~870px for a 26-character URL while the loop inputs shrank to their
1877
+ spinner width, so this drawer is sized to the content instead. */
1878
+ .settings-drawer-shell[data-section="sources"] .settings-drawer-panel {
1879
+ width: min(1080px, calc(100vw - 48px));
1880
+ max-width: 1080px;
1881
+ }
1882
+
1453
1883
  .settings-drawer-shell[data-open="true"] .settings-drawer-panel {
1454
1884
  transform: scale(1) translateY(0);
1455
1885
  opacity: 1;
@@ -1481,6 +1911,8 @@ body[data-page="logs"] #logCenterTable {
1481
1911
  min-height: 0;
1482
1912
  overflow: auto;
1483
1913
  display: grid;
1914
+ grid-auto-rows: max-content;
1915
+ align-content: start;
1484
1916
  gap: 16px;
1485
1917
  padding-right: 6px;
1486
1918
  }
@@ -1663,7 +2095,7 @@ body[data-page="logs"] #logCenterTable {
1663
2095
  .progress-track {
1664
2096
  height: 10px;
1665
2097
  border-radius: 999px;
1666
- background: #ebeffa;
2098
+ background: var(--surface-muted);
1667
2099
  overflow: hidden;
1668
2100
  margin-bottom: 16px;
1669
2101
  }
@@ -1776,7 +2208,7 @@ body[data-page="logs"] #logCenterTable {
1776
2208
  height: 40px;
1777
2209
  border-radius: 12px;
1778
2210
  border: 1px solid var(--border);
1779
- background: #fff;
2211
+ background: var(--surface);
1780
2212
  font-size: 12px;
1781
2213
  font-weight: 800;
1782
2214
  color: var(--accent);
@@ -1824,7 +2256,7 @@ body[data-page="logs"] #logCenterTable {
1824
2256
  .qr-cell {
1825
2257
  aspect-ratio: 1;
1826
2258
  border-radius: 2px;
1827
- background: #eef2fa;
2259
+ background: var(--surface-muted);
1828
2260
  }
1829
2261
 
1830
2262
  .qr-cell.filled {
@@ -1879,7 +2311,7 @@ body[data-page="logs"] #logCenterTable {
1879
2311
  width: 50px;
1880
2312
  height: 30px;
1881
2313
  border-radius: 999px;
1882
- background: #d9deef;
2314
+ background: var(--border-strong);
1883
2315
  transition: background 0.18s ease;
1884
2316
  }
1885
2317
 
@@ -1894,7 +2326,7 @@ body[data-page="logs"] #logCenterTable {
1894
2326
  width: 24px;
1895
2327
  height: 24px;
1896
2328
  border-radius: 999px;
1897
- background: #fff;
2329
+ background: var(--surface);
1898
2330
  box-shadow: 0 4px 12px rgba(27, 38, 70, 0.2);
1899
2331
  }
1900
2332
 
@@ -1919,7 +2351,7 @@ body[data-page="logs"] #logCenterTable {
1919
2351
  padding: 16px;
1920
2352
  border-radius: 18px;
1921
2353
  border: 1px solid rgba(91, 92, 226, 0.24);
1922
- background: linear-gradient(180deg, #f7f6ff 0%, #fff 100%);
2354
+ background: linear-gradient(180deg, var(--accent-soft) 0%, var(--surface) 100%);
1923
2355
  text-align: center;
1924
2356
  }
1925
2357
 
@@ -1954,7 +2386,7 @@ body[data-page="logs"] #logCenterTable {
1954
2386
  margin: 18px 0 0;
1955
2387
  padding: 14px;
1956
2388
  border-radius: 16px;
1957
- background: #f7f9ff;
2389
+ background: var(--surface-soft);
1958
2390
  border: 1px solid var(--border);
1959
2391
  font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
1960
2392
  color: var(--text);
@@ -2112,9 +2544,13 @@ body[data-page="logs"] #logCenterTable {
2112
2544
  align-items: flex-start;
2113
2545
  }
2114
2546
 
2115
- .source-drawer-settings {
2547
+ .account-pool-toolbar {
2116
2548
  grid-template-columns: repeat(2, minmax(0, 1fr));
2117
2549
  }
2550
+
2551
+ .account-pool-toolbar .account-pool-search {
2552
+ grid-column: 1 / -1;
2553
+ }
2118
2554
  }
2119
2555
 
2120
2556
  @media (max-width: 720px) {
@@ -2193,15 +2629,19 @@ body[data-page="logs"] #logCenterTable {
2193
2629
 
2194
2630
  body {
2195
2631
  overflow: auto;
2196
- background: linear-gradient(180deg, #fbfcff 0%, var(--bg) 100%);
2632
+ background: linear-gradient(180deg, var(--surface-soft) 0%, var(--bg) 100%);
2197
2633
  }
2198
2634
 
2199
2635
  .settings-drawer-shell {
2200
2636
  padding: 0;
2201
2637
  }
2202
2638
 
2639
+ /* Section-specific desktop widths (sources, availability) are more specific
2640
+ than a bare `.settings-drawer-panel`, so each one has to be listed here or
2641
+ that sheet stays inset with desktop corners on a phone. */
2203
2642
  .settings-drawer-panel,
2204
- .settings-drawer-shell[data-section="availability_targets"] .settings-drawer-panel {
2643
+ .settings-drawer-shell[data-section="availability_targets"] .settings-drawer-panel,
2644
+ .settings-drawer-shell[data-section="sources"] .settings-drawer-panel {
2205
2645
  width: 100vw;
2206
2646
  max-width: none;
2207
2647
  height: 100vh;
@@ -2213,7 +2653,7 @@ body[data-page="logs"] #logCenterTable {
2213
2653
  border-radius: 0;
2214
2654
  transform: none !important;
2215
2655
  overflow: hidden;
2216
- background: #fff;
2656
+ background: var(--surface);
2217
2657
  }
2218
2658
 
2219
2659
  .settings-drawer-head {
@@ -2238,7 +2678,7 @@ body[data-page="logs"] #logCenterTable {
2238
2678
  position: sticky;
2239
2679
  bottom: 0;
2240
2680
  padding: 12px 16px calc(12px + var(--safe-area-bottom));
2241
- background: rgba(255, 255, 255, 0.98);
2681
+ background: var(--surface);
2242
2682
  border-top: 1px solid var(--border);
2243
2683
  }
2244
2684
 
@@ -2316,6 +2756,91 @@ body[data-page="logs"] #logCenterTable {
2316
2756
  min-height: 44px;
2317
2757
  }
2318
2758
 
2759
+ /* The cards are a block stack, so the table's own scroll box would become a
2760
+ second, nested scroller inside the drawer body. */
2761
+ .settings-drawer-body .table-wrap {
2762
+ overflow: visible;
2763
+ border: 0;
2764
+ border-radius: 0;
2765
+ }
2766
+
2767
+ .source-credential-rounds {
2768
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2769
+ }
2770
+
2771
+ .settings-source-hint {
2772
+ margin-top: 4px;
2773
+ }
2774
+
2775
+ .account-pool-toolbar {
2776
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2777
+ }
2778
+
2779
+ .account-pool-toolbar .account-pool-search {
2780
+ grid-column: 1 / -1;
2781
+ }
2782
+
2783
+ .account-pool-actions {
2784
+ width: 100%;
2785
+ }
2786
+
2787
+ .account-pool-actions .btn {
2788
+ flex: 1;
2789
+ min-height: 44px;
2790
+ }
2791
+
2792
+ .account-pool-toolbar input,
2793
+ .account-pool-toolbar select {
2794
+ min-height: 44px;
2795
+ }
2796
+
2797
+ .account-pool-table thead,
2798
+ .account-pool-table colgroup {
2799
+ display: none;
2800
+ }
2801
+
2802
+ .account-pool-table,
2803
+ .account-pool-table tbody,
2804
+ .account-pool-table tr,
2805
+ .account-pool-table td {
2806
+ display: block;
2807
+ width: 100%;
2808
+ }
2809
+
2810
+ .account-pool-table tr {
2811
+ display: grid;
2812
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2813
+ gap: 4px 12px;
2814
+ margin-bottom: 12px;
2815
+ padding: 14px;
2816
+ border: 1px solid var(--border);
2817
+ border-radius: 14px;
2818
+ }
2819
+
2820
+ .account-pool-table td {
2821
+ padding: 4px 0;
2822
+ border: 0;
2823
+ }
2824
+
2825
+ .account-pool-table td::before {
2826
+ content: attr(data-field-label);
2827
+ display: block;
2828
+ margin-bottom: 3px;
2829
+ color: var(--text-soft);
2830
+ font-size: 12px;
2831
+ font-weight: 700;
2832
+ }
2833
+
2834
+ .account-pool-table td:first-child,
2835
+ .account-pool-table td:last-child {
2836
+ grid-column: 1 / -1;
2837
+ }
2838
+
2839
+ .account-pool-table td:last-child .btn {
2840
+ width: 100%;
2841
+ min-height: 44px;
2842
+ }
2843
+
2319
2844
  .app-frame {
2320
2845
  display: block;
2321
2846
  height: auto;
@@ -2337,7 +2862,7 @@ body[data-page="logs"] #logCenterTable {
2337
2862
  padding: 8px 10px calc(8px + var(--safe-area-bottom));
2338
2863
  border: 1px solid rgba(207, 215, 239, 0.82);
2339
2864
  border-width: 1px 0 0;
2340
- background: rgba(255, 255, 255, 0.96);
2865
+ background: var(--surface);
2341
2866
  box-shadow: 0 -16px 34px rgba(29, 39, 71, 0.12);
2342
2867
  backdrop-filter: blur(18px);
2343
2868
  }
@@ -2525,15 +3050,21 @@ body[data-page="logs"] #logCenterTable {
2525
3050
  position: fixed;
2526
3051
  inset: auto max(12px, var(--safe-area-right)) calc(76px + var(--safe-area-bottom)) max(12px, var(--safe-area-left));
2527
3052
  z-index: var(--z-sticky);
3053
+ display: grid;
2528
3054
  grid-template-columns: repeat(2, minmax(0, 1fr));
2529
3055
  gap: 10px;
2530
3056
  padding: 10px;
2531
- background: rgba(255, 255, 255, 0.98);
3057
+ background: var(--surface);
2532
3058
  backdrop-filter: blur(16px);
2533
3059
  border: 1px solid var(--border);
2534
3060
  border-radius: 16px;
2535
3061
  }
2536
3062
 
3063
+ .mobile-run-bar .run-big {
3064
+ min-width: 0;
3065
+ padding-inline: 12px;
3066
+ }
3067
+
2537
3068
  #runsCurrentStage {
2538
3069
  scroll-margin-bottom: 170px;
2539
3070
  }
@@ -2641,7 +3172,8 @@ body[data-page="logs"] #logCenterTable {
2641
3172
  overflow-x: auto;
2642
3173
  }
2643
3174
 
2644
- .settings-drawer-panel {
3175
+ .settings-drawer-panel,
3176
+ .settings-drawer-shell[data-section="sources"] .settings-drawer-panel {
2645
3177
  width: 100vw;
2646
3178
  max-width: none;
2647
3179
  height: 100vh;
@@ -2660,6 +3192,10 @@ body[data-page="logs"] #logCenterTable {
2660
3192
  grid-template-columns: 1fr;
2661
3193
  }
2662
3194
 
3195
+ .account-pool-toolbar {
3196
+ grid-template-columns: 1fr;
3197
+ }
3198
+
2663
3199
  .toast-root {
2664
3200
  left: 12px;
2665
3201
  right: 12px;