@riebeckite/plugin-excalibrain 0.0.31 → 0.0.33

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.
package/README.md CHANGED
@@ -132,6 +132,13 @@ The `render` option selects where the map is produced:
132
132
 
133
133
  `heading` / `headingText` control the optional `<h2>`.
134
134
 
135
+ ## Live example
136
+
137
+ The map is assembled from this page's links; the fence body is ignored.
138
+
139
+ ~~~excalibrain
140
+ ~~~
141
+
135
142
  ## Options
136
143
 
137
144
  | Option | Type | Default | Description |
@@ -179,7 +186,7 @@ wrapping an `<a href>` around its `<rect>` and `<text>`. Links are
179
186
 
180
187
  ## Exports
181
188
 
182
- - `excaliBrain(options?)` / `excaliBrainPlugin` — plugin factory
189
+ - `excaliBrain(options?)` / `excaliBrain` — plugin factory
183
190
  - `resolveExcaliBrainOptions(options?)` — resolved defaults
184
191
  - `buildExcaliBrainGraph(input)` — pure graph builder
185
192
  - `layoutExcaliBrain(graph, options?)` — pure deterministic layout
package/README_ja.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  関係は ExcaliBrain のオントロジーに従い、YAML frontmatter と本文中の Dataview インラインフィールドから取得します。明示されていない関係は、コンテンツグラフから推論します。
24
24
 
25
- ## 設定する
25
+ ## 設定
26
26
 
27
27
  ```ts
28
28
  import { defineConfig } from "@riebeckite/core";
@@ -90,11 +90,11 @@ related:: [[note-a]] and [[note-b]] are similar
90
90
  - 相手からこのノートへのバックリンクは `parent`
91
91
  - 相互リンクは `leftFriend`
92
92
 
93
- `siblings` が有効な場合(既定)、親ノートの他の子ノートを `sibling` として追加します。兄弟の推論には `infer` も必要で、`infer: false` にすると無効になります。リンク先はコンテンツマニフェストから解決し、解決できない場合は元のリンクテキストをラベルにした仮想ノード(`data-node-virtual="true"`)にします。
93
+ `siblings` が有効な場合(既定)、親ノートの他の子ノートを `sibling` として追加します。兄弟の推論にも `infer` が必要で、`infer: false` にすると無効になります。リンク先はコンテンツマニフェストから解決し、解決できない場合は元のリンクテキストをラベルにした仮想ノード(`data-node-virtual="true"`)にします。
94
94
 
95
95
  ## 公開範囲
96
96
 
97
- ノードはコンテンツマニフェストから解決します。`publishing.routable` が false のターゲットはマップから除外するため、公開対象外のノートがノードやリンクとして現れることはなく、タイトルやパーマリンクも漏れません。
97
+ ノードはコンテンツマニフェストから解決します。`publishing.routable` が `false` のターゲットはマップから除外するため、公開対象外のノートがノードやリンクとして現れることはなく、タイトルやパーマリンクも漏れません。
98
98
 
99
99
  ## 描画
100
100
 
@@ -103,16 +103,23 @@ related:: [[note-a]] and [[note-b]] are similar
103
103
  | モード | 動作 |
104
104
  | --- | --- |
105
105
  | `"build"`(既定) | ビルド時に SVG を生成し、記事に埋め込みます |
106
- | `"client"` | `div.rb-excalibrain__canvas` にグラフとレイアウトのペイロードをエスケープして持ち、`initExcaliBrain()` がブラウザで SVG を生成します |
106
+ | `"client"` | `div.rb-excalibrain__canvas` にグラフとレイアウトのペイロードをエスケープして保持し、`initExcaliBrain()` がブラウザで SVG を生成します |
107
107
  | `"both"` | 埋め込み SVG とクライアント側の描画を併用します(プログレッシブエンハンスメント) |
108
108
 
109
- ### 差し込み方
109
+ ### 記事への差し込み
110
110
 
111
111
  - ` ```excalibrain ` フェンスがある場合は、そのプレースホルダーをマップに置き換えます。
112
112
  - フェンスがなく、`auto` が有効で関係が 1 つ以上ある場合は、記事 HTML の末尾にマップのセクションを追加します(マニフェストのエントリとキャッシュ済みの記事 HTML の両方を更新します)。
113
113
 
114
114
  `heading` と `headingText` は任意の `<h2>` を制御します。
115
115
 
116
+ ## 実行例
117
+
118
+ マップはこのページのリンクから組み立てられます。フェンスの中身は使われません。
119
+
120
+ ~~~excalibrain
121
+ ~~~
122
+
116
123
  ## オプション
117
124
 
118
125
  | 項目 | 型 | 既定値 | 説明 |
@@ -150,11 +157,11 @@ related:: [[note-a]] and [[note-b]] are similar
150
157
 
151
158
  - マップは閲覧専用です。クライアント側の処理は SVG を生成するだけで、ドラッグ、ズーム、展開・折りたたみの操作はありません。
152
159
  - `maxPerRegion` は領域ごとのノード数を打ち切るため、関係が多いノートでは先頭のノードだけを表示します。
153
- - 描画できるのは上記のオントロジーのロールだけで、ノード単位のスタイルや領域単位の設定は下記のオプション以外にありません。
160
+ - 描画できるのは上記のオントロジーのロールだけで、ノード単位のスタイルや領域単位の設定は上記のオプション以外にありません。
154
161
 
155
162
  ## 主なエクスポート
156
163
 
157
- - `excaliBrain(options?)` / `excaliBrainPlugin`: プラグインを作成する
164
+ - `excaliBrain(options?)` / `excaliBrain`: プラグインを作成する
158
165
  - `resolveExcaliBrainOptions(options?)`: 既定値を解決する
159
166
  - `buildExcaliBrainGraph(input)`: 純粋なグラフ構築
160
167
  - `layoutExcaliBrain(graph, options?)`: 決定的なレイアウト
package/dist/client.js CHANGED
@@ -27,6 +27,9 @@ function renderExcaliBrainSvg(graph, layout, options = {}) {
27
27
  parts.push(
28
28
  `<svg class="${className}__svg" viewBox="0 0 ${layout.width} ${layout.height}" role="img" aria-label="${escapeAttribute(`${graph.center.title} ExcaliBrain`)}" xmlns="http://www.w3.org/2000/svg" width="${layout.width}" height="${layout.height}">`
29
29
  );
30
+ parts.push(
31
+ `<defs><marker id="${className}-arrow" class="${className}__arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" /></marker></defs>`
32
+ );
30
33
  const links = layout.links.map((link) => renderLink(link, byId, className)).join("");
31
34
  parts.push(`<g class="${className}__links">${links}</g>`);
32
35
  for (const region of EXCALIBRAIN_REGION_ORDER) {
@@ -43,7 +46,7 @@ function renderExcaliBrainSvg(graph, layout, options = {}) {
43
46
  return parts.join("");
44
47
  }
45
48
  function renderNode(node, className) {
46
- const box = `<rect class="${className}__node-box" x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="4" />`;
49
+ const box = `<rect class="${className}__node-box" x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="8" />`;
47
50
  const label = `<text class="${className}__node-label" x="${round(
48
51
  node.x + node.width / 2
49
52
  )}" y="${round(node.y + node.height / 2)}" text-anchor="middle" dominant-baseline="middle">${escapeHtml(node.title)}</text>`;
@@ -62,8 +65,12 @@ function renderLink(link, byId, className) {
62
65
  const from = byId.get(link.from);
63
66
  const to = byId.get(link.to);
64
67
  if (!from || !to) return "";
65
- const d = `M ${round(from.x + from.width / 2)} ${round(from.y + from.height / 2)} L ${round(to.x + to.width / 2)} ${round(to.y + to.height / 2)}`;
66
- return `<path class="${className}__link" data-link-role="${ROLE_ATTRIBUTE[link.role]}" data-relation-type="${link.relationType}" d="${d}" />`;
68
+ const fromX = from.x + from.width / 2;
69
+ const fromY = from.y + from.height / 2;
70
+ const toX = to.x + to.width / 2;
71
+ const toY = to.y + to.height / 2;
72
+ const d = `M ${round(fromX)} ${round(fromY)} L ${round(toX)} ${round(toY)}`;
73
+ return `<path class="${className}__link" data-link-role="${ROLE_ATTRIBUTE[link.role]}" data-relation-type="${link.relationType}" marker-end="url(#${className}-arrow)" d="${d}" />`;
67
74
  }
68
75
  function round(value) {
69
76
  return Math.round(value * 100) / 100;
package/dist/index.d.ts CHANGED
@@ -8,4 +8,3 @@ export { resolveExcaliBrainOptions, validateExcaliBrainOptions, } from "./src/op
8
8
  export { renderExcaliBrainSection, renderExcaliBrainSvg, } from "./src/render.js";
9
9
  export type { ExcaliBrainBuildInput, ExcaliBrainClientOptions, ExcaliBrainGraph, ExcaliBrainLayout, ExcaliBrainLink, ExcaliBrainNode, ExcaliBrainNodeRole, ExcaliBrainOntology, ExcaliBrainOptions, ExcaliBrainPositionedLink, ExcaliBrainPositionedNode, ExcaliBrainRegion, ExcaliBrainRelationType, ExcaliBrainRenderMode, ExcaliBrainRole, } from "./src/types.js";
10
10
  export declare function excaliBrain(options?: ExcaliBrainOptions): import("@riebeckite/core").RiebeckitePlugin<ExcaliBrainOptions>;
11
- export declare const excaliBrainPlugin: typeof excaliBrain;
package/dist/index.js CHANGED
@@ -443,6 +443,11 @@ function layoutExcaliBrain(graph, options = {}) {
443
443
  nearRadius,
444
444
  Math.min(nearRadius * 1.5, minDimension / 2 - 28)
445
445
  );
446
+ const sideFarRadius = Math.max(0, width / 2 - MAX_NODE_WIDTH / 2 - 4);
447
+ const sideNearRadius = Math.min(
448
+ sideFarRadius,
449
+ Math.max(MAX_CENTER_WIDTH / 2 + MAX_NODE_WIDTH / 2 + 20, width * 0.16)
450
+ );
446
451
  const positioned = [
447
452
  positionCenter(graph.center, cx, cy, width, height)
448
453
  ];
@@ -476,7 +481,7 @@ function layoutExcaliBrain(graph, options = {}) {
476
481
  continue;
477
482
  }
478
483
  const anchor = ROLE_ANCHOR[role];
479
- const radius = anchor.radius === "far" ? farRadius : nearRadius;
484
+ const radius = role === "leftFriend" || role === "rightFriend" ? sideNearRadius : role === "previous" || role === "next" ? sideFarRadius : anchor.radius === "far" ? farRadius : nearRadius;
480
485
  group.forEach((node, index) => {
481
486
  const angle = spreadAngle(anchor.angle, index, group.length);
482
487
  positioned.push(positionNode(node, angle, radius, cx, cy, width, height));
@@ -652,6 +657,9 @@ function renderExcaliBrainSvg(graph, layout, options = {}) {
652
657
  parts.push(
653
658
  `<svg class="${className}__svg" viewBox="0 0 ${layout.width} ${layout.height}" role="img" aria-label="${escapeAttribute(`${graph.center.title} ExcaliBrain`)}" xmlns="http://www.w3.org/2000/svg" width="${layout.width}" height="${layout.height}">`
654
659
  );
660
+ parts.push(
661
+ `<defs><marker id="${className}-arrow" class="${className}__arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" /></marker></defs>`
662
+ );
655
663
  const links = layout.links.map((link) => renderLink(link, byId, className)).join("");
656
664
  parts.push(`<g class="${className}__links">${links}</g>`);
657
665
  for (const region of EXCALIBRAIN_REGION_ORDER) {
@@ -692,7 +700,7 @@ function renderExcaliBrainSection(input) {
692
700
  ].join("");
693
701
  }
694
702
  function renderNode(node, className) {
695
- const box = `<rect class="${className}__node-box" x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="4" />`;
703
+ const box = `<rect class="${className}__node-box" x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="8" />`;
696
704
  const label = `<text class="${className}__node-label" x="${round(
697
705
  node.x + node.width / 2
698
706
  )}" y="${round(node.y + node.height / 2)}" text-anchor="middle" dominant-baseline="middle">${escapeHtml(node.title)}</text>`;
@@ -711,8 +719,12 @@ function renderLink(link, byId, className) {
711
719
  const from = byId.get(link.from);
712
720
  const to = byId.get(link.to);
713
721
  if (!from || !to) return "";
714
- const d = `M ${round(from.x + from.width / 2)} ${round(from.y + from.height / 2)} L ${round(to.x + to.width / 2)} ${round(to.y + to.height / 2)}`;
715
- return `<path class="${className}__link" data-link-role="${ROLE_ATTRIBUTE[link.role]}" data-relation-type="${link.relationType}" d="${d}" />`;
722
+ const fromX = from.x + from.width / 2;
723
+ const fromY = from.y + from.height / 2;
724
+ const toX = to.x + to.width / 2;
725
+ const toY = to.y + to.height / 2;
726
+ const d = `M ${round(fromX)} ${round(fromY)} L ${round(toX)} ${round(toY)}`;
727
+ return `<path class="${className}__link" data-link-role="${ROLE_ATTRIBUTE[link.role]}" data-relation-type="${link.relationType}" marker-end="url(#${className}-arrow)" d="${d}" />`;
716
728
  }
717
729
  function round(value) {
718
730
  return Math.round(value * 100) / 100;
@@ -802,14 +814,12 @@ function excaliBrain(options = {}) {
802
814
  ]
803
815
  });
804
816
  }
805
- var excaliBrainPlugin = excaliBrain;
806
817
  export {
807
818
  DEFAULT_ONTOLOGY,
808
819
  buildExcaliBrainGraph,
809
820
  collectDefinedRelations,
810
821
  collectHiddenTargets,
811
822
  excaliBrain,
812
- excaliBrainPlugin,
813
823
  layoutExcaliBrain,
814
824
  normalizeFieldName,
815
825
  renderExcaliBrainSection,
@@ -1,9 +1,7 @@
1
1
  import type { ExcaliBrainNodeRole, ExcaliBrainOntology } from "./types.js";
2
- export type ExcaliBrainFieldRole = "parents" | "children" | "leftFriends" | "rightFriends" | "previous" | "next" | "hidden";
2
+ type ExcaliBrainFieldRole = "parents" | "children" | "leftFriends" | "rightFriends" | "previous" | "next" | "hidden";
3
3
  /** ExcaliBrain's default ontology field names. */
4
4
  export declare const DEFAULT_ONTOLOGY: Required<ExcaliBrainOntology>;
5
- /** Canonical processing order; earlier roles win when a target is listed twice. */
6
- export declare const FIELD_ROLE_ORDER: readonly ExcaliBrainFieldRole[];
7
5
  export type ResolvedOntology = {
8
6
  /** Normalized field name to ontology role. */
9
7
  fieldRole: Map<string, ExcaliBrainFieldRole>;
@@ -15,7 +13,6 @@ export type DefinedRelation = {
15
13
  /** Lowercase a field name and normalize spaces to hyphens. */
16
14
  export declare function normalizeFieldName(value: string): string;
17
15
  export declare function resolveOntology(overrides?: ExcaliBrainOntology): ResolvedOntology;
18
- export declare function fieldRoleOf(field: string, ontology: ResolvedOntology): ExcaliBrainFieldRole | null;
19
16
  /**
20
17
  * Collect explicit relations from YAML frontmatter and dataview inline fields.
21
18
  * Results follow {@link FIELD_ROLE_ORDER} so defined relations are deterministic.
@@ -39,3 +36,4 @@ export declare function collectHiddenTargets(input: {
39
36
  export declare function extractWikilinkTargets(value: string): string[];
40
37
  /** Extract `Field:: value` pairs from the note body (frontmatter excluded). */
41
38
  export declare function extractInlineFields(markdown: string): Array<[string, string]>;
39
+ export {};
@@ -1,5 +1,3 @@
1
- export declare const EXCALIBRAIN_PLACEHOLDER_ATTRIBUTE = "data-rb-excalibrain";
2
1
  export declare function createExcaliBrainPlaceholder(): string;
3
- export declare function createExcaliBrainPlaceholderPattern(): RegExp;
4
2
  export declare function hasExcaliBrainPlaceholder(html: string): boolean;
5
3
  export declare function replaceExcaliBrainPlaceholders(html: string, replacement: string): string;
@@ -1,5 +1,5 @@
1
1
  import type { HastNode } from "./types.js";
2
- export type RehypeExcaliBrainOptions = {
2
+ type RehypeExcaliBrainOptions = {
3
3
  language?: string;
4
4
  };
5
5
  /**
@@ -7,3 +7,4 @@ export type RehypeExcaliBrainOptions = {
7
7
  * resolved against the content manifest in `onManifestCreated`.
8
8
  */
9
9
  export declare function rehypeExcaliBrain(options?: RehypeExcaliBrainOptions): (tree: HastNode) => void;
10
+ export {};
@@ -1,5 +1,5 @@
1
1
  import type { ExcaliBrainGraph, ExcaliBrainLayout, ExcaliBrainOptions, ExcaliBrainRenderMode } from "./types.js";
2
- export type ExcaliBrainSectionInput = {
2
+ type ExcaliBrainSectionInput = {
3
3
  graph: ExcaliBrainGraph;
4
4
  layout: ExcaliBrainLayout;
5
5
  options?: ExcaliBrainOptions;
@@ -9,3 +9,4 @@ export type ExcaliBrainSectionInput = {
9
9
  export declare function renderExcaliBrainSvg(graph: ExcaliBrainGraph, layout: ExcaliBrainLayout, options?: ExcaliBrainOptions): string;
10
10
  /** Render the `<section>` wrapper, with inline SVG and/or a client canvas. */
11
11
  export declare function renderExcaliBrainSection(input: ExcaliBrainSectionInput): string;
12
+ export {};
@@ -110,11 +110,11 @@ export type ElementNode = {
110
110
  properties?: Record<string, unknown>;
111
111
  children?: HastNode[];
112
112
  };
113
- export type TextNode = {
113
+ type TextNode = {
114
114
  type: "text";
115
115
  value: string;
116
116
  };
117
- export type RawNode = {
117
+ type RawNode = {
118
118
  type: "raw";
119
119
  value: string;
120
120
  };
@@ -122,3 +122,4 @@ export type HastNode = ElementNode | TextNode | RawNode | {
122
122
  type: string;
123
123
  [key: string]: unknown;
124
124
  };
125
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-excalibrain",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,11 +21,11 @@
21
21
  "./style.css": "./style.css"
22
22
  },
23
23
  "dependencies": {
24
- "@riebeckite/core": "0.0.31"
24
+ "@riebeckite/core": "0.0.33"
25
25
  },
26
26
  "devDependencies": {
27
- "tsx": "^4.22.4",
28
- "@riebeckite/test": "0.0.31"
27
+ "@riebeckite/test": "0.0.33",
28
+ "tsx": "^4.22.4"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
package/style.css CHANGED
@@ -3,6 +3,11 @@
3
3
  --rb-excalibrain-paper: var(--rb-color-paper, #ffffff);
4
4
  --rb-excalibrain-muted: var(--rb-color-muted, #69645c);
5
5
  --rb-excalibrain-accent: var(--rb-color-accent, #686868);
6
+ --rb-excalibrain-parent: #7656b5;
7
+ --rb-excalibrain-child: #16856f;
8
+ --rb-excalibrain-left-friend: #2776b7;
9
+ --rb-excalibrain-right-friend: #c05a2b;
10
+ --rb-excalibrain-sibling: #a55c96;
6
11
  --rb-excalibrain-rule: var(
7
12
  --rb-color-border,
8
13
  color-mix(in srgb, var(--rb-excalibrain-ink) 18%, transparent)
@@ -27,8 +32,12 @@
27
32
 
28
33
  .rb-excalibrain__canvas {
29
34
  overflow: auto;
30
- border: 1px solid var(--rb-excalibrain-rule);
35
+ border: 1px solid
36
+ color-mix(in srgb, var(--rb-excalibrain-rule) 72%, transparent);
37
+ border-radius: 0.5rem;
31
38
  background: var(--rb-excalibrain-surface);
39
+ box-shadow: inset 0 1px
40
+ color-mix(in srgb, var(--rb-excalibrain-paper) 75%, transparent);
32
41
  }
33
42
 
34
43
  .rb-excalibrain__svg {
@@ -40,25 +49,75 @@
40
49
 
41
50
  .rb-excalibrain__link {
42
51
  fill: none;
43
- stroke: var(--rb-excalibrain-rule);
44
- stroke-width: 1.25;
52
+ stroke: var(--rb-excalibrain-accent);
53
+ stroke-width: 1.5;
54
+ stroke-linecap: round;
55
+ opacity: 0.72;
56
+ }
57
+
58
+ .rb-excalibrain__arrow {
59
+ fill: context-stroke;
60
+ }
61
+
62
+ .rb-excalibrain__link[data-link-role="parent"] {
63
+ stroke: var(--rb-excalibrain-parent);
64
+ }
65
+
66
+ .rb-excalibrain__link[data-link-role="child"] {
67
+ stroke: var(--rb-excalibrain-child);
68
+ }
69
+
70
+ .rb-excalibrain__link[data-link-role="left-friend"] {
71
+ stroke: var(--rb-excalibrain-left-friend);
72
+ }
73
+
74
+ .rb-excalibrain__link[data-link-role="right-friend"] {
75
+ stroke: var(--rb-excalibrain-right-friend);
76
+ }
77
+
78
+ .rb-excalibrain__link[data-link-role="sibling"] {
79
+ stroke: var(--rb-excalibrain-sibling);
45
80
  }
46
81
 
47
82
  .rb-excalibrain__link[data-relation-type="defined"] {
48
- stroke: var(--rb-excalibrain-accent);
83
+ opacity: 1;
49
84
  }
50
85
 
51
86
  .rb-excalibrain__node-box {
52
87
  fill: var(--rb-excalibrain-paper);
53
- stroke: var(--rb-excalibrain-rule);
88
+ stroke: color-mix(in srgb, var(--rb-excalibrain-ink) 22%, transparent);
54
89
  stroke-width: 1.25;
90
+ filter: drop-shadow(
91
+ 0 1px 1px color-mix(in srgb, var(--rb-excalibrain-ink) 16%, transparent)
92
+ );
55
93
  }
56
94
 
57
95
  .rb-excalibrain__node[data-node-role="center"] .rb-excalibrain__node-box {
96
+ fill: var(--rb-excalibrain-ink);
58
97
  stroke: var(--rb-excalibrain-ink);
59
98
  stroke-width: 2;
60
99
  }
61
100
 
101
+ .rb-excalibrain__node[data-node-role="parent"] .rb-excalibrain__node-box {
102
+ stroke: var(--rb-excalibrain-parent);
103
+ }
104
+
105
+ .rb-excalibrain__node[data-node-role="child"] .rb-excalibrain__node-box {
106
+ stroke: var(--rb-excalibrain-child);
107
+ }
108
+
109
+ .rb-excalibrain__node[data-node-role="left-friend"] .rb-excalibrain__node-box {
110
+ stroke: var(--rb-excalibrain-left-friend);
111
+ }
112
+
113
+ .rb-excalibrain__node[data-node-role="right-friend"] .rb-excalibrain__node-box {
114
+ stroke: var(--rb-excalibrain-right-friend);
115
+ }
116
+
117
+ .rb-excalibrain__node[data-node-role="sibling"] .rb-excalibrain__node-box {
118
+ stroke: var(--rb-excalibrain-sibling);
119
+ }
120
+
62
121
  .rb-excalibrain__node[data-node-virtual="true"] .rb-excalibrain__node-box {
63
122
  fill: none;
64
123
  stroke-dasharray: 4 3;
@@ -69,6 +128,11 @@
69
128
  font-size: 0.8125rem;
70
129
  }
71
130
 
131
+ .rb-excalibrain__node[data-node-role="center"] .rb-excalibrain__node-label {
132
+ fill: var(--rb-excalibrain-paper);
133
+ font-weight: 700;
134
+ }
135
+
72
136
  .rb-excalibrain__node-link {
73
137
  text-decoration: none;
74
138
  }