@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/advanced.cjs CHANGED
@@ -417,7 +417,7 @@ function resolveColorWithDiagnostic(color, line11, diagnostics, palette) {
417
417
  );
418
418
  return void 0;
419
419
  }
420
- var nord, colorNames, RECOGNIZED_COLOR_NAMES, seriesColors;
420
+ var nord, colorNames, RECOGNIZED_COLOR_NAMES, CATEGORICAL_COLOR_ORDER, seriesColors;
421
421
  var init_colors = __esm({
422
422
  "src/colors.ts"() {
423
423
  "use strict";
@@ -475,6 +475,16 @@ var init_colors = __esm({
475
475
  "black",
476
476
  "white"
477
477
  ]);
478
+ CATEGORICAL_COLOR_ORDER = Object.freeze([
479
+ "red",
480
+ "green",
481
+ "blue",
482
+ "yellow",
483
+ "teal",
484
+ "purple",
485
+ "orange",
486
+ "cyan"
487
+ ]);
478
488
  seriesColors = [
479
489
  nord.nord10,
480
490
  // blue
@@ -1328,11 +1338,7 @@ var init_tag_groups = __esm({
1328
1338
  init_diagnostics();
1329
1339
  init_colors();
1330
1340
  AUTO_TAG_COLOR_SENTINEL = "";
1331
- autoTagColorCycle = Object.freeze(
1332
- RECOGNIZED_COLOR_NAMES.filter(
1333
- (n) => n !== "gray" && n !== "black" && n !== "white"
1334
- )
1335
- );
1341
+ autoTagColorCycle = CATEGORICAL_COLOR_ORDER;
1336
1342
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
1337
1343
  VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
1338
1344
  }
@@ -3122,7 +3128,7 @@ function shapeFill(palette, intent, isDark, opts) {
3122
3128
  }
3123
3129
  function getSeriesColors(palette) {
3124
3130
  const c = palette.colors;
3125
- return [c.blue, c.green, c.yellow, c.orange, c.purple, c.red, c.teal, c.cyan];
3131
+ return CATEGORICAL_COLOR_ORDER.map((name) => c[name]);
3126
3132
  }
3127
3133
  function getSegmentColors(palette, count) {
3128
3134
  if (count <= 0) return [];
@@ -3175,6 +3181,7 @@ var POLITICAL_TINT_BANDS;
3175
3181
  var init_color_utils = __esm({
3176
3182
  "src/palettes/color-utils.ts"() {
3177
3183
  "use strict";
3184
+ init_colors();
3178
3185
  POLITICAL_TINT_BANDS = {
3179
3186
  light: [32, 48, 64, 80],
3180
3187
  dark: [44, 58, 72, 86]
@@ -11495,7 +11502,7 @@ var init_chart_types = __esm({
11495
11502
  },
11496
11503
  {
11497
11504
  id: "map",
11498
- description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
11505
+ description: "Geographic map: a value or count per country, state, or region (choropleth); points of interest; routes. Use when categories are real-world places."
11499
11506
  },
11500
11507
  // ── Tier 3 — Specialized analytical charts ────────────────
11501
11508
  {
@@ -11512,7 +11519,7 @@ var init_chart_types = __esm({
11512
11519
  },
11513
11520
  {
11514
11521
  id: "slope",
11515
- description: "Change between two periods"
11522
+ description: "Change for multiple things between exactly two periods"
11516
11523
  },
11517
11524
  {
11518
11525
  id: "sankey",
@@ -18963,6 +18970,7 @@ function parseBoxesAndLines(content, palette) {
18963
18970
  const nodes = [];
18964
18971
  const edges = [];
18965
18972
  const groups = [];
18973
+ const nodePositions = /* @__PURE__ */ new Map();
18966
18974
  const result = {
18967
18975
  type: "boxes-and-lines",
18968
18976
  title: null,
@@ -18996,6 +19004,8 @@ function parseBoxesAndLines(content, palette) {
18996
19004
  }
18997
19005
  const groupStack = [];
18998
19006
  let contentStarted = false;
19007
+ let inLayoutBlock = false;
19008
+ const LAYOUT_ENTRY_RE = /^(.+?):\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*$/;
18999
19009
  let currentTagGroup = null;
19000
19010
  const metaAliasMap = /* @__PURE__ */ new Map();
19001
19011
  const nameAliasMap = /* @__PURE__ */ new Map();
@@ -19197,6 +19207,42 @@ function parseBoxesAndLines(content, palette) {
19197
19207
  if (currentTagGroup && indent === 0) {
19198
19208
  currentTagGroup = null;
19199
19209
  }
19210
+ if (!inLayoutBlock && indent === 0 && trimmed === "layout") {
19211
+ let isBlock = false;
19212
+ for (let j = i + 1; j < lines.length; j++) {
19213
+ const peek = lines[j];
19214
+ if (!peek.trim()) continue;
19215
+ isBlock = measureIndent2(peek) > 0 && LAYOUT_ENTRY_RE.test(peek.trim());
19216
+ break;
19217
+ }
19218
+ if (isBlock) {
19219
+ flushDescription();
19220
+ closeGroupsToIndent(0);
19221
+ inLayoutBlock = true;
19222
+ continue;
19223
+ }
19224
+ }
19225
+ if (inLayoutBlock) {
19226
+ if (indent > 0) {
19227
+ const lm = trimmed.match(LAYOUT_ENTRY_RE);
19228
+ if (lm) {
19229
+ nodePositions.set(lm[1].trim(), {
19230
+ x: Number(lm[2]),
19231
+ y: Number(lm[3])
19232
+ });
19233
+ } else {
19234
+ result.diagnostics.push(
19235
+ makeDgmoError(
19236
+ lineNum,
19237
+ `Invalid layout entry "${trimmed}" \u2014 expected "<node-id>: <x>, <y>"`,
19238
+ "warning"
19239
+ )
19240
+ );
19241
+ }
19242
+ continue;
19243
+ }
19244
+ inLayoutBlock = false;
19245
+ }
19200
19246
  if (descState !== null) {
19201
19247
  if (indent > descState.indent) {
19202
19248
  if (trimmed.includes("->") || trimmed.includes("<->")) {
@@ -19449,6 +19495,22 @@ function parseBoxesAndLines(content, palette) {
19449
19495
  );
19450
19496
  }
19451
19497
  finalizeAutoTagColors(result.tagGroups);
19498
+ if (nodePositions.size > 0) {
19499
+ const nodeLabelSet = new Set(result.nodes.map((n) => n.label));
19500
+ for (const id of nodePositions.keys()) {
19501
+ if (!nodeLabelSet.has(id)) {
19502
+ pushWarning(0, `layout entry for unknown node "${id}" (ignored)`);
19503
+ }
19504
+ }
19505
+ const unpositioned = result.nodes.filter((n) => !nodePositions.has(n.label)).map((n) => n.label);
19506
+ if (unpositioned.length > 0) {
19507
+ pushWarning(
19508
+ 0,
19509
+ `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`
19510
+ );
19511
+ }
19512
+ result.nodePositions = nodePositions;
19513
+ }
19452
19514
  if (result.tagGroups.length > 0) {
19453
19515
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
19454
19516
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
@@ -21549,7 +21611,18 @@ function parseJourneyMap(content, palette) {
21549
21611
  }
21550
21612
  }
21551
21613
  } else {
21552
- personaName = afterKeyword;
21614
+ const colorMatch = afterKeyword.match(/^(.+?)\s+color:\s*(\S+)$/i);
21615
+ if (colorMatch) {
21616
+ personaName = colorMatch[1].trim();
21617
+ personaColor = resolveColorWithDiagnostic(
21618
+ colorMatch[2],
21619
+ lineNumber,
21620
+ result.diagnostics,
21621
+ palette
21622
+ ) ?? void 0;
21623
+ } else {
21624
+ personaName = afterKeyword;
21625
+ }
21553
21626
  }
21554
21627
  if (!personaName) {
21555
21628
  return fail(lineNumber, "persona requires a name");
@@ -24490,6 +24563,63 @@ var init_export_container = __esm({
24490
24563
  }
24491
24564
  });
24492
24565
 
24566
+ // src/utils/card.ts
24567
+ function renderNodeCard(container, opts) {
24568
+ 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);
24569
+ if (opts.dashed) {
24570
+ rect.attr("stroke-dasharray", "6 3");
24571
+ }
24572
+ 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);
24573
+ const meta = opts.meta;
24574
+ if (!meta || meta.rows.length === 0) return;
24575
+ 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);
24576
+ const keyX = meta.keyX ?? 10;
24577
+ const maxKeyWidth = Math.max(
24578
+ ...meta.rows.map(([key]) => measureText(`${key}: `, meta.fontSize))
24579
+ );
24580
+ const valueX = keyX + maxKeyWidth;
24581
+ const metaStartY = opts.headerHeight + meta.separatorGap + meta.fontSize;
24582
+ for (let i = 0; i < meta.rows.length; i++) {
24583
+ const [displayKey, value] = meta.rows[i];
24584
+ const rowY = metaStartY + i * meta.lineHeight;
24585
+ container.append("text").attr("x", keyX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(`${displayKey}: `);
24586
+ container.append("text").attr("x", valueX).attr("y", rowY).attr("fill", meta.textColor).attr("font-size", meta.fontSize).text(value);
24587
+ }
24588
+ }
24589
+ function renderCollapseBar(container, opts) {
24590
+ container.append("clipPath").attr("id", opts.clipId).append("rect").attr("width", opts.width).attr("height", opts.height).attr("rx", opts.rx);
24591
+ 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);
24592
+ }
24593
+ var init_card = __esm({
24594
+ "src/utils/card.ts"() {
24595
+ "use strict";
24596
+ init_text_measure();
24597
+ }
24598
+ });
24599
+
24600
+ // src/utils/visual-conventions.ts
24601
+ 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;
24602
+ var init_visual_conventions = __esm({
24603
+ "src/utils/visual-conventions.ts"() {
24604
+ "use strict";
24605
+ NODE_STROKE_WIDTH = 1.5;
24606
+ EDGE_STROKE_WIDTH = 1.5;
24607
+ CARD_RADIUS = 6;
24608
+ CONTAINER_RADIUS = 8;
24609
+ COLLAPSE_BAR_INSET = 0;
24610
+ HEADER_HEIGHT2 = 28;
24611
+ LABEL_FONT_SIZE2 = 13;
24612
+ META_FONT_SIZE2 = 11;
24613
+ META_LINE_HEIGHT2 = 16;
24614
+ SEPARATOR_GAP2 = 6;
24615
+ COLLAPSE_BAR_HEIGHT = 6;
24616
+ CONTAINER_HEADER_HEIGHT = 28;
24617
+ CONTAINER_LABEL_FONT_SIZE = 13;
24618
+ CONTAINER_META_FONT_SIZE = 11;
24619
+ CONTAINER_META_LINE_HEIGHT2 = 16;
24620
+ }
24621
+ });
24622
+
24493
24623
  // src/org/renderer.ts
24494
24624
  var renderer_exports = {};
24495
24625
  __export(renderer_exports, {
@@ -24647,9 +24777,16 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24647
24777
  }
24648
24778
  }
24649
24779
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
24650
- const clipId = `clip-${c.nodeId}`;
24651
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", sContainerRadius);
24652
- 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");
24780
+ renderCollapseBar(cG, {
24781
+ width: c.width,
24782
+ height: c.height,
24783
+ barHeight: sCollapseBarHeight,
24784
+ inset: sCollapseBarInset,
24785
+ rx: sContainerRadius,
24786
+ fill: containerStroke(palette, colorOff ? void 0 : c.color),
24787
+ clipId: `clip-${c.nodeId}`,
24788
+ className: "org-collapse-bar"
24789
+ });
24653
24790
  }
24654
24791
  if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
24655
24792
  const iconSize = 14;
@@ -24700,42 +24837,48 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
24700
24837
  solid
24701
24838
  );
24702
24839
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
24703
- 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);
24704
- if (node.isContainer) {
24705
- rect.attr("stroke-dasharray", "6 3");
24706
- }
24707
24840
  const labelColor = contrastText(
24708
24841
  fill2,
24709
24842
  palette.textOnFillLight,
24710
24843
  palette.textOnFillDark
24711
24844
  );
24712
- 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);
24713
24845
  const metaEntries = Object.entries(node.metadata);
24714
- if (metaEntries.length > 0) {
24715
- 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);
24716
- const metaDisplayKeys = metaEntries.map(
24717
- ([k]) => displayNames.get(k) ?? k
24718
- );
24719
- const maxKeyWidth = Math.max(
24720
- ...metaDisplayKeys.map((k) => measureText(`${k}: `, sMetaFontSize))
24721
- );
24722
- const valueX = 10 + maxKeyWidth;
24723
- const metaStartY = sHeaderHeight + sSeparatorGap + sMetaFontSize;
24724
- for (let i = 0; i < metaEntries.length; i++) {
24725
- const [, value] = metaEntries[i];
24726
- const displayKey = metaDisplayKeys[i];
24727
- const rowY = metaStartY + i * sMetaLineHeight;
24728
- nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}: `);
24729
- nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(value);
24846
+ renderNodeCard(nodeG, {
24847
+ width: node.width,
24848
+ height: node.height,
24849
+ rx: sCardRadius,
24850
+ fill: fill2,
24851
+ stroke: stroke2,
24852
+ strokeWidth: sNodeStrokeWidth,
24853
+ ...node.isContainer && { dashed: true },
24854
+ label: node.label,
24855
+ labelColor,
24856
+ labelFontSize: sLabelFontSize,
24857
+ headerHeight: sHeaderHeight,
24858
+ ...metaEntries.length > 0 && {
24859
+ meta: {
24860
+ rows: metaEntries.map(
24861
+ ([k, value]) => [displayNames.get(k) ?? k, value]
24862
+ ),
24863
+ fontSize: sMetaFontSize,
24864
+ lineHeight: sMetaLineHeight,
24865
+ separatorGap: sSeparatorGap,
24866
+ separatorColor: solid ? labelColor : stroke2,
24867
+ textColor: labelColor
24868
+ }
24730
24869
  }
24731
- }
24870
+ });
24732
24871
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
24733
- const clipId = `clip-${node.id}`;
24734
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", sCardRadius);
24735
- nodeG.append("rect").attr("x", sCollapseBarInset).attr("y", node.height - sCollapseBarHeight).attr("width", node.width - sCollapseBarInset * 2).attr("height", sCollapseBarHeight).attr(
24736
- "fill",
24737
- solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color)
24738
- ).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
24872
+ renderCollapseBar(nodeG, {
24873
+ width: node.width,
24874
+ height: node.height,
24875
+ barHeight: sCollapseBarHeight,
24876
+ inset: sCollapseBarInset,
24877
+ rx: sCardRadius,
24878
+ fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
24879
+ clipId: `clip-${node.id}`,
24880
+ className: "org-collapse-bar"
24881
+ });
24739
24882
  }
24740
24883
  if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
24741
24884
  const iconSize = 14;
@@ -24879,7 +25022,7 @@ function renderOrgForExport(content, theme, palette) {
24879
25022
  return extractExportSvg(container, theme);
24880
25023
  });
24881
25024
  }
24882
- 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;
25025
+ 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;
24883
25026
  var init_renderer = __esm({
24884
25027
  "src/org/renderer.ts"() {
24885
25028
  "use strict";
@@ -24893,27 +25036,14 @@ var init_renderer = __esm({
24893
25036
  init_layout();
24894
25037
  init_legend_constants();
24895
25038
  init_legend_integration();
25039
+ init_card();
24896
25040
  init_text_measure();
24897
25041
  init_legend_layout();
24898
25042
  init_title_constants();
25043
+ init_visual_conventions();
24899
25044
  DIAGRAM_PADDING = 20;
24900
25045
  MAX_SCALE = 3;
24901
25046
  TITLE_HEIGHT = 30;
24902
- LABEL_FONT_SIZE2 = 13;
24903
- META_FONT_SIZE2 = 11;
24904
- META_LINE_HEIGHT2 = 16;
24905
- HEADER_HEIGHT2 = 28;
24906
- SEPARATOR_GAP2 = 6;
24907
- EDGE_STROKE_WIDTH = 1.5;
24908
- NODE_STROKE_WIDTH = 1.5;
24909
- CARD_RADIUS = 6;
24910
- CONTAINER_RADIUS = 8;
24911
- CONTAINER_LABEL_FONT_SIZE = 13;
24912
- CONTAINER_META_FONT_SIZE = 11;
24913
- CONTAINER_META_LINE_HEIGHT2 = 16;
24914
- CONTAINER_HEADER_HEIGHT = 28;
24915
- COLLAPSE_BAR_HEIGHT = 6;
24916
- COLLAPSE_BAR_INSET = 0;
24917
25047
  ANCESTOR_DOT_R = 4;
24918
25048
  ANCESTOR_LABEL_FONT_SIZE = 11;
24919
25049
  ANCESTOR_ROW_HEIGHT = 22;
@@ -25695,21 +25825,21 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25695
25825
  if (width <= 0 || height <= 0) return;
25696
25826
  const ctx = ScaleContext.identity();
25697
25827
  const sDiagramPadding = ctx.aesthetic(DIAGRAM_PADDING2);
25698
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE4);
25699
- const sMetaFontSize = ctx.text(META_FONT_SIZE4);
25700
- const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT4);
25701
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT4);
25702
- const sSeparatorGap = ctx.structural(SEPARATOR_GAP4);
25703
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH2);
25704
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH2);
25828
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE2);
25829
+ const sMetaFontSize = ctx.text(META_FONT_SIZE2);
25830
+ const sMetaLineHeight = ctx.structural(META_LINE_HEIGHT2);
25831
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT2);
25832
+ const sSeparatorGap = ctx.structural(SEPARATOR_GAP2);
25833
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
25834
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
25705
25835
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE);
25706
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE3);
25707
- const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE2);
25708
- const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT4);
25709
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT2);
25836
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
25837
+ const sContainerMetaFontSize = ctx.text(CONTAINER_META_FONT_SIZE);
25838
+ const sContainerMetaLineHeight = ctx.structural(CONTAINER_META_LINE_HEIGHT2);
25839
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
25710
25840
  const sTitleFontSize = ctx.text(TITLE_FONT_SIZE);
25711
25841
  const sTitleHeight = ctx.structural(TITLE_HEIGHT2);
25712
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT2);
25842
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
25713
25843
  const sLegendFixedGap = ctx.aesthetic(LEGEND_FIXED_GAP2);
25714
25844
  const hasLegend = layout.legend.length > 0;
25715
25845
  const layoutLegendShift = LEGEND_HEIGHT + LEGEND_GROUP_GAP;
@@ -25800,7 +25930,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25800
25930
  }
25801
25931
  const fill2 = containerFill2(palette, isDark, c.color);
25802
25932
  const stroke2 = containerStroke2(palette, c.color);
25803
- 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);
25933
+ 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);
25804
25934
  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);
25805
25935
  const metaEntries = Object.entries(c.metadata);
25806
25936
  if (metaEntries.length > 0) {
@@ -25825,7 +25955,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25825
25955
  }
25826
25956
  if (!exportDims && c.hiddenCount && c.hiddenCount > 0) {
25827
25957
  const clipId = `clip-${c.nodeId}`;
25828
- cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS2);
25958
+ cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
25829
25959
  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})`);
25830
25960
  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}`);
25831
25961
  }
@@ -25864,13 +25994,23 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25864
25994
  const solid = parsed.options["solid-fill"] === "on";
25865
25995
  const fill2 = nodeFill2(palette, isDark, node.color, solid);
25866
25996
  const stroke2 = nodeStroke2(palette, node.color);
25867
- 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);
25868
25997
  const labelColor = contrastText(
25869
25998
  fill2,
25870
25999
  palette.textOnFillLight,
25871
26000
  palette.textOnFillDark
25872
26001
  );
25873
- 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);
26002
+ renderNodeCard(nodeG, {
26003
+ width: node.width,
26004
+ height: node.height,
26005
+ rx: CARD_RADIUS,
26006
+ fill: fill2,
26007
+ stroke: stroke2,
26008
+ strokeWidth: sNodeStrokeWidth,
26009
+ label: node.label,
26010
+ labelColor,
26011
+ labelFontSize: sLabelFontSize,
26012
+ headerHeight: sHeaderHeight
26013
+ });
25874
26014
  const metaEntries = Object.entries(node.metadata);
25875
26015
  if (metaEntries.length > 0) {
25876
26016
  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);
@@ -25905,7 +26045,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
25905
26045
  }
25906
26046
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
25907
26047
  const clipId = `clip-${node.id}`;
25908
- nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS2);
26048
+ nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
25909
26049
  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})`);
25910
26050
  }
25911
26051
  }
@@ -26035,7 +26175,7 @@ async function renderSitemapForExport(content, theme, palette) {
26035
26175
  document.body.removeChild(container);
26036
26176
  return svgHtml;
26037
26177
  }
26038
- 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;
26178
+ var d3Selection7, d3Shape2, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
26039
26179
  var init_renderer2 = __esm({
26040
26180
  "src/sitemap/renderer.ts"() {
26041
26181
  "use strict";
@@ -26050,27 +26190,15 @@ var init_renderer2 = __esm({
26050
26190
  init_legend_integration();
26051
26191
  init_legend_layout();
26052
26192
  init_scaling();
26193
+ init_card();
26053
26194
  init_title_constants();
26195
+ init_visual_conventions();
26054
26196
  DIAGRAM_PADDING2 = 20;
26055
26197
  MAX_SCALE2 = 3;
26056
26198
  TITLE_HEIGHT2 = 30;
26057
- LABEL_FONT_SIZE4 = 13;
26058
- META_FONT_SIZE4 = 11;
26059
- META_LINE_HEIGHT4 = 16;
26060
- HEADER_HEIGHT4 = 28;
26061
- SEPARATOR_GAP4 = 6;
26062
- EDGE_STROKE_WIDTH2 = 1.5;
26063
- NODE_STROKE_WIDTH2 = 1.5;
26064
- CARD_RADIUS2 = 6;
26065
- CONTAINER_RADIUS2 = 8;
26066
- CONTAINER_LABEL_FONT_SIZE3 = 13;
26067
- CONTAINER_META_FONT_SIZE2 = 11;
26068
- CONTAINER_META_LINE_HEIGHT4 = 16;
26069
- CONTAINER_HEADER_HEIGHT2 = 28;
26070
26199
  ARROWHEAD_W = 10;
26071
26200
  ARROWHEAD_H = 7;
26072
26201
  EDGE_LABEL_FONT_SIZE = 11;
26073
- COLLAPSE_BAR_HEIGHT2 = 6;
26074
26202
  LEGEND_FIXED_GAP2 = 8;
26075
26203
  lineGenerator = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveBasis);
26076
26204
  lineGeneratorLinear = d3Shape2.line().x((d) => d.x).y((d) => d.y).curve(d3Shape2.curveLinear);
@@ -26327,7 +26455,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
26327
26455
  const sCardMetaLineHeight = ctx.structural(CARD_META_LINE_HEIGHT);
26328
26456
  const sCardSeparatorGap = ctx.structural(CARD_SEPARATOR_GAP);
26329
26457
  const sCardGap = ctx.aesthetic(CARD_GAP);
26330
- const sCardRadius = ctx.structural(CARD_RADIUS3);
26458
+ const sCardRadius = ctx.structural(CARD_RADIUS);
26331
26459
  const sCardPaddingX = ctx.aesthetic(CARD_PADDING_X);
26332
26460
  const sCardPaddingY = ctx.aesthetic(CARD_PADDING_Y);
26333
26461
  const sCardStrokeWidth = ctx.structural(CARD_STROKE_WIDTH);
@@ -26707,7 +26835,7 @@ function computeSwimlaneLayout(parsed, buckets, baseLayout, collapsedLanes, coll
26707
26835
  const totalHeight = laneY - sLaneGap + sColumnPadding + sDiagramPadding;
26708
26836
  return { columnXs, lanes, totalWidth, totalHeight, startY };
26709
26837
  }
26710
- 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) {
26838
+ 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) {
26711
26839
  const visibleColumns = parsed.columns.filter((c) => !isArchiveColumn(c.name));
26712
26840
  const buckets = bucketCardsBySwimlane(visibleColumns, swimlaneGroup);
26713
26841
  const grid = computeSwimlaneLayout(
@@ -26847,7 +26975,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
26847
26975
  }
26848
26976
  }
26849
26977
  }
26850
- 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) {
26978
+ 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) {
26851
26979
  const card = cardLayout.card;
26852
26980
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
26853
26981
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -26897,7 +27025,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
26897
27025
  }
26898
27026
  }
26899
27027
  }
26900
- 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;
27028
+ 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;
26901
27029
  var init_renderer3 = __esm({
26902
27030
  "src/kanban/renderer.ts"() {
26903
27031
  "use strict";
@@ -26912,6 +27040,7 @@ var init_renderer3 = __esm({
26912
27040
  init_legend_integration();
26913
27041
  init_scaling();
26914
27042
  init_text_measure();
27043
+ init_visual_conventions();
26915
27044
  init_title_constants();
26916
27045
  DIAGRAM_PADDING3 = 20;
26917
27046
  COLUMN_GAP = 16;
@@ -26922,7 +27051,6 @@ var init_renderer3 = __esm({
26922
27051
  CARD_META_LINE_HEIGHT = 14;
26923
27052
  CARD_SEPARATOR_GAP = 4;
26924
27053
  CARD_GAP = 8;
26925
- CARD_RADIUS3 = 6;
26926
27054
  CARD_PADDING_X = 10;
26927
27055
  CARD_PADDING_Y = 6;
26928
27056
  CARD_STROKE_WIDTH = 1.5;
@@ -27223,8 +27351,8 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
27223
27351
  const sClassFontSize = ctx.text(CLASS_FONT_SIZE2);
27224
27352
  const sMemberFontSize = ctx.text(MEMBER_FONT_SIZE2);
27225
27353
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE2);
27226
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH3);
27227
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH3);
27354
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
27355
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
27228
27356
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT2);
27229
27357
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y2);
27230
27358
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X);
@@ -27483,7 +27611,7 @@ function renderClassDiagramForExport(content, theme, palette) {
27483
27611
  return extractExportSvg(container, theme);
27484
27612
  });
27485
27613
  }
27486
- 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;
27614
+ 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;
27487
27615
  var init_renderer4 = __esm({
27488
27616
  "src/class/renderer.ts"() {
27489
27617
  "use strict";
@@ -27500,13 +27628,12 @@ var init_renderer4 = __esm({
27500
27628
  init_scaling();
27501
27629
  init_text_measure();
27502
27630
  init_note_box();
27631
+ init_visual_conventions();
27503
27632
  DIAGRAM_PADDING4 = 20;
27504
27633
  MAX_SCALE3 = 3;
27505
27634
  CLASS_FONT_SIZE2 = 13;
27506
27635
  MEMBER_FONT_SIZE2 = 11;
27507
27636
  EDGE_LABEL_FONT_SIZE2 = 11;
27508
- EDGE_STROKE_WIDTH3 = 1.5;
27509
- NODE_STROKE_WIDTH3 = 1.5;
27510
27637
  MEMBER_LINE_HEIGHT2 = 18;
27511
27638
  COMPARTMENT_PADDING_Y2 = 8;
27512
27639
  MEMBER_PADDING_X = 10;
@@ -28000,7 +28127,7 @@ function constraintIcon(constraint) {
28000
28127
  return "\u25CB";
28001
28128
  }
28002
28129
  }
28003
- function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH4) {
28130
+ function drawCardinality(g, point, prevPoint, cardinality, color, useLabels, edgeLabelFontSize = EDGE_LABEL_FONT_SIZE4, edgeStrokeWidth = EDGE_STROKE_WIDTH) {
28004
28131
  const dx = point.x - prevPoint.x;
28005
28132
  const dy = point.y - prevPoint.y;
28006
28133
  const len = Math.sqrt(dx * dx + dy * dy);
@@ -28060,8 +28187,8 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
28060
28187
  const sTableFontSize = ctx.text(TABLE_FONT_SIZE2);
28061
28188
  const sColumnFontSize = ctx.text(COLUMN_FONT_SIZE2);
28062
28189
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE4);
28063
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH4);
28064
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH4);
28190
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
28191
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
28065
28192
  const sMemberLineHeight = ctx.structural(MEMBER_LINE_HEIGHT4);
28066
28193
  const sCompartmentPaddingY = ctx.structural(COMPARTMENT_PADDING_Y4);
28067
28194
  const sMemberPaddingX = ctx.structural(MEMBER_PADDING_X2);
@@ -28339,7 +28466,7 @@ function renderERDiagramForExport(content, theme, palette) {
28339
28466
  document.body.removeChild(container);
28340
28467
  }
28341
28468
  }
28342
- 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;
28469
+ 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;
28343
28470
  var init_renderer5 = __esm({
28344
28471
  "src/er/renderer.ts"() {
28345
28472
  "use strict";
@@ -28358,13 +28485,12 @@ var init_renderer5 = __esm({
28358
28485
  init_parser9();
28359
28486
  init_layout4();
28360
28487
  init_classify();
28488
+ init_visual_conventions();
28361
28489
  DIAGRAM_PADDING5 = 20;
28362
28490
  MAX_SCALE4 = 3;
28363
28491
  TABLE_FONT_SIZE2 = 13;
28364
28492
  COLUMN_FONT_SIZE2 = 11;
28365
28493
  EDGE_LABEL_FONT_SIZE4 = 11;
28366
- EDGE_STROKE_WIDTH4 = 1.5;
28367
- NODE_STROKE_WIDTH4 = 1.5;
28368
28494
  MEMBER_LINE_HEIGHT4 = 18;
28369
28495
  COMPARTMENT_PADDING_Y4 = 8;
28370
28496
  MEMBER_PADDING_X2 = 10;
@@ -28592,9 +28718,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28592
28718
  const sDiagramPadding = sctx.aesthetic(DIAGRAM_PADDING6);
28593
28719
  const sMinNodeFontSize = sctx.text(MIN_NODE_FONT_SIZE);
28594
28720
  const sEdgeLabelFontSize = sctx.text(EDGE_LABEL_FONT_SIZE5);
28595
- const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH5);
28596
- const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH5);
28597
- const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT3);
28721
+ const sEdgeStrokeWidth = sctx.structural(EDGE_STROKE_WIDTH);
28722
+ const sNodeStrokeWidth = sctx.structural(NODE_STROKE_WIDTH);
28723
+ const sCollapseBarHeight = sctx.structural(COLLAPSE_BAR_HEIGHT2);
28598
28724
  const sDescFontSize = sctx.text(DESC_FONT_SIZE);
28599
28725
  const sGroupLabelFontSize = sctx.text(GROUP_LABEL_FONT_SIZE);
28600
28726
  const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
@@ -28686,8 +28812,32 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28686
28812
  const scaleX = width / (contentW + sDiagramPadding * 2);
28687
28813
  const scaleY = height / (contentH + sDiagramPadding * 2);
28688
28814
  const scale = Math.min(scaleX, scaleY, 3);
28689
- const offsetX = (width - contentW * scale) / 2;
28690
- const offsetY = sDiagramPadding + titleOffset + legendH;
28815
+ let centerShiftX = 0;
28816
+ let centerShiftY = 0;
28817
+ if (parsed.nodePositions && parsed.nodePositions.size > 0) {
28818
+ let bMinX = Infinity, bMinY = Infinity, bMaxX = -Infinity, bMaxY = -Infinity;
28819
+ const accB = (x, y) => {
28820
+ if (x < bMinX) bMinX = x;
28821
+ if (x > bMaxX) bMaxX = x;
28822
+ if (y < bMinY) bMinY = y;
28823
+ if (y > bMaxY) bMaxY = y;
28824
+ };
28825
+ for (const n of layout.nodes) {
28826
+ accB(n.x - n.width / 2, n.y - n.height / 2);
28827
+ accB(n.x + n.width / 2, n.y + n.height / 2);
28828
+ }
28829
+ for (const g of layout.groups) {
28830
+ accB(g.x - g.width / 2, g.y - g.height / 2);
28831
+ accB(g.x + g.width / 2, g.y + g.height / 2);
28832
+ }
28833
+ for (const e of layout.edges) for (const p of e.points) accB(p.x, p.y);
28834
+ if (Number.isFinite(bMinX)) {
28835
+ centerShiftX = (layout.width - bMaxX - bMinX) / 2;
28836
+ centerShiftY = (layout.height - bMaxY - bMinY) / 2;
28837
+ }
28838
+ }
28839
+ const offsetX = (width - contentW * scale) / 2 + centerShiftX * scale;
28840
+ const offsetY = sDiagramPadding + titleOffset + legendH + centerShiftY * scale;
28691
28841
  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);
28692
28842
  if (sctx.isBelowFloor) {
28693
28843
  svg.attr("width", "100%");
@@ -28823,7 +28973,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
28823
28973
  const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
28824
28974
  edgeGroups.set(i, edgeG);
28825
28975
  const markerId = `bl-arrow-${color.replace("#", "")}`;
28826
- const gen = parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28976
+ const gen = le.straight ? lineGeneratorStraight : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
28827
28977
  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})`);
28828
28978
  if (le.bidirectional) {
28829
28979
  const revId = `bl-arrow-rev-${color.replace("#", "")}`;
@@ -29104,7 +29254,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
29104
29254
  }
29105
29255
  });
29106
29256
  }
29107
- 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;
29257
+ 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;
29108
29258
  var init_renderer6 = __esm({
29109
29259
  "src/boxes-and-lines/renderer.ts"() {
29110
29260
  "use strict";
@@ -29122,14 +29272,13 @@ var init_renderer6 = __esm({
29122
29272
  init_wrapped_desc();
29123
29273
  init_scaling();
29124
29274
  init_text_measure();
29275
+ init_visual_conventions();
29125
29276
  DIAGRAM_PADDING6 = 20;
29126
29277
  NODE_FONT_SIZE = 11;
29127
29278
  MIN_NODE_FONT_SIZE = 9;
29128
29279
  EDGE_LABEL_FONT_SIZE5 = 11;
29129
- EDGE_STROKE_WIDTH5 = 1.5;
29130
- NODE_STROKE_WIDTH5 = 1.5;
29131
29280
  NODE_RX = 8;
29132
- COLLAPSE_BAR_HEIGHT3 = 4;
29281
+ COLLAPSE_BAR_HEIGHT2 = 4;
29133
29282
  ARROWHEAD_W2 = 5;
29134
29283
  ARROWHEAD_H2 = 4;
29135
29284
  DESC_FONT_SIZE = 10;
@@ -29143,6 +29292,7 @@ var init_renderer6 = __esm({
29143
29292
  VALUE_FONT_SIZE = 11;
29144
29293
  lineGeneratorLR = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29145
29294
  lineGeneratorTB = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveBasis);
29295
+ lineGeneratorStraight = d3Shape5.line().x((d) => d.x).y((d) => d.y).curve(d3Shape5.curveLinear);
29146
29296
  }
29147
29297
  });
29148
29298
 
@@ -30330,6 +30480,156 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30330
30480
  return { x: rect.x + dx * s, y: rect.y + dy * s };
30331
30481
  };
30332
30482
  const isInsideRect = (p, rect) => Math.abs(p.x - rect.x) <= rect.w / 2 && Math.abs(p.y - rect.y) <= rect.h / 2;
30483
+ const pinned = parsed.nodePositions;
30484
+ const groupLabelSet = new Set(parsed.groups.map((g) => g.label));
30485
+ const groupsAreFlat = parsed.groups.every(
30486
+ (g) => !g.parentGroup && !g.children.some((c) => groupLabelSet.has(c))
30487
+ );
30488
+ const allOriginalGroupLabels = new Set(
30489
+ (collapseInfo?.originalGroups ?? parsed.groups).map((g) => g.label)
30490
+ );
30491
+ const collapsedAreFlatPinned = collapsedGroupLabels.size === 0 || pinned !== void 0 && collapseInfo !== void 0 && [...collapsedGroupLabels].every((label) => {
30492
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30493
+ if (!og || og.parentGroup) return false;
30494
+ return og.children.every(
30495
+ (c) => pinned.has(c) && !allOriginalGroupLabels.has(c)
30496
+ );
30497
+ });
30498
+ const allPinned = pinned !== void 0 && (parsed.nodes.length > 0 || collapsedGroupLabels.size > 0) && parsed.nodes.every((n2) => pinned.has(n2.label)) && groupsAreFlat && collapsedAreFlatPinned;
30499
+ function placePinned(pins) {
30500
+ const collapsedPosByGid = /* @__PURE__ */ new Map();
30501
+ const collapsedBoxes = [];
30502
+ if (collapseInfo)
30503
+ for (const label of collapsedGroupLabels) {
30504
+ const og = collapseInfo.originalGroups.find((g) => g.label === label);
30505
+ if (!og) continue;
30506
+ let cx0 = Infinity, cy0 = Infinity, cx1 = -Infinity, cy1 = -Infinity;
30507
+ for (const c of og.children) {
30508
+ const p = pins.get(c);
30509
+ if (!p) continue;
30510
+ cx0 = Math.min(cx0, p.x);
30511
+ cx1 = Math.max(cx1, p.x);
30512
+ cy0 = Math.min(cy0, p.y);
30513
+ cy1 = Math.max(cy1, p.y);
30514
+ }
30515
+ if (!Number.isFinite(cx0)) continue;
30516
+ const cx = (cx0 + cx1) / 2;
30517
+ const cy = (cy0 + cy1) / 2;
30518
+ collapsedPosByGid.set(`__group_${label}`, { x: cx, y: cy });
30519
+ collapsedBoxes.push({
30520
+ label,
30521
+ lineNumber: og.lineNumber,
30522
+ childCount: collapseInfo.collapsedChildCounts.get(label) ?? og.children.length,
30523
+ x: cx,
30524
+ y: cy
30525
+ });
30526
+ }
30527
+ const posOf = (label) => pins.get(label) ?? collapsedPosByGid.get(label);
30528
+ const rectOf = (label) => {
30529
+ const p = posOf(label);
30530
+ const s = sizes.get(label) ?? { width: NODE_WIDTH, height: NODE_HEIGHT };
30531
+ return { x: p.x, y: p.y, w: s.width, h: s.height };
30532
+ };
30533
+ const nodes = parsed.nodes.map((n2) => {
30534
+ const r = rectOf(n2.label);
30535
+ return { label: n2.label, x: r.x, y: r.y, width: r.w, height: r.h };
30536
+ });
30537
+ const edges = parsed.edges.flatMap((e) => {
30538
+ const sp = posOf(e.source);
30539
+ const tp = posOf(e.target);
30540
+ if (!sp || !tp) return [];
30541
+ const srcRect = rectOf(e.source);
30542
+ const tgtRect = rectOf(e.target);
30543
+ const p0 = rectBorderPoint(srcRect, tp);
30544
+ const p1 = rectBorderPoint(tgtRect, sp);
30545
+ return [
30546
+ {
30547
+ source: e.source,
30548
+ target: e.target,
30549
+ ...e.label !== void 0 && { label: e.label },
30550
+ bidirectional: e.bidirectional,
30551
+ lineNumber: e.lineNumber,
30552
+ points: [p0, p1],
30553
+ yOffset: 0,
30554
+ parallelCount: 1,
30555
+ metadata: e.metadata,
30556
+ straight: true
30557
+ }
30558
+ ];
30559
+ });
30560
+ const GROUP_PAD = 16;
30561
+ const nodeByLabel = new Map(nodes.map((n2) => [n2.label, n2]));
30562
+ const groups = [];
30563
+ for (const grp of parsed.groups) {
30564
+ let gx0 = Infinity, gy0 = Infinity, gx1 = -Infinity, gy1 = -Infinity;
30565
+ for (const c of grp.children) {
30566
+ const n2 = nodeByLabel.get(c);
30567
+ if (!n2) continue;
30568
+ gx0 = Math.min(gx0, n2.x - n2.width / 2);
30569
+ gx1 = Math.max(gx1, n2.x + n2.width / 2);
30570
+ gy0 = Math.min(gy0, n2.y - n2.height / 2);
30571
+ gy1 = Math.max(gy1, n2.y + n2.height / 2);
30572
+ }
30573
+ if (!Number.isFinite(gx0)) continue;
30574
+ const x0 = gx0 - GROUP_PAD;
30575
+ const x1 = gx1 + GROUP_PAD;
30576
+ const y0 = gy0 - GROUP_LABEL_ZONE2;
30577
+ const y1 = gy1 + GROUP_PAD;
30578
+ groups.push({
30579
+ label: grp.label,
30580
+ lineNumber: grp.lineNumber,
30581
+ x: (x0 + x1) / 2,
30582
+ y: (y0 + y1) / 2,
30583
+ width: x1 - x0,
30584
+ height: y1 - y0,
30585
+ collapsed: false,
30586
+ childCount: grp.children.length
30587
+ });
30588
+ }
30589
+ for (const cb of collapsedBoxes) {
30590
+ groups.push({
30591
+ label: cb.label,
30592
+ lineNumber: cb.lineNumber,
30593
+ x: cb.x,
30594
+ y: cb.y,
30595
+ width: NODE_WIDTH,
30596
+ height: NODE_HEIGHT,
30597
+ collapsed: true,
30598
+ childCount: cb.childCount
30599
+ });
30600
+ }
30601
+ const M = 40;
30602
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
30603
+ const acc = (x, y) => {
30604
+ if (x < minX) minX = x;
30605
+ if (x > maxX) maxX = x;
30606
+ if (y < minY) minY = y;
30607
+ if (y > maxY) maxY = y;
30608
+ };
30609
+ for (const n2 of nodes) {
30610
+ acc(n2.x - n2.width / 2, n2.y - n2.height / 2);
30611
+ acc(n2.x + n2.width / 2, n2.y + n2.height / 2);
30612
+ }
30613
+ for (const e of edges) for (const p of e.points) acc(p.x, p.y);
30614
+ for (const gr of groups) {
30615
+ acc(gr.x - gr.width / 2, gr.y - gr.height / 2);
30616
+ acc(gr.x + gr.width / 2, gr.y + gr.height / 2);
30617
+ }
30618
+ const TOL = 2;
30619
+ const sx = minX < M - TOL ? M - minX : 0;
30620
+ const sy = minY < M - TOL ? M - minY : 0;
30621
+ const shifted = sx !== 0 || sy !== 0;
30622
+ return {
30623
+ nodes: shifted ? nodes.map((n2) => ({ ...n2, x: n2.x + sx, y: n2.y + sy })) : nodes,
30624
+ edges: shifted ? edges.map((e) => ({
30625
+ ...e,
30626
+ points: e.points.map((p) => ({ x: p.x + sx, y: p.y + sy }))
30627
+ })) : edges,
30628
+ groups: shifted ? groups.map((gr) => ({ ...gr, x: gr.x + sx, y: gr.y + sy })) : groups,
30629
+ width: maxX + sx + M,
30630
+ height: maxY + sy + M
30631
+ };
30632
+ }
30333
30633
  function place(cfg) {
30334
30634
  const r = cfg.seed === void 0 ? null : rng2(cfg.seed + 1);
30335
30635
  const ord = (a) => r ? shuffle(a, r) : a.slice();
@@ -30468,6 +30768,7 @@ function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
30468
30768
  height: gg.height ?? 600
30469
30769
  };
30470
30770
  }
30771
+ if (allPinned) return placePinned(pinned);
30471
30772
  const n = parsed.nodes.length;
30472
30773
  const seedCount = opts?.seeds ?? (n <= 12 ? 80 : n <= 22 ? 40 : n <= 35 ? 22 : 10);
30473
30774
  const REFINE_K = opts?.refineK ?? 6;
@@ -30664,7 +30965,7 @@ function computeNodeSize(node, reserveValueRow) {
30664
30965
  }
30665
30966
  totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
30666
30967
  const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
30667
- const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30968
+ const totalHeight = labelHeight + SEPARATOR_GAP4 + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
30668
30969
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
30669
30970
  }
30670
30971
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
@@ -30793,7 +31094,7 @@ function applyParallelEdgeOffsets(layout) {
30793
31094
  }))
30794
31095
  };
30795
31096
  }
30796
- 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;
31097
+ 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;
30797
31098
  var init_layout5 = __esm({
30798
31099
  "src/boxes-and-lines/layout.ts"() {
30799
31100
  "use strict";
@@ -30809,13 +31110,13 @@ var init_layout5 = __esm({
30809
31110
  DESC_FONT_SIZE2 = 10;
30810
31111
  DESC_LINE_HEIGHT2 = 1.4;
30811
31112
  DESC_PADDING = 8;
30812
- SEPARATOR_GAP5 = 4;
31113
+ SEPARATOR_GAP4 = 4;
30813
31114
  MAX_DESC_LINES2 = 6;
30814
31115
  MAX_LABEL_LINES = 3;
30815
31116
  LABEL_LINE_HEIGHT = 1.3;
30816
31117
  LABEL_PAD = 12;
30817
31118
  VALUE_ROW_FONT = 11;
30818
- VALUE_ROW_H = SEPARATOR_GAP5 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
31119
+ VALUE_ROW_H = SEPARATOR_GAP4 + VALUE_ROW_FONT * DESC_LINE_HEIGHT2 + DESC_PADDING;
30819
31120
  }
30820
31121
  });
30821
31122
 
@@ -31576,11 +31877,11 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31576
31877
  });
31577
31878
  }
31578
31879
  for (const edge of renderLayout.edges) {
31579
- 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);
31880
+ 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);
31580
31881
  }
31581
31882
  for (const node of renderLayout.nodes) {
31582
31883
  const isRoot = node.radius === 0 && renderLayout.nodes.indexOf(node) === 0;
31583
- const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH6;
31884
+ const strokeW = isRoot ? ROOT_STROKE_WIDTH : NODE_STROKE_WIDTH;
31584
31885
  const effectiveColor = options?.colorByDepth ? depthColor(node.depth, palette) : node.color;
31585
31886
  const fill2 = nodeFill4(
31586
31887
  palette,
@@ -31663,7 +31964,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
31663
31964
  const clipId = `collapse-clip-${node.id}`;
31664
31965
  const defs = mainG.append("defs");
31665
31966
  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);
31666
- 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})`);
31967
+ 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})`);
31667
31968
  }
31668
31969
  if (onClickItem) {
31669
31970
  nodeG.style("cursor", "pointer").on("click", (event) => {
@@ -31711,7 +32012,7 @@ function renderMindmapForExport(content, theme, palette) {
31711
32012
  return extractExportSvg(container, theme);
31712
32013
  });
31713
32014
  }
31714
- 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;
32015
+ var d3Selection12, DIAGRAM_PADDING7, TITLE_HEIGHT4, SINGLE_LABEL_HEIGHT2, LABEL_LINE_HEIGHT3, DESC_LINE_HEIGHT4, NODE_RADIUS, ROOT_STROKE_WIDTH, DEPTH_COLOR_KEYS;
31715
32016
  var init_renderer7 = __esm({
31716
32017
  "src/mindmap/renderer.ts"() {
31717
32018
  "use strict";
@@ -31729,6 +32030,7 @@ var init_renderer7 = __esm({
31729
32030
  init_legend_layout();
31730
32031
  init_title_constants();
31731
32032
  init_scaling();
32033
+ init_visual_conventions();
31732
32034
  DIAGRAM_PADDING7 = 20;
31733
32035
  TITLE_HEIGHT4 = 30;
31734
32036
  SINGLE_LABEL_HEIGHT2 = 28;
@@ -31736,9 +32038,6 @@ var init_renderer7 = __esm({
31736
32038
  DESC_LINE_HEIGHT4 = 14;
31737
32039
  NODE_RADIUS = 6;
31738
32040
  ROOT_STROKE_WIDTH = 2.5;
31739
- NODE_STROKE_WIDTH6 = 1.5;
31740
- EDGE_STROKE_WIDTH6 = 1.5;
31741
- COLLAPSE_BAR_HEIGHT4 = 6;
31742
32041
  DEPTH_COLOR_KEYS = [
31743
32042
  "red",
31744
32043
  "orange",
@@ -32966,10 +33265,10 @@ function computeC4NodeDimensions(el, options) {
32966
33265
  const metaEntries = collectCardMetadata(el.metadata);
32967
33266
  if (metaEntries.length > 0) {
32968
33267
  height2 += DIVIDER_GAP;
32969
- height2 += metaEntries.length * META_LINE_HEIGHT5;
33268
+ height2 += metaEntries.length * META_LINE_HEIGHT4;
32970
33269
  const maxMetaWidth = Math.max(
32971
33270
  ...metaEntries.map(
32972
- (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE5) + CARD_H_PAD3 * 2
33271
+ (e) => measureText(`${e.key}: ${e.value}`, META_FONT_SIZE4) + CARD_H_PAD3 * 2
32973
33272
  )
32974
33273
  );
32975
33274
  if (maxMetaWidth > width) width = Math.min(MAX_NODE_WIDTH, maxMetaWidth);
@@ -34246,7 +34545,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
34246
34545
  height: totalHeight
34247
34546
  };
34248
34547
  }
34249
- 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;
34548
+ 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;
34250
34549
  var init_layout8 = __esm({
34251
34550
  "src/c4/layout.ts"() {
34252
34551
  "use strict";
@@ -34265,8 +34564,8 @@ var init_layout8 = __esm({
34265
34564
  DESC_FONT_SIZE4 = 11;
34266
34565
  CARD_V_PAD3 = 14;
34267
34566
  CARD_H_PAD3 = 20;
34268
- META_LINE_HEIGHT5 = 16;
34269
- META_FONT_SIZE5 = 11;
34567
+ META_LINE_HEIGHT4 = 16;
34568
+ META_FONT_SIZE4 = 11;
34270
34569
  MARGIN6 = 40;
34271
34570
  BOUNDARY_PAD = 40;
34272
34571
  GROUP_BOUNDARY_PAD = 24;
@@ -34387,7 +34686,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34387
34686
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34388
34687
  const pathD = lineGenerator4(edge.points);
34389
34688
  if (pathD) {
34390
- 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)");
34689
+ 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)");
34391
34690
  if (dashed) {
34392
34691
  pathEl.attr("stroke-dasharray", "6 3");
34393
34692
  }
@@ -34453,7 +34752,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34453
34752
  palette.textOnFillLight,
34454
34753
  palette.textOnFillDark
34455
34754
  );
34456
- 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);
34755
+ 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);
34457
34756
  let yPos = -h / 2 + CARD_V_PAD4;
34458
34757
  const typeLabel = `\xAB${node.type}\xBB`;
34459
34758
  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);
@@ -34497,7 +34796,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
34497
34796
  }
34498
34797
  if (node.drillable) {
34499
34798
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
34500
- 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);
34799
+ 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);
34501
34800
  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");
34502
34801
  }
34503
34802
  }
@@ -34557,14 +34856,14 @@ function drawCylinderCard(nodeG, w, h, fill2, stroke2, dashed) {
34557
34856
  `A ${w / 2} ${ry} 0 0 1 ${-w / 2} ${h / 2 - ry}`,
34558
34857
  "Z"
34559
34858
  ].join(" ");
34560
- const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH7);
34859
+ const el = nodeG.append("path").attr("d", path).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH);
34561
34860
  if (dashed) {
34562
34861
  el.attr("stroke-dasharray", "6 3");
34563
34862
  }
34564
- 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);
34863
+ 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);
34565
34864
  }
34566
34865
  function drawCardRect(nodeG, w, h, fill2, stroke2, dashed) {
34567
- 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);
34866
+ 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);
34568
34867
  if (dashed) {
34569
34868
  el.attr("stroke-dasharray", "6 3");
34570
34869
  }
@@ -34584,7 +34883,7 @@ function renderEdges(contentG, edges, palette, onClickItem, obstacleRects) {
34584
34883
  const bidir = hasBidirectionalMarkers(edge.arrowType);
34585
34884
  const pathD = lineGenerator4(edge.points);
34586
34885
  if (pathD) {
34587
- 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)");
34886
+ 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)");
34588
34887
  if (dashed) {
34589
34888
  pathEl.attr("stroke-dasharray", "6 3");
34590
34889
  }
@@ -35079,13 +35378,13 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35079
35378
  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);
35080
35379
  yPos += DIVIDER_GAP2;
35081
35380
  const maxKeyWidth = Math.max(
35082
- ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE6))
35381
+ ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE2))
35083
35382
  );
35084
35383
  const valueX = -w / 2 + CARD_H_PAD4 + maxKeyWidth;
35085
35384
  for (const entry of metaEntries) {
35086
- 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}:`);
35087
- 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);
35088
- yPos += META_LINE_HEIGHT6;
35385
+ 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}:`);
35386
+ 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);
35387
+ yPos += META_LINE_HEIGHT2;
35089
35388
  }
35090
35389
  }
35091
35390
  } else {
@@ -35112,7 +35411,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
35112
35411
  }
35113
35412
  if (node.drillable) {
35114
35413
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
35115
- 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);
35414
+ 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);
35116
35415
  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");
35117
35416
  }
35118
35417
  }
@@ -35241,7 +35540,7 @@ function renderC4DeploymentForExport(content, theme, palette) {
35241
35540
  document.body.removeChild(el);
35242
35541
  }
35243
35542
  }
35244
- 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;
35543
+ 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;
35245
35544
  var init_renderer9 = __esm({
35246
35545
  "src/c4/renderer.ts"() {
35247
35546
  "use strict";
@@ -35257,6 +35556,7 @@ var init_renderer9 = __esm({
35257
35556
  init_legend_constants();
35258
35557
  init_legend_integration();
35259
35558
  init_title_constants();
35559
+ init_visual_conventions();
35260
35560
  DIAGRAM_PADDING8 = 20;
35261
35561
  MAX_SCALE5 = 3;
35262
35562
  TITLE_HEIGHT6 = 30;
@@ -35266,16 +35566,11 @@ var init_renderer9 = __esm({
35266
35566
  DESC_LINE_HEIGHT6 = 16;
35267
35567
  EDGE_LABEL_FONT_SIZE6 = 11;
35268
35568
  TECH_FONT_SIZE = 10;
35269
- EDGE_STROKE_WIDTH7 = 1.5;
35270
- NODE_STROKE_WIDTH7 = 1.5;
35271
- CARD_RADIUS4 = 6;
35272
35569
  CARD_H_PAD4 = 20;
35273
35570
  CARD_V_PAD4 = 14;
35274
35571
  TYPE_LABEL_HEIGHT2 = 18;
35275
35572
  DIVIDER_GAP2 = 6;
35276
35573
  NAME_HEIGHT2 = 20;
35277
- META_FONT_SIZE6 = 11;
35278
- META_LINE_HEIGHT6 = 16;
35279
35574
  BOUNDARY_LABEL_FONT_SIZE = 12;
35280
35575
  BOUNDARY_STROKE_WIDTH = 1.5;
35281
35576
  BOUNDARY_RADIUS = 8;
@@ -35679,7 +35974,7 @@ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff,
35679
35974
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
35680
35975
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
35681
35976
  }
35682
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35977
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35683
35978
  const w = node.width;
35684
35979
  const h = node.height;
35685
35980
  const rx = h / 2;
@@ -35691,7 +35986,7 @@ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeS
35691
35986
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
35692
35987
  ).attr("stroke-width", sNodeStrokeWidth);
35693
35988
  }
35694
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
35989
+ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35695
35990
  const w = node.width;
35696
35991
  const h = node.height;
35697
35992
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -35710,7 +36005,7 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
35710
36005
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35711
36006
  ).attr("stroke-width", sNodeStrokeWidth);
35712
36007
  }
35713
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8) {
36008
+ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
35714
36009
  const w = node.width / 2;
35715
36010
  const h = node.height / 2;
35716
36011
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -35732,7 +36027,7 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35732
36027
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35733
36028
  ).attr("stroke-width", sNodeStrokeWidth);
35734
36029
  }
35735
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW) {
36030
+ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
35736
36031
  const w = node.width / 2;
35737
36032
  const h = node.height / 2;
35738
36033
  const sk = sIoSkew;
@@ -35758,7 +36053,7 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
35758
36053
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35759
36054
  ).attr("stroke-width", sNodeStrokeWidth);
35760
36055
  }
35761
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sSubroutineInset = SUBROUTINE_INSET) {
36056
+ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
35762
36057
  const w = node.width;
35763
36058
  const h = node.height;
35764
36059
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -35776,7 +36071,7 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
35776
36071
  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);
35777
36072
  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);
35778
36073
  }
35779
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36074
+ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35780
36075
  const w = node.width;
35781
36076
  const h = node.height;
35782
36077
  const waveH = sDocWaveHeight;
@@ -35807,7 +36102,7 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
35807
36102
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
35808
36103
  ).attr("stroke-width", sNodeStrokeWidth);
35809
36104
  }
35810
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH8, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
36105
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
35811
36106
  switch (node.shape) {
35812
36107
  case "terminal":
35813
36108
  renderTerminal(
@@ -35894,8 +36189,8 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
35894
36189
  const sTitleY = ctx.structural(TITLE_Y);
35895
36190
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE2);
35896
36191
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE7);
35897
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH8);
35898
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH8);
36192
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
36193
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
35899
36194
  const sArrowheadW = ctx.structural(ARROWHEAD_W3);
35900
36195
  const sArrowheadH = ctx.structural(ARROWHEAD_H3);
35901
36196
  const sIoSkew = ctx.structural(IO_SKEW);
@@ -36119,7 +36414,7 @@ function renderFlowchartForExport(content, theme, palette) {
36119
36414
  document.body.removeChild(container);
36120
36415
  }
36121
36416
  }
36122
- 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;
36417
+ var d3Selection15, DIAGRAM_PADDING9, MAX_SCALE6, NODE_FONT_SIZE2, EDGE_LABEL_FONT_SIZE7, ARROWHEAD_W3, ARROWHEAD_H3, IO_SKEW, SUBROUTINE_INSET, DOC_WAVE_HEIGHT;
36123
36418
  var init_flowchart_renderer = __esm({
36124
36419
  "src/graph/flowchart-renderer.ts"() {
36125
36420
  "use strict";
@@ -36135,12 +36430,11 @@ var init_flowchart_renderer = __esm({
36135
36430
  init_scaling();
36136
36431
  init_text_measure();
36137
36432
  init_note_box();
36433
+ init_visual_conventions();
36138
36434
  DIAGRAM_PADDING9 = 20;
36139
36435
  MAX_SCALE6 = 3;
36140
36436
  NODE_FONT_SIZE2 = 13;
36141
36437
  EDGE_LABEL_FONT_SIZE7 = 11;
36142
- EDGE_STROKE_WIDTH8 = 1.5;
36143
- NODE_STROKE_WIDTH8 = 1.5;
36144
36438
  ARROWHEAD_W3 = 10;
36145
36439
  ARROWHEAD_H3 = 7;
36146
36440
  IO_SKEW = 15;
@@ -37124,7 +37418,7 @@ function hasRoles(node) {
37124
37418
  }
37125
37419
  function computeNodeWidth2(node, expanded, options) {
37126
37420
  const badgeVal = node.computedConcurrentInvocations === 0 && node.computedInstances > 1 ? node.computedInstances : 0;
37127
- const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE7) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37421
+ const badgeWidth = badgeVal > 0 ? measureText(`${badgeVal}x`, META_FONT_SIZE5) + 2 * CHAR_WIDTH_RATIO * NODE_FONT_SIZE3 : 0;
37128
37422
  const labelWidth2 = measureText(node.label, NODE_FONT_SIZE3) + badgeWidth + PADDING_X3;
37129
37423
  const allKeys = [];
37130
37424
  if (node.computedRps > 0) allKeys.push("RPS");
@@ -37171,7 +37465,7 @@ function computeNodeWidth2(node, expanded, options) {
37171
37465
  }
37172
37466
  if (allKeys.length === 0) return Math.max(MIN_NODE_WIDTH2, labelWidth2);
37173
37467
  const keyColWidth = Math.max(
37174
- ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE7))
37468
+ ...allKeys.map((k) => measureText(`${k}: `, META_FONT_SIZE5))
37175
37469
  );
37176
37470
  let maxRowWidth = 0;
37177
37471
  if (node.computedRps > 0) {
@@ -37184,7 +37478,7 @@ function computeNodeWidth2(node, expanded, options) {
37184
37478
  const rpsVal = effectiveCap > 0 && !node.isEdge ? `${formatRpsShort(node.computedRps)} / ${formatRpsShort(effectiveCap)}` : formatRps(node.computedRps);
37185
37479
  maxRowWidth = Math.max(
37186
37480
  maxRowWidth,
37187
- keyColWidth + measureText(rpsVal, META_FONT_SIZE7)
37481
+ keyColWidth + measureText(rpsVal, META_FONT_SIZE5)
37188
37482
  );
37189
37483
  }
37190
37484
  if (expanded) {
@@ -37201,7 +37495,7 @@ function computeNodeWidth2(node, expanded, options) {
37201
37495
  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);
37202
37496
  maxRowWidth = Math.max(
37203
37497
  maxRowWidth,
37204
- keyColWidth + measureText(valStr, META_FONT_SIZE7)
37498
+ keyColWidth + measureText(valStr, META_FONT_SIZE5)
37205
37499
  );
37206
37500
  }
37207
37501
  }
@@ -37212,7 +37506,7 @@ function computeNodeWidth2(node, expanded, options) {
37212
37506
  if (ms > 0) {
37213
37507
  maxRowWidth = Math.max(
37214
37508
  maxRowWidth,
37215
- keyColWidth + measureText(formatMs(ms), META_FONT_SIZE7)
37509
+ keyColWidth + measureText(formatMs(ms), META_FONT_SIZE5)
37216
37510
  );
37217
37511
  }
37218
37512
  }
@@ -37223,37 +37517,37 @@ function computeNodeWidth2(node, expanded, options) {
37223
37517
  const combinedVal = `${formatMs(perc.p90)} / ${formatMs(threshold)}`;
37224
37518
  maxRowWidth = Math.max(
37225
37519
  maxRowWidth,
37226
- keyColWidth + measureText(combinedVal, META_FONT_SIZE7)
37520
+ keyColWidth + measureText(combinedVal, META_FONT_SIZE5)
37227
37521
  );
37228
37522
  }
37229
37523
  }
37230
37524
  if (node.computedUptime < 1) {
37231
37525
  maxRowWidth = Math.max(
37232
37526
  maxRowWidth,
37233
- keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE7)
37527
+ keyColWidth + measureText(formatUptime(node.computedUptime), META_FONT_SIZE5)
37234
37528
  );
37235
37529
  }
37236
37530
  if (node.computedAvailability < 1) {
37237
37531
  maxRowWidth = Math.max(
37238
37532
  maxRowWidth,
37239
- keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE7)
37533
+ keyColWidth + measureText(formatUptime(node.computedAvailability), META_FONT_SIZE5)
37240
37534
  );
37241
37535
  }
37242
37536
  if (node.computedCbState === "open") {
37243
37537
  maxRowWidth = Math.max(
37244
37538
  maxRowWidth,
37245
- measureText("CB: OPEN", META_FONT_SIZE7) + 8
37539
+ measureText("CB: OPEN", META_FONT_SIZE5) + 8
37246
37540
  );
37247
37541
  }
37248
37542
  }
37249
- const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE7;
37543
+ const DESC_MAX_WIDTH2 = 120 * CHAR_WIDTH_RATIO * META_FONT_SIZE5;
37250
37544
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
37251
37545
  let descWidth = 0;
37252
37546
  for (const dl of descLines) {
37253
- const truncated = truncateText(dl, META_FONT_SIZE7, DESC_MAX_WIDTH2);
37547
+ const truncated = truncateText(dl, META_FONT_SIZE5, DESC_MAX_WIDTH2);
37254
37548
  descWidth = Math.max(
37255
37549
  descWidth,
37256
- measureText(truncated, META_FONT_SIZE7) + PADDING_X3
37550
+ measureText(truncated, META_FONT_SIZE5) + PADDING_X3
37257
37551
  );
37258
37552
  }
37259
37553
  return Math.max(MIN_NODE_WIDTH2, labelWidth2, maxRowWidth + 20, descWidth);
@@ -37263,17 +37557,17 @@ function computeNodeHeight2(node, expanded, options) {
37263
37557
  const computedCount = countComputedRows(node, expanded);
37264
37558
  const hasRps = node.computedRps > 0;
37265
37559
  const descLineCount = expanded && node.description && !node.isEdge ? node.description.length : 0;
37266
- const descH = descLineCount * META_LINE_HEIGHT7;
37560
+ const descH = descLineCount * META_LINE_HEIGHT5;
37267
37561
  if (propCount === 0 && computedCount === 0 && !hasRps)
37268
37562
  return NODE_HEADER_HEIGHT + descH + NODE_PAD_BOTTOM;
37269
37563
  let h = NODE_HEADER_HEIGHT + descH + NODE_SEPARATOR_GAP;
37270
37564
  const computedSectionCount = (hasRps ? 1 : 0) + computedCount;
37271
- h += computedSectionCount * META_LINE_HEIGHT7;
37565
+ h += computedSectionCount * META_LINE_HEIGHT5;
37272
37566
  if (computedSectionCount > 0 && propCount > 0) h += NODE_SEPARATOR_GAP;
37273
- h += propCount * META_LINE_HEIGHT7;
37567
+ h += propCount * META_LINE_HEIGHT5;
37274
37568
  if (hasRoles(node)) h += ROLE_DOT_ROW;
37275
37569
  h += NODE_PAD_BOTTOM;
37276
- if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT5;
37570
+ if (node.id.startsWith("[")) h += COLLAPSE_BAR_HEIGHT3;
37277
37571
  return h;
37278
37572
  }
37279
37573
  function formatRps(rps) {
@@ -37608,7 +37902,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
37608
37902
  height: totalHeight
37609
37903
  };
37610
37904
  }
37611
- 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;
37905
+ 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;
37612
37906
  var init_layout10 = __esm({
37613
37907
  "src/infra/layout.ts"() {
37614
37908
  "use strict";
@@ -37616,13 +37910,13 @@ var init_layout10 = __esm({
37616
37910
  init_text_measure();
37617
37911
  MIN_NODE_WIDTH2 = 140;
37618
37912
  NODE_HEADER_HEIGHT = 28;
37619
- META_LINE_HEIGHT7 = 14;
37913
+ META_LINE_HEIGHT5 = 14;
37620
37914
  NODE_SEPARATOR_GAP = 4;
37621
37915
  NODE_PAD_BOTTOM = 10;
37622
37916
  ROLE_DOT_ROW = 12;
37623
- COLLAPSE_BAR_HEIGHT5 = 6;
37917
+ COLLAPSE_BAR_HEIGHT3 = 6;
37624
37918
  NODE_FONT_SIZE3 = 13;
37625
- META_FONT_SIZE7 = 10;
37919
+ META_FONT_SIZE5 = 10;
37626
37920
  EDGE_LABEL_FONT_SIZE8 = 11;
37627
37921
  PADDING_X3 = 24;
37628
37922
  GROUP_PADDING2 = 20;
@@ -37726,19 +38020,19 @@ __export(renderer_exports10, {
37726
38020
  function buildScaledConstants(ctx) {
37727
38021
  return {
37728
38022
  sNodeFontSize: ctx.text(NODE_FONT_SIZE4),
37729
- sMetaFontSize: ctx.text(META_FONT_SIZE8),
37730
- sMetaLineHeight: ctx.structural(META_LINE_HEIGHT8),
38023
+ sMetaFontSize: ctx.text(META_FONT_SIZE6),
38024
+ sMetaLineHeight: ctx.structural(META_LINE_HEIGHT6),
37731
38025
  sEdgeLabelFontSize: ctx.text(EDGE_LABEL_FONT_SIZE9),
37732
38026
  sGroupLabelFontSize: ctx.text(GROUP_LABEL_FONT_SIZE2),
37733
38027
  sNodeBorderRadius: ctx.structural(NODE_BORDER_RADIUS),
37734
- sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH9),
37735
- sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH9),
38028
+ sEdgeStrokeWidth: ctx.structural(EDGE_STROKE_WIDTH),
38029
+ sNodeStrokeWidth: ctx.structural(NODE_STROKE_WIDTH),
37736
38030
  sOverloadStrokeWidth: ctx.structural(OVERLOAD_STROKE_WIDTH),
37737
38031
  sRoleDotRadius: ctx.structural(ROLE_DOT_RADIUS),
37738
38032
  sNodeSeparatorGap: ctx.structural(NODE_SEPARATOR_GAP2),
37739
38033
  sNodePadBottom: ctx.structural(NODE_PAD_BOTTOM2),
37740
- sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT6),
37741
- sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET2),
38034
+ sCollapseBarHeight: ctx.structural(COLLAPSE_BAR_HEIGHT),
38035
+ sCollapseBarInset: ctx.structural(COLLAPSE_BAR_INSET),
37742
38036
  sParticleR: ctx.structural(PARTICLE_R),
37743
38037
  sRejectParticleR: ctx.structural(PARTICLE_R),
37744
38038
  sRejectDropDistance: ctx.structural(REJECT_DROP_DISTANCE),
@@ -38062,7 +38356,7 @@ function isWarning(node) {
38062
38356
  return cap > 0 && node.computedRps / cap > 0.7;
38063
38357
  }
38064
38358
  function truncateDesc(text) {
38065
- return truncateText(text, META_FONT_SIZE8, DESC_MAX_WIDTH);
38359
+ return truncateText(text, META_FONT_SIZE6, DESC_MAX_WIDTH);
38066
38360
  }
38067
38361
  function sloLatencyColor(p90, slo) {
38068
38362
  const t = slo.latencyP90 ?? 0;
@@ -38541,7 +38835,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38541
38835
  if (!isNodeCollapsed) {
38542
38836
  const expanded = expandedNodeIds?.has(node.id) ?? false;
38543
38837
  const descLines = expanded && node.description && !node.isEdge ? node.description : [];
38544
- const descH = descLines.length * META_LINE_HEIGHT8;
38838
+ const descH = descLines.length * META_LINE_HEIGHT6;
38545
38839
  for (let di = 0; di < descLines.length; di++) {
38546
38840
  const rawLine = descLines[di];
38547
38841
  const processed = preprocessDescriptionLine(rawLine);
@@ -38549,7 +38843,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
38549
38843
  const isTruncated = descTruncated !== processed;
38550
38844
  const textEl = g.append("text").attr("x", node.x).attr(
38551
38845
  "y",
38552
- y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT8 + META_LINE_HEIGHT8 / 2 + sc.sMetaFontSize * 0.35
38846
+ y + NODE_HEADER_HEIGHT2 + di * META_LINE_HEIGHT6 + META_LINE_HEIGHT6 / 2 + sc.sMetaFontSize * 0.35
38553
38847
  ).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sc.sMetaFontSize).attr("fill", textFill);
38554
38848
  renderInlineText(textEl, descTruncated, palette, sc.sMetaFontSize);
38555
38849
  if (isTruncated) textEl.append("title").text(rawLine);
@@ -39067,7 +39361,7 @@ function parseAndLayoutInfra(content) {
39067
39361
  const layout = layoutInfra(computed);
39068
39362
  return { parsed, computed, layout };
39069
39363
  }
39070
- 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;
39364
+ 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;
39071
39365
  var init_renderer10 = __esm({
39072
39366
  "src/infra/renderer.ts"() {
39073
39367
  "use strict";
@@ -39088,21 +39382,18 @@ var init_renderer10 = __esm({
39088
39382
  init_legend_layout();
39089
39383
  init_title_constants();
39090
39384
  init_scaling();
39385
+ init_visual_conventions();
39091
39386
  NODE_FONT_SIZE4 = 13;
39092
- META_FONT_SIZE8 = 10;
39093
- META_LINE_HEIGHT8 = 14;
39387
+ META_FONT_SIZE6 = 10;
39388
+ META_LINE_HEIGHT6 = 14;
39094
39389
  EDGE_LABEL_FONT_SIZE9 = 11;
39095
39390
  GROUP_LABEL_FONT_SIZE2 = 14;
39096
39391
  NODE_BORDER_RADIUS = 8;
39097
- EDGE_STROKE_WIDTH9 = 1.5;
39098
- NODE_STROKE_WIDTH9 = 1.5;
39099
39392
  OVERLOAD_STROKE_WIDTH = 3;
39100
39393
  ROLE_DOT_RADIUS = 3;
39101
39394
  NODE_HEADER_HEIGHT2 = 28;
39102
39395
  NODE_SEPARATOR_GAP2 = 4;
39103
39396
  NODE_PAD_BOTTOM2 = 10;
39104
- COLLAPSE_BAR_HEIGHT6 = 6;
39105
- COLLAPSE_BAR_INSET2 = 0;
39106
39397
  LEGEND_FIXED_GAP3 = 16;
39107
39398
  SPEED_BADGE_H_PAD = 5;
39108
39399
  SPEED_BADGE_V_PAD = 3;
@@ -39141,7 +39432,7 @@ var init_renderer10 = __esm({
39141
39432
  partitions: "partitions"
39142
39433
  };
39143
39434
  DESC_MAX_CHARS = 120;
39144
- DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE8;
39435
+ DESC_MAX_WIDTH = DESC_MAX_CHARS * CHAR_WIDTH_RATIO * META_FONT_SIZE6;
39145
39436
  RPS_FORMAT_KEYS = /* @__PURE__ */ new Set(["max-rps", "ratelimit-rps"]);
39146
39437
  MS_FORMAT_KEYS = /* @__PURE__ */ new Set([
39147
39438
  "latency-ms",
@@ -40931,18 +41222,18 @@ function renderPert(container, resolved, layout, palette, isDark, options = {})
40931
41222
  const sLegendPillHeight = ctx.structural(LEGEND_PILL_HEIGHT);
40932
41223
  const sLegendBlockHeight = showTagLegend ? sLegendTopGap + sLegendPillHeight + sLegendBottomGap : 0;
40933
41224
  const sNodeRadius = ctx.structural(NODE_RADIUS2);
40934
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH10);
41225
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
40935
41226
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE5);
40936
41227
  const sNodeCellFontSize = ctx.text(NODE_CELL_FONT_SIZE2);
40937
41228
  const sNodeTopRowHeight = ctx.structural(NODE_TOP_ROW_HEIGHT);
40938
41229
  const sNodeBottomRowHeight = ctx.structural(NODE_BOTTOM_ROW_HEIGHT);
40939
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH10);
41230
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
40940
41231
  const sArrowheadW = ctx.structural(ARROWHEAD_W4);
40941
41232
  const sArrowheadH = ctx.structural(ARROWHEAD_H4);
40942
- const sContainerRadius = ctx.structural(CONTAINER_RADIUS3);
40943
- const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE4);
40944
- const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT3);
40945
- const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT7);
41233
+ const sContainerRadius = ctx.structural(CONTAINER_RADIUS);
41234
+ const sContainerLabelFontSize = ctx.text(CONTAINER_LABEL_FONT_SIZE);
41235
+ const sContainerHeaderHeight = ctx.structural(CONTAINER_HEADER_HEIGHT);
41236
+ const sCollapseBarHeight = ctx.structural(COLLAPSE_BAR_HEIGHT);
40946
41237
  const sPinIconW = ctx.structural(PIN_ICON_W);
40947
41238
  const sPinIconH = ctx.structural(PIN_ICON_H);
40948
41239
  const scaledWidth = layout.width + sDiagramPad * 2;
@@ -41509,7 +41800,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41509
41800
  palette.textOnFillDark
41510
41801
  );
41511
41802
  const sNR = sc.nodeRadius ?? NODE_RADIUS2;
41512
- const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT7;
41803
+ const sCBH = sc.collapseBarHeight ?? COLLAPSE_BAR_HEIGHT;
41513
41804
  drawTextbookCard(g, {
41514
41805
  width: grp.width,
41515
41806
  height: grp.height,
@@ -41543,10 +41834,10 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
41543
41834
  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})`);
41544
41835
  continue;
41545
41836
  }
41546
- const sCR = sc.containerRadius ?? CONTAINER_RADIUS3;
41547
- const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE4;
41548
- const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT3;
41549
- const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH10;
41837
+ const sCR = sc.containerRadius ?? CONTAINER_RADIUS;
41838
+ const sCLFS = sc.containerLabelFontSize ?? CONTAINER_LABEL_FONT_SIZE;
41839
+ const sCHH = sc.containerHeaderHeight ?? CONTAINER_HEADER_HEIGHT;
41840
+ const sNSW = sc.nodeStrokeWidth ?? NODE_STROKE_WIDTH;
41550
41841
  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);
41551
41842
  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);
41552
41843
  }
@@ -41599,7 +41890,7 @@ function renderEdges2(root, resolved, layout, palette, collapsedSet, sc = {}) {
41599
41890
  }
41600
41891
  const path = lineGenerator6(e.points);
41601
41892
  if (!path) continue;
41602
- const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH10;
41893
+ const sESW = sc.edgeStrokeWidth ?? EDGE_STROKE_WIDTH;
41603
41894
  const sELFS = sc.edgeLabelFontSize ?? 10;
41604
41895
  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 ?? "");
41605
41896
  const parsedEdge = edgeByKey.get(`${e.source}->${e.target}`);
@@ -41781,7 +42072,7 @@ function computeDurationEmphasis(activities) {
41781
42072
  function drawTextbookCard(g, a) {
41782
42073
  const { width: w, height: h, x, y } = a;
41783
42074
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41784
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42075
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41785
42076
  const sTRH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41786
42077
  const sBRH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41787
42078
  const sNFS = a.sNodeFontSize ?? NODE_FONT_SIZE5;
@@ -41880,7 +42171,7 @@ function drawTextbookCard(g, a) {
41880
42171
  function drawMilestonePill(g, a) {
41881
42172
  const { width: w, height: h, x, y } = a;
41882
42173
  const sNR = a.sNodeRadius ?? NODE_RADIUS2;
41883
- const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH10;
42174
+ const sNSW = a.sNodeStrokeWidth ?? NODE_STROKE_WIDTH;
41884
42175
  const topRowH = a.sNodeTopRowHeight ?? NODE_TOP_ROW_HEIGHT;
41885
42176
  const botRowH = a.sNodeBottomRowHeight ?? NODE_BOTTOM_ROW_HEIGHT;
41886
42177
  const sNCFS = a.sNodeCellFontSize ?? NODE_CELL_FONT_SIZE2;
@@ -42013,7 +42304,7 @@ function renderCaptionBlock(svg, bullets, args) {
42013
42304
  palette.textOnFillDark
42014
42305
  );
42015
42306
  const block = svg.append("g").attr("class", "pert-caption-block").attr("data-pert-caption", "");
42016
- 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);
42307
+ 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);
42017
42308
  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");
42018
42309
  const textX = x + CAPTION_BOX_PADDING_X;
42019
42310
  const firstBaselineY = y + CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT + CAPTION_FONT_SIZE;
@@ -42130,7 +42421,7 @@ function renderTornadoBlock(svg, rows, args) {
42130
42421
  palette.textOnFillDark
42131
42422
  );
42132
42423
  const block = svg.append("g").attr("class", "pert-tornado-block").attr("data-pert-tornado", "");
42133
- 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);
42424
+ 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);
42134
42425
  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");
42135
42426
  const fmt = (v) => {
42136
42427
  const r = Math.round(v * 100) / 100;
@@ -42286,7 +42577,7 @@ function renderScurveBlock(svg, data, args) {
42286
42577
  palette.textOnFillDark
42287
42578
  );
42288
42579
  const block = svg.append("g").attr("class", "pert-scurve-block").attr("data-pert-scurve", "");
42289
- 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);
42580
+ 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);
42290
42581
  const hasTitle = typeof title === "string" && title.length > 0;
42291
42582
  if (hasTitle) {
42292
42583
  const titleText = title.replace(/\.$/, "");
@@ -42470,7 +42761,7 @@ function formatScurveDate(iso) {
42470
42761
  if (month < 0 || month > 11 || isNaN(day)) return iso;
42471
42762
  return `${SCURVE_MONTH_NAMES[month]} ${day}`;
42472
42763
  }
42473
- 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;
42764
+ 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;
42474
42765
  var init_renderer11 = __esm({
42475
42766
  "src/pert/renderer.ts"() {
42476
42767
  "use strict";
@@ -42488,20 +42779,15 @@ var init_renderer11 = __esm({
42488
42779
  init_analyzer();
42489
42780
  init_layout11();
42490
42781
  init_internal();
42782
+ init_visual_conventions();
42491
42783
  DIAGRAM_PADDING11 = 20;
42492
42784
  NODE_FONT_SIZE5 = 13;
42493
42785
  NODE_CELL_FONT_SIZE2 = 11;
42494
42786
  NODE_RADIUS2 = 6;
42495
- NODE_STROKE_WIDTH10 = 1.5;
42496
42787
  NODE_TOP_ROW_HEIGHT = 26;
42497
42788
  NODE_BOTTOM_ROW_HEIGHT = 26;
42498
- EDGE_STROKE_WIDTH10 = 1.5;
42499
42789
  ARROWHEAD_W4 = 10;
42500
42790
  ARROWHEAD_H4 = 7;
42501
- CONTAINER_RADIUS3 = 8;
42502
- CONTAINER_LABEL_FONT_SIZE4 = 13;
42503
- CONTAINER_HEADER_HEIGHT3 = 28;
42504
- COLLAPSE_BAR_HEIGHT7 = 6;
42505
42791
  DURATION_FADE_OPACITY = 0.55;
42506
42792
  PIN_ICON_W = 13;
42507
42793
  PIN_ICON_H = 13;
@@ -45492,8 +45778,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
45492
45778
  const sNodeFontSize = ctx.text(NODE_FONT_SIZE6);
45493
45779
  const sEdgeLabelFontSize = ctx.text(EDGE_LABEL_FONT_SIZE10);
45494
45780
  const sGroupLabelFontSize = ctx.text(GROUP_LABEL_FONT_SIZE3);
45495
- const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH11);
45496
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH11);
45781
+ const sEdgeStrokeWidth = ctx.structural(EDGE_STROKE_WIDTH);
45782
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
45497
45783
  const sArrowheadW = ctx.structural(ARROWHEAD_W5);
45498
45784
  const sArrowheadH = ctx.structural(ARROWHEAD_H5);
45499
45785
  const sPseudostateRadius = ctx.structural(PSEUDOSTATE_RADIUS);
@@ -45770,7 +46056,7 @@ function renderStateForExport(content, theme, palette) {
45770
46056
  document.body.removeChild(container);
45771
46057
  }
45772
46058
  }
45773
- 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;
46059
+ 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;
45774
46060
  var init_state_renderer = __esm({
45775
46061
  "src/graph/state-renderer.ts"() {
45776
46062
  "use strict";
@@ -45786,13 +46072,12 @@ var init_state_renderer = __esm({
45786
46072
  init_scaling();
45787
46073
  init_text_measure();
45788
46074
  init_note_box();
46075
+ init_visual_conventions();
45789
46076
  DIAGRAM_PADDING12 = 20;
45790
46077
  MAX_SCALE7 = 3;
45791
46078
  NODE_FONT_SIZE6 = 13;
45792
46079
  EDGE_LABEL_FONT_SIZE10 = 11;
45793
46080
  GROUP_LABEL_FONT_SIZE3 = 11;
45794
- EDGE_STROKE_WIDTH11 = 1.5;
45795
- NODE_STROKE_WIDTH11 = 1.5;
45796
46081
  ARROWHEAD_W5 = 10;
45797
46082
  ARROWHEAD_H5 = 7;
45798
46083
  PSEUDOSTATE_RADIUS = 10;
@@ -47725,14 +48010,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47725
48010
  const panelY = PADDING2;
47726
48011
  const textX = panelX + CARD_PADDING_X3;
47727
48012
  const clipId = "persona-clip";
47728
- defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5);
48013
+ defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
47729
48014
  const personaFill = shapeFill(palette, personaColor, isDark, { solid });
47730
48015
  const onPersonaText = contrastText(
47731
48016
  personaFill,
47732
48017
  palette.textOnFillLight,
47733
48018
  palette.textOnFillDark
47734
48019
  );
47735
- personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS5).attr("fill", personaFill);
48020
+ personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
47736
48021
  if (descLines.length > 0) {
47737
48022
  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);
47738
48023
  }
@@ -47740,7 +48025,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47740
48025
  const silY = panelY + panelHeight / 2 - 6;
47741
48026
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
47742
48027
  renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
47743
- 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);
48028
+ 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);
47744
48029
  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);
47745
48030
  for (let li = 0; li < descLines.length; li++) {
47746
48031
  const lineEl = personaG.append("text").attr("x", textX).attr("y", panelY + titleRowH + descLineH * (li + 1)).attr("font-size", FONT_SIZE_META).attr("fill", onPersonaText);
@@ -47980,7 +48265,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
47980
48265
  { solid }
47981
48266
  );
47982
48267
  const rowStroke = stepColor ?? palette.textMuted;
47983
- 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);
48268
+ 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);
47984
48269
  const faceCx = listX + CARD_PADDING_X3 + COLLAPSED_FACE_R;
47985
48270
  const faceCy = itemY + COLLAPSED_CARD_H / 2;
47986
48271
  if (step.score !== void 0) {
@@ -48143,7 +48428,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
48143
48428
  const scoreColor = scoreToColor(score, palette);
48144
48429
  const tintedBg = mix(scoreColor, palette.surface, 20);
48145
48430
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
48146
- 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);
48431
+ 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);
48147
48432
  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);
48148
48433
  const centerX = bx + bw / 2;
48149
48434
  for (let i = 0; i < lines.length; i++) {
@@ -48300,7 +48585,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48300
48585
  palette.textOnFillLight,
48301
48586
  palette.textOnFillDark
48302
48587
  );
48303
- 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);
48588
+ 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);
48304
48589
  const titleMaxW = sl.width - CARD_PADDING_X3 * 2;
48305
48590
  const titleLines = wrapTextToWidth(sl.step.title, FONT_SIZE_STEP, titleMaxW);
48306
48591
  for (let i = 0; i < titleLines.length; i++) {
@@ -48359,7 +48644,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
48359
48644
  const stripFill = shapeFill(palette, stripColor, isDark, {
48360
48645
  ...solid !== void 0 && { solid }
48361
48646
  });
48362
- 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);
48647
+ 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);
48363
48648
  const stripTextColor = contrastText(
48364
48649
  stripFill,
48365
48650
  palette.textOnFillLight,
@@ -48475,7 +48760,7 @@ function renderJourneyMapForExport(content, theme, palette) {
48475
48760
  }
48476
48761
  return svgEl.outerHTML;
48477
48762
  }
48478
- 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;
48763
+ 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;
48479
48764
  var init_renderer14 = __esm({
48480
48765
  "src/journey-map/renderer.ts"() {
48481
48766
  "use strict";
@@ -48490,9 +48775,9 @@ var init_renderer14 = __esm({
48490
48775
  init_tag_groups();
48491
48776
  init_scaling();
48492
48777
  init_text_measure();
48778
+ init_visual_conventions();
48493
48779
  DIAGRAM_PADDING13 = 20;
48494
48780
  PADDING2 = DIAGRAM_PADDING13;
48495
- CARD_RADIUS5 = 6;
48496
48781
  CARD_PADDING_X3 = 10;
48497
48782
  CARD_PADDING_Y3 = 6;
48498
48783
  CARD_HEADER_HEIGHT3 = 24;
@@ -48569,7 +48854,7 @@ function computeCycleLayout(parsed, options) {
48569
48854
  const hasDesc = !hideDescriptions && node.description.length > 0;
48570
48855
  const labelWidth2 = Math.max(
48571
48856
  MIN_NODE_WIDTH4,
48572
- measureText(node.label, LABEL_FONT_SIZE5) + NODE_PAD_X * 2
48857
+ measureText(node.label, LABEL_FONT_SIZE4) + NODE_PAD_X * 2
48573
48858
  );
48574
48859
  if (circleNodes) {
48575
48860
  return computeCircleNodeDims(node, hasDesc);
@@ -48786,7 +49071,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48786
49071
  let bestScore = Infinity;
48787
49072
  for (let w = minW; w <= MAX_NODE_WIDTH3; w += DESC_WIDTH_STEP) {
48788
49073
  const wrapped2 = wrapDescForWidth(description, w);
48789
- const h = HEADER_HEIGHT5 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
49074
+ const h = HEADER_HEIGHT4 + wrapped2.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y;
48790
49075
  const ratio = w / h;
48791
49076
  const score = Math.abs(Math.log(ratio / DESC_TARGET_RATIO));
48792
49077
  if (score < bestScore) {
@@ -48798,7 +49083,7 @@ function chooseDescribedRectDims(description, labelWidth2) {
48798
49083
  const wrapped = wrapDescForWidth(description, minW);
48799
49084
  return {
48800
49085
  width: minW,
48801
- height: HEADER_HEIGHT5 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
49086
+ height: HEADER_HEIGHT4 + wrapped.length * DESC_LINE_HEIGHT7 + DESC_PAD_Y,
48802
49087
  wrappedDesc: wrapped
48803
49088
  };
48804
49089
  }
@@ -48811,7 +49096,7 @@ function wrapDescForWidth(description, nodeWidth) {
48811
49096
  );
48812
49097
  }
48813
49098
  function renderedDescNodeHeight(numLines, scale) {
48814
- const headerH = HEADER_HEIGHT5 * scale;
49099
+ const headerH = HEADER_HEIGHT4 * scale;
48815
49100
  const descFont = Math.max(
48816
49101
  RENDERER_DESC_FONT_MIN,
48817
49102
  Math.round(RENDERER_DESC_FONT * scale)
@@ -49146,7 +49431,7 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
49146
49431
  const midAngle = srcExitAngle + dir * visibleSweep / 2;
49147
49432
  return { path, midAngle };
49148
49433
  }
49149
- 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;
49434
+ 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;
49150
49435
  var init_layout14 = __esm({
49151
49436
  "src/cycle/layout.ts"() {
49152
49437
  "use strict";
@@ -49154,7 +49439,7 @@ var init_layout14 = __esm({
49154
49439
  init_wrapped_desc();
49155
49440
  init_text_measure();
49156
49441
  MIN_ARC_ANGLE = 15 * Math.PI / 180;
49157
- LABEL_FONT_SIZE5 = 13;
49442
+ LABEL_FONT_SIZE4 = 13;
49158
49443
  CIRCLE_LABEL_FONT_SIZE = 16;
49159
49444
  DESC_FONT_SIZE6 = 11;
49160
49445
  EDGE_LABEL_FONT_SIZE11 = 11;
@@ -49164,7 +49449,7 @@ var init_layout14 = __esm({
49164
49449
  DESC_WIDTH_STEP = 20;
49165
49450
  DESC_TARGET_RATIO = 1.6;
49166
49451
  PLAIN_NODE_HEIGHT = 50;
49167
- HEADER_HEIGHT5 = 36;
49452
+ HEADER_HEIGHT4 = 36;
49168
49453
  DESC_LINE_HEIGHT7 = 16;
49169
49454
  DESC_PAD_Y = 14;
49170
49455
  NODE_PAD_X = 20;
@@ -53261,6 +53546,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53261
53546
  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);
53262
53547
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
53263
53548
  const defs = svg.append("defs");
53549
+ const uid = mapInstanceCounter++;
53550
+ const nid = (base) => `${base}__m${uid}`;
53264
53551
  const arrowSize = (w) => Math.min(15, 7 + w * 0.95);
53265
53552
  const haloColor = palette.bg;
53266
53553
  const gRegions = svg.append("g").attr("class", "dgmo-map-regions");
@@ -53293,8 +53580,8 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53293
53580
  for (const r of layout.regions) drawRegion(gRegions, r, 0.5);
53294
53581
  if (layout.relief.length && layout.reliefHatch) {
53295
53582
  const h = layout.reliefHatch;
53296
- const rangeClipId = "dgmo-relief-clip";
53297
- const landClipId = "dgmo-relief-land";
53583
+ const rangeClipId = nid("dgmo-relief-clip");
53584
+ const landClipId = nid("dgmo-relief-land");
53298
53585
  const rangeClip = defs.append("clipPath").attr("id", rangeClipId);
53299
53586
  for (const s of layout.relief) rangeClip.append("path").attr("d", s.d);
53300
53587
  const landClip = defs.append("clipPath").attr("id", landClipId);
@@ -53307,7 +53594,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53307
53594
  }
53308
53595
  if (layout.coastlineStyle) {
53309
53596
  const cs = layout.coastlineStyle;
53310
- const maskId = "dgmo-map-water-mask";
53597
+ const maskId = nid("dgmo-map-water-mask");
53311
53598
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53312
53599
  mask.append("rect").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "white");
53313
53600
  const landD = layout.regions.filter((r) => r.id !== "lake").map((r) => r.d).join(" ");
@@ -53325,7 +53612,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53325
53612
  appendWaterLines(
53326
53613
  gWater,
53327
53614
  defs,
53328
- "dgmo-map-coast",
53615
+ nid("dgmo-map-coast"),
53329
53616
  // Pass the canvas frame so edges collinear with it (the antimeridian on a
53330
53617
  // world map, regional clipExtent cuts) don't get ringed as fake coast —
53331
53618
  // land runs cleanly to the render-area edge.
@@ -53362,7 +53649,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53362
53649
  (l) => l.poiId !== void 0 && !l.hidden
53363
53650
  );
53364
53651
  if (poiLabels.length) {
53365
- const patchBlurId = "dgmo-map-label-patch-blur";
53652
+ const patchBlurId = nid("dgmo-map-label-patch-blur");
53366
53653
  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);
53367
53654
  const PAD = 8;
53368
53655
  const buildPatch = (labels, maskId, decoCluster) => {
@@ -53407,7 +53694,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53407
53694
  if (clusterUi) {
53408
53695
  buildPatch(
53409
53696
  poiLabels.filter((l) => l.clusterMember === void 0),
53410
- "dgmo-map-label-patch"
53697
+ nid("dgmo-map-label-patch")
53411
53698
  );
53412
53699
  const byCluster = /* @__PURE__ */ new Map();
53413
53700
  for (const l of poiLabels) {
@@ -53418,9 +53705,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53418
53705
  }
53419
53706
  let ci = 0;
53420
53707
  for (const [cid, labs] of byCluster)
53421
- buildPatch(labs, `dgmo-map-label-patch-c${ci++}`, cid);
53708
+ buildPatch(labs, nid(`dgmo-map-label-patch-c${ci++}`), cid);
53422
53709
  } else {
53423
- buildPatch(poiLabels, "dgmo-map-label-patch");
53710
+ buildPatch(poiLabels, nid("dgmo-map-label-patch"));
53424
53711
  }
53425
53712
  }
53426
53713
  if (layout.insets.length) {
@@ -53429,7 +53716,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53429
53716
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
53430
53717
  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");
53431
53718
  if (box.contextLand) {
53432
- const clipId = `dgmo-map-inset-clip-${bi}`;
53719
+ const clipId = nid(`dgmo-map-inset-clip-${bi}`);
53433
53720
  defs.append("clipPath").attr("id", clipId).append("path").attr("d", d);
53434
53721
  insetG.append("path").attr("d", box.contextLand.d).attr("fill", box.contextLand.fill).attr("clip-path", `url(#${clipId})`);
53435
53722
  }
@@ -53437,7 +53724,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53437
53724
  for (const r of layout.insetRegions) drawRegion(insetG, r, 0.5);
53438
53725
  if (layout.coastlineStyle) {
53439
53726
  const cs = layout.coastlineStyle;
53440
- const maskId = "dgmo-map-inset-water-mask";
53727
+ const maskId = nid("dgmo-map-inset-water-mask");
53441
53728
  const mask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
53442
53729
  const reach = Math.max(0, ...cs.lines.map((l) => l.d + l.thickness));
53443
53730
  for (const box of layout.insets) {
@@ -53446,7 +53733,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53446
53733
  }
53447
53734
  layout.insets.forEach((box, bi) => {
53448
53735
  if (box.contextLand)
53449
- mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#dgmo-map-inset-clip-${bi})`);
53736
+ mask.append("path").attr("d", box.contextLand.d).attr("fill", "black").attr("clip-path", `url(#${nid(`dgmo-map-inset-clip-${bi}`)})`);
53450
53737
  });
53451
53738
  for (const r of layout.insetRegions)
53452
53739
  if (r.id !== "lake")
@@ -53454,7 +53741,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53454
53741
  for (const r of layout.insetRegions)
53455
53742
  if (r.id === "lake")
53456
53743
  mask.append("path").attr("d", r.d).attr("fill", "white");
53457
- const clipId = "dgmo-map-inset-water-clip";
53744
+ const clipId = nid("dgmo-map-inset-water-clip");
53458
53745
  const clip = defs.append("clipPath").attr("id", clipId);
53459
53746
  for (const box of layout.insets) {
53460
53747
  const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
@@ -53464,7 +53751,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53464
53751
  appendWaterLines(
53465
53752
  gInsetWater,
53466
53753
  defs,
53467
- "dgmo-map-inset-coast",
53754
+ nid("dgmo-map-inset-coast"),
53468
53755
  coastlineOuterRings(layout.insetRegions, cs.minExtent),
53469
53756
  cs,
53470
53757
  layout.background
@@ -53493,7 +53780,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
53493
53780
  }
53494
53781
  wireSync(p, leg.lineNumber);
53495
53782
  if (leg.arrow) {
53496
- const id = `dgmo-map-arrow-${i}`;
53783
+ const id = nid(`dgmo-map-arrow-${i}`);
53497
53784
  const s = arrowSize(leg.width);
53498
53785
  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);
53499
53786
  p.attr("marker-end", `url(#${id})`);
@@ -53689,7 +53976,7 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
53689
53976
  }
53690
53977
  return t;
53691
53978
  }
53692
- var d3Selection23, LABEL_FONT;
53979
+ var d3Selection23, LABEL_FONT, mapInstanceCounter;
53693
53980
  var init_renderer16 = __esm({
53694
53981
  "src/map/renderer.ts"() {
53695
53982
  "use strict";
@@ -53702,6 +53989,7 @@ var init_renderer16 = __esm({
53702
53989
  init_legend_band();
53703
53990
  init_layout15();
53704
53991
  LABEL_FONT = 11;
53992
+ mapInstanceCounter = 0;
53705
53993
  }
53706
53994
  });
53707
53995
 
@@ -54633,7 +54921,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54633
54921
  const sHMargin = ctx.aesthetic(H_MARGIN);
54634
54922
  const sVMargin = ctx.aesthetic(V_MARGIN3);
54635
54923
  const sTitleAreaHeight = ctx.structural(TITLE_AREA_HEIGHT4);
54636
- const sHeaderHeight = ctx.structural(HEADER_HEIGHT6);
54924
+ const sHeaderHeight = ctx.structural(HEADER_HEIGHT5);
54637
54925
  const sRowHeight = ctx.structural(ROW_HEIGHT);
54638
54926
  const sPhaseHeight = ctx.structural(PHASE_HEIGHT);
54639
54927
  const sTaskLabelMin = ctx.structural(TASK_LABEL_MIN);
@@ -54658,7 +54946,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
54658
54946
  const sLegendLetterFont = ctx.text(LEGEND_LETTER_FONT);
54659
54947
  const sViolationLineHeight = ctx.structural(VIOLATION_LINE_HEIGHT);
54660
54948
  const sStackTopGap = ctx.structural(STACK_TOP_GAP);
54661
- const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH12);
54949
+ const sNodeStrokeWidth = ctx.structural(NODE_STROKE_WIDTH);
54662
54950
  const sNodeRadius = ctx.structural(NODE_RADIUS3);
54663
54951
  const innerWidth = Math.max(0, width - 2 * sHMargin);
54664
54952
  let roleColW = Math.max(
@@ -55204,7 +55492,7 @@ function parseQuotedSegments(message) {
55204
55492
  out.push({ text: message.slice(last), bold: false });
55205
55493
  return out;
55206
55494
  }
55207
- 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;
55495
+ 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;
55208
55496
  var init_renderer19 = __esm({
55209
55497
  "src/raci/renderer.ts"() {
55210
55498
  "use strict";
@@ -55216,6 +55504,7 @@ var init_renderer19 = __esm({
55216
55504
  init_variants();
55217
55505
  init_scaling();
55218
55506
  init_text_measure();
55507
+ init_visual_conventions();
55219
55508
  MARKER_LABELS = {
55220
55509
  raci: { R: "Responsible", A: "Accountable", C: "Consulted", I: "Informed" },
55221
55510
  rasci: {
@@ -55237,7 +55526,7 @@ var init_renderer19 = __esm({
55237
55526
  TITLE_LEGEND_GAP = 16;
55238
55527
  LEGEND_LABEL_FONT = 12;
55239
55528
  LEGEND_LETTER_FONT = 14;
55240
- HEADER_HEIGHT6 = 36;
55529
+ HEADER_HEIGHT5 = 36;
55241
55530
  ROW_HEIGHT = 36;
55242
55531
  PHASE_HEIGHT = 40;
55243
55532
  TASK_LABEL_MIN = 200;
@@ -55257,7 +55546,6 @@ var init_renderer19 = __esm({
55257
55546
  ROLE_HEADER_FONT = 12;
55258
55547
  PHASE_FONT = 13;
55259
55548
  TINT_PCT = 25;
55260
- NODE_STROKE_WIDTH12 = 1.5;
55261
55549
  NODE_RADIUS3 = 6;
55262
55550
  AUTO_ACCENTS = [
55263
55551
  "blue",
@@ -55857,11 +56145,11 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55857
56145
  const lines = splitParticipantLabel(
55858
56146
  p.label,
55859
56147
  labelTextWidth(PARTICIPANT_BOX_WIDTH),
55860
- LABEL_FONT_SIZE6
56148
+ LABEL_FONT_SIZE5
55861
56149
  );
55862
56150
  if (lines.length === 0) continue;
55863
56151
  const widest = Math.max(
55864
- ...lines.map((l) => measureText(l, LABEL_FONT_SIZE6))
56152
+ ...lines.map((l) => measureText(l, LABEL_FONT_SIZE5))
55865
56153
  );
55866
56154
  const labelWidth2 = widest + 10;
55867
56155
  uniformBoxWidth = Math.max(uniformBoxWidth, labelWidth2);
@@ -55895,7 +56183,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
55895
56183
  const sSelfCallWidth = ctx.structural(SELF_CALL_WIDTH);
55896
56184
  const sNoteTextWidthMax = sNoteMaxW - sNotePadH * 2 - sNoteFold;
55897
56185
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
55898
- const sLabelFontSize = ctx.text(LABEL_FONT_SIZE6);
56186
+ const sLabelFontSize = ctx.text(LABEL_FONT_SIZE5);
55899
56187
  const sLabelTextWidth = labelTextWidth(sBoxW);
55900
56188
  const participantIndexMap = /* @__PURE__ */ new Map();
55901
56189
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
@@ -57032,7 +57320,7 @@ function buildNoteMessageMap(elements) {
57032
57320
  walk(elements);
57033
57321
  return map;
57034
57322
  }
57035
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE6) {
57323
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
57036
57324
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
57037
57325
  if (tagAttr) {
57038
57326
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -57080,7 +57368,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
57080
57368
  });
57081
57369
  }
57082
57370
  }
57083
- 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;
57371
+ 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;
57084
57372
  var init_renderer20 = __esm({
57085
57373
  "src/sequence/renderer.ts"() {
57086
57374
  "use strict";
@@ -57101,7 +57389,7 @@ var init_renderer20 = __esm({
57101
57389
  PARTICIPANT_GAP = 160;
57102
57390
  PARTICIPANT_BOX_WIDTH = 120;
57103
57391
  PARTICIPANT_BOX_HEIGHT = 50;
57104
- LABEL_FONT_SIZE6 = 13;
57392
+ LABEL_FONT_SIZE5 = 13;
57105
57393
  TOP_MARGIN = 20;
57106
57394
  TITLE_HEIGHT8 = 30;
57107
57395
  PARTICIPANT_Y_OFFSET = 10;
@@ -57610,6 +57898,7 @@ __export(advanced_exports, {
57610
57898
  applyGroupOrdering: () => applyGroupOrdering,
57611
57899
  applyPositionOverrides: () => applyPositionOverrides,
57612
57900
  atlasPalette: () => atlasPalette,
57901
+ autoTagColorCycle: () => autoTagColorCycle,
57613
57902
  blueprintPalette: () => blueprintPalette,
57614
57903
  buildExtendedChartOption: () => buildExtendedChartOption,
57615
57904
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -62288,6 +62577,7 @@ init_renderer4();
62288
62577
  init_parser9();
62289
62578
  init_layout4();
62290
62579
  init_renderer5();
62580
+ init_tag_groups();
62291
62581
  init_inline_markdown();
62292
62582
  init_name_normalize();
62293
62583
  init_parser10();
@@ -63784,6 +64074,7 @@ function formatLineDiff(path, original, migrated) {
63784
64074
  applyGroupOrdering,
63785
64075
  applyPositionOverrides,
63786
64076
  atlasPalette,
64077
+ autoTagColorCycle,
63787
64078
  blueprintPalette,
63788
64079
  buildExtendedChartOption,
63789
64080
  buildNoteMessageMap,