bugpatrol 0.3.0 → 0.4.1

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.
package/src/ui/style.css CHANGED
@@ -15,19 +15,22 @@
15
15
  --gh-merged: #b197fc;
16
16
  --gh-closed: #ff6b6b;
17
17
  }
18
- @media (prefers-color-scheme: light) {
19
- :root {
20
- --bg: #f6f7f9;
21
- --panel: #fff;
22
- --panel-2: #f0f2f6;
23
- --line: #dfe3ea;
24
- --fg: #14171c;
25
- --muted: #5b6270;
26
- --accent: #2b59d8;
27
- --gh-open: #237a36;
28
- --gh-merged: #7042b8;
29
- --gh-closed: #b73535;
30
- }
18
+ /* The theme comes from data-theme on <html>: the user's choice, or else the system setting (index.html). */
19
+ :root {
20
+ color-scheme: dark;
21
+ }
22
+ :root[data-theme="light"] {
23
+ color-scheme: light;
24
+ --bg: #f6f7f9;
25
+ --panel: #fff;
26
+ --panel-2: #f0f2f6;
27
+ --line: #dfe3ea;
28
+ --fg: #14171c;
29
+ --muted: #5b6270;
30
+ --accent: #2b59d8;
31
+ --gh-open: #237a36;
32
+ --gh-merged: #7042b8;
33
+ --gh-closed: #b73535;
31
34
  }
32
35
 
33
36
  * {
@@ -47,6 +50,9 @@ body {
47
50
  -apple-system,
48
51
  sans-serif;
49
52
  }
53
+ a {
54
+ color: var(--accent);
55
+ }
50
56
  button {
51
57
  font: inherit;
52
58
  color: inherit;
@@ -533,6 +539,25 @@ h1 {
533
539
  padding: 0.15rem 0.6rem;
534
540
  color: var(--muted);
535
541
  }
542
+ .theme-toggle {
543
+ display: inline-grid;
544
+ place-items: center;
545
+ width: 28px;
546
+ height: 28px;
547
+ border: 1px solid var(--line);
548
+ border-radius: 999px;
549
+ padding: 0;
550
+ background: none;
551
+ color: var(--muted);
552
+ }
553
+ .theme-toggle svg,
554
+ .surface svg {
555
+ width: 15px;
556
+ height: 15px;
557
+ }
558
+ .theme-toggle:hover {
559
+ color: var(--fg);
560
+ }
536
561
  .pill.running {
537
562
  color: var(--accent);
538
563
  border-color: var(--accent);
@@ -621,10 +646,9 @@ h1 {
621
646
  .overview-grid {
622
647
  display: grid;
623
648
  grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr);
649
+ align-items: start;
624
650
  gap: 0.85rem;
625
- }
626
- .coverage {
627
- margin-top: 0.85rem;
651
+ margin-bottom: 0.85rem;
628
652
  }
629
653
  .usage {
630
654
  margin-top: 0.85rem;
@@ -886,6 +910,36 @@ h1 {
886
910
  background: var(--panel-2);
887
911
  cursor: zoom-in;
888
912
  }
913
+ /* An API capture is text: the HTTP exchange in a monospace block. */
914
+ pre.http {
915
+ margin: 0;
916
+ background: var(--panel-2);
917
+ border: 1px solid var(--line);
918
+ border-radius: 6px;
919
+ padding: 0.6rem 0.75rem;
920
+ font-size: 0.75rem;
921
+ line-height: 1.45;
922
+ white-space: pre-wrap;
923
+ overflow-wrap: anywhere;
924
+ overflow: auto;
925
+ max-height: 420px;
926
+ }
927
+ .evidence-grid .http-evidence {
928
+ grid-column: 1 / -1;
929
+ }
930
+ .http-thumb {
931
+ display: grid;
932
+ place-items: center;
933
+ border: 1px solid var(--line);
934
+ font:
935
+ 600 0.62rem / 1.1 ui-monospace,
936
+ monospace;
937
+ color: var(--muted);
938
+ text-align: center;
939
+ }
940
+ pre.http.live-shot {
941
+ max-height: none;
942
+ }
889
943
  .evidence-grid figcaption {
890
944
  color: var(--muted);
891
945
  text-align: center;
@@ -1342,3 +1396,598 @@ h1 {
1342
1396
  font-weight: 600;
1343
1397
  margin: 0.5rem 0;
1344
1398
  }
1399
+
1400
+ /* ---------- coverage matrix ---------- */
1401
+ .matrix-scroll {
1402
+ overflow-x: auto;
1403
+ }
1404
+ .matrix {
1405
+ border-collapse: collapse;
1406
+ font-size: 0.8rem;
1407
+ font-variant-numeric: tabular-nums;
1408
+ }
1409
+ .matrix th,
1410
+ .matrix td {
1411
+ padding: 0.3rem 0.45rem;
1412
+ border-bottom: 1px solid var(--line);
1413
+ text-align: center;
1414
+ white-space: nowrap;
1415
+ }
1416
+ .matrix thead th {
1417
+ color: var(--muted);
1418
+ font-weight: 600;
1419
+ font-size: 0.75rem;
1420
+ }
1421
+ .matrix .matrix-groups th {
1422
+ border-bottom: 0;
1423
+ padding-bottom: 0;
1424
+ font-size: 0.7rem;
1425
+ font-weight: 400;
1426
+ text-transform: uppercase;
1427
+ letter-spacing: 0.04em;
1428
+ }
1429
+ .matrix .matrix-groups th:not(:empty) {
1430
+ border-bottom: 1px solid var(--line);
1431
+ }
1432
+ .matrix .matrix-groups th.declared {
1433
+ border-right: 1px solid var(--line);
1434
+ }
1435
+ .matrix thead th.declared {
1436
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1437
+ }
1438
+ .matrix th:first-child {
1439
+ text-align: left;
1440
+ }
1441
+ .matrix tbody th {
1442
+ font-weight: 400;
1443
+ font-size: 0.85rem;
1444
+ padding-right: 1.25rem;
1445
+ }
1446
+ .matrix .method {
1447
+ display: inline-block;
1448
+ min-width: 3.6rem;
1449
+ color: var(--muted);
1450
+ font:
1451
+ 600 0.68rem / 1 ui-monospace,
1452
+ monospace;
1453
+ }
1454
+ .matrix-cell {
1455
+ display: inline-block;
1456
+ min-width: 4.8rem;
1457
+ padding: 0.12rem 0.4rem;
1458
+ border: 1px solid transparent;
1459
+ border-radius: 5px;
1460
+ font:
1461
+ 600 0.75rem / 1.4 ui-monospace,
1462
+ monospace;
1463
+ color: var(--fg);
1464
+ }
1465
+ button.matrix-cell:hover,
1466
+ .matrix-cell.active {
1467
+ outline: 2px solid var(--fg);
1468
+ outline-offset: 1px;
1469
+ }
1470
+ .matrix-cell.pass {
1471
+ background: color-mix(in srgb, var(--ok) 18%, transparent);
1472
+ }
1473
+ .matrix-cell.fail {
1474
+ background: var(--critical);
1475
+ color: #2a0505;
1476
+ }
1477
+ /* A second cue next to the colour: the status of a failed case can look like a good one. */
1478
+ .matrix-cell.fail::after {
1479
+ content: " ✕";
1480
+ }
1481
+ .matrix-cell.blocked {
1482
+ background: color-mix(in srgb, var(--major) 18%, transparent);
1483
+ font-weight: 400;
1484
+ }
1485
+ .matrix-cell.skip {
1486
+ background: var(--panel-2);
1487
+ border-color: var(--line);
1488
+ color: var(--muted);
1489
+ font-weight: 400;
1490
+ }
1491
+ .matrix-cell.untested {
1492
+ border: 1px dashed var(--muted);
1493
+ color: var(--muted);
1494
+ font-weight: 400;
1495
+ }
1496
+ .matrix-legend {
1497
+ display: flex;
1498
+ flex-wrap: wrap;
1499
+ gap: 1rem;
1500
+ margin-bottom: 0.6rem;
1501
+ color: var(--muted);
1502
+ font-size: 0.75rem;
1503
+ }
1504
+ .matrix-legend > span {
1505
+ display: inline-flex;
1506
+ align-items: center;
1507
+ gap: 0.35rem;
1508
+ }
1509
+ .matrix-legend .matrix-cell {
1510
+ min-width: 2.2rem;
1511
+ min-height: 1.3rem;
1512
+ font-size: 0.68rem;
1513
+ text-align: center;
1514
+ }
1515
+
1516
+ .matrix-footer {
1517
+ margin: 0.75rem 0 0;
1518
+ font-size: 0.8rem;
1519
+ }
1520
+
1521
+ /* ---------- surfaces ---------- */
1522
+ .surfaces {
1523
+ display: inline-flex;
1524
+ align-items: center;
1525
+ gap: 0.35rem;
1526
+ }
1527
+ .surface {
1528
+ display: inline-grid;
1529
+ place-items: center;
1530
+ width: 28px;
1531
+ height: 28px;
1532
+ border: 1px solid var(--line);
1533
+ border-radius: 999px;
1534
+ color: var(--muted);
1535
+ }
1536
+ .surface.active {
1537
+ border-color: var(--fg);
1538
+ color: var(--fg);
1539
+ }
1540
+ .surface-note {
1541
+ margin: -0.25rem 0 0.75rem;
1542
+ }
1543
+ .surface-list {
1544
+ display: grid;
1545
+ gap: 1rem;
1546
+ }
1547
+ .surface-block + .surface-block {
1548
+ border-top: 1px solid var(--line);
1549
+ padding-top: 1rem;
1550
+ }
1551
+ .surface-head {
1552
+ display: flex;
1553
+ align-items: baseline;
1554
+ gap: 0.5rem;
1555
+ margin-bottom: 0.5rem;
1556
+ }
1557
+ .surface-head h3 {
1558
+ margin: 0;
1559
+ }
1560
+ .surface-numbers {
1561
+ display: grid;
1562
+ gap: 0.45rem;
1563
+ width: 100%;
1564
+ text-align: left;
1565
+ background: transparent;
1566
+ border: 0;
1567
+ padding: 0;
1568
+ }
1569
+ .surface-line {
1570
+ display: flex;
1571
+ align-items: baseline;
1572
+ gap: 0.5rem;
1573
+ color: var(--muted);
1574
+ }
1575
+ .surface-line .big {
1576
+ font-size: 1.5rem;
1577
+ line-height: 1;
1578
+ color: var(--fg);
1579
+ font-variant-numeric: tabular-nums;
1580
+ }
1581
+ .config-name {
1582
+ font-weight: 400;
1583
+ }
1584
+
1585
+ /* ---------- stats band ---------- */
1586
+ .band {
1587
+ display: grid;
1588
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
1589
+ gap: 1px;
1590
+ background: var(--line);
1591
+ border: 1px solid var(--line);
1592
+ border-radius: 10px;
1593
+ overflow: hidden;
1594
+ margin-bottom: 0.85rem;
1595
+ }
1596
+ .band.confidence {
1597
+ grid-template-columns: minmax(220px, 1.3fr) repeat(auto-fit, minmax(150px, 1fr));
1598
+ }
1599
+ .stat {
1600
+ display: flex;
1601
+ flex-direction: column;
1602
+ gap: 0.15rem;
1603
+ min-width: 0;
1604
+ padding: 0.7rem 0.9rem;
1605
+ background: var(--panel);
1606
+ border: 0;
1607
+ text-align: left;
1608
+ }
1609
+ button.stat:hover {
1610
+ background: var(--panel-2);
1611
+ }
1612
+ .stat-label {
1613
+ color: var(--muted);
1614
+ font-size: 0.72rem;
1615
+ font-weight: 600;
1616
+ text-transform: uppercase;
1617
+ letter-spacing: 0.04em;
1618
+ }
1619
+ .stat-value {
1620
+ font-size: 1.35rem;
1621
+ line-height: 1.2;
1622
+ font-variant-numeric: tabular-nums;
1623
+ overflow-wrap: anywhere;
1624
+ }
1625
+ .stat-note {
1626
+ display: -webkit-box;
1627
+ -webkit-box-orient: vertical;
1628
+ -webkit-line-clamp: 2;
1629
+ overflow: hidden;
1630
+ color: var(--muted);
1631
+ font-size: 0.78rem;
1632
+ }
1633
+ .confidence .stat:first-child .stat-value {
1634
+ font-size: 1.15rem;
1635
+ }
1636
+ .stat.tone-fail .stat-value {
1637
+ color: var(--critical);
1638
+ }
1639
+ .stat.tone-warn .stat-value {
1640
+ color: var(--major);
1641
+ }
1642
+ .stat.tone-pass .stat-value {
1643
+ color: var(--ok);
1644
+ }
1645
+ :root[data-theme="light"] .stat.tone-fail .stat-value {
1646
+ color: #b73535;
1647
+ }
1648
+ :root[data-theme="light"] .stat.tone-warn .stat-value {
1649
+ color: #a35300;
1650
+ }
1651
+ :root[data-theme="light"] .stat.tone-pass .stat-value {
1652
+ color: #237a36;
1653
+ }
1654
+ .session-detail .band {
1655
+ margin: 0.25rem 0 0.85rem;
1656
+ }
1657
+
1658
+ /* ---------- stacked bar ---------- */
1659
+ .bar {
1660
+ display: flex;
1661
+ gap: 1px;
1662
+ height: 8px;
1663
+ margin: 0.3rem 0 0.15rem;
1664
+ border-radius: 4px;
1665
+ overflow: hidden;
1666
+ background: var(--panel-2);
1667
+ }
1668
+ .bar > span {
1669
+ flex-basis: 0;
1670
+ min-width: 2px;
1671
+ }
1672
+ .bar-pass {
1673
+ background: var(--ok);
1674
+ }
1675
+ .bar-fail {
1676
+ background: var(--critical);
1677
+ }
1678
+ .bar-blocked {
1679
+ background: var(--major);
1680
+ }
1681
+ .bar-skip {
1682
+ background: var(--line);
1683
+ }
1684
+ .bar-untested {
1685
+ background: repeating-linear-gradient(135deg, var(--muted) 0 2px, transparent 2px 5px);
1686
+ }
1687
+ .bar-legend {
1688
+ display: flex;
1689
+ flex-wrap: wrap;
1690
+ gap: 0.25rem 0.9rem;
1691
+ color: var(--muted);
1692
+ font-size: 0.78rem;
1693
+ font-variant-numeric: tabular-nums;
1694
+ }
1695
+ .bar-legend span {
1696
+ display: inline-flex;
1697
+ align-items: center;
1698
+ gap: 0.3rem;
1699
+ }
1700
+ .bar-legend i {
1701
+ width: 8px;
1702
+ height: 8px;
1703
+ border-radius: 2px;
1704
+ }
1705
+
1706
+ /* ---------- empty state and commands ---------- */
1707
+ .empty-state {
1708
+ max-width: 40rem;
1709
+ margin: 1.5rem auto;
1710
+ text-align: center;
1711
+ }
1712
+ .empty-state.compact {
1713
+ margin: 0.25rem 0;
1714
+ max-width: none;
1715
+ text-align: left;
1716
+ }
1717
+ .empty-state h3 {
1718
+ font-size: 0.95rem;
1719
+ margin: 0 0 0.35rem;
1720
+ }
1721
+ .empty-state p {
1722
+ margin: 0 0 0.45rem;
1723
+ color: var(--muted);
1724
+ }
1725
+ .empty-state .command,
1726
+ .empty-state .primary {
1727
+ margin-top: 0.6rem;
1728
+ }
1729
+ .empty-state:not(.compact) .command {
1730
+ margin-inline: auto;
1731
+ }
1732
+ .empty-state .docs {
1733
+ display: block;
1734
+ margin-top: 0.6rem;
1735
+ font-size: 0.8rem;
1736
+ color: var(--accent);
1737
+ }
1738
+ .command {
1739
+ display: flex;
1740
+ align-items: flex-start;
1741
+ gap: 0.5rem;
1742
+ width: fit-content;
1743
+ max-width: 100%;
1744
+ padding: 0.35rem 0.4rem 0.35rem 0.7rem;
1745
+ background: var(--panel-2);
1746
+ border: 1px solid var(--line);
1747
+ border-radius: 6px;
1748
+ text-align: left;
1749
+ }
1750
+ .command code {
1751
+ padding-top: 0.15rem;
1752
+ white-space: pre-wrap;
1753
+ overflow-wrap: anywhere;
1754
+ }
1755
+ .copy,
1756
+ .primary,
1757
+ .close {
1758
+ flex: none;
1759
+ background: var(--panel);
1760
+ border: 1px solid var(--line);
1761
+ border-radius: 5px;
1762
+ padding: 0.1rem 0.55rem;
1763
+ font-size: 0.75rem;
1764
+ color: var(--muted);
1765
+ }
1766
+ .copy:hover,
1767
+ .close:hover {
1768
+ color: var(--fg);
1769
+ }
1770
+ .primary {
1771
+ background: var(--accent);
1772
+ border-color: var(--accent);
1773
+ color: var(--panel);
1774
+ padding: 0.3rem 0.8rem;
1775
+ font-size: 0.85rem;
1776
+ }
1777
+ .link {
1778
+ background: none;
1779
+ border: 0;
1780
+ padding: 0;
1781
+ color: var(--accent);
1782
+ font-size: inherit;
1783
+ }
1784
+ .link:hover {
1785
+ text-decoration: underline;
1786
+ }
1787
+ .callout {
1788
+ display: flex;
1789
+ flex-wrap: wrap;
1790
+ align-items: center;
1791
+ gap: 0.4rem 0.75rem;
1792
+ margin: 0.5rem 0 0.75rem;
1793
+ padding: 0.6rem 0.75rem;
1794
+ border-left: 3px solid var(--major);
1795
+ background: var(--panel-2);
1796
+ border-radius: 0 6px 6px 0;
1797
+ }
1798
+ .callout p {
1799
+ margin: 0;
1800
+ }
1801
+ .subsection {
1802
+ margin-top: 1rem;
1803
+ }
1804
+ .subsection > h3 {
1805
+ margin-bottom: 0.25rem;
1806
+ }
1807
+ .stack-gap {
1808
+ display: grid;
1809
+ grid-template-columns: minmax(0, 1fr);
1810
+ gap: 0.85rem;
1811
+ }
1812
+
1813
+ /* ---------- activity findings ---------- */
1814
+ .finding-group {
1815
+ border-top: 1px solid var(--line);
1816
+ }
1817
+ .finding-group,
1818
+ .candidate-row {
1819
+ scroll-margin-top: 72px;
1820
+ }
1821
+ .finding-group > summary {
1822
+ display: flex;
1823
+ align-items: center;
1824
+ gap: 0.5rem;
1825
+ padding: 0.5rem 0.2rem;
1826
+ cursor: pointer;
1827
+ }
1828
+ .finding-group > summary:hover {
1829
+ background: var(--panel-2);
1830
+ }
1831
+ .group-label {
1832
+ font-weight: 600;
1833
+ }
1834
+ .group-repeat {
1835
+ margin-left: auto;
1836
+ font-size: 0.78rem;
1837
+ white-space: nowrap;
1838
+ }
1839
+ .group-count {
1840
+ min-width: 2.5rem;
1841
+ text-align: right;
1842
+ font-variant-numeric: tabular-nums;
1843
+ }
1844
+ .assertion {
1845
+ padding: 0.05rem 0.35rem;
1846
+ border: 1px solid var(--line);
1847
+ border-radius: 4px;
1848
+ color: var(--muted);
1849
+ }
1850
+ .candidate-row {
1851
+ margin-left: 1.1rem;
1852
+ border-top: 1px dashed var(--line);
1853
+ }
1854
+ .candidate-row > summary {
1855
+ display: flex;
1856
+ align-items: center;
1857
+ gap: 0.5rem;
1858
+ padding: 0.35rem 0.2rem;
1859
+ cursor: pointer;
1860
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1861
+ font-size: 0.8rem;
1862
+ }
1863
+ .candidate-row > summary .badge {
1864
+ font-family: ui-sans-serif, system-ui, sans-serif;
1865
+ border: 0;
1866
+ white-space: nowrap;
1867
+ }
1868
+ .candidate-row .state-words {
1869
+ font-family: ui-sans-serif, system-ui, sans-serif;
1870
+ font-size: 0.75rem;
1871
+ white-space: nowrap;
1872
+ }
1873
+ .candidate-row > p {
1874
+ margin: 0.2rem 0 0.4rem;
1875
+ font-size: 0.8rem;
1876
+ }
1877
+ .candidate-row > pre.http {
1878
+ max-height: 22rem;
1879
+ margin-bottom: 0.6rem;
1880
+ }
1881
+ .candidate-shot {
1882
+ max-width: 320px;
1883
+ border-radius: 6px;
1884
+ margin-bottom: 0.6rem;
1885
+ }
1886
+ .chips {
1887
+ display: flex;
1888
+ flex-wrap: wrap;
1889
+ gap: 0.4rem;
1890
+ }
1891
+ .chip {
1892
+ display: inline-flex;
1893
+ gap: 0.45rem;
1894
+ padding: 0.15rem 0.6rem;
1895
+ border: 1px solid var(--line);
1896
+ border-radius: 999px;
1897
+ font-size: 0.8rem;
1898
+ }
1899
+ .chip strong {
1900
+ font-variant-numeric: tabular-nums;
1901
+ }
1902
+ .raw-events > summary {
1903
+ cursor: pointer;
1904
+ color: var(--muted);
1905
+ font-weight: 600;
1906
+ }
1907
+
1908
+ /* ---------- coverage ---------- */
1909
+ .matrix-tools {
1910
+ display: flex;
1911
+ flex-wrap: wrap;
1912
+ align-items: center;
1913
+ gap: 0.5rem 1rem;
1914
+ margin-bottom: 0.6rem;
1915
+ }
1916
+ .matrix-tools .toggle {
1917
+ margin: 0;
1918
+ font-size: 0.85rem;
1919
+ }
1920
+ .matrix-tools .matrix-legend {
1921
+ margin: 0 0 0 auto;
1922
+ }
1923
+ .search {
1924
+ width: 16rem;
1925
+ padding: 0.3rem 0.55rem;
1926
+ border: 1px solid var(--line);
1927
+ border-radius: 6px;
1928
+ background: var(--panel);
1929
+ color: var(--fg);
1930
+ font: inherit;
1931
+ font-size: 0.85rem;
1932
+ }
1933
+ .matrix-scroll {
1934
+ max-height: calc(100vh - 220px);
1935
+ overflow: auto;
1936
+ border: 1px solid var(--line);
1937
+ border-radius: 6px;
1938
+ }
1939
+ .matrix thead th {
1940
+ position: sticky;
1941
+ top: 0;
1942
+ z-index: 2;
1943
+ background: var(--panel);
1944
+ }
1945
+ .matrix .matrix-groups + tr th {
1946
+ top: 1.45rem;
1947
+ }
1948
+ /* The endpoint stays in view when the reader scrolls to the right. */
1949
+ .matrix th:first-child {
1950
+ position: sticky;
1951
+ left: 0;
1952
+ z-index: 1;
1953
+ background: var(--panel);
1954
+ box-shadow: 1px 0 0 var(--line);
1955
+ }
1956
+ .matrix thead th:first-child {
1957
+ z-index: 3;
1958
+ }
1959
+ .matrix.hide-skipped td.cell-skip > *,
1960
+ .matrix.hide-skipped td.cell-blocked > * {
1961
+ visibility: hidden;
1962
+ }
1963
+ .drawer {
1964
+ position: fixed;
1965
+ top: 64px;
1966
+ right: 1rem;
1967
+ bottom: 1rem;
1968
+ z-index: 15;
1969
+ width: min(560px, 45vw);
1970
+ padding: 1rem;
1971
+ overflow: auto;
1972
+ box-shadow: 0 10px 30px rgb(0 0 0 / 0.25);
1973
+ }
1974
+ .drawer .section-title h2 {
1975
+ font-size: 0.85rem;
1976
+ overflow-wrap: anywhere;
1977
+ }
1978
+ .drawer .section-title .badge {
1979
+ margin-left: auto;
1980
+ }
1981
+ .drawer pre.http {
1982
+ max-height: none;
1983
+ }
1984
+ .screen-table {
1985
+ margin-top: 0.25rem;
1986
+ }
1987
+ .screen-table .issue-count {
1988
+ float: none;
1989
+ }
1990
+
1991
+ .block {
1992
+ margin-bottom: 0.85rem;
1993
+ }