@diagrammo/dgmo 0.30.0 → 0.31.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.
Files changed (41) hide show
  1. package/README.md +21 -3
  2. package/dist/advanced.cjs +560 -269
  3. package/dist/advanced.d.cts +27 -2
  4. package/dist/advanced.d.ts +27 -2
  5. package/dist/advanced.js +559 -269
  6. package/dist/auto.cjs +558 -270
  7. package/dist/auto.js +93 -93
  8. package/dist/auto.mjs +558 -270
  9. package/dist/cli.cjs +144 -143
  10. package/dist/index.cjs +557 -269
  11. package/dist/index.js +557 -269
  12. package/package.json +1 -1
  13. package/src/advanced.ts +3 -0
  14. package/src/boxes-and-lines/layout-search.ts +214 -0
  15. package/src/boxes-and-lines/layout.ts +4 -0
  16. package/src/boxes-and-lines/parser.ts +78 -0
  17. package/src/boxes-and-lines/renderer.ts +57 -5
  18. package/src/boxes-and-lines/types.ts +9 -0
  19. package/src/c4/renderer.ts +7 -5
  20. package/src/chart-types.ts +2 -2
  21. package/src/class/renderer.ts +4 -2
  22. package/src/cli-banner.ts +107 -0
  23. package/src/cli.ts +13 -0
  24. package/src/colors.ts +22 -0
  25. package/src/er/renderer.ts +4 -2
  26. package/src/graph/flowchart-renderer.ts +4 -2
  27. package/src/graph/state-renderer.ts +4 -2
  28. package/src/infra/renderer.ts +8 -4
  29. package/src/journey-map/parser.ts +15 -1
  30. package/src/journey-map/renderer.ts +1 -1
  31. package/src/kanban/renderer.ts +1 -1
  32. package/src/map/renderer.ts +27 -14
  33. package/src/mindmap/renderer.ts +5 -3
  34. package/src/org/renderer.ts +67 -120
  35. package/src/palettes/color-utils.ts +7 -2
  36. package/src/pert/renderer.ts +13 -8
  37. package/src/raci/renderer.ts +1 -1
  38. package/src/sitemap/renderer.ts +35 -37
  39. package/src/utils/card.ts +183 -0
  40. package/src/utils/tag-groups.ts +10 -10
  41. package/src/utils/visual-conventions.ts +61 -0
package/dist/index.cjs CHANGED
@@ -320,7 +320,7 @@ function resolveColorWithDiagnostic(color, line11, diagnostics, palette) {
320
320
  );
321
321
  return void 0;
322
322
  }
323
- var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
323
+ var nord, colorNames, RECOGNIZED_COLOR_NAMES, CATEGORICAL_COLOR_ORDER, seriesColors;
324
324
  var init_colors = __esm({
325
325
  "src/colors.ts"() {
326
326
  "use strict";
@@ -378,6 +378,16 @@ var init_colors = __esm({
378
378
  "black",
379
379
  "white"
380
380
  ]);
381
+ CATEGORICAL_COLOR_ORDER = Object.freeze([
382
+ "red",
383
+ "green",
384
+ "blue",
385
+ "yellow",
386
+ "teal",
387
+ "purple",
388
+ "orange",
389
+ "cyan"
390
+ ]);
381
391
  seriesColors = [
382
392
  nord.nord10,
383
393
  // blue
@@ -1231,11 +1241,7 @@ var init_tag_groups = __esm({
1231
1241
  init_diagnostics();
1232
1242
  init_colors();
1233
1243
  AUTO_TAG_COLOR_SENTINEL = "";
1234
- autoTagColorCycle = Object.freeze(
1235
- RECOGNIZED_COLOR_NAMES.filter(
1236
- (n) => n !== "gray" && n !== "black" && n !== "white"
1237
- )
1238
- );
1244
+ autoTagColorCycle = CATEGORICAL_COLOR_ORDER;
1239
1245
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
1240
1246
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
1241
1247
  }
@@ -3025,7 +3031,7 @@ function shapeFill(palette, intent, isDark, opts) {
3025
3031
  }
3026
3032
  function getSeriesColors(palette) {
3027
3033
  const c = palette.colors;
3028
- return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];
3034
+ return CATEGORICAL_COLOR_ORDER.map((name) => c[name]);
3029
3035
  }
3030
3036
  function getSegmentColors(palette, count) {
3031
3037
  if (count <= 0) return [];
@@ -3078,6 +3084,7 @@ var POLITICAL_TINT_BANDS;
3078
3084
  var init_color_utils = __esm({
3079
3085
  "src/palettes/color-utils.ts"() {
3080
3086
  "use strict";
3087
+ init_colors();
3081
3088
  POLITICAL_TINT_BANDS = {
3082
3089
  light: [32, 48, 64, 80],
3083
3090
  dark: [44, 58, 72, 86]
@@ -11534,7 +11541,7 @@ var init_chart_types = __esm({
11534
11541
  },
11535
11542
  {
11536
11543
  id: "map",
11537
- description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
11544
+ description: "Geographic map: a value or count per country, state, or region (choropleth); points of interest; routes. Use when categories are real-world places."
11538
11545
  },
11539
11546
  // ── Tier 3 — Specialized analytical charts ────────────────
11540
11547
  {
@@ -11551,7 +11558,7 @@ var init_chart_types = __esm({
11551
11558
  },
11552
11559
  {
11553
11560
  id: "slope",
11554
- description: "Change between two periods"
11561
+ description: "Change for multiple things between exactly two periods"
11555
11562
  },
11556
11563
  {
11557
11564
  id: "sankey",
@@ -18989,6 +18996,7 @@ function parseBoxesAndLines(content, palette) {
18989
18996
  const nodes = [];
18990
18997
  const edges = [];
18991
18998
  const groups = [];
18999
+ const nodePositions = /* @__PURE__ */ new Map();
18992
19000
  const result = {
18993
19001
  type: "boxes-and-lines",
18994
19002
  title: null,
@@ -19022,6 +19030,8 @@ function parseBoxesAndLines(content, palette) {
19022
19030
  }
19023
19031
  const groupStack = [];
19024
19032
  let contentStarted = false;
19033
+ let inLayoutBlock = false;
19034
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
19025
19035
  let currentTagGroup = null;
19026
19036
  const metaAliasMap = /* @__PURE__ */ new Map();
19027
19037
  const nameAliasMap = /* @__PURE__ */ new Map();
@@ -19223,6 +19233,42 @@ function parseBoxesAndLines(content, palette) {
19223
19233
  if (currentTagGroup && indent === 0) {
19224
19234
  currentTagGroup = null;
19225
19235
  }
19236
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
19237
+ let isBlock = false;
19238
+ for (let j = i + 1; j < lines.length; j++) {
19239
+ const peek = lines[j];
19240
+ if (!peek.trim()) continue;
19241
+ isBlock = measureIndent2(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
19242
+ break;
19243
+ }
19244
+ if (isBlock) {
19245
+ flushDescription();
19246
+ closeGroupsToIndent(0);
19247
+ inLayoutBlock = true;
19248
+ continue;
19249
+ }
19250
+ }
19251
+ if (inLayoutBlock) {
19252
+ if (indent > 0) {
19253
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
19254
+ if (lm) {
19255
+ nodePositions.set(lm[1].trim(), {
19256
+ x: Number(lm[2]),
19257
+ y: Number(lm[3])
19258
+ });
19259
+ } else {
19260
+ result.diagnostics.push(
19261
+ makeDgmoError(
19262
+ lineNum,
19263
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
19264
+ "warning"
19265
+ )
19266
+ );
19267
+ }
19268
+ continue;
19269
+ }
19270
+ inLayoutBlock = false;
19271
+ }
19226
19272
  if (descState !== null) {
19227
19273
  if (indent > descState.indent) {
19228
19274
  if (trimmed.includes("->") || trimmed.includes("<->")) {
@@ -19475,6 +19521,22 @@ function parseBoxesAndLines(content, palette) {
19475
19521
  );
19476
19522
  }
19477
19523
  finalizeAutoTagColors(result.tagGroups);
19524
+ if (nodePositions.size > 0) {
19525
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
19526
+ for (const id of nodePositions.keys()) {
19527
+ if (!nodeLabelSet.has(id)) {
19528
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
19529
+ }
19530
+ }
19531
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
19532
+ if (unpositioned.length > 0) {
19533
+ pushWarning(
19534
+ 0,
19535
+ `layout block is partial \u2014 ${unpositioned.length} node(s) without coordinates (${unpositioned.slice(0, 5).join(", ")}${unpositioned.length > 5 ? "\u2026" : ""}); ignoring the block and auto-laying-out`
19536
+ );
19537
+ }
19538
+ result.nodePositions = nodePositions;
19539
+ }
19478
19540
  if (result.tagGroups.length > 0) {
19479
19541
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
19480
19542
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
@@ -21575,7 +21637,18 @@ function parseJourneyMap(content, palette) {
21575
21637
  }
21576
21638
  }
21577
21639
  } else {
21578
- personaName = afterKeyword;
21640
+ const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
21641
+ if (colorMatch) {
21642
+ personaName = colorMatch[1].trim();
21643
+ personaColor = resolveColorWithDiagnostic(
21644
+ colorMatch[2],
21645
+ lineNumber,
21646
+ result.diagnostics,
21647
+ palette
21648
+ ) ?? void 0;
21649
+ } else {
21650
+ personaName = afterKeyword;
21651
+ }
21579
21652
  }
21580
21653
  if (!personaName) {
21581
21654
  return fail(lineNumber, "persona requires a name");
@@ -24516,6 +24589,63 @@ var init_export_container = __esm({
24516
24589
  }
24517
24590
  });
24518
24591
 
24592
+ // src/utils/card.ts
24593
+ function renderNodeCard(container, opts) {
24594
+ const rect = container.append("rect").attr("x", 0).attr("y", 0).attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx).attr("fill", opts.fill).attr("stroke", opts.stroke).attr("stroke-width", opts.strokeWidth);
24595
+ if (opts.dashed) {
24596
+ rect.attr("stroke-dasharray", "6 3");
24597
+ }
24598
+ container.append("text").attr("x", opts.width / 2).attr("y", opts.headerHeight / 2 + opts.labelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", opts.labelColor).attr("font-size", opts.labelFontSize).attr("font-weight", "bold").text(opts.label);
24599
+ const meta = opts.meta;
24600
+ if (!meta || meta.rows.length === 0) return;
24601
+ container.append("line").attr("x1", 0).attr("y1", opts.headerHeight).attr("x2", opts.width).attr("y2", opts.headerHeight).attr("stroke", meta.separatorColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
24602
+ const keyX = meta.keyX ?? 10;
24603
+ const maxKeyWidth = Math.max(
24604
+ ...meta.rows.map(([key]) => measureText(`${key}: `, meta.fontSize))
24605
+ );
24606
+ const valueX = keyX + maxKeyWidth;
24607
+ const metaStartY = opts.headerHeight + meta.separatorGap + meta.fontSize;
24608
+ for (let i = 0; i < meta.rows.length; i++) {
24609
+ const [displayKey, value] = meta.rows[i];
24610
+ const rowY = metaStartY + i * meta.lineHeight;
24611
+ container.append("text").attr("x", keyX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(`${displayKey}: `);
24612
+ container.append("text").attr("x", valueX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(value);
24613
+ }
24614
+ }
24615
+ function renderCollapseBar(container, opts) {
24616
+ container.append("clipPath").attr("id", opts.clipId).append("rect").attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx);
24617
+ container.append("rect").attr("x", opts.inset).attr("y", opts.height - opts.barHeight).attr("width", opts.width - opts.inset * 2).attr("height", opts.barHeight).attr("fill", opts.fill).attr("clip-path", `url(#${opts.clipId})`).attr("class", opts.className);
24618
+ }
24619
+ var init_card = __esm({
24620
+ "src/utils/card.ts"() {
24621
+ "use strict";
24622
+ init_text_measure();
24623
+ }
24624
+ });
24625
+
24626
+ // src/utils/visual-conventions.ts
24627
+ var NODE_STROKE_WIDTH, EDGE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, COLLAPSE_BAR_INSET, HEADER_HEIGHT2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT2, SEPARATOR_GAP2, COLLAPSE_BAR_HEIGHT, CONTAINER_HEADER_HEIGHT, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2;
24628
+ var init_visual_conventions = __esm({
24629
+ "src/utils/visual-conventions.ts"() {
24630
+ "use strict";
24631
+ NODE_STROKE_WIDTH = 1.5;
24632
+ EDGE_STROKE_WIDTH = 1.5;
24633
+ CARD_RADIUS = 6;
24634
+ CONTAINER_RADIUS = 8;
24635
+ COLLAPSE_BAR_INSET = 0;
24636
+ HEADER_HEIGHT2 = 28;
24637
+ LABEL_FONT_SIZE2 = 13;
24638
+ META_FONT_SIZE2 = 11;
24639
+ META_LINE_HEIGHT2 = 16;
24640
+ SEPARATOR_GAP2 = 6;
24641
+ COLLAPSE_BAR_HEIGHT = 6;
24642
+ CONTAINER_HEADER_HEIGHT = 28;
24643
+ CONTAINER_LABEL_FONT_SIZE = 13;
24644
+ CONTAINER_META_FONT_SIZE = 11;
24645
+ CONTAINER_META_LINE_HEIGHT2 = 16;
24646
+ }
24647
+ });
24648
+
24519
24649
  // src/org/renderer.ts
24520
24650
  var renderer_exports = {};
24521
24651
  __export(renderer_exports, {
@@ -24673,9 +24803,16 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24673
24803
  }
24674
24804
  }
24675
24805
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
24676
- const clipId = `clip-${c.nodeId}`;
24677
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", sContainerRadius);
24678
- cG.append("rect").attr("x", sCollapseBarInset).attr("y", c.height - sCollapseBarHeight).attr("width", c.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr("fill", containerStroke(palette, colorOff ? void 0 : c.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24806
+ renderCollapseBar(cG, {
24807
+ width: c.width,
24808
+ height: c.height,
24809
+ barHeight: sCollapseBarHeight,
24810
+ inset: sCollapseBarInset,
24811
+ rx: sContainerRadius,
24812
+ fill: containerStroke(palette, colorOff ? void 0 : c.color),
24813
+ clipId: `clip-${c.nodeId}`,
24814
+ className: "org-collapse-bar"
24815
+ });
24679
24816
  }
24680
24817
  if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
24681
24818
  const iconSize = 14;
@@ -24726,42 +24863,48 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24726
24863
  solid
24727
24864
  );
24728
24865
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
24729
- const rect = nodeG.append("rect").attr("x", 0).attr("y", 0).attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sNodeStrokeWidth);
24730
- if (node.isContainer) {
24731
- rect.attr("stroke-dasharray", "6 3");
24732
- }
24733
24866
  const labelColor = contrastText(
24734
24867
  fill2,
24735
24868
  palette.textOnFillLight,
24736
24869
  palette.textOnFillDark
24737
24870
  );
24738
- nodeG.append("text").attr("x", node.width / 2).attr("y", sHeaderHeight / 2 + sLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", sLabelFontSize).attr("font-weight", "bold").text(node.label);
24739
24871
  const metaEntries = Object.entries(node.metadata);
24740
- if (metaEntries.length > 0) {
24741
- nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
24742
- const metaDisplayKeys = metaEntries.map(
24743
- ([k]) => displayNames.get(k) ?? k
24744
- );
24745
- const maxKeyWidth = Math.max(
24746
- ...metaDisplayKeys.map((k) => measureText(`${k}: `, sMetaFontSize))
24747
- );
24748
- const valueX = 10 + maxKeyWidth;
24749
- const metaStartY = sHeaderHeight + sSeparatorGap + sMetaFontSize;
24750
- for (let i = 0; i < metaEntries.length; i++) {
24751
- const [, value] = metaEntries[i];
24752
- const displayKey = metaDisplayKeys[i];
24753
- const rowY = metaStartY + i * sMetaLineHeight;
24754
- nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}: `);
24755
- nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(value);
24872
+ renderNodeCard(nodeG, {
24873
+ width: node.width,
24874
+ height: node.height,
24875
+ rx: sCardRadius,
24876
+ fill: fill2,
24877
+ stroke: stroke2,
24878
+ strokeWidth: sNodeStrokeWidth,
24879
+ ...node.isContainer && { dashed: true },
24880
+ label: node.label,
24881
+ labelColor,
24882
+ labelFontSize: sLabelFontSize,
24883
+ headerHeight: sHeaderHeight,
24884
+ ...metaEntries.length > 0 && {
24885
+ meta: {
24886
+ rows: metaEntries.map(
24887
+ ([k, value]) => [displayNames.get(k) ?? k, value]
24888
+ ),
24889
+ fontSize: sMetaFontSize,
24890
+ lineHeight: sMetaLineHeight,
24891
+ separatorGap: sSeparatorGap,
24892
+ separatorColor: solid ? labelColor : stroke2,
24893
+ textColor: labelColor
24894
+ }
24756
24895
  }
24757
- }
24896
+ });
24758
24897
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
24759
- const clipId = `clip-${node.id}`;
24760
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius);
24761
- nodeG.append("rect").attr("x", sCollapseBarInset).attr("y", node.height - sCollapseBarHeight).attr("width", node.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr(
24762
- "fill",
24763
- solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color)
24764
- ).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24898
+ renderCollapseBar(nodeG, {
24899
+ width: node.width,
24900
+ height: node.height,
24901
+ barHeight: sCollapseBarHeight,
24902
+ inset: sCollapseBarInset,
24903
+ rx: sCardRadius,
24904
+ fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
24905
+ clipId: `clip-${node.id}`,
24906
+ className: "org-collapse-bar"
24907
+ });
24765
24908
  }
24766
24909
  if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
24767
24910
  const iconSize = 14;
@@ -24905,7 +25048,7 @@ function renderOrgForExport(content, theme, palette) {
24905
25048
  return extractExportSvg(container, theme);
24906
25049
  });
24907
25050
  }
24908
- var d3Selection6, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
25051
+ var d3Selection6, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
24909
25052
  var init_renderer = __esm({
24910
25053
  "src/org/renderer.ts"() {
24911
25054
  "use strict";
@@ -24919,27 +25062,14 @@ var init_renderer = __esm({
24919
25062
  init_layout();
24920
25063
  init_legend_constants();
24921
25064
  init_legend_integration();
25065
+ init_card();
24922
25066
  init_text_measure();
24923
25067
  init_legend_layout();
24924
25068
  init_title_constants();
25069
+ init_visual_conventions();
24925
25070
  DIAGRAM_PADDING = 20;
24926
25071
  MAX_SCALE = 3;
24927
25072
  TITLE_HEIGHT = 30;
24928
- LABEL_FONT_SIZE2 = 13;
24929
- META_FONT_SIZE2 = 11;
24930
- META_LINE_HEIGHT2 = 16;
24931
- HEADER_HEIGHT2 = 28;
24932
- SEPARATOR_GAP2 = 6;
24933
- EDGE_STROKE_WIDTH = 1.5;
24934
- NODE_STROKE_WIDTH = 1.5;
24935
- CARD_RADIUS = 6;
24936
- CONTAINER_RADIUS = 8;
24937
- CONTAINER_LABEL_FONT_SIZE = 13;
24938
- CONTAINER_META_FONT_SIZE = 11;
24939
- CONTAINER_META_LINE_HEIGHT2 = 16;
24940
- CONTAINER_HEADER_HEIGHT = 28;
24941
- COLLAPSE_BAR_HEIGHT = 6;
24942
- COLLAPSE_BAR_INSET = 0;
24943
25073
  ANCESTOR_DOT_R = 4;
24944
25074
  ANCESTOR_LABEL_FONT_SIZE = 11;
24945
25075
  ANCESTOR_ROW_HEIGHT = 22;
@@ -25721,21 +25851,21 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25721
25851
  if (width <= 0 || height <= 0) return;
25722
25852
  const ctx = ScaleContext.identity();
25723
25853
  const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING2);
25724
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE4);
25725
- const sMetaFontSize = ctx.text(META_FONT_SIZE4);
25726
- const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT4);
25727
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT4);
25728
- const sSeparatorGap = ctx.structural(SEPARATOR_GAP4);
25729
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH2);
25730
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH2);
25854
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE2);
25855
+ const sMetaFontSize = ctx.text(META_FONT_SIZE2);
25856
+ const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT2);
25857
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT2);
25858
+ const sSeparatorGap = ctx.structural(SEPARATOR_GAP2);
25859
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
25860
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
25731
25861
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
25732
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE3);
25733
- const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE2);
25734
- const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT4);
25735
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT2);
25862
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
25863
+ const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE);
25864
+ const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT2);
25865
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
25736
25866
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
25737
25867
  const sTitleHeight = ctx.structural(TITLE_HEIGHT2);
25738
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT2);
25868
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
25739
25869
  const sLegendFixedGap = ctx.aesthetic(LEGEND_FIXED_GAP2);
25740
25870
  const hasLegend = layout.legend.length > 0;
25741
25871
  const layoutLegendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
@@ -25826,7 +25956,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25826
25956
  }
25827
25957
  const fill2 = containerFill2(palette, isDark, c.color);
25828
25958
  const stroke2 = containerStroke2(palette, c.color);
25829
- cG.append("rect").attr("x", 0).attr("y", 0).attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-opacity", 0.35).attr("stroke-width", sNodeStrokeWidth);
25959
+ cG.append("rect").attr("x", 0).attr("y", 0).attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-opacity", 0.35).attr("stroke-width", sNodeStrokeWidth);
25830
25960
  cG.append("text").attr("x", c.width / 2).attr("y", sContainerHeaderHeight / 2 + sContainerLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", sContainerLabelFontSize).attr("font-weight", "bold").text(c.label);
25831
25961
  const metaEntries = Object.entries(c.metadata);
25832
25962
  if (metaEntries.length > 0) {
@@ -25851,7 +25981,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25851
25981
  }
25852
25982
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
25853
25983
  const clipId = `clip-${c.nodeId}`;
25854
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2);
25984
+ cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
25855
25985
  cG.append("rect").attr("y", c.height - sCollapseBarHeight).attr("width", c.width).attr("height", sCollapseBarHeight).attr("fill", c.color ?? palette.primary).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
25856
25986
  cG.append("text").attr("x", c.width / 2).attr("y", c.height - sCollapseBarHeight - 6).attr("text-anchor", "middle").attr("fill", palette.textMuted).attr("font-size", sMetaFontSize).text(`+${c.hiddenCount}`);
25857
25987
  }
@@ -25890,13 +26020,23 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25890
26020
  const solid = parsed.options["solid-fill"] === "on";
25891
26021
  const fill2 = nodeFill2(palette, isDark, node.color, solid);
25892
26022
  const stroke2 = nodeStroke2(palette, node.color);
25893
- nodeG.append("rect").attr("x", 0).attr("y", 0).attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sNodeStrokeWidth);
25894
26023
  const labelColor = contrastText(
25895
26024
  fill2,
25896
26025
  palette.textOnFillLight,
25897
26026
  palette.textOnFillDark
25898
26027
  );
25899
- nodeG.append("text").attr("x", node.width / 2).attr("y", sHeaderHeight / 2 + sLabelFontSize / 2 - 2).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", sLabelFontSize).attr("font-weight", "bold").text(node.label);
26028
+ renderNodeCard(nodeG, {
26029
+ width: node.width,
26030
+ height: node.height,
26031
+ rx: CARD_RADIUS,
26032
+ fill: fill2,
26033
+ stroke: stroke2,
26034
+ strokeWidth: sNodeStrokeWidth,
26035
+ label: node.label,
26036
+ labelColor,
26037
+ labelFontSize: sLabelFontSize,
26038
+ headerHeight: sHeaderHeight
26039
+ });
25900
26040
  const metaEntries = Object.entries(node.metadata);
25901
26041
  if (metaEntries.length > 0) {
25902
26042
  nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3);
@@ -25931,7 +26071,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25931
26071
  }
25932
26072
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
25933
26073
  const clipId = `clip-${node.id}`;
25934
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2);
26074
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
25935
26075
  nodeG.append("rect").attr("y", node.height - sCollapseBarHeight).attr("width", node.width).attr("height", sCollapseBarHeight).attr("fill", solid ? labelColor : node.color ?? palette.primary).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
25936
26076
  }
25937
26077
  }
@@ -26061,7 +26201,7 @@ async function renderSitemapForExport(content, theme, palette) {
26061
26201
  document.body.removeChild(container);
26062
26202
  return svgHtml;
26063
26203
  }
26064
- var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE4, META_FONT_SIZE4, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE3, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26204
+ var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26065
26205
  var init_renderer2 = __esm({
26066
26206
  "src/sitemap/renderer.ts"() {
26067
26207
  "use strict";
@@ -26076,27 +26216,15 @@ var init_renderer2 = __esm({
26076
26216
  init_legend_integration();
26077
26217
  init_legend_layout();
26078
26218
  init_scaling();
26219
+ init_card();
26079
26220
  init_title_constants();
26221
+ init_visual_conventions();
26080
26222
  DIAGRAM_PADDING2 = 20;
26081
26223
  MAX_SCALE2 = 3;
26082
26224
  TITLE_HEIGHT2 = 30;
26083
- LABEL_FONT_SIZE4 = 13;
26084
- META_FONT_SIZE4 = 11;
26085
- META_LINE_HEIGHT4 = 16;
26086
- HEADER_HEIGHT4 = 28;
26087
- SEPARATOR_GAP4 = 6;
26088
- EDGE_STROKE_WIDTH2 = 1.5;
26089
- NODE_STROKE_WIDTH2 = 1.5;
26090
- CARD_RADIUS2 = 6;
26091
- CONTAINER_RADIUS2 = 8;
26092
- CONTAINER_LABEL_FONT_SIZE3 = 13;
26093
- CONTAINER_META_FONT_SIZE2 = 11;
26094
- CONTAINER_META_LINE_HEIGHT4 = 16;
26095
- CONTAINER_HEADER_HEIGHT2 = 28;
26096
26225
  ARROWHEAD_W = 10;
26097
26226
  ARROWHEAD_H = 7;
26098
26227
  EDGE_LABEL_FONT_SIZE = 11;
26099
- COLLAPSE_BAR_HEIGHT2 = 6;
26100
26228
  LEGEND_FIXED_GAP2 = 8;
26101
26229
  lineGenerator = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveBasis);
26102
26230
  lineGeneratorLinear = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveLinear);
@@ -26263,7 +26391,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
26263
26391
  const sCardMetaLineHeight = ctx.structural(CARD_META_LINE_HEIGHT);
26264
26392
  const sCardSeparatorGap = ctx.structural(CARD_SEPARATOR_GAP);
26265
26393
  const sCardGap = ctx.aesthetic(CARD_GAP);
26266
- const sCardRadius = ctx.structural(CARD_RADIUS3);
26394
+ const sCardRadius = ctx.structural(CARD_RADIUS);
26267
26395
  const sCardPaddingX = ctx.aesthetic(CARD_PADDING_X);
26268
26396
  const sCardPaddingY = ctx.aesthetic(CARD_PADDING_Y);
26269
26397
  const sCardStrokeWidth = ctx.structural(CARD_STROKE_WIDTH);
@@ -26643,7 +26771,7 @@ function computeSwimlaneLayout(parsed, buckets, baseLayout, collapsedLanes, coll
26643
26771
  const totalHeight = laneY - sLaneGap + sColumnPadding + sDiagramPadding;
26644
26772
  return { columnXs, lanes, totalWidth, totalHeight, startY };
26645
26773
  }
26646
- function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, isDark, activeTagGroup, collapsedLanes, collapsedColumns, hiddenMetaGroups, sDiagramPadding = DIAGRAM_PADDING3, sTitleHeight = TITLE_HEIGHT3, sLaneHeaderWidth = LANE_HEADER_WIDTH, sColumnGap = COLUMN_GAP, sCollapsedColumnWidth = COLLAPSED_COLUMN_WIDTH, sColumnHeaderHeight = COLUMN_HEADER_HEIGHT, sColumnPadding = COLUMN_PADDING, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardPaddingY = CARD_PADDING_Y, sCardGap = CARD_GAP, sCollapsedLaneHeight = COLLAPSED_LANE_HEIGHT, sLaneGap = LANE_GAP, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT, sColumnHeaderFontSize = COLUMN_HEADER_FONT_SIZE, sColumnRadius = COLUMN_RADIUS, sColumnHeaderRadius = COLUMN_HEADER_RADIUS, sWipFontSize = WIP_FONT_SIZE, sCardRadius = CARD_RADIUS3, sCardPaddingX = CARD_PADDING_X, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE) {
26774
+ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, isDark, activeTagGroup, collapsedLanes, collapsedColumns, hiddenMetaGroups, sDiagramPadding = DIAGRAM_PADDING3, sTitleHeight = TITLE_HEIGHT3, sLaneHeaderWidth = LANE_HEADER_WIDTH, sColumnGap = COLUMN_GAP, sCollapsedColumnWidth = COLLAPSED_COLUMN_WIDTH, sColumnHeaderHeight = COLUMN_HEADER_HEIGHT, sColumnPadding = COLUMN_PADDING, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardPaddingY = CARD_PADDING_Y, sCardGap = CARD_GAP, sCollapsedLaneHeight = COLLAPSED_LANE_HEIGHT, sLaneGap = LANE_GAP, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT, sColumnHeaderFontSize = COLUMN_HEADER_FONT_SIZE, sColumnRadius = COLUMN_RADIUS, sColumnHeaderRadius = COLUMN_HEADER_RADIUS, sWipFontSize = WIP_FONT_SIZE, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE) {
26647
26775
  const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
26648
26776
  const buckets = bucketCardsBySwimlane(visibleColumns, swimlaneGroup);
26649
26777
  const grid = computeSwimlaneLayout(
@@ -26783,7 +26911,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
26783
26911
  }
26784
26912
  }
26785
26913
  }
26786
- function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, solid, sCardRadius = CARD_RADIUS3, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
26914
+ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, solid, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
26787
26915
  const card = cardLayout.card;
26788
26916
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
26789
26917
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -26833,7 +26961,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
26833
26961
  }
26834
26962
  }
26835
26963
  }
26836
- var d3Selection8, DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_RADIUS3, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
26964
+ var d3Selection8, DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
26837
26965
  var init_renderer3 = __esm({
26838
26966
  "src/kanban/renderer.ts"() {
26839
26967
  "use strict";
@@ -26848,6 +26976,7 @@ var init_renderer3 = __esm({
26848
26976
  init_legend_integration();
26849
26977
  init_scaling();
26850
26978
  init_text_measure();
26979
+ init_visual_conventions();
26851
26980
  init_title_constants();
26852
26981
  DIAGRAM_PADDING3 = 20;
26853
26982
  COLUMN_GAP = 16;
@@ -26858,7 +26987,6 @@ var init_renderer3 = __esm({
26858
26987
  CARD_META_LINE_HEIGHT = 14;
26859
26988
  CARD_SEPARATOR_GAP = 4;
26860
26989
  CARD_GAP = 8;
26861
- CARD_RADIUS3 = 6;
26862
26990
  CARD_PADDING_X = 10;
26863
26991
  CARD_PADDING_Y = 6;
26864
26992
  CARD_STROKE_WIDTH = 1.5;
@@ -27159,8 +27287,8 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
27159
27287
  const sClassFontSize = ctx.text(CLASS_FONT_SIZE2);
27160
27288
  const sMemberFontSize = ctx.text(MEMBER_FONT_SIZE2);
27161
27289
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE2);
27162
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH3);
27163
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH3);
27290
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
27291
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27164
27292
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT2);
27165
27293
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y2);
27166
27294
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X);
@@ -27419,7 +27547,7 @@ function renderClassDiagramForExport(content, theme, palette) {
27419
27547
  return extractExportSvg(container, theme);
27420
27548
  });
27421
27549
  }
27422
- var d3Selection9, d3Shape3, DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27550
+ var d3Selection9, d3Shape3, DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27423
27551
  var init_renderer4 = __esm({
27424
27552
  "src/class/renderer.ts"() {
27425
27553
  "use strict";
@@ -27436,13 +27564,12 @@ var init_renderer4 = __esm({
27436
27564
  init_scaling();
27437
27565
  init_text_measure();
27438
27566
  init_note_box();
27567
+ init_visual_conventions();
27439
27568
  DIAGRAM_PADDING4 = 20;
27440
27569
  MAX_SCALE3 = 3;
27441
27570
  CLASS_FONT_SIZE2 = 13;
27442
27571
  MEMBER_FONT_SIZE2 = 11;
27443
27572
  EDGE_LABEL_FONT_SIZE2 = 11;
27444
- EDGE_STROKE_WIDTH3 = 1.5;
27445
- NODE_STROKE_WIDTH3 = 1.5;
27446
27573
  MEMBER_LINE_HEIGHT2 = 18;
27447
27574
  COMPARTMENT_PADDING_Y2 = 8;
27448
27575
  MEMBER_PADDING_X = 10;
@@ -27936,7 +28063,7 @@ function constraintIcon(constraint) {
27936
28063
  return "\u25CB";
27937
28064
  }
27938
28065
  }
27939
- function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH4) {
28066
+ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH) {
27940
28067
  const dx = point.x - prevPoint.x;
27941
28068
  const dy = point.y - prevPoint.y;
27942
28069
  const len = Math.sqrt(dx * dx + dy * dy);
@@ -27996,8 +28123,8 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
27996
28123
  const sTableFontSize = ctx.text(TABLE_FONT_SIZE2);
27997
28124
  const sColumnFontSize = ctx.text(COLUMN_FONT_SIZE2);
27998
28125
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE4);
27999
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH4);
28000
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH4);
28126
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
28127
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
28001
28128
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT4);
28002
28129
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y4);
28003
28130
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X2);
@@ -28275,7 +28402,7 @@ function renderERDiagramForExport(content, theme, palette) {
28275
28402
  document.body.removeChild(container);
28276
28403
  }
28277
28404
  }
28278
- var d3Selection10, d3Shape4, DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28405
+ var d3Selection10, d3Shape4, DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28279
28406
  var init_renderer5 = __esm({
28280
28407
  "src/er/renderer.ts"() {
28281
28408
  "use strict";
@@ -28294,13 +28421,12 @@ var init_renderer5 = __esm({
28294
28421
  init_parser9();
28295
28422
  init_layout4();
28296
28423
  init_classify();
28424
+ init_visual_conventions();
28297
28425
  DIAGRAM_PADDING5 = 20;
28298
28426
  MAX_SCALE4 = 3;
28299
28427
  TABLE_FONT_SIZE2 = 13;
28300
28428
  COLUMN_FONT_SIZE2 = 11;
28301
28429
  EDGE_LABEL_FONT_SIZE4 = 11;
28302
- EDGE_STROKE_WIDTH4 = 1.5;
28303
- NODE_STROKE_WIDTH4 = 1.5;
28304
28430
  MEMBER_LINE_HEIGHT4 = 18;
28305
28431
  COMPARTMENT_PADDING_Y4 = 8;
28306
28432
  MEMBER_PADDING_X2 = 10;
@@ -28528,9 +28654,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28528
28654
  const sDiagramPadding = sctx.aesthetic(DIAGRAM_PADDING6);
28529
28655
  const sMinNodeFontSize = sctx.text(MIN_NODE_FONT_SIZE);
28530
28656
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE5);
28531
- const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH5);
28532
- const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH5);
28533
- const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT3);
28657
+ const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH);
28658
+ const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH);
28659
+ const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT2);
28534
28660
  const sDescFontSize = sctx.text(DESC_FONT_SIZE);
28535
28661
  const sGroupLabelFontSize = sctx.text(GROUP_LABEL_FONT_SIZE);
28536
28662
  const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
@@ -28622,8 +28748,32 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28622
28748
  const scaleX = width / (contentW + sDiagramPadding * 2);
28623
28749
  const scaleY = height / (contentH + sDiagramPadding * 2);
28624
28750
  const scale = Math.min(scaleX, scaleY, 3);
28625
- const offsetX = (width - contentW * scale) / 2;
28626
- const offsetY = sDiagramPadding + titleOffset + legendH;
28751
+ let centerShiftX = 0;
28752
+ let centerShiftY = 0;
28753
+ if (parsed.nodePositions && parsed.nodePositions.size > 0) {
28754
+ let bMinX = Infinity, bMinY = Infinity, bMaxX = -Infinity, bMaxY = -Infinity;
28755
+ const accB = (x, y) => {
28756
+ if (x < bMinX) bMinX = x;
28757
+ if (x > bMaxX) bMaxX = x;
28758
+ if (y < bMinY) bMinY = y;
28759
+ if (y > bMaxY) bMaxY = y;
28760
+ };
28761
+ for (const n of layout.nodes) {
28762
+ accB(n.x - n.width / 2, n.y - n.height / 2);
28763
+ accB(n.x + n.width / 2, n.y + n.height / 2);
28764
+ }
28765
+ for (const g of layout.groups) {
28766
+ accB(g.x - g.width / 2, g.y - g.height / 2);
28767
+ accB(g.x + g.width / 2, g.y + g.height / 2);
28768
+ }
28769
+ for (const e of layout.edges) for (const p of e.points) accB(p.x, p.y);
28770
+ if (Number.isFinite(bMinX)) {
28771
+ centerShiftX = (layout.width - bMaxX - bMinX) / 2;
28772
+ centerShiftY = (layout.height - bMaxY - bMinY) / 2;
28773
+ }
28774
+ }
28775
+ const offsetX = (width - contentW * scale) / 2 + centerShiftX * scale;
28776
+ const offsetY = sDiagramPadding + titleOffset + legendH + centerShiftY * scale;
28627
28777
  const svg = d3Selection11.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").style("font-family", FONT_FAMILY).style("background", palette.bg);
28628
28778
  if (sctx.isBelowFloor) {
28629
28779
  svg.attr("width", "100%");
@@ -28759,7 +28909,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28759
28909
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
28760
28910
  edgeGroups.set(i, edgeG);
28761
28911
  const markerId = `bl-arrow-${color.replace("#", "")}`;
28762
- const gen = parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28912
+ const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28763
28913
  const path = edgeG.append("path").attr("class", "bl-edge").attr("d", gen(points) ?? "").attr("fill", "none").attr("stroke", color).attr("stroke-width", sEdgeStrokeWidth).attr("marker-end", `url(#${markerId})`);
28764
28914
  if (le.bidirectional) {
28765
28915
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
@@ -29040,7 +29190,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
29040
29190
  }
29041
29191
  });
29042
29192
  }
29043
- var d3Selection11, d3Shape5, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
29193
+ var d3Selection11, d3Shape5, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, NODE_RX, COLLAPSE_BAR_HEIGHT2, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB, lineGeneratorStraight;
29044
29194
  var init_renderer6 = __esm({
29045
29195
  "src/boxes-and-lines/renderer.ts"() {
29046
29196
  "use strict";
@@ -29058,14 +29208,13 @@ var init_renderer6 = __esm({
29058
29208
  init_wrapped_desc();
29059
29209
  init_scaling();
29060
29210
  init_text_measure();
29211
+ init_visual_conventions();
29061
29212
  DIAGRAM_PADDING6 = 20;
29062
29213
  NODE_FONT_SIZE = 11;
29063
29214
  MIN_NODE_FONT_SIZE = 9;
29064
29215
  EDGE_LABEL_FONT_SIZE5 = 11;
29065
- EDGE_STROKE_WIDTH5 = 1.5;
29066
- NODE_STROKE_WIDTH5 = 1.5;
29067
29216
  NODE_RX = 8;
29068
- COLLAPSE_BAR_HEIGHT3 = 4;
29217
+ COLLAPSE_BAR_HEIGHT2 = 4;
29069
29218
  ARROWHEAD_W2 = 5;
29070
29219
  ARROWHEAD_H2 = 4;
29071
29220
  DESC_FONT_SIZE = 10;
@@ -29079,6 +29228,7 @@ var init_renderer6 = __esm({
29079
29228
  VALUE_FONT_SIZE = 11;
29080
29229
  lineGeneratorLR = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29081
29230
  lineGeneratorTB = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29231
+ lineGeneratorStraight = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveLinear);
29082
29232
  }
29083
29233
  });
29084
29234
 
@@ -30266,6 +30416,156 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30266
30416
  return { x: rect.x + dx * s, y: rect.y + dy * s };
30267
30417
  };
30268
30418
  const isInsideRect = (p, rect) => Math.abs(p.x - rect.x) <= rect.w / 2 && Math.abs(p.y - rect.y) <= rect.h / 2;
30419
+ const pinned = parsed.nodePositions;
30420
+ const groupLabelSet = new Set(parsed.groups.map((g) => g.label));
30421
+ const groupsAreFlat = parsed.groups.every(
30422
+ (g) => !g.parentGroup && !g.children.some((c) => groupLabelSet.has(c))
30423
+ );
30424
+ const allOriginalGroupLabels = new Set(
30425
+ (collapseInfo?.originalGroups ?? parsed.groups).map((g) => g.label)
30426
+ );
30427
+ const collapsedAreFlatPinned = collapsedGroupLabels.size === 0 || pinned !== void 0 && collapseInfo !== void 0 && [...collapsedGroupLabels].every((label) => {
30428
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30429
+ if (!og || og.parentGroup) return false;
30430
+ return og.children.every(
30431
+ (c) => pinned.has(c) && !allOriginalGroupLabels.has(c)
30432
+ );
30433
+ });
30434
+ const allPinned = pinned !== void 0 && (parsed.nodes.length > 0 || collapsedGroupLabels.size > 0) && parsed.nodes.every((n2) => pinned.has(n2.label)) && groupsAreFlat && collapsedAreFlatPinned;
30435
+ function placePinned(pins) {
30436
+ const collapsedPosByGid = /* @__PURE__ */ new Map();
30437
+ const collapsedBoxes = [];
30438
+ if (collapseInfo)
30439
+ for (const label of collapsedGroupLabels) {
30440
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30441
+ if (!og) continue;
30442
+ let cx0 = Infinity, cy0 = Infinity, cx1 = -Infinity, cy1 = -Infinity;
30443
+ for (const c of og.children) {
30444
+ const p = pins.get(c);
30445
+ if (!p) continue;
30446
+ cx0 = Math.min(cx0, p.x);
30447
+ cx1 = Math.max(cx1, p.x);
30448
+ cy0 = Math.min(cy0, p.y);
30449
+ cy1 = Math.max(cy1, p.y);
30450
+ }
30451
+ if (!Number.isFinite(cx0)) continue;
30452
+ const cx = (cx0 + cx1) / 2;
30453
+ const cy = (cy0 + cy1) / 2;
30454
+ collapsedPosByGid.set(`__group_${label}`, { x: cx, y: cy });
30455
+ collapsedBoxes.push({
30456
+ label,
30457
+ lineNumber: og.lineNumber,
30458
+ childCount: collapseInfo.collapsedChildCounts.get(label) ?? og.children.length,
30459
+ x: cx,
30460
+ y: cy
30461
+ });
30462
+ }
30463
+ const posOf = (label) => pins.get(label) ?? collapsedPosByGid.get(label);
30464
+ const rectOf = (label) => {
30465
+ const p = posOf(label);
30466
+ const s = sizes.get(label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
30467
+ return { x: p.x, y: p.y, w: s.width, h: s.height };
30468
+ };
30469
+ const nodes = parsed.nodes.map((n2) => {
30470
+ const r = rectOf(n2.label);
30471
+ return { label: n2.label, x: r.x, y: r.y, width: r.w, height: r.h };
30472
+ });
30473
+ const edges = parsed.edges.flatMap((e) => {
30474
+ const sp = posOf(e.source);
30475
+ const tp = posOf(e.target);
30476
+ if (!sp || !tp) return [];
30477
+ const srcRect = rectOf(e.source);
30478
+ const tgtRect = rectOf(e.target);
30479
+ const p0 = rectBorderPoint(srcRect, tp);
30480
+ const p1 = rectBorderPoint(tgtRect, sp);
30481
+ return [
30482
+ {
30483
+ source: e.source,
30484
+ target: e.target,
30485
+ ...e.label !== void 0 && { label: e.label },
30486
+ bidirectional: e.bidirectional,
30487
+ lineNumber: e.lineNumber,
30488
+ points: [p0, p1],
30489
+ yOffset: 0,
30490
+ parallelCount: 1,
30491
+ metadata: e.metadata,
30492
+ straight: true
30493
+ }
30494
+ ];
30495
+ });
30496
+ const GROUP_PAD = 16;
30497
+ const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
30498
+ const groups = [];
30499
+ for (const grp of parsed.groups) {
30500
+ let gx0 = Infinity, gy0 = Infinity, gx1 = -Infinity, gy1 = -Infinity;
30501
+ for (const c of grp.children) {
30502
+ const n2 = nodeByLabel.get(c);
30503
+ if (!n2) continue;
30504
+ gx0 = Math.min(gx0, n2.x - n2.width / 2);
30505
+ gx1 = Math.max(gx1, n2.x + n2.width / 2);
30506
+ gy0 = Math.min(gy0, n2.y - n2.height / 2);
30507
+ gy1 = Math.max(gy1, n2.y + n2.height / 2);
30508
+ }
30509
+ if (!Number.isFinite(gx0)) continue;
30510
+ const x0 = gx0 - GROUP_PAD;
30511
+ const x1 = gx1 + GROUP_PAD;
30512
+ const y0 = gy0 - GROUP_LABEL_ZONE2;
30513
+ const y1 = gy1 + GROUP_PAD;
30514
+ groups.push({
30515
+ label: grp.label,
30516
+ lineNumber: grp.lineNumber,
30517
+ x: (x0 + x1) / 2,
30518
+ y: (y0 + y1) / 2,
30519
+ width: x1 - x0,
30520
+ height: y1 - y0,
30521
+ collapsed: false,
30522
+ childCount: grp.children.length
30523
+ });
30524
+ }
30525
+ for (const cb of collapsedBoxes) {
30526
+ groups.push({
30527
+ label: cb.label,
30528
+ lineNumber: cb.lineNumber,
30529
+ x: cb.x,
30530
+ y: cb.y,
30531
+ width: NODE_WIDTH,
30532
+ height: NODE_HEIGHT,
30533
+ collapsed: true,
30534
+ childCount: cb.childCount
30535
+ });
30536
+ }
30537
+ const M = 40;
30538
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
30539
+ const acc = (x, y) => {
30540
+ if (x < minX) minX = x;
30541
+ if (x > maxX) maxX = x;
30542
+ if (y < minY) minY = y;
30543
+ if (y > maxY) maxY = y;
30544
+ };
30545
+ for (const n2 of nodes) {
30546
+ acc(n2.x - n2.width / 2, n2.y - n2.height / 2);
30547
+ acc(n2.x + n2.width / 2, n2.y + n2.height / 2);
30548
+ }
30549
+ for (const e of edges) for (const p of e.points) acc(p.x, p.y);
30550
+ for (const gr of groups) {
30551
+ acc(gr.x - gr.width / 2, gr.y - gr.height / 2);
30552
+ acc(gr.x + gr.width / 2, gr.y + gr.height / 2);
30553
+ }
30554
+ const TOL = 2;
30555
+ const sx = minX < M - TOL ? M - minX : 0;
30556
+ const sy = minY < M - TOL ? M - minY : 0;
30557
+ const shifted = sx !== 0 || sy !== 0;
30558
+ return {
30559
+ nodes: shifted ? nodes.map((n2) => ({ ...n2, x: n2.x + sx, y: n2.y + sy })) : nodes,
30560
+ edges: shifted ? edges.map((e) => ({
30561
+ ...e,
30562
+ points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
30563
+ })) : edges,
30564
+ groups: shifted ? groups.map((gr) => ({ ...gr, x: gr.x + sx, y: gr.y + sy })) : groups,
30565
+ width: maxX + sx + M,
30566
+ height: maxY + sy + M
30567
+ };
30568
+ }
30269
30569
  function place(cfg) {
30270
30570
  const r = cfg.seed === void 0 ? null : rng2(cfg.seed + 1);
30271
30571
  const ord = (a) => r ? shuffle(a, r) : a.slice();
@@ -30404,6 +30704,7 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30404
30704
  height: gg.height ?? 600
30405
30705
  };
30406
30706
  }
30707
+ if (allPinned) return placePinned(pinned);
30407
30708
  const n = parsed.nodes.length;
30408
30709
  const seedCount = opts?.seeds ?? (n <= 12 ? 80 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
30409
30710
  const REFINE_K = opts?.refineK ?? 6;
@@ -30600,7 +30901,7 @@ function computeNodeSize(node, reserveValueRow) {
30600
30901
  }
30601
30902
  totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
30602
30903
  const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
30603
- const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30904
+ const totalHeight = labelHeight + SEPARATOR_GAP4 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30604
30905
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
30605
30906
  }
30606
30907
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
@@ -30729,7 +31030,7 @@ function applyParallelEdgeOffsets(layout) {
30729
31030
  }))
30730
31031
  };
30731
31032
  }
30732
- var MARGIN4, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
31033
+ var MARGIN4, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP4, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, VALUE_ROW_FONT, VALUE_ROW_H;
30733
31034
  var init_layout5 = __esm({
30734
31035
  "src/boxes-and-lines/layout.ts"() {
30735
31036
  "use strict";
@@ -30745,13 +31046,13 @@ var init_layout5 = __esm({
30745
31046
  DESC_FONT_SIZE2 = 10;
30746
31047
  DESC_LINE_HEIGHT2 = 1.4;
30747
31048
  DESC_PADDING = 8;
30748
- SEPARATOR_GAP5 = 4;
31049
+ SEPARATOR_GAP4 = 4;
30749
31050
  MAX_DESC_LINES2 = 6;
30750
31051
  MAX_LABEL_LINES = 3;
30751
31052
  LABEL_LINE_HEIGHT = 1.3;
30752
31053
  LABEL_PAD = 12;
30753
31054
  VALUE_ROW_FONT = 11;
30754
- VALUE_ROW_H = SEPARATOR_GAP5 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
31055
+ VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30755
31056
  }
30756
31057
  });
30757
31058
 
@@ -31512,11 +31813,11 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31512
31813
  });
31513
31814
  }
31514
31815
  for (const edge of renderLayout.edges) {
31515
- mainG.append("path").attr("class", "mindmap-edge").attr("d", edge.path).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", EDGE_STROKE_WIDTH6).attr("stroke-opacity", 0.5);
31816
+ mainG.append("path").attr("class", "mindmap-edge").attr("d", edge.path).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", EDGE_STROKE_WIDTH).attr("stroke-opacity", 0.5);
31516
31817
  }
31517
31818
  for (const node of renderLayout.nodes) {
31518
31819
  const isRoot = node.radius === 0 && renderLayout.nodes.indexOf(node) === 0;
31519
- const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH6;
31820
+ const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH;
31520
31821
  const effectiveColor = options?.colorByDepth ? depthColor(node.depth, palette) : node.color;
31521
31822
  const fill2 = nodeFill4(
31522
31823
  palette,
@@ -31599,7 +31900,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31599
31900
  const clipId = `collapse-clip-${node.id}`;
31600
31901
  const defs = mainG.append("defs");
31601
31902
  defs.append("clipPath").attr("id", clipId).append("rect").attr("x", node.x).attr("y", node.y).attr("width", node.width).attr("height", node.height).attr("rx", NODE_RADIUS).attr("ry", NODE_RADIUS);
31602
- nodeG.append("rect").attr("class", "collapse-bar").attr("x", node.x).attr("y", node.y + node.height - COLLAPSE_BAR_HEIGHT4).attr("width", node.width).attr("height", COLLAPSE_BAR_HEIGHT4).attr("fill", stroke2).attr("clip-path", `url(#${clipId})`);
31903
+ nodeG.append("rect").attr("class", "collapse-bar").attr("x", node.x).attr("y", node.y + node.height - COLLAPSE_BAR_HEIGHT).attr("width", node.width).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", stroke2).attr("clip-path", `url(#${clipId})`);
31603
31904
  }
31604
31905
  if (onClickItem) {
31605
31906
  nodeG.style("cursor", "pointer").on("click", (event) => {
@@ -31647,7 +31948,7 @@ function renderMindmapForExport(content, theme, palette) {
31647
31948
  return extractExportSvg(container, theme);
31648
31949
  });
31649
31950
  }
31650
- var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, NODE_STROKE_WIDTH6, EDGE_STROKE_WIDTH6, COLLAPSE_BAR_HEIGHT4, DEPTH_COLOR_KEYS;
31951
+ var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
31651
31952
  var init_renderer7 = __esm({
31652
31953
  "src/mindmap/renderer.ts"() {
31653
31954
  "use strict";
@@ -31665,6 +31966,7 @@ var init_renderer7 = __esm({
31665
31966
  init_legend_layout();
31666
31967
  init_title_constants();
31667
31968
  init_scaling();
31969
+ init_visual_conventions();
31668
31970
  DIAGRAM_PADDING7 = 20;
31669
31971
  TITLE_HEIGHT4 = 30;
31670
31972
  SINGLE_LABEL_HEIGHT2 = 28;
@@ -31672,9 +31974,6 @@ var init_renderer7 = __esm({
31672
31974
  DESC_LINE_HEIGHT4 = 14;
31673
31975
  NODE_RADIUS = 6;
31674
31976
  ROOT_STROKE_WIDTH = 2.5;
31675
- NODE_STROKE_WIDTH6 = 1.5;
31676
- EDGE_STROKE_WIDTH6 = 1.5;
31677
- COLLAPSE_BAR_HEIGHT4 = 6;
31678
31977
  DEPTH_COLOR_KEYS = [
31679
31978
  "red",
31680
31979
  "orange",
@@ -32902,10 +33201,10 @@ function computeC4NodeDimensions(el, options) {
32902
33201
  const metaEntries = collectCardMetadata(el.metadata);
32903
33202
  if (metaEntries.length > 0) {
32904
33203
  height2 += DIVIDER_GAP;
32905
- height2 += metaEntries.length * META_LINE_HEIGHT5;
33204
+ height2 += metaEntries.length * META_LINE_HEIGHT4;
32906
33205
  const maxMetaWidth = Math.max(
32907
33206
  ...metaEntries.map(
32908
- (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE5) + CARD_H_PAD3 * 2
33207
+ (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE4) + CARD_H_PAD3 * 2
32909
33208
  )
32910
33209
  );
32911
33210
  if (maxMetaWidth > width) width = Math.min(MAX_NODE_WIDTH, maxMetaWidth);
@@ -34182,7 +34481,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
34182
34481
  height: totalHeight
34183
34482
  };
34184
34483
  }
34185
- var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_FONT_SIZE5, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34484
+ var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT4, META_FONT_SIZE4, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34186
34485
  var init_layout8 = __esm({
34187
34486
  "src/c4/layout.ts"() {
34188
34487
  "use strict";
@@ -34201,8 +34500,8 @@ var init_layout8 = __esm({
34201
34500
  DESC_FONT_SIZE4 = 11;
34202
34501
  CARD_V_PAD3 = 14;
34203
34502
  CARD_H_PAD3 = 20;
34204
- META_LINE_HEIGHT5 = 16;
34205
- META_FONT_SIZE5 = 11;
34503
+ META_LINE_HEIGHT4 = 16;
34504
+ META_FONT_SIZE4 = 11;
34206
34505
  MARGIN6 = 40;
34207
34506
  BOUNDARY_PAD = 40;
34208
34507
  GROUP_BOUNDARY_PAD = 24;
@@ -34323,7 +34622,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34323
34622
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34324
34623
  const pathD = lineGenerator4(edge.points);
34325
34624
  if (pathD) {
34326
- const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH7).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34625
+ const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34327
34626
  if (dashed) {
34328
34627
  pathEl.attr("stroke-dasharray", "6 3");
34329
34628
  }
@@ -34389,7 +34688,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34389
34688
  palette.textOnFillLight,
34390
34689
  palette.textOnFillDark
34391
34690
  );
34392
- nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4).attr("ry", CARD_RADIUS4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34691
+ nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS).attr("ry", CARD_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34393
34692
  let yPos = -h / 2 + CARD_V_PAD4;
34394
34693
  const typeLabel = `\xAB${node.type}\xBB`;
34395
34694
  nodeG.append("text").attr("x", 0).attr("y", yPos + TYPE_FONT_SIZE / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", TYPE_FONT_SIZE).attr("font-style", "italic").text(typeLabel);
@@ -34433,7 +34732,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34433
34732
  }
34434
34733
  if (node.drillable) {
34435
34734
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34436
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4);
34735
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
34437
34736
  nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
34438
34737
  }
34439
34738
  }
@@ -34493,14 +34792,14 @@ function drawCylinderCard(nodeG, w, h, fill2, stroke2, dashed) {
34493
34792
  `A ${w / 2} ${ry} 0 0 1 ${-w / 2} ${h / 2 - ry}`,
34494
34793
  "Z"
34495
34794
  ].join(" ");
34496
- const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34795
+ const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34497
34796
  if (dashed) {
34498
34797
  el.attr("stroke-dasharray", "6 3");
34499
34798
  }
34500
- nodeG.append("ellipse").attr("cx", 0).attr("cy", -h / 2 + ry).attr("rx", w / 2).attr("ry", ry).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34799
+ nodeG.append("ellipse").attr("cx", 0).attr("cy", -h / 2 + ry).attr("rx", w / 2).attr("ry", ry).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34501
34800
  }
34502
34801
  function drawCardRect(nodeG, w, h, fill2, stroke2, dashed) {
34503
- const el = nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4).attr("ry", CARD_RADIUS4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34802
+ const el = nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS).attr("ry", CARD_RADIUS).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34504
34803
  if (dashed) {
34505
34804
  el.attr("stroke-dasharray", "6 3");
34506
34805
  }
@@ -34520,7 +34819,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
34520
34819
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34521
34820
  const pathD = lineGenerator4(edge.points);
34522
34821
  if (pathD) {
34523
- const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH7).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34822
+ const pathEl = edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH).attr("class", "c4-edge").attr("marker-end", "url(#c4-arrow-end)");
34524
34823
  if (dashed) {
34525
34824
  pathEl.attr("stroke-dasharray", "6 3");
34526
34825
  }
@@ -35015,13 +35314,13 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35015
35314
  nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD4 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD4 / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
35016
35315
  yPos += DIVIDER_GAP2;
35017
35316
  const maxKeyWidth = Math.max(
35018
- ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE6))
35317
+ ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE2))
35019
35318
  );
35020
35319
  const valueX = -w / 2 + CARD_H_PAD4 + maxKeyWidth;
35021
35320
  for (const entry of metaEntries) {
35022
- nodeG.append("text").attr("x", -w / 2 + CARD_H_PAD4).attr("y", yPos + META_FONT_SIZE6 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE6).text(`${entry.key}:`);
35023
- nodeG.append("text").attr("x", valueX).attr("y", yPos + META_FONT_SIZE6 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE6).text(entry.value);
35024
- yPos += META_LINE_HEIGHT6;
35321
+ nodeG.append("text").attr("x", -w / 2 + CARD_H_PAD4).attr("y", yPos + META_FONT_SIZE2 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE2).text(`${entry.key}:`);
35322
+ nodeG.append("text").attr("x", valueX).attr("y", yPos + META_FONT_SIZE2 / 2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", META_FONT_SIZE2).text(entry.value);
35323
+ yPos += META_LINE_HEIGHT2;
35025
35324
  }
35026
35325
  }
35027
35326
  } else {
@@ -35048,7 +35347,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35048
35347
  }
35049
35348
  if (node.drillable) {
35050
35349
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
35051
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS4);
35350
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
35052
35351
  nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
35053
35352
  }
35054
35353
  }
@@ -35177,7 +35476,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
35177
35476
  document.body.removeChild(el);
35178
35477
  }
35179
35478
  }
35180
- var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE6, TECH_FONT_SIZE, EDGE_STROKE_WIDTH7, NODE_STROKE_WIDTH7, CARD_RADIUS4, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, META_FONT_SIZE6, META_LINE_HEIGHT6, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
35479
+ var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE6, TECH_FONT_SIZE, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
35181
35480
  var init_renderer9 = __esm({
35182
35481
  "src/c4/renderer.ts"() {
35183
35482
  "use strict";
@@ -35193,6 +35492,7 @@ var init_renderer9 = __esm({
35193
35492
  init_legend_constants();
35194
35493
  init_legend_integration();
35195
35494
  init_title_constants();
35495
+ init_visual_conventions();
35196
35496
  DIAGRAM_PADDING8 = 20;
35197
35497
  MAX_SCALE5 = 3;
35198
35498
  TITLE_HEIGHT6 = 30;
@@ -35202,16 +35502,11 @@ var init_renderer9 = __esm({
35202
35502
  DESC_LINE_HEIGHT6 = 16;
35203
35503
  EDGE_LABEL_FONT_SIZE6 = 11;
35204
35504
  TECH_FONT_SIZE = 10;
35205
- EDGE_STROKE_WIDTH7 = 1.5;
35206
- NODE_STROKE_WIDTH7 = 1.5;
35207
- CARD_RADIUS4 = 6;
35208
35505
  CARD_H_PAD4 = 20;
35209
35506
  CARD_V_PAD4 = 14;
35210
35507
  TYPE_LABEL_HEIGHT2 = 18;
35211
35508
  DIVIDER_GAP2 = 6;
35212
35509
  NAME_HEIGHT2 = 20;
35213
- META_FONT_SIZE6 = 11;
35214
- META_LINE_HEIGHT6 = 16;
35215
35510
  BOUNDARY_LABEL_FONT_SIZE = 12;
35216
35511
  BOUNDARY_STROKE_WIDTH = 1.5;
35217
35512
  BOUNDARY_RADIUS = 8;
@@ -35615,7 +35910,7 @@ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff,
35615
35910
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
35616
35911
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
35617
35912
  }
35618
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35913
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35619
35914
  const w = node.width;
35620
35915
  const h = node.height;
35621
35916
  const rx = h / 2;
@@ -35627,7 +35922,7 @@ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeS
35627
35922
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
35628
35923
  ).attr("stroke-width", sNodeStrokeWidth);
35629
35924
  }
35630
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35925
+ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35631
35926
  const w = node.width;
35632
35927
  const h = node.height;
35633
35928
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -35646,7 +35941,7 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
35646
35941
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35647
35942
  ).attr("stroke-width", sNodeStrokeWidth);
35648
35943
  }
35649
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35944
+ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35650
35945
  const w = node.width / 2;
35651
35946
  const h = node.height / 2;
35652
35947
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -35668,7 +35963,7 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35668
35963
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35669
35964
  ).attr("stroke-width", sNodeStrokeWidth);
35670
35965
  }
35671
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW) {
35966
+ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
35672
35967
  const w = node.width / 2;
35673
35968
  const h = node.height / 2;
35674
35969
  const sk = sIoSkew;
@@ -35694,7 +35989,7 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
35694
35989
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35695
35990
  ).attr("stroke-width", sNodeStrokeWidth);
35696
35991
  }
35697
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sSubroutineInset = SUBROUTINE_INSET) {
35992
+ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
35698
35993
  const w = node.width;
35699
35994
  const h = node.height;
35700
35995
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -35712,7 +36007,7 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
35712
36007
  g.append("line").attr("x1", -w / 2 + sSubroutineInset).attr("y1", -h / 2).attr("x2", -w / 2 + sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
35713
36008
  g.append("line").attr("x1", w / 2 - sSubroutineInset).attr("y1", -h / 2).attr("x2", w / 2 - sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
35714
36009
  }
35715
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36010
+ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35716
36011
  const w = node.width;
35717
36012
  const h = node.height;
35718
36013
  const waveH = sDocWaveHeight;
@@ -35743,7 +36038,7 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35743
36038
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35744
36039
  ).attr("stroke-width", sNodeStrokeWidth);
35745
36040
  }
35746
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36041
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35747
36042
  switch (node.shape) {
35748
36043
  case "terminal":
35749
36044
  renderTerminal(
@@ -35830,8 +36125,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
35830
36125
  const sTitleY = ctx.structural(TITLE_Y);
35831
36126
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
35832
36127
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
35833
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH8);
35834
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH8);
36128
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
36129
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
35835
36130
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
35836
36131
  const sArrowheadH = ctx.structural(ARROWHEAD_H3);
35837
36132
  const sIoSkew = ctx.structural(IO_SKEW);
@@ -36055,7 +36350,7 @@ function renderFlowchartForExport(content, theme, palette) {
36055
36350
  document.body.removeChild(container);
36056
36351
  }
36057
36352
  }
36058
- var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, EDGE_STROKE_WIDTH8, NODE_STROKE_WIDTH8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36353
+ var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36059
36354
  var init_flowchart_renderer = __esm({
36060
36355
  "src/graph/flowchart-renderer.ts"() {
36061
36356
  "use strict";
@@ -36071,12 +36366,11 @@ var init_flowchart_renderer = __esm({
36071
36366
  init_scaling();
36072
36367
  init_text_measure();
36073
36368
  init_note_box();
36369
+ init_visual_conventions();
36074
36370
  DIAGRAM_PADDING9 = 20;
36075
36371
  MAX_SCALE6 = 3;
36076
36372
  NODE_FONT_SIZE2 = 13;
36077
36373
  EDGE_LABEL_FONT_SIZE7 = 11;
36078
- EDGE_STROKE_WIDTH8 = 1.5;
36079
- NODE_STROKE_WIDTH8 = 1.5;
36080
36374
  ARROWHEAD_W3 = 10;
36081
36375
  ARROWHEAD_H3 = 7;
36082
36376
  IO_SKEW = 15;
@@ -37060,7 +37354,7 @@ function hasRoles(node) {
37060
37354
  }
37061
37355
  function computeNodeWidth2(node, expanded, options) {
37062
37356
  const badgeVal = node.computedConcurrentInvocations === 0 && node.computedInstances > 1 ? node.computedInstances : 0;
37063
- const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE7) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37357
+ const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE5) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37064
37358
  const labelWidth2 = measureText(node.label, NODE_FONT_SIZE3) + badgeWidth + PADDING_X3;
37065
37359
  const allKeys = [];
37066
37360
  if (node.computedRps > 0) allKeys.push("RPS");
@@ -37107,7 +37401,7 @@ function computeNodeWidth2(node, expanded, options) {
37107
37401
  }
37108
37402
  if (allKeys.length === 0) return Math.max(MIN_NODE_WIDTH2, labelWidth2);
37109
37403
  const keyColWidth = Math.max(
37110
- ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE7))
37404
+ ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE5))
37111
37405
  );
37112
37406
  let maxRowWidth = 0;
37113
37407
  if (node.computedRps > 0) {
@@ -37120,7 +37414,7 @@ function computeNodeWidth2(node, expanded, options) {
37120
37414
  const rpsVal = effectiveCap > 0 && !node.isEdge ? `${formatRpsShort(node.computedRps)} / ${formatRpsShort(effectiveCap)}` : formatRps(node.computedRps);
37121
37415
  maxRowWidth = Math.max(
37122
37416
  maxRowWidth,
37123
- keyColWidth + measureText(rpsVal, META_FONT_SIZE7)
37417
+ keyColWidth + measureText(rpsVal, META_FONT_SIZE5)
37124
37418
  );
37125
37419
  }
37126
37420
  if (expanded) {
@@ -37137,7 +37431,7 @@ function computeNodeWidth2(node, expanded, options) {
37137
37431
  const valStr = p.key === "max-rps" || p.key === "ratelimit-rps" ? formatRpsShort(numVal) : p.key === "latency-ms" || p.key === "cb-latency-threshold-ms" || p.key === "duration-ms" || p.key === "cold-start-ms" ? formatMs(numVal) : PCT_KEYS.includes(p.key) ? `${numVal}%` : String(p.value);
37138
37432
  maxRowWidth = Math.max(
37139
37433
  maxRowWidth,
37140
- keyColWidth + measureText(valStr, META_FONT_SIZE7)
37434
+ keyColWidth + measureText(valStr, META_FONT_SIZE5)
37141
37435
  );
37142
37436
  }
37143
37437
  }
@@ -37148,7 +37442,7 @@ function computeNodeWidth2(node, expanded, options) {
37148
37442
  if (ms > 0) {
37149
37443
  maxRowWidth = Math.max(
37150
37444
  maxRowWidth,
37151
- keyColWidth + measureText(formatMs(ms), META_FONT_SIZE7)
37445
+ keyColWidth + measureText(formatMs(ms), META_FONT_SIZE5)
37152
37446
  );
37153
37447
  }
37154
37448
  }
@@ -37159,37 +37453,37 @@ function computeNodeWidth2(node, expanded, options) {
37159
37453
  const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
37160
37454
  maxRowWidth = Math.max(
37161
37455
  maxRowWidth,
37162
- keyColWidth + measureText(combinedVal, META_FONT_SIZE7)
37456
+ keyColWidth + measureText(combinedVal, META_FONT_SIZE5)
37163
37457
  );
37164
37458
  }
37165
37459
  }
37166
37460
  if (node.computedUptime < 1) {
37167
37461
  maxRowWidth = Math.max(
37168
37462
  maxRowWidth,
37169
- keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE7)
37463
+ keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE5)
37170
37464
  );
37171
37465
  }
37172
37466
  if (node.computedAvailability < 1) {
37173
37467
  maxRowWidth = Math.max(
37174
37468
  maxRowWidth,
37175
- keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE7)
37469
+ keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE5)
37176
37470
  );
37177
37471
  }
37178
37472
  if (node.computedCbState === "open") {
37179
37473
  maxRowWidth = Math.max(
37180
37474
  maxRowWidth,
37181
- measureText("CB: OPEN", META_FONT_SIZE7) + 8
37475
+ measureText("CB: OPEN", META_FONT_SIZE5) + 8
37182
37476
  );
37183
37477
  }
37184
37478
  }
37185
- const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE7;
37479
+ const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE5;
37186
37480
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
37187
37481
  let descWidth = 0;
37188
37482
  for (const dl of descLines) {
37189
- const truncated = truncateText(dl, META_FONT_SIZE7, DESC_MAX_WIDTH2);
37483
+ const truncated = truncateText(dl, META_FONT_SIZE5, DESC_MAX_WIDTH2);
37190
37484
  descWidth = Math.max(
37191
37485
  descWidth,
37192
- measureText(truncated, META_FONT_SIZE7) + PADDING_X3
37486
+ measureText(truncated, META_FONT_SIZE5) + PADDING_X3
37193
37487
  );
37194
37488
  }
37195
37489
  return Math.max(MIN_NODE_WIDTH2, labelWidth2, maxRowWidth + 20, descWidth);
@@ -37199,17 +37493,17 @@ function computeNodeHeight2(node, expanded, options) {
37199
37493
  const computedCount = countComputedRows(node, expanded);
37200
37494
  const hasRps = node.computedRps > 0;
37201
37495
  const descLineCount = expanded && node.description && !node.isEdge ? node.description.length : 0;
37202
- const descH = descLineCount * META_LINE_HEIGHT7;
37496
+ const descH = descLineCount * META_LINE_HEIGHT5;
37203
37497
  if (propCount === 0 && computedCount === 0 && !hasRps)
37204
37498
  return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
37205
37499
  let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
37206
37500
  const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
37207
- h += computedSectionCount * META_LINE_HEIGHT7;
37501
+ h += computedSectionCount * META_LINE_HEIGHT5;
37208
37502
  if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
37209
- h += propCount * META_LINE_HEIGHT7;
37503
+ h += propCount * META_LINE_HEIGHT5;
37210
37504
  if (hasRoles(node)) h += ROLE_DOT_ROW;
37211
37505
  h += NODE_PAD_BOTTOM;
37212
- if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT5;
37506
+ if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT3;
37213
37507
  return h;
37214
37508
  }
37215
37509
  function formatRps(rps) {
@@ -37544,7 +37838,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
37544
37838
  height: totalHeight
37545
37839
  };
37546
37840
  }
37547
- var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT5, NODE_FONT_SIZE3, META_FONT_SIZE7, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
37841
+ var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
37548
37842
  var init_layout10 = __esm({
37549
37843
  "src/infra/layout.ts"() {
37550
37844
  "use strict";
@@ -37552,13 +37846,13 @@ var init_layout10 = __esm({
37552
37846
  init_text_measure();
37553
37847
  MIN_NODE_WIDTH2 = 140;
37554
37848
  NODE_HEADER_HEIGHT = 28;
37555
- META_LINE_HEIGHT7 = 14;
37849
+ META_LINE_HEIGHT5 = 14;
37556
37850
  NODE_SEPARATOR_GAP = 4;
37557
37851
  NODE_PAD_BOTTOM = 10;
37558
37852
  ROLE_DOT_ROW = 12;
37559
- COLLAPSE_BAR_HEIGHT5 = 6;
37853
+ COLLAPSE_BAR_HEIGHT3 = 6;
37560
37854
  NODE_FONT_SIZE3 = 13;
37561
- META_FONT_SIZE7 = 10;
37855
+ META_FONT_SIZE5 = 10;
37562
37856
  EDGE_LABEL_FONT_SIZE8 = 11;
37563
37857
  PADDING_X3 = 24;
37564
37858
  GROUP_PADDING2 = 20;
@@ -37662,19 +37956,19 @@ __export(renderer_exports10, {
37662
37956
  function buildScaledConstants(ctx) {
37663
37957
  return {
37664
37958
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
37665
- sMetaFontSize: ctx.text(META_FONT_SIZE8),
37666
- sMetaLineHeight: ctx.structural(META_LINE_HEIGHT8),
37959
+ sMetaFontSize: ctx.text(META_FONT_SIZE6),
37960
+ sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
37667
37961
  sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
37668
37962
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
37669
37963
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
37670
- sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH9),
37671
- sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH9),
37964
+ sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
37965
+ sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH),
37672
37966
  sOverloadStrokeWidth: ctx.structural(OVERLOAD_STROKE_WIDTH),
37673
37967
  sRoleDotRadius: ctx.structural(ROLE_DOT_RADIUS),
37674
37968
  sNodeSeparatorGap: ctx.structural(NODE_SEPARATOR_GAP2),
37675
37969
  sNodePadBottom: ctx.structural(NODE_PAD_BOTTOM2),
37676
- sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT6),
37677
- sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET2),
37970
+ sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT),
37971
+ sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET),
37678
37972
  sParticleR: ctx.structural(PARTICLE_R),
37679
37973
  sRejectParticleR: ctx.structural(PARTICLE_R),
37680
37974
  sRejectDropDistance: ctx.structural(REJECT_DROP_DISTANCE),
@@ -37998,7 +38292,7 @@ function isWarning(node) {
37998
38292
  return cap > 0 && node.computedRps / cap > 0.7;
37999
38293
  }
38000
38294
  function truncateDesc(text) {
38001
- return truncateText(text, META_FONT_SIZE8, DESC_MAX_WIDTH);
38295
+ return truncateText(text, META_FONT_SIZE6, DESC_MAX_WIDTH);
38002
38296
  }
38003
38297
  function sloLatencyColor(p90, slo) {
38004
38298
  const t = slo.latencyP90 ?? 0;
@@ -38477,7 +38771,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38477
38771
  if (!isNodeCollapsed) {
38478
38772
  const expanded = expandedNodeIds?.has(node.id) ?? false;
38479
38773
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
38480
- const descH = descLines.length * META_LINE_HEIGHT8;
38774
+ const descH = descLines.length * META_LINE_HEIGHT6;
38481
38775
  for (let di = 0; di < descLines.length; di++) {
38482
38776
  const rawLine = descLines[di];
38483
38777
  const processed = preprocessDescriptionLine(rawLine);
@@ -38485,7 +38779,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38485
38779
  const isTruncated = descTruncated !== processed;
38486
38780
  const textEl = g.append("text").attr("x", node.x).attr(
38487
38781
  "y",
38488
- y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT8 + META_LINE_HEIGHT8 / 2 + sc.sMetaFontSize * 0.35
38782
+ y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT6 + META_LINE_HEIGHT6 / 2 + sc.sMetaFontSize * 0.35
38489
38783
  ).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sMetaFontSize).attr("fill", textFill);
38490
38784
  renderInlineText(textEl, descTruncated, palette, sc.sMetaFontSize);
38491
38785
  if (isTruncated) textEl.append("title").text(rawLine);
@@ -39003,7 +39297,7 @@ function parseAndLayoutInfra(content) {
39003
39297
  const layout = layoutInfra(computed);
39004
39298
  return { parsed, computed, layout };
39005
39299
  }
39006
- var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE8, META_LINE_HEIGHT8, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, EDGE_STROKE_WIDTH9, NODE_STROKE_WIDTH9, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, COLLAPSE_BAR_HEIGHT6, COLLAPSE_BAR_INSET2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
39300
+ var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
39007
39301
  var init_renderer10 = __esm({
39008
39302
  "src/infra/renderer.ts"() {
39009
39303
  "use strict";
@@ -39024,21 +39318,18 @@ var init_renderer10 = __esm({
39024
39318
  init_legend_layout();
39025
39319
  init_title_constants();
39026
39320
  init_scaling();
39321
+ init_visual_conventions();
39027
39322
  NODE_FONT_SIZE4 = 13;
39028
- META_FONT_SIZE8 = 10;
39029
- META_LINE_HEIGHT8 = 14;
39323
+ META_FONT_SIZE6 = 10;
39324
+ META_LINE_HEIGHT6 = 14;
39030
39325
  EDGE_LABEL_FONT_SIZE9 = 11;
39031
39326
  GROUP_LABEL_FONT_SIZE2 = 14;
39032
39327
  NODE_BORDER_RADIUS = 8;
39033
- EDGE_STROKE_WIDTH9 = 1.5;
39034
- NODE_STROKE_WIDTH9 = 1.5;
39035
39328
  OVERLOAD_STROKE_WIDTH = 3;
39036
39329
  ROLE_DOT_RADIUS = 3;
39037
39330
  NODE_HEADER_HEIGHT2 = 28;
39038
39331
  NODE_SEPARATOR_GAP2 = 4;
39039
39332
  NODE_PAD_BOTTOM2 = 10;
39040
- COLLAPSE_BAR_HEIGHT6 = 6;
39041
- COLLAPSE_BAR_INSET2 = 0;
39042
39333
  LEGEND_FIXED_GAP3 = 16;
39043
39334
  SPEED_BADGE_H_PAD = 5;
39044
39335
  SPEED_BADGE_V_PAD = 3;
@@ -39077,7 +39368,7 @@ var init_renderer10 = __esm({
39077
39368
  partitions: "partitions"
39078
39369
  };
39079
39370
  DESC_MAX_CHARS = 120;
39080
- DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE8;
39371
+ DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE6;
39081
39372
  RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
39082
39373
  MS_FORMAT_KEYS = /* @__PURE__ */ new Set([
39083
39374
  "latency-ms",
@@ -40864,18 +41155,18 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
40864
41155
  const sLegendPillHeight = ctx.structural(LEGEND_PILL_HEIGHT);
40865
41156
  const sLegendBlockHeight = showTagLegend ? sLegendTopGap + sLegendPillHeight + sLegendBottomGap : 0;
40866
41157
  const sNodeRadius = ctx.structural(NODE_RADIUS2);
40867
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH10);
41158
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
40868
41159
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE5);
40869
41160
  const sNodeCellFontSize = ctx.text(NODE_CELL_FONT_SIZE2);
40870
41161
  const sNodeTopRowHeight = ctx.structural(NODE_TOP_ROW_HEIGHT);
40871
41162
  const sNodeBottomRowHeight = ctx.structural(NODE_BOTTOM_ROW_HEIGHT);
40872
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH10);
41163
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
40873
41164
  const sArrowheadW = ctx.structural(ARROWHEAD_W4);
40874
41165
  const sArrowheadH = ctx.structural(ARROWHEAD_H4);
40875
- const sContainerRadius = ctx.structural(CONTAINER_RADIUS3);
40876
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE4);
40877
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT3);
40878
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT7);
41166
+ const sContainerRadius = ctx.structural(CONTAINER_RADIUS);
41167
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
41168
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
41169
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
40879
41170
  const sPinIconW = ctx.structural(PIN_ICON_W);
40880
41171
  const sPinIconH = ctx.structural(PIN_ICON_H);
40881
41172
  const scaledWidth = layout.width + sDiagramPad * 2;
@@ -41442,7 +41733,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41442
41733
  palette.textOnFillDark
41443
41734
  );
41444
41735
  const sNR = sc.nodeRadius ?? NODE_RADIUS2;
41445
- const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT7;
41736
+ const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT;
41446
41737
  drawTextbookCard(g, {
41447
41738
  width: grp.width,
41448
41739
  height: grp.height,
@@ -41476,10 +41767,10 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41476
41767
  g.append("rect").attr("class", "pert-collapse-bar").attr("x", grp.x).attr("y", grp.y + grp.height - sCBH).attr("width", grp.width).attr("height", sCBH).attr("fill", cardBaseColor).attr("clip-path", `url(#${clipId})`);
41477
41768
  continue;
41478
41769
  }
41479
- const sCR = sc.containerRadius ?? CONTAINER_RADIUS3;
41480
- const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE4;
41481
- const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT3;
41482
- const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41770
+ const sCR = sc.containerRadius ?? CONTAINER_RADIUS;
41771
+ const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE;
41772
+ const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT;
41773
+ const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH;
41483
41774
  g.append("rect").attr("x", grp.x).attr("y", grp.y).attr("width", grp.width).attr("height", grp.height).attr("rx", sCR).attr("ry", sCR).attr("fill", containerFill3).attr("stroke", containerStroke3).attr("stroke-opacity", 0.35).attr("stroke-width", sNSW);
41484
41775
  g.append("text").attr("x", grp.x + grp.width / 2).attr("y", grp.y + sCHH / 2 + sCLFS / 2 - 2).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("fill", palette.text).attr("font-size", sCLFS).attr("font-weight", "bold").text(label);
41485
41776
  }
@@ -41532,7 +41823,7 @@ function renderEdges2(root, resolved, layout, palette, collapsedSet, sc = {}) {
41532
41823
  }
41533
41824
  const path = lineGenerator6(e.points);
41534
41825
  if (!path) continue;
41535
- const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH10;
41826
+ const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH;
41536
41827
  const sELFS = sc.edgeLabelFontSize ?? 10;
41537
41828
  layer.append("path").attr("class", "pert-edge").attr("d", path).attr("fill", "none").attr("stroke", bandColor(band, palette, palette.textMuted)).attr("stroke-width", sESW).attr("marker-end", `url(#${bandArrow(band)})`).attr("data-source", e.source).attr("data-target", e.target).attr("data-critical", String(isCritical)).attr("data-critical-path", String(isCritical)).attr("data-criticality-band", band ?? "");
41538
41829
  const parsedEdge = edgeByKey.get(`${e.source}->${e.target}`);
@@ -41714,7 +42005,7 @@ function computeDurationEmphasis(activities) {
41714
42005
  function drawTextbookCard(g, a) {
41715
42006
  const { width: w, height: h, x, y } = a;
41716
42007
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41717
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42008
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41718
42009
  const sTRH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41719
42010
  const sBRH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41720
42011
  const sNFS = a.sNodeFontSize ?? NODE_FONT_SIZE5;
@@ -41813,7 +42104,7 @@ function drawTextbookCard(g, a) {
41813
42104
  function drawMilestonePill(g, a) {
41814
42105
  const { width: w, height: h, x, y } = a;
41815
42106
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41816
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42107
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41817
42108
  const topRowH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41818
42109
  const botRowH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41819
42110
  const sNCFS = a.sNodeCellFontSize ?? NODE_CELL_FONT_SIZE2;
@@ -41946,7 +42237,7 @@ function renderCaptionBlock(svg, bullets, args) {
41946
42237
  palette.textOnFillDark
41947
42238
  );
41948
42239
  const block = svg.append("g").attr("class", "pert-caption-block").attr("data-pert-caption", "");
41949
- block.append("rect").attr("class", "pert-caption-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42240
+ block.append("rect").attr("class", "pert-caption-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
41950
42241
  block.append("text").attr("class", "pert-caption-header").attr("x", x + width / 2).attr("y", y + CAPTION_BOX_PADDING_Y + CAPTION_FONT_SIZE).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", CAPTION_FONT_SIZE).attr("font-weight", "700").text("Summary");
41951
42242
  const textX = x + CAPTION_BOX_PADDING_X;
41952
42243
  const firstBaselineY = y + CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT + CAPTION_FONT_SIZE;
@@ -42063,7 +42354,7 @@ function renderTornadoBlock(svg, rows, args) {
42063
42354
  palette.textOnFillDark
42064
42355
  );
42065
42356
  const block = svg.append("g").attr("class", "pert-tornado-block").attr("data-pert-tornado", "");
42066
- block.append("rect").attr("class", "pert-tornado-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42357
+ block.append("rect").attr("class", "pert-tornado-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
42067
42358
  block.append("text").attr("class", "pert-tornado-header").attr("x", x + width / 2).attr("y", y + CAPTION_BOX_PADDING_Y + CAPTION_FONT_SIZE).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", CAPTION_FONT_SIZE).attr("font-weight", "700").text("Activity Risk");
42068
42359
  const fmt = (v) => {
42069
42360
  const r = Math.round(v * 100) / 100;
@@ -42219,7 +42510,7 @@ function renderScurveBlock(svg, data, args) {
42219
42510
  palette.textOnFillDark
42220
42511
  );
42221
42512
  const block = svg.append("g").attr("class", "pert-scurve-block").attr("data-pert-scurve", "");
42222
- block.append("rect").attr("class", "pert-scurve-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH10);
42513
+ block.append("rect").attr("class", "pert-scurve-rect").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("rx", NODE_RADIUS2).attr("ry", NODE_RADIUS2).attr("fill", fill2).attr("stroke", chromeStroke).attr("stroke-width", NODE_STROKE_WIDTH);
42223
42514
  const hasTitle = typeof title === "string" && title.length > 0;
42224
42515
  if (hasTitle) {
42225
42516
  const titleText = title.replace(/\.$/, "");
@@ -42403,7 +42694,7 @@ function formatScurveDate(iso) {
42403
42694
  if (month < 0 || month > 11 || isNaN(day)) return iso;
42404
42695
  return `${SCURVE_MONTH_NAMES[month]} ${day}`;
42405
42696
  }
42406
- var d3Selection17, d3Shape9, DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_STROKE_WIDTH10, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, EDGE_STROKE_WIDTH10, ARROWHEAD_W4, ARROWHEAD_H4, CONTAINER_RADIUS3, CONTAINER_LABEL_FONT_SIZE4, CONTAINER_HEADER_HEIGHT3, COLLAPSE_BAR_HEIGHT7, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42697
+ var d3Selection17, d3Shape9, DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, ARROWHEAD_W4, ARROWHEAD_H4, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42407
42698
  var init_renderer11 = __esm({
42408
42699
  "src/pert/renderer.ts"() {
42409
42700
  "use strict";
@@ -42421,20 +42712,15 @@ var init_renderer11 = __esm({
42421
42712
  init_analyzer();
42422
42713
  init_layout11();
42423
42714
  init_internal();
42715
+ init_visual_conventions();
42424
42716
  DIAGRAM_PADDING11 = 20;
42425
42717
  NODE_FONT_SIZE5 = 13;
42426
42718
  NODE_CELL_FONT_SIZE2 = 11;
42427
42719
  NODE_RADIUS2 = 6;
42428
- NODE_STROKE_WIDTH10 = 1.5;
42429
42720
  NODE_TOP_ROW_HEIGHT = 26;
42430
42721
  NODE_BOTTOM_ROW_HEIGHT = 26;
42431
- EDGE_STROKE_WIDTH10 = 1.5;
42432
42722
  ARROWHEAD_W4 = 10;
42433
42723
  ARROWHEAD_H4 = 7;
42434
- CONTAINER_RADIUS3 = 8;
42435
- CONTAINER_LABEL_FONT_SIZE4 = 13;
42436
- CONTAINER_HEADER_HEIGHT3 = 28;
42437
- COLLAPSE_BAR_HEIGHT7 = 6;
42438
42724
  DURATION_FADE_OPACITY = 0.55;
42439
42725
  PIN_ICON_W = 13;
42440
42726
  PIN_ICON_H = 13;
@@ -45425,8 +45711,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
45425
45711
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
45426
45712
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
45427
45713
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
45428
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH11);
45429
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH11);
45714
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
45715
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
45430
45716
  const sArrowheadW = ctx.structural(ARROWHEAD_W5);
45431
45717
  const sArrowheadH = ctx.structural(ARROWHEAD_H5);
45432
45718
  const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
@@ -45703,7 +45989,7 @@ function renderStateForExport(content, theme, palette) {
45703
45989
  document.body.removeChild(container);
45704
45990
  }
45705
45991
  }
45706
- var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, EDGE_STROKE_WIDTH11, NODE_STROKE_WIDTH11, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
45992
+ var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
45707
45993
  var init_state_renderer = __esm({
45708
45994
  "src/graph/state-renderer.ts"() {
45709
45995
  "use strict";
@@ -45719,13 +46005,12 @@ var init_state_renderer = __esm({
45719
46005
  init_scaling();
45720
46006
  init_text_measure();
45721
46007
  init_note_box();
46008
+ init_visual_conventions();
45722
46009
  DIAGRAM_PADDING12 = 20;
45723
46010
  MAX_SCALE7 = 3;
45724
46011
  NODE_FONT_SIZE6 = 13;
45725
46012
  EDGE_LABEL_FONT_SIZE10 = 11;
45726
46013
  GROUP_LABEL_FONT_SIZE3 = 11;
45727
- EDGE_STROKE_WIDTH11 = 1.5;
45728
- NODE_STROKE_WIDTH11 = 1.5;
45729
46014
  ARROWHEAD_W5 = 10;
45730
46015
  ARROWHEAD_H5 = 7;
45731
46016
  PSEUDOSTATE_RADIUS = 10;
@@ -47438,14 +47723,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47438
47723
  const panelY = PADDING2;
47439
47724
  const textX = panelX + CARD_PADDING_X3;
47440
47725
  const clipId = "persona-clip";
47441
- defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5);
47726
+ defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
47442
47727
  const personaFill = shapeFill(palette, personaColor, isDark, { solid });
47443
47728
  const onPersonaText = contrastText(
47444
47729
  personaFill,
47445
47730
  palette.textOnFillLight,
47446
47731
  palette.textOnFillDark
47447
47732
  );
47448
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", personaFill);
47733
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
47449
47734
  if (descLines.length > 0) {
47450
47735
  personaG.append("line").attr("x1", panelX + 1).attr("x2", panelX + panelWidth - silhouetteZone).attr("y1", panelY + titleRowH).attr("y2", panelY + titleRowH).attr("stroke", solid ? onPersonaText : personaColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
47451
47736
  }
@@ -47453,7 +47738,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47453
47738
  const silY = panelY + panelHeight / 2 - 6;
47454
47739
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
47455
47740
  renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
47456
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
47741
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
47457
47742
  personaG.append("text").attr("x", textX).attr("y", panelY + CARD_PADDING_Y3 + FONT_SIZE_STEP).attr("font-size", FONT_SIZE_STEP).attr("font-weight", "500").attr("fill", onPersonaText).text(parsed.persona.name);
47458
47743
  for (let li = 0; li < descLines.length; li++) {
47459
47744
  const lineEl = personaG.append("text").attr("x", textX).attr("y", panelY + titleRowH + descLineH * (li + 1)).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
@@ -47693,7 +47978,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47693
47978
  { solid }
47694
47979
  );
47695
47980
  const rowStroke = stepColor ?? palette.textMuted;
47696
- itemG.append("rect").attr("x", listX).attr("y", itemY).attr("width", cardW).attr("height", COLLAPSED_CARD_H).attr("rx", CARD_RADIUS5).attr("fill", rowFill).attr("stroke", rowStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
47981
+ itemG.append("rect").attr("x", listX).attr("y", itemY).attr("width", cardW).attr("height", COLLAPSED_CARD_H).attr("rx", CARD_RADIUS).attr("fill", rowFill).attr("stroke", rowStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
47697
47982
  const faceCx = listX + CARD_PADDING_X3 + COLLAPSED_FACE_R;
47698
47983
  const faceCy = itemY + COLLAPSED_CARD_H / 2;
47699
47984
  if (step.score !== void 0) {
@@ -47856,7 +48141,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47856
48141
  const scoreColor = scoreToColor(score, palette);
47857
48142
  const tintedBg = mix(scoreColor, palette.surface, 20);
47858
48143
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
47859
- g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS5).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48144
+ g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
47860
48145
  g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy - FACE_RADIUS - 1).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
47861
48146
  const centerX = bx + bw / 2;
47862
48147
  for (let i = 0; i < lines.length; i++) {
@@ -48013,7 +48298,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48013
48298
  palette.textOnFillLight,
48014
48299
  palette.textOnFillDark
48015
48300
  );
48016
- stepG.append("rect").attr("x", cx).attr("y", cy).attr("width", sl.width).attr("height", sl.height).attr("rx", CARD_RADIUS5).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48301
+ stepG.append("rect").attr("x", cx).attr("y", cy).attr("width", sl.width).attr("height", sl.height).attr("rx", CARD_RADIUS).attr("fill", cardFill).attr("stroke", cardStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
48017
48302
  const titleMaxW = sl.width - CARD_PADDING_X3 * 2;
48018
48303
  const titleLines = wrapTextToWidth(sl.step.title, FONT_SIZE_STEP, titleMaxW);
48019
48304
  for (let i = 0; i < titleLines.length; i++) {
@@ -48072,7 +48357,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48072
48357
  const stripFill = shapeFill(palette, stripColor, isDark, {
48073
48358
  ...solid !== void 0 && { solid }
48074
48359
  });
48075
- stepG.append("rect").attr("x", cx).attr("y", stripY).attr("width", sl.width).attr("height", TAG_STRIP_HEIGHT).attr("rx", CARD_RADIUS5).attr("fill", stripFill).attr("stroke", stripColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48360
+ stepG.append("rect").attr("x", cx).attr("y", stripY).attr("width", sl.width).attr("height", TAG_STRIP_HEIGHT).attr("rx", CARD_RADIUS).attr("fill", stripFill).attr("stroke", stripColor).attr("stroke-width", CARD_STROKE_WIDTH2);
48076
48361
  const stripTextColor = contrastText(
48077
48362
  stripFill,
48078
48363
  palette.textOnFillLight,
@@ -48188,7 +48473,7 @@ function renderJourneyMapForExport(content, theme, palette) {
48188
48473
  }
48189
48474
  return svgEl.outerHTML;
48190
48475
  }
48191
- var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_RADIUS5, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48476
+ var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48192
48477
  var init_renderer14 = __esm({
48193
48478
  "src/journey-map/renderer.ts"() {
48194
48479
  "use strict";
@@ -48203,9 +48488,9 @@ var init_renderer14 = __esm({
48203
48488
  init_tag_groups();
48204
48489
  init_scaling();
48205
48490
  init_text_measure();
48491
+ init_visual_conventions();
48206
48492
  DIAGRAM_PADDING13 = 20;
48207
48493
  PADDING2 = DIAGRAM_PADDING13;
48208
- CARD_RADIUS5 = 6;
48209
48494
  CARD_PADDING_X3 = 10;
48210
48495
  CARD_PADDING_Y3 = 6;
48211
48496
  CARD_HEADER_HEIGHT3 = 24;
@@ -48282,7 +48567,7 @@ function computeCycleLayout(parsed, options) {
48282
48567
  const hasDesc = !hideDescriptions && node.description.length > 0;
48283
48568
  const labelWidth2 = Math.max(
48284
48569
  MIN_NODE_WIDTH4,
48285
- measureText(node.label, LABEL_FONT_SIZE5) + NODE_PAD_X * 2
48570
+ measureText(node.label, LABEL_FONT_SIZE4) + NODE_PAD_X * 2
48286
48571
  );
48287
48572
  if (circleNodes) {
48288
48573
  return computeCircleNodeDims(node, hasDesc);
@@ -48499,7 +48784,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48499
48784
  let bestScore = Infinity;
48500
48785
  for (let w = minW; w <= MAX_NODE_WIDTH3; w += DESC_WIDTH_STEP) {
48501
48786
  const wrapped2 = wrapDescForWidth(description, w);
48502
- const h = HEADER_HEIGHT5 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48787
+ const h = HEADER_HEIGHT4 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48503
48788
  const ratio = w / h;
48504
48789
  const score = Math.abs(Math.log(ratio / DESC_TARGET_RATIO));
48505
48790
  if (score < bestScore) {
@@ -48511,7 +48796,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48511
48796
  const wrapped = wrapDescForWidth(description, minW);
48512
48797
  return {
48513
48798
  width: minW,
48514
- height: HEADER_HEIGHT5 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48799
+ height: HEADER_HEIGHT4 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48515
48800
  wrappedDesc: wrapped
48516
48801
  };
48517
48802
  }
@@ -48524,7 +48809,7 @@ function wrapDescForWidth(description, nodeWidth) {
48524
48809
  );
48525
48810
  }
48526
48811
  function renderedDescNodeHeight(numLines, scale) {
48527
- const headerH = HEADER_HEIGHT5 * scale;
48812
+ const headerH = HEADER_HEIGHT4 * scale;
48528
48813
  const descFont = Math.max(
48529
48814
  RENDERER_DESC_FONT_MIN,
48530
48815
  Math.round(RENDERER_DESC_FONT * scale)
@@ -48859,7 +49144,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
48859
49144
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
48860
49145
  return { path, midAngle };
48861
49146
  }
48862
- var MIN_ARC_ANGLE, LABEL_FONT_SIZE5, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6, EDGE_LABEL_FONT_SIZE11, MIN_NODE_WIDTH4, MAX_NODE_WIDTH3, DESC_MIN_WIDTH, DESC_WIDTH_STEP, DESC_TARGET_RATIO, PLAIN_NODE_HEIGHT, HEADER_HEIGHT5, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, RENDERER_DESC_FONT, RENDERER_DESC_FONT_MIN, RENDERER_DESC_LINE_H, RENDERER_DESC_LINE_H_MIN, EDGE_LABEL_MAX_WIDTH;
49147
+ var MIN_ARC_ANGLE, LABEL_FONT_SIZE4, CIRCLE_LABEL_FONT_SIZE, DESC_FONT_SIZE6, EDGE_LABEL_FONT_SIZE11, MIN_NODE_WIDTH4, MAX_NODE_WIDTH3, DESC_MIN_WIDTH, DESC_WIDTH_STEP, DESC_TARGET_RATIO, PLAIN_NODE_HEIGHT, HEADER_HEIGHT4, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, RENDERER_DESC_FONT, RENDERER_DESC_FONT_MIN, RENDERER_DESC_LINE_H, RENDERER_DESC_LINE_H_MIN, EDGE_LABEL_MAX_WIDTH;
48863
49148
  var init_layout14 = __esm({
48864
49149
  "src/cycle/layout.ts"() {
48865
49150
  "use strict";
@@ -48867,7 +49152,7 @@ var init_layout14 = __esm({
48867
49152
  init_wrapped_desc();
48868
49153
  init_text_measure();
48869
49154
  MIN_ARC_ANGLE = 15 * Math.PI / 180;
48870
- LABEL_FONT_SIZE5 = 13;
49155
+ LABEL_FONT_SIZE4 = 13;
48871
49156
  CIRCLE_LABEL_FONT_SIZE = 16;
48872
49157
  DESC_FONT_SIZE6 = 11;
48873
49158
  EDGE_LABEL_FONT_SIZE11 = 11;
@@ -48877,7 +49162,7 @@ var init_layout14 = __esm({
48877
49162
  DESC_WIDTH_STEP = 20;
48878
49163
  DESC_TARGET_RATIO = 1.6;
48879
49164
  PLAIN_NODE_HEIGHT = 50;
48880
- HEADER_HEIGHT5 = 36;
49165
+ HEADER_HEIGHT4 = 36;
48881
49166
  DESC_LINE_HEIGHT7 = 16;
48882
49167
  DESC_PAD_Y = 14;
48883
49168
  NODE_PAD_X = 20;
@@ -52974,6 +53259,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
52974
53259
  const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY).style("background", layout.background);
52975
53260
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
52976
53261
  const defs = svg.append("defs");
53262
+ const uid = mapInstanceCounter++;
53263
+ const nid = (base) => `${base}__m${uid}`;
52977
53264
  const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
52978
53265
  const haloColor = palette.bg;
52979
53266
  const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
@@ -53006,8 +53293,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53006
53293
  for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
53007
53294
  if (layout.relief.length && layout.reliefHatch) {
53008
53295
  const h = layout.reliefHatch;
53009
- const rangeClipId = "dgmo-relief-clip";
53010
- const landClipId = "dgmo-relief-land";
53296
+ const rangeClipId = nid("dgmo-relief-clip");
53297
+ const landClipId = nid("dgmo-relief-land");
53011
53298
  const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
53012
53299
  for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
53013
53300
  const landClip = defs.append("clipPath").attr("id", landClipId);
@@ -53020,7 +53307,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53020
53307
  }
53021
53308
  if (layout.coastlineStyle) {
53022
53309
  const cs = layout.coastlineStyle;
53023
- const maskId = "dgmo-map-water-mask";
53310
+ const maskId = nid("dgmo-map-water-mask");
53024
53311
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53025
53312
  mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
53026
53313
  const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
@@ -53038,7 +53325,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53038
53325
  appendWaterLines(
53039
53326
  gWater,
53040
53327
  defs,
53041
- "dgmo-map-coast",
53328
+ nid("dgmo-map-coast"),
53042
53329
  // Pass the canvas frame so edges collinear with it (the antimeridian on a
53043
53330
  // world map, regional clipExtent cuts) don't get ringed as fake coast —
53044
53331
  // land runs cleanly to the render-area edge.
@@ -53075,7 +53362,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53075
53362
  (l) => l.poiId !== void 0 && !l.hidden
53076
53363
  );
53077
53364
  if (poiLabels.length) {
53078
- const patchBlurId = "dgmo-map-label-patch-blur";
53365
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
53079
53366
  defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
53080
53367
  const PAD = 8;
53081
53368
  const buildPatch = (labels, maskId, decoCluster) => {
@@ -53120,7 +53407,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53120
53407
  if (clusterUi) {
53121
53408
  buildPatch(
53122
53409
  poiLabels.filter((l) => l.clusterMember === void 0),
53123
- "dgmo-map-label-patch"
53410
+ nid("dgmo-map-label-patch")
53124
53411
  );
53125
53412
  const byCluster = /* @__PURE__ */ new Map();
53126
53413
  for (const l of poiLabels) {
@@ -53131,9 +53418,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53131
53418
  }
53132
53419
  let ci = 0;
53133
53420
  for (const [cid, labs] of byCluster)
53134
- buildPatch(labs, `dgmo-map-label-patch-c${ci++}`, cid);
53421
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
53135
53422
  } else {
53136
- buildPatch(poiLabels, "dgmo-map-label-patch");
53423
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
53137
53424
  }
53138
53425
  }
53139
53426
  if (layout.insets.length) {
@@ -53142,7 +53429,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53142
53429
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
53143
53430
  insetG.append("path").attr("d", d).attr("fill", layout.background).attr("stroke", mix(palette.text, palette.bg, 55)).attr("stroke-width", 1).attr("stroke-linejoin", "round");
53144
53431
  if (box.contextLand) {
53145
- const clipId = `dgmo-map-inset-clip-${bi}`;
53432
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
53146
53433
  defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
53147
53434
  insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
53148
53435
  }
@@ -53150,7 +53437,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53150
53437
  for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
53151
53438
  if (layout.coastlineStyle) {
53152
53439
  const cs = layout.coastlineStyle;
53153
- const maskId = "dgmo-map-inset-water-mask";
53440
+ const maskId = nid("dgmo-map-inset-water-mask");
53154
53441
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53155
53442
  const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
53156
53443
  for (const box of layout.insets) {
@@ -53159,7 +53446,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53159
53446
  }
53160
53447
  layout.insets.forEach((box, bi) => {
53161
53448
  if (box.contextLand)
53162
- mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#dgmo-map-inset-clip-${bi})`);
53449
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
53163
53450
  });
53164
53451
  for (const r of layout.insetRegions)
53165
53452
  if (r.id !== "lake")
@@ -53167,7 +53454,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53167
53454
  for (const r of layout.insetRegions)
53168
53455
  if (r.id === "lake")
53169
53456
  mask.append("path").attr("d", r.d).attr("fill", "white");
53170
- const clipId = "dgmo-map-inset-water-clip";
53457
+ const clipId = nid("dgmo-map-inset-water-clip");
53171
53458
  const clip = defs.append("clipPath").attr("id", clipId);
53172
53459
  for (const box of layout.insets) {
53173
53460
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
@@ -53177,7 +53464,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53177
53464
  appendWaterLines(
53178
53465
  gInsetWater,
53179
53466
  defs,
53180
- "dgmo-map-inset-coast",
53467
+ nid("dgmo-map-inset-coast"),
53181
53468
  coastlineOuterRings(layout.insetRegions, cs.minExtent),
53182
53469
  cs,
53183
53470
  layout.background
@@ -53206,7 +53493,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53206
53493
  }
53207
53494
  wireSync(p, leg.lineNumber);
53208
53495
  if (leg.arrow) {
53209
- const id = `dgmo-map-arrow-${i}`;
53496
+ const id = nid(`dgmo-map-arrow-${i}`);
53210
53497
  const s = arrowSize(leg.width);
53211
53498
  defs.append("marker").attr("id", id).attr("viewBox", "0 0 10 10").attr("refX", 10).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", s).attr("markerHeight", s).attr("orient", "auto-start-reverse").append("path").attr("d", "M0,0L10,5L0,10z").attr("fill", leg.color);
53212
53499
  p.attr("marker-end", `url(#${id})`);
@@ -53402,7 +53689,7 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
53402
53689
  }
53403
53690
  return t;
53404
53691
  }
53405
- var d3Selection23, LABEL_FONT;
53692
+ var d3Selection23, LABEL_FONT, mapInstanceCounter;
53406
53693
  var init_renderer16 = __esm({
53407
53694
  "src/map/renderer.ts"() {
53408
53695
  "use strict";
@@ -53415,6 +53702,7 @@ var init_renderer16 = __esm({
53415
53702
  init_legend_band();
53416
53703
  init_layout15();
53417
53704
  LABEL_FONT = 11;
53705
+ mapInstanceCounter = 0;
53418
53706
  }
53419
53707
  });
53420
53708
 
@@ -54346,7 +54634,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54346
54634
  const sHMargin = ctx.aesthetic(H_MARGIN);
54347
54635
  const sVMargin = ctx.aesthetic(V_MARGIN3);
54348
54636
  const sTitleAreaHeight = ctx.structural(TITLE_AREA_HEIGHT4);
54349
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT6);
54637
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT5);
54350
54638
  const sRowHeight = ctx.structural(ROW_HEIGHT);
54351
54639
  const sPhaseHeight = ctx.structural(PHASE_HEIGHT);
54352
54640
  const sTaskLabelMin = ctx.structural(TASK_LABEL_MIN);
@@ -54371,7 +54659,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54371
54659
  const sLegendLetterFont = ctx.text(LEGEND_LETTER_FONT);
54372
54660
  const sViolationLineHeight = ctx.structural(VIOLATION_LINE_HEIGHT);
54373
54661
  const sStackTopGap = ctx.structural(STACK_TOP_GAP);
54374
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH12);
54662
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
54375
54663
  const sNodeRadius = ctx.structural(NODE_RADIUS3);
54376
54664
  const innerWidth = Math.max(0, width - 2 * sHMargin);
54377
54665
  let roleColW = Math.max(
@@ -54917,7 +55205,7 @@ function parseQuotedSegments(message) {
54917
55205
  out.push({ text: message.slice(last), bold: false });
54918
55206
  return out;
54919
55207
  }
54920
- var d3Selection26, MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT6, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_STROKE_WIDTH12, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
55208
+ var d3Selection26, MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
54921
55209
  var init_renderer19 = __esm({
54922
55210
  "src/raci/renderer.ts"() {
54923
55211
  "use strict";
@@ -54929,6 +55217,7 @@ var init_renderer19 = __esm({
54929
55217
  init_variants();
54930
55218
  init_scaling();
54931
55219
  init_text_measure();
55220
+ init_visual_conventions();
54932
55221
  MARKER_LABELS = {
54933
55222
  raci: { R: "Responsible", A: "Accountable", C: "Consulted", I: "Informed" },
54934
55223
  rasci: {
@@ -54950,7 +55239,7 @@ var init_renderer19 = __esm({
54950
55239
  TITLE_LEGEND_GAP = 16;
54951
55240
  LEGEND_LABEL_FONT = 12;
54952
55241
  LEGEND_LETTER_FONT = 14;
54953
- HEADER_HEIGHT6 = 36;
55242
+ HEADER_HEIGHT5 = 36;
54954
55243
  ROW_HEIGHT = 36;
54955
55244
  PHASE_HEIGHT = 40;
54956
55245
  TASK_LABEL_MIN = 200;
@@ -54970,7 +55259,6 @@ var init_renderer19 = __esm({
54970
55259
  ROLE_HEADER_FONT = 12;
54971
55260
  PHASE_FONT = 13;
54972
55261
  TINT_PCT = 25;
54973
- NODE_STROKE_WIDTH12 = 1.5;
54974
55262
  NODE_RADIUS3 = 6;
54975
55263
  AUTO_ACCENTS = [
54976
55264
  "blue",
@@ -55570,11 +55858,11 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55570
55858
  const lines = splitParticipantLabel(
55571
55859
  p.label,
55572
55860
  labelTextWidth(PARTICIPANT_BOX_WIDTH),
55573
- LABEL_FONT_SIZE6
55861
+ LABEL_FONT_SIZE5
55574
55862
  );
55575
55863
  if (lines.length === 0) continue;
55576
55864
  const widest = Math.max(
55577
- ...lines.map((l) => measureText(l, LABEL_FONT_SIZE6))
55865
+ ...lines.map((l) => measureText(l, LABEL_FONT_SIZE5))
55578
55866
  );
55579
55867
  const labelWidth2 = widest + 10;
55580
55868
  uniformBoxWidth = Math.max(uniformBoxWidth, labelWidth2);
@@ -55608,7 +55896,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55608
55896
  const sSelfCallWidth = ctx.structural(SELF_CALL_WIDTH);
55609
55897
  const sNoteTextWidthMax = sNoteMaxW - sNotePadH * 2 - sNoteFold;
55610
55898
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
55611
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE6);
55899
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE5);
55612
55900
  const sLabelTextWidth = labelTextWidth(sBoxW);
55613
55901
  const participantIndexMap = /* @__PURE__ */ new Map();
55614
55902
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
@@ -56745,7 +57033,7 @@ function buildNoteMessageMap(elements) {
56745
57033
  walk(elements);
56746
57034
  return map;
56747
57035
  }
56748
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE6) {
57036
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
56749
57037
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
56750
57038
  if (tagAttr) {
56751
57039
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -56793,7 +57081,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
56793
57081
  });
56794
57082
  }
56795
57083
  }
56796
- var d3Selection27, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE6, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
57084
+ var d3Selection27, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
56797
57085
  var init_renderer20 = __esm({
56798
57086
  "src/sequence/renderer.ts"() {
56799
57087
  "use strict";
@@ -56814,7 +57102,7 @@ var init_renderer20 = __esm({
56814
57102
  PARTICIPANT_GAP = 160;
56815
57103
  PARTICIPANT_BOX_WIDTH = 120;
56816
57104
  PARTICIPANT_BOX_HEIGHT = 50;
56817
- LABEL_FONT_SIZE6 = 13;
57105
+ LABEL_FONT_SIZE5 = 13;
56818
57106
  TOP_MARGIN = 20;
56819
57107
  TITLE_HEIGHT8 = 30;
56820
57108
  PARTICIPANT_Y_OFFSET = 10;