@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.js CHANGED
@@ -318,7 +318,7 @@ function resolveColorWithDiagnostic(color, line11, diagnostics, palette) {
318
318
  );
319
319
  return void 0;
320
320
  }
321
- var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
321
+ var nord, colorNames, RECOGNIZED_COLOR_NAMES, CATEGORICAL_COLOR_ORDER, seriesColors;
322
322
  var init_colors = __esm({
323
323
  "src/colors.ts"() {
324
324
  "use strict";
@@ -376,6 +376,16 @@ var init_colors = __esm({
376
376
  "black",
377
377
  "white"
378
378
  ]);
379
+ CATEGORICAL_COLOR_ORDER = Object.freeze([
380
+ "red",
381
+ "green",
382
+ "blue",
383
+ "yellow",
384
+ "teal",
385
+ "purple",
386
+ "orange",
387
+ "cyan"
388
+ ]);
379
389
  seriesColors = [
380
390
  nord.nord10,
381
391
  // blue
@@ -1229,11 +1239,7 @@ var init_tag_groups = __esm({
1229
1239
  init_diagnostics();
1230
1240
  init_colors();
1231
1241
  AUTO_TAG_COLOR_SENTINEL = "";
1232
- autoTagColorCycle = Object.freeze(
1233
- RECOGNIZED_COLOR_NAMES.filter(
1234
- (n) => n !== "gray" && n !== "black" && n !== "white"
1235
- )
1236
- );
1242
+ autoTagColorCycle = CATEGORICAL_COLOR_ORDER;
1237
1243
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
1238
1244
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
1239
1245
  }
@@ -3023,7 +3029,7 @@ function shapeFill(palette, intent, isDark, opts) {
3023
3029
  }
3024
3030
  function getSeriesColors(palette) {
3025
3031
  const c = palette.colors;
3026
- return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];
3032
+ return CATEGORICAL_COLOR_ORDER.map((name) => c[name]);
3027
3033
  }
3028
3034
  function getSegmentColors(palette, count) {
3029
3035
  if (count <= 0) return [];
@@ -3076,6 +3082,7 @@ var POLITICAL_TINT_BANDS;
3076
3082
  var init_color_utils = __esm({
3077
3083
  "src/palettes/color-utils.ts"() {
3078
3084
  "use strict";
3085
+ init_colors();
3079
3086
  POLITICAL_TINT_BANDS = {
3080
3087
  light: [32, 48, 64, 80],
3081
3088
  dark: [44, 58, 72, 86]
@@ -11532,7 +11539,7 @@ var init_chart_types = __esm({
11532
11539
  },
11533
11540
  {
11534
11541
  id: "map",
11535
- description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
11542
+ description: "Geographic map: a value or count per country, state, or region (choropleth); points of interest; routes. Use when categories are real-world places."
11536
11543
  },
11537
11544
  // ── Tier 3 — Specialized analytical charts ────────────────
11538
11545
  {
@@ -11549,7 +11556,7 @@ var init_chart_types = __esm({
11549
11556
  },
11550
11557
  {
11551
11558
  id: "slope",
11552
- description: "Change between two periods"
11559
+ description: "Change for multiple things between exactly two periods"
11553
11560
  },
11554
11561
  {
11555
11562
  id: "sankey",
@@ -19005,6 +19012,7 @@ function parseBoxesAndLines(content, palette) {
19005
19012
  const nodes = [];
19006
19013
  const edges = [];
19007
19014
  const groups = [];
19015
+ const nodePositions = /* @__PURE__ */ new Map();
19008
19016
  const result = {
19009
19017
  type: "boxes-and-lines",
19010
19018
  title: null,
@@ -19038,6 +19046,8 @@ function parseBoxesAndLines(content, palette) {
19038
19046
  }
19039
19047
  const groupStack = [];
19040
19048
  let contentStarted = false;
19049
+ let inLayoutBlock = false;
19050
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
19041
19051
  let currentTagGroup = null;
19042
19052
  const metaAliasMap = /* @__PURE__ */ new Map();
19043
19053
  const nameAliasMap = /* @__PURE__ */ new Map();
@@ -19239,6 +19249,42 @@ function parseBoxesAndLines(content, palette) {
19239
19249
  if (currentTagGroup && indent === 0) {
19240
19250
  currentTagGroup = null;
19241
19251
  }
19252
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
19253
+ let isBlock = false;
19254
+ for (let j = i + 1; j < lines.length; j++) {
19255
+ const peek = lines[j];
19256
+ if (!peek.trim()) continue;
19257
+ isBlock = measureIndent2(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
19258
+ break;
19259
+ }
19260
+ if (isBlock) {
19261
+ flushDescription();
19262
+ closeGroupsToIndent(0);
19263
+ inLayoutBlock = true;
19264
+ continue;
19265
+ }
19266
+ }
19267
+ if (inLayoutBlock) {
19268
+ if (indent > 0) {
19269
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
19270
+ if (lm) {
19271
+ nodePositions.set(lm[1].trim(), {
19272
+ x: Number(lm[2]),
19273
+ y: Number(lm[3])
19274
+ });
19275
+ } else {
19276
+ result.diagnostics.push(
19277
+ makeDgmoError(
19278
+ lineNum,
19279
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
19280
+ "warning"
19281
+ )
19282
+ );
19283
+ }
19284
+ continue;
19285
+ }
19286
+ inLayoutBlock = false;
19287
+ }
19242
19288
  if (descState !== null) {
19243
19289
  if (indent > descState.indent) {
19244
19290
  if (trimmed.includes("->") || trimmed.includes("<->")) {
@@ -19491,6 +19537,22 @@ function parseBoxesAndLines(content, palette) {
19491
19537
  );
19492
19538
  }
19493
19539
  finalizeAutoTagColors(result.tagGroups);
19540
+ if (nodePositions.size > 0) {
19541
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
19542
+ for (const id of nodePositions.keys()) {
19543
+ if (!nodeLabelSet.has(id)) {
19544
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
19545
+ }
19546
+ }
19547
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
19548
+ if (unpositioned.length > 0) {
19549
+ pushWarning(
19550
+ 0,
19551
+ `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`
19552
+ );
19553
+ }
19554
+ result.nodePositions = nodePositions;
19555
+ }
19494
19556
  if (result.tagGroups.length > 0) {
19495
19557
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
19496
19558
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
@@ -21591,7 +21653,18 @@ function parseJourneyMap(content, palette) {
21591
21653
  }
21592
21654
  }
21593
21655
  } else {
21594
- personaName = afterKeyword;
21656
+ const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
21657
+ if (colorMatch) {
21658
+ personaName = colorMatch[1].trim();
21659
+ personaColor = resolveColorWithDiagnostic(
21660
+ colorMatch[2],
21661
+ lineNumber,
21662
+ result.diagnostics,
21663
+ palette
21664
+ ) ?? void 0;
21665
+ } else {
21666
+ personaName = afterKeyword;
21667
+ }
21595
21668
  }
21596
21669
  if (!personaName) {
21597
21670
  return fail(lineNumber, "persona requires a name");
@@ -24532,6 +24605,63 @@ var init_export_container = __esm({
24532
24605
  }
24533
24606
  });
24534
24607
 
24608
+ // src/utils/card.ts
24609
+ function renderNodeCard(container, opts) {
24610
+ 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);
24611
+ if (opts.dashed) {
24612
+ rect.attr("stroke-dasharray", "6 3");
24613
+ }
24614
+ 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);
24615
+ const meta = opts.meta;
24616
+ if (!meta || meta.rows.length === 0) return;
24617
+ 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);
24618
+ const keyX = meta.keyX ?? 10;
24619
+ const maxKeyWidth = Math.max(
24620
+ ...meta.rows.map(([key]) => measureText(`${key}: `, meta.fontSize))
24621
+ );
24622
+ const valueX = keyX + maxKeyWidth;
24623
+ const metaStartY = opts.headerHeight + meta.separatorGap + meta.fontSize;
24624
+ for (let i = 0; i < meta.rows.length; i++) {
24625
+ const [displayKey, value] = meta.rows[i];
24626
+ const rowY = metaStartY + i * meta.lineHeight;
24627
+ container.append("text").attr("x", keyX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(`${displayKey}: `);
24628
+ container.append("text").attr("x", valueX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(value);
24629
+ }
24630
+ }
24631
+ function renderCollapseBar(container, opts) {
24632
+ container.append("clipPath").attr("id", opts.clipId).append("rect").attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx);
24633
+ 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);
24634
+ }
24635
+ var init_card = __esm({
24636
+ "src/utils/card.ts"() {
24637
+ "use strict";
24638
+ init_text_measure();
24639
+ }
24640
+ });
24641
+
24642
+ // src/utils/visual-conventions.ts
24643
+ 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;
24644
+ var init_visual_conventions = __esm({
24645
+ "src/utils/visual-conventions.ts"() {
24646
+ "use strict";
24647
+ NODE_STROKE_WIDTH = 1.5;
24648
+ EDGE_STROKE_WIDTH = 1.5;
24649
+ CARD_RADIUS = 6;
24650
+ CONTAINER_RADIUS = 8;
24651
+ COLLAPSE_BAR_INSET = 0;
24652
+ HEADER_HEIGHT2 = 28;
24653
+ LABEL_FONT_SIZE2 = 13;
24654
+ META_FONT_SIZE2 = 11;
24655
+ META_LINE_HEIGHT2 = 16;
24656
+ SEPARATOR_GAP2 = 6;
24657
+ COLLAPSE_BAR_HEIGHT = 6;
24658
+ CONTAINER_HEADER_HEIGHT = 28;
24659
+ CONTAINER_LABEL_FONT_SIZE = 13;
24660
+ CONTAINER_META_FONT_SIZE = 11;
24661
+ CONTAINER_META_LINE_HEIGHT2 = 16;
24662
+ }
24663
+ });
24664
+
24535
24665
  // src/org/renderer.ts
24536
24666
  var renderer_exports = {};
24537
24667
  __export(renderer_exports, {
@@ -24690,9 +24820,16 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24690
24820
  }
24691
24821
  }
24692
24822
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
24693
- const clipId = `clip-${c.nodeId}`;
24694
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", sContainerRadius);
24695
- 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");
24823
+ renderCollapseBar(cG, {
24824
+ width: c.width,
24825
+ height: c.height,
24826
+ barHeight: sCollapseBarHeight,
24827
+ inset: sCollapseBarInset,
24828
+ rx: sContainerRadius,
24829
+ fill: containerStroke(palette, colorOff ? void 0 : c.color),
24830
+ clipId: `clip-${c.nodeId}`,
24831
+ className: "org-collapse-bar"
24832
+ });
24696
24833
  }
24697
24834
  if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
24698
24835
  const iconSize = 14;
@@ -24743,42 +24880,48 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24743
24880
  solid
24744
24881
  );
24745
24882
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
24746
- 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);
24747
- if (node.isContainer) {
24748
- rect.attr("stroke-dasharray", "6 3");
24749
- }
24750
24883
  const labelColor = contrastText(
24751
24884
  fill2,
24752
24885
  palette.textOnFillLight,
24753
24886
  palette.textOnFillDark
24754
24887
  );
24755
- 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);
24756
24888
  const metaEntries = Object.entries(node.metadata);
24757
- if (metaEntries.length > 0) {
24758
- 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);
24759
- const metaDisplayKeys = metaEntries.map(
24760
- ([k]) => displayNames.get(k) ?? k
24761
- );
24762
- const maxKeyWidth = Math.max(
24763
- ...metaDisplayKeys.map((k) => measureText(`${k}: `, sMetaFontSize))
24764
- );
24765
- const valueX = 10 + maxKeyWidth;
24766
- const metaStartY = sHeaderHeight + sSeparatorGap + sMetaFontSize;
24767
- for (let i = 0; i < metaEntries.length; i++) {
24768
- const [, value] = metaEntries[i];
24769
- const displayKey = metaDisplayKeys[i];
24770
- const rowY = metaStartY + i * sMetaLineHeight;
24771
- nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}: `);
24772
- nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(value);
24889
+ renderNodeCard(nodeG, {
24890
+ width: node.width,
24891
+ height: node.height,
24892
+ rx: sCardRadius,
24893
+ fill: fill2,
24894
+ stroke: stroke2,
24895
+ strokeWidth: sNodeStrokeWidth,
24896
+ ...node.isContainer && { dashed: true },
24897
+ label: node.label,
24898
+ labelColor,
24899
+ labelFontSize: sLabelFontSize,
24900
+ headerHeight: sHeaderHeight,
24901
+ ...metaEntries.length > 0 && {
24902
+ meta: {
24903
+ rows: metaEntries.map(
24904
+ ([k, value]) => [displayNames.get(k) ?? k, value]
24905
+ ),
24906
+ fontSize: sMetaFontSize,
24907
+ lineHeight: sMetaLineHeight,
24908
+ separatorGap: sSeparatorGap,
24909
+ separatorColor: solid ? labelColor : stroke2,
24910
+ textColor: labelColor
24911
+ }
24773
24912
  }
24774
- }
24913
+ });
24775
24914
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
24776
- const clipId = `clip-${node.id}`;
24777
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius);
24778
- nodeG.append("rect").attr("x", sCollapseBarInset).attr("y", node.height - sCollapseBarHeight).attr("width", node.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr(
24779
- "fill",
24780
- solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color)
24781
- ).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24915
+ renderCollapseBar(nodeG, {
24916
+ width: node.width,
24917
+ height: node.height,
24918
+ barHeight: sCollapseBarHeight,
24919
+ inset: sCollapseBarInset,
24920
+ rx: sCardRadius,
24921
+ fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
24922
+ clipId: `clip-${node.id}`,
24923
+ className: "org-collapse-bar"
24924
+ });
24782
24925
  }
24783
24926
  if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
24784
24927
  const iconSize = 14;
@@ -24922,7 +25065,7 @@ function renderOrgForExport(content, theme, palette) {
24922
25065
  return extractExportSvg(container, theme);
24923
25066
  });
24924
25067
  }
24925
- var 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;
25068
+ var DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
24926
25069
  var init_renderer = __esm({
24927
25070
  "src/org/renderer.ts"() {
24928
25071
  "use strict";
@@ -24935,27 +25078,14 @@ var init_renderer = __esm({
24935
25078
  init_layout();
24936
25079
  init_legend_constants();
24937
25080
  init_legend_integration();
25081
+ init_card();
24938
25082
  init_text_measure();
24939
25083
  init_legend_layout();
24940
25084
  init_title_constants();
25085
+ init_visual_conventions();
24941
25086
  DIAGRAM_PADDING = 20;
24942
25087
  MAX_SCALE = 3;
24943
25088
  TITLE_HEIGHT = 30;
24944
- LABEL_FONT_SIZE2 = 13;
24945
- META_FONT_SIZE2 = 11;
24946
- META_LINE_HEIGHT2 = 16;
24947
- HEADER_HEIGHT2 = 28;
24948
- SEPARATOR_GAP2 = 6;
24949
- EDGE_STROKE_WIDTH = 1.5;
24950
- NODE_STROKE_WIDTH = 1.5;
24951
- CARD_RADIUS = 6;
24952
- CONTAINER_RADIUS = 8;
24953
- CONTAINER_LABEL_FONT_SIZE = 13;
24954
- CONTAINER_META_FONT_SIZE = 11;
24955
- CONTAINER_META_LINE_HEIGHT2 = 16;
24956
- CONTAINER_HEADER_HEIGHT = 28;
24957
- COLLAPSE_BAR_HEIGHT = 6;
24958
- COLLAPSE_BAR_INSET = 0;
24959
25089
  ANCESTOR_DOT_R = 4;
24960
25090
  ANCESTOR_LABEL_FONT_SIZE = 11;
24961
25091
  ANCESTOR_ROW_HEIGHT = 22;
@@ -25739,21 +25869,21 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25739
25869
  if (width <= 0 || height <= 0) return;
25740
25870
  const ctx = ScaleContext.identity();
25741
25871
  const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING2);
25742
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE4);
25743
- const sMetaFontSize = ctx.text(META_FONT_SIZE4);
25744
- const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT4);
25745
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT4);
25746
- const sSeparatorGap = ctx.structural(SEPARATOR_GAP4);
25747
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH2);
25748
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH2);
25872
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE2);
25873
+ const sMetaFontSize = ctx.text(META_FONT_SIZE2);
25874
+ const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT2);
25875
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT2);
25876
+ const sSeparatorGap = ctx.structural(SEPARATOR_GAP2);
25877
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
25878
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
25749
25879
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
25750
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE3);
25751
- const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE2);
25752
- const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT4);
25753
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT2);
25880
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
25881
+ const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE);
25882
+ const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT2);
25883
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
25754
25884
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
25755
25885
  const sTitleHeight = ctx.structural(TITLE_HEIGHT2);
25756
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT2);
25886
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
25757
25887
  const sLegendFixedGap = ctx.aesthetic(LEGEND_FIXED_GAP2);
25758
25888
  const hasLegend = layout.legend.length > 0;
25759
25889
  const layoutLegendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
@@ -25844,7 +25974,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25844
25974
  }
25845
25975
  const fill2 = containerFill2(palette, isDark, c.color);
25846
25976
  const stroke2 = containerStroke2(palette, c.color);
25847
- 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);
25977
+ 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);
25848
25978
  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);
25849
25979
  const metaEntries = Object.entries(c.metadata);
25850
25980
  if (metaEntries.length > 0) {
@@ -25869,7 +25999,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25869
25999
  }
25870
26000
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
25871
26001
  const clipId = `clip-${c.nodeId}`;
25872
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2);
26002
+ cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
25873
26003
  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})`);
25874
26004
  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}`);
25875
26005
  }
@@ -25908,13 +26038,23 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25908
26038
  const solid = parsed.options["solid-fill"] === "on";
25909
26039
  const fill2 = nodeFill2(palette, isDark, node.color, solid);
25910
26040
  const stroke2 = nodeStroke2(palette, node.color);
25911
- 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);
25912
26041
  const labelColor = contrastText(
25913
26042
  fill2,
25914
26043
  palette.textOnFillLight,
25915
26044
  palette.textOnFillDark
25916
26045
  );
25917
- 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);
26046
+ renderNodeCard(nodeG, {
26047
+ width: node.width,
26048
+ height: node.height,
26049
+ rx: CARD_RADIUS,
26050
+ fill: fill2,
26051
+ stroke: stroke2,
26052
+ strokeWidth: sNodeStrokeWidth,
26053
+ label: node.label,
26054
+ labelColor,
26055
+ labelFontSize: sLabelFontSize,
26056
+ headerHeight: sHeaderHeight
26057
+ });
25918
26058
  const metaEntries = Object.entries(node.metadata);
25919
26059
  if (metaEntries.length > 0) {
25920
26060
  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);
@@ -25949,7 +26089,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25949
26089
  }
25950
26090
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
25951
26091
  const clipId = `clip-${node.id}`;
25952
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2);
26092
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
25953
26093
  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})`);
25954
26094
  }
25955
26095
  }
@@ -26079,7 +26219,7 @@ async function renderSitemapForExport(content, theme, palette) {
26079
26219
  document.body.removeChild(container);
26080
26220
  return svgHtml;
26081
26221
  }
26082
- var 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;
26222
+ var DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26083
26223
  var init_renderer2 = __esm({
26084
26224
  "src/sitemap/renderer.ts"() {
26085
26225
  "use strict";
@@ -26092,27 +26232,15 @@ var init_renderer2 = __esm({
26092
26232
  init_legend_integration();
26093
26233
  init_legend_layout();
26094
26234
  init_scaling();
26235
+ init_card();
26095
26236
  init_title_constants();
26237
+ init_visual_conventions();
26096
26238
  DIAGRAM_PADDING2 = 20;
26097
26239
  MAX_SCALE2 = 3;
26098
26240
  TITLE_HEIGHT2 = 30;
26099
- LABEL_FONT_SIZE4 = 13;
26100
- META_FONT_SIZE4 = 11;
26101
- META_LINE_HEIGHT4 = 16;
26102
- HEADER_HEIGHT4 = 28;
26103
- SEPARATOR_GAP4 = 6;
26104
- EDGE_STROKE_WIDTH2 = 1.5;
26105
- NODE_STROKE_WIDTH2 = 1.5;
26106
- CARD_RADIUS2 = 6;
26107
- CONTAINER_RADIUS2 = 8;
26108
- CONTAINER_LABEL_FONT_SIZE3 = 13;
26109
- CONTAINER_META_FONT_SIZE2 = 11;
26110
- CONTAINER_META_LINE_HEIGHT4 = 16;
26111
- CONTAINER_HEADER_HEIGHT2 = 28;
26112
26241
  ARROWHEAD_W = 10;
26113
26242
  ARROWHEAD_H = 7;
26114
26243
  EDGE_LABEL_FONT_SIZE = 11;
26115
- COLLAPSE_BAR_HEIGHT2 = 6;
26116
26244
  LEGEND_FIXED_GAP2 = 8;
26117
26245
  lineGenerator = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveBasis);
26118
26246
  lineGeneratorLinear = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveLinear);
@@ -26280,7 +26408,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
26280
26408
  const sCardMetaLineHeight = ctx.structural(CARD_META_LINE_HEIGHT);
26281
26409
  const sCardSeparatorGap = ctx.structural(CARD_SEPARATOR_GAP);
26282
26410
  const sCardGap = ctx.aesthetic(CARD_GAP);
26283
- const sCardRadius = ctx.structural(CARD_RADIUS3);
26411
+ const sCardRadius = ctx.structural(CARD_RADIUS);
26284
26412
  const sCardPaddingX = ctx.aesthetic(CARD_PADDING_X);
26285
26413
  const sCardPaddingY = ctx.aesthetic(CARD_PADDING_Y);
26286
26414
  const sCardStrokeWidth = ctx.structural(CARD_STROKE_WIDTH);
@@ -26660,7 +26788,7 @@ function computeSwimlaneLayout(parsed, buckets, baseLayout, collapsedLanes, coll
26660
26788
  const totalHeight = laneY - sLaneGap + sColumnPadding + sDiagramPadding;
26661
26789
  return { columnXs, lanes, totalWidth, totalHeight, startY };
26662
26790
  }
26663
- 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) {
26791
+ 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) {
26664
26792
  const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
26665
26793
  const buckets = bucketCardsBySwimlane(visibleColumns, swimlaneGroup);
26666
26794
  const grid = computeSwimlaneLayout(
@@ -26800,7 +26928,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
26800
26928
  }
26801
26929
  }
26802
26930
  }
26803
- 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) {
26931
+ 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) {
26804
26932
  const card = cardLayout.card;
26805
26933
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
26806
26934
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -26850,7 +26978,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
26850
26978
  }
26851
26979
  }
26852
26980
  }
26853
- var 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;
26981
+ var 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;
26854
26982
  var init_renderer3 = __esm({
26855
26983
  "src/kanban/renderer.ts"() {
26856
26984
  "use strict";
@@ -26864,6 +26992,7 @@ var init_renderer3 = __esm({
26864
26992
  init_legend_integration();
26865
26993
  init_scaling();
26866
26994
  init_text_measure();
26995
+ init_visual_conventions();
26867
26996
  init_title_constants();
26868
26997
  DIAGRAM_PADDING3 = 20;
26869
26998
  COLUMN_GAP = 16;
@@ -26874,7 +27003,6 @@ var init_renderer3 = __esm({
26874
27003
  CARD_META_LINE_HEIGHT = 14;
26875
27004
  CARD_SEPARATOR_GAP = 4;
26876
27005
  CARD_GAP = 8;
26877
- CARD_RADIUS3 = 6;
26878
27006
  CARD_PADDING_X = 10;
26879
27007
  CARD_PADDING_Y = 6;
26880
27008
  CARD_STROKE_WIDTH = 1.5;
@@ -27177,8 +27305,8 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
27177
27305
  const sClassFontSize = ctx.text(CLASS_FONT_SIZE2);
27178
27306
  const sMemberFontSize = ctx.text(MEMBER_FONT_SIZE2);
27179
27307
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE2);
27180
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH3);
27181
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH3);
27308
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
27309
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27182
27310
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT2);
27183
27311
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y2);
27184
27312
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X);
@@ -27437,7 +27565,7 @@ function renderClassDiagramForExport(content, theme, palette) {
27437
27565
  return extractExportSvg(container, theme);
27438
27566
  });
27439
27567
  }
27440
- var 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;
27568
+ var 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;
27441
27569
  var init_renderer4 = __esm({
27442
27570
  "src/class/renderer.ts"() {
27443
27571
  "use strict";
@@ -27452,13 +27580,12 @@ var init_renderer4 = __esm({
27452
27580
  init_scaling();
27453
27581
  init_text_measure();
27454
27582
  init_note_box();
27583
+ init_visual_conventions();
27455
27584
  DIAGRAM_PADDING4 = 20;
27456
27585
  MAX_SCALE3 = 3;
27457
27586
  CLASS_FONT_SIZE2 = 13;
27458
27587
  MEMBER_FONT_SIZE2 = 11;
27459
27588
  EDGE_LABEL_FONT_SIZE2 = 11;
27460
- EDGE_STROKE_WIDTH3 = 1.5;
27461
- NODE_STROKE_WIDTH3 = 1.5;
27462
27589
  MEMBER_LINE_HEIGHT2 = 18;
27463
27590
  COMPARTMENT_PADDING_Y2 = 8;
27464
27591
  MEMBER_PADDING_X = 10;
@@ -27954,7 +28081,7 @@ function constraintIcon(constraint) {
27954
28081
  return "\u25CB";
27955
28082
  }
27956
28083
  }
27957
- function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH4) {
28084
+ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH) {
27958
28085
  const dx = point.x - prevPoint.x;
27959
28086
  const dy = point.y - prevPoint.y;
27960
28087
  const len = Math.sqrt(dx * dx + dy * dy);
@@ -28014,8 +28141,8 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
28014
28141
  const sTableFontSize = ctx.text(TABLE_FONT_SIZE2);
28015
28142
  const sColumnFontSize = ctx.text(COLUMN_FONT_SIZE2);
28016
28143
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE4);
28017
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH4);
28018
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH4);
28144
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
28145
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
28019
28146
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT4);
28020
28147
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y4);
28021
28148
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X2);
@@ -28293,7 +28420,7 @@ function renderERDiagramForExport(content, theme, palette) {
28293
28420
  document.body.removeChild(container);
28294
28421
  }
28295
28422
  }
28296
- var 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;
28423
+ var DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28297
28424
  var init_renderer5 = __esm({
28298
28425
  "src/er/renderer.ts"() {
28299
28426
  "use strict";
@@ -28310,13 +28437,12 @@ var init_renderer5 = __esm({
28310
28437
  init_parser9();
28311
28438
  init_layout4();
28312
28439
  init_classify();
28440
+ init_visual_conventions();
28313
28441
  DIAGRAM_PADDING5 = 20;
28314
28442
  MAX_SCALE4 = 3;
28315
28443
  TABLE_FONT_SIZE2 = 13;
28316
28444
  COLUMN_FONT_SIZE2 = 11;
28317
28445
  EDGE_LABEL_FONT_SIZE4 = 11;
28318
- EDGE_STROKE_WIDTH4 = 1.5;
28319
- NODE_STROKE_WIDTH4 = 1.5;
28320
28446
  MEMBER_LINE_HEIGHT4 = 18;
28321
28447
  COMPARTMENT_PADDING_Y4 = 8;
28322
28448
  MEMBER_PADDING_X2 = 10;
@@ -28546,9 +28672,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28546
28672
  const sDiagramPadding = sctx.aesthetic(DIAGRAM_PADDING6);
28547
28673
  const sMinNodeFontSize = sctx.text(MIN_NODE_FONT_SIZE);
28548
28674
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE5);
28549
- const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH5);
28550
- const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH5);
28551
- const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT3);
28675
+ const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH);
28676
+ const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH);
28677
+ const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT2);
28552
28678
  const sDescFontSize = sctx.text(DESC_FONT_SIZE);
28553
28679
  const sGroupLabelFontSize = sctx.text(GROUP_LABEL_FONT_SIZE);
28554
28680
  const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
@@ -28640,8 +28766,32 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28640
28766
  const scaleX = width / (contentW + sDiagramPadding * 2);
28641
28767
  const scaleY = height / (contentH + sDiagramPadding * 2);
28642
28768
  const scale = Math.min(scaleX, scaleY, 3);
28643
- const offsetX = (width - contentW * scale) / 2;
28644
- const offsetY = sDiagramPadding + titleOffset + legendH;
28769
+ let centerShiftX = 0;
28770
+ let centerShiftY = 0;
28771
+ if (parsed.nodePositions && parsed.nodePositions.size > 0) {
28772
+ let bMinX = Infinity, bMinY = Infinity, bMaxX = -Infinity, bMaxY = -Infinity;
28773
+ const accB = (x, y) => {
28774
+ if (x < bMinX) bMinX = x;
28775
+ if (x > bMaxX) bMaxX = x;
28776
+ if (y < bMinY) bMinY = y;
28777
+ if (y > bMaxY) bMaxY = y;
28778
+ };
28779
+ for (const n of layout.nodes) {
28780
+ accB(n.x - n.width / 2, n.y - n.height / 2);
28781
+ accB(n.x + n.width / 2, n.y + n.height / 2);
28782
+ }
28783
+ for (const g of layout.groups) {
28784
+ accB(g.x - g.width / 2, g.y - g.height / 2);
28785
+ accB(g.x + g.width / 2, g.y + g.height / 2);
28786
+ }
28787
+ for (const e of layout.edges) for (const p of e.points) accB(p.x, p.y);
28788
+ if (Number.isFinite(bMinX)) {
28789
+ centerShiftX = (layout.width - bMaxX - bMinX) / 2;
28790
+ centerShiftY = (layout.height - bMaxY - bMinY) / 2;
28791
+ }
28792
+ }
28793
+ const offsetX = (width - contentW * scale) / 2 + centerShiftX * scale;
28794
+ const offsetY = sDiagramPadding + titleOffset + legendH + centerShiftY * scale;
28645
28795
  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);
28646
28796
  if (sctx.isBelowFloor) {
28647
28797
  svg.attr("width", "100%");
@@ -28777,7 +28927,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28777
28927
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
28778
28928
  edgeGroups.set(i, edgeG);
28779
28929
  const markerId = `bl-arrow-${color.replace("#", "")}`;
28780
- const gen = parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28930
+ const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28781
28931
  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})`);
28782
28932
  if (le.bidirectional) {
28783
28933
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
@@ -29058,7 +29208,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
29058
29208
  }
29059
29209
  });
29060
29210
  }
29061
- var 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;
29211
+ var 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;
29062
29212
  var init_renderer6 = __esm({
29063
29213
  "src/boxes-and-lines/renderer.ts"() {
29064
29214
  "use strict";
@@ -29074,14 +29224,13 @@ var init_renderer6 = __esm({
29074
29224
  init_wrapped_desc();
29075
29225
  init_scaling();
29076
29226
  init_text_measure();
29227
+ init_visual_conventions();
29077
29228
  DIAGRAM_PADDING6 = 20;
29078
29229
  NODE_FONT_SIZE = 11;
29079
29230
  MIN_NODE_FONT_SIZE = 9;
29080
29231
  EDGE_LABEL_FONT_SIZE5 = 11;
29081
- EDGE_STROKE_WIDTH5 = 1.5;
29082
- NODE_STROKE_WIDTH5 = 1.5;
29083
29232
  NODE_RX = 8;
29084
- COLLAPSE_BAR_HEIGHT3 = 4;
29233
+ COLLAPSE_BAR_HEIGHT2 = 4;
29085
29234
  ARROWHEAD_W2 = 5;
29086
29235
  ARROWHEAD_H2 = 4;
29087
29236
  DESC_FONT_SIZE = 10;
@@ -29095,6 +29244,7 @@ var init_renderer6 = __esm({
29095
29244
  VALUE_FONT_SIZE = 11;
29096
29245
  lineGeneratorLR = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29097
29246
  lineGeneratorTB = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29247
+ lineGeneratorStraight = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveLinear);
29098
29248
  }
29099
29249
  });
29100
29250
 
@@ -30284,6 +30434,156 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30284
30434
  return { x: rect.x + dx * s, y: rect.y + dy * s };
30285
30435
  };
30286
30436
  const isInsideRect = (p, rect) => Math.abs(p.x - rect.x) <= rect.w / 2 && Math.abs(p.y - rect.y) <= rect.h / 2;
30437
+ const pinned = parsed.nodePositions;
30438
+ const groupLabelSet = new Set(parsed.groups.map((g) => g.label));
30439
+ const groupsAreFlat = parsed.groups.every(
30440
+ (g) => !g.parentGroup && !g.children.some((c) => groupLabelSet.has(c))
30441
+ );
30442
+ const allOriginalGroupLabels = new Set(
30443
+ (collapseInfo?.originalGroups ?? parsed.groups).map((g) => g.label)
30444
+ );
30445
+ const collapsedAreFlatPinned = collapsedGroupLabels.size === 0 || pinned !== void 0 && collapseInfo !== void 0 && [...collapsedGroupLabels].every((label) => {
30446
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30447
+ if (!og || og.parentGroup) return false;
30448
+ return og.children.every(
30449
+ (c) => pinned.has(c) && !allOriginalGroupLabels.has(c)
30450
+ );
30451
+ });
30452
+ const allPinned = pinned !== void 0 && (parsed.nodes.length > 0 || collapsedGroupLabels.size > 0) && parsed.nodes.every((n2) => pinned.has(n2.label)) && groupsAreFlat && collapsedAreFlatPinned;
30453
+ function placePinned(pins) {
30454
+ const collapsedPosByGid = /* @__PURE__ */ new Map();
30455
+ const collapsedBoxes = [];
30456
+ if (collapseInfo)
30457
+ for (const label of collapsedGroupLabels) {
30458
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30459
+ if (!og) continue;
30460
+ let cx0 = Infinity, cy0 = Infinity, cx1 = -Infinity, cy1 = -Infinity;
30461
+ for (const c of og.children) {
30462
+ const p = pins.get(c);
30463
+ if (!p) continue;
30464
+ cx0 = Math.min(cx0, p.x);
30465
+ cx1 = Math.max(cx1, p.x);
30466
+ cy0 = Math.min(cy0, p.y);
30467
+ cy1 = Math.max(cy1, p.y);
30468
+ }
30469
+ if (!Number.isFinite(cx0)) continue;
30470
+ const cx = (cx0 + cx1) / 2;
30471
+ const cy = (cy0 + cy1) / 2;
30472
+ collapsedPosByGid.set(`__group_${label}`, { x: cx, y: cy });
30473
+ collapsedBoxes.push({
30474
+ label,
30475
+ lineNumber: og.lineNumber,
30476
+ childCount: collapseInfo.collapsedChildCounts.get(label) ?? og.children.length,
30477
+ x: cx,
30478
+ y: cy
30479
+ });
30480
+ }
30481
+ const posOf = (label) => pins.get(label) ?? collapsedPosByGid.get(label);
30482
+ const rectOf = (label) => {
30483
+ const p = posOf(label);
30484
+ const s = sizes.get(label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
30485
+ return { x: p.x, y: p.y, w: s.width, h: s.height };
30486
+ };
30487
+ const nodes = parsed.nodes.map((n2) => {
30488
+ const r = rectOf(n2.label);
30489
+ return { label: n2.label, x: r.x, y: r.y, width: r.w, height: r.h };
30490
+ });
30491
+ const edges = parsed.edges.flatMap((e) => {
30492
+ const sp = posOf(e.source);
30493
+ const tp = posOf(e.target);
30494
+ if (!sp || !tp) return [];
30495
+ const srcRect = rectOf(e.source);
30496
+ const tgtRect = rectOf(e.target);
30497
+ const p0 = rectBorderPoint(srcRect, tp);
30498
+ const p1 = rectBorderPoint(tgtRect, sp);
30499
+ return [
30500
+ {
30501
+ source: e.source,
30502
+ target: e.target,
30503
+ ...e.label !== void 0 && { label: e.label },
30504
+ bidirectional: e.bidirectional,
30505
+ lineNumber: e.lineNumber,
30506
+ points: [p0, p1],
30507
+ yOffset: 0,
30508
+ parallelCount: 1,
30509
+ metadata: e.metadata,
30510
+ straight: true
30511
+ }
30512
+ ];
30513
+ });
30514
+ const GROUP_PAD = 16;
30515
+ const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
30516
+ const groups = [];
30517
+ for (const grp of parsed.groups) {
30518
+ let gx0 = Infinity, gy0 = Infinity, gx1 = -Infinity, gy1 = -Infinity;
30519
+ for (const c of grp.children) {
30520
+ const n2 = nodeByLabel.get(c);
30521
+ if (!n2) continue;
30522
+ gx0 = Math.min(gx0, n2.x - n2.width / 2);
30523
+ gx1 = Math.max(gx1, n2.x + n2.width / 2);
30524
+ gy0 = Math.min(gy0, n2.y - n2.height / 2);
30525
+ gy1 = Math.max(gy1, n2.y + n2.height / 2);
30526
+ }
30527
+ if (!Number.isFinite(gx0)) continue;
30528
+ const x0 = gx0 - GROUP_PAD;
30529
+ const x1 = gx1 + GROUP_PAD;
30530
+ const y0 = gy0 - GROUP_LABEL_ZONE2;
30531
+ const y1 = gy1 + GROUP_PAD;
30532
+ groups.push({
30533
+ label: grp.label,
30534
+ lineNumber: grp.lineNumber,
30535
+ x: (x0 + x1) / 2,
30536
+ y: (y0 + y1) / 2,
30537
+ width: x1 - x0,
30538
+ height: y1 - y0,
30539
+ collapsed: false,
30540
+ childCount: grp.children.length
30541
+ });
30542
+ }
30543
+ for (const cb of collapsedBoxes) {
30544
+ groups.push({
30545
+ label: cb.label,
30546
+ lineNumber: cb.lineNumber,
30547
+ x: cb.x,
30548
+ y: cb.y,
30549
+ width: NODE_WIDTH,
30550
+ height: NODE_HEIGHT,
30551
+ collapsed: true,
30552
+ childCount: cb.childCount
30553
+ });
30554
+ }
30555
+ const M = 40;
30556
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
30557
+ const acc = (x, y) => {
30558
+ if (x < minX) minX = x;
30559
+ if (x > maxX) maxX = x;
30560
+ if (y < minY) minY = y;
30561
+ if (y > maxY) maxY = y;
30562
+ };
30563
+ for (const n2 of nodes) {
30564
+ acc(n2.x - n2.width / 2, n2.y - n2.height / 2);
30565
+ acc(n2.x + n2.width / 2, n2.y + n2.height / 2);
30566
+ }
30567
+ for (const e of edges) for (const p of e.points) acc(p.x, p.y);
30568
+ for (const gr of groups) {
30569
+ acc(gr.x - gr.width / 2, gr.y - gr.height / 2);
30570
+ acc(gr.x + gr.width / 2, gr.y + gr.height / 2);
30571
+ }
30572
+ const TOL = 2;
30573
+ const sx = minX < M - TOL ? M - minX : 0;
30574
+ const sy = minY < M - TOL ? M - minY : 0;
30575
+ const shifted = sx !== 0 || sy !== 0;
30576
+ return {
30577
+ nodes: shifted ? nodes.map((n2) => ({ ...n2, x: n2.x + sx, y: n2.y + sy })) : nodes,
30578
+ edges: shifted ? edges.map((e) => ({
30579
+ ...e,
30580
+ points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
30581
+ })) : edges,
30582
+ groups: shifted ? groups.map((gr) => ({ ...gr, x: gr.x + sx, y: gr.y + sy })) : groups,
30583
+ width: maxX + sx + M,
30584
+ height: maxY + sy + M
30585
+ };
30586
+ }
30287
30587
  function place(cfg) {
30288
30588
  const r = cfg.seed === void 0 ? null : rng2(cfg.seed + 1);
30289
30589
  const ord = (a) => r ? shuffle(a, r) : a.slice();
@@ -30422,6 +30722,7 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30422
30722
  height: gg.height ?? 600
30423
30723
  };
30424
30724
  }
30725
+ if (allPinned) return placePinned(pinned);
30425
30726
  const n = parsed.nodes.length;
30426
30727
  const seedCount = opts?.seeds ?? (n <= 12 ? 80 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
30427
30728
  const REFINE_K = opts?.refineK ?? 6;
@@ -30616,7 +30917,7 @@ function computeNodeSize(node, reserveValueRow) {
30616
30917
  }
30617
30918
  totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
30618
30919
  const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
30619
- const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30920
+ const totalHeight = labelHeight + SEPARATOR_GAP4 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30620
30921
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
30621
30922
  }
30622
30923
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
@@ -30745,7 +31046,7 @@ function applyParallelEdgeOffsets(layout) {
30745
31046
  }))
30746
31047
  };
30747
31048
  }
30748
- 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;
31049
+ 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;
30749
31050
  var init_layout5 = __esm({
30750
31051
  "src/boxes-and-lines/layout.ts"() {
30751
31052
  "use strict";
@@ -30761,13 +31062,13 @@ var init_layout5 = __esm({
30761
31062
  DESC_FONT_SIZE2 = 10;
30762
31063
  DESC_LINE_HEIGHT2 = 1.4;
30763
31064
  DESC_PADDING = 8;
30764
- SEPARATOR_GAP5 = 4;
31065
+ SEPARATOR_GAP4 = 4;
30765
31066
  MAX_DESC_LINES2 = 6;
30766
31067
  MAX_LABEL_LINES = 3;
30767
31068
  LABEL_LINE_HEIGHT = 1.3;
30768
31069
  LABEL_PAD = 12;
30769
31070
  VALUE_ROW_FONT = 11;
30770
- VALUE_ROW_H = SEPARATOR_GAP5 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
31071
+ VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30771
31072
  }
30772
31073
  });
30773
31074
 
@@ -31529,11 +31830,11 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31529
31830
  });
31530
31831
  }
31531
31832
  for (const edge of renderLayout.edges) {
31532
- 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);
31833
+ 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);
31533
31834
  }
31534
31835
  for (const node of renderLayout.nodes) {
31535
31836
  const isRoot = node.radius === 0 && renderLayout.nodes.indexOf(node) === 0;
31536
- const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH6;
31837
+ const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH;
31537
31838
  const effectiveColor = options?.colorByDepth ? depthColor(node.depth, palette) : node.color;
31538
31839
  const fill2 = nodeFill4(
31539
31840
  palette,
@@ -31616,7 +31917,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31616
31917
  const clipId = `collapse-clip-${node.id}`;
31617
31918
  const defs = mainG.append("defs");
31618
31919
  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);
31619
- 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})`);
31920
+ 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})`);
31620
31921
  }
31621
31922
  if (onClickItem) {
31622
31923
  nodeG.style("cursor", "pointer").on("click", (event) => {
@@ -31664,7 +31965,7 @@ function renderMindmapForExport(content, theme, palette) {
31664
31965
  return extractExportSvg(container, theme);
31665
31966
  });
31666
31967
  }
31667
- var 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;
31968
+ var DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
31668
31969
  var init_renderer7 = __esm({
31669
31970
  "src/mindmap/renderer.ts"() {
31670
31971
  "use strict";
@@ -31681,6 +31982,7 @@ var init_renderer7 = __esm({
31681
31982
  init_legend_layout();
31682
31983
  init_title_constants();
31683
31984
  init_scaling();
31985
+ init_visual_conventions();
31684
31986
  DIAGRAM_PADDING7 = 20;
31685
31987
  TITLE_HEIGHT4 = 30;
31686
31988
  SINGLE_LABEL_HEIGHT2 = 28;
@@ -31688,9 +31990,6 @@ var init_renderer7 = __esm({
31688
31990
  DESC_LINE_HEIGHT4 = 14;
31689
31991
  NODE_RADIUS = 6;
31690
31992
  ROOT_STROKE_WIDTH = 2.5;
31691
- NODE_STROKE_WIDTH6 = 1.5;
31692
- EDGE_STROKE_WIDTH6 = 1.5;
31693
- COLLAPSE_BAR_HEIGHT4 = 6;
31694
31993
  DEPTH_COLOR_KEYS = [
31695
31994
  "red",
31696
31995
  "orange",
@@ -32919,10 +33218,10 @@ function computeC4NodeDimensions(el, options) {
32919
33218
  const metaEntries = collectCardMetadata(el.metadata);
32920
33219
  if (metaEntries.length > 0) {
32921
33220
  height2 += DIVIDER_GAP;
32922
- height2 += metaEntries.length * META_LINE_HEIGHT5;
33221
+ height2 += metaEntries.length * META_LINE_HEIGHT4;
32923
33222
  const maxMetaWidth = Math.max(
32924
33223
  ...metaEntries.map(
32925
- (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE5) + CARD_H_PAD3 * 2
33224
+ (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE4) + CARD_H_PAD3 * 2
32926
33225
  )
32927
33226
  );
32928
33227
  if (maxMetaWidth > width) width = Math.min(MAX_NODE_WIDTH, maxMetaWidth);
@@ -34199,7 +34498,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
34199
34498
  height: totalHeight
34200
34499
  };
34201
34500
  }
34202
- var 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;
34501
+ var 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;
34203
34502
  var init_layout8 = __esm({
34204
34503
  "src/c4/layout.ts"() {
34205
34504
  "use strict";
@@ -34217,8 +34516,8 @@ var init_layout8 = __esm({
34217
34516
  DESC_FONT_SIZE4 = 11;
34218
34517
  CARD_V_PAD3 = 14;
34219
34518
  CARD_H_PAD3 = 20;
34220
- META_LINE_HEIGHT5 = 16;
34221
- META_FONT_SIZE5 = 11;
34519
+ META_LINE_HEIGHT4 = 16;
34520
+ META_FONT_SIZE4 = 11;
34222
34521
  MARGIN6 = 40;
34223
34522
  BOUNDARY_PAD = 40;
34224
34523
  GROUP_BOUNDARY_PAD = 24;
@@ -34341,7 +34640,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34341
34640
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34342
34641
  const pathD = lineGenerator4(edge.points);
34343
34642
  if (pathD) {
34344
- 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)");
34643
+ 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)");
34345
34644
  if (dashed) {
34346
34645
  pathEl.attr("stroke-dasharray", "6 3");
34347
34646
  }
@@ -34407,7 +34706,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34407
34706
  palette.textOnFillLight,
34408
34707
  palette.textOnFillDark
34409
34708
  );
34410
- 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);
34709
+ 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);
34411
34710
  let yPos = -h / 2 + CARD_V_PAD4;
34412
34711
  const typeLabel = `\xAB${node.type}\xBB`;
34413
34712
  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);
@@ -34451,7 +34750,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34451
34750
  }
34452
34751
  if (node.drillable) {
34453
34752
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34454
- 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);
34753
+ 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);
34455
34754
  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");
34456
34755
  }
34457
34756
  }
@@ -34511,14 +34810,14 @@ function drawCylinderCard(nodeG, w, h, fill2, stroke2, dashed) {
34511
34810
  `A ${w / 2} ${ry} 0 0 1 ${-w / 2} ${h / 2 - ry}`,
34512
34811
  "Z"
34513
34812
  ].join(" ");
34514
- const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34813
+ const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34515
34814
  if (dashed) {
34516
34815
  el.attr("stroke-dasharray", "6 3");
34517
34816
  }
34518
- 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);
34817
+ 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);
34519
34818
  }
34520
34819
  function drawCardRect(nodeG, w, h, fill2, stroke2, dashed) {
34521
- 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);
34820
+ 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);
34522
34821
  if (dashed) {
34523
34822
  el.attr("stroke-dasharray", "6 3");
34524
34823
  }
@@ -34538,7 +34837,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
34538
34837
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34539
34838
  const pathD = lineGenerator4(edge.points);
34540
34839
  if (pathD) {
34541
- 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)");
34840
+ 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)");
34542
34841
  if (dashed) {
34543
34842
  pathEl.attr("stroke-dasharray", "6 3");
34544
34843
  }
@@ -35033,13 +35332,13 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35033
35332
  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);
35034
35333
  yPos += DIVIDER_GAP2;
35035
35334
  const maxKeyWidth = Math.max(
35036
- ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE6))
35335
+ ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE2))
35037
35336
  );
35038
35337
  const valueX = -w / 2 + CARD_H_PAD4 + maxKeyWidth;
35039
35338
  for (const entry of metaEntries) {
35040
- 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}:`);
35041
- 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);
35042
- yPos += META_LINE_HEIGHT6;
35339
+ 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}:`);
35340
+ 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);
35341
+ yPos += META_LINE_HEIGHT2;
35043
35342
  }
35044
35343
  }
35045
35344
  } else {
@@ -35066,7 +35365,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35066
35365
  }
35067
35366
  if (node.drillable) {
35068
35367
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
35069
- 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);
35368
+ 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);
35070
35369
  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");
35071
35370
  }
35072
35371
  }
@@ -35195,7 +35494,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
35195
35494
  document.body.removeChild(el);
35196
35495
  }
35197
35496
  }
35198
- var 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;
35497
+ var 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;
35199
35498
  var init_renderer9 = __esm({
35200
35499
  "src/c4/renderer.ts"() {
35201
35500
  "use strict";
@@ -35209,6 +35508,7 @@ var init_renderer9 = __esm({
35209
35508
  init_legend_constants();
35210
35509
  init_legend_integration();
35211
35510
  init_title_constants();
35511
+ init_visual_conventions();
35212
35512
  DIAGRAM_PADDING8 = 20;
35213
35513
  MAX_SCALE5 = 3;
35214
35514
  TITLE_HEIGHT6 = 30;
@@ -35218,16 +35518,11 @@ var init_renderer9 = __esm({
35218
35518
  DESC_LINE_HEIGHT6 = 16;
35219
35519
  EDGE_LABEL_FONT_SIZE6 = 11;
35220
35520
  TECH_FONT_SIZE = 10;
35221
- EDGE_STROKE_WIDTH7 = 1.5;
35222
- NODE_STROKE_WIDTH7 = 1.5;
35223
- CARD_RADIUS4 = 6;
35224
35521
  CARD_H_PAD4 = 20;
35225
35522
  CARD_V_PAD4 = 14;
35226
35523
  TYPE_LABEL_HEIGHT2 = 18;
35227
35524
  DIVIDER_GAP2 = 6;
35228
35525
  NAME_HEIGHT2 = 20;
35229
- META_FONT_SIZE6 = 11;
35230
- META_LINE_HEIGHT6 = 16;
35231
35526
  BOUNDARY_LABEL_FONT_SIZE = 12;
35232
35527
  BOUNDARY_STROKE_WIDTH = 1.5;
35233
35528
  BOUNDARY_RADIUS = 8;
@@ -35632,7 +35927,7 @@ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff,
35632
35927
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
35633
35928
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
35634
35929
  }
35635
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35930
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35636
35931
  const w = node.width;
35637
35932
  const h = node.height;
35638
35933
  const rx = h / 2;
@@ -35644,7 +35939,7 @@ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeS
35644
35939
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
35645
35940
  ).attr("stroke-width", sNodeStrokeWidth);
35646
35941
  }
35647
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35942
+ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35648
35943
  const w = node.width;
35649
35944
  const h = node.height;
35650
35945
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -35663,7 +35958,7 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
35663
35958
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35664
35959
  ).attr("stroke-width", sNodeStrokeWidth);
35665
35960
  }
35666
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35961
+ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35667
35962
  const w = node.width / 2;
35668
35963
  const h = node.height / 2;
35669
35964
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -35685,7 +35980,7 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35685
35980
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35686
35981
  ).attr("stroke-width", sNodeStrokeWidth);
35687
35982
  }
35688
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW) {
35983
+ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
35689
35984
  const w = node.width / 2;
35690
35985
  const h = node.height / 2;
35691
35986
  const sk = sIoSkew;
@@ -35711,7 +36006,7 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
35711
36006
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35712
36007
  ).attr("stroke-width", sNodeStrokeWidth);
35713
36008
  }
35714
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sSubroutineInset = SUBROUTINE_INSET) {
36009
+ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
35715
36010
  const w = node.width;
35716
36011
  const h = node.height;
35717
36012
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -35729,7 +36024,7 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
35729
36024
  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);
35730
36025
  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);
35731
36026
  }
35732
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36027
+ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35733
36028
  const w = node.width;
35734
36029
  const h = node.height;
35735
36030
  const waveH = sDocWaveHeight;
@@ -35760,7 +36055,7 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35760
36055
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35761
36056
  ).attr("stroke-width", sNodeStrokeWidth);
35762
36057
  }
35763
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36058
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35764
36059
  switch (node.shape) {
35765
36060
  case "terminal":
35766
36061
  renderTerminal(
@@ -35847,8 +36142,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
35847
36142
  const sTitleY = ctx.structural(TITLE_Y);
35848
36143
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
35849
36144
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
35850
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH8);
35851
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH8);
36145
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
36146
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
35852
36147
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
35853
36148
  const sArrowheadH = ctx.structural(ARROWHEAD_H3);
35854
36149
  const sIoSkew = ctx.structural(IO_SKEW);
@@ -36072,7 +36367,7 @@ function renderFlowchartForExport(content, theme, palette) {
36072
36367
  document.body.removeChild(container);
36073
36368
  }
36074
36369
  }
36075
- var 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;
36370
+ var DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36076
36371
  var init_flowchart_renderer = __esm({
36077
36372
  "src/graph/flowchart-renderer.ts"() {
36078
36373
  "use strict";
@@ -36087,12 +36382,11 @@ var init_flowchart_renderer = __esm({
36087
36382
  init_scaling();
36088
36383
  init_text_measure();
36089
36384
  init_note_box();
36385
+ init_visual_conventions();
36090
36386
  DIAGRAM_PADDING9 = 20;
36091
36387
  MAX_SCALE6 = 3;
36092
36388
  NODE_FONT_SIZE2 = 13;
36093
36389
  EDGE_LABEL_FONT_SIZE7 = 11;
36094
- EDGE_STROKE_WIDTH8 = 1.5;
36095
- NODE_STROKE_WIDTH8 = 1.5;
36096
36390
  ARROWHEAD_W3 = 10;
36097
36391
  ARROWHEAD_H3 = 7;
36098
36392
  IO_SKEW = 15;
@@ -37077,7 +37371,7 @@ function hasRoles(node) {
37077
37371
  }
37078
37372
  function computeNodeWidth2(node, expanded, options) {
37079
37373
  const badgeVal = node.computedConcurrentInvocations === 0 && node.computedInstances > 1 ? node.computedInstances : 0;
37080
- const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE7) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37374
+ const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE5) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37081
37375
  const labelWidth2 = measureText(node.label, NODE_FONT_SIZE3) + badgeWidth + PADDING_X3;
37082
37376
  const allKeys = [];
37083
37377
  if (node.computedRps > 0) allKeys.push("RPS");
@@ -37124,7 +37418,7 @@ function computeNodeWidth2(node, expanded, options) {
37124
37418
  }
37125
37419
  if (allKeys.length === 0) return Math.max(MIN_NODE_WIDTH2, labelWidth2);
37126
37420
  const keyColWidth = Math.max(
37127
- ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE7))
37421
+ ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE5))
37128
37422
  );
37129
37423
  let maxRowWidth = 0;
37130
37424
  if (node.computedRps > 0) {
@@ -37137,7 +37431,7 @@ function computeNodeWidth2(node, expanded, options) {
37137
37431
  const rpsVal = effectiveCap > 0 && !node.isEdge ? `${formatRpsShort(node.computedRps)} / ${formatRpsShort(effectiveCap)}` : formatRps(node.computedRps);
37138
37432
  maxRowWidth = Math.max(
37139
37433
  maxRowWidth,
37140
- keyColWidth + measureText(rpsVal, META_FONT_SIZE7)
37434
+ keyColWidth + measureText(rpsVal, META_FONT_SIZE5)
37141
37435
  );
37142
37436
  }
37143
37437
  if (expanded) {
@@ -37154,7 +37448,7 @@ function computeNodeWidth2(node, expanded, options) {
37154
37448
  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);
37155
37449
  maxRowWidth = Math.max(
37156
37450
  maxRowWidth,
37157
- keyColWidth + measureText(valStr, META_FONT_SIZE7)
37451
+ keyColWidth + measureText(valStr, META_FONT_SIZE5)
37158
37452
  );
37159
37453
  }
37160
37454
  }
@@ -37165,7 +37459,7 @@ function computeNodeWidth2(node, expanded, options) {
37165
37459
  if (ms > 0) {
37166
37460
  maxRowWidth = Math.max(
37167
37461
  maxRowWidth,
37168
- keyColWidth + measureText(formatMs(ms), META_FONT_SIZE7)
37462
+ keyColWidth + measureText(formatMs(ms), META_FONT_SIZE5)
37169
37463
  );
37170
37464
  }
37171
37465
  }
@@ -37176,37 +37470,37 @@ function computeNodeWidth2(node, expanded, options) {
37176
37470
  const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
37177
37471
  maxRowWidth = Math.max(
37178
37472
  maxRowWidth,
37179
- keyColWidth + measureText(combinedVal, META_FONT_SIZE7)
37473
+ keyColWidth + measureText(combinedVal, META_FONT_SIZE5)
37180
37474
  );
37181
37475
  }
37182
37476
  }
37183
37477
  if (node.computedUptime < 1) {
37184
37478
  maxRowWidth = Math.max(
37185
37479
  maxRowWidth,
37186
- keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE7)
37480
+ keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE5)
37187
37481
  );
37188
37482
  }
37189
37483
  if (node.computedAvailability < 1) {
37190
37484
  maxRowWidth = Math.max(
37191
37485
  maxRowWidth,
37192
- keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE7)
37486
+ keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE5)
37193
37487
  );
37194
37488
  }
37195
37489
  if (node.computedCbState === "open") {
37196
37490
  maxRowWidth = Math.max(
37197
37491
  maxRowWidth,
37198
- measureText("CB: OPEN", META_FONT_SIZE7) + 8
37492
+ measureText("CB: OPEN", META_FONT_SIZE5) + 8
37199
37493
  );
37200
37494
  }
37201
37495
  }
37202
- const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE7;
37496
+ const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE5;
37203
37497
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
37204
37498
  let descWidth = 0;
37205
37499
  for (const dl of descLines) {
37206
- const truncated = truncateText(dl, META_FONT_SIZE7, DESC_MAX_WIDTH2);
37500
+ const truncated = truncateText(dl, META_FONT_SIZE5, DESC_MAX_WIDTH2);
37207
37501
  descWidth = Math.max(
37208
37502
  descWidth,
37209
- measureText(truncated, META_FONT_SIZE7) + PADDING_X3
37503
+ measureText(truncated, META_FONT_SIZE5) + PADDING_X3
37210
37504
  );
37211
37505
  }
37212
37506
  return Math.max(MIN_NODE_WIDTH2, labelWidth2, maxRowWidth + 20, descWidth);
@@ -37216,17 +37510,17 @@ function computeNodeHeight2(node, expanded, options) {
37216
37510
  const computedCount = countComputedRows(node, expanded);
37217
37511
  const hasRps = node.computedRps > 0;
37218
37512
  const descLineCount = expanded && node.description && !node.isEdge ? node.description.length : 0;
37219
- const descH = descLineCount * META_LINE_HEIGHT7;
37513
+ const descH = descLineCount * META_LINE_HEIGHT5;
37220
37514
  if (propCount === 0 && computedCount === 0 && !hasRps)
37221
37515
  return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
37222
37516
  let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
37223
37517
  const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
37224
- h += computedSectionCount * META_LINE_HEIGHT7;
37518
+ h += computedSectionCount * META_LINE_HEIGHT5;
37225
37519
  if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
37226
- h += propCount * META_LINE_HEIGHT7;
37520
+ h += propCount * META_LINE_HEIGHT5;
37227
37521
  if (hasRoles(node)) h += ROLE_DOT_ROW;
37228
37522
  h += NODE_PAD_BOTTOM;
37229
- if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT5;
37523
+ if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT3;
37230
37524
  return h;
37231
37525
  }
37232
37526
  function formatRps(rps) {
@@ -37561,20 +37855,20 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
37561
37855
  height: totalHeight
37562
37856
  };
37563
37857
  }
37564
- var 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;
37858
+ var 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;
37565
37859
  var init_layout10 = __esm({
37566
37860
  "src/infra/layout.ts"() {
37567
37861
  "use strict";
37568
37862
  init_text_measure();
37569
37863
  MIN_NODE_WIDTH2 = 140;
37570
37864
  NODE_HEADER_HEIGHT = 28;
37571
- META_LINE_HEIGHT7 = 14;
37865
+ META_LINE_HEIGHT5 = 14;
37572
37866
  NODE_SEPARATOR_GAP = 4;
37573
37867
  NODE_PAD_BOTTOM = 10;
37574
37868
  ROLE_DOT_ROW = 12;
37575
- COLLAPSE_BAR_HEIGHT5 = 6;
37869
+ COLLAPSE_BAR_HEIGHT3 = 6;
37576
37870
  NODE_FONT_SIZE3 = 13;
37577
- META_FONT_SIZE7 = 10;
37871
+ META_FONT_SIZE5 = 10;
37578
37872
  EDGE_LABEL_FONT_SIZE8 = 11;
37579
37873
  PADDING_X3 = 24;
37580
37874
  GROUP_PADDING2 = 20;
@@ -37680,19 +37974,19 @@ import * as d3Shape8 from "d3-shape";
37680
37974
  function buildScaledConstants(ctx) {
37681
37975
  return {
37682
37976
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
37683
- sMetaFontSize: ctx.text(META_FONT_SIZE8),
37684
- sMetaLineHeight: ctx.structural(META_LINE_HEIGHT8),
37977
+ sMetaFontSize: ctx.text(META_FONT_SIZE6),
37978
+ sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
37685
37979
  sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
37686
37980
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
37687
37981
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
37688
- sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH9),
37689
- sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH9),
37982
+ sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
37983
+ sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH),
37690
37984
  sOverloadStrokeWidth: ctx.structural(OVERLOAD_STROKE_WIDTH),
37691
37985
  sRoleDotRadius: ctx.structural(ROLE_DOT_RADIUS),
37692
37986
  sNodeSeparatorGap: ctx.structural(NODE_SEPARATOR_GAP2),
37693
37987
  sNodePadBottom: ctx.structural(NODE_PAD_BOTTOM2),
37694
- sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT6),
37695
- sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET2),
37988
+ sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT),
37989
+ sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET),
37696
37990
  sParticleR: ctx.structural(PARTICLE_R),
37697
37991
  sRejectParticleR: ctx.structural(PARTICLE_R),
37698
37992
  sRejectDropDistance: ctx.structural(REJECT_DROP_DISTANCE),
@@ -38016,7 +38310,7 @@ function isWarning(node) {
38016
38310
  return cap > 0 && node.computedRps / cap > 0.7;
38017
38311
  }
38018
38312
  function truncateDesc(text) {
38019
- return truncateText(text, META_FONT_SIZE8, DESC_MAX_WIDTH);
38313
+ return truncateText(text, META_FONT_SIZE6, DESC_MAX_WIDTH);
38020
38314
  }
38021
38315
  function sloLatencyColor(p90, slo) {
38022
38316
  const t = slo.latencyP90 ?? 0;
@@ -38495,7 +38789,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38495
38789
  if (!isNodeCollapsed) {
38496
38790
  const expanded = expandedNodeIds?.has(node.id) ?? false;
38497
38791
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
38498
- const descH = descLines.length * META_LINE_HEIGHT8;
38792
+ const descH = descLines.length * META_LINE_HEIGHT6;
38499
38793
  for (let di = 0; di < descLines.length; di++) {
38500
38794
  const rawLine = descLines[di];
38501
38795
  const processed = preprocessDescriptionLine(rawLine);
@@ -38503,7 +38797,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38503
38797
  const isTruncated = descTruncated !== processed;
38504
38798
  const textEl = g.append("text").attr("x", node.x).attr(
38505
38799
  "y",
38506
- y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT8 + META_LINE_HEIGHT8 / 2 + sc.sMetaFontSize * 0.35
38800
+ y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT6 + META_LINE_HEIGHT6 / 2 + sc.sMetaFontSize * 0.35
38507
38801
  ).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sMetaFontSize).attr("fill", textFill);
38508
38802
  renderInlineText(textEl, descTruncated, palette, sc.sMetaFontSize);
38509
38803
  if (isTruncated) textEl.append("title").text(rawLine);
@@ -39021,7 +39315,7 @@ function parseAndLayoutInfra(content) {
39021
39315
  const layout = layoutInfra(computed);
39022
39316
  return { parsed, computed, layout };
39023
39317
  }
39024
- var 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;
39318
+ var 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;
39025
39319
  var init_renderer10 = __esm({
39026
39320
  "src/infra/renderer.ts"() {
39027
39321
  "use strict";
@@ -39040,21 +39334,18 @@ var init_renderer10 = __esm({
39040
39334
  init_legend_layout();
39041
39335
  init_title_constants();
39042
39336
  init_scaling();
39337
+ init_visual_conventions();
39043
39338
  NODE_FONT_SIZE4 = 13;
39044
- META_FONT_SIZE8 = 10;
39045
- META_LINE_HEIGHT8 = 14;
39339
+ META_FONT_SIZE6 = 10;
39340
+ META_LINE_HEIGHT6 = 14;
39046
39341
  EDGE_LABEL_FONT_SIZE9 = 11;
39047
39342
  GROUP_LABEL_FONT_SIZE2 = 14;
39048
39343
  NODE_BORDER_RADIUS = 8;
39049
- EDGE_STROKE_WIDTH9 = 1.5;
39050
- NODE_STROKE_WIDTH9 = 1.5;
39051
39344
  OVERLOAD_STROKE_WIDTH = 3;
39052
39345
  ROLE_DOT_RADIUS = 3;
39053
39346
  NODE_HEADER_HEIGHT2 = 28;
39054
39347
  NODE_SEPARATOR_GAP2 = 4;
39055
39348
  NODE_PAD_BOTTOM2 = 10;
39056
- COLLAPSE_BAR_HEIGHT6 = 6;
39057
- COLLAPSE_BAR_INSET2 = 0;
39058
39349
  LEGEND_FIXED_GAP3 = 16;
39059
39350
  SPEED_BADGE_H_PAD = 5;
39060
39351
  SPEED_BADGE_V_PAD = 3;
@@ -39093,7 +39384,7 @@ var init_renderer10 = __esm({
39093
39384
  partitions: "partitions"
39094
39385
  };
39095
39386
  DESC_MAX_CHARS = 120;
39096
- DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE8;
39387
+ DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE6;
39097
39388
  RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
39098
39389
  MS_FORMAT_KEYS = /* @__PURE__ */ new Set([
39099
39390
  "latency-ms",
@@ -40882,18 +41173,18 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
40882
41173
  const sLegendPillHeight = ctx.structural(LEGEND_PILL_HEIGHT);
40883
41174
  const sLegendBlockHeight = showTagLegend ? sLegendTopGap + sLegendPillHeight + sLegendBottomGap : 0;
40884
41175
  const sNodeRadius = ctx.structural(NODE_RADIUS2);
40885
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH10);
41176
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
40886
41177
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE5);
40887
41178
  const sNodeCellFontSize = ctx.text(NODE_CELL_FONT_SIZE2);
40888
41179
  const sNodeTopRowHeight = ctx.structural(NODE_TOP_ROW_HEIGHT);
40889
41180
  const sNodeBottomRowHeight = ctx.structural(NODE_BOTTOM_ROW_HEIGHT);
40890
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH10);
41181
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
40891
41182
  const sArrowheadW = ctx.structural(ARROWHEAD_W4);
40892
41183
  const sArrowheadH = ctx.structural(ARROWHEAD_H4);
40893
- const sContainerRadius = ctx.structural(CONTAINER_RADIUS3);
40894
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE4);
40895
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT3);
40896
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT7);
41184
+ const sContainerRadius = ctx.structural(CONTAINER_RADIUS);
41185
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
41186
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
41187
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
40897
41188
  const sPinIconW = ctx.structural(PIN_ICON_W);
40898
41189
  const sPinIconH = ctx.structural(PIN_ICON_H);
40899
41190
  const scaledWidth = layout.width + sDiagramPad * 2;
@@ -41460,7 +41751,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41460
41751
  palette.textOnFillDark
41461
41752
  );
41462
41753
  const sNR = sc.nodeRadius ?? NODE_RADIUS2;
41463
- const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT7;
41754
+ const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT;
41464
41755
  drawTextbookCard(g, {
41465
41756
  width: grp.width,
41466
41757
  height: grp.height,
@@ -41494,10 +41785,10 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41494
41785
  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})`);
41495
41786
  continue;
41496
41787
  }
41497
- const sCR = sc.containerRadius ?? CONTAINER_RADIUS3;
41498
- const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE4;
41499
- const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT3;
41500
- const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41788
+ const sCR = sc.containerRadius ?? CONTAINER_RADIUS;
41789
+ const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE;
41790
+ const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT;
41791
+ const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH;
41501
41792
  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);
41502
41793
  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);
41503
41794
  }
@@ -41550,7 +41841,7 @@ function renderEdges2(root, resolved, layout, palette, collapsedSet, sc = {}) {
41550
41841
  }
41551
41842
  const path = lineGenerator6(e.points);
41552
41843
  if (!path) continue;
41553
- const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH10;
41844
+ const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH;
41554
41845
  const sELFS = sc.edgeLabelFontSize ?? 10;
41555
41846
  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 ?? "");
41556
41847
  const parsedEdge = edgeByKey.get(`${e.source}->${e.target}`);
@@ -41732,7 +42023,7 @@ function computeDurationEmphasis(activities) {
41732
42023
  function drawTextbookCard(g, a) {
41733
42024
  const { width: w, height: h, x, y } = a;
41734
42025
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41735
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42026
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41736
42027
  const sTRH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41737
42028
  const sBRH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41738
42029
  const sNFS = a.sNodeFontSize ?? NODE_FONT_SIZE5;
@@ -41831,7 +42122,7 @@ function drawTextbookCard(g, a) {
41831
42122
  function drawMilestonePill(g, a) {
41832
42123
  const { width: w, height: h, x, y } = a;
41833
42124
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41834
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42125
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41835
42126
  const topRowH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41836
42127
  const botRowH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41837
42128
  const sNCFS = a.sNodeCellFontSize ?? NODE_CELL_FONT_SIZE2;
@@ -41964,7 +42255,7 @@ function renderCaptionBlock(svg, bullets, args) {
41964
42255
  palette.textOnFillDark
41965
42256
  );
41966
42257
  const block = svg.append("g").attr("class", "pert-caption-block").attr("data-pert-caption", "");
41967
- 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);
42258
+ 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);
41968
42259
  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");
41969
42260
  const textX = x + CAPTION_BOX_PADDING_X;
41970
42261
  const firstBaselineY = y + CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT + CAPTION_FONT_SIZE;
@@ -42081,7 +42372,7 @@ function renderTornadoBlock(svg, rows, args) {
42081
42372
  palette.textOnFillDark
42082
42373
  );
42083
42374
  const block = svg.append("g").attr("class", "pert-tornado-block").attr("data-pert-tornado", "");
42084
- 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);
42375
+ 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);
42085
42376
  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");
42086
42377
  const fmt = (v) => {
42087
42378
  const r = Math.round(v * 100) / 100;
@@ -42237,7 +42528,7 @@ function renderScurveBlock(svg, data, args) {
42237
42528
  palette.textOnFillDark
42238
42529
  );
42239
42530
  const block = svg.append("g").attr("class", "pert-scurve-block").attr("data-pert-scurve", "");
42240
- 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);
42531
+ 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);
42241
42532
  const hasTitle = typeof title === "string" && title.length > 0;
42242
42533
  if (hasTitle) {
42243
42534
  const titleText = title.replace(/\.$/, "");
@@ -42421,7 +42712,7 @@ function formatScurveDate(iso) {
42421
42712
  if (month < 0 || month > 11 || isNaN(day)) return iso;
42422
42713
  return `${SCURVE_MONTH_NAMES[month]} ${day}`;
42423
42714
  }
42424
- var 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;
42715
+ var 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;
42425
42716
  var init_renderer11 = __esm({
42426
42717
  "src/pert/renderer.ts"() {
42427
42718
  "use strict";
@@ -42437,20 +42728,15 @@ var init_renderer11 = __esm({
42437
42728
  init_analyzer();
42438
42729
  init_layout11();
42439
42730
  init_internal();
42731
+ init_visual_conventions();
42440
42732
  DIAGRAM_PADDING11 = 20;
42441
42733
  NODE_FONT_SIZE5 = 13;
42442
42734
  NODE_CELL_FONT_SIZE2 = 11;
42443
42735
  NODE_RADIUS2 = 6;
42444
- NODE_STROKE_WIDTH10 = 1.5;
42445
42736
  NODE_TOP_ROW_HEIGHT = 26;
42446
42737
  NODE_BOTTOM_ROW_HEIGHT = 26;
42447
- EDGE_STROKE_WIDTH10 = 1.5;
42448
42738
  ARROWHEAD_W4 = 10;
42449
42739
  ARROWHEAD_H4 = 7;
42450
- CONTAINER_RADIUS3 = 8;
42451
- CONTAINER_LABEL_FONT_SIZE4 = 13;
42452
- CONTAINER_HEADER_HEIGHT3 = 28;
42453
- COLLAPSE_BAR_HEIGHT7 = 6;
42454
42740
  DURATION_FADE_OPACITY = 0.55;
42455
42741
  PIN_ICON_W = 13;
42456
42742
  PIN_ICON_H = 13;
@@ -45442,8 +45728,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
45442
45728
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
45443
45729
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
45444
45730
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
45445
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH11);
45446
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH11);
45731
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
45732
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
45447
45733
  const sArrowheadW = ctx.structural(ARROWHEAD_W5);
45448
45734
  const sArrowheadH = ctx.structural(ARROWHEAD_H5);
45449
45735
  const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
@@ -45720,7 +46006,7 @@ function renderStateForExport(content, theme, palette) {
45720
46006
  document.body.removeChild(container);
45721
46007
  }
45722
46008
  }
45723
- var 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;
46009
+ var 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;
45724
46010
  var init_state_renderer = __esm({
45725
46011
  "src/graph/state-renderer.ts"() {
45726
46012
  "use strict";
@@ -45735,13 +46021,12 @@ var init_state_renderer = __esm({
45735
46021
  init_scaling();
45736
46022
  init_text_measure();
45737
46023
  init_note_box();
46024
+ init_visual_conventions();
45738
46025
  DIAGRAM_PADDING12 = 20;
45739
46026
  MAX_SCALE7 = 3;
45740
46027
  NODE_FONT_SIZE6 = 13;
45741
46028
  EDGE_LABEL_FONT_SIZE10 = 11;
45742
46029
  GROUP_LABEL_FONT_SIZE3 = 11;
45743
- EDGE_STROKE_WIDTH11 = 1.5;
45744
- NODE_STROKE_WIDTH11 = 1.5;
45745
46030
  ARROWHEAD_W5 = 10;
45746
46031
  ARROWHEAD_H5 = 7;
45747
46032
  PSEUDOSTATE_RADIUS = 10;
@@ -47456,14 +47741,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47456
47741
  const panelY = PADDING2;
47457
47742
  const textX = panelX + CARD_PADDING_X3;
47458
47743
  const clipId = "persona-clip";
47459
- defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5);
47744
+ defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
47460
47745
  const personaFill = shapeFill(palette, personaColor, isDark, { solid });
47461
47746
  const onPersonaText = contrastText(
47462
47747
  personaFill,
47463
47748
  palette.textOnFillLight,
47464
47749
  palette.textOnFillDark
47465
47750
  );
47466
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", personaFill);
47751
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
47467
47752
  if (descLines.length > 0) {
47468
47753
  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);
47469
47754
  }
@@ -47471,7 +47756,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47471
47756
  const silY = panelY + panelHeight / 2 - 6;
47472
47757
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
47473
47758
  renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
47474
- 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);
47759
+ 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);
47475
47760
  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);
47476
47761
  for (let li = 0; li < descLines.length; li++) {
47477
47762
  const lineEl = personaG.append("text").attr("x", textX).attr("y", panelY + titleRowH + descLineH * (li + 1)).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
@@ -47711,7 +47996,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47711
47996
  { solid }
47712
47997
  );
47713
47998
  const rowStroke = stepColor ?? palette.textMuted;
47714
- 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);
47999
+ 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);
47715
48000
  const faceCx = listX + CARD_PADDING_X3 + COLLAPSED_FACE_R;
47716
48001
  const faceCy = itemY + COLLAPSED_CARD_H / 2;
47717
48002
  if (step.score !== void 0) {
@@ -47874,7 +48159,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47874
48159
  const scoreColor = scoreToColor(score, palette);
47875
48160
  const tintedBg = mix(scoreColor, palette.surface, 20);
47876
48161
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
47877
- 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);
48162
+ 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);
47878
48163
  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);
47879
48164
  const centerX = bx + bw / 2;
47880
48165
  for (let i = 0; i < lines.length; i++) {
@@ -48031,7 +48316,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48031
48316
  palette.textOnFillLight,
48032
48317
  palette.textOnFillDark
48033
48318
  );
48034
- 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);
48319
+ 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);
48035
48320
  const titleMaxW = sl.width - CARD_PADDING_X3 * 2;
48036
48321
  const titleLines = wrapTextToWidth(sl.step.title, FONT_SIZE_STEP, titleMaxW);
48037
48322
  for (let i = 0; i < titleLines.length; i++) {
@@ -48090,7 +48375,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48090
48375
  const stripFill = shapeFill(palette, stripColor, isDark, {
48091
48376
  ...solid !== void 0 && { solid }
48092
48377
  });
48093
- 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);
48378
+ 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);
48094
48379
  const stripTextColor = contrastText(
48095
48380
  stripFill,
48096
48381
  palette.textOnFillLight,
@@ -48206,7 +48491,7 @@ function renderJourneyMapForExport(content, theme, palette) {
48206
48491
  }
48207
48492
  return svgEl.outerHTML;
48208
48493
  }
48209
- var 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;
48494
+ var 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;
48210
48495
  var init_renderer14 = __esm({
48211
48496
  "src/journey-map/renderer.ts"() {
48212
48497
  "use strict";
@@ -48219,9 +48504,9 @@ var init_renderer14 = __esm({
48219
48504
  init_tag_groups();
48220
48505
  init_scaling();
48221
48506
  init_text_measure();
48507
+ init_visual_conventions();
48222
48508
  DIAGRAM_PADDING13 = 20;
48223
48509
  PADDING2 = DIAGRAM_PADDING13;
48224
- CARD_RADIUS5 = 6;
48225
48510
  CARD_PADDING_X3 = 10;
48226
48511
  CARD_PADDING_Y3 = 6;
48227
48512
  CARD_HEADER_HEIGHT3 = 24;
@@ -48298,7 +48583,7 @@ function computeCycleLayout(parsed, options) {
48298
48583
  const hasDesc = !hideDescriptions && node.description.length > 0;
48299
48584
  const labelWidth2 = Math.max(
48300
48585
  MIN_NODE_WIDTH4,
48301
- measureText(node.label, LABEL_FONT_SIZE5) + NODE_PAD_X * 2
48586
+ measureText(node.label, LABEL_FONT_SIZE4) + NODE_PAD_X * 2
48302
48587
  );
48303
48588
  if (circleNodes) {
48304
48589
  return computeCircleNodeDims(node, hasDesc);
@@ -48515,7 +48800,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48515
48800
  let bestScore = Infinity;
48516
48801
  for (let w = minW; w <= MAX_NODE_WIDTH3; w += DESC_WIDTH_STEP) {
48517
48802
  const wrapped2 = wrapDescForWidth(description, w);
48518
- const h = HEADER_HEIGHT5 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48803
+ const h = HEADER_HEIGHT4 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48519
48804
  const ratio = w / h;
48520
48805
  const score = Math.abs(Math.log(ratio / DESC_TARGET_RATIO));
48521
48806
  if (score < bestScore) {
@@ -48527,7 +48812,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48527
48812
  const wrapped = wrapDescForWidth(description, minW);
48528
48813
  return {
48529
48814
  width: minW,
48530
- height: HEADER_HEIGHT5 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48815
+ height: HEADER_HEIGHT4 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48531
48816
  wrappedDesc: wrapped
48532
48817
  };
48533
48818
  }
@@ -48540,7 +48825,7 @@ function wrapDescForWidth(description, nodeWidth) {
48540
48825
  );
48541
48826
  }
48542
48827
  function renderedDescNodeHeight(numLines, scale) {
48543
- const headerH = HEADER_HEIGHT5 * scale;
48828
+ const headerH = HEADER_HEIGHT4 * scale;
48544
48829
  const descFont = Math.max(
48545
48830
  RENDERER_DESC_FONT_MIN,
48546
48831
  Math.round(RENDERER_DESC_FONT * scale)
@@ -48875,7 +49160,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
48875
49160
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
48876
49161
  return { path, midAngle };
48877
49162
  }
48878
- 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;
49163
+ 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;
48879
49164
  var init_layout14 = __esm({
48880
49165
  "src/cycle/layout.ts"() {
48881
49166
  "use strict";
@@ -48883,7 +49168,7 @@ var init_layout14 = __esm({
48883
49168
  init_wrapped_desc();
48884
49169
  init_text_measure();
48885
49170
  MIN_ARC_ANGLE = 15 * Math.PI / 180;
48886
- LABEL_FONT_SIZE5 = 13;
49171
+ LABEL_FONT_SIZE4 = 13;
48887
49172
  CIRCLE_LABEL_FONT_SIZE = 16;
48888
49173
  DESC_FONT_SIZE6 = 11;
48889
49174
  EDGE_LABEL_FONT_SIZE11 = 11;
@@ -48893,7 +49178,7 @@ var init_layout14 = __esm({
48893
49178
  DESC_WIDTH_STEP = 20;
48894
49179
  DESC_TARGET_RATIO = 1.6;
48895
49180
  PLAIN_NODE_HEIGHT = 50;
48896
- HEADER_HEIGHT5 = 36;
49181
+ HEADER_HEIGHT4 = 36;
48897
49182
  DESC_LINE_HEIGHT7 = 16;
48898
49183
  DESC_PAD_Y = 14;
48899
49184
  NODE_PAD_X = 20;
@@ -53000,6 +53285,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53000
53285
  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);
53001
53286
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
53002
53287
  const defs = svg.append("defs");
53288
+ const uid = mapInstanceCounter++;
53289
+ const nid = (base) => `${base}__m${uid}`;
53003
53290
  const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
53004
53291
  const haloColor = palette.bg;
53005
53292
  const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
@@ -53032,8 +53319,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53032
53319
  for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
53033
53320
  if (layout.relief.length && layout.reliefHatch) {
53034
53321
  const h = layout.reliefHatch;
53035
- const rangeClipId = "dgmo-relief-clip";
53036
- const landClipId = "dgmo-relief-land";
53322
+ const rangeClipId = nid("dgmo-relief-clip");
53323
+ const landClipId = nid("dgmo-relief-land");
53037
53324
  const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
53038
53325
  for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
53039
53326
  const landClip = defs.append("clipPath").attr("id", landClipId);
@@ -53046,7 +53333,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53046
53333
  }
53047
53334
  if (layout.coastlineStyle) {
53048
53335
  const cs = layout.coastlineStyle;
53049
- const maskId = "dgmo-map-water-mask";
53336
+ const maskId = nid("dgmo-map-water-mask");
53050
53337
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53051
53338
  mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
53052
53339
  const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
@@ -53064,7 +53351,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53064
53351
  appendWaterLines(
53065
53352
  gWater,
53066
53353
  defs,
53067
- "dgmo-map-coast",
53354
+ nid("dgmo-map-coast"),
53068
53355
  // Pass the canvas frame so edges collinear with it (the antimeridian on a
53069
53356
  // world map, regional clipExtent cuts) don't get ringed as fake coast —
53070
53357
  // land runs cleanly to the render-area edge.
@@ -53101,7 +53388,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53101
53388
  (l) => l.poiId !== void 0 && !l.hidden
53102
53389
  );
53103
53390
  if (poiLabels.length) {
53104
- const patchBlurId = "dgmo-map-label-patch-blur";
53391
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
53105
53392
  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);
53106
53393
  const PAD = 8;
53107
53394
  const buildPatch = (labels, maskId, decoCluster) => {
@@ -53146,7 +53433,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53146
53433
  if (clusterUi) {
53147
53434
  buildPatch(
53148
53435
  poiLabels.filter((l) => l.clusterMember === void 0),
53149
- "dgmo-map-label-patch"
53436
+ nid("dgmo-map-label-patch")
53150
53437
  );
53151
53438
  const byCluster = /* @__PURE__ */ new Map();
53152
53439
  for (const l of poiLabels) {
@@ -53157,9 +53444,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53157
53444
  }
53158
53445
  let ci = 0;
53159
53446
  for (const [cid, labs] of byCluster)
53160
- buildPatch(labs, `dgmo-map-label-patch-c${ci++}`, cid);
53447
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
53161
53448
  } else {
53162
- buildPatch(poiLabels, "dgmo-map-label-patch");
53449
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
53163
53450
  }
53164
53451
  }
53165
53452
  if (layout.insets.length) {
@@ -53168,7 +53455,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53168
53455
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
53169
53456
  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");
53170
53457
  if (box.contextLand) {
53171
- const clipId = `dgmo-map-inset-clip-${bi}`;
53458
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
53172
53459
  defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
53173
53460
  insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
53174
53461
  }
@@ -53176,7 +53463,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53176
53463
  for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
53177
53464
  if (layout.coastlineStyle) {
53178
53465
  const cs = layout.coastlineStyle;
53179
- const maskId = "dgmo-map-inset-water-mask";
53466
+ const maskId = nid("dgmo-map-inset-water-mask");
53180
53467
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53181
53468
  const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
53182
53469
  for (const box of layout.insets) {
@@ -53185,7 +53472,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53185
53472
  }
53186
53473
  layout.insets.forEach((box, bi) => {
53187
53474
  if (box.contextLand)
53188
- mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#dgmo-map-inset-clip-${bi})`);
53475
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
53189
53476
  });
53190
53477
  for (const r of layout.insetRegions)
53191
53478
  if (r.id !== "lake")
@@ -53193,7 +53480,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53193
53480
  for (const r of layout.insetRegions)
53194
53481
  if (r.id === "lake")
53195
53482
  mask.append("path").attr("d", r.d).attr("fill", "white");
53196
- const clipId = "dgmo-map-inset-water-clip";
53483
+ const clipId = nid("dgmo-map-inset-water-clip");
53197
53484
  const clip = defs.append("clipPath").attr("id", clipId);
53198
53485
  for (const box of layout.insets) {
53199
53486
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
@@ -53203,7 +53490,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53203
53490
  appendWaterLines(
53204
53491
  gInsetWater,
53205
53492
  defs,
53206
- "dgmo-map-inset-coast",
53493
+ nid("dgmo-map-inset-coast"),
53207
53494
  coastlineOuterRings(layout.insetRegions, cs.minExtent),
53208
53495
  cs,
53209
53496
  layout.background
@@ -53232,7 +53519,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53232
53519
  }
53233
53520
  wireSync(p, leg.lineNumber);
53234
53521
  if (leg.arrow) {
53235
- const id = `dgmo-map-arrow-${i}`;
53522
+ const id = nid(`dgmo-map-arrow-${i}`);
53236
53523
  const s = arrowSize(leg.width);
53237
53524
  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);
53238
53525
  p.attr("marker-end", `url(#${id})`);
@@ -53428,7 +53715,7 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
53428
53715
  }
53429
53716
  return t;
53430
53717
  }
53431
- var LABEL_FONT;
53718
+ var LABEL_FONT, mapInstanceCounter;
53432
53719
  var init_renderer16 = __esm({
53433
53720
  "src/map/renderer.ts"() {
53434
53721
  "use strict";
@@ -53440,6 +53727,7 @@ var init_renderer16 = __esm({
53440
53727
  init_legend_band();
53441
53728
  init_layout15();
53442
53729
  LABEL_FONT = 11;
53730
+ mapInstanceCounter = 0;
53443
53731
  }
53444
53732
  });
53445
53733
 
@@ -54371,7 +54659,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54371
54659
  const sHMargin = ctx.aesthetic(H_MARGIN);
54372
54660
  const sVMargin = ctx.aesthetic(V_MARGIN3);
54373
54661
  const sTitleAreaHeight = ctx.structural(TITLE_AREA_HEIGHT4);
54374
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT6);
54662
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT5);
54375
54663
  const sRowHeight = ctx.structural(ROW_HEIGHT);
54376
54664
  const sPhaseHeight = ctx.structural(PHASE_HEIGHT);
54377
54665
  const sTaskLabelMin = ctx.structural(TASK_LABEL_MIN);
@@ -54396,7 +54684,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54396
54684
  const sLegendLetterFont = ctx.text(LEGEND_LETTER_FONT);
54397
54685
  const sViolationLineHeight = ctx.structural(VIOLATION_LINE_HEIGHT);
54398
54686
  const sStackTopGap = ctx.structural(STACK_TOP_GAP);
54399
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH12);
54687
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
54400
54688
  const sNodeRadius = ctx.structural(NODE_RADIUS3);
54401
54689
  const innerWidth = Math.max(0, width - 2 * sHMargin);
54402
54690
  let roleColW = Math.max(
@@ -54942,7 +55230,7 @@ function parseQuotedSegments(message) {
54942
55230
  out.push({ text: message.slice(last), bold: false });
54943
55231
  return out;
54944
55232
  }
54945
- var 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;
55233
+ var 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;
54946
55234
  var init_renderer19 = __esm({
54947
55235
  "src/raci/renderer.ts"() {
54948
55236
  "use strict";
@@ -54953,6 +55241,7 @@ var init_renderer19 = __esm({
54953
55241
  init_variants();
54954
55242
  init_scaling();
54955
55243
  init_text_measure();
55244
+ init_visual_conventions();
54956
55245
  MARKER_LABELS = {
54957
55246
  raci: { R: "Responsible", A: "Accountable", C: "Consulted", I: "Informed" },
54958
55247
  rasci: {
@@ -54974,7 +55263,7 @@ var init_renderer19 = __esm({
54974
55263
  TITLE_LEGEND_GAP = 16;
54975
55264
  LEGEND_LABEL_FONT = 12;
54976
55265
  LEGEND_LETTER_FONT = 14;
54977
- HEADER_HEIGHT6 = 36;
55266
+ HEADER_HEIGHT5 = 36;
54978
55267
  ROW_HEIGHT = 36;
54979
55268
  PHASE_HEIGHT = 40;
54980
55269
  TASK_LABEL_MIN = 200;
@@ -54994,7 +55283,6 @@ var init_renderer19 = __esm({
54994
55283
  ROLE_HEADER_FONT = 12;
54995
55284
  PHASE_FONT = 13;
54996
55285
  TINT_PCT = 25;
54997
- NODE_STROKE_WIDTH12 = 1.5;
54998
55286
  NODE_RADIUS3 = 6;
54999
55287
  AUTO_ACCENTS = [
55000
55288
  "blue",
@@ -55595,11 +55883,11 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55595
55883
  const lines = splitParticipantLabel(
55596
55884
  p.label,
55597
55885
  labelTextWidth(PARTICIPANT_BOX_WIDTH),
55598
- LABEL_FONT_SIZE6
55886
+ LABEL_FONT_SIZE5
55599
55887
  );
55600
55888
  if (lines.length === 0) continue;
55601
55889
  const widest = Math.max(
55602
- ...lines.map((l) => measureText(l, LABEL_FONT_SIZE6))
55890
+ ...lines.map((l) => measureText(l, LABEL_FONT_SIZE5))
55603
55891
  );
55604
55892
  const labelWidth2 = widest + 10;
55605
55893
  uniformBoxWidth = Math.max(uniformBoxWidth, labelWidth2);
@@ -55633,7 +55921,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55633
55921
  const sSelfCallWidth = ctx.structural(SELF_CALL_WIDTH);
55634
55922
  const sNoteTextWidthMax = sNoteMaxW - sNotePadH * 2 - sNoteFold;
55635
55923
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
55636
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE6);
55924
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE5);
55637
55925
  const sLabelTextWidth = labelTextWidth(sBoxW);
55638
55926
  const participantIndexMap = /* @__PURE__ */ new Map();
55639
55927
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
@@ -56770,7 +57058,7 @@ function buildNoteMessageMap(elements) {
56770
57058
  walk(elements);
56771
57059
  return map;
56772
57060
  }
56773
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE6) {
57061
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
56774
57062
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
56775
57063
  if (tagAttr) {
56776
57064
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -56818,7 +57106,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
56818
57106
  });
56819
57107
  }
56820
57108
  }
56821
- var 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;
57109
+ var 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;
56822
57110
  var init_renderer20 = __esm({
56823
57111
  "src/sequence/renderer.ts"() {
56824
57112
  "use strict";
@@ -56838,7 +57126,7 @@ var init_renderer20 = __esm({
56838
57126
  PARTICIPANT_GAP = 160;
56839
57127
  PARTICIPANT_BOX_WIDTH = 120;
56840
57128
  PARTICIPANT_BOX_HEIGHT = 50;
56841
- LABEL_FONT_SIZE6 = 13;
57129
+ LABEL_FONT_SIZE5 = 13;
56842
57130
  TOP_MARGIN = 20;
56843
57131
  TITLE_HEIGHT8 = 30;
56844
57132
  PARTICIPANT_Y_OFFSET = 10;