@repobit/dex-system-design 0.24.3 → 0.24.5

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 (66) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +4 -4
  3. package/src/components/accordion/accordion-bg.css.js +6 -1
  4. package/src/components/accordion/accordion-bg.js +3 -1
  5. package/src/components/accordion/accordion-bg.stories.js +49 -0
  6. package/src/components/accordion/accordion.css.js +40 -0
  7. package/src/components/accordion/accordion.js +31 -0
  8. package/src/components/accordion/accordion.stories.js +147 -4
  9. package/src/components/agent-endpoints/agent-endpoints.css.js +92 -0
  10. package/src/components/agent-endpoints/agent-endpoints.js +86 -0
  11. package/src/components/agent-endpoints/agent-endpoints.stories.js +148 -0
  12. package/src/components/ai-guardian-demo.stories.js +669 -0
  13. package/src/components/awards/awards-flex.css.js +169 -0
  14. package/src/components/awards/awards-flex.js +269 -0
  15. package/src/components/awards/awards-flex.stories.js +657 -0
  16. package/src/components/bento-grid/bento-grid.css.js +57 -0
  17. package/src/components/bento-grid/bento-grid.js +186 -0
  18. package/src/components/bento-grid/bento-grid.stories.js +440 -0
  19. package/src/components/bento-grid/bento-item.css.js +79 -0
  20. package/src/components/bento-grid/bento-item.js +54 -0
  21. package/src/components/button/button.css.js +26 -0
  22. package/src/components/button/button.js +8 -0
  23. package/src/components/button/button.stories.js +12 -0
  24. package/src/components/comparison-panel/comparison-panel.css.js +104 -0
  25. package/src/components/comparison-panel/comparison-panel.js +100 -0
  26. package/src/components/comparison-panel/comparison-panel.stories.js +223 -0
  27. package/src/components/compatibility-table/compatibility-table.css.js +243 -0
  28. package/src/components/compatibility-table/compatibility-table.js +123 -0
  29. package/src/components/compatibility-table/compatibility-table.stories.js +189 -0
  30. package/src/components/cta-banner/cta-banner.css.js +60 -0
  31. package/src/components/cta-banner/cta-banner.js +63 -0
  32. package/src/components/dropdown/dropdown.css.js +1 -1
  33. package/src/components/footer/footer.css.js +0 -1
  34. package/src/components/header/header-code.css.js +125 -0
  35. package/src/components/header/header-code.js +69 -0
  36. package/src/components/header/header-code.stories.js +226 -0
  37. package/src/components/heading/heading.css.js +3 -0
  38. package/src/components/icons/bd-ai-icon.js +27 -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.js +7 -3
  47. package/src/components/process-steps/process-steps.css.js +95 -0
  48. package/src/components/process-steps/process-steps.js +72 -0
  49. package/src/components/process-steps/process-steps.stories.js +144 -0
  50. package/src/components/quick-answer/quick-answer.css.js +67 -0
  51. package/src/components/quick-answer/quick-answer.js +59 -0
  52. package/src/components/quick-answer/quick-answer.stories.js +160 -0
  53. package/src/components/terminal/terminal-cursor.js +49 -0
  54. package/src/components/terminal/terminal-message.css.js +161 -0
  55. package/src/components/terminal/terminal-message.js +169 -0
  56. package/src/components/terminal/terminal-message.stories.js +321 -0
  57. package/src/components/trust-panel/trust-panel.css.js +167 -0
  58. package/src/components/trust-panel/trust-panel.js +116 -0
  59. package/src/components/trust-panel/trust-panel.stories.js +234 -0
  60. package/src/tokens/tokens.css +1 -1
  61. package/src/components/tabsComponent/tabsComponent.css.js +0 -267
  62. package/src/components/tabsComponent/tabsComponent.js +0 -193
  63. package/src/components/tabsComponent/tabsComponent.stories.js +0 -134
  64. package/src/components/tabsComponentFamily/tabsComponentFamily.css.js +0 -181
  65. package/src/components/tabsComponentFamily/tabsComponentFamily.js +0 -180
  66. package/src/components/tabsComponentFamily/tabsComponentFamily.stories.js +0 -319
package/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.24.5](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.4...@repobit/dex-system-design@0.24.5) (2026-09-01)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **DEX-1014:** bitdefender AI components and new adjustments for components
11
+
12
+
13
+ ## [0.24.4](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.3...@repobit/dex-system-design@0.24.4) (2026-09-01)
14
+
15
+ ### Bug Fixes
16
+
17
+ * **DEX-1014:** padding adjustments
18
+ * **DEX-1014:** padding adjustments
19
+
20
+
6
21
  ## [0.24.3](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.2...@repobit/dex-system-design@0.24.3) (2026-08-25)
7
22
 
8
23
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repobit/dex-system-design",
3
- "version": "0.24.3",
3
+ "version": "0.24.5",
4
4
  "description": "Design system based on Web Components.",
5
5
  "author": "Iordache Matei Cezar <miordache@bitdefender.com>",
6
6
  "homepage": "https://github.com/bitdefender/dex-core#readme",
@@ -74,8 +74,8 @@
74
74
  "url": "https://github.com/bitdefender/dex-core/issues"
75
75
  },
76
76
  "dependencies": {
77
- "@repobit/dex-store": "1.6.19",
78
- "@repobit/dex-store-elements": "2.0.24",
77
+ "@repobit/dex-store": "1.6.21",
78
+ "@repobit/dex-store-elements": "2.0.26",
79
79
  "lit": "^3.3.2"
80
80
  },
81
81
  "devDependencies": {
@@ -92,5 +92,5 @@
92
92
  "volta": {
93
93
  "node": "24.14.0"
94
94
  },
95
- "gitHead": "e3429ddb72eb37b8ab1524792a5b8db3f8c65de7"
95
+ "gitHead": "5cb3f2de5d59ff4292b2a4175fde263f72ac5152"
96
96
  }
@@ -207,7 +207,7 @@ export default css`
207
207
  /* FAQ container — padding 64px top/bottom */
208
208
  .bd-accordion-bg-container {
209
209
  margin: auto;
210
- // padding-top: var(--spacing-64);
210
+ padding-top: var(--spacing-64);
211
211
  padding-bottom: var(--spacing-64);
212
212
  }
213
213
 
@@ -215,6 +215,11 @@ export default css`
215
215
  background: none;
216
216
  }
217
217
 
218
+ .bd-accordion-bg-container.no-padding {
219
+ padding-top: 0;
220
+ padding-bottom: 0;
221
+ }
222
+
218
223
  /* Inner — max-width 1290px centrat */
219
224
  .bd-accordion-bg-inner {
220
225
  max-width: 1290px;
@@ -11,6 +11,7 @@ class BdAccordionBg extends LitElement {
11
11
  static properties = {
12
12
  title : { type: String },
13
13
  noBg : { type: Boolean, reflect: true, attribute: "no-bg" },
14
+ noPadding : { type: Boolean, reflect: true, attribute: "no-padding" },
14
15
  guideIcon : { type: String, reflect: true, attribute: "guide-icon" },
15
16
  guideLabel: { type: String, reflect: true, attribute: "guide-label" },
16
17
  guideHref : { type: String, reflect: true, attribute: "guide-href" },
@@ -21,6 +22,7 @@ class BdAccordionBg extends LitElement {
21
22
  constructor() {
22
23
  super();
23
24
  this.noBg = false;
25
+ this.noPadding = false;
24
26
  this._variant = "default";
25
27
  this.variant = "default";
26
28
  this.guideIcon = "";
@@ -68,7 +70,7 @@ class BdAccordionBg extends LitElement {
68
70
 
69
71
  _renderFaq() {
70
72
  return html`
71
- <div class="bd-accordion-bg-container ${this.noBg ? "no-bg" : ""}">
73
+ <div class="bd-accordion-bg-container ${this.noBg ? "no-bg" : ""} ${this.noPadding ? "no-padding" : ""}">
72
74
  <div class="bd-accordion-bg-inner">
73
75
  <div class="bd-accordion-bg-header">
74
76
  <bd-h as="h2" class="bd-accordion-bg-title">${this.title}</bd-h>
@@ -50,6 +50,7 @@ Componenta urcă în DOM și detectează clasa părintelui:
50
50
  |---|---|---|---|
51
51
  | \`title\` | String | — | Titlul secțiunii |
52
52
  | \`no-bg\` | Boolean | \`false\` | Elimină background-ul containerului |
53
+ | \`no-padding\` | Boolean | \`false\` | Elimină padding-top/bottom (64px) al containerului \`.bd-accordion-bg-container\` — util când secțiunea e lipită de alta deasupra/dedesubt. Se aplică doar variantei \`faq\` |
53
54
  | \`guide-icon\` | String | — | Cale icon pentru link-ul ghid (doar terms-of-use) |
54
55
  | \`guide-label\` | String | — | Text link ghid (doar terms-of-use) |
55
56
  | \`guide-href\` | String | \`#\` | URL link ghid (doar terms-of-use) |
@@ -166,6 +167,54 @@ export const FaqNoBgItems = {
166
167
  `
167
168
  };
168
169
 
170
+ // ─── FAQ — Fără padding (no-padding) ──────────────────────────────────────────
171
+
172
+ export const FaqNoPadding = {
173
+ name : "FAQ — Fără padding (no-padding)",
174
+ parameters: {
175
+ docs: {
176
+ description: {
177
+ story: "Compară aceeași secțiune FAQ cu și fără atributul `no-padding`. Fără el, containerul `.bd-accordion-bg-container` are 64px padding-top/bottom (vezi chenarul roșu de deasupra, care marchează unde s-ar termina normal spațiul). Cu `no-padding`, acel spațiu dispare complet — util când secțiunea trebuie lipită imediat de blocul de deasupra sau de dedesubt."
178
+ }
179
+ }
180
+ },
181
+ render: () => html`
182
+ <div>
183
+ <bd-p kind="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">
184
+ Fără <code>no-padding</code> — 64px padding-top/bottom (spațiul albastru de sus/jos):
185
+ </bd-p>
186
+ <div style="outline: 2px dashed red;">
187
+ <div class="accordion faq block">
188
+ <bd-accordion-bg title="Questions? Answers.">
189
+ <bd-accordion-bg-item title="How does Bitdefender protect me?">
190
+ <bd-p kind="small">Bitdefender provides multi-layer protection against all cyber threats.</bd-p>
191
+ </bd-accordion-bg-item>
192
+ <bd-accordion-bg-item title="Does it work on Mac?">
193
+ <bd-p kind="small">Yes, Bitdefender is fully compatible with macOS 10.14 and later.</bd-p>
194
+ </bd-accordion-bg-item>
195
+ </bd-accordion-bg>
196
+ </div>
197
+ </div>
198
+
199
+ <bd-p kind="small" style="color: var(--color-neutral-500); margin: 24px 0 8px;">
200
+ Cu <code>no-padding</code> — 0px padding-top/bottom (secțiunea lipită de chenar):
201
+ </bd-p>
202
+ <div style="outline: 2px dashed red;">
203
+ <div class="accordion faq block">
204
+ <bd-accordion-bg title="Questions? Answers." no-padding>
205
+ <bd-accordion-bg-item title="How does Bitdefender protect me?">
206
+ <bd-p kind="small">Bitdefender provides multi-layer protection against all cyber threats.</bd-p>
207
+ </bd-accordion-bg-item>
208
+ <bd-accordion-bg-item title="Does it work on Mac?">
209
+ <bd-p kind="small">Yes, Bitdefender is fully compatible with macOS 10.14 and later.</bd-p>
210
+ </bd-accordion-bg-item>
211
+ </bd-accordion-bg>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ `
216
+ };
217
+
169
218
  // ─── Terms of Use ─────────────────────────────────────────────────────────────
170
219
 
171
220
  export const TermsOfUse = {
@@ -195,6 +195,46 @@ export const accordionItem = css`
195
195
  width: 100%;
196
196
  }
197
197
  }
198
+
199
+ /* === CHEVRON VARIANT (text + arrow icon only, no visible border/pill/background) === */
200
+ .header--chevron {
201
+ display: inline-flex;
202
+ align-items: center;
203
+ justify-content: flex-start;
204
+ width: auto;
205
+ gap: var(--spacing-8);
206
+ padding: 0;
207
+ border: none;
208
+ border-radius: 0;
209
+ background: none;
210
+ margin-bottom: var(--spacing-24);
211
+ font-size: var(--typography-fontSize-sm);
212
+ font-weight: var(--typography-fontWeight-semibold);
213
+ }
214
+
215
+ .header--chevron .title-badge-wrapper {
216
+ flex: 0 1 auto;
217
+ }
218
+
219
+ .header--chevron .title {
220
+ color: var(--color-blue-600);
221
+ white-space: nowrap;
222
+ }
223
+
224
+ .header--chevron:hover .title {
225
+ text-decoration: underline;
226
+ }
227
+
228
+ .toggle--chevron {
229
+ width: 16px;
230
+ min-width: 16px;
231
+ height: 16px;
232
+ margin-top: 0;
233
+ }
234
+
235
+ .content--chevron {
236
+ padding: 0;
237
+ }
198
238
  `;
199
239
 
200
240
  export const accordionSection = css`
@@ -1,6 +1,8 @@
1
1
  import { LitElement, html } from "lit";
2
2
  import { tokens } from "../../tokens/tokens.js";
3
3
  import "../heading/heading.js";
4
+ import "../icons/arrow-down-icon.js";
5
+ import "../icons/arrow-up-icon.js";
4
6
  import "../icons/minus-icon.js";
5
7
  import "../icons/plus-icon.js";
6
8
  import "../paragraph/paragraph.js";
@@ -12,6 +14,7 @@ export class BdAccordionItem extends LitElement {
12
14
  static properties = {
13
15
  open : { type: Boolean, reflect: true },
14
16
  title : { type: String },
17
+ chevron : { type: Boolean, reflect: true }, // text + arrow icon variant
15
18
  _panelId: { type: String, state: true }
16
19
  };
17
20
 
@@ -19,6 +22,7 @@ export class BdAccordionItem extends LitElement {
19
22
  super();
20
23
  this.open = false;
21
24
  this.title = "";
25
+ this.chevron = false;
22
26
  this._panelId = `acc-panel-${Math.random().toString(36)
23
27
  .slice(2, 11)}`;
24
28
  }
@@ -46,6 +50,33 @@ export class BdAccordionItem extends LitElement {
46
50
  render() {
47
51
  const badgeEl = this.querySelector("[slot='badge']");
48
52
 
53
+ if (this.chevron) {
54
+ return html`
55
+ <button
56
+ type="button"
57
+ class="header header--chevron"
58
+ aria-expanded="${this.open}"
59
+ aria-controls="${this._panelId}"
60
+ @click=${this.toggle}
61
+ @focusin=${this._onTriggerFocusIn}
62
+ @focusout=${this._onTriggerFocusOut}
63
+ >
64
+ <span class="title-badge-wrapper">
65
+ <span class="title">${this.title}</span>
66
+ ${badgeEl ? badgeEl.cloneNode(true) : ""}
67
+ </span>
68
+ <span class="toggle toggle--chevron" aria-hidden="true">
69
+ ${this.open
70
+ ? html`<bd-arrow-up-icon size="16" color="#006DFF"></bd-arrow-up-icon>`
71
+ : html`<bd-arrow-down-icon size="16" color="#006DFF"></bd-arrow-down-icon>`}
72
+ </span>
73
+ </button>
74
+ <div id="${this._panelId}" class="content content--chevron" ?hidden=${!this.open}>
75
+ <slot></slot>
76
+ </div>
77
+ `;
78
+ }
79
+
49
80
  return html`
50
81
  <button
51
82
  type="button"
@@ -1,4 +1,5 @@
1
1
  import { html } from "lit";
2
+ import "../compatibility-table/compatibility-table.js";
2
3
  import "./accordion.js";
3
4
 
4
5
  export default {
@@ -22,6 +23,12 @@ Two Lit web components for building accordion sections.
22
23
  </bd-accordion-section>
23
24
  \`\`\`
24
25
 
26
+ \`bd-accordion-item\` also supports a \`chevron\` variant — plain blue text with an arrow
27
+ icon (\`bd-arrow-down-icon\`/\`bd-arrow-up-icon\`) on the right, no border or
28
+ background — instead of the default left-side plus/minus icon. Combine it with
29
+ \`bd-compatibility-table\` (\`variant="risk"\`) to build a collapsible risk-mapping
30
+ table, as shown below.
31
+
25
32
  ### Attributes
26
33
 
27
34
  #### \`bd-accordion-section\`
@@ -34,10 +41,11 @@ Two Lit web components for building accordion sections.
34
41
  | \`guide-href\` | String | \`#\` | URL for the user guide link |
35
42
 
36
43
  #### \`bd-accordion-item\`
37
- | Attribute | Type | Default | Description |
38
- |-----------|---------|---------|--------------------------------------|
39
- | \`title\` | String | — | Trigger label |
40
- | \`open\` | Boolean | \`false\`| Whether the panel is expanded |
44
+ | Attribute | Type | Default | Description |
45
+ |-----------|---------|---------|-------------------------------------------------------------------------|
46
+ | \`title\` | String | — | Trigger label |
47
+ | \`open\` | Boolean | \`false\`| Whether the panel is expanded |
48
+ | \`chevron\` | Boolean | \`false\`| Renders the plain text + arrow-icon style instead of the default left plus/minus icon |
41
49
  `
42
50
  }
43
51
  }
@@ -240,4 +248,139 @@ export const ManyItems = {
240
248
  </bd-accordion-item>
241
249
  </bd-accordion-section>
242
250
  `
251
+ };
252
+
253
+
254
+ // ─── Chevron variant — risk mapping (matches reference design) ────────────────
255
+
256
+ export const RiskMappingAccordion = {
257
+ name : "Chevron variant — Risk mapping table",
258
+ render: () => html`
259
+ <div style="max-width: 900px;">
260
+ <bd-h as="h2" font-weight="700" style="margin: 0 0 8px;">Coverage against agentic AI risk categories</bd-h>
261
+ <bd-p kind="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
262
+ How AI Guardian maps to the risk categories the industry is standardising on for agentic applications.
263
+ </bd-p>
264
+
265
+ <bd-accordion-item chevron title="Show the full mapping (6 categories)">
266
+ <bd-compatibility-table
267
+ variant="risk"
268
+ .rows=${[
269
+ { category: "Prompt injection", coverage: "Inspects agent inputs and actions; returns allowed, flagged or blocked" },
270
+ { category: "Tool and MCP misuse", coverage: "Detects and blocks malicious or tampered MCP tools before invocation" },
271
+ { category: "Excessive or unscoped permissions", coverage: "Policy baseline defines what agents may do with tools, files and actions" },
272
+ { category: "Sensitive data exposure", coverage: "Detects credential and secret exposure before it leaves the machine" },
273
+ { category: "Unvetted extensions and skills", coverage: "Scans and validates skills before they run" },
274
+ { category: "Unmonitored agent activity", coverage: "Real-time tool-call monitoring with an auditable record" }
275
+ ]}
276
+ ></bd-compatibility-table>
277
+ </bd-accordion-item>
278
+
279
+ <bd-p kind="small" style="color: var(--color-neutral-500); margin-top: 16px;">
280
+ Category naming follows OWASP Top 10 for Agentic Applications (2026).
281
+ </bd-p>
282
+ </div>
283
+ `,
284
+ parameters: {
285
+ docs: {
286
+ description: {
287
+ story: "The chevron variant of bd-accordion-item (plain blue text, bd-arrow-down-icon/bd-arrow-up-icon on the right, no border) toggling a bd-compatibility-table in risk variant (2 columns: Risk category / AI Guardian coverage)."
288
+ }
289
+ }
290
+ }
291
+ };
292
+
293
+
294
+ // ─── Chevron variant — collapsed state ─────────────────────────────────────────
295
+
296
+ export const ChevronCollapsed = {
297
+ name : "Chevron variant — collapsed",
298
+ render: () => html`
299
+ <bd-accordion-item chevron title="Show the full mapping (6 categories)">
300
+ <bd-compatibility-table
301
+ variant="risk"
302
+ .rows=${[
303
+ { category: "Prompt injection", coverage: "Inspects agent inputs and actions; returns allowed, flagged or blocked" },
304
+ { category: "Tool and MCP misuse", coverage: "Detects and blocks malicious or tampered MCP tools before invocation" }
305
+ ]}
306
+ ></bd-compatibility-table>
307
+ </bd-accordion-item>
308
+ `,
309
+ parameters: {
310
+ docs: {
311
+ description: {
312
+ story: "Starts collapsed — click the text to expand and see the icon switch from bd-arrow-down-icon to bd-arrow-up-icon."
313
+ }
314
+ }
315
+ }
316
+ };
317
+
318
+
319
+ // ─── Default plus/minus vs chevron, side by side ───────────────────────────────
320
+
321
+ export const DefaultVsChevron = {
322
+ name : "Default plus/minus vs chevron",
323
+ render: () => html`
324
+ <div style="display: flex; flex-direction: column; gap: 32px;">
325
+ <div>
326
+ <bd-p kind="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Default (plus/minus, left icon)</bd-p>
327
+ <bd-accordion-item title="Default accordion item">
328
+ <p>Regular accordion content, unaffected by the new chevron variant.</p>
329
+ </bd-accordion-item>
330
+ </div>
331
+
332
+ <div>
333
+ <bd-p kind="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Chevron (plain text, right arrow icon, no border)</bd-p>
334
+ <bd-accordion-item chevron title="Chevron accordion item">
335
+ <p>Same underlying component, opt-in chevron styling via the chevron attribute.</p>
336
+ </bd-accordion-item>
337
+ </div>
338
+ </div>
339
+ `,
340
+ parameters: {
341
+ docs: {
342
+ description: {
343
+ story: "The two styles side by side, demonstrating that the chevron attribute is purely additive — existing default accordion items are completely unaffected."
344
+ }
345
+ }
346
+ }
347
+ };
348
+ // ─── Chevron variant — operational details (light table variant) ───────────
349
+
350
+ export const OperationalDetailsAccordion = {
351
+ name : "Chevron variant — Operational details (light table)",
352
+ render: () => html`
353
+ <div style="max-width: 900px;">
354
+ <bd-h as="h2" font-weight="700" style="margin: 0 0 8px;">How it runs</bd-h>
355
+ <bd-p kind="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
356
+ AI Guardian installs from a signed macOS installer and runs as a background service; the rows below list how it installs, where analysis happens, and what the BETA costs.
357
+ </bd-p>
358
+
359
+ <bd-accordion-item chevron title="Show operational details (11 rows)">
360
+ <bd-compatibility-table
361
+ variant="light"
362
+ .rows=${[
363
+ { label: "Runs as", value: "Background service on the endpoint" },
364
+ { label: "Install method", value: "Download the macOS installer (.dmg)" },
365
+ { label: "System permissions required", value: "Granted during install, when the Bitdefender agent asks" },
366
+ { label: "Installer", value: "Signed with a Bitdefender Apple Developer ID and recognised by macOS" },
367
+ { label: "Agent version checks", value: "Handled by the installer" },
368
+ { label: "Where analysis happens", value: "On-device, with some checks (such as URL reputation) using Bitdefender cloud services" },
369
+ { label: "Prompt data", value: "Analysed on-device — prompts never leave your Mac" },
370
+ { label: "Offline operation", value: "Some features" },
371
+ { label: "Performance overhead", value: "Designed to be minimal; not yet measured" },
372
+ { label: "Availability", value: "Open BETA, free download" },
373
+ { label: "Price during BETA", value: "Free" }
374
+ ]}
375
+ ></bd-compatibility-table>
376
+ </bd-accordion-item>
377
+ </div>
378
+ `,
379
+ parameters: {
380
+ docs: {
381
+ description: {
382
+ story: "Same chevron bd-accordion-item pattern as the risk mapping example, this time revealing a bd-compatibility-table in the new light variant — no outer border/background, just a 2-column grid of label/value rows with thin dividers. Matches the \"How it runs\" reference exactly."
383
+ }
384
+ }
385
+ }
243
386
  };
@@ -0,0 +1,92 @@
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-agentendpoints-wrapper {
10
+ max-width: var(--layout-ensemble-max-width, 1200px);
11
+ margin: 0 auto;
12
+ padding: var(--spacing-48) var(--layout-ensemble-inline-padding, var(--spacing-24));
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ .bd-agentendpoints-eyebrow {
17
+ display: block;
18
+ margin: 0 0 var(--spacing-8);
19
+ color: var(--color-blue-500);
20
+ }
21
+
22
+ .bd-agentendpoints-title {
23
+ display: block;
24
+ margin: 0 0 var(--spacing-16);
25
+ color: var(--color-neutral-1000);
26
+ line-height: var(--typography-lineHeight-tight, 1.1);
27
+ }
28
+
29
+ .bd-agentendpoints-description {
30
+ display: block;
31
+ margin: 0 0 var(--spacing-24);
32
+ color: var(--color-neutral-600);
33
+ max-width: 70ch;
34
+ }
35
+
36
+ .bd-agentendpoints-row {
37
+ display: flex;
38
+ flex-wrap: wrap;
39
+ gap: var(--spacing-12);
40
+ margin-bottom: var(--spacing-12);
41
+ }
42
+
43
+ .bd-agentendpoints-row:last-of-type {
44
+ margin-bottom: 0;
45
+ }
46
+
47
+ /* === button--outline-white ===
48
+ White pill button with a thin gray border, rounded corners — used both
49
+ for the /endpoint links (with a leading arrow, monospace label) and the
50
+ "Ask <assistant>" links (with a leading brand icon). Reusable class,
51
+ not scoped to this component only. */
52
+ .button--outline-white {
53
+ display: inline-flex;
54
+ align-items: center;
55
+ gap: var(--spacing-8);
56
+ padding: var(--spacing-10, 10px) var(--spacing-16);
57
+ background: var(--color-neutral-0, #fff);
58
+ border: 1px solid var(--color-neutral-200, #e5e7eb);
59
+ border-radius: var(--radius-full, 999px);
60
+ color: var(--color-neutral-800);
61
+ font-size: var(--typography-fontSize-sm);
62
+ font-weight: var(--typography-fontWeight-medium, 500);
63
+ text-decoration: none;
64
+ white-space: nowrap;
65
+ transition: border-color 0.2s ease, background 0.2s ease;
66
+ }
67
+
68
+ .button--outline-white:hover {
69
+ border-color: var(--color-blue-300, #93c5fd);
70
+ background: var(--color-blue-50, #eef4ff);
71
+ }
72
+
73
+ .bd-agentendpoints-arrow {
74
+ color: var(--color-neutral-400, #9ca3af);
75
+ }
76
+
77
+ .bd-agentendpoints-mono {
78
+ font-family: var(--typography-fontFamily-mono, monospace);
79
+ color: var(--color-neutral-700);
80
+ }
81
+
82
+ .bd-agentendpoints-icon {
83
+ display: block;
84
+ flex-shrink: 0;
85
+ }
86
+
87
+ @media (max-width: 599px) {
88
+ .bd-agentendpoints-wrapper {
89
+ padding: var(--spacing-32) var(--spacing-24);
90
+ }
91
+ }
92
+ `;
@@ -0,0 +1,86 @@
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 agentEndpointsCSS from "./agent-endpoints.css.js";
6
+
7
+ class AgentEndpoints extends LitElement {
8
+ static properties = {
9
+ eyebrow : { type: String },
10
+ title : { type: String },
11
+ description: { type: String },
12
+ endpoints : { type: Array }, // [{ label: String, href: String }]
13
+ assistants : { type: Array } // [{ label: String, href: String, icon: String }]
14
+ };
15
+
16
+ static styles = [tokens, agentEndpointsCSS];
17
+
18
+ constructor() {
19
+ super();
20
+ this.eyebrow = "";
21
+ this.title = "";
22
+ this.description = "";
23
+ this.endpoints = [];
24
+ this.assistants = [];
25
+ }
26
+
27
+ render() {
28
+ return html`
29
+ <div class="bd-agentendpoints-wrapper">
30
+ ${this.eyebrow
31
+ ? html`<bd-p kind="regular" font-weight="var(--typography-fontWeight-semibold, 600)" class="bd-agentendpoints-eyebrow"><slot name="eyebrow">${this.eyebrow}</slot></bd-p>`
32
+ : nothing}
33
+
34
+ ${this.title
35
+ ? html`<bd-h as="h2" class="bd-agentendpoints-title"><slot name="title">${this.title}</slot></bd-h>`
36
+ : nothing}
37
+
38
+ ${this.description
39
+ ? html`<bd-p kind="regular" class="bd-agentendpoints-description"><slot name="description">${this.description}</slot></bd-p>`
40
+ : nothing}
41
+
42
+ ${this.endpoints && this.endpoints.length
43
+ ? html`
44
+ <div class="bd-agentendpoints-row">
45
+ ${this.endpoints.map(
46
+ (ep) => html`
47
+ <a class="button--outline-white" href=${ep.href} target="_blank" rel="noopener noreferrer">
48
+ <span class="bd-agentendpoints-arrow" aria-hidden="true">→</span>
49
+ <span class="bd-agentendpoints-mono">${ep.label}</span>
50
+ </a>
51
+ `
52
+ )}
53
+ </div>
54
+ `
55
+ : nothing}
56
+
57
+ ${this.assistants && this.assistants.length
58
+ ? html`
59
+ <div class="bd-agentendpoints-row">
60
+ ${this.assistants.map(
61
+ (a) => html`
62
+ <a
63
+ class="button--outline-white"
64
+ href=${a.href}
65
+ target="_blank"
66
+ rel="noopener noreferrer"
67
+ aria-label="${a.label} (opens in new tab)"
68
+ >
69
+ ${a.icon
70
+ ? html`<img src=${a.icon} alt="" class="bd-agentendpoints-icon" width="20" height="20" loading="lazy" />`
71
+ : nothing}
72
+ <span>${a.label}</span>
73
+ </a>
74
+ `
75
+ )}
76
+ </div>
77
+ `
78
+ : nothing}
79
+
80
+ <slot name="rows"></slot>
81
+ </div>
82
+ `;
83
+ }
84
+ }
85
+
86
+ customElements.define("bd-agent-endpoints", AgentEndpoints);