executable-stories-react 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -427,21 +427,29 @@ function DocLink({ entry }) {
427
427
  );
428
428
  }
429
429
 
430
- // src/components/doc/DocSection.tsx
430
+ // src/lib/markdown.ts
431
431
  var import_marked = require("marked");
432
432
 
433
433
  // src/lib/url.ts
434
434
  var import_url = require("executable-stories-core/utils/url");
435
435
 
436
- // src/components/doc/DocSection.tsx
437
- var import_jsx_runtime9 = require("react/jsx-runtime");
438
- function neutralizeUrl(value) {
439
- return (0, import_url.safeUrl)(value) ?? "#";
440
- }
436
+ // src/lib/markdown.ts
441
437
  function safeMarkdownHtml(markdown) {
442
438
  const raw = import_marked.marked.parse(markdown, { async: false });
443
439
  return raw.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<\/?(?:iframe|object|embed|form|base)\b[^>]*>/gi, "").replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, "").replace(/\son[a-z]+\s*=\s*'[^']*'/gi, "").replace(/\son[a-z]+\s*=\s*[^\s>]+/gi, "").replace(/(href|src)\s*=\s*"([^"]*)"/gi, (_m, attr, val) => `${attr}="${neutralizeUrl(val)}"`).replace(/(href|src)\s*=\s*'([^']*)'/gi, (_m, attr, val) => `${attr}='${neutralizeUrl(val)}'`);
444
440
  }
441
+ function dedent(text) {
442
+ const lines = text.replace(/\t/g, " ").split("\n");
443
+ const indents = lines.filter((line) => line.trim().length > 0).map((line) => line.length - line.trimStart().length);
444
+ const shortest = indents.length > 0 ? Math.min(...indents) : 0;
445
+ return lines.map((line) => line.slice(shortest)).join("\n").trim();
446
+ }
447
+ function neutralizeUrl(value) {
448
+ return (0, import_url.safeUrl)(value) ?? "#";
449
+ }
450
+
451
+ // src/components/doc/DocSection.tsx
452
+ var import_jsx_runtime9 = require("react/jsx-runtime");
445
453
  function DocSection({ entry }) {
446
454
  const renderers = useBuiltinRenderers();
447
455
  if (renderers.section) {
@@ -1409,8 +1417,35 @@ function ReportScenarioList({ feature }) {
1409
1417
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_jsx_runtime27.Fragment, { children: feature.scenarios.map((scenario) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReportScenario, { scenario }, scenario.id)) });
1410
1418
  }
1411
1419
 
1412
- // src/components/ReportFeature.tsx
1420
+ // src/components/ReportFeatureIntro.tsx
1413
1421
  var import_jsx_runtime28 = require("react/jsx-runtime");
1422
+ function ReportFeatureIntro({ feature }) {
1423
+ const hasNarrative = Boolean(feature.narrative?.trim());
1424
+ const hasGlossary = Boolean(feature.glossary?.length);
1425
+ if (!hasNarrative && !hasGlossary) return null;
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-3 border-l-2 border-border pl-4 text-sm", children: [
1427
+ hasNarrative ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1428
+ "div",
1429
+ {
1430
+ className: "es-doc-prose prose prose-sm max-w-none text-muted-foreground",
1431
+ dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
1432
+ }
1433
+ ) : null,
1434
+ hasGlossary ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
1435
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
1436
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
1437
+ ] }, entry.term)) }) : null
1438
+ ] });
1439
+ }
1440
+ function featureKindLabel(kind) {
1441
+ if (kind === "ability") return "Ability";
1442
+ if (kind === "business-need") return "Business need";
1443
+ if (kind === "feature") return "Feature";
1444
+ return null;
1445
+ }
1446
+
1447
+ // src/components/ReportFeature.tsx
1448
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1414
1449
  function ReportFeature({ feature }) {
1415
1450
  const titleId = `${feature.id}-title`;
1416
1451
  const bodyId = `${feature.id}-body`;
@@ -1418,10 +1453,11 @@ function ReportFeature({ feature }) {
1418
1453
  const skipped = s.skipped + s.pending;
1419
1454
  const collapse = useCollapse();
1420
1455
  const collapsed = collapse?.isCollapsed(feature.id) ?? false;
1456
+ const kindLabel = featureKindLabel(feature.kind);
1421
1457
  return (
1422
1458
  // Suite = a section heading + a divider, NOT another bordered card. Drops a
1423
1459
  // layer of nesting so the scenario cards below read as the primary unit.
1424
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1460
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1425
1461
  "section",
1426
1462
  {
1427
1463
  id: feature.id,
@@ -1429,9 +1465,9 @@ function ReportFeature({ feature }) {
1429
1465
  "aria-labelledby": titleId,
1430
1466
  className: "flex flex-col gap-3",
1431
1467
  children: [
1432
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1433
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0", children: [
1434
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1468
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-end justify-between gap-4 border-b border-border pb-2", children: [
1469
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0", children: [
1470
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h2", { id: titleId, className: "text-base font-semibold tracking-tight text-foreground", children: collapse ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1435
1471
  "button",
1436
1472
  {
1437
1473
  type: "button",
@@ -1440,31 +1476,34 @@ function ReportFeature({ feature }) {
1440
1476
  "aria-controls": bodyId,
1441
1477
  className: "flex w-full cursor-pointer items-center gap-2 text-left hover:text-foreground/80",
1442
1478
  children: [
1443
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1444
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "truncate", children: feature.title })
1479
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, className: cn("shrink-0 text-xs text-muted-foreground transition-transform", !collapsed && "rotate-90"), children: "\u25B8" }),
1480
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate", children: feature.title })
1445
1481
  ]
1446
1482
  }
1447
1483
  ) : feature.title }),
1448
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: cn("mt-0.5 truncate font-mono text-xs text-muted-foreground", collapse && "pl-5"), children: feature.sourceFile })
1484
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { className: cn("mt-0.5 flex items-center gap-2 text-xs text-muted-foreground", collapse && "pl-5"), children: [
1485
+ kindLabel ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "shrink-0 rounded-sm bg-muted px-1.5 py-0.5 font-medium text-foreground", children: kindLabel }) : null,
1486
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate font-mono", children: feature.sourceFile })
1487
+ ] })
1449
1488
  ] }),
1450
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1489
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1451
1490
  "p",
1452
1491
  {
1453
1492
  className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
1454
1493
  "aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
1455
1494
  children: [
1456
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { children: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
1457
1496
  s.passed,
1458
1497
  " passed"
1459
1498
  ] }),
1460
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1461
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1499
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1500
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: cn(s.failed > 0 && "font-medium text-fail"), children: [
1462
1501
  s.failed,
1463
1502
  " failed"
1464
1503
  ] }),
1465
- skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
1466
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1467
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { children: [
1504
+ skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
1505
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
1468
1507
  skipped,
1469
1508
  " skipped"
1470
1509
  ] })
@@ -1473,7 +1512,10 @@ function ReportFeature({ feature }) {
1473
1512
  }
1474
1513
  )
1475
1514
  ] }),
1476
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ReportScenarioList, { feature }) })
1515
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { id: bodyId, hidden: collapsed, className: "flex flex-col gap-3", children: [
1516
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportFeatureIntro, { feature }),
1517
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportScenarioList, { feature })
1518
+ ] })
1477
1519
  ]
1478
1520
  }
1479
1521
  )
@@ -1481,17 +1523,17 @@ function ReportFeature({ feature }) {
1481
1523
  }
1482
1524
 
1483
1525
  // src/components/ReportFeatureList.tsx
1484
- var import_jsx_runtime29 = require("react/jsx-runtime");
1526
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1485
1527
  function ReportFeatureList() {
1486
1528
  const report = useReport();
1487
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ReportFeature, { feature }, feature.id)) });
1529
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex flex-col gap-8", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReportFeature, { feature }, feature.id)) });
1488
1530
  }
1489
1531
 
1490
1532
  // src/components/ui/empty.tsx
1491
1533
  var import_class_variance_authority2 = require("class-variance-authority");
1492
- var import_jsx_runtime30 = require("react/jsx-runtime");
1534
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1493
1535
  function Empty({ className, ...props }) {
1494
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1536
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1495
1537
  "div",
1496
1538
  {
1497
1539
  "data-slot": "empty",
@@ -1504,7 +1546,7 @@ function Empty({ className, ...props }) {
1504
1546
  );
1505
1547
  }
1506
1548
  function EmptyHeader({ className, ...props }) {
1507
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1549
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1508
1550
  "div",
1509
1551
  {
1510
1552
  "data-slot": "empty-header",
@@ -1531,7 +1573,7 @@ var emptyMediaVariants = (0, import_class_variance_authority2.cva)(
1531
1573
  }
1532
1574
  );
1533
1575
  function EmptyTitle({ className, ...props }) {
1534
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1576
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1535
1577
  "div",
1536
1578
  {
1537
1579
  "data-slot": "empty-title",
@@ -1542,16 +1584,16 @@ function EmptyTitle({ className, ...props }) {
1542
1584
  }
1543
1585
 
1544
1586
  // src/components/ReportEmpty.tsx
1545
- var import_jsx_runtime31 = require("react/jsx-runtime");
1587
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1546
1588
  function ReportEmpty({ message }) {
1547
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1589
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { "aria-live": "polite", className: "border", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EmptyHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EmptyTitle, { children: message ?? "No scenarios in this report." }) }) });
1548
1590
  }
1549
1591
 
1550
1592
  // src/components/ReportSummary.tsx
1551
- var import_jsx_runtime32 = require("react/jsx-runtime");
1593
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1552
1594
  function ReportSummary({ className }) {
1553
1595
  const report = useReport();
1554
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1596
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1555
1597
  ReportSummaryView,
1556
1598
  {
1557
1599
  summary: report.summary,
@@ -1577,7 +1619,7 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1577
1619
  if (summary.pending > 0) {
1578
1620
  cards.push({ status: "pending", label: "Pending", value: summary.pending });
1579
1621
  }
1580
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1622
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1581
1623
  "dl",
1582
1624
  {
1583
1625
  className: cn(
@@ -1590,17 +1632,17 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1590
1632
  "aria-label": ariaLabel,
1591
1633
  children: cards.map((c) => {
1592
1634
  const tone = TONE[c.status];
1593
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1635
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1594
1636
  "div",
1595
1637
  {
1596
1638
  "data-status": c.status,
1597
1639
  className: "rounded-lg border bg-card px-4 py-3",
1598
1640
  children: [
1599
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1600
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("dt", { className: "flex items-center gap-1.5 font-mono text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: [
1642
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cn("size-1.5 shrink-0 rounded-full", tone.dot), "aria-hidden": "true" }),
1601
1643
  c.label
1602
1644
  ] }),
1603
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1645
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { className: cn("mt-2 text-3xl font-semibold leading-none tracking-tight tabular-nums", tone.num), children: c.value })
1604
1646
  ]
1605
1647
  },
1606
1648
  c.status
@@ -1663,7 +1705,7 @@ function prUrl(ci) {
1663
1705
  }
1664
1706
 
1665
1707
  // src/components/ReportMeta.tsx
1666
- var import_jsx_runtime33 = require("react/jsx-runtime");
1708
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1667
1709
  function ReportMeta() {
1668
1710
  const report = useReport();
1669
1711
  const items = [];
@@ -1686,13 +1728,13 @@ function ReportMeta() {
1686
1728
  const short = sha.slice(0, 8);
1687
1729
  items.push({
1688
1730
  label: "Commit",
1689
- value: url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1731
+ value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: short }) : short
1690
1732
  });
1691
1733
  }
1692
1734
  if (report.ci) {
1693
1735
  items.push({
1694
1736
  label: "CI",
1695
- value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1737
+ value: report.ci.url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("a", { href: report.ci.url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: [
1696
1738
  ciDisplayName(report.ci.name),
1697
1739
  report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""
1698
1740
  ] }) : `${ciDisplayName(report.ci.name)}${report.ci.buildNumber ? ` #${report.ci.buildNumber}` : ""}`
@@ -1703,7 +1745,7 @@ function ReportMeta() {
1703
1745
  const label = `#${report.ci.prNumber}`;
1704
1746
  items.push({
1705
1747
  label: "PR",
1706
- value: url ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1748
+ value: url ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("a", { href: url, target: "_blank", rel: "noreferrer noopener", className: linkClass, children: label }) : label
1707
1749
  });
1708
1750
  }
1709
1751
  if (items.length === 0) return null;
@@ -1711,50 +1753,50 @@ function ReportMeta() {
1711
1753
  // Run metadata is useful but secondary to "what failed" — tuck it into a
1712
1754
  // collapsed disclosure so it doesn't push the result down. Native <details>
1713
1755
  // so it works with no JS (the SSR/no-hydration report still toggles).
1714
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1715
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
1716
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1756
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("details", { "data-es-meta-card": true, className: "es-run-details group rounded-lg border border-border bg-card text-xs", children: [
1757
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("summary", { className: "flex cursor-pointer list-none select-none items-center gap-1.5 px-4 py-2 font-medium text-muted-foreground [&::-webkit-details-marker]:hidden", children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { "aria-hidden": true, className: "text-xs transition-transform group-open:rotate-90", children: "\u25B8" }),
1717
1759
  "Run details"
1718
1760
  ] }),
1719
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
1720
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dt", { className: "font-medium", children: item.label }),
1721
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
1761
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dl", { className: "flex flex-wrap gap-x-5 gap-y-2 border-t border-border px-4 py-3 text-muted-foreground", "aria-label": "Run metadata", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-baseline gap-1.5", children: [
1762
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dt", { className: "font-medium", children: item.label }),
1763
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: "font-mono text-foreground", children: item.value })
1722
1764
  ] }, item.label)) })
1723
1765
  ] })
1724
1766
  );
1725
1767
  }
1726
1768
 
1727
1769
  // src/components/ReportSchemaError.tsx
1728
- var import_jsx_runtime34 = require("react/jsx-runtime");
1770
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1729
1771
  function ReportSchemaError({ error }) {
1730
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1731
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("strong", { children: "Report could not be displayed." }) }),
1732
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { children: error.message }),
1733
- error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { children: [
1772
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("section", { className: "es-schema-error", role: "alert", "aria-live": "assertive", children: [
1773
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: "Report could not be displayed." }) }),
1774
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: error.message }),
1775
+ error.code === "SCHEMA_VERSION_MISMATCH" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
1734
1776
  "The report bundle is newer than this version of ",
1735
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("code", { children: "executable-stories-react" }),
1777
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("code", { children: "executable-stories-react" }),
1736
1778
  ". Upgrade the package, or regenerate the report with an older formatters CLI."
1737
1779
  ] }) : null,
1738
- error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("details", { children: [
1739
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("summary", { children: [
1780
+ error.issues && error.issues.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("details", { children: [
1781
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("summary", { children: [
1740
1782
  error.issues.length,
1741
1783
  " validation issue",
1742
1784
  error.issues.length === 1 ? "" : "s"
1743
1785
  ] }),
1744
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1786
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("pre", { children: error.issues.slice(0, 20).map((i) => `${i.path}: ${i.message}`).join("\n") })
1745
1787
  ] }) : null
1746
1788
  ] });
1747
1789
  }
1748
1790
 
1749
1791
  // src/components/ReportShell.tsx
1750
- var import_jsx_runtime35 = require("react/jsx-runtime");
1792
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1751
1793
  function ReportErrorShell({
1752
1794
  error,
1753
1795
  className,
1754
1796
  title,
1755
1797
  dataTheme
1756
1798
  }) {
1757
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ReportSchemaError, { error }) });
1799
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("main", { className: cn("es-report", className), "aria-label": title ?? "Test report", "data-theme": dataTheme, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ReportSchemaError, { error }) });
1758
1800
  }
1759
1801
 
1760
1802
  // src/interactive/ReportInteractive.tsx
@@ -1763,12 +1805,12 @@ var import_lucide_react5 = require("lucide-react");
1763
1805
  // src/components/ui/switch.tsx
1764
1806
  var React4 = require("react");
1765
1807
  var import_switch = require("@base-ui/react/switch");
1766
- var import_jsx_runtime36 = require("react/jsx-runtime");
1808
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1767
1809
  function Switch({
1768
1810
  className,
1769
1811
  ...props
1770
1812
  }) {
1771
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1813
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1772
1814
  import_switch.Switch.Root,
1773
1815
  {
1774
1816
  "data-slot": "switch",
@@ -1777,7 +1819,7 @@ function Switch({
1777
1819
  className
1778
1820
  ),
1779
1821
  ...props,
1780
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1822
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1781
1823
  import_switch.Switch.Thumb,
1782
1824
  {
1783
1825
  "data-slot": "switch-thumb",
@@ -1793,7 +1835,7 @@ var React5 = __toESM(require("react"), 1);
1793
1835
  var import_toggle_group = require("@base-ui/react/toggle-group");
1794
1836
  var import_toggle = require("@base-ui/react/toggle");
1795
1837
  var import_class_variance_authority3 = require("class-variance-authority");
1796
- var import_jsx_runtime37 = require("react/jsx-runtime");
1838
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1797
1839
  var toggleItemVariants = (0, import_class_variance_authority3.cva)(
1798
1840
  "inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap text-muted-foreground transition-[color,background-color,box-shadow] outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-background data-[pressed]:text-foreground data-[pressed]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1799
1841
  {
@@ -1815,13 +1857,13 @@ function ToggleGroup({
1815
1857
  children,
1816
1858
  ...props
1817
1859
  }) {
1818
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1860
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1819
1861
  import_toggle_group.ToggleGroup,
1820
1862
  {
1821
1863
  "data-slot": "toggle-group",
1822
1864
  className: cn("flex w-fit items-center gap-0.5 rounded-lg bg-muted p-0.5", className),
1823
1865
  ...props,
1824
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ToggleGroupContext.Provider, { value: { size }, children })
1866
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToggleGroupContext.Provider, { value: { size }, children })
1825
1867
  }
1826
1868
  );
1827
1869
  }
@@ -1832,7 +1874,7 @@ function ToggleGroupItem({
1832
1874
  ...props
1833
1875
  }) {
1834
1876
  const context = React5.useContext(ToggleGroupContext);
1835
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1877
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1836
1878
  import_toggle.Toggle,
1837
1879
  {
1838
1880
  "data-slot": "toggle-group-item",
@@ -1849,9 +1891,9 @@ var import_lucide_react3 = require("lucide-react");
1849
1891
 
1850
1892
  // src/components/ui/input.tsx
1851
1893
  var React6 = require("react");
1852
- var import_jsx_runtime38 = require("react/jsx-runtime");
1894
+ var import_jsx_runtime39 = require("react/jsx-runtime");
1853
1895
  function Input({ className, type, ...props }) {
1854
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1896
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1855
1897
  "input",
1856
1898
  {
1857
1899
  type,
@@ -1868,7 +1910,7 @@ function Input({ className, type, ...props }) {
1868
1910
  }
1869
1911
 
1870
1912
  // src/interactive/ReportSearch.tsx
1871
- var import_jsx_runtime39 = require("react/jsx-runtime");
1913
+ var import_jsx_runtime40 = require("react/jsx-runtime");
1872
1914
  var ReportSearch = (0, import_react8.forwardRef)(
1873
1915
  function ReportSearch2(props, ref) {
1874
1916
  const {
@@ -1890,17 +1932,17 @@ var ReportSearch = (0, import_react8.forwardRef)(
1890
1932
  e.preventDefault();
1891
1933
  }
1892
1934
  }
1893
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("es-search flex flex-col gap-1", className), children: [
1894
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
1895
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "relative w-full sm:w-72", children: [
1896
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1935
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("es-search flex flex-col gap-1", className), children: [
1936
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("label", { htmlFor: inputId, className: "sr-only", children: "Search" }),
1937
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "relative w-full sm:w-72", children: [
1938
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
1897
1939
  import_lucide_react3.Search,
1898
1940
  {
1899
1941
  "aria-hidden": true,
1900
1942
  className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"
1901
1943
  }
1902
1944
  ),
1903
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1945
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
1904
1946
  Input,
1905
1947
  {
1906
1948
  ref,
@@ -1917,7 +1959,7 @@ var ReportSearch = (0, import_react8.forwardRef)(
1917
1959
  }
1918
1960
  )
1919
1961
  ] }),
1920
- showCounts ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
1962
+ showCounts ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
1921
1963
  "span",
1922
1964
  {
1923
1965
  className: "text-xs tabular-nums text-muted-foreground",
@@ -2006,7 +2048,7 @@ function scrollToScenarioId(scenarioId, options = {}) {
2006
2048
  }
2007
2049
 
2008
2050
  // src/interactive/ReportFailureBanner.tsx
2009
- var import_jsx_runtime40 = require("react/jsx-runtime");
2051
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2010
2052
  function ReportFailureBanner({ failures }) {
2011
2053
  const first = failures[0];
2012
2054
  const jumpToFirst = (0, import_react9.useCallback)(() => {
@@ -2014,7 +2056,7 @@ function ReportFailureBanner({ failures }) {
2014
2056
  scrollToScenarioId(first.scenarioId);
2015
2057
  }, [first]);
2016
2058
  if (failures.length === 0) return null;
2017
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2059
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2018
2060
  "div",
2019
2061
  {
2020
2062
  className: "es-failure-banner",
@@ -2022,13 +2064,13 @@ function ReportFailureBanner({ failures }) {
2022
2064
  "aria-live": "polite",
2023
2065
  "aria-label": "Failure summary",
2024
2066
  children: [
2025
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "es-failure-banner-text", children: [
2026
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("strong", { children: failures.length }),
2067
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "es-failure-banner-text", children: [
2068
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: failures.length }),
2027
2069
  " ",
2028
2070
  "failure",
2029
2071
  failures.length === 1 ? "" : "s"
2030
2072
  ] }),
2031
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2073
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2032
2074
  "button",
2033
2075
  {
2034
2076
  type: "button",
@@ -2045,7 +2087,7 @@ function ReportFailureBanner({ failures }) {
2045
2087
 
2046
2088
  // src/interactive/ReportFreshness.tsx
2047
2089
  var import_react10 = require("react");
2048
- var import_jsx_runtime41 = require("react/jsx-runtime");
2090
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2049
2091
  function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
2050
2092
  const [now, setNow] = (0, import_react10.useState)(nowMs);
2051
2093
  (0, import_react10.useEffect)(() => {
@@ -2053,7 +2095,7 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
2053
2095
  }, [nowMs]);
2054
2096
  if (lastRunMs === void 0 || now === void 0) return null;
2055
2097
  const age = formatRelativeAge(lastRunMs, now);
2056
- const runLink = ciUrl ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2098
+ const runLink = ciUrl ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2057
2099
  "a",
2058
2100
  {
2059
2101
  href: ciUrl,
@@ -2064,9 +2106,9 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
2064
2106
  }
2065
2107
  ) : null;
2066
2108
  if (isReportStale(lastRunMs, staleAfterDays, now)) {
2067
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
2068
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { children: [
2069
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("strong", { children: [
2109
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "es-stale-banner", role: "status", "aria-label": "Report freshness", children: [
2110
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { children: [
2111
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("strong", { children: [
2070
2112
  "Last verified ",
2071
2113
  age,
2072
2114
  "."
@@ -2076,10 +2118,10 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
2076
2118
  runLink
2077
2119
  ] });
2078
2120
  }
2079
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
2121
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("p", { className: "es-freshness", "aria-label": "Report freshness", children: [
2080
2122
  "Verified ",
2081
2123
  age,
2082
- runLink ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
2124
+ runLink ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
2083
2125
  " \xB7 ",
2084
2126
  runLink
2085
2127
  ] }) : null
@@ -2087,15 +2129,15 @@ function ReportFreshness({ lastRunMs, ciUrl, staleAfterDays, nowMs }) {
2087
2129
  }
2088
2130
 
2089
2131
  // src/interactive/ReportLastRunDelta.tsx
2090
- var import_jsx_runtime42 = require("react/jsx-runtime");
2132
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2091
2133
  var MAX_LINKS = 5;
2092
2134
  function ScenarioLinks({ scenarios, tone }) {
2093
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
2094
- scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { children: [
2135
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
2136
+ scenarios.slice(0, MAX_LINKS).map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { children: [
2095
2137
  i > 0 ? ", " : "",
2096
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
2138
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("a", { href: `#${s.id}`, className: cn("underline underline-offset-2 hover:no-underline", tone), children: s.title })
2097
2139
  ] }, s.id)),
2098
- scenarios.length > MAX_LINKS ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { children: [
2140
+ scenarios.length > MAX_LINKS ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { children: [
2099
2141
  " and ",
2100
2142
  scenarios.length - MAX_LINKS,
2101
2143
  " more"
@@ -2112,23 +2154,23 @@ function ReportLastRunDelta({
2112
2154
  if (!delta) return null;
2113
2155
  const { newlyFailing, newlyPassing, added } = delta;
2114
2156
  if (newlyFailing.length === 0 && newlyPassing.length === 0 && added.length === 0) {
2115
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
2157
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: "Since last run: no behavior changes." });
2116
2158
  }
2117
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
2118
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-medium text-foreground", children: "Since last run:" }),
2119
- newlyFailing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "ml-2 text-fail", children: [
2159
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "es-last-run-delta", children: [
2160
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "font-medium text-foreground", children: "Since last run:" }),
2161
+ newlyFailing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2 text-fail", children: [
2120
2162
  newlyFailing.length,
2121
2163
  " newly failing (",
2122
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
2164
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ScenarioLinks, { scenarios: newlyFailing, tone: "text-fail" }),
2123
2165
  ")"
2124
2166
  ] }) : null,
2125
- newlyPassing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "ml-2 text-pass", children: [
2167
+ newlyPassing.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2 text-pass", children: [
2126
2168
  newlyPassing.length,
2127
2169
  " fixed (",
2128
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
2170
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ScenarioLinks, { scenarios: newlyPassing, tone: "text-pass" }),
2129
2171
  ")"
2130
2172
  ] }) : null,
2131
- added.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "ml-2", children: [
2173
+ added.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "ml-2", children: [
2132
2174
  added.length,
2133
2175
  " new"
2134
2176
  ] }) : null
@@ -2192,7 +2234,7 @@ function Button({
2192
2234
  }
2193
2235
 
2194
2236
  // src/interactive/ReportShortcutsHelp.tsx
2195
- var import_jsx_runtime43 = require("react/jsx-runtime");
2237
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2196
2238
  var SHORTCUTS = [
2197
2239
  { keys: "/", description: "Focus search" },
2198
2240
  { keys: "f", description: "Jump to next failure" },
@@ -2204,9 +2246,9 @@ var SHORTCUTS = [
2204
2246
  ];
2205
2247
  function Keys({ keys }) {
2206
2248
  const parts = keys.split(" ");
2207
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
2208
- i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
2209
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
2249
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "inline-flex items-center gap-1", children: parts.map((k, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
2250
+ i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", children: "+" }) : null,
2251
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("kbd", { className: "inline-flex h-6 min-w-6 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground", children: k })
2210
2252
  ] }, k)) });
2211
2253
  }
2212
2254
  function ReportShortcutsHelp({ open, onClose }) {
@@ -2217,7 +2259,7 @@ function ReportShortcutsHelp({ open, onClose }) {
2217
2259
  if (open && !dialog.open) dialog.showModal();
2218
2260
  else if (!open && dialog.open) dialog.close();
2219
2261
  }, [open]);
2220
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2262
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2221
2263
  "dialog",
2222
2264
  {
2223
2265
  ref: dialogRef,
@@ -2225,12 +2267,12 @@ function ReportShortcutsHelp({ open, onClose }) {
2225
2267
  "aria-label": "Keyboard shortcuts",
2226
2268
  onClose,
2227
2269
  children: [
2228
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
2229
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
2230
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("dt", { className: "justify-self-start", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Keys, { keys: s.keys }) }),
2231
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("dd", { className: "text-sm text-muted-foreground", children: s.description })
2270
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h2", { className: "text-base font-semibold", children: "Keyboard shortcuts" }),
2271
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dl", { className: "mt-4 grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2.5", children: SHORTCUTS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "col-span-2 grid grid-cols-subgrid items-center", children: [
2272
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dt", { className: "justify-self-start", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Keys, { keys: s.keys }) }),
2273
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dd", { className: "text-sm text-muted-foreground", children: s.description })
2232
2274
  ] }, s.keys)) }),
2233
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
2275
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("form", { method: "dialog", className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Button, { type: "submit", variant: "outline", size: "sm", children: "Close" }) })
2234
2276
  ]
2235
2277
  }
2236
2278
  );
@@ -2433,7 +2475,7 @@ function failuresFirst(report) {
2433
2475
 
2434
2476
  // src/interactive/ReportFilters.tsx
2435
2477
  var import_react14 = require("react");
2436
- var import_jsx_runtime44 = require("react/jsx-runtime");
2478
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2437
2479
  var TAG_LIMIT = 12;
2438
2480
  function ReportFilters({
2439
2481
  statuses,
@@ -2447,10 +2489,10 @@ function ReportFilters({
2447
2489
  if (statuses.length === 0 && tags.length === 0) return null;
2448
2490
  const tagsCollapsed = tags.length > TAG_LIMIT && !showAllTags;
2449
2491
  const visibleTags = tagsCollapsed ? tags.slice(0, TAG_LIMIT) : tags;
2450
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col gap-2", children: [
2451
- statuses.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
2492
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-col gap-2", children: [
2493
+ statuses.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { role: "group", "aria-label": "Filter by status", className: "flex flex-wrap gap-1", children: statuses.map((opt) => {
2452
2494
  const active = status === opt.key;
2453
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2495
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2454
2496
  "button",
2455
2497
  {
2456
2498
  type: "button",
@@ -2462,23 +2504,23 @@ function ReportFilters({
2462
2504
  ),
2463
2505
  children: [
2464
2506
  opt.label,
2465
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
2507
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ml-1 font-mono opacity-70", children: opt.count })
2466
2508
  ]
2467
2509
  },
2468
2510
  opt.key
2469
2511
  );
2470
2512
  }) }) : null,
2471
- tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
2513
+ tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("ul", { "aria-label": "Filter by tag", className: "flex flex-wrap items-center gap-1.5", children: [
2472
2514
  visibleTags.map((tag) => {
2473
2515
  const active = activeTags.includes(tag);
2474
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2516
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
2475
2517
  "button",
2476
2518
  {
2477
2519
  type: "button",
2478
2520
  "aria-pressed": active,
2479
2521
  onClick: () => onToggleTag(tag),
2480
2522
  className: "cursor-pointer",
2481
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2523
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
2482
2524
  Badge,
2483
2525
  {
2484
2526
  variant: "tag",
@@ -2491,7 +2533,7 @@ function ReportFilters({
2491
2533
  }
2492
2534
  ) }, tag);
2493
2535
  }),
2494
- tags.length > TAG_LIMIT ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2536
+ tags.length > TAG_LIMIT ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
2495
2537
  "button",
2496
2538
  {
2497
2539
  type: "button",
@@ -2507,7 +2549,7 @@ function ReportFilters({
2507
2549
 
2508
2550
  // src/interactive/ReportToc.tsx
2509
2551
  var import_react15 = require("react");
2510
- var import_jsx_runtime45 = require("react/jsx-runtime");
2552
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2511
2553
  var DOT = {
2512
2554
  passed: "bg-pass",
2513
2555
  failed: "bg-fail",
@@ -2536,11 +2578,11 @@ function TocContent({ onNavigate }) {
2536
2578
  return () => observer.disconnect();
2537
2579
  }, [scenarioIds]);
2538
2580
  if (report.features.length === 0) return null;
2539
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("li", { children: [
2540
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2541
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2581
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("ul", { className: "flex list-none flex-col gap-4 pl-0", children: report.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("li", { children: [
2582
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "mb-1.5 font-semibold leading-snug text-foreground", children: feature.title }),
2583
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("ul", { className: "flex list-none flex-col gap-0.5 pl-0", children: feature.scenarios.map((scenario) => {
2542
2584
  const active = activeId === scenario.id;
2543
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2585
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
2544
2586
  "a",
2545
2587
  {
2546
2588
  href: `#${scenario.id}`,
@@ -2555,14 +2597,14 @@ function TocContent({ onNavigate }) {
2555
2597
  active ? "border-primary font-medium text-foreground" : "border-border text-muted-foreground"
2556
2598
  ),
2557
2599
  children: [
2558
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
2600
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2559
2601
  "span",
2560
2602
  {
2561
2603
  "aria-hidden": true,
2562
2604
  className: cn("mt-1 size-1.5 shrink-0 rounded-full", DOT[scenario.status])
2563
2605
  }
2564
2606
  ),
2565
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "break-words", children: scenario.title })
2607
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "break-words", children: scenario.title })
2566
2608
  ]
2567
2609
  }
2568
2610
  ) }, scenario.id);
@@ -2572,14 +2614,14 @@ function TocContent({ onNavigate }) {
2572
2614
  function ReportToc() {
2573
2615
  const report = useReport();
2574
2616
  if (report.features.length === 0) return null;
2575
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2617
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
2576
2618
  "nav",
2577
2619
  {
2578
2620
  "aria-label": "Table of contents",
2579
2621
  className: "sticky top-4 hidden h-fit w-64 shrink-0 self-start text-xs lg:block",
2580
2622
  children: [
2581
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2582
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TocContent, {})
2623
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "mb-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Contents" }),
2624
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TocContent, {})
2583
2625
  ]
2584
2626
  }
2585
2627
  );
@@ -2589,31 +2631,31 @@ function ReportToc() {
2589
2631
  var import_react16 = require("react");
2590
2632
  var import_dialog = require("@base-ui/react/dialog");
2591
2633
  var import_lucide_react4 = require("lucide-react");
2592
- var import_jsx_runtime46 = require("react/jsx-runtime");
2634
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2593
2635
  function ReportTocDrawer() {
2594
2636
  const report = useReport();
2595
2637
  const [open, setOpen] = (0, import_react16.useState)(false);
2596
2638
  if (report.features.length === 0) return null;
2597
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_dialog.Dialog.Root, { open, onOpenChange: setOpen, children: [
2598
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_dialog.Dialog.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
2599
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react4.ListIcon, { "aria-hidden": true }),
2639
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Root, { open, onOpenChange: setOpen, children: [
2640
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Trigger, { className: "flex cursor-pointer items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:hidden [&_svg]:size-3.5", children: [
2641
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react4.ListIcon, { "aria-hidden": true }),
2600
2642
  " Contents"
2601
2643
  ] }),
2602
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_dialog.Dialog.Portal, { children: [
2603
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2604
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_dialog.Dialog.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
2605
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between", children: [
2606
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_dialog.Dialog.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2607
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2644
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Portal, { children: [
2645
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_dialog.Dialog.Backdrop, { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-200 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" }),
2646
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_dialog.Dialog.Popup, { className: "fixed inset-y-0 left-0 z-50 flex w-72 max-w-[80vw] flex-col gap-3 overflow-y-auto border-r border-border bg-background p-4 font-sans text-xs shadow-lg outline-none transition-transform duration-200 data-[ending-style]:-translate-x-full data-[starting-style]:-translate-x-full", children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
2648
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_dialog.Dialog.Title, { className: "text-xs font-semibold tracking-wide text-muted-foreground uppercase", children: "Contents" }),
2649
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2608
2650
  import_dialog.Dialog.Close,
2609
2651
  {
2610
2652
  "aria-label": "Close contents",
2611
2653
  className: "cursor-pointer rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground [&_svg]:size-4",
2612
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react4.XIcon, { "aria-hidden": true })
2654
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_lucide_react4.XIcon, { "aria-hidden": true })
2613
2655
  }
2614
2656
  )
2615
2657
  ] }),
2616
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TocContent, { onNavigate: () => setOpen(false) })
2658
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TocContent, { onNavigate: () => setOpen(false) })
2617
2659
  ] })
2618
2660
  ] })
2619
2661
  ] });
@@ -2696,14 +2738,14 @@ function useUrlState() {
2696
2738
  }
2697
2739
 
2698
2740
  // src/interactive/ReportInteractive.tsx
2699
- var import_jsx_runtime47 = require("react/jsx-runtime");
2741
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2700
2742
  function ReportInteractive(props) {
2701
2743
  const { report, className, title, dataTheme } = props;
2702
2744
  const result = unwrapReport(report);
2703
2745
  if (!result.ok) {
2704
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
2746
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportErrorShell, { error: result.error, className, title, dataTheme });
2705
2747
  }
2706
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportInteractiveView, { ...props, report: result.data });
2748
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportInteractiveView, { ...props, report: result.data });
2707
2749
  }
2708
2750
  var THEME_OPTIONS = [
2709
2751
  { value: "light", label: "Light", Icon: import_lucide_react5.Sun },
@@ -2711,7 +2753,7 @@ var THEME_OPTIONS = [
2711
2753
  { value: "dark", label: "Dark", Icon: import_lucide_react5.Moon }
2712
2754
  ];
2713
2755
  function ThemeSegment({ pref, onPref }) {
2714
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2756
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2715
2757
  ToggleGroup,
2716
2758
  {
2717
2759
  size: "sm",
@@ -2721,7 +2763,7 @@ function ThemeSegment({ pref, onPref }) {
2721
2763
  if (next) onPref(next);
2722
2764
  },
2723
2765
  "aria-label": "Color theme",
2724
- children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Icon, {}) }, value))
2766
+ children: THEME_OPTIONS.map(({ value, label, Icon }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ToggleGroupItem, { value, "aria-label": label, title: label, className: "px-2", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon, {}) }, value))
2725
2767
  }
2726
2768
  );
2727
2769
  }
@@ -2852,13 +2894,13 @@ function ReportInteractiveView({
2852
2894
  const totalScenarios = report.summary.total;
2853
2895
  const matchedScenarios = filtered.summary.total;
2854
2896
  const showToc = !hideToc && totalScenarios > 3;
2855
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2897
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(CollapseProvider, { value: collapse.api, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioActionsProvider, { value: scenarioActions, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScenarioHistoryProvider, { value: scenarioHistory ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2856
2898
  ReportRoot,
2857
2899
  {
2858
2900
  report: filtered,
2859
2901
  customRenderers,
2860
2902
  renderers,
2861
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
2903
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
2862
2904
  "main",
2863
2905
  {
2864
2906
  className: cn("es-report", "es-report-interactive", className),
@@ -2867,8 +2909,8 @@ function ReportInteractiveView({
2867
2909
  "data-theme": dataTheme,
2868
2910
  "data-detail-level": detail,
2869
2911
  children: [
2870
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("header", { className: "es-report-header", children: [
2871
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
2912
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("header", { className: "es-report-header", children: [
2913
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
2872
2914
  "div",
2873
2915
  {
2874
2916
  "data-es-navbar": true,
@@ -2877,9 +2919,9 @@ function ReportInteractiveView({
2877
2919
  hideHeader ? "justify-end" : "justify-between"
2878
2920
  ),
2879
2921
  children: [
2880
- hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h1", { className: "min-w-0", children: title ?? "Story Report" }),
2881
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
2882
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2922
+ hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h1", { className: "min-w-0", children: title ?? "Story Report" }),
2923
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
2924
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2883
2925
  ReportSearch,
2884
2926
  {
2885
2927
  ref: searchRef,
@@ -2889,16 +2931,16 @@ function ReportInteractiveView({
2889
2931
  totalCount: totalScenarios
2890
2932
  }
2891
2933
  ),
2892
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ThemeSegment, { pref: themePref, onPref: setThemePref })
2934
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeSegment, { pref: themePref, onPref: setThemePref })
2893
2935
  ] })
2894
2936
  ]
2895
2937
  }
2896
2938
  ),
2897
- hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
2898
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportSummary, {}),
2899
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportMeta, {})
2939
+ hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
2940
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportSummary, {}),
2941
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportMeta, {})
2900
2942
  ] }),
2901
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2943
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2902
2944
  ReportFreshness,
2903
2945
  {
2904
2946
  lastRunMs: reportLastRunMs(report),
@@ -2906,8 +2948,8 @@ function ReportInteractiveView({
2906
2948
  staleAfterDays
2907
2949
  }
2908
2950
  ),
2909
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportLastRunDelta, { history: scenarioHistory, report }),
2910
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2951
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportLastRunDelta, { history: scenarioHistory, report }),
2952
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2911
2953
  ReportFilters,
2912
2954
  {
2913
2955
  statuses: statusOptions,
@@ -2918,14 +2960,14 @@ function ReportInteractiveView({
2918
2960
  onToggleTag: toggleTag
2919
2961
  }
2920
2962
  ),
2921
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
2922
- showToc ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportTocDrawer, {}) : null,
2923
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
2924
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
2925
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
2963
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border/60 pt-3", children: [
2964
+ showToc ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportTocDrawer, {}) : null,
2965
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
2966
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Switch, { id: expandId, checked: expandedAll, onCheckedChange: setExpanded }),
2967
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { htmlFor: expandId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Expand all" })
2926
2968
  ] }),
2927
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
2928
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2969
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
2970
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2929
2971
  Switch,
2930
2972
  {
2931
2973
  id: docsId,
@@ -2933,16 +2975,16 @@ function ReportInteractiveView({
2933
2975
  onCheckedChange: (checked) => setDetail(checked ? "full" : "minimal")
2934
2976
  }
2935
2977
  ),
2936
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
2978
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("label", { htmlFor: docsId, className: "cursor-pointer text-sm text-muted-foreground select-none", children: "Show documentation" })
2937
2979
  ] })
2938
2980
  ] })
2939
2981
  ] }),
2940
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportFailureBanner, { failures }),
2941
- hasContent ? showToc ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-6", children: [
2942
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportToc, {}),
2943
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportFeatureList, {}) })
2944
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportFeatureList, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
2945
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2982
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFailureBanner, { failures }),
2983
+ hasContent ? showToc ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex gap-6", children: [
2984
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportToc, {}),
2985
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFeatureList, {}) })
2986
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportFeatureList, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportEmpty, { message: query ? "No scenarios match the search." : void 0 }),
2987
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2946
2988
  "button",
2947
2989
  {
2948
2990
  type: "button",
@@ -2953,8 +2995,8 @@ function ReportInteractiveView({
2953
2995
  children: "?"
2954
2996
  }
2955
2997
  ),
2956
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
2957
- toast ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2998
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ReportShortcutsHelp, { open: helpOpen, onClose: () => setHelpOpen(false) }),
2999
+ toast ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2958
3000
  "div",
2959
3001
  {
2960
3002
  role: "status",
@@ -2978,7 +3020,7 @@ var import_react21 = require("react");
2978
3020
 
2979
3021
  // src/components/doc/MermaidView.tsx
2980
3022
  var import_react20 = require("react");
2981
- var import_jsx_runtime48 = require("react/jsx-runtime");
3023
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2982
3024
  function prefersDark(el) {
2983
3025
  const themed = el?.closest("[data-theme]");
2984
3026
  if (themed?.dataset.theme === "dark") return true;
@@ -3032,9 +3074,9 @@ function MermaidView({ entry, load }) {
3032
3074
  };
3033
3075
  }, [entry.code, load]);
3034
3076
  if (svg) {
3035
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("figure", { ref, className: "my-3", children: [
3036
- entry.title ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
3037
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3077
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("figure", { ref, className: "my-3", children: [
3078
+ entry.title ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("figcaption", { className: "mb-1.5 text-xs font-medium text-muted-foreground", children: entry.title }) : null,
3079
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3038
3080
  "div",
3039
3081
  {
3040
3082
  role: "img",
@@ -3045,8 +3087,8 @@ function MermaidView({ entry, load }) {
3045
3087
  )
3046
3088
  ] });
3047
3089
  }
3048
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
3049
- error ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3090
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
3091
+ error ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3050
3092
  "p",
3051
3093
  {
3052
3094
  role: "alert",
@@ -3058,12 +3100,12 @@ function MermaidView({ entry, load }) {
3058
3100
  ]
3059
3101
  }
3060
3102
  ) : null,
3061
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(MermaidSource, { entry, ref })
3103
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MermaidSource, { entry, ref })
3062
3104
  ] });
3063
3105
  }
3064
3106
 
3065
3107
  // src/interactive/island-renderers.tsx
3066
- var import_jsx_runtime49 = require("react/jsx-runtime");
3108
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3067
3109
  var HLJS_ESM = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/es/highlight.min.js";
3068
3110
  var MERMAID_ESM = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
3069
3111
  function cachedCdnModule(url) {
@@ -3097,13 +3139,13 @@ function CdnHighlightedCode({ entry }) {
3097
3139
  cancelled = true;
3098
3140
  };
3099
3141
  }, [entry.content, entry.lang]);
3100
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3142
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(CodeFigure, { label: entry.label, children: html !== null ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3101
3143
  "code",
3102
3144
  {
3103
3145
  className: cn("hljs font-mono text-xs", entry.lang && `language-${entry.lang}`),
3104
3146
  dangerouslySetInnerHTML: { __html: html }
3105
3147
  }
3106
- ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
3148
+ ) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("code", { className: cn("font-mono text-xs", entry.lang && `language-${entry.lang}`), children: entry.content }) });
3107
3149
  }
3108
3150
  function buildIslandRenderers(opts) {
3109
3151
  const renderers = {};
@@ -3117,7 +3159,7 @@ function buildIslandRenderers(opts) {
3117
3159
  }
3118
3160
 
3119
3161
  // src/interactive/ReportInteractiveIsland.tsx
3120
- var import_jsx_runtime50 = require("react/jsx-runtime");
3162
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3121
3163
  function ReportInteractiveIsland({
3122
3164
  report,
3123
3165
  title,
@@ -3131,7 +3173,7 @@ function ReportInteractiveIsland({
3131
3173
  () => buildIslandRenderers({ syntaxHighlighting, mermaid }),
3132
3174
  [syntaxHighlighting, mermaid]
3133
3175
  );
3134
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3176
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3135
3177
  ReportInteractive,
3136
3178
  {
3137
3179
  report,