@repobit/dex-system-design 0.24.4 → 0.24.6

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 (72) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +4 -4
  3. package/src/components/accordion/accordion.css.js +40 -0
  4. package/src/components/accordion/accordion.js +31 -0
  5. package/src/components/accordion/accordion.stories.js +147 -4
  6. package/src/components/agent-endpoints/agent-endpoints.css.js +92 -0
  7. package/src/components/agent-endpoints/agent-endpoints.js +86 -0
  8. package/src/components/agent-endpoints/agent-endpoints.stories.js +148 -0
  9. package/src/components/ai-guardian-demo.stories.js +848 -0
  10. package/src/components/awards/awards-flex.css.js +169 -0
  11. package/src/components/awards/awards-flex.js +269 -0
  12. package/src/components/awards/awards-flex.stories.js +657 -0
  13. package/src/components/bento-grid/bento-grid.css.js +57 -0
  14. package/src/components/bento-grid/bento-grid.js +186 -0
  15. package/src/components/bento-grid/bento-grid.stories.js +440 -0
  16. package/src/components/bento-grid/bento-item.css.js +105 -0
  17. package/src/components/bento-grid/bento-item.js +57 -0
  18. package/src/components/button/button.css.js +26 -0
  19. package/src/components/button/button.js +8 -0
  20. package/src/components/button/button.stories.js +12 -0
  21. package/src/components/comparison-panel/comparison-panel.css.js +104 -0
  22. package/src/components/comparison-panel/comparison-panel.js +100 -0
  23. package/src/components/comparison-panel/comparison-panel.stories.js +223 -0
  24. package/src/components/compatibility-table/compatibility-table.css.js +243 -0
  25. package/src/components/compatibility-table/compatibility-table.js +123 -0
  26. package/src/components/compatibility-table/compatibility-table.stories.js +189 -0
  27. package/src/components/cta-banner/cta-banner.css.js +60 -0
  28. package/src/components/cta-banner/cta-banner.js +63 -0
  29. package/src/components/dropdown/dropdown.css.js +1 -1
  30. package/src/components/footer/footer.css.js +0 -1
  31. package/src/components/header/header-code.css.js +125 -0
  32. package/src/components/header/header-code.js +69 -0
  33. package/src/components/header/header-code.stories.js +226 -0
  34. package/src/components/heading/heading.css.js +3 -0
  35. package/src/components/icons/bd-ai-icon.js +27 -0
  36. package/src/components/icons/quote-icon.js +28 -0
  37. package/src/components/install-options/install-options.css.js +276 -0
  38. package/src/components/install-options/install-options.js +184 -0
  39. package/src/components/list/list-item/list-item.css.js +3 -3
  40. package/src/components/list/list-item/list-item.js +10 -4
  41. package/src/components/overview/overview.css.js +121 -0
  42. package/src/components/overview/overview.js +63 -0
  43. package/src/components/overview/overview.stories.js +193 -0
  44. package/src/components/page-switcher/page-switcher.css.js +100 -0
  45. package/src/components/page-switcher/page-switcher.js +42 -0
  46. package/src/components/paragraph/paragraph.css.js +1 -5
  47. package/src/components/paragraph/paragraph.js +7 -3
  48. package/src/components/process-steps/process-steps.css.js +95 -0
  49. package/src/components/process-steps/process-steps.js +72 -0
  50. package/src/components/process-steps/process-steps.stories.js +144 -0
  51. package/src/components/quick-answer/quick-answer.css.js +67 -0
  52. package/src/components/quick-answer/quick-answer.js +59 -0
  53. package/src/components/quick-answer/quick-answer.stories.js +160 -0
  54. package/src/components/review/review-grid.css.js +34 -0
  55. package/src/components/review/review-grid.js +63 -0
  56. package/src/components/review/review.css.js +50 -0
  57. package/src/components/review/review.js +58 -0
  58. package/src/components/review/review.stories.js +228 -0
  59. package/src/components/terminal/terminal-cursor.js +49 -0
  60. package/src/components/terminal/terminal-message.css.js +161 -0
  61. package/src/components/terminal/terminal-message.js +169 -0
  62. package/src/components/terminal/terminal-message.stories.js +321 -0
  63. package/src/components/trust-panel/trust-panel.css.js +167 -0
  64. package/src/components/trust-panel/trust-panel.js +116 -0
  65. package/src/components/trust-panel/trust-panel.stories.js +234 -0
  66. package/src/tokens/tokens.css +1 -1
  67. package/src/components/tabsComponent/tabsComponent.css.js +0 -267
  68. package/src/components/tabsComponent/tabsComponent.js +0 -193
  69. package/src/components/tabsComponent/tabsComponent.stories.js +0 -134
  70. package/src/components/tabsComponentFamily/tabsComponentFamily.css.js +0 -181
  71. package/src/components/tabsComponentFamily/tabsComponentFamily.js +0 -180
  72. package/src/components/tabsComponentFamily/tabsComponentFamily.stories.js +0 -319
@@ -0,0 +1,276 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ font-family: var(--typography-fontFamily-sans);
7
+ }
8
+
9
+ .bd-installoptions-container {
10
+ background: var(--color-blue-50);
11
+ padding: var(--spacing-64) var(--layout-ensemble-inline-padding, var(--spacing-24));
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ .bd-installoptions-eyebrow {
16
+ color: var(--color-blue-500);
17
+ font-weight: var(--typography-fontWeight-semibold);
18
+ margin: 0 0 var(--spacing-16);
19
+ max-width: var(--layout-ensemble-max-width, 1200px);
20
+ margin-inline: auto;
21
+ }
22
+
23
+ .bd-installoptions-title {
24
+ margin: 0 0 var(--spacing-16);
25
+ color: var(--color-neutral-1000);
26
+ line-height: var(--typography-lineHeight-tight);
27
+ max-width: var(--layout-ensemble-max-width, 1200px);
28
+ margin-inline: auto;
29
+ }
30
+
31
+ .bd-installoptions-description {
32
+ color: var(--color-neutral-700);
33
+ max-width: 640px;
34
+ margin: 0 auto var(--spacing-32);
35
+ }
36
+
37
+ .bd-installoptions-worksin {
38
+ display: flex;
39
+ align-items: center;
40
+ flex-wrap: wrap;
41
+ gap: var(--spacing-16);
42
+ max-width: var(--layout-ensemble-max-width, 1200px);
43
+ margin: 0 auto var(--spacing-40);
44
+ }
45
+
46
+ .bd-installoptions-worksin-label {
47
+ color: var(--color-neutral-500);
48
+ font-family: var(--typography-fontFamily-mono, monospace);
49
+ font-size: var(--typography-fontSize-xs);
50
+ text-transform: uppercase;
51
+ letter-spacing: 0.06em;
52
+ flex-shrink: 0;
53
+ }
54
+
55
+ .bd-installoptions-pills {
56
+ display: flex;
57
+ flex-wrap: wrap;
58
+ gap: var(--spacing-12);
59
+ }
60
+
61
+ .bd-installoptions-pill {
62
+ display: inline-flex;
63
+ align-items: center;
64
+ gap: var(--spacing-8);
65
+ padding: var(--spacing-8) var(--spacing-16);
66
+ background: var(--color-neutral-0);
67
+ border: var(--border-width-1) solid var(--color-neutral-200);
68
+ border-radius: var(--radius-full);
69
+ font-size: var(--typography-fontSize-sm);
70
+ font-weight: var(--typography-fontWeight-semibold);
71
+ color: var(--color-neutral-900);
72
+ }
73
+
74
+ /*
75
+ Placeholder brand marks: these render an initial letter on a solid
76
+ background because the real Claude Code / Codex / OpenClaw / opencode /
77
+ Hermes Agent logos are not in this icon set. Swap the initial+color pairs
78
+ for real <img>/<svg> marks as soon as brand assets are available.
79
+ */
80
+ .bd-installoptions-pill-icon {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ width: 20px;
85
+ height: 20px;
86
+ border-radius: var(--radius-md);
87
+ color: var(--color-neutral-0);
88
+ font-size: var(--typography-fontSize-xxs);
89
+ font-weight: var(--typography-fontWeight-bold);
90
+ flex-shrink: 0;
91
+ }
92
+
93
+ .bd-installoptions-grid {
94
+ display: grid;
95
+ grid-template-columns: repeat(3, 1fr);
96
+ gap: var(--spacing-24);
97
+ max-width: var(--layout-ensemble-max-width, 1200px);
98
+ margin-inline: auto;
99
+ }
100
+
101
+ .bd-installoptions-card {
102
+ background: var(--color-neutral-0);
103
+ border: var(--border-width-1) solid var(--color-neutral-100);
104
+ border-radius: var(--radius-xl);
105
+ padding: var(--spacing-24);
106
+ box-sizing: border-box;
107
+ display: flex;
108
+ flex-direction: column;
109
+ gap: var(--spacing-12);
110
+ }
111
+
112
+ .bd-installoptions-card-head {
113
+ display: flex;
114
+ align-items: flex-start;
115
+ justify-content: space-between;
116
+ gap: var(--spacing-12);
117
+ }
118
+
119
+ .bd-installoptions-card-title {
120
+ margin: 0;
121
+ color: var(--color-neutral-900);
122
+ }
123
+
124
+ .bd-installoptions-badge {
125
+ flex-shrink: 0;
126
+ padding: var(--spacing-4) var(--spacing-8);
127
+ background: var(--color-blue-50);
128
+ color: var(--color-blue-700);
129
+ border-radius: var(--radius-md);
130
+ font-size: var(--typography-fontSize-xxs);
131
+ font-weight: var(--typography-fontWeight-bold);
132
+ text-transform: uppercase;
133
+ letter-spacing: 0.04em;
134
+ white-space: nowrap;
135
+ }
136
+
137
+ .bd-installoptions-card-description {
138
+ color: var(--color-neutral-600);
139
+ margin: 0;
140
+ flex-grow: 1;
141
+ }
142
+
143
+ .bd-installoptions-code {
144
+ position: relative;
145
+ background: var(--color-neutral-900);
146
+ border-radius: var(--radius-md);
147
+ padding: var(--spacing-16);
148
+ box-sizing: border-box;
149
+ }
150
+
151
+ .bd-installoptions-code-text {
152
+ margin: 0;
153
+ color: var(--color-neutral-0);
154
+ font-family: var(--typography-fontFamily-mono, monospace);
155
+ font-size: var(--typography-fontSize-sm);
156
+ white-space: pre-wrap;
157
+ word-break: break-word;
158
+ padding-right: var(--spacing-56);
159
+ }
160
+
161
+ .bd-installoptions-copy {
162
+ position: absolute;
163
+ top: var(--spacing-12);
164
+ right: var(--spacing-12);
165
+ padding: var(--spacing-4) var(--spacing-10);
166
+ background: rgba(255, 255, 255, 0.12);
167
+ color: var(--color-neutral-0);
168
+ border: none;
169
+ border-radius: var(--radius-sm);
170
+ font-family: var(--typography-fontFamily-sans);
171
+ font-size: var(--typography-fontSize-xs);
172
+ font-weight: var(--typography-fontWeight-semibold);
173
+ cursor: pointer;
174
+ transition: background var(--transition-duration-fast) var(--transition-easing-smooth);
175
+ }
176
+
177
+ .bd-installoptions-copy:hover {
178
+ background: rgba(255, 255, 255, 0.2);
179
+ }
180
+
181
+ .bd-installoptions-copy:focus-visible {
182
+ outline: none;
183
+ box-shadow: var(--focus-outline-primary);
184
+ }
185
+
186
+ .bd-installoptions-card-link {
187
+ font-weight: var(--typography-fontWeight-semibold);
188
+ margin-top: auto;
189
+ }
190
+
191
+ /* === "Then just ask" prompt panel (prompt-panel attribute) === */
192
+
193
+ .bd-installoptions-promptpanel {
194
+ max-width: var(--layout-ensemble-max-width, 1200px);
195
+ margin: var(--spacing-64) auto 0;
196
+ }
197
+
198
+ .bd-installoptions-prompt-title {
199
+ margin: 0 0 var(--spacing-16);
200
+ color: var(--color-neutral-1000);
201
+ line-height: var(--typography-lineHeight-tight);
202
+ }
203
+
204
+ .bd-installoptions-prompt-description {
205
+ color: var(--color-neutral-700);
206
+ max-width: 640px;
207
+ margin: 0 0 var(--spacing-24);
208
+ }
209
+
210
+ .bd-installoptions-prompt-label {
211
+ display: block;
212
+ color: var(--color-neutral-500);
213
+ font-family: var(--typography-fontFamily-mono, monospace);
214
+ font-size: var(--typography-fontSize-xs);
215
+ text-transform: uppercase;
216
+ letter-spacing: 0.06em;
217
+ margin-bottom: var(--spacing-8);
218
+ }
219
+
220
+ .bd-installoptions-prompt-code {
221
+ position: relative;
222
+ background: var(--color-neutral-900);
223
+ border: var(--border-width-2) solid var(--color-blue-500);
224
+ border-radius: var(--radius-md);
225
+ padding: var(--spacing-16);
226
+ padding-right: var(--spacing-64);
227
+ box-sizing: border-box;
228
+ margin-bottom: var(--spacing-24);
229
+ }
230
+
231
+ .bd-installoptions-prompt-code-text {
232
+ color: var(--color-neutral-0);
233
+ font-family: var(--typography-fontFamily-mono, monospace);
234
+ font-size: var(--typography-fontSize-sm);
235
+ line-height: var(--typography-lineHeight-normal);
236
+ }
237
+
238
+ .bd-installoptions-prompt-code-text ::slotted(*) {
239
+ margin: 0;
240
+ font: inherit;
241
+ color: inherit;
242
+ }
243
+
244
+ .bd-installoptions-copy--prompt {
245
+ top: var(--spacing-12);
246
+ right: var(--spacing-12);
247
+ }
248
+
249
+ .bd-installoptions-prompt-note {
250
+ background: var(--color-yellow-50, #fffbeb);
251
+ border: var(--border-width-1) solid var(--color-yellow-300, #fcd34d);
252
+ border-radius: var(--radius-md);
253
+ padding: var(--spacing-16) var(--spacing-20);
254
+ color: var(--color-yellow-800, #92400e);
255
+ font-size: var(--typography-fontSize-sm);
256
+ line-height: var(--typography-lineHeight-normal);
257
+ margin-bottom: var(--spacing-24);
258
+ }
259
+
260
+ .bd-installoptions-prompt-note ::slotted(*) {
261
+ margin: 0;
262
+ font: inherit;
263
+ color: inherit;
264
+ }
265
+
266
+ .bd-installoptions-prompt-footer {
267
+ color: var(--color-neutral-600);
268
+ margin: 0;
269
+ }
270
+
271
+ @media (max-width: 899px) {
272
+ .bd-installoptions-grid {
273
+ grid-template-columns: 1fr;
274
+ }
275
+ }
276
+ `;
@@ -0,0 +1,184 @@
1
+ import { LitElement, html, nothing } from "lit";
2
+ import { tokens } from "../../tokens/tokens.js";
3
+ import "../heading/heading.js";
4
+ import "../link/link.js";
5
+ import "../paragraph/paragraph.js";
6
+ import installOptionsCSS from "./install-options.css.js";
7
+
8
+ class BdInstallOptions extends LitElement {
9
+ static properties = {
10
+ eyebrow : { type: String },
11
+ title : { type: String },
12
+ description: { type: String },
13
+ worksIn : { type: Array }, // [{ label, initial, color }]
14
+ cards : { type: Array }, // [{ title, badge, description, code, linkLabel, linkHref }]
15
+
16
+ // "Then just ask" sub-panel — rendered only when this is set, so a
17
+ // consumer of bd-install-options who doesn't need it gets nothing extra.
18
+ promptPanel: { type: Boolean, reflect: true, attribute: "prompt-panel" },
19
+ promptLabel: { type: String, attribute: "prompt-label" } // small mono label above the prompt block
20
+ };
21
+
22
+ static styles = [tokens, installOptionsCSS];
23
+
24
+ constructor() {
25
+ super();
26
+ this.eyebrow = "";
27
+ this.title = "";
28
+ this.description = "";
29
+ this.worksIn = [];
30
+ this.cards = [];
31
+ this.promptPanel = false;
32
+ this.promptLabel = "";
33
+ }
34
+
35
+ async _copy(text, btn) {
36
+ try {
37
+ await navigator.clipboard.writeText(text);
38
+ const original = btn.textContent;
39
+ btn.textContent = "Copied";
40
+ btn.disabled = true;
41
+ setTimeout(() => {
42
+ btn.textContent = original;
43
+ btn.disabled = false;
44
+ }, 1500);
45
+ } catch {
46
+ // clipboard permission denied or unavailable — button stays as "Copy"
47
+ }
48
+ }
49
+
50
+ async _copyPromptSlot(btn) {
51
+ const slot = this.renderRoot?.querySelector('slot[name="prompt"]');
52
+ const nodes = slot?.assignedNodes({ flatten: true }) || [];
53
+ const text = nodes.map((n) => n.textContent || "").join("")
54
+ .trim();
55
+ if (!text) return;
56
+ this._copy(text, btn);
57
+ }
58
+
59
+ _renderWorksIn() {
60
+ if (!this.worksIn.length) return nothing;
61
+ return html`
62
+ <div class="bd-installoptions-worksin">
63
+ <span class="bd-installoptions-worksin-label">Works in</span>
64
+ <div class="bd-installoptions-pills">
65
+ ${this.worksIn.map(
66
+ ({ label, initial, color }) => html`
67
+ <span class="bd-installoptions-pill">
68
+ <span
69
+ class="bd-installoptions-pill-icon"
70
+ style="background:${color || "var(--color-neutral-800)"}"
71
+ aria-hidden="true"
72
+ >${initial || label?.[0] || "?"}</span>
73
+ ${label}
74
+ </span>
75
+ `
76
+ )}
77
+ </div>
78
+ </div>
79
+ `;
80
+ }
81
+
82
+ _renderCard(card) {
83
+ return html`
84
+ <div class="bd-installoptions-card">
85
+ <div class="bd-installoptions-card-head">
86
+ <bd-h as="h3" class="bd-installoptions-card-title">${card.title}</bd-h>
87
+ ${card.badge
88
+ ? html`<span class="bd-installoptions-badge">${card.badge}</span>`
89
+ : nothing}
90
+ </div>
91
+
92
+ ${card.description
93
+ ? html`<bd-p kind="small" class="bd-installoptions-card-description">${card.description}</bd-p>`
94
+ : nothing}
95
+
96
+ ${card.code
97
+ ? html`
98
+ <div class="bd-installoptions-code">
99
+ <pre class="bd-installoptions-code-text">${card.code}</pre>
100
+ <button
101
+ type="button"
102
+ class="bd-installoptions-copy"
103
+ @click=${(e) => this._copy(card.code, e.currentTarget)}
104
+ >Copy</button>
105
+ </div>
106
+ `
107
+ : nothing}
108
+
109
+ ${card.linkLabel
110
+ ? html`
111
+ <bd-link href=${card.linkHref || "#"} kind="primary" class="bd-installoptions-card-link">
112
+ ${card.linkLabel} →
113
+ </bd-link>
114
+ `
115
+ : nothing}
116
+ </div>
117
+ `;
118
+ }
119
+
120
+ _renderPromptPanel() {
121
+ if (!this.promptPanel) return nothing;
122
+
123
+ return html`
124
+ <div class="bd-installoptions-promptpanel">
125
+ <bd-h as="h2" class="bd-installoptions-prompt-title">
126
+ <slot name="prompt-title"></slot>
127
+ </bd-h>
128
+
129
+ <bd-p kind="regular" class="bd-installoptions-prompt-description">
130
+ <slot name="prompt-description"></slot>
131
+ </bd-p>
132
+
133
+ ${this.promptLabel
134
+ ? html`<span class="bd-installoptions-prompt-label">${this.promptLabel}</span>`
135
+ : nothing}
136
+
137
+ <div class="bd-installoptions-prompt-code">
138
+ <div class="bd-installoptions-prompt-code-text">
139
+ <slot name="prompt"></slot>
140
+ </div>
141
+ <button
142
+ type="button"
143
+ class="bd-installoptions-copy bd-installoptions-copy--prompt"
144
+ @click=${(e) => this._copyPromptSlot(e.currentTarget)}
145
+ >Copy</button>
146
+ </div>
147
+
148
+ <div class="bd-installoptions-prompt-note">
149
+ <slot name="prompt-note"></slot>
150
+ </div>
151
+
152
+ <bd-p kind="regular" class="bd-installoptions-prompt-footer">
153
+ <slot name="prompt-footer"></slot>
154
+ </bd-p>
155
+ </div>
156
+ `;
157
+ }
158
+
159
+ render() {
160
+ return html`
161
+ <div class="bd-installoptions-container">
162
+ ${this.eyebrow
163
+ ? html`<bd-p kind="normal" class="bd-installoptions-eyebrow">${this.eyebrow}</bd-p>`
164
+ : nothing}
165
+
166
+ <bd-h as="h2" class="bd-installoptions-title">${this.title}</bd-h>
167
+
168
+ ${this.description
169
+ ? html`<bd-p kind="regular" class="bd-installoptions-description">${this.description}</bd-p>`
170
+ : nothing}
171
+
172
+ ${this._renderWorksIn()}
173
+
174
+ <div class="bd-installoptions-grid">
175
+ ${this.cards.map((card) => this._renderCard(card))}
176
+ </div>
177
+
178
+ ${this._renderPromptPanel()}
179
+ </div>
180
+ `;
181
+ }
182
+ }
183
+
184
+ customElements.define("bd-install-options", BdInstallOptions);
@@ -11,7 +11,7 @@ export default css`
11
11
  gap: var(--spacing-8);
12
12
  color: var(--color-neutral-700);
13
13
  line-height: var(--typography-lineHeight-normal);
14
- font-family: var(--typography-fontFamily-sans);
14
+ font-family: var(--font-family-mono);
15
15
  }
16
16
 
17
17
  /* === SIZE VARIANTS === */
@@ -47,7 +47,7 @@ export default css`
47
47
  --bd-li-marker-size: var(--spacing-6);
48
48
  width: var(--bd-li-marker-size);
49
49
  height: var(--bd-li-marker-size);
50
- background-color: var(--color-neutral-1000);
50
+ background-color: var(--bd-li-marker-color, var(--color-neutral-1000));
51
51
  border-radius: 50%;
52
52
  }
53
53
 
@@ -63,7 +63,7 @@ export default css`
63
63
  .bd-list-item.number .bd-list-item-marker::before {
64
64
  content: counter(bd-list-counter) ".";
65
65
  font-weight: var(--typography-fontWeight-semibold);
66
- color: var(--color-neutral-1000);
66
+ color: var(--bd-li-marker-color, var(--color-neutral-1000));
67
67
  }
68
68
 
69
69
  /* Check List */
@@ -4,9 +4,10 @@ import listItemCSS from "./list-item.css.js";
4
4
 
5
5
  export class BdListItem extends LitElement {
6
6
  static properties = {
7
- kind: { type: String }, // bullet, number, check, none
8
- size: { type: String }, // sm, md, lg
9
- icon: { type: String } // custom icon URL
7
+ kind : { type: String }, // bullet, number, check, none
8
+ size : { type: String }, // sm, md, lg
9
+ icon : { type: String }, // custom icon URL
10
+ color: { type: String } // optional
10
11
  };
11
12
 
12
13
  constructor() {
@@ -14,11 +15,16 @@ export class BdListItem extends LitElement {
14
15
  this.kind = "bullet";
15
16
  this.size = "md";
16
17
  this.icon = "";
18
+ this.color = "";
17
19
  }
18
20
 
19
21
  render() {
22
+ const style = this.color
23
+ ? `color: ${this.color}; --bd-li-marker-color: ${this.color};`
24
+ : "";
25
+
20
26
  return html`
21
- <li class="bd-list-item ${this.kind} ${this.size}">
27
+ <li class="bd-list-item ${this.kind} ${this.size}" style="${style}">
22
28
  ${this._renderMarker()}
23
29
  <span class="bd-list-item-content">
24
30
  <slot></slot>
@@ -0,0 +1,121 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ font-family: var(--typography-fontFamily-sans);
7
+ }
8
+
9
+ .bd-infopanel-container {
10
+ display: grid;
11
+ grid-template-columns: 1fr 1fr;
12
+ grid-template-rows: auto auto;
13
+ column-gap: var(--spacing-48);
14
+ row-gap: 0;
15
+ max-width: var(--layout-ensemble-max-width, 1200px);
16
+ margin: 0 auto;
17
+ padding: var(--spacing-48) var(--layout-ensemble-inline-padding, var(--spacing-24));
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ /* Title spans both columns on its own row */
22
+ .bd-infopanel-title {
23
+ grid-column: 1 / -1;
24
+ grid-row: 1;
25
+ margin: 0;
26
+ color: var(--color-neutral-1000);
27
+ line-height: var(--typography-lineHeight-tight, 1.1);
28
+ margin-bottom: var(--spacing-48);
29
+ }
30
+
31
+ /* === LEFT COLUMN (description) === */
32
+ .bd-infopanel-left {
33
+ grid-column: 1;
34
+ grid-row: 2;
35
+ display: flex;
36
+ flex-direction: column;
37
+ gap: var(--spacing-16);
38
+ }
39
+
40
+ .bd-infopanel-description {
41
+ margin: 0;
42
+ color: var(--color-neutral-900);
43
+ max-width: 46ch;
44
+ line-height: 1.5;
45
+ font-family: var(--typography-fontFamily-sans);
46
+ }
47
+
48
+ /* === RIGHT COLUMN (facts) === */
49
+ .bd-infopanel-right {
50
+ grid-column: 2;
51
+ grid-row: 2;
52
+ display: flex;
53
+ flex-direction: column;
54
+ }
55
+
56
+ .bd-infopanel-row {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: var(--spacing-4);
60
+ padding-top: var(--spacing-16);
61
+ padding-bottom: var(--spacing-24);
62
+ }
63
+
64
+ .bd-infopanel-row:first-of-type {
65
+ padding-top: 0;
66
+ }
67
+
68
+ .bd-infopanel-row:last-of-type {
69
+ padding-bottom: 0;
70
+ }
71
+
72
+ .bd-infopanel-divider {
73
+ border-top: 2px solid var(--color-blue-500);
74
+ margin-bottom: var(--spacing-16);
75
+ }
76
+
77
+ .bd-infopanel-label {
78
+ margin: 0;
79
+ color: var(--color-neutral-600);
80
+ text-transform: uppercase;
81
+ letter-spacing: .1em;
82
+ font-family: var(--typography-fontFamily-mono, monospace);
83
+ font-size: var(--typography-fontSize-xxs);
84
+ }
85
+
86
+ .bd-infopanel-value {
87
+ margin: 0;
88
+ color: var(--color-neutral-1000);
89
+ font-weight: var(--typography-fontWeight-bold, 700);
90
+ }
91
+
92
+ /* === RESPONSIVE === */
93
+ @media (max-width: 899px) {
94
+ .bd-infopanel-container {
95
+ grid-template-columns: 1fr;
96
+ grid-template-rows: auto auto auto;
97
+ gap: var(--spacing-32);
98
+ padding: var(--spacing-32) var(--spacing-24);
99
+ }
100
+
101
+ .bd-infopanel-title {
102
+ grid-column: 1;
103
+ grid-row: 1;
104
+ margin-bottom: var(--spacing-16);
105
+ }
106
+
107
+ .bd-infopanel-left {
108
+ grid-column: 1;
109
+ grid-row: 2;
110
+ }
111
+
112
+ .bd-infopanel-right {
113
+ grid-column: 1;
114
+ grid-row: 3;
115
+ }
116
+
117
+ .bd-infopanel-description {
118
+ max-width: none;
119
+ }
120
+ }
121
+ `;
@@ -0,0 +1,63 @@
1
+ import { LitElement, html, nothing } from "lit";
2
+ import { tokens } from "../../tokens/tokens.js";
3
+ import "../heading/heading.js";
4
+ import "../paragraph/paragraph.js";
5
+ import infoPanelCSS from "./overview.css.js";
6
+
7
+ class Overview extends LitElement {
8
+ static properties = {
9
+ title : { type: String },
10
+ description: { type: String },
11
+ facts : { type: Array } // [{ label: String, value: String }]
12
+ };
13
+
14
+ static styles = [tokens, infoPanelCSS];
15
+
16
+ constructor() {
17
+ super();
18
+ this.title = "";
19
+ this.description = "";
20
+ this.facts = [];
21
+ }
22
+
23
+ render() {
24
+ return html`
25
+ <div class="bd-infopanel-container">
26
+ ${this.title
27
+ ? html`
28
+ <bd-h as="h2" class="bd-infopanel-title">
29
+ <slot name="title">${this.title}</slot>
30
+ </bd-h>
31
+ `
32
+ : nothing}
33
+
34
+ <div class="bd-infopanel-left">
35
+ ${this.description
36
+ ? html`
37
+ <bd-p kind="large" class="bd-infopanel-description">
38
+ <slot name="description">${this.description}</slot>
39
+ </bd-p>
40
+ `
41
+ : nothing}
42
+
43
+ <slot></slot>
44
+ </div>
45
+
46
+ <div class="bd-infopanel-right">
47
+ ${this.facts.map(
48
+ (fact) => html`
49
+ <div class="bd-infopanel-row">
50
+ <div class="bd-infopanel-divider"></div>
51
+ <bd-p kind="xsmall" class="bd-infopanel-label">${fact.label}</bd-p>
52
+ <bd-p kind="normal" class="bd-infopanel-value">${fact.value}</bd-p>
53
+ </div>
54
+ `
55
+ )}
56
+ <slot name="facts"></slot>
57
+ </div>
58
+ </div>
59
+ `;
60
+ }
61
+ }
62
+
63
+ customElements.define("bd-overview", Overview);