@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/auto.cjs CHANGED
@@ -320,7 +320,7 @@ function resolveColorWithDiagnostic(color, line11, diagnostics, palette) {
320
320
  );
321
321
  return void 0;
322
322
  }
323
- var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
323
+ var nord, colorNames, RECOGNIZED_COLOR_NAMES, CATEGORICAL_COLOR_ORDER, seriesColors;
324
324
  var init_colors = __esm({
325
325
  "src/colors.ts"() {
326
326
  "use strict";
@@ -378,6 +378,16 @@ var init_colors = __esm({
378
378
  "black",
379
379
  "white"
380
380
  ]);
381
+ CATEGORICAL_COLOR_ORDER = Object.freeze([
382
+ "red",
383
+ "green",
384
+ "blue",
385
+ "yellow",
386
+ "teal",
387
+ "purple",
388
+ "orange",
389
+ "cyan"
390
+ ]);
381
391
  seriesColors = [
382
392
  nord.nord10,
383
393
  // blue
@@ -1231,11 +1241,7 @@ var init_tag_groups = __esm({
1231
1241
  init_diagnostics();
1232
1242
  init_colors();
1233
1243
  AUTO_TAG_COLOR_SENTINEL = "";
1234
- autoTagColorCycle = Object.freeze(
1235
- RECOGNIZED_COLOR_NAMES.filter(
1236
- (n) => n !== "gray" && n !== "black" && n !== "white"
1237
- )
1238
- );
1244
+ autoTagColorCycle = CATEGORICAL_COLOR_ORDER;
1239
1245
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
1240
1246
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
1241
1247
  }
@@ -3025,7 +3031,7 @@ function shapeFill(palette, intent, isDark, opts) {
3025
3031
  }
3026
3032
  function getSeriesColors(palette) {
3027
3033
  const c = palette.colors;
3028
- return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];
3034
+ return CATEGORICAL_COLOR_ORDER.map((name) => c[name]);
3029
3035
  }
3030
3036
  function getSegmentColors(palette, count) {
3031
3037
  if (count <= 0) return [];
@@ -3078,6 +3084,7 @@ var POLITICAL_TINT_BANDS;
3078
3084
  var init_color_utils = __esm({
3079
3085
  "src/palettes/color-utils.ts"() {
3080
3086
  "use strict";
3087
+ init_colors();
3081
3088
  POLITICAL_TINT_BANDS = {
3082
3089
  light: [32, 48, 64, 80],
3083
3090
  dark: [44, 58, 72, 86]
@@ -11459,7 +11466,7 @@ var init_chart_types = __esm({
11459
11466
  },
11460
11467
  {
11461
11468
  id: "map",
11462
- description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
11469
+ description: "Geographic map: a value or count per country, state, or region (choropleth); points of interest; routes. Use when categories are real-world places."
11463
11470
  },
11464
11471
  // ── Tier 3 — Specialized analytical charts ────────────────
11465
11472
  {
@@ -11476,7 +11483,7 @@ var init_chart_types = __esm({
11476
11483
  },
11477
11484
  {
11478
11485
  id: "slope",
11479
- description: "Change between two periods"
11486
+ description: "Change for multiple things between exactly two periods"
11480
11487
  },
11481
11488
  {
11482
11489
  id: "sankey",
@@ -18914,6 +18921,7 @@ function parseBoxesAndLines(content, palette) {
18914
18921
  const nodes = [];
18915
18922
  const edges = [];
18916
18923
  const groups = [];
18924
+ const nodePositions = /* @__PURE__ */ new Map();
18917
18925
  const result = {
18918
18926
  type: "boxes-and-lines",
18919
18927
  title: null,
@@ -18947,6 +18955,8 @@ function parseBoxesAndLines(content, palette) {
18947
18955
  }
18948
18956
  const groupStack = [];
18949
18957
  let contentStarted = false;
18958
+ let inLayoutBlock = false;
18959
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
18950
18960
  let currentTagGroup = null;
18951
18961
  const metaAliasMap = /* @__PURE__ */ new Map();
18952
18962
  const nameAliasMap = /* @__PURE__ */ new Map();
@@ -19148,6 +19158,42 @@ function parseBoxesAndLines(content, palette) {
19148
19158
  if (currentTagGroup && indent === 0) {
19149
19159
  currentTagGroup = null;
19150
19160
  }
19161
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
19162
+ let isBlock = false;
19163
+ for (let j = i + 1; j < lines.length; j++) {
19164
+ const peek = lines[j];
19165
+ if (!peek.trim()) continue;
19166
+ isBlock = measureIndent2(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
19167
+ break;
19168
+ }
19169
+ if (isBlock) {
19170
+ flushDescription();
19171
+ closeGroupsToIndent(0);
19172
+ inLayoutBlock = true;
19173
+ continue;
19174
+ }
19175
+ }
19176
+ if (inLayoutBlock) {
19177
+ if (indent > 0) {
19178
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
19179
+ if (lm) {
19180
+ nodePositions.set(lm[1].trim(), {
19181
+ x: Number(lm[2]),
19182
+ y: Number(lm[3])
19183
+ });
19184
+ } else {
19185
+ result.diagnostics.push(
19186
+ makeDgmoError(
19187
+ lineNum,
19188
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
19189
+ "warning"
19190
+ )
19191
+ );
19192
+ }
19193
+ continue;
19194
+ }
19195
+ inLayoutBlock = false;
19196
+ }
19151
19197
  if (descState !== null) {
19152
19198
  if (indent > descState.indent) {
19153
19199
  if (trimmed.includes("->") || trimmed.includes("<->")) {
@@ -19400,6 +19446,22 @@ function parseBoxesAndLines(content, palette) {
19400
19446
  );
19401
19447
  }
19402
19448
  finalizeAutoTagColors(result.tagGroups);
19449
+ if (nodePositions.size > 0) {
19450
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
19451
+ for (const id of nodePositions.keys()) {
19452
+ if (!nodeLabelSet.has(id)) {
19453
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
19454
+ }
19455
+ }
19456
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
19457
+ if (unpositioned.length > 0) {
19458
+ pushWarning(
19459
+ 0,
19460
+ `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`
19461
+ );
19462
+ }
19463
+ result.nodePositions = nodePositions;
19464
+ }
19403
19465
  if (result.tagGroups.length > 0) {
19404
19466
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
19405
19467
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
@@ -21500,7 +21562,18 @@ function parseJourneyMap(content, palette) {
21500
21562
  }
21501
21563
  }
21502
21564
  } else {
21503
- personaName = afterKeyword;
21565
+ const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
21566
+ if (colorMatch) {
21567
+ personaName = colorMatch[1].trim();
21568
+ personaColor = resolveColorWithDiagnostic(
21569
+ colorMatch[2],
21570
+ lineNumber,
21571
+ result.diagnostics,
21572
+ palette
21573
+ ) ?? void 0;
21574
+ } else {
21575
+ personaName = afterKeyword;
21576
+ }
21504
21577
  }
21505
21578
  if (!personaName) {
21506
21579
  return fail(lineNumber, "persona requires a name");
@@ -24441,6 +24514,63 @@ var init_export_container = __esm({
24441
24514
  }
24442
24515
  });
24443
24516
 
24517
+ // src/utils/card.ts
24518
+ function renderNodeCard(container, opts) {
24519
+ 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);
24520
+ if (opts.dashed) {
24521
+ rect.attr("stroke-dasharray", "6 3");
24522
+ }
24523
+ 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);
24524
+ const meta = opts.meta;
24525
+ if (!meta || meta.rows.length === 0) return;
24526
+ 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);
24527
+ const keyX = meta.keyX ?? 10;
24528
+ const maxKeyWidth = Math.max(
24529
+ ...meta.rows.map(([key]) => measureText(`${key}: `, meta.fontSize))
24530
+ );
24531
+ const valueX = keyX + maxKeyWidth;
24532
+ const metaStartY = opts.headerHeight + meta.separatorGap + meta.fontSize;
24533
+ for (let i = 0; i < meta.rows.length; i++) {
24534
+ const [displayKey, value] = meta.rows[i];
24535
+ const rowY = metaStartY + i * meta.lineHeight;
24536
+ container.append("text").attr("x", keyX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(`${displayKey}: `);
24537
+ container.append("text").attr("x", valueX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(value);
24538
+ }
24539
+ }
24540
+ function renderCollapseBar(container, opts) {
24541
+ container.append("clipPath").attr("id", opts.clipId).append("rect").attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx);
24542
+ 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);
24543
+ }
24544
+ var init_card = __esm({
24545
+ "src/utils/card.ts"() {
24546
+ "use strict";
24547
+ init_text_measure();
24548
+ }
24549
+ });
24550
+
24551
+ // src/utils/visual-conventions.ts
24552
+ 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;
24553
+ var init_visual_conventions = __esm({
24554
+ "src/utils/visual-conventions.ts"() {
24555
+ "use strict";
24556
+ NODE_STROKE_WIDTH = 1.5;
24557
+ EDGE_STROKE_WIDTH = 1.5;
24558
+ CARD_RADIUS = 6;
24559
+ CONTAINER_RADIUS = 8;
24560
+ COLLAPSE_BAR_INSET = 0;
24561
+ HEADER_HEIGHT2 = 28;
24562
+ LABEL_FONT_SIZE2 = 13;
24563
+ META_FONT_SIZE2 = 11;
24564
+ META_LINE_HEIGHT2 = 16;
24565
+ SEPARATOR_GAP2 = 6;
24566
+ COLLAPSE_BAR_HEIGHT = 6;
24567
+ CONTAINER_HEADER_HEIGHT = 28;
24568
+ CONTAINER_LABEL_FONT_SIZE = 13;
24569
+ CONTAINER_META_FONT_SIZE = 11;
24570
+ CONTAINER_META_LINE_HEIGHT2 = 16;
24571
+ }
24572
+ });
24573
+
24444
24574
  // src/org/renderer.ts
24445
24575
  var renderer_exports = {};
24446
24576
  __export(renderer_exports, {
@@ -24598,9 +24728,16 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24598
24728
  }
24599
24729
  }
24600
24730
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
24601
- const clipId = `clip-${c.nodeId}`;
24602
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", sContainerRadius);
24603
- 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");
24731
+ renderCollapseBar(cG, {
24732
+ width: c.width,
24733
+ height: c.height,
24734
+ barHeight: sCollapseBarHeight,
24735
+ inset: sCollapseBarInset,
24736
+ rx: sContainerRadius,
24737
+ fill: containerStroke(palette, colorOff ? void 0 : c.color),
24738
+ clipId: `clip-${c.nodeId}`,
24739
+ className: "org-collapse-bar"
24740
+ });
24604
24741
  }
24605
24742
  if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
24606
24743
  const iconSize = 14;
@@ -24651,42 +24788,48 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24651
24788
  solid
24652
24789
  );
24653
24790
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
24654
- 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);
24655
- if (node.isContainer) {
24656
- rect.attr("stroke-dasharray", "6 3");
24657
- }
24658
24791
  const labelColor = contrastText(
24659
24792
  fill2,
24660
24793
  palette.textOnFillLight,
24661
24794
  palette.textOnFillDark
24662
24795
  );
24663
- 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);
24664
24796
  const metaEntries = Object.entries(node.metadata);
24665
- if (metaEntries.length > 0) {
24666
- 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);
24667
- const metaDisplayKeys = metaEntries.map(
24668
- ([k]) => displayNames.get(k) ?? k
24669
- );
24670
- const maxKeyWidth = Math.max(
24671
- ...metaDisplayKeys.map((k) => measureText(`${k}: `, sMetaFontSize))
24672
- );
24673
- const valueX = 10 + maxKeyWidth;
24674
- const metaStartY = sHeaderHeight + sSeparatorGap + sMetaFontSize;
24675
- for (let i = 0; i < metaEntries.length; i++) {
24676
- const [, value] = metaEntries[i];
24677
- const displayKey = metaDisplayKeys[i];
24678
- const rowY = metaStartY + i * sMetaLineHeight;
24679
- nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}: `);
24680
- nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(value);
24797
+ renderNodeCard(nodeG, {
24798
+ width: node.width,
24799
+ height: node.height,
24800
+ rx: sCardRadius,
24801
+ fill: fill2,
24802
+ stroke: stroke2,
24803
+ strokeWidth: sNodeStrokeWidth,
24804
+ ...node.isContainer && { dashed: true },
24805
+ label: node.label,
24806
+ labelColor,
24807
+ labelFontSize: sLabelFontSize,
24808
+ headerHeight: sHeaderHeight,
24809
+ ...metaEntries.length > 0 && {
24810
+ meta: {
24811
+ rows: metaEntries.map(
24812
+ ([k, value]) => [displayNames.get(k) ?? k, value]
24813
+ ),
24814
+ fontSize: sMetaFontSize,
24815
+ lineHeight: sMetaLineHeight,
24816
+ separatorGap: sSeparatorGap,
24817
+ separatorColor: solid ? labelColor : stroke2,
24818
+ textColor: labelColor
24819
+ }
24681
24820
  }
24682
- }
24821
+ });
24683
24822
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
24684
- const clipId = `clip-${node.id}`;
24685
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius);
24686
- nodeG.append("rect").attr("x", sCollapseBarInset).attr("y", node.height - sCollapseBarHeight).attr("width", node.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr(
24687
- "fill",
24688
- solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color)
24689
- ).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24823
+ renderCollapseBar(nodeG, {
24824
+ width: node.width,
24825
+ height: node.height,
24826
+ barHeight: sCollapseBarHeight,
24827
+ inset: sCollapseBarInset,
24828
+ rx: sCardRadius,
24829
+ fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
24830
+ clipId: `clip-${node.id}`,
24831
+ className: "org-collapse-bar"
24832
+ });
24690
24833
  }
24691
24834
  if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
24692
24835
  const iconSize = 14;
@@ -24830,7 +24973,7 @@ function renderOrgForExport(content, theme, palette) {
24830
24973
  return extractExportSvg(container, theme);
24831
24974
  });
24832
24975
  }
24833
- var d3Selection6, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
24976
+ var d3Selection6, DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
24834
24977
  var init_renderer = __esm({
24835
24978
  "src/org/renderer.ts"() {
24836
24979
  "use strict";
@@ -24844,27 +24987,14 @@ var init_renderer = __esm({
24844
24987
  init_layout();
24845
24988
  init_legend_constants();
24846
24989
  init_legend_integration();
24990
+ init_card();
24847
24991
  init_text_measure();
24848
24992
  init_legend_layout();
24849
24993
  init_title_constants();
24994
+ init_visual_conventions();
24850
24995
  DIAGRAM_PADDING = 20;
24851
24996
  MAX_SCALE = 3;
24852
24997
  TITLE_HEIGHT = 30;
24853
- LABEL_FONT_SIZE2 = 13;
24854
- META_FONT_SIZE2 = 11;
24855
- META_LINE_HEIGHT2 = 16;
24856
- HEADER_HEIGHT2 = 28;
24857
- SEPARATOR_GAP2 = 6;
24858
- EDGE_STROKE_WIDTH = 1.5;
24859
- NODE_STROKE_WIDTH = 1.5;
24860
- CARD_RADIUS = 6;
24861
- CONTAINER_RADIUS = 8;
24862
- CONTAINER_LABEL_FONT_SIZE = 13;
24863
- CONTAINER_META_FONT_SIZE = 11;
24864
- CONTAINER_META_LINE_HEIGHT2 = 16;
24865
- CONTAINER_HEADER_HEIGHT = 28;
24866
- COLLAPSE_BAR_HEIGHT = 6;
24867
- COLLAPSE_BAR_INSET = 0;
24868
24998
  ANCESTOR_DOT_R = 4;
24869
24999
  ANCESTOR_LABEL_FONT_SIZE = 11;
24870
25000
  ANCESTOR_ROW_HEIGHT = 22;
@@ -25646,21 +25776,21 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25646
25776
  if (width <= 0 || height <= 0) return;
25647
25777
  const ctx = ScaleContext.identity();
25648
25778
  const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING2);
25649
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE4);
25650
- const sMetaFontSize = ctx.text(META_FONT_SIZE4);
25651
- const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT4);
25652
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT4);
25653
- const sSeparatorGap = ctx.structural(SEPARATOR_GAP4);
25654
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH2);
25655
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH2);
25779
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE2);
25780
+ const sMetaFontSize = ctx.text(META_FONT_SIZE2);
25781
+ const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT2);
25782
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT2);
25783
+ const sSeparatorGap = ctx.structural(SEPARATOR_GAP2);
25784
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
25785
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
25656
25786
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
25657
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE3);
25658
- const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE2);
25659
- const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT4);
25660
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT2);
25787
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
25788
+ const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE);
25789
+ const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT2);
25790
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
25661
25791
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
25662
25792
  const sTitleHeight = ctx.structural(TITLE_HEIGHT2);
25663
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT2);
25793
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
25664
25794
  const sLegendFixedGap = ctx.aesthetic(LEGEND_FIXED_GAP2);
25665
25795
  const hasLegend = layout.legend.length > 0;
25666
25796
  const layoutLegendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
@@ -25751,7 +25881,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25751
25881
  }
25752
25882
  const fill2 = containerFill2(palette, isDark, c.color);
25753
25883
  const stroke2 = containerStroke2(palette, c.color);
25754
- 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);
25884
+ 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);
25755
25885
  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);
25756
25886
  const metaEntries = Object.entries(c.metadata);
25757
25887
  if (metaEntries.length > 0) {
@@ -25776,7 +25906,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25776
25906
  }
25777
25907
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
25778
25908
  const clipId = `clip-${c.nodeId}`;
25779
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2);
25909
+ cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
25780
25910
  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})`);
25781
25911
  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}`);
25782
25912
  }
@@ -25815,13 +25945,23 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25815
25945
  const solid = parsed.options["solid-fill"] === "on";
25816
25946
  const fill2 = nodeFill2(palette, isDark, node.color, solid);
25817
25947
  const stroke2 = nodeStroke2(palette, node.color);
25818
- 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);
25819
25948
  const labelColor = contrastText(
25820
25949
  fill2,
25821
25950
  palette.textOnFillLight,
25822
25951
  palette.textOnFillDark
25823
25952
  );
25824
- 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);
25953
+ renderNodeCard(nodeG, {
25954
+ width: node.width,
25955
+ height: node.height,
25956
+ rx: CARD_RADIUS,
25957
+ fill: fill2,
25958
+ stroke: stroke2,
25959
+ strokeWidth: sNodeStrokeWidth,
25960
+ label: node.label,
25961
+ labelColor,
25962
+ labelFontSize: sLabelFontSize,
25963
+ headerHeight: sHeaderHeight
25964
+ });
25825
25965
  const metaEntries = Object.entries(node.metadata);
25826
25966
  if (metaEntries.length > 0) {
25827
25967
  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);
@@ -25856,7 +25996,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25856
25996
  }
25857
25997
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
25858
25998
  const clipId = `clip-${node.id}`;
25859
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2);
25999
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
25860
26000
  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})`);
25861
26001
  }
25862
26002
  }
@@ -25986,7 +26126,7 @@ async function renderSitemapForExport(content, theme, palette) {
25986
26126
  document.body.removeChild(container);
25987
26127
  return svgHtml;
25988
26128
  }
25989
- var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE4, META_FONT_SIZE4, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE3, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26129
+ var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
25990
26130
  var init_renderer2 = __esm({
25991
26131
  "src/sitemap/renderer.ts"() {
25992
26132
  "use strict";
@@ -26001,27 +26141,15 @@ var init_renderer2 = __esm({
26001
26141
  init_legend_integration();
26002
26142
  init_legend_layout();
26003
26143
  init_scaling();
26144
+ init_card();
26004
26145
  init_title_constants();
26146
+ init_visual_conventions();
26005
26147
  DIAGRAM_PADDING2 = 20;
26006
26148
  MAX_SCALE2 = 3;
26007
26149
  TITLE_HEIGHT2 = 30;
26008
- LABEL_FONT_SIZE4 = 13;
26009
- META_FONT_SIZE4 = 11;
26010
- META_LINE_HEIGHT4 = 16;
26011
- HEADER_HEIGHT4 = 28;
26012
- SEPARATOR_GAP4 = 6;
26013
- EDGE_STROKE_WIDTH2 = 1.5;
26014
- NODE_STROKE_WIDTH2 = 1.5;
26015
- CARD_RADIUS2 = 6;
26016
- CONTAINER_RADIUS2 = 8;
26017
- CONTAINER_LABEL_FONT_SIZE3 = 13;
26018
- CONTAINER_META_FONT_SIZE2 = 11;
26019
- CONTAINER_META_LINE_HEIGHT4 = 16;
26020
- CONTAINER_HEADER_HEIGHT2 = 28;
26021
26150
  ARROWHEAD_W = 10;
26022
26151
  ARROWHEAD_H = 7;
26023
26152
  EDGE_LABEL_FONT_SIZE = 11;
26024
- COLLAPSE_BAR_HEIGHT2 = 6;
26025
26153
  LEGEND_FIXED_GAP2 = 8;
26026
26154
  lineGenerator = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveBasis);
26027
26155
  lineGeneratorLinear = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveLinear);
@@ -26188,7 +26316,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
26188
26316
  const sCardMetaLineHeight = ctx.structural(CARD_META_LINE_HEIGHT);
26189
26317
  const sCardSeparatorGap = ctx.structural(CARD_SEPARATOR_GAP);
26190
26318
  const sCardGap = ctx.aesthetic(CARD_GAP);
26191
- const sCardRadius = ctx.structural(CARD_RADIUS3);
26319
+ const sCardRadius = ctx.structural(CARD_RADIUS);
26192
26320
  const sCardPaddingX = ctx.aesthetic(CARD_PADDING_X);
26193
26321
  const sCardPaddingY = ctx.aesthetic(CARD_PADDING_Y);
26194
26322
  const sCardStrokeWidth = ctx.structural(CARD_STROKE_WIDTH);
@@ -26568,7 +26696,7 @@ function computeSwimlaneLayout(parsed, buckets, baseLayout, collapsedLanes, coll
26568
26696
  const totalHeight = laneY - sLaneGap + sColumnPadding + sDiagramPadding;
26569
26697
  return { columnXs, lanes, totalWidth, totalHeight, startY };
26570
26698
  }
26571
- 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) {
26699
+ 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) {
26572
26700
  const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
26573
26701
  const buckets = bucketCardsBySwimlane(visibleColumns, swimlaneGroup);
26574
26702
  const grid = computeSwimlaneLayout(
@@ -26708,7 +26836,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
26708
26836
  }
26709
26837
  }
26710
26838
  }
26711
- 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) {
26839
+ 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) {
26712
26840
  const card = cardLayout.card;
26713
26841
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
26714
26842
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -26758,7 +26886,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
26758
26886
  }
26759
26887
  }
26760
26888
  }
26761
- var d3Selection8, DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_RADIUS3, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
26889
+ var d3Selection8, DIAGRAM_PADDING3, COLUMN_GAP, COLUMN_HEADER_HEIGHT, COLUMN_PADDING, COLUMN_MIN_WIDTH, CARD_HEADER_HEIGHT, CARD_META_LINE_HEIGHT, CARD_SEPARATOR_GAP, CARD_GAP, CARD_PADDING_X, CARD_PADDING_Y, CARD_STROKE_WIDTH, TITLE_HEIGHT3, COLUMN_HEADER_FONT_SIZE, CARD_TITLE_FONT_SIZE, CARD_META_FONT_SIZE, WIP_FONT_SIZE, COLUMN_RADIUS, COLUMN_HEADER_RADIUS, COLLAPSED_COLUMN_WIDTH, COLLAPSED_LANE_HEIGHT, LANE_HEADER_WIDTH, LANE_GAP;
26762
26890
  var init_renderer3 = __esm({
26763
26891
  "src/kanban/renderer.ts"() {
26764
26892
  "use strict";
@@ -26773,6 +26901,7 @@ var init_renderer3 = __esm({
26773
26901
  init_legend_integration();
26774
26902
  init_scaling();
26775
26903
  init_text_measure();
26904
+ init_visual_conventions();
26776
26905
  init_title_constants();
26777
26906
  DIAGRAM_PADDING3 = 20;
26778
26907
  COLUMN_GAP = 16;
@@ -26783,7 +26912,6 @@ var init_renderer3 = __esm({
26783
26912
  CARD_META_LINE_HEIGHT = 14;
26784
26913
  CARD_SEPARATOR_GAP = 4;
26785
26914
  CARD_GAP = 8;
26786
- CARD_RADIUS3 = 6;
26787
26915
  CARD_PADDING_X = 10;
26788
26916
  CARD_PADDING_Y = 6;
26789
26917
  CARD_STROKE_WIDTH = 1.5;
@@ -27084,8 +27212,8 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
27084
27212
  const sClassFontSize = ctx.text(CLASS_FONT_SIZE2);
27085
27213
  const sMemberFontSize = ctx.text(MEMBER_FONT_SIZE2);
27086
27214
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE2);
27087
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH3);
27088
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH3);
27215
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
27216
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27089
27217
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT2);
27090
27218
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y2);
27091
27219
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X);
@@ -27344,7 +27472,7 @@ function renderClassDiagramForExport(content, theme, palette) {
27344
27472
  return extractExportSvg(container, theme);
27345
27473
  });
27346
27474
  }
27347
- var d3Selection9, d3Shape3, DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, EDGE_STROKE_WIDTH3, NODE_STROKE_WIDTH3, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27475
+ var d3Selection9, d3Shape3, DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABEL_FONT_SIZE2, MEMBER_LINE_HEIGHT2, COMPARTMENT_PADDING_Y2, MEMBER_PADDING_X, CLASS_TYPE_MAP, CLASS_TYPE_ORDER, LEGEND_GROUP_NAME, lineGenerator2;
27348
27476
  var init_renderer4 = __esm({
27349
27477
  "src/class/renderer.ts"() {
27350
27478
  "use strict";
@@ -27361,13 +27489,12 @@ var init_renderer4 = __esm({
27361
27489
  init_scaling();
27362
27490
  init_text_measure();
27363
27491
  init_note_box();
27492
+ init_visual_conventions();
27364
27493
  DIAGRAM_PADDING4 = 20;
27365
27494
  MAX_SCALE3 = 3;
27366
27495
  CLASS_FONT_SIZE2 = 13;
27367
27496
  MEMBER_FONT_SIZE2 = 11;
27368
27497
  EDGE_LABEL_FONT_SIZE2 = 11;
27369
- EDGE_STROKE_WIDTH3 = 1.5;
27370
- NODE_STROKE_WIDTH3 = 1.5;
27371
27498
  MEMBER_LINE_HEIGHT2 = 18;
27372
27499
  COMPARTMENT_PADDING_Y2 = 8;
27373
27500
  MEMBER_PADDING_X = 10;
@@ -27861,7 +27988,7 @@ function constraintIcon(constraint) {
27861
27988
  return "\u25CB";
27862
27989
  }
27863
27990
  }
27864
- function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH4) {
27991
+ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH) {
27865
27992
  const dx = point.x - prevPoint.x;
27866
27993
  const dy = point.y - prevPoint.y;
27867
27994
  const len = Math.sqrt(dx * dx + dy * dy);
@@ -27921,8 +28048,8 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
27921
28048
  const sTableFontSize = ctx.text(TABLE_FONT_SIZE2);
27922
28049
  const sColumnFontSize = ctx.text(COLUMN_FONT_SIZE2);
27923
28050
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE4);
27924
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH4);
27925
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH4);
28051
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
28052
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27926
28053
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT4);
27927
28054
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y4);
27928
28055
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X2);
@@ -28200,7 +28327,7 @@ function renderERDiagramForExport(content, theme, palette) {
28200
28327
  document.body.removeChild(container);
28201
28328
  }
28202
28329
  }
28203
- var d3Selection10, d3Shape4, DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH4, NODE_STROKE_WIDTH4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28330
+ var d3Selection10, d3Shape4, DIAGRAM_PADDING5, MAX_SCALE4, TABLE_FONT_SIZE2, COLUMN_FONT_SIZE2, EDGE_LABEL_FONT_SIZE4, MEMBER_LINE_HEIGHT4, COMPARTMENT_PADDING_Y4, MEMBER_PADDING_X2, lineGenerator3;
28204
28331
  var init_renderer5 = __esm({
28205
28332
  "src/er/renderer.ts"() {
28206
28333
  "use strict";
@@ -28219,13 +28346,12 @@ var init_renderer5 = __esm({
28219
28346
  init_parser9();
28220
28347
  init_layout4();
28221
28348
  init_classify();
28349
+ init_visual_conventions();
28222
28350
  DIAGRAM_PADDING5 = 20;
28223
28351
  MAX_SCALE4 = 3;
28224
28352
  TABLE_FONT_SIZE2 = 13;
28225
28353
  COLUMN_FONT_SIZE2 = 11;
28226
28354
  EDGE_LABEL_FONT_SIZE4 = 11;
28227
- EDGE_STROKE_WIDTH4 = 1.5;
28228
- NODE_STROKE_WIDTH4 = 1.5;
28229
28355
  MEMBER_LINE_HEIGHT4 = 18;
28230
28356
  COMPARTMENT_PADDING_Y4 = 8;
28231
28357
  MEMBER_PADDING_X2 = 10;
@@ -28453,9 +28579,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28453
28579
  const sDiagramPadding = sctx.aesthetic(DIAGRAM_PADDING6);
28454
28580
  const sMinNodeFontSize = sctx.text(MIN_NODE_FONT_SIZE);
28455
28581
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE5);
28456
- const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH5);
28457
- const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH5);
28458
- const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT3);
28582
+ const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH);
28583
+ const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH);
28584
+ const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT2);
28459
28585
  const sDescFontSize = sctx.text(DESC_FONT_SIZE);
28460
28586
  const sGroupLabelFontSize = sctx.text(GROUP_LABEL_FONT_SIZE);
28461
28587
  const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
@@ -28547,8 +28673,32 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28547
28673
  const scaleX = width / (contentW + sDiagramPadding * 2);
28548
28674
  const scaleY = height / (contentH + sDiagramPadding * 2);
28549
28675
  const scale = Math.min(scaleX, scaleY, 3);
28550
- const offsetX = (width - contentW * scale) / 2;
28551
- const offsetY = sDiagramPadding + titleOffset + legendH;
28676
+ let centerShiftX = 0;
28677
+ let centerShiftY = 0;
28678
+ if (parsed.nodePositions && parsed.nodePositions.size > 0) {
28679
+ let bMinX = Infinity, bMinY = Infinity, bMaxX = -Infinity, bMaxY = -Infinity;
28680
+ const accB = (x, y) => {
28681
+ if (x < bMinX) bMinX = x;
28682
+ if (x > bMaxX) bMaxX = x;
28683
+ if (y < bMinY) bMinY = y;
28684
+ if (y > bMaxY) bMaxY = y;
28685
+ };
28686
+ for (const n of layout.nodes) {
28687
+ accB(n.x - n.width / 2, n.y - n.height / 2);
28688
+ accB(n.x + n.width / 2, n.y + n.height / 2);
28689
+ }
28690
+ for (const g of layout.groups) {
28691
+ accB(g.x - g.width / 2, g.y - g.height / 2);
28692
+ accB(g.x + g.width / 2, g.y + g.height / 2);
28693
+ }
28694
+ for (const e of layout.edges) for (const p of e.points) accB(p.x, p.y);
28695
+ if (Number.isFinite(bMinX)) {
28696
+ centerShiftX = (layout.width - bMaxX - bMinX) / 2;
28697
+ centerShiftY = (layout.height - bMaxY - bMinY) / 2;
28698
+ }
28699
+ }
28700
+ const offsetX = (width - contentW * scale) / 2 + centerShiftX * scale;
28701
+ const offsetY = sDiagramPadding + titleOffset + legendH + centerShiftY * scale;
28552
28702
  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);
28553
28703
  if (sctx.isBelowFloor) {
28554
28704
  svg.attr("width", "100%");
@@ -28684,7 +28834,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28684
28834
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
28685
28835
  edgeGroups.set(i, edgeG);
28686
28836
  const markerId = `bl-arrow-${color.replace("#", "")}`;
28687
- const gen = parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28837
+ const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28688
28838
  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})`);
28689
28839
  if (le.bidirectional) {
28690
28840
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
@@ -28965,7 +29115,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
28965
29115
  }
28966
29116
  });
28967
29117
  }
28968
- var d3Selection11, d3Shape5, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
29118
+ var d3Selection11, d3Shape5, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE5, NODE_RX, COLLAPSE_BAR_HEIGHT2, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB, lineGeneratorStraight;
28969
29119
  var init_renderer6 = __esm({
28970
29120
  "src/boxes-and-lines/renderer.ts"() {
28971
29121
  "use strict";
@@ -28983,14 +29133,13 @@ var init_renderer6 = __esm({
28983
29133
  init_wrapped_desc();
28984
29134
  init_scaling();
28985
29135
  init_text_measure();
29136
+ init_visual_conventions();
28986
29137
  DIAGRAM_PADDING6 = 20;
28987
29138
  NODE_FONT_SIZE = 11;
28988
29139
  MIN_NODE_FONT_SIZE = 9;
28989
29140
  EDGE_LABEL_FONT_SIZE5 = 11;
28990
- EDGE_STROKE_WIDTH5 = 1.5;
28991
- NODE_STROKE_WIDTH5 = 1.5;
28992
29141
  NODE_RX = 8;
28993
- COLLAPSE_BAR_HEIGHT3 = 4;
29142
+ COLLAPSE_BAR_HEIGHT2 = 4;
28994
29143
  ARROWHEAD_W2 = 5;
28995
29144
  ARROWHEAD_H2 = 4;
28996
29145
  DESC_FONT_SIZE = 10;
@@ -29004,6 +29153,7 @@ var init_renderer6 = __esm({
29004
29153
  VALUE_FONT_SIZE = 11;
29005
29154
  lineGeneratorLR = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29006
29155
  lineGeneratorTB = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29156
+ lineGeneratorStraight = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveLinear);
29007
29157
  }
29008
29158
  });
29009
29159
 
@@ -30191,6 +30341,156 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30191
30341
  return { x: rect.x + dx * s, y: rect.y + dy * s };
30192
30342
  };
30193
30343
  const isInsideRect = (p, rect) => Math.abs(p.x - rect.x) <= rect.w / 2 && Math.abs(p.y - rect.y) <= rect.h / 2;
30344
+ const pinned = parsed.nodePositions;
30345
+ const groupLabelSet = new Set(parsed.groups.map((g) => g.label));
30346
+ const groupsAreFlat = parsed.groups.every(
30347
+ (g) => !g.parentGroup && !g.children.some((c) => groupLabelSet.has(c))
30348
+ );
30349
+ const allOriginalGroupLabels = new Set(
30350
+ (collapseInfo?.originalGroups ?? parsed.groups).map((g) => g.label)
30351
+ );
30352
+ const collapsedAreFlatPinned = collapsedGroupLabels.size === 0 || pinned !== void 0 && collapseInfo !== void 0 && [...collapsedGroupLabels].every((label) => {
30353
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30354
+ if (!og || og.parentGroup) return false;
30355
+ return og.children.every(
30356
+ (c) => pinned.has(c) && !allOriginalGroupLabels.has(c)
30357
+ );
30358
+ });
30359
+ const allPinned = pinned !== void 0 && (parsed.nodes.length > 0 || collapsedGroupLabels.size > 0) && parsed.nodes.every((n2) => pinned.has(n2.label)) && groupsAreFlat && collapsedAreFlatPinned;
30360
+ function placePinned(pins) {
30361
+ const collapsedPosByGid = /* @__PURE__ */ new Map();
30362
+ const collapsedBoxes = [];
30363
+ if (collapseInfo)
30364
+ for (const label of collapsedGroupLabels) {
30365
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30366
+ if (!og) continue;
30367
+ let cx0 = Infinity, cy0 = Infinity, cx1 = -Infinity, cy1 = -Infinity;
30368
+ for (const c of og.children) {
30369
+ const p = pins.get(c);
30370
+ if (!p) continue;
30371
+ cx0 = Math.min(cx0, p.x);
30372
+ cx1 = Math.max(cx1, p.x);
30373
+ cy0 = Math.min(cy0, p.y);
30374
+ cy1 = Math.max(cy1, p.y);
30375
+ }
30376
+ if (!Number.isFinite(cx0)) continue;
30377
+ const cx = (cx0 + cx1) / 2;
30378
+ const cy = (cy0 + cy1) / 2;
30379
+ collapsedPosByGid.set(`__group_${label}`, { x: cx, y: cy });
30380
+ collapsedBoxes.push({
30381
+ label,
30382
+ lineNumber: og.lineNumber,
30383
+ childCount: collapseInfo.collapsedChildCounts.get(label) ?? og.children.length,
30384
+ x: cx,
30385
+ y: cy
30386
+ });
30387
+ }
30388
+ const posOf = (label) => pins.get(label) ?? collapsedPosByGid.get(label);
30389
+ const rectOf = (label) => {
30390
+ const p = posOf(label);
30391
+ const s = sizes.get(label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
30392
+ return { x: p.x, y: p.y, w: s.width, h: s.height };
30393
+ };
30394
+ const nodes = parsed.nodes.map((n2) => {
30395
+ const r = rectOf(n2.label);
30396
+ return { label: n2.label, x: r.x, y: r.y, width: r.w, height: r.h };
30397
+ });
30398
+ const edges = parsed.edges.flatMap((e) => {
30399
+ const sp = posOf(e.source);
30400
+ const tp = posOf(e.target);
30401
+ if (!sp || !tp) return [];
30402
+ const srcRect = rectOf(e.source);
30403
+ const tgtRect = rectOf(e.target);
30404
+ const p0 = rectBorderPoint(srcRect, tp);
30405
+ const p1 = rectBorderPoint(tgtRect, sp);
30406
+ return [
30407
+ {
30408
+ source: e.source,
30409
+ target: e.target,
30410
+ ...e.label !== void 0 && { label: e.label },
30411
+ bidirectional: e.bidirectional,
30412
+ lineNumber: e.lineNumber,
30413
+ points: [p0, p1],
30414
+ yOffset: 0,
30415
+ parallelCount: 1,
30416
+ metadata: e.metadata,
30417
+ straight: true
30418
+ }
30419
+ ];
30420
+ });
30421
+ const GROUP_PAD = 16;
30422
+ const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
30423
+ const groups = [];
30424
+ for (const grp of parsed.groups) {
30425
+ let gx0 = Infinity, gy0 = Infinity, gx1 = -Infinity, gy1 = -Infinity;
30426
+ for (const c of grp.children) {
30427
+ const n2 = nodeByLabel.get(c);
30428
+ if (!n2) continue;
30429
+ gx0 = Math.min(gx0, n2.x - n2.width / 2);
30430
+ gx1 = Math.max(gx1, n2.x + n2.width / 2);
30431
+ gy0 = Math.min(gy0, n2.y - n2.height / 2);
30432
+ gy1 = Math.max(gy1, n2.y + n2.height / 2);
30433
+ }
30434
+ if (!Number.isFinite(gx0)) continue;
30435
+ const x0 = gx0 - GROUP_PAD;
30436
+ const x1 = gx1 + GROUP_PAD;
30437
+ const y0 = gy0 - GROUP_LABEL_ZONE2;
30438
+ const y1 = gy1 + GROUP_PAD;
30439
+ groups.push({
30440
+ label: grp.label,
30441
+ lineNumber: grp.lineNumber,
30442
+ x: (x0 + x1) / 2,
30443
+ y: (y0 + y1) / 2,
30444
+ width: x1 - x0,
30445
+ height: y1 - y0,
30446
+ collapsed: false,
30447
+ childCount: grp.children.length
30448
+ });
30449
+ }
30450
+ for (const cb of collapsedBoxes) {
30451
+ groups.push({
30452
+ label: cb.label,
30453
+ lineNumber: cb.lineNumber,
30454
+ x: cb.x,
30455
+ y: cb.y,
30456
+ width: NODE_WIDTH,
30457
+ height: NODE_HEIGHT,
30458
+ collapsed: true,
30459
+ childCount: cb.childCount
30460
+ });
30461
+ }
30462
+ const M = 40;
30463
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
30464
+ const acc = (x, y) => {
30465
+ if (x < minX) minX = x;
30466
+ if (x > maxX) maxX = x;
30467
+ if (y < minY) minY = y;
30468
+ if (y > maxY) maxY = y;
30469
+ };
30470
+ for (const n2 of nodes) {
30471
+ acc(n2.x - n2.width / 2, n2.y - n2.height / 2);
30472
+ acc(n2.x + n2.width / 2, n2.y + n2.height / 2);
30473
+ }
30474
+ for (const e of edges) for (const p of e.points) acc(p.x, p.y);
30475
+ for (const gr of groups) {
30476
+ acc(gr.x - gr.width / 2, gr.y - gr.height / 2);
30477
+ acc(gr.x + gr.width / 2, gr.y + gr.height / 2);
30478
+ }
30479
+ const TOL = 2;
30480
+ const sx = minX < M - TOL ? M - minX : 0;
30481
+ const sy = minY < M - TOL ? M - minY : 0;
30482
+ const shifted = sx !== 0 || sy !== 0;
30483
+ return {
30484
+ nodes: shifted ? nodes.map((n2) => ({ ...n2, x: n2.x + sx, y: n2.y + sy })) : nodes,
30485
+ edges: shifted ? edges.map((e) => ({
30486
+ ...e,
30487
+ points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
30488
+ })) : edges,
30489
+ groups: shifted ? groups.map((gr) => ({ ...gr, x: gr.x + sx, y: gr.y + sy })) : groups,
30490
+ width: maxX + sx + M,
30491
+ height: maxY + sy + M
30492
+ };
30493
+ }
30194
30494
  function place(cfg) {
30195
30495
  const r = cfg.seed === void 0 ? null : rng2(cfg.seed + 1);
30196
30496
  const ord = (a) => r ? shuffle(a, r) : a.slice();
@@ -30329,6 +30629,7 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30329
30629
  height: gg.height ?? 600
30330
30630
  };
30331
30631
  }
30632
+ if (allPinned) return placePinned(pinned);
30332
30633
  const n = parsed.nodes.length;
30333
30634
  const seedCount = opts?.seeds ?? (n <= 12 ? 80 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
30334
30635
  const REFINE_K = opts?.refineK ?? 6;
@@ -30525,7 +30826,7 @@ function computeNodeSize(node, reserveValueRow) {
30525
30826
  }
30526
30827
  totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
30527
30828
  const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
30528
- const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30829
+ const totalHeight = labelHeight + SEPARATOR_GAP4 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30529
30830
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
30530
30831
  }
30531
30832
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
@@ -30654,7 +30955,7 @@ function applyParallelEdgeOffsets(layout) {
30654
30955
  }))
30655
30956
  };
30656
30957
  }
30657
- 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;
30958
+ 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;
30658
30959
  var init_layout5 = __esm({
30659
30960
  "src/boxes-and-lines/layout.ts"() {
30660
30961
  "use strict";
@@ -30670,13 +30971,13 @@ var init_layout5 = __esm({
30670
30971
  DESC_FONT_SIZE2 = 10;
30671
30972
  DESC_LINE_HEIGHT2 = 1.4;
30672
30973
  DESC_PADDING = 8;
30673
- SEPARATOR_GAP5 = 4;
30974
+ SEPARATOR_GAP4 = 4;
30674
30975
  MAX_DESC_LINES2 = 6;
30675
30976
  MAX_LABEL_LINES = 3;
30676
30977
  LABEL_LINE_HEIGHT = 1.3;
30677
30978
  LABEL_PAD = 12;
30678
30979
  VALUE_ROW_FONT = 11;
30679
- VALUE_ROW_H = SEPARATOR_GAP5 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30980
+ VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30680
30981
  }
30681
30982
  });
30682
30983
 
@@ -31437,11 +31738,11 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31437
31738
  });
31438
31739
  }
31439
31740
  for (const edge of renderLayout.edges) {
31440
- 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);
31741
+ 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);
31441
31742
  }
31442
31743
  for (const node of renderLayout.nodes) {
31443
31744
  const isRoot = node.radius === 0 && renderLayout.nodes.indexOf(node) === 0;
31444
- const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH6;
31745
+ const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH;
31445
31746
  const effectiveColor = options?.colorByDepth ? depthColor(node.depth, palette) : node.color;
31446
31747
  const fill2 = nodeFill4(
31447
31748
  palette,
@@ -31524,7 +31825,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31524
31825
  const clipId = `collapse-clip-${node.id}`;
31525
31826
  const defs = mainG.append("defs");
31526
31827
  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);
31527
- 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})`);
31828
+ 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})`);
31528
31829
  }
31529
31830
  if (onClickItem) {
31530
31831
  nodeG.style("cursor", "pointer").on("click", (event) => {
@@ -31572,7 +31873,7 @@ function renderMindmapForExport(content, theme, palette) {
31572
31873
  return extractExportSvg(container, theme);
31573
31874
  });
31574
31875
  }
31575
- var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, NODE_STROKE_WIDTH6, EDGE_STROKE_WIDTH6, COLLAPSE_BAR_HEIGHT4, DEPTH_COLOR_KEYS;
31876
+ var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
31576
31877
  var init_renderer7 = __esm({
31577
31878
  "src/mindmap/renderer.ts"() {
31578
31879
  "use strict";
@@ -31590,6 +31891,7 @@ var init_renderer7 = __esm({
31590
31891
  init_legend_layout();
31591
31892
  init_title_constants();
31592
31893
  init_scaling();
31894
+ init_visual_conventions();
31593
31895
  DIAGRAM_PADDING7 = 20;
31594
31896
  TITLE_HEIGHT4 = 30;
31595
31897
  SINGLE_LABEL_HEIGHT2 = 28;
@@ -31597,9 +31899,6 @@ var init_renderer7 = __esm({
31597
31899
  DESC_LINE_HEIGHT4 = 14;
31598
31900
  NODE_RADIUS = 6;
31599
31901
  ROOT_STROKE_WIDTH = 2.5;
31600
- NODE_STROKE_WIDTH6 = 1.5;
31601
- EDGE_STROKE_WIDTH6 = 1.5;
31602
- COLLAPSE_BAR_HEIGHT4 = 6;
31603
31902
  DEPTH_COLOR_KEYS = [
31604
31903
  "red",
31605
31904
  "orange",
@@ -32827,10 +33126,10 @@ function computeC4NodeDimensions(el, options) {
32827
33126
  const metaEntries = collectCardMetadata(el.metadata);
32828
33127
  if (metaEntries.length > 0) {
32829
33128
  height2 += DIVIDER_GAP;
32830
- height2 += metaEntries.length * META_LINE_HEIGHT5;
33129
+ height2 += metaEntries.length * META_LINE_HEIGHT4;
32831
33130
  const maxMetaWidth = Math.max(
32832
33131
  ...metaEntries.map(
32833
- (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE5) + CARD_H_PAD3 * 2
33132
+ (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE4) + CARD_H_PAD3 * 2
32834
33133
  )
32835
33134
  );
32836
33135
  if (maxMetaWidth > width) width = Math.min(MAX_NODE_WIDTH, maxMetaWidth);
@@ -34107,7 +34406,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
34107
34406
  height: totalHeight
34108
34407
  };
34109
34408
  }
34110
- var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_FONT_SIZE5, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34409
+ var import_dagre5, gNode, gEdge, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, NAME_FONT_SIZE, DESC_LINE_HEIGHT5, DESC_FONT_SIZE4, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT4, META_FONT_SIZE4, MARGIN6, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
34111
34410
  var init_layout8 = __esm({
34112
34411
  "src/c4/layout.ts"() {
34113
34412
  "use strict";
@@ -34126,8 +34425,8 @@ var init_layout8 = __esm({
34126
34425
  DESC_FONT_SIZE4 = 11;
34127
34426
  CARD_V_PAD3 = 14;
34128
34427
  CARD_H_PAD3 = 20;
34129
- META_LINE_HEIGHT5 = 16;
34130
- META_FONT_SIZE5 = 11;
34428
+ META_LINE_HEIGHT4 = 16;
34429
+ META_FONT_SIZE4 = 11;
34131
34430
  MARGIN6 = 40;
34132
34431
  BOUNDARY_PAD = 40;
34133
34432
  GROUP_BOUNDARY_PAD = 24;
@@ -34248,7 +34547,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34248
34547
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34249
34548
  const pathD = lineGenerator4(edge.points);
34250
34549
  if (pathD) {
34251
- 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)");
34550
+ 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)");
34252
34551
  if (dashed) {
34253
34552
  pathEl.attr("stroke-dasharray", "6 3");
34254
34553
  }
@@ -34314,7 +34613,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34314
34613
  palette.textOnFillLight,
34315
34614
  palette.textOnFillDark
34316
34615
  );
34317
- 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);
34616
+ 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);
34318
34617
  let yPos = -h / 2 + CARD_V_PAD4;
34319
34618
  const typeLabel = `\xAB${node.type}\xBB`;
34320
34619
  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);
@@ -34358,7 +34657,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34358
34657
  }
34359
34658
  if (node.drillable) {
34360
34659
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34361
- 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);
34660
+ 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);
34362
34661
  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");
34363
34662
  }
34364
34663
  }
@@ -34418,14 +34717,14 @@ function drawCylinderCard(nodeG, w, h, fill2, stroke2, dashed) {
34418
34717
  `A ${w / 2} ${ry} 0 0 1 ${-w / 2} ${h / 2 - ry}`,
34419
34718
  "Z"
34420
34719
  ].join(" ");
34421
- const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34720
+ const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34422
34721
  if (dashed) {
34423
34722
  el.attr("stroke-dasharray", "6 3");
34424
34723
  }
34425
- 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);
34724
+ 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);
34426
34725
  }
34427
34726
  function drawCardRect(nodeG, w, h, fill2, stroke2, dashed) {
34428
- 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);
34727
+ 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);
34429
34728
  if (dashed) {
34430
34729
  el.attr("stroke-dasharray", "6 3");
34431
34730
  }
@@ -34445,7 +34744,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
34445
34744
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34446
34745
  const pathD = lineGenerator4(edge.points);
34447
34746
  if (pathD) {
34448
- 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)");
34747
+ 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)");
34449
34748
  if (dashed) {
34450
34749
  pathEl.attr("stroke-dasharray", "6 3");
34451
34750
  }
@@ -34940,13 +35239,13 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
34940
35239
  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);
34941
35240
  yPos += DIVIDER_GAP2;
34942
35241
  const maxKeyWidth = Math.max(
34943
- ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE6))
35242
+ ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE2))
34944
35243
  );
34945
35244
  const valueX = -w / 2 + CARD_H_PAD4 + maxKeyWidth;
34946
35245
  for (const entry of metaEntries) {
34947
- 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}:`);
34948
- 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);
34949
- yPos += META_LINE_HEIGHT6;
35246
+ 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}:`);
35247
+ 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);
35248
+ yPos += META_LINE_HEIGHT2;
34950
35249
  }
34951
35250
  }
34952
35251
  } else {
@@ -34973,7 +35272,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
34973
35272
  }
34974
35273
  if (node.drillable) {
34975
35274
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34976
- 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);
35275
+ 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);
34977
35276
  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");
34978
35277
  }
34979
35278
  }
@@ -35102,7 +35401,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
35102
35401
  document.body.removeChild(el);
35103
35402
  }
35104
35403
  }
35105
- var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE6, TECH_FONT_SIZE, EDGE_STROKE_WIDTH7, NODE_STROKE_WIDTH7, CARD_RADIUS4, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, META_FONT_SIZE6, META_LINE_HEIGHT6, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
35404
+ var d3Selection14, d3Shape6, DIAGRAM_PADDING8, MAX_SCALE5, TITLE_HEIGHT6, TYPE_FONT_SIZE, NAME_FONT_SIZE2, DESC_FONT_SIZE5, DESC_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE6, TECH_FONT_SIZE, CARD_H_PAD4, CARD_V_PAD4, TYPE_LABEL_HEIGHT2, DIVIDER_GAP2, NAME_HEIGHT2, BOUNDARY_LABEL_FONT_SIZE, BOUNDARY_STROKE_WIDTH, BOUNDARY_RADIUS, DRILL_BAR_HEIGHT, CYLINDER_RY, PERSON_HEAD_R, PERSON_ARM_SPAN, PERSON_LEG_SPAN, PERSON_ICON_W, PERSON_SW, lineGenerator4;
35106
35405
  var init_renderer9 = __esm({
35107
35406
  "src/c4/renderer.ts"() {
35108
35407
  "use strict";
@@ -35118,6 +35417,7 @@ var init_renderer9 = __esm({
35118
35417
  init_legend_constants();
35119
35418
  init_legend_integration();
35120
35419
  init_title_constants();
35420
+ init_visual_conventions();
35121
35421
  DIAGRAM_PADDING8 = 20;
35122
35422
  MAX_SCALE5 = 3;
35123
35423
  TITLE_HEIGHT6 = 30;
@@ -35127,16 +35427,11 @@ var init_renderer9 = __esm({
35127
35427
  DESC_LINE_HEIGHT6 = 16;
35128
35428
  EDGE_LABEL_FONT_SIZE6 = 11;
35129
35429
  TECH_FONT_SIZE = 10;
35130
- EDGE_STROKE_WIDTH7 = 1.5;
35131
- NODE_STROKE_WIDTH7 = 1.5;
35132
- CARD_RADIUS4 = 6;
35133
35430
  CARD_H_PAD4 = 20;
35134
35431
  CARD_V_PAD4 = 14;
35135
35432
  TYPE_LABEL_HEIGHT2 = 18;
35136
35433
  DIVIDER_GAP2 = 6;
35137
35434
  NAME_HEIGHT2 = 20;
35138
- META_FONT_SIZE6 = 11;
35139
- META_LINE_HEIGHT6 = 16;
35140
35435
  BOUNDARY_LABEL_FONT_SIZE = 12;
35141
35436
  BOUNDARY_STROKE_WIDTH = 1.5;
35142
35437
  BOUNDARY_RADIUS = 8;
@@ -35540,7 +35835,7 @@ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff,
35540
35835
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
35541
35836
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
35542
35837
  }
35543
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35838
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35544
35839
  const w = node.width;
35545
35840
  const h = node.height;
35546
35841
  const rx = h / 2;
@@ -35552,7 +35847,7 @@ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeS
35552
35847
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
35553
35848
  ).attr("stroke-width", sNodeStrokeWidth);
35554
35849
  }
35555
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35850
+ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35556
35851
  const w = node.width;
35557
35852
  const h = node.height;
35558
35853
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -35571,7 +35866,7 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
35571
35866
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35572
35867
  ).attr("stroke-width", sNodeStrokeWidth);
35573
35868
  }
35574
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35869
+ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35575
35870
  const w = node.width / 2;
35576
35871
  const h = node.height / 2;
35577
35872
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -35593,7 +35888,7 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35593
35888
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35594
35889
  ).attr("stroke-width", sNodeStrokeWidth);
35595
35890
  }
35596
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW) {
35891
+ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
35597
35892
  const w = node.width / 2;
35598
35893
  const h = node.height / 2;
35599
35894
  const sk = sIoSkew;
@@ -35619,7 +35914,7 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
35619
35914
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35620
35915
  ).attr("stroke-width", sNodeStrokeWidth);
35621
35916
  }
35622
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sSubroutineInset = SUBROUTINE_INSET) {
35917
+ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
35623
35918
  const w = node.width;
35624
35919
  const h = node.height;
35625
35920
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -35637,7 +35932,7 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
35637
35932
  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);
35638
35933
  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);
35639
35934
  }
35640
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35935
+ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35641
35936
  const w = node.width;
35642
35937
  const h = node.height;
35643
35938
  const waveH = sDocWaveHeight;
@@ -35668,7 +35963,7 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35668
35963
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35669
35964
  ).attr("stroke-width", sNodeStrokeWidth);
35670
35965
  }
35671
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35966
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35672
35967
  switch (node.shape) {
35673
35968
  case "terminal":
35674
35969
  renderTerminal(
@@ -35755,8 +36050,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
35755
36050
  const sTitleY = ctx.structural(TITLE_Y);
35756
36051
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
35757
36052
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
35758
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH8);
35759
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH8);
36053
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
36054
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
35760
36055
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
35761
36056
  const sArrowheadH = ctx.structural(ARROWHEAD_H3);
35762
36057
  const sIoSkew = ctx.structural(IO_SKEW);
@@ -35980,7 +36275,7 @@ function renderFlowchartForExport(content, theme, palette) {
35980
36275
  document.body.removeChild(container);
35981
36276
  }
35982
36277
  }
35983
- var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, EDGE_STROKE_WIDTH8, NODE_STROKE_WIDTH8, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36278
+ var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
35984
36279
  var init_flowchart_renderer = __esm({
35985
36280
  "src/graph/flowchart-renderer.ts"() {
35986
36281
  "use strict";
@@ -35996,12 +36291,11 @@ var init_flowchart_renderer = __esm({
35996
36291
  init_scaling();
35997
36292
  init_text_measure();
35998
36293
  init_note_box();
36294
+ init_visual_conventions();
35999
36295
  DIAGRAM_PADDING9 = 20;
36000
36296
  MAX_SCALE6 = 3;
36001
36297
  NODE_FONT_SIZE2 = 13;
36002
36298
  EDGE_LABEL_FONT_SIZE7 = 11;
36003
- EDGE_STROKE_WIDTH8 = 1.5;
36004
- NODE_STROKE_WIDTH8 = 1.5;
36005
36299
  ARROWHEAD_W3 = 10;
36006
36300
  ARROWHEAD_H3 = 7;
36007
36301
  IO_SKEW = 15;
@@ -36985,7 +37279,7 @@ function hasRoles(node) {
36985
37279
  }
36986
37280
  function computeNodeWidth2(node, expanded, options) {
36987
37281
  const badgeVal = node.computedConcurrentInvocations === 0 && node.computedInstances > 1 ? node.computedInstances : 0;
36988
- const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE7) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37282
+ const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE5) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
36989
37283
  const labelWidth2 = measureText(node.label, NODE_FONT_SIZE3) + badgeWidth + PADDING_X3;
36990
37284
  const allKeys = [];
36991
37285
  if (node.computedRps > 0) allKeys.push("RPS");
@@ -37032,7 +37326,7 @@ function computeNodeWidth2(node, expanded, options) {
37032
37326
  }
37033
37327
  if (allKeys.length === 0) return Math.max(MIN_NODE_WIDTH2, labelWidth2);
37034
37328
  const keyColWidth = Math.max(
37035
- ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE7))
37329
+ ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE5))
37036
37330
  );
37037
37331
  let maxRowWidth = 0;
37038
37332
  if (node.computedRps > 0) {
@@ -37045,7 +37339,7 @@ function computeNodeWidth2(node, expanded, options) {
37045
37339
  const rpsVal = effectiveCap > 0 && !node.isEdge ? `${formatRpsShort(node.computedRps)} / ${formatRpsShort(effectiveCap)}` : formatRps(node.computedRps);
37046
37340
  maxRowWidth = Math.max(
37047
37341
  maxRowWidth,
37048
- keyColWidth + measureText(rpsVal, META_FONT_SIZE7)
37342
+ keyColWidth + measureText(rpsVal, META_FONT_SIZE5)
37049
37343
  );
37050
37344
  }
37051
37345
  if (expanded) {
@@ -37062,7 +37356,7 @@ function computeNodeWidth2(node, expanded, options) {
37062
37356
  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);
37063
37357
  maxRowWidth = Math.max(
37064
37358
  maxRowWidth,
37065
- keyColWidth + measureText(valStr, META_FONT_SIZE7)
37359
+ keyColWidth + measureText(valStr, META_FONT_SIZE5)
37066
37360
  );
37067
37361
  }
37068
37362
  }
@@ -37073,7 +37367,7 @@ function computeNodeWidth2(node, expanded, options) {
37073
37367
  if (ms > 0) {
37074
37368
  maxRowWidth = Math.max(
37075
37369
  maxRowWidth,
37076
- keyColWidth + measureText(formatMs(ms), META_FONT_SIZE7)
37370
+ keyColWidth + measureText(formatMs(ms), META_FONT_SIZE5)
37077
37371
  );
37078
37372
  }
37079
37373
  }
@@ -37084,37 +37378,37 @@ function computeNodeWidth2(node, expanded, options) {
37084
37378
  const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
37085
37379
  maxRowWidth = Math.max(
37086
37380
  maxRowWidth,
37087
- keyColWidth + measureText(combinedVal, META_FONT_SIZE7)
37381
+ keyColWidth + measureText(combinedVal, META_FONT_SIZE5)
37088
37382
  );
37089
37383
  }
37090
37384
  }
37091
37385
  if (node.computedUptime < 1) {
37092
37386
  maxRowWidth = Math.max(
37093
37387
  maxRowWidth,
37094
- keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE7)
37388
+ keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE5)
37095
37389
  );
37096
37390
  }
37097
37391
  if (node.computedAvailability < 1) {
37098
37392
  maxRowWidth = Math.max(
37099
37393
  maxRowWidth,
37100
- keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE7)
37394
+ keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE5)
37101
37395
  );
37102
37396
  }
37103
37397
  if (node.computedCbState === "open") {
37104
37398
  maxRowWidth = Math.max(
37105
37399
  maxRowWidth,
37106
- measureText("CB: OPEN", META_FONT_SIZE7) + 8
37400
+ measureText("CB: OPEN", META_FONT_SIZE5) + 8
37107
37401
  );
37108
37402
  }
37109
37403
  }
37110
- const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE7;
37404
+ const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE5;
37111
37405
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
37112
37406
  let descWidth = 0;
37113
37407
  for (const dl of descLines) {
37114
- const truncated = truncateText(dl, META_FONT_SIZE7, DESC_MAX_WIDTH2);
37408
+ const truncated = truncateText(dl, META_FONT_SIZE5, DESC_MAX_WIDTH2);
37115
37409
  descWidth = Math.max(
37116
37410
  descWidth,
37117
- measureText(truncated, META_FONT_SIZE7) + PADDING_X3
37411
+ measureText(truncated, META_FONT_SIZE5) + PADDING_X3
37118
37412
  );
37119
37413
  }
37120
37414
  return Math.max(MIN_NODE_WIDTH2, labelWidth2, maxRowWidth + 20, descWidth);
@@ -37124,17 +37418,17 @@ function computeNodeHeight2(node, expanded, options) {
37124
37418
  const computedCount = countComputedRows(node, expanded);
37125
37419
  const hasRps = node.computedRps > 0;
37126
37420
  const descLineCount = expanded && node.description && !node.isEdge ? node.description.length : 0;
37127
- const descH = descLineCount * META_LINE_HEIGHT7;
37421
+ const descH = descLineCount * META_LINE_HEIGHT5;
37128
37422
  if (propCount === 0 && computedCount === 0 && !hasRps)
37129
37423
  return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
37130
37424
  let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
37131
37425
  const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
37132
- h += computedSectionCount * META_LINE_HEIGHT7;
37426
+ h += computedSectionCount * META_LINE_HEIGHT5;
37133
37427
  if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
37134
- h += propCount * META_LINE_HEIGHT7;
37428
+ h += propCount * META_LINE_HEIGHT5;
37135
37429
  if (hasRoles(node)) h += ROLE_DOT_ROW;
37136
37430
  h += NODE_PAD_BOTTOM;
37137
- if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT5;
37431
+ if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT3;
37138
37432
  return h;
37139
37433
  }
37140
37434
  function formatRps(rps) {
@@ -37469,7 +37763,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
37469
37763
  height: totalHeight
37470
37764
  };
37471
37765
  }
37472
- var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT5, NODE_FONT_SIZE3, META_FONT_SIZE7, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
37766
+ var import_dagre7, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT5, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT3, NODE_FONT_SIZE3, META_FONT_SIZE5, EDGE_LABEL_FONT_SIZE8, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
37473
37767
  var init_layout10 = __esm({
37474
37768
  "src/infra/layout.ts"() {
37475
37769
  "use strict";
@@ -37477,13 +37771,13 @@ var init_layout10 = __esm({
37477
37771
  init_text_measure();
37478
37772
  MIN_NODE_WIDTH2 = 140;
37479
37773
  NODE_HEADER_HEIGHT = 28;
37480
- META_LINE_HEIGHT7 = 14;
37774
+ META_LINE_HEIGHT5 = 14;
37481
37775
  NODE_SEPARATOR_GAP = 4;
37482
37776
  NODE_PAD_BOTTOM = 10;
37483
37777
  ROLE_DOT_ROW = 12;
37484
- COLLAPSE_BAR_HEIGHT5 = 6;
37778
+ COLLAPSE_BAR_HEIGHT3 = 6;
37485
37779
  NODE_FONT_SIZE3 = 13;
37486
- META_FONT_SIZE7 = 10;
37780
+ META_FONT_SIZE5 = 10;
37487
37781
  EDGE_LABEL_FONT_SIZE8 = 11;
37488
37782
  PADDING_X3 = 24;
37489
37783
  GROUP_PADDING2 = 20;
@@ -37587,19 +37881,19 @@ __export(renderer_exports10, {
37587
37881
  function buildScaledConstants(ctx) {
37588
37882
  return {
37589
37883
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
37590
- sMetaFontSize: ctx.text(META_FONT_SIZE8),
37591
- sMetaLineHeight: ctx.structural(META_LINE_HEIGHT8),
37884
+ sMetaFontSize: ctx.text(META_FONT_SIZE6),
37885
+ sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
37592
37886
  sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
37593
37887
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
37594
37888
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
37595
- sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH9),
37596
- sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH9),
37889
+ sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
37890
+ sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH),
37597
37891
  sOverloadStrokeWidth: ctx.structural(OVERLOAD_STROKE_WIDTH),
37598
37892
  sRoleDotRadius: ctx.structural(ROLE_DOT_RADIUS),
37599
37893
  sNodeSeparatorGap: ctx.structural(NODE_SEPARATOR_GAP2),
37600
37894
  sNodePadBottom: ctx.structural(NODE_PAD_BOTTOM2),
37601
- sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT6),
37602
- sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET2),
37895
+ sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT),
37896
+ sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET),
37603
37897
  sParticleR: ctx.structural(PARTICLE_R),
37604
37898
  sRejectParticleR: ctx.structural(PARTICLE_R),
37605
37899
  sRejectDropDistance: ctx.structural(REJECT_DROP_DISTANCE),
@@ -37923,7 +38217,7 @@ function isWarning(node) {
37923
38217
  return cap > 0 && node.computedRps / cap > 0.7;
37924
38218
  }
37925
38219
  function truncateDesc(text) {
37926
- return truncateText(text, META_FONT_SIZE8, DESC_MAX_WIDTH);
38220
+ return truncateText(text, META_FONT_SIZE6, DESC_MAX_WIDTH);
37927
38221
  }
37928
38222
  function sloLatencyColor(p90, slo) {
37929
38223
  const t = slo.latencyP90 ?? 0;
@@ -38402,7 +38696,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38402
38696
  if (!isNodeCollapsed) {
38403
38697
  const expanded = expandedNodeIds?.has(node.id) ?? false;
38404
38698
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
38405
- const descH = descLines.length * META_LINE_HEIGHT8;
38699
+ const descH = descLines.length * META_LINE_HEIGHT6;
38406
38700
  for (let di = 0; di < descLines.length; di++) {
38407
38701
  const rawLine = descLines[di];
38408
38702
  const processed = preprocessDescriptionLine(rawLine);
@@ -38410,7 +38704,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38410
38704
  const isTruncated = descTruncated !== processed;
38411
38705
  const textEl = g.append("text").attr("x", node.x).attr(
38412
38706
  "y",
38413
- y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT8 + META_LINE_HEIGHT8 / 2 + sc.sMetaFontSize * 0.35
38707
+ y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT6 + META_LINE_HEIGHT6 / 2 + sc.sMetaFontSize * 0.35
38414
38708
  ).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sMetaFontSize).attr("fill", textFill);
38415
38709
  renderInlineText(textEl, descTruncated, palette, sc.sMetaFontSize);
38416
38710
  if (isTruncated) textEl.append("title").text(rawLine);
@@ -38928,7 +39222,7 @@ function parseAndLayoutInfra(content) {
38928
39222
  const layout = layoutInfra(computed);
38929
39223
  return { parsed, computed, layout };
38930
39224
  }
38931
- var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE8, META_LINE_HEIGHT8, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, EDGE_STROKE_WIDTH9, NODE_STROKE_WIDTH9, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, COLLAPSE_BAR_HEIGHT6, COLLAPSE_BAR_INSET2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
39225
+ var d3Selection16, d3Shape8, NODE_FONT_SIZE4, META_FONT_SIZE6, META_LINE_HEIGHT6, EDGE_LABEL_FONT_SIZE9, GROUP_LABEL_FONT_SIZE2, NODE_BORDER_RADIUS, OVERLOAD_STROKE_WIDTH, ROLE_DOT_RADIUS, NODE_HEADER_HEIGHT2, NODE_SEPARATOR_GAP2, NODE_PAD_BOTTOM2, LEGEND_FIXED_GAP3, SPEED_BADGE_H_PAD, SPEED_BADGE_V_PAD, SPEED_BADGE_GAP, COLOR_HEALTHY, COLOR_WARNING, COLOR_OVERLOADED, FLOW_SPEED_MIN, FLOW_SPEED_MAX, PARTICLE_R, PARTICLE_COUNT_MIN, PARTICLE_COUNT_MAX, NODE_PULSE_SPEED, NODE_PULSE_OVERLOAD, REJECT_DROP_DISTANCE, REJECT_DURATION_MIN, REJECT_DURATION_MAX, REJECT_COUNT_MIN, REJECT_COUNT_MAX, PROP_DISPLAY, DESC_MAX_CHARS, DESC_MAX_WIDTH, RPS_FORMAT_KEYS, MS_FORMAT_KEYS, PCT_FORMAT_KEYS;
38932
39226
  var init_renderer10 = __esm({
38933
39227
  "src/infra/renderer.ts"() {
38934
39228
  "use strict";
@@ -38949,21 +39243,18 @@ var init_renderer10 = __esm({
38949
39243
  init_legend_layout();
38950
39244
  init_title_constants();
38951
39245
  init_scaling();
39246
+ init_visual_conventions();
38952
39247
  NODE_FONT_SIZE4 = 13;
38953
- META_FONT_SIZE8 = 10;
38954
- META_LINE_HEIGHT8 = 14;
39248
+ META_FONT_SIZE6 = 10;
39249
+ META_LINE_HEIGHT6 = 14;
38955
39250
  EDGE_LABEL_FONT_SIZE9 = 11;
38956
39251
  GROUP_LABEL_FONT_SIZE2 = 14;
38957
39252
  NODE_BORDER_RADIUS = 8;
38958
- EDGE_STROKE_WIDTH9 = 1.5;
38959
- NODE_STROKE_WIDTH9 = 1.5;
38960
39253
  OVERLOAD_STROKE_WIDTH = 3;
38961
39254
  ROLE_DOT_RADIUS = 3;
38962
39255
  NODE_HEADER_HEIGHT2 = 28;
38963
39256
  NODE_SEPARATOR_GAP2 = 4;
38964
39257
  NODE_PAD_BOTTOM2 = 10;
38965
- COLLAPSE_BAR_HEIGHT6 = 6;
38966
- COLLAPSE_BAR_INSET2 = 0;
38967
39258
  LEGEND_FIXED_GAP3 = 16;
38968
39259
  SPEED_BADGE_H_PAD = 5;
38969
39260
  SPEED_BADGE_V_PAD = 3;
@@ -39002,7 +39293,7 @@ var init_renderer10 = __esm({
39002
39293
  partitions: "partitions"
39003
39294
  };
39004
39295
  DESC_MAX_CHARS = 120;
39005
- DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE8;
39296
+ DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE6;
39006
39297
  RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
39007
39298
  MS_FORMAT_KEYS = /* @__PURE__ */ new Set([
39008
39299
  "latency-ms",
@@ -40789,18 +41080,18 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
40789
41080
  const sLegendPillHeight = ctx.structural(LEGEND_PILL_HEIGHT);
40790
41081
  const sLegendBlockHeight = showTagLegend ? sLegendTopGap + sLegendPillHeight + sLegendBottomGap : 0;
40791
41082
  const sNodeRadius = ctx.structural(NODE_RADIUS2);
40792
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH10);
41083
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
40793
41084
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE5);
40794
41085
  const sNodeCellFontSize = ctx.text(NODE_CELL_FONT_SIZE2);
40795
41086
  const sNodeTopRowHeight = ctx.structural(NODE_TOP_ROW_HEIGHT);
40796
41087
  const sNodeBottomRowHeight = ctx.structural(NODE_BOTTOM_ROW_HEIGHT);
40797
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH10);
41088
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
40798
41089
  const sArrowheadW = ctx.structural(ARROWHEAD_W4);
40799
41090
  const sArrowheadH = ctx.structural(ARROWHEAD_H4);
40800
- const sContainerRadius = ctx.structural(CONTAINER_RADIUS3);
40801
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE4);
40802
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT3);
40803
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT7);
41091
+ const sContainerRadius = ctx.structural(CONTAINER_RADIUS);
41092
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
41093
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
41094
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
40804
41095
  const sPinIconW = ctx.structural(PIN_ICON_W);
40805
41096
  const sPinIconH = ctx.structural(PIN_ICON_H);
40806
41097
  const scaledWidth = layout.width + sDiagramPad * 2;
@@ -41367,7 +41658,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41367
41658
  palette.textOnFillDark
41368
41659
  );
41369
41660
  const sNR = sc.nodeRadius ?? NODE_RADIUS2;
41370
- const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT7;
41661
+ const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT;
41371
41662
  drawTextbookCard(g, {
41372
41663
  width: grp.width,
41373
41664
  height: grp.height,
@@ -41401,10 +41692,10 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41401
41692
  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})`);
41402
41693
  continue;
41403
41694
  }
41404
- const sCR = sc.containerRadius ?? CONTAINER_RADIUS3;
41405
- const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE4;
41406
- const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT3;
41407
- const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41695
+ const sCR = sc.containerRadius ?? CONTAINER_RADIUS;
41696
+ const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE;
41697
+ const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT;
41698
+ const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH;
41408
41699
  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);
41409
41700
  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);
41410
41701
  }
@@ -41457,7 +41748,7 @@ function renderEdges2(root, resolved, layout, palette, collapsedSet, sc = {}) {
41457
41748
  }
41458
41749
  const path = lineGenerator6(e.points);
41459
41750
  if (!path) continue;
41460
- const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH10;
41751
+ const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH;
41461
41752
  const sELFS = sc.edgeLabelFontSize ?? 10;
41462
41753
  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 ?? "");
41463
41754
  const parsedEdge = edgeByKey.get(`${e.source}->${e.target}`);
@@ -41639,7 +41930,7 @@ function computeDurationEmphasis(activities) {
41639
41930
  function drawTextbookCard(g, a) {
41640
41931
  const { width: w, height: h, x, y } = a;
41641
41932
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41642
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41933
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41643
41934
  const sTRH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41644
41935
  const sBRH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41645
41936
  const sNFS = a.sNodeFontSize ?? NODE_FONT_SIZE5;
@@ -41738,7 +42029,7 @@ function drawTextbookCard(g, a) {
41738
42029
  function drawMilestonePill(g, a) {
41739
42030
  const { width: w, height: h, x, y } = a;
41740
42031
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41741
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42032
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41742
42033
  const topRowH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41743
42034
  const botRowH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41744
42035
  const sNCFS = a.sNodeCellFontSize ?? NODE_CELL_FONT_SIZE2;
@@ -41871,7 +42162,7 @@ function renderCaptionBlock(svg, bullets, args) {
41871
42162
  palette.textOnFillDark
41872
42163
  );
41873
42164
  const block = svg.append("g").attr("class", "pert-caption-block").attr("data-pert-caption", "");
41874
- 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);
42165
+ 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);
41875
42166
  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");
41876
42167
  const textX = x + CAPTION_BOX_PADDING_X;
41877
42168
  const firstBaselineY = y + CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT + CAPTION_FONT_SIZE;
@@ -41988,7 +42279,7 @@ function renderTornadoBlock(svg, rows, args) {
41988
42279
  palette.textOnFillDark
41989
42280
  );
41990
42281
  const block = svg.append("g").attr("class", "pert-tornado-block").attr("data-pert-tornado", "");
41991
- 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);
42282
+ 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);
41992
42283
  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");
41993
42284
  const fmt = (v) => {
41994
42285
  const r = Math.round(v * 100) / 100;
@@ -42144,7 +42435,7 @@ function renderScurveBlock(svg, data, args) {
42144
42435
  palette.textOnFillDark
42145
42436
  );
42146
42437
  const block = svg.append("g").attr("class", "pert-scurve-block").attr("data-pert-scurve", "");
42147
- 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);
42438
+ 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);
42148
42439
  const hasTitle = typeof title === "string" && title.length > 0;
42149
42440
  if (hasTitle) {
42150
42441
  const titleText = title.replace(/\.$/, "");
@@ -42328,7 +42619,7 @@ function formatScurveDate(iso) {
42328
42619
  if (month < 0 || month > 11 || isNaN(day)) return iso;
42329
42620
  return `${SCURVE_MONTH_NAMES[month]} ${day}`;
42330
42621
  }
42331
- var d3Selection17, d3Shape9, DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_STROKE_WIDTH10, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, EDGE_STROKE_WIDTH10, ARROWHEAD_W4, ARROWHEAD_H4, CONTAINER_RADIUS3, CONTAINER_LABEL_FONT_SIZE4, CONTAINER_HEADER_HEIGHT3, COLLAPSE_BAR_HEIGHT7, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42622
+ var d3Selection17, d3Shape9, DIAGRAM_PADDING11, NODE_FONT_SIZE5, NODE_CELL_FONT_SIZE2, NODE_RADIUS2, NODE_TOP_ROW_HEIGHT, NODE_BOTTOM_ROW_HEIGHT, ARROWHEAD_W4, ARROWHEAD_H4, DURATION_FADE_OPACITY, PIN_ICON_W, PIN_ICON_H, LEGEND_PILL_HEIGHT, LEGEND_TOP_GAP, LEGEND_BOTTOM_GAP, FIELD_LEGEND_HEADER_BAND_HEIGHT, FIELD_LEGEND_CELL_VPAD, FIELD_LEGEND_LABEL_FONT_SIZE, FIELD_LEGEND_DESC_FONT_SIZE, FIELD_LEGEND_DESC_LINE_HEIGHT, FIELD_LEGEND_LABEL_DESC_GAP, FIELD_LEGEND_CELLS, lineGenerator6, FIELD_LEGEND_MIN_W, SUB_BULLET_INDENT, CAPTION_HEADER_BAND_HEIGHT, TORNADO_TOP_N, TORNADO_ROW_HEIGHT, TORNADO_NAME_COL_W, TORNADO_BAR_FONT_SIZE, TORNADO_BAR_HEIGHT, SUMMARY_MIN_W, SUMMARY_MAX_W, ANALYSIS_GAP, COL1_VSTACK_GAP, TORNADO_MIN_W, SCURVE_MIN_W, SCURVE_BOX_HEIGHT, SCURVE_PLOT_PADDING_X, SCURVE_PLOT_PADDING_RIGHT, SCURVE_PLOT_PADDING_BOTTOM, SCURVE_TICK_FONT_SIZE, SCURVE_PERCENTILE_RADIUS, DAYS_PER_UNIT, SCURVE_MONTH_NAMES, UNIT_TO_DAYS_LOCAL2;
42332
42623
  var init_renderer11 = __esm({
42333
42624
  "src/pert/renderer.ts"() {
42334
42625
  "use strict";
@@ -42346,20 +42637,15 @@ var init_renderer11 = __esm({
42346
42637
  init_analyzer();
42347
42638
  init_layout11();
42348
42639
  init_internal();
42640
+ init_visual_conventions();
42349
42641
  DIAGRAM_PADDING11 = 20;
42350
42642
  NODE_FONT_SIZE5 = 13;
42351
42643
  NODE_CELL_FONT_SIZE2 = 11;
42352
42644
  NODE_RADIUS2 = 6;
42353
- NODE_STROKE_WIDTH10 = 1.5;
42354
42645
  NODE_TOP_ROW_HEIGHT = 26;
42355
42646
  NODE_BOTTOM_ROW_HEIGHT = 26;
42356
- EDGE_STROKE_WIDTH10 = 1.5;
42357
42647
  ARROWHEAD_W4 = 10;
42358
42648
  ARROWHEAD_H4 = 7;
42359
- CONTAINER_RADIUS3 = 8;
42360
- CONTAINER_LABEL_FONT_SIZE4 = 13;
42361
- CONTAINER_HEADER_HEIGHT3 = 28;
42362
- COLLAPSE_BAR_HEIGHT7 = 6;
42363
42649
  DURATION_FADE_OPACITY = 0.55;
42364
42650
  PIN_ICON_W = 13;
42365
42651
  PIN_ICON_H = 13;
@@ -45350,8 +45636,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
45350
45636
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
45351
45637
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
45352
45638
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
45353
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH11);
45354
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH11);
45639
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
45640
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
45355
45641
  const sArrowheadW = ctx.structural(ARROWHEAD_W5);
45356
45642
  const sArrowheadH = ctx.structural(ARROWHEAD_H5);
45357
45643
  const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
@@ -45628,7 +45914,7 @@ function renderStateForExport(content, theme, palette) {
45628
45914
  document.body.removeChild(container);
45629
45915
  }
45630
45916
  }
45631
- var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, EDGE_STROKE_WIDTH11, NODE_STROKE_WIDTH11, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
45917
+ var d3Selection19, DIAGRAM_PADDING12, MAX_SCALE7, NODE_FONT_SIZE6, EDGE_LABEL_FONT_SIZE10, GROUP_LABEL_FONT_SIZE3, ARROWHEAD_W5, ARROWHEAD_H5, PSEUDOSTATE_RADIUS, STATE_CORNER_RADIUS, GROUP_EXTRA_PADDING;
45632
45918
  var init_state_renderer = __esm({
45633
45919
  "src/graph/state-renderer.ts"() {
45634
45920
  "use strict";
@@ -45644,13 +45930,12 @@ var init_state_renderer = __esm({
45644
45930
  init_scaling();
45645
45931
  init_text_measure();
45646
45932
  init_note_box();
45933
+ init_visual_conventions();
45647
45934
  DIAGRAM_PADDING12 = 20;
45648
45935
  MAX_SCALE7 = 3;
45649
45936
  NODE_FONT_SIZE6 = 13;
45650
45937
  EDGE_LABEL_FONT_SIZE10 = 11;
45651
45938
  GROUP_LABEL_FONT_SIZE3 = 11;
45652
- EDGE_STROKE_WIDTH11 = 1.5;
45653
- NODE_STROKE_WIDTH11 = 1.5;
45654
45939
  ARROWHEAD_W5 = 10;
45655
45940
  ARROWHEAD_H5 = 7;
45656
45941
  PSEUDOSTATE_RADIUS = 10;
@@ -47363,14 +47648,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47363
47648
  const panelY = PADDING2;
47364
47649
  const textX = panelX + CARD_PADDING_X3;
47365
47650
  const clipId = "persona-clip";
47366
- defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5);
47651
+ defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
47367
47652
  const personaFill = shapeFill(palette, personaColor, isDark, { solid });
47368
47653
  const onPersonaText = contrastText(
47369
47654
  personaFill,
47370
47655
  palette.textOnFillLight,
47371
47656
  palette.textOnFillDark
47372
47657
  );
47373
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", personaFill);
47658
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
47374
47659
  if (descLines.length > 0) {
47375
47660
  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);
47376
47661
  }
@@ -47378,7 +47663,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47378
47663
  const silY = panelY + panelHeight / 2 - 6;
47379
47664
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
47380
47665
  renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
47381
- 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);
47666
+ 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);
47382
47667
  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);
47383
47668
  for (let li = 0; li < descLines.length; li++) {
47384
47669
  const lineEl = personaG.append("text").attr("x", textX).attr("y", panelY + titleRowH + descLineH * (li + 1)).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
@@ -47618,7 +47903,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47618
47903
  { solid }
47619
47904
  );
47620
47905
  const rowStroke = stepColor ?? palette.textMuted;
47621
- 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);
47906
+ 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);
47622
47907
  const faceCx = listX + CARD_PADDING_X3 + COLLAPSED_FACE_R;
47623
47908
  const faceCy = itemY + COLLAPSED_CARD_H / 2;
47624
47909
  if (step.score !== void 0) {
@@ -47781,7 +48066,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47781
48066
  const scoreColor = scoreToColor(score, palette);
47782
48067
  const tintedBg = mix(scoreColor, palette.surface, 20);
47783
48068
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
47784
- 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);
48069
+ 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);
47785
48070
  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);
47786
48071
  const centerX = bx + bw / 2;
47787
48072
  for (let i = 0; i < lines.length; i++) {
@@ -47938,7 +48223,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
47938
48223
  palette.textOnFillLight,
47939
48224
  palette.textOnFillDark
47940
48225
  );
47941
- 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);
48226
+ 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);
47942
48227
  const titleMaxW = sl.width - CARD_PADDING_X3 * 2;
47943
48228
  const titleLines = wrapTextToWidth(sl.step.title, FONT_SIZE_STEP, titleMaxW);
47944
48229
  for (let i = 0; i < titleLines.length; i++) {
@@ -47997,7 +48282,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
47997
48282
  const stripFill = shapeFill(palette, stripColor, isDark, {
47998
48283
  ...solid !== void 0 && { solid }
47999
48284
  });
48000
- 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);
48285
+ 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);
48001
48286
  const stripTextColor = contrastText(
48002
48287
  stripFill,
48003
48288
  palette.textOnFillLight,
@@ -48113,7 +48398,7 @@ function renderJourneyMapForExport(content, theme, palette) {
48113
48398
  }
48114
48399
  return svgEl.outerHTML;
48115
48400
  }
48116
- var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_RADIUS5, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48401
+ var d3, d3Shape10, DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
48117
48402
  var init_renderer14 = __esm({
48118
48403
  "src/journey-map/renderer.ts"() {
48119
48404
  "use strict";
@@ -48128,9 +48413,9 @@ var init_renderer14 = __esm({
48128
48413
  init_tag_groups();
48129
48414
  init_scaling();
48130
48415
  init_text_measure();
48416
+ init_visual_conventions();
48131
48417
  DIAGRAM_PADDING13 = 20;
48132
48418
  PADDING2 = DIAGRAM_PADDING13;
48133
- CARD_RADIUS5 = 6;
48134
48419
  CARD_PADDING_X3 = 10;
48135
48420
  CARD_PADDING_Y3 = 6;
48136
48421
  CARD_HEADER_HEIGHT3 = 24;
@@ -48207,7 +48492,7 @@ function computeCycleLayout(parsed, options) {
48207
48492
  const hasDesc = !hideDescriptions && node.description.length > 0;
48208
48493
  const labelWidth2 = Math.max(
48209
48494
  MIN_NODE_WIDTH4,
48210
- measureText(node.label, LABEL_FONT_SIZE5) + NODE_PAD_X * 2
48495
+ measureText(node.label, LABEL_FONT_SIZE4) + NODE_PAD_X * 2
48211
48496
  );
48212
48497
  if (circleNodes) {
48213
48498
  return computeCircleNodeDims(node, hasDesc);
@@ -48424,7 +48709,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48424
48709
  let bestScore = Infinity;
48425
48710
  for (let w = minW; w <= MAX_NODE_WIDTH3; w += DESC_WIDTH_STEP) {
48426
48711
  const wrapped2 = wrapDescForWidth(description, w);
48427
- const h = HEADER_HEIGHT5 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48712
+ const h = HEADER_HEIGHT4 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48428
48713
  const ratio = w / h;
48429
48714
  const score = Math.abs(Math.log(ratio / DESC_TARGET_RATIO));
48430
48715
  if (score < bestScore) {
@@ -48436,7 +48721,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48436
48721
  const wrapped = wrapDescForWidth(description, minW);
48437
48722
  return {
48438
48723
  width: minW,
48439
- height: HEADER_HEIGHT5 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48724
+ height: HEADER_HEIGHT4 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48440
48725
  wrappedDesc: wrapped
48441
48726
  };
48442
48727
  }
@@ -48449,7 +48734,7 @@ function wrapDescForWidth(description, nodeWidth) {
48449
48734
  );
48450
48735
  }
48451
48736
  function renderedDescNodeHeight(numLines, scale) {
48452
- const headerH = HEADER_HEIGHT5 * scale;
48737
+ const headerH = HEADER_HEIGHT4 * scale;
48453
48738
  const descFont = Math.max(
48454
48739
  RENDERER_DESC_FONT_MIN,
48455
48740
  Math.round(RENDERER_DESC_FONT * scale)
@@ -48784,7 +49069,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
48784
49069
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
48785
49070
  return { path, midAngle };
48786
49071
  }
48787
- 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;
49072
+ 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;
48788
49073
  var init_layout14 = __esm({
48789
49074
  "src/cycle/layout.ts"() {
48790
49075
  "use strict";
@@ -48792,7 +49077,7 @@ var init_layout14 = __esm({
48792
49077
  init_wrapped_desc();
48793
49078
  init_text_measure();
48794
49079
  MIN_ARC_ANGLE = 15 * Math.PI / 180;
48795
- LABEL_FONT_SIZE5 = 13;
49080
+ LABEL_FONT_SIZE4 = 13;
48796
49081
  CIRCLE_LABEL_FONT_SIZE = 16;
48797
49082
  DESC_FONT_SIZE6 = 11;
48798
49083
  EDGE_LABEL_FONT_SIZE11 = 11;
@@ -48802,7 +49087,7 @@ var init_layout14 = __esm({
48802
49087
  DESC_WIDTH_STEP = 20;
48803
49088
  DESC_TARGET_RATIO = 1.6;
48804
49089
  PLAIN_NODE_HEIGHT = 50;
48805
- HEADER_HEIGHT5 = 36;
49090
+ HEADER_HEIGHT4 = 36;
48806
49091
  DESC_LINE_HEIGHT7 = 16;
48807
49092
  DESC_PAD_Y = 14;
48808
49093
  NODE_PAD_X = 20;
@@ -52899,6 +53184,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
52899
53184
  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);
52900
53185
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
52901
53186
  const defs = svg.append("defs");
53187
+ const uid = mapInstanceCounter++;
53188
+ const nid = (base) => `${base}__m${uid}`;
52902
53189
  const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
52903
53190
  const haloColor = palette.bg;
52904
53191
  const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
@@ -52931,8 +53218,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
52931
53218
  for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
52932
53219
  if (layout.relief.length && layout.reliefHatch) {
52933
53220
  const h = layout.reliefHatch;
52934
- const rangeClipId = "dgmo-relief-clip";
52935
- const landClipId = "dgmo-relief-land";
53221
+ const rangeClipId = nid("dgmo-relief-clip");
53222
+ const landClipId = nid("dgmo-relief-land");
52936
53223
  const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
52937
53224
  for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
52938
53225
  const landClip = defs.append("clipPath").attr("id", landClipId);
@@ -52945,7 +53232,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
52945
53232
  }
52946
53233
  if (layout.coastlineStyle) {
52947
53234
  const cs = layout.coastlineStyle;
52948
- const maskId = "dgmo-map-water-mask";
53235
+ const maskId = nid("dgmo-map-water-mask");
52949
53236
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
52950
53237
  mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
52951
53238
  const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
@@ -52963,7 +53250,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
52963
53250
  appendWaterLines(
52964
53251
  gWater,
52965
53252
  defs,
52966
- "dgmo-map-coast",
53253
+ nid("dgmo-map-coast"),
52967
53254
  // Pass the canvas frame so edges collinear with it (the antimeridian on a
52968
53255
  // world map, regional clipExtent cuts) don't get ringed as fake coast —
52969
53256
  // land runs cleanly to the render-area edge.
@@ -53000,7 +53287,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53000
53287
  (l) => l.poiId !== void 0 && !l.hidden
53001
53288
  );
53002
53289
  if (poiLabels.length) {
53003
- const patchBlurId = "dgmo-map-label-patch-blur";
53290
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
53004
53291
  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);
53005
53292
  const PAD = 8;
53006
53293
  const buildPatch = (labels, maskId, decoCluster) => {
@@ -53045,7 +53332,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53045
53332
  if (clusterUi) {
53046
53333
  buildPatch(
53047
53334
  poiLabels.filter((l) => l.clusterMember === void 0),
53048
- "dgmo-map-label-patch"
53335
+ nid("dgmo-map-label-patch")
53049
53336
  );
53050
53337
  const byCluster = /* @__PURE__ */ new Map();
53051
53338
  for (const l of poiLabels) {
@@ -53056,9 +53343,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53056
53343
  }
53057
53344
  let ci = 0;
53058
53345
  for (const [cid, labs] of byCluster)
53059
- buildPatch(labs, `dgmo-map-label-patch-c${ci++}`, cid);
53346
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
53060
53347
  } else {
53061
- buildPatch(poiLabels, "dgmo-map-label-patch");
53348
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
53062
53349
  }
53063
53350
  }
53064
53351
  if (layout.insets.length) {
@@ -53067,7 +53354,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53067
53354
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
53068
53355
  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");
53069
53356
  if (box.contextLand) {
53070
- const clipId = `dgmo-map-inset-clip-${bi}`;
53357
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
53071
53358
  defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
53072
53359
  insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
53073
53360
  }
@@ -53075,7 +53362,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53075
53362
  for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
53076
53363
  if (layout.coastlineStyle) {
53077
53364
  const cs = layout.coastlineStyle;
53078
- const maskId = "dgmo-map-inset-water-mask";
53365
+ const maskId = nid("dgmo-map-inset-water-mask");
53079
53366
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53080
53367
  const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
53081
53368
  for (const box of layout.insets) {
@@ -53084,7 +53371,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53084
53371
  }
53085
53372
  layout.insets.forEach((box, bi) => {
53086
53373
  if (box.contextLand)
53087
- mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#dgmo-map-inset-clip-${bi})`);
53374
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
53088
53375
  });
53089
53376
  for (const r of layout.insetRegions)
53090
53377
  if (r.id !== "lake")
@@ -53092,7 +53379,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53092
53379
  for (const r of layout.insetRegions)
53093
53380
  if (r.id === "lake")
53094
53381
  mask.append("path").attr("d", r.d).attr("fill", "white");
53095
- const clipId = "dgmo-map-inset-water-clip";
53382
+ const clipId = nid("dgmo-map-inset-water-clip");
53096
53383
  const clip = defs.append("clipPath").attr("id", clipId);
53097
53384
  for (const box of layout.insets) {
53098
53385
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
@@ -53102,7 +53389,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53102
53389
  appendWaterLines(
53103
53390
  gInsetWater,
53104
53391
  defs,
53105
- "dgmo-map-inset-coast",
53392
+ nid("dgmo-map-inset-coast"),
53106
53393
  coastlineOuterRings(layout.insetRegions, cs.minExtent),
53107
53394
  cs,
53108
53395
  layout.background
@@ -53131,7 +53418,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53131
53418
  }
53132
53419
  wireSync(p, leg.lineNumber);
53133
53420
  if (leg.arrow) {
53134
- const id = `dgmo-map-arrow-${i}`;
53421
+ const id = nid(`dgmo-map-arrow-${i}`);
53135
53422
  const s = arrowSize(leg.width);
53136
53423
  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);
53137
53424
  p.attr("marker-end", `url(#${id})`);
@@ -53327,7 +53614,7 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
53327
53614
  }
53328
53615
  return t;
53329
53616
  }
53330
- var d3Selection23, LABEL_FONT;
53617
+ var d3Selection23, LABEL_FONT, mapInstanceCounter;
53331
53618
  var init_renderer16 = __esm({
53332
53619
  "src/map/renderer.ts"() {
53333
53620
  "use strict";
@@ -53340,6 +53627,7 @@ var init_renderer16 = __esm({
53340
53627
  init_legend_band();
53341
53628
  init_layout15();
53342
53629
  LABEL_FONT = 11;
53630
+ mapInstanceCounter = 0;
53343
53631
  }
53344
53632
  });
53345
53633
 
@@ -54271,7 +54559,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54271
54559
  const sHMargin = ctx.aesthetic(H_MARGIN);
54272
54560
  const sVMargin = ctx.aesthetic(V_MARGIN3);
54273
54561
  const sTitleAreaHeight = ctx.structural(TITLE_AREA_HEIGHT4);
54274
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT6);
54562
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT5);
54275
54563
  const sRowHeight = ctx.structural(ROW_HEIGHT);
54276
54564
  const sPhaseHeight = ctx.structural(PHASE_HEIGHT);
54277
54565
  const sTaskLabelMin = ctx.structural(TASK_LABEL_MIN);
@@ -54296,7 +54584,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54296
54584
  const sLegendLetterFont = ctx.text(LEGEND_LETTER_FONT);
54297
54585
  const sViolationLineHeight = ctx.structural(VIOLATION_LINE_HEIGHT);
54298
54586
  const sStackTopGap = ctx.structural(STACK_TOP_GAP);
54299
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH12);
54587
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
54300
54588
  const sNodeRadius = ctx.structural(NODE_RADIUS3);
54301
54589
  const innerWidth = Math.max(0, width - 2 * sHMargin);
54302
54590
  let roleColW = Math.max(
@@ -54842,7 +55130,7 @@ function parseQuotedSegments(message) {
54842
55130
  out.push({ text: message.slice(last), bold: false });
54843
55131
  return out;
54844
55132
  }
54845
- var d3Selection26, MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT6, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_STROKE_WIDTH12, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
55133
+ var d3Selection26, MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
54846
55134
  var init_renderer19 = __esm({
54847
55135
  "src/raci/renderer.ts"() {
54848
55136
  "use strict";
@@ -54854,6 +55142,7 @@ var init_renderer19 = __esm({
54854
55142
  init_variants();
54855
55143
  init_scaling();
54856
55144
  init_text_measure();
55145
+ init_visual_conventions();
54857
55146
  MARKER_LABELS = {
54858
55147
  raci: { R: "Responsible", A: "Accountable", C: "Consulted", I: "Informed" },
54859
55148
  rasci: {
@@ -54875,7 +55164,7 @@ var init_renderer19 = __esm({
54875
55164
  TITLE_LEGEND_GAP = 16;
54876
55165
  LEGEND_LABEL_FONT = 12;
54877
55166
  LEGEND_LETTER_FONT = 14;
54878
- HEADER_HEIGHT6 = 36;
55167
+ HEADER_HEIGHT5 = 36;
54879
55168
  ROW_HEIGHT = 36;
54880
55169
  PHASE_HEIGHT = 40;
54881
55170
  TASK_LABEL_MIN = 200;
@@ -54895,7 +55184,6 @@ var init_renderer19 = __esm({
54895
55184
  ROLE_HEADER_FONT = 12;
54896
55185
  PHASE_FONT = 13;
54897
55186
  TINT_PCT = 25;
54898
- NODE_STROKE_WIDTH12 = 1.5;
54899
55187
  NODE_RADIUS3 = 6;
54900
55188
  AUTO_ACCENTS = [
54901
55189
  "blue",
@@ -55495,11 +55783,11 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55495
55783
  const lines = splitParticipantLabel(
55496
55784
  p.label,
55497
55785
  labelTextWidth(PARTICIPANT_BOX_WIDTH),
55498
- LABEL_FONT_SIZE6
55786
+ LABEL_FONT_SIZE5
55499
55787
  );
55500
55788
  if (lines.length === 0) continue;
55501
55789
  const widest = Math.max(
55502
- ...lines.map((l) => measureText(l, LABEL_FONT_SIZE6))
55790
+ ...lines.map((l) => measureText(l, LABEL_FONT_SIZE5))
55503
55791
  );
55504
55792
  const labelWidth2 = widest + 10;
55505
55793
  uniformBoxWidth = Math.max(uniformBoxWidth, labelWidth2);
@@ -55533,7 +55821,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55533
55821
  const sSelfCallWidth = ctx.structural(SELF_CALL_WIDTH);
55534
55822
  const sNoteTextWidthMax = sNoteMaxW - sNotePadH * 2 - sNoteFold;
55535
55823
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
55536
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE6);
55824
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE5);
55537
55825
  const sLabelTextWidth = labelTextWidth(sBoxW);
55538
55826
  const participantIndexMap = /* @__PURE__ */ new Map();
55539
55827
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
@@ -56670,7 +56958,7 @@ function buildNoteMessageMap(elements) {
56670
56958
  walk(elements);
56671
56959
  return map;
56672
56960
  }
56673
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE6) {
56961
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
56674
56962
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
56675
56963
  if (tagAttr) {
56676
56964
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -56718,7 +57006,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
56718
57006
  });
56719
57007
  }
56720
57008
  }
56721
- var d3Selection27, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE6, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
57009
+ var d3Selection27, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
56722
57010
  var init_renderer20 = __esm({
56723
57011
  "src/sequence/renderer.ts"() {
56724
57012
  "use strict";
@@ -56739,7 +57027,7 @@ var init_renderer20 = __esm({
56739
57027
  PARTICIPANT_GAP = 160;
56740
57028
  PARTICIPANT_BOX_WIDTH = 120;
56741
57029
  PARTICIPANT_BOX_HEIGHT = 50;
56742
- LABEL_FONT_SIZE6 = 13;
57030
+ LABEL_FONT_SIZE5 = 13;
56743
57031
  TOP_MARGIN = 20;
56744
57032
  TITLE_HEIGHT8 = 30;
56745
57033
  PARTICIPANT_Y_OFFSET = 10;
@@ -62195,7 +62483,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
62195
62483
 
62196
62484
  // src/auto/index.ts
62197
62485
  init_safe_href();
62198
- var VERSION = "0.30.0";
62486
+ var VERSION = "0.31.0";
62199
62487
  var DEFAULTS = {
62200
62488
  theme: "auto",
62201
62489
  palette: "slate",