@unson/brainbase-mcp 0.41.10 → 0.41.13

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.
@@ -364,6 +364,38 @@
364
364
  margin-top: 14px;
365
365
  }
366
366
 
367
+ /* 根拠と履歴: one fold per record, after its relations (ledger D14). */
368
+ .bb-graph-rail > .bb-graph-evidence {
369
+ border-bottom: 1px solid var(--bb-color-border);
370
+ padding-block: 18px;
371
+ font-size: 13px;
372
+ }
373
+
374
+ .bb-graph-evidence > summary {
375
+ display: flex;
376
+ align-items: center;
377
+ gap: var(--bb-space-2);
378
+ color: var(--bb-color-ink);
379
+ font-weight: 690;
380
+ cursor: pointer;
381
+ }
382
+
383
+ .bb-graph-evidence-part {
384
+ margin-top: var(--bb-space-3);
385
+ }
386
+
387
+ .bb-graph-evidence-part > h4 {
388
+ margin: 0 0 var(--bb-space-1);
389
+ color: var(--bb-color-muted);
390
+ font-size: 12px;
391
+ font-weight: 690;
392
+ }
393
+
394
+ .bb-graph-evidence-part > p {
395
+ margin: 0 0 var(--bb-space-1);
396
+ overflow-wrap: anywhere;
397
+ }
398
+
367
399
  .bb-graph-rail > .bb-graph-history {
368
400
  border-bottom: 1px solid var(--bb-color-border);
369
401
  padding-block: 18px;
@@ -38,6 +38,45 @@ export const GRAPH_ENTITY_TYPE_LABELS = Object.freeze({
38
38
  org: '組織',
39
39
  project: 'プロジェクト',
40
40
  decision: '判断',
41
+ // The kinds an organization's Graph defines on top of the local four, so the
42
+ // screens never show an internal type id (ledger D14).
43
+ app: 'アプリ',
44
+ product: 'プロダクト',
45
+ brand: 'ブランド',
46
+ customer: '顧客',
47
+ partner: '協業先',
48
+ contact: '名刺の連絡先',
49
+ raci: '責任分担表',
50
+ raci_assignment: '責任の割り当て',
51
+ role_assignment: '役割',
52
+ glossary_term: '用語',
53
+ document: '文書',
54
+ frame: '考え方の枠組み',
55
+ story: 'ストーリー',
56
+ infrastructure_environment: '稼働環境',
57
+ speaking: '登壇',
58
+ media_appearance: 'メディア出演',
59
+ publication: '出版物',
60
+ press_mention: '報道',
61
+ initiative: '施策',
62
+ ai_query: 'AIへの問い合わせ',
63
+ ai_decision: 'AIを使った判断',
64
+ philosophy: '哲学',
65
+ capital: '資本',
66
+ contract: '契約',
67
+ database: 'データベース',
68
+ database_cluster: 'データベースのクラスタ',
69
+ diagnosis: '診断',
70
+ finance: '財務',
71
+ finance_account: '財務の口座',
72
+ org_alias: '組織の別名',
73
+ organization: '組織(旧い形式)',
74
+ person_alias: '人物の別名',
75
+ push_case: '推進案件',
76
+ objective: '目的',
77
+ variable: '変数',
78
+ model: '世界モデル',
79
+ constraint: '制約',
41
80
  });
42
81
 
43
82
  export const GRAPH_ENTITY_TYPE_MEANINGS = Object.freeze({
@@ -51,14 +90,72 @@ export const GRAPH_ENTITY_TYPE_MEANINGS = Object.freeze({
51
90
  * `outgoing` follows the counterpart name when this record is the start of the
52
91
  * relation; `incoming` follows it when this record is the end.
53
92
  */
93
+ const relation = (label, meaning, outgoing, incoming) => Object.freeze({ label, meaning, outgoing, incoming });
94
+
95
+ /*
96
+ * Every relation of the local Graph and of an organization's Graph has a plain
97
+ * Japanese name (ledger D14); a relation id is shown only in the details.
98
+ * Relations that mean the same to a reader share one name (所有 for owns and
99
+ * owned_by, 所属 for member_of and belongs_to), and a list of relation kinds
100
+ * shows them as one row (`groupRelationKinds`).
101
+ */
54
102
  export const GRAPH_RELATION_LABELS = Object.freeze({
55
- member_of: Object.freeze({ label: '所属', meaning: '人物が組織に所属している', outgoing: 'に所属', incoming: 'が所属' }),
56
- participates_in: Object.freeze({ label: '参加', meaning: '人物がプロジェクトに参加している', outgoing: 'に参加', incoming: 'が参加' }),
57
- accountable_for: Object.freeze({ label: '責任', meaning: '人物がプロジェクトの成果や判断に責任を持つ', outgoing: 'に責任を持つ', incoming: 'が責任を持つ' }),
58
- owned_by: Object.freeze({ label: '所有', meaning: 'プロジェクトを組織が所有している', outgoing: 'が所有', incoming: 'を所有' }),
59
- related_to: Object.freeze({ label: '関わる', meaning: '会社が顧客・協業先などとしてプロジェクトに関わっている', outgoing: 'に関わる', incoming: 'が関わる' }),
60
- governs: Object.freeze({ label: '方針', meaning: '判断や原則がプロジェクトの進め方を決める', outgoing: 'の進め方を決める', incoming: 'が進め方を決める' }),
61
- supersedes: Object.freeze({ label: '置き換え', meaning: '判断が以前の判断を置き換える', outgoing: 'を置き換える', incoming: 'に置き換えられた' }),
103
+ member_of: relation('所属', '人物が組織やプロジェクトに所属している', 'に所属', 'が所属'),
104
+ belongs_to: relation('所属', '記録が組織・プロダクト・ブランド・プロジェクトに含まれる', 'に所属', 'が所属'),
105
+ belongs_to_project: relation('所属', '記録がプロジェクトに含まれる', 'に所属', 'が所属'),
106
+ participates_in: relation('参加', '人物がプロジェクトに参加している', 'に参加', 'が参加'),
107
+ accountable_for: relation('責任', '人物や組織が成果や判断に最終的な責任を持つ', 'に責任を持つ', 'が責任を持つ'),
108
+ owned_by: relation('所有', 'プロジェクトなどを組織や人が所有している', 'が所有', 'を所有'),
109
+ owns: relation('所有', '組織がアプリ・プロダクト・ブランド・プロジェクトを所有している', 'を所有', 'が所有'),
110
+ owns_app: relation('所有', 'プロジェクトがアプリを持っている(旧い形式)', 'を所有', 'が所有'),
111
+ related_to: relation('関わる', '会社が顧客・協業先などとしてプロジェクトに関わっている', 'に関わる', 'が関わる'),
112
+ governs: relation('進め方を決める', '判断や原則が、対象の進め方を決める', 'の進め方を決める', 'が進め方を決める'),
113
+ governed_by: relation('従う原則', '推進案件が従う原則', 'に従う', 'が従う'),
114
+ supersedes: relation('置き換え', '判断が以前の判断を置き換える', 'を置き換える', 'に置き換えられた'),
115
+ superseded_by: relation('同一人物に統合', '古い人物の記録を、正しい人物の記録へまとめた', 'へ統合', 'を統合'),
116
+ derived_from: relation('由来', '記録が別の記録をもとにしている', 'に由来', 'が由来とする'),
117
+ depends_on: relation('依存', '稼働や成果が別の記録に依存している', 'に依存', 'が依存'),
118
+ assigned_to: relation('責任の割り当て', '責任分担で、人や組織に責任を割り当てている', 'に割り当て', 'で割り当て'),
119
+ requested_by: relation('問い合わせた人', 'AIへの問い合わせをした人', 'が問い合わせた', 'を問い合わせた'),
120
+ made_by: relation('判断した人', '判断をした人', 'が判断した', 'を判断した'),
121
+ references: relation('根拠として参照', '判断や問い合わせが、根拠として別の記録を参照している', 'を参照', 'が参照'),
122
+ evidenced_by: relation('根拠の文書', '判断の根拠になった文書', 'を根拠にする', 'が根拠にする'),
123
+ informs: relation('判断材料', '文書がプロジェクトの判断材料になる', 'の判断材料', 'が判断材料'),
124
+ mentions: relation('言及', '判断が協業先やプロダクトに言及している', 'に言及', 'が言及'),
125
+ alias_of: relation('別名', '人や組織の別の呼び名', 'の別名', 'が別名'),
126
+ applies_to: relation('適用先', '文書が適用される組織', 'に適用', 'が適用'),
127
+ describes: relation('説明', '文書が組織を説明している', 'を説明', 'が説明'),
128
+ brand_of: relation('ブランドの対象', 'ブランドが表す組織やプロジェクト', 'のブランド', 'がブランド'),
129
+ sub_brand_of: relation('上位ブランド', 'ブランドの上位にあるブランド', 'の下位ブランド', 'が下位ブランド'),
130
+ operates: relation('運営', '組織が運営している', 'を運営', 'が運営'),
131
+ operated_by: relation('運営', '組織が運営している', 'が運営', 'を運営'),
132
+ covers_engagement: relation('責任分担の対象', '責任分担表が対象とする組織や案件', 'の責任分担', 'が責任分担を示す'),
133
+ describes_org: relation('責任分担の対象', '責任分担表が対象とする組織や案件', 'の責任分担', 'が責任分担を示す'),
134
+ has_raci: relation('責任分担表', '組織やプロジェクトが持つ責任分担表', 'を持つ', 'が持つ'),
135
+ has_project: relation('含む', 'プロジェクトが子プロジェクト・案件・施策を含む', 'を含む', 'に含まれる'),
136
+ has_engagement: relation('含む', 'プロジェクトが子プロジェクト・案件・施策を含む', 'を含む', 'に含まれる'),
137
+ has_initiative: relation('含む', 'プロジェクトが子プロジェクト・案件・施策を含む', 'を含む', 'に含まれる'),
138
+ relates_to_project: relation('関連', 'プロジェクトどうしが関連している', 'と関連', 'と関連'),
139
+ serves_customer: relation('価値を届ける顧客', 'プロジェクトが価値を届ける顧客', 'に価値を届ける', 'が価値を届ける'),
140
+ org_unit_of: relation('上位の顧客', '部署が属する顧客の会社', 'の部署', 'が部署'),
141
+ supports_project: relation('支援', '協業先がプロジェクトを運営する組織を支援している', 'を支援', 'が支援'),
142
+ key_contact_for: relation('主な窓口', 'ブランドや推進案件の主な窓口', 'の主な窓口', 'が主な窓口'),
143
+ primary_contact_for: relation('主な窓口', 'ブランドや推進案件の主な窓口', 'の主な窓口', 'が主な窓口'),
144
+ has_push_case: relation('推進案件', '顧客について進めている推進案件', 'を推進案件に持つ', 'の推進案件'),
145
+ has_diagnosis: relation('診断', '推進案件についての診断', 'を持つ', 'が持つ'),
146
+ role_at: relation('役割', '人物の役割と、その役割の所属先', 'での役割', 'がある'),
147
+ holds_role: relation('役割', '人物の役割と、その役割の所属先', 'を持つ', 'が持つ'),
148
+ uses_app: relation('利用', 'プロジェクトやアプリが、アプリやデータベースを使う', 'を使う', 'が使う'),
149
+ uses_database: relation('利用', 'プロジェクトやアプリが、アプリやデータベースを使う', 'を使う', 'が使う'),
150
+ has_environment: relation('稼働環境', 'プロジェクトが稼働環境として持つアプリ', 'を稼働環境に持つ', 'の稼働環境'),
151
+ hosted_on: relation('置き場所', 'データベースが置かれているクラスタ', 'に置かれている', 'が置かれている'),
152
+ uses_secret_store: relation('秘密情報の保管先', 'アプリが使う(または使うべき)秘密情報の保管先', 'を保管先に使う', 'が保管先に使う'),
153
+ should_use_secret_store: relation('秘密情報の保管先', 'アプリが使う(または使うべき)秘密情報の保管先', 'を保管先に使うべき', 'が保管先に使うべき'),
154
+ created: relation('生み出した', '人物がプロダクトを生み出した', 'を生み出した', 'が生み出した'),
155
+ authored: relation('著作', '人物が出版物を著した', 'を著した', 'が著した'),
156
+ spoke_at: relation('登壇', '人物が登壇した', 'で登壇', 'が登壇'),
157
+ appeared_in: relation('出演', '人物がメディアに出演した', 'に出演', 'が出演'),
158
+ mentioned_in: relation('掲載', '人物が報道に掲載された', 'に掲載', 'が掲載'),
62
159
  });
63
160
 
64
161
  /** Relations a correction may add (the host refuses any other). */
@@ -213,9 +310,9 @@ export function facts(doc, rows, className = 'bb-graph-facts') {
213
310
  }
214
311
 
215
312
  /** Ids and digests stay in this disclosure, never in the visible copy. */
216
- export function recordDetails(doc, rows) {
313
+ export function recordDetails(doc, rows, { title = '記録の詳細' } = {}) {
217
314
  const details = makeElement(doc, 'details', { className: 'bb-graph-audit' });
218
- details.append(makeElement(doc, 'summary', { text: '記録の詳細' }), facts(doc, rows, 'bb-graph-facts is-mono'));
315
+ details.append(makeElement(doc, 'summary', { text: title }), facts(doc, rows, 'bb-graph-facts is-mono'));
219
316
  return details;
220
317
  }
221
318
 
@@ -307,9 +404,33 @@ export function ownLabel(table, key) {
307
404
  return typeof key === 'string' && Object.hasOwn(table, key) ? table[key] : undefined;
308
405
  }
309
406
 
310
- /** A relation's plain label; an unknown relation shows its raw id. */
311
- export function relationLabel(relation) {
312
- return ownLabel(GRAPH_RELATION_LABELS, relation)?.label ?? relation;
407
+ /**
408
+ * A relation's plain label. An unknown relation shows the meaning its host
409
+ * gave (when there is one) rather than its raw id.
410
+ */
411
+ export function relationLabel(relation, meaning) {
412
+ return ownLabel(GRAPH_RELATION_LABELS, relation)?.label ?? textOrNull(meaning) ?? relation;
413
+ }
414
+
415
+ /**
416
+ * The relation kinds of an ontology answer as rows a reader can tell apart:
417
+ * kinds with the same plain name are one row (所有 for owns, owned_by and
418
+ * owns_app), and each row keeps every kind with its start and end kinds. Rows
419
+ * keep the order in which their first kind appears.
420
+ */
421
+ export function groupRelationKinds(relations) {
422
+ const rows = new Map();
423
+ for (const item of Array.isArray(relations) ? relations : []) {
424
+ if (!isRecord(item) || typeof item.id !== 'string') continue;
425
+ const known = ownLabel(GRAPH_RELATION_LABELS, item.id);
426
+ const label = relationLabel(item.id, item.meaning);
427
+ const row = rows.get(label) ?? { label, meanings: [], kinds: [] };
428
+ const meaning = known?.meaning ?? textOrNull(item.meaning);
429
+ if (meaning && !row.meanings.includes(meaning)) row.meanings.push(meaning);
430
+ row.kinds.push(item);
431
+ rows.set(label, row);
432
+ }
433
+ return [...rows.values()];
313
434
  }
314
435
 
315
436
  /** A type's plain label; an unknown type (from another host's Graph) shows its raw id. */
@@ -620,6 +741,59 @@ export function renderGraphIssues(doc, issues) {
620
741
  });
621
742
  }
622
743
 
744
+ /**
745
+ * 根拠と履歴 of one record, folded: where the record came from (the host's 出典
746
+ * notice, which may carry its authorization), the source or correction records
747
+ * that could not be read, and the corrections made. None of these is a notice
748
+ * for the whole screen (ledger D14); records that could not be read are counted
749
+ * on the fold itself so they are not hidden.
750
+ *
751
+ * @param {Document} doc
752
+ * @param {{ source?: string | Element | null, issues?: unknown[], history?: unknown[] }} parts
753
+ */
754
+ export function renderEvidenceAndHistory(doc, { source = null, issues = [], history = [] } = {}) {
755
+ const unreadable = (Array.isArray(issues) ? issues : []).filter(isRecord);
756
+ const corrections = (Array.isArray(history) ? history : []).filter(isRecord);
757
+ const details = makeElement(doc, 'details', { className: 'bb-graph-evidence' });
758
+ const summary = makeElement(doc, 'summary', { text: '根拠と履歴' });
759
+ if (unreadable.length > 0) summary.append(badge(doc, `読めない記録 ${unreadable.length}件`, 'warning'));
760
+ details.append(summary);
761
+ const section = (title, ...children) => {
762
+ const block = makeElement(doc, 'section', { className: 'bb-graph-evidence-part' });
763
+ block.append(makeElement(doc, 'h4', { text: title }), ...children.filter(Boolean));
764
+ details.append(block);
765
+ };
766
+ if (source) {
767
+ const body = typeof source === 'object' && typeof source.tagName === 'string' ? source : makeElement(doc, 'p', { text: String(source) });
768
+ section('出どころ', body);
769
+ }
770
+ if (unreadable.length > 0) {
771
+ const list = makeElement(doc, 'ul', { className: 'bb-graph-issue-list' });
772
+ for (const issue of unreadable) {
773
+ const where = `${String(issue.file ?? '不明')}${Number.isInteger(issue.line) ? `(${issue.line}行目)` : ''}`;
774
+ list.append(makeElement(doc, 'li', { text: `${where}: ${String(issue.reason ?? '理由不明')}` }));
775
+ }
776
+ section(
777
+ '読めない記録',
778
+ makeElement(doc, 'p', { text: `この記録の出典や訂正の履歴のうち、壊れていて読めない記録が${unreadable.length}件あります。表示している内容は読めた記録だけから作っているため、最後の訂正や出典が抜けているかもしれません。` }),
779
+ list,
780
+ );
781
+ }
782
+ if (corrections.length > 0) {
783
+ const list = makeElement(doc, 'ol', { className: 'bb-graph-history-list' });
784
+ for (const record of corrections) {
785
+ const fields = Array.isArray(record.changedFields) ? record.changedFields.map((field) => FIELD_LABELS[field] ?? field).join('・') : '';
786
+ list.append(makeElement(doc, 'li', {
787
+ text: `${formatDateTime(record.at)} ${CORRECTION_KIND_LABELS[record.kind] ?? '直した'}${fields ? `(${fields})` : ''}。理由: ${String(record.reason ?? '')}`,
788
+ }));
789
+ }
790
+ section(`訂正の履歴(${corrections.length}件)`, list);
791
+ } else if (Array.isArray(history)) {
792
+ section('訂正の履歴', makeElement(doc, 'p', { className: 'bb-graph-empty', text: 'この記録は、まだ訂正されていません。' }));
793
+ }
794
+ return details;
795
+ }
796
+
623
797
  // ---------------------------------------------------------------------------
624
798
  // Layout
625
799
 
@@ -662,6 +836,11 @@ export function createGraphLayout(doc, { root, rail, label, className, contractV
662
836
  surface.append(...workspaceChildren.filter(Boolean));
663
837
  const detail = makeElement(doc, 'div', { className: `bb-graph-rail ${className}-rail` });
664
838
  detail.append(...railChildren.filter(Boolean));
839
+ // A view with nothing for the rail (its detail is inside the workspace) draws no inline rail.
840
+ if (!rail && !railChildren.some(Boolean)) {
841
+ root.replaceChildren(surface);
842
+ return;
843
+ }
665
844
  if (rail) {
666
845
  root.replaceChildren(surface);
667
846
  rail.replaceChildren(detail);
@@ -292,7 +292,7 @@
292
292
  }
293
293
 
294
294
  .bb-jh-ledger .bb-ws-ledger-row {
295
- grid-template-columns: 92px minmax(0, 1fr) 250px 105px;
295
+ grid-template-columns: 92px minmax(0, 1fr) 250px 120px;
296
296
  align-items: center;
297
297
  min-height: 52px;
298
298
  }
@@ -581,7 +581,7 @@
581
581
  .bb-jh-ledger .bb-ws-ledger-row > span:nth-child(1)::before { content: '日時'; }
582
582
  .bb-jh-ledger .bb-ws-ledger-row > span:nth-child(2)::before { content: '行った判断'; }
583
583
  .bb-jh-ledger .bb-ws-ledger-row > span:nth-child(3)::before { content: '使った参照'; }
584
- .bb-jh-ledger .bb-ws-ledger-row > span:nth-child(4)::before { content: '入口・状態'; }
584
+ .bb-jh-ledger .bb-ws-ledger-row > span:nth-child(4)::before { content: '判断したAI'; }
585
585
  }
586
586
 
587
587
  /* Compact workspace header, search controls and shared floating notifications. */
@@ -617,3 +617,156 @@
617
617
  }
618
618
  .bb-jh-notifications .bb-jh-banner.is-danger { border-left-color: var(--bb-color-notice-danger); }
619
619
  .bb-jh-notifications .bb-jh-banner-sources > span { white-space: normal; }
620
+
621
+ /* Loading stays in the page, like the other workspace screens. */
622
+ .bb-jh-loading { color: var(--bb-color-muted); }
623
+ .bb-jh-summary-note { font-size: 11.5px; }
624
+ .bb-jh-entrypoint { display: grid; gap: 2px; }
625
+ .bb-jh-entrypoint small.bb-jh-waiting { color: var(--bb-color-warning-strong, var(--bb-color-accent-strong)); font-size: 11px; font-weight: 600; }
626
+ .bb-jh-filter-fields .bb-jh-filter .bb-ws-combobox { width: 100%; }
627
+
628
+ /* Detail: references that only have an id, the one question, and the record details. */
629
+ .bb-jh-references { display: grid; gap: 8px; }
630
+ .bb-jh-reference-list small { color: var(--bb-color-quiet); font-size: 11px; }
631
+ .bb-jh-reference-kinds { margin: 0; color: var(--bb-color-ink); font-size: 13px; font-weight: 600; }
632
+ .bb-jh-references .bb-jh-reference-note,
633
+ .bb-jh-handoff .bb-jh-reference-note { margin: 0; }
634
+ .bb-jh-feedback { display: grid; gap: 12px; }
635
+ .bb-jh-feedback-events { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
636
+ .bb-jh-feedback-answers { display: flex; flex-wrap: wrap; gap: 6px; }
637
+ .bb-jh-feedback-composer > .bb-ws-button { justify-self: start; }
638
+ .bb-jh-record-details { margin-top: 10px; }
639
+ .bb-jh-record-details > summary { color: var(--bb-color-muted); font-size: 12px; cursor: pointer; }
640
+ .bb-jh-record-details[open] > summary { margin-bottom: 8px; }
641
+ .bb-jh-record-details .bb-ws-definition dd { overflow-wrap: anywhere; }
642
+ .bb-jh-id-list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; font-family: var(--bb-font-mono); font-size: 10.5px; color: var(--bb-color-quiet); overflow-wrap: anywhere; }
643
+ .bb-jh-handoff { display: grid; gap: 6px; margin-top: 14px; }
644
+ .bb-jh-handoff h4 { margin: 0; font-size: 12.5px; color: var(--bb-color-ink); }
645
+ .bb-jh-feedback-answers .bb-ws-button[aria-pressed="true"] { border-color: var(--bb-color-accent); background: var(--bb-color-accent-soft, #eeebfd); color: var(--bb-color-accent-strong, var(--bb-color-accent)); }
646
+ .bb-jh-feedback-composer [data-action="submit-judgment-feedback"] { border-color: var(--bb-color-accent); background: var(--bb-color-accent); color: #fff; }
647
+ .bb-jh-feedback-composer [data-action="submit-judgment-feedback"]:disabled { opacity: .55; cursor: default; }
648
+ .bb-jh-feedback-composer textarea,
649
+ .bb-jh-reference-export textarea { box-sizing: border-box; }
650
+
651
+ /* 判断の根拠と本人の考え (story-judgment-history-frame-basis-v1) */
652
+ .bb-jh-basis {
653
+ display: grid;
654
+ gap: 14px;
655
+ }
656
+
657
+ .bb-jh-basis-group {
658
+ display: grid;
659
+ gap: 6px;
660
+ min-width: 0;
661
+ }
662
+
663
+ .bb-jh-basis-group h4 {
664
+ margin: 0;
665
+ color: var(--bb-color-muted);
666
+ font-size: 11px;
667
+ font-weight: 680;
668
+ letter-spacing: 0.04em;
669
+ }
670
+
671
+ .bb-jh-basis-list {
672
+ display: grid;
673
+ gap: 10px;
674
+ margin: 0;
675
+ padding: 0;
676
+ list-style: none;
677
+ }
678
+
679
+ .bb-jh-basis-list li {
680
+ display: grid;
681
+ gap: 3px;
682
+ min-width: 0;
683
+ padding-left: 10px;
684
+ border-left: 2px solid var(--bb-color-border);
685
+ }
686
+
687
+ .bb-jh-basis-list strong {
688
+ color: var(--bb-color-ink);
689
+ font-size: 13px;
690
+ line-height: 1.45;
691
+ overflow-wrap: anywhere;
692
+ }
693
+
694
+ .bb-jh-basis-list strong.bb-jh-unrecorded {
695
+ color: var(--bb-color-quiet);
696
+ font-weight: 500;
697
+ }
698
+
699
+ .bb-jh-basis-usage {
700
+ color: var(--bb-color-muted);
701
+ font-size: 12px;
702
+ line-height: 1.5;
703
+ }
704
+
705
+ .bb-jh-basis-usage.is-violated,
706
+ .bb-jh-basis-usage.is-failed {
707
+ color: var(--bb-color-danger);
708
+ }
709
+
710
+ .bb-jh-basis-usage.is-tension {
711
+ color: var(--bb-color-warning);
712
+ }
713
+
714
+ .bb-jh-basis-usage.is-unrecorded {
715
+ color: var(--bb-color-quiet);
716
+ }
717
+
718
+ .bb-jh-basis-why {
719
+ color: var(--bb-color-muted);
720
+ font-size: 12px;
721
+ line-height: 1.5;
722
+ }
723
+
724
+ .bb-jh-basis-list small {
725
+ color: var(--bb-color-quiet);
726
+ font-size: 11px;
727
+ }
728
+
729
+ .bb-jh-owner {
730
+ display: grid;
731
+ gap: 4px;
732
+ padding: 10px 12px;
733
+ border: 1px solid var(--bb-color-border);
734
+ border-radius: var(--bb-radius-sm);
735
+ background: var(--bb-color-panel);
736
+ }
737
+
738
+ .bb-jh-owner.is-applied {
739
+ border-color: var(--bb-color-accent);
740
+ background: var(--bb-color-accent-soft);
741
+ }
742
+
743
+ .bb-jh-owner strong {
744
+ color: var(--bb-color-ink);
745
+ font-size: 13px;
746
+ line-height: 1.5;
747
+ }
748
+
749
+ .bb-jh-owner p {
750
+ margin: 0;
751
+ color: var(--bb-color-muted);
752
+ font-size: 12px;
753
+ line-height: 1.5;
754
+ }
755
+
756
+ .bb-jh-owner-badge {
757
+ width: fit-content;
758
+ padding: 1px 7px;
759
+ border: 1px solid var(--bb-color-border);
760
+ border-radius: 999px;
761
+ color: var(--bb-color-quiet);
762
+ font-size: 11px;
763
+ line-height: 1.6;
764
+ white-space: nowrap;
765
+ }
766
+
767
+ .bb-jh-owner-badge.is-applied {
768
+ border-color: var(--bb-color-accent);
769
+ background: var(--bb-color-accent-soft);
770
+ color: var(--bb-color-accent-strong);
771
+ font-weight: 680;
772
+ }