@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.
- package/CHANGELOG.md +15 -0
- package/package.json +4 -4
- package/src/components/accordion/accordion-bg.css.js +6 -1
- package/src/components/accordion/accordion-bg.js +3 -1
- package/src/components/accordion/accordion-bg.stories.js +49 -0
- package/src/components/accordion/accordion.css.js +40 -0
- package/src/components/accordion/accordion.js +31 -0
- package/src/components/accordion/accordion.stories.js +147 -4
- package/src/components/agent-endpoints/agent-endpoints.css.js +92 -0
- package/src/components/agent-endpoints/agent-endpoints.js +86 -0
- package/src/components/agent-endpoints/agent-endpoints.stories.js +148 -0
- package/src/components/ai-guardian-demo.stories.js +669 -0
- package/src/components/awards/awards-flex.css.js +169 -0
- package/src/components/awards/awards-flex.js +269 -0
- package/src/components/awards/awards-flex.stories.js +657 -0
- package/src/components/bento-grid/bento-grid.css.js +57 -0
- package/src/components/bento-grid/bento-grid.js +186 -0
- package/src/components/bento-grid/bento-grid.stories.js +440 -0
- package/src/components/bento-grid/bento-item.css.js +79 -0
- package/src/components/bento-grid/bento-item.js +54 -0
- package/src/components/button/button.css.js +26 -0
- package/src/components/button/button.js +8 -0
- package/src/components/button/button.stories.js +12 -0
- package/src/components/comparison-panel/comparison-panel.css.js +104 -0
- package/src/components/comparison-panel/comparison-panel.js +100 -0
- package/src/components/comparison-panel/comparison-panel.stories.js +223 -0
- package/src/components/compatibility-table/compatibility-table.css.js +243 -0
- package/src/components/compatibility-table/compatibility-table.js +123 -0
- package/src/components/compatibility-table/compatibility-table.stories.js +189 -0
- package/src/components/cta-banner/cta-banner.css.js +60 -0
- package/src/components/cta-banner/cta-banner.js +63 -0
- package/src/components/dropdown/dropdown.css.js +1 -1
- package/src/components/footer/footer.css.js +0 -1
- package/src/components/header/header-code.css.js +125 -0
- package/src/components/header/header-code.js +69 -0
- package/src/components/header/header-code.stories.js +226 -0
- package/src/components/heading/heading.css.js +3 -0
- package/src/components/icons/bd-ai-icon.js +27 -0
- package/src/components/list/list-item/list-item.css.js +3 -3
- package/src/components/list/list-item/list-item.js +10 -4
- package/src/components/overview/overview.css.js +121 -0
- package/src/components/overview/overview.js +63 -0
- package/src/components/overview/overview.stories.js +193 -0
- package/src/components/page-switcher/page-switcher.css.js +100 -0
- package/src/components/page-switcher/page-switcher.js +42 -0
- package/src/components/paragraph/paragraph.js +7 -3
- package/src/components/process-steps/process-steps.css.js +95 -0
- package/src/components/process-steps/process-steps.js +72 -0
- package/src/components/process-steps/process-steps.stories.js +144 -0
- package/src/components/quick-answer/quick-answer.css.js +67 -0
- package/src/components/quick-answer/quick-answer.js +59 -0
- package/src/components/quick-answer/quick-answer.stories.js +160 -0
- package/src/components/terminal/terminal-cursor.js +49 -0
- package/src/components/terminal/terminal-message.css.js +161 -0
- package/src/components/terminal/terminal-message.js +169 -0
- package/src/components/terminal/terminal-message.stories.js +321 -0
- package/src/components/trust-panel/trust-panel.css.js +167 -0
- package/src/components/trust-panel/trust-panel.js +116 -0
- package/src/components/trust-panel/trust-panel.stories.js +234 -0
- package/src/tokens/tokens.css +1 -1
- package/src/components/tabsComponent/tabsComponent.css.js +0 -267
- package/src/components/tabsComponent/tabsComponent.js +0 -193
- package/src/components/tabsComponent/tabsComponent.stories.js +0 -134
- package/src/components/tabsComponentFamily/tabsComponentFamily.css.js +0 -181
- package/src/components/tabsComponentFamily/tabsComponentFamily.js +0 -180
- package/src/components/tabsComponentFamily/tabsComponentFamily.stories.js +0 -319
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
width: 100%;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* === HEADER (eyebrow / title / description) === */
|
|
11
|
+
.bd-bentogrid-header {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
align-items: flex-start;
|
|
15
|
+
gap: var(--spacing-8);
|
|
16
|
+
margin-bottom: var(--spacing-48);
|
|
17
|
+
max-width: 70ch;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.bd-bentogrid-eyebrow {
|
|
21
|
+
display: block;
|
|
22
|
+
margin: 0;
|
|
23
|
+
color: var(--color-blue-500);
|
|
24
|
+
--typography-body-regular-fontWeight: var(--typography-fontWeight-bold, 700);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.bd-bentogrid-title {
|
|
28
|
+
display: block;
|
|
29
|
+
margin: 0;
|
|
30
|
+
color: var(--color-neutral-1000);
|
|
31
|
+
line-height: var(--typography-lineHeight-tight, 1.1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.bd-bentogrid-description {
|
|
35
|
+
display: block;
|
|
36
|
+
margin: 0;
|
|
37
|
+
color: var(--color-neutral-600);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* === GRID === */
|
|
41
|
+
.bd-bentogrid-track {
|
|
42
|
+
display: grid;
|
|
43
|
+
grid-template-columns: repeat(var(--bd-bento-total-units, 24), minmax(0, 1fr));
|
|
44
|
+
gap: var(--bd-bento-gap, 24px);
|
|
45
|
+
width: 100%;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
::slotted(bd-bento-item) {
|
|
49
|
+
grid-column: span var(--bd-bento-span, 24);
|
|
50
|
+
min-width: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* featured items always take the full row width */
|
|
54
|
+
::slotted(bd-bento-item[priority="featured"]) {
|
|
55
|
+
grid-column: span var(--bd-bento-total-units, 24) !important;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
@@ -0,0 +1,186 @@
|
|
|
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 bentoGridCSS from "./bento-grid.css.js";
|
|
6
|
+
import "./bento-item.js";
|
|
7
|
+
|
|
8
|
+
const BREAKPOINT_WIDTHS = { xl: 1280, lg: 960, md: 640 };
|
|
9
|
+
const DEFAULT_GAP = { xl: 24, lg: 24, md: 20, sm: 16 };
|
|
10
|
+
const TOTAL_UNITS = 24; // fine-grained grid columns used purely for weighted spans
|
|
11
|
+
|
|
12
|
+
function resolveBreakpoint(width, maxColumns, minCardWidth) {
|
|
13
|
+
const bp =
|
|
14
|
+
width >= BREAKPOINT_WIDTHS.xl
|
|
15
|
+
? "xl" :
|
|
16
|
+
width >= BREAKPOINT_WIDTHS.lg
|
|
17
|
+
? "lg" :
|
|
18
|
+
width >= BREAKPOINT_WIDTHS.md ? "md" : "sm";
|
|
19
|
+
|
|
20
|
+
let columns = bp === "sm" ? 1 : bp === "md" ? 2 : Math.max(1, Math.min(2, maxColumns));
|
|
21
|
+
const gap = DEFAULT_GAP[bp];
|
|
22
|
+
|
|
23
|
+
while (columns > 1) {
|
|
24
|
+
const cardWidth = (width - gap * (columns - 1)) / columns;
|
|
25
|
+
if (cardWidth >= minCardWidth) break;
|
|
26
|
+
columns -= 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { bp, columns, gap };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class BentoGrid extends LitElement {
|
|
33
|
+
static properties = {
|
|
34
|
+
eyebrow : { type: String },
|
|
35
|
+
title : { type: String },
|
|
36
|
+
description : { type: String },
|
|
37
|
+
maxColumns : { type: Number, attribute: "max-columns" },
|
|
38
|
+
minCardWidth: { type: Number, attribute: "min-card-width" },
|
|
39
|
+
// Fixed wide/narrow ratio applied to every pair, e.g. 0.7 = 70/30.
|
|
40
|
+
wideShare : { type: Number, attribute: "wide-share" },
|
|
41
|
+
_columns : { state: true },
|
|
42
|
+
_gap : { state: true }
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
static styles = [tokens, bentoGridCSS];
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
super();
|
|
49
|
+
this.eyebrow = "";
|
|
50
|
+
this.title = "";
|
|
51
|
+
this.description = "";
|
|
52
|
+
this.maxColumns = 2;
|
|
53
|
+
this.minCardWidth = 260;
|
|
54
|
+
this.wideShare = 0.7;
|
|
55
|
+
this._columns = 2;
|
|
56
|
+
this._gap = 24;
|
|
57
|
+
this._resizeObserver = null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
connectedCallback() {
|
|
61
|
+
super.connectedCallback();
|
|
62
|
+
this._resizeObserver = new ResizeObserver(() => this._relayout());
|
|
63
|
+
this._resizeObserver.observe(this);
|
|
64
|
+
this._relayout();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
disconnectedCallback() {
|
|
68
|
+
super.disconnectedCallback();
|
|
69
|
+
this._resizeObserver?.disconnect();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get _items() {
|
|
73
|
+
return [...this.children].filter((el) => el.tagName === "BD-BENTO-ITEM");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Assigns each item a `grid-column: span N` out of TOTAL_UNITS invisible
|
|
77
|
+
// grid columns, instead of a flex-basis percentage. CSS Grid subtracts
|
|
78
|
+
// `gap` from the available track space BEFORE distributing column widths,
|
|
79
|
+
// so two items whose spans sum to TOTAL_UNITS always fit on the same row
|
|
80
|
+
// with the gap properly accounted for.
|
|
81
|
+
//
|
|
82
|
+
// Rows are formed by walking items in DOM order and consuming exactly 2
|
|
83
|
+
// "slots" per row UNLESS an item is priority="featured", in which case it
|
|
84
|
+
// consumes the whole row by itself (span = TOTAL_UNITS) and does not pair
|
|
85
|
+
// with anything.
|
|
86
|
+
//
|
|
87
|
+
// Within a pair, the wide/narrow side follows a repeating 3-pair cycle,
|
|
88
|
+
// NOT content length: pair 0 (rows 1-2) is wide-then-narrow, pairs 1 and 2
|
|
89
|
+
// (rows 3-4, 5-6) are narrow-then-wide, then the cycle repeats.
|
|
90
|
+
_applyWeights() {
|
|
91
|
+
const items = this._items;
|
|
92
|
+
let i = 0;
|
|
93
|
+
let pairIndex = 0; // counts pairs only (featured/solo rows don't affect the pattern)
|
|
94
|
+
|
|
95
|
+
const wideSpan = Math.round(this.wideShare * TOTAL_UNITS);
|
|
96
|
+
const narrowSpan = TOTAL_UNITS - wideSpan;
|
|
97
|
+
|
|
98
|
+
while (i < items.length) {
|
|
99
|
+
const current = items[i];
|
|
100
|
+
|
|
101
|
+
if (current.getAttribute("priority") === "featured") {
|
|
102
|
+
current.style.setProperty("--bd-bento-span", String(TOTAL_UNITS));
|
|
103
|
+
i += 1;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const next = items[i + 1];
|
|
108
|
+
const nextIsFeatured = next && next.getAttribute("priority") === "featured";
|
|
109
|
+
|
|
110
|
+
if (!next || nextIsFeatured) {
|
|
111
|
+
// odd one out (last item, or blocked by a featured item next) — full width
|
|
112
|
+
current.style.setProperty("--bd-bento-span", String(TOTAL_UNITS));
|
|
113
|
+
i += 1;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const firstIsWide = pairIndex % 3 === 0;
|
|
118
|
+
|
|
119
|
+
current.style.setProperty("--bd-bento-span", String(firstIsWide ? wideSpan : narrowSpan));
|
|
120
|
+
next.style.setProperty("--bd-bento-span", String(firstIsWide ? narrowSpan : wideSpan));
|
|
121
|
+
|
|
122
|
+
i += 2;
|
|
123
|
+
pairIndex += 1;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
_relayout() {
|
|
128
|
+
const width = this.clientWidth || 960;
|
|
129
|
+
const { columns, gap } = resolveBreakpoint(width, this.maxColumns, this.minCardWidth);
|
|
130
|
+
this._columns = columns;
|
|
131
|
+
this._gap = gap;
|
|
132
|
+
this.style.setProperty("--bd-bento-gap", `${gap}px`);
|
|
133
|
+
this.style.setProperty("--bd-bento-total-units", String(TOTAL_UNITS));
|
|
134
|
+
|
|
135
|
+
if (columns <= 1) {
|
|
136
|
+
this._items.forEach((item) => item.style.setProperty("--bd-bento-span", String(TOTAL_UNITS)));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this._applyWeights();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
_onSlotChange() {
|
|
144
|
+
this._relayout();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
render() {
|
|
148
|
+
return html`
|
|
149
|
+
${this.eyebrow || this.title || this.description
|
|
150
|
+
? html`
|
|
151
|
+
<div class="bd-bentogrid-header">
|
|
152
|
+
${this.eyebrow
|
|
153
|
+
? html`
|
|
154
|
+
<bd-p kind="regular" class="bd-bentogrid-eyebrow">
|
|
155
|
+
<slot name="eyebrow">${this.eyebrow}</slot>
|
|
156
|
+
</bd-p>
|
|
157
|
+
`
|
|
158
|
+
: nothing}
|
|
159
|
+
|
|
160
|
+
${this.title
|
|
161
|
+
? html`
|
|
162
|
+
<bd-h as="h2" class="bd-bentogrid-title">
|
|
163
|
+
<slot name="title">${this.title}</slot>
|
|
164
|
+
</bd-h>
|
|
165
|
+
`
|
|
166
|
+
: nothing}
|
|
167
|
+
|
|
168
|
+
${this.description
|
|
169
|
+
? html`
|
|
170
|
+
<bd-p kind="regular" class="bd-bentogrid-description">
|
|
171
|
+
<slot name="description">${this.description}</slot>
|
|
172
|
+
</bd-p>
|
|
173
|
+
`
|
|
174
|
+
: nothing}
|
|
175
|
+
</div>
|
|
176
|
+
`
|
|
177
|
+
: nothing}
|
|
178
|
+
|
|
179
|
+
<div class="bd-bentogrid-track" role="list">
|
|
180
|
+
<slot @slotchange=${this._onSlotChange}></slot>
|
|
181
|
+
</div>
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
customElements.define("bd-bento-grid", BentoGrid);
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import "../icons/analysis-icon.js";
|
|
3
|
+
import "../icons/arrow-up-icon.js";
|
|
4
|
+
import "../icons/family-icon.js";
|
|
5
|
+
import "../icons/globe-icon.js";
|
|
6
|
+
import "../icons/individual-icon.js";
|
|
7
|
+
import "../icons/machine-learning-icon.js";
|
|
8
|
+
import "./bento-grid.js";
|
|
9
|
+
import "./bento-item.js";
|
|
10
|
+
export default {
|
|
11
|
+
title : "Components/Bento Grid",
|
|
12
|
+
component : "bd-bento-grid",
|
|
13
|
+
tags : ["autodocs"],
|
|
14
|
+
parameters: {
|
|
15
|
+
layout: "padded",
|
|
16
|
+
docs : {
|
|
17
|
+
description: {
|
|
18
|
+
component: `
|
|
19
|
+
**BentoGrid** is a fully automatic responsive grid of \`bd-bento-item\` cards, matching
|
|
20
|
+
the visual language of \`bd-card-item\` as a standalone component. It can optionally
|
|
21
|
+
render its own header block (eyebrow + title + description) above the cards, so the
|
|
22
|
+
whole "Protection" section — heading and grid — is a single component.
|
|
23
|
+
|
|
24
|
+
Zero configuration needed for the grid itself:
|
|
25
|
+
- Measures its own width and resolves 1 or 2 columns automatically (2 max, never more).
|
|
26
|
+
- Pairs items two at a time in DOM order; within each pair, the wide/narrow side
|
|
27
|
+
follows a repeating 3-pair cycle (never a flat 50/50).
|
|
28
|
+
- \`priority="featured"\` always takes the full row width by itself and never pairs.
|
|
29
|
+
- Recalculates automatically on resize and whenever items are added/removed.
|
|
30
|
+
|
|
31
|
+
### Header block
|
|
32
|
+
|
|
33
|
+
\`eyebrow\`, \`title\`, and \`description\` are all optional and independent — set any
|
|
34
|
+
combination of them (or none) and only the ones with content render. Each also has a
|
|
35
|
+
matching named slot (\`eyebrow\`, \`title\`, \`description\`) if you need markup instead
|
|
36
|
+
of plain text.
|
|
37
|
+
|
|
38
|
+
### Usage
|
|
39
|
+
\`\`\`html
|
|
40
|
+
<bd-bento-grid
|
|
41
|
+
eyebrow="Protection"
|
|
42
|
+
title="What does AI Guardian protect against?"
|
|
43
|
+
description="AI Guardian watches how an AI agent behaves and secures six of the highest-risk areas in agentic workflows. Each protection returns a verdict in real time."
|
|
44
|
+
>
|
|
45
|
+
<bd-bento-item title="MCP tool protection">...</bd-bento-item>
|
|
46
|
+
<bd-bento-item title="Skill vetting">...</bd-bento-item>
|
|
47
|
+
</bd-bento-grid>
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
### bd-bento-grid Attributes
|
|
51
|
+
| Attribute | Type | Default | Description |
|
|
52
|
+
|----------------------|--------|---------|----------------------------------------------------------------------|
|
|
53
|
+
| \`eyebrow\` | String | \`""\` | Small blue label above the title |
|
|
54
|
+
| \`title\` | String | \`""\` | Heading above the grid |
|
|
55
|
+
| \`description\` | String | \`""\` | Paragraph under the title |
|
|
56
|
+
| \`max-columns\` | Number | \`2\` | Hard cap on columns |
|
|
57
|
+
| \`min-card-width\` | Number | \`260\` | Minimum px before the grid drops to 1 column |
|
|
58
|
+
| \`wide-share\` | Number | \`0.7\` | Wide/narrow ratio applied within each pair (0.7 = 70/30) |
|
|
59
|
+
|
|
60
|
+
### Slots
|
|
61
|
+
| Slot | Description |
|
|
62
|
+
|-----------------|--------------------------------------------------------------|
|
|
63
|
+
| \`eyebrow\` | Overrides the \`eyebrow\` attribute if content is provided |
|
|
64
|
+
| \`title\` | Overrides the \`title\` attribute if content is provided |
|
|
65
|
+
| \`description\` | Overrides the \`description\` attribute if content is provided |
|
|
66
|
+
| (default) | The \`bd-bento-item\` cards themselves |
|
|
67
|
+
|
|
68
|
+
### bd-bento-item Attributes
|
|
69
|
+
| Attribute | Type | Default | Description |
|
|
70
|
+
|-----------------|--------|---------------|--------------------------------------------------|
|
|
71
|
+
| \`title\` | String | \`""\` | Card title |
|
|
72
|
+
| \`body\` | String | \`""\` | Card description (or slot a bd-p) |
|
|
73
|
+
| \`icon\` | String | \`""\` | Icon URL (or use the icon slot) |
|
|
74
|
+
| \`priority\` | String | \`"standard"\` | \`"standard"\` or \`"featured"\` (featured = always full width, never paired) |
|
|
75
|
+
`
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const icons = [
|
|
82
|
+
html`<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>`,
|
|
83
|
+
html`<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>`,
|
|
84
|
+
html`<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>`,
|
|
85
|
+
html`<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>`,
|
|
86
|
+
html`<bd-family-icon slot="icon" width="32" height="32" color="#006DFF"></bd-family-icon>`,
|
|
87
|
+
html`<bd-arrow-up-icon slot="icon" width="32" height="32" color="#006DFF"></bd-arrow-up-icon>`
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const titles = [
|
|
91
|
+
"AI Protection", "Multi-layer Security", "VPN Included", "Parental Controls",
|
|
92
|
+
"Identity Protection", "Password Manager"
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
const descriptions = [
|
|
96
|
+
"Powered by machine learning and behavioral analysis.",
|
|
97
|
+
"Multiple independent protection layers stop any attack.",
|
|
98
|
+
"Unlimited encrypted VPN traffic for all your devices.",
|
|
99
|
+
"Advanced controls to protect your children online.",
|
|
100
|
+
"Goes beyond credit monitoring to protect your identity.",
|
|
101
|
+
"Store and autofill passwords securely across all devices."
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
const makeItems = (count) => Array.from({ length: count }, (_, i) => html`
|
|
105
|
+
<bd-bento-item title="${titles[i % titles.length]}">
|
|
106
|
+
${icons[i % icons.length]}
|
|
107
|
+
<bd-p>${descriptions[i % descriptions.length]}</bd-p>
|
|
108
|
+
</bd-bento-item>
|
|
109
|
+
`);
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// ─── 1. Default — 4 items, zero config ─────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
export const Default = {
|
|
115
|
+
name : "1. Default (4 Items, Zero Config)",
|
|
116
|
+
render: () => html`
|
|
117
|
+
<bd-bento-grid>
|
|
118
|
+
${makeItems(4)}
|
|
119
|
+
</bd-bento-grid>
|
|
120
|
+
`,
|
|
121
|
+
parameters: {
|
|
122
|
+
docs: {
|
|
123
|
+
description: {
|
|
124
|
+
story: "No attributes — columns and the wide/narrow split are computed automatically, no header block rendered since eyebrow/title/description are all empty."
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
// ─── 2. With header — matches the reference exactly ────────────────────────
|
|
132
|
+
|
|
133
|
+
export const WithHeader = {
|
|
134
|
+
name : "2. With Header (Matches Reference)",
|
|
135
|
+
render: () => html`
|
|
136
|
+
<bd-bento-grid
|
|
137
|
+
eyebrow="Protection"
|
|
138
|
+
title="What does AI Guardian protect against?"
|
|
139
|
+
description="AI Guardian watches how an AI agent behaves and secures six of the highest-risk areas in agentic workflows. Each protection returns a verdict in real time."
|
|
140
|
+
>
|
|
141
|
+
<bd-bento-item title="MCP tool protection">
|
|
142
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
143
|
+
<bd-p>Detects and blocks malicious MCP tools (tool poisoning) before an agent can call them.</bd-p>
|
|
144
|
+
</bd-bento-item>
|
|
145
|
+
<bd-bento-item title="Skill vetting">
|
|
146
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
147
|
+
<bd-p>Scans and validates agent skills before they run, so unreviewed skills don't execute silently.</bd-p>
|
|
148
|
+
</bd-bento-item>
|
|
149
|
+
<bd-bento-item title="Prompt injection detection">
|
|
150
|
+
<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
|
|
151
|
+
<bd-p>Catches attempts to hijack an agent through crafted inputs and hidden instructions.</bd-p>
|
|
152
|
+
</bd-bento-item>
|
|
153
|
+
<bd-bento-item title="Tool-call monitoring">
|
|
154
|
+
<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
|
|
155
|
+
<bd-p>Watches every tool an agent invokes in real time, building an auditable record of actions.</bd-p>
|
|
156
|
+
</bd-bento-item>
|
|
157
|
+
<bd-bento-item title="Credential leak detection">
|
|
158
|
+
<bd-family-icon slot="icon" width="32" height="32" color="#006DFF"></bd-family-icon>
|
|
159
|
+
<bd-p>Detects exposure of secrets such as API keys before they leave the machine.</bd-p>
|
|
160
|
+
</bd-bento-item>
|
|
161
|
+
<bd-bento-item title="Sensitive file protection">
|
|
162
|
+
<bd-arrow-up-icon slot="icon" width="32" height="32" color="#006DFF"></bd-arrow-up-icon>
|
|
163
|
+
<bd-p>Blocks unauthorised access to sensitive files such as SSH keys and system credentials.</bd-p>
|
|
164
|
+
</bd-bento-item>
|
|
165
|
+
</bd-bento-grid>
|
|
166
|
+
`,
|
|
167
|
+
parameters: {
|
|
168
|
+
docs: {
|
|
169
|
+
description: {
|
|
170
|
+
story: "eyebrow + title + description rendered as the grid's own header block, matching the reference screenshot exactly."
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// ─── 3. Six items, matches the reference: featured + 2 pairs ──────────────
|
|
178
|
+
|
|
179
|
+
export const SixItems = {
|
|
180
|
+
name : "3. Six Items (Featured + Pairs)",
|
|
181
|
+
render: () => html`
|
|
182
|
+
<bd-bento-grid>
|
|
183
|
+
<bd-bento-item title="AI Guardian" priority="featured">
|
|
184
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
185
|
+
<bd-p>A unified security layer for autonomous AI agents — inspects tool calls, file access, prompts, and skills in real time.</bd-p>
|
|
186
|
+
</bd-bento-item>
|
|
187
|
+
<bd-bento-item title="AI Protection">
|
|
188
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
189
|
+
<bd-p>Powered by machine learning and behavioral analysis.</bd-p>
|
|
190
|
+
</bd-bento-item>
|
|
191
|
+
<bd-bento-item title="Multi-layer Security">
|
|
192
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
193
|
+
<bd-p>Multiple independent protection layers stop any attack.</bd-p>
|
|
194
|
+
</bd-bento-item>
|
|
195
|
+
<bd-bento-item title="VPN Included">
|
|
196
|
+
<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
|
|
197
|
+
<bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
|
|
198
|
+
</bd-bento-item>
|
|
199
|
+
<bd-bento-item title="Parental Controls">
|
|
200
|
+
<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
|
|
201
|
+
<bd-p>Advanced controls to protect your children online.</bd-p>
|
|
202
|
+
</bd-bento-item>
|
|
203
|
+
</bd-bento-grid>
|
|
204
|
+
`,
|
|
205
|
+
parameters: {
|
|
206
|
+
docs: {
|
|
207
|
+
description: {
|
|
208
|
+
story: "priority=\"featured\" forces AI Guardian to take the full row width and never pair. The remaining 4 items then pair as (AI Protection, Multi-layer Security) and (VPN Included, Parental Controls)."
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
// ─── 4. Without featured — plain 6-item pairing ────────────────────────────
|
|
216
|
+
|
|
217
|
+
export const SixItemsNoFeatured = {
|
|
218
|
+
name : "4. Six Items — No Featured (All Paired)",
|
|
219
|
+
render: () => html`
|
|
220
|
+
<bd-bento-grid>
|
|
221
|
+
${makeItems(6)}
|
|
222
|
+
</bd-bento-grid>
|
|
223
|
+
`,
|
|
224
|
+
parameters: {
|
|
225
|
+
docs: {
|
|
226
|
+
description: {
|
|
227
|
+
story: "All 6 items are standard priority — they pair up as 3 rows of 2, each with an automatic wide/narrow split."
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
// ─── 5. Single column (narrow container) ───────────────────────────────────
|
|
235
|
+
|
|
236
|
+
export const SingleColumn = {
|
|
237
|
+
name : "5. Single Column (Narrow Container)",
|
|
238
|
+
render: () => html`
|
|
239
|
+
<div style="max-width: 360px;">
|
|
240
|
+
<bd-bento-grid eyebrow="Protection" title="Compact view">
|
|
241
|
+
${makeItems(3)}
|
|
242
|
+
</bd-bento-grid>
|
|
243
|
+
</div>
|
|
244
|
+
`,
|
|
245
|
+
parameters: {
|
|
246
|
+
docs: {
|
|
247
|
+
description: {
|
|
248
|
+
story: "Wrapped in a 360px-wide container — collapses to a single column automatically, header block wraps naturally too."
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
// ─── 6. Odd item count ───────────────────────────────────────────────────────
|
|
256
|
+
|
|
257
|
+
export const OddItemCount = {
|
|
258
|
+
name : "6. Odd Item Count (Uneven Last Row)",
|
|
259
|
+
render: () => html`
|
|
260
|
+
<bd-bento-grid>
|
|
261
|
+
${makeItems(5)}
|
|
262
|
+
</bd-bento-grid>
|
|
263
|
+
`,
|
|
264
|
+
parameters: {
|
|
265
|
+
docs: {
|
|
266
|
+
description: {
|
|
267
|
+
story: "5 items — pairs as (1,2)(3,4), with item 5 alone on the last row at full width."
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
// ─── 7. With CTA button ──────────────────────────────────────────────────────
|
|
275
|
+
|
|
276
|
+
export const WithCTA = {
|
|
277
|
+
name : "7. With CTA Button",
|
|
278
|
+
render: () => html`
|
|
279
|
+
<bd-bento-grid>
|
|
280
|
+
<bd-bento-item title="AI Protection">
|
|
281
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
282
|
+
<bd-p>Powered by machine learning and behavioral analysis.</bd-p>
|
|
283
|
+
<bd-button-link href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
284
|
+
</bd-bento-item>
|
|
285
|
+
<bd-bento-item title="Multi-layer Security">
|
|
286
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
287
|
+
<bd-p>Multiple independent protection layers stop any attack.</bd-p>
|
|
288
|
+
<bd-button-link href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
289
|
+
</bd-bento-item>
|
|
290
|
+
</bd-bento-grid>
|
|
291
|
+
`,
|
|
292
|
+
parameters: {
|
|
293
|
+
docs: {
|
|
294
|
+
description: {
|
|
295
|
+
story: "Uses the default slot to append a bd-button-link after the body paragraph."
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
// ─── 8. Text-only cards (no icons) ─────────────────────────────────────────
|
|
303
|
+
|
|
304
|
+
export const TextOnly = {
|
|
305
|
+
name : "8. Text-Only Cards (No Icons)",
|
|
306
|
+
render: () => html`
|
|
307
|
+
<bd-bento-grid>
|
|
308
|
+
${Array.from({ length: 4 }, (_, i) => html`
|
|
309
|
+
<bd-bento-item title="${titles[i]}">
|
|
310
|
+
<bd-p>${descriptions[i]}</bd-p>
|
|
311
|
+
</bd-bento-item>
|
|
312
|
+
`)}
|
|
313
|
+
</bd-bento-grid>
|
|
314
|
+
`,
|
|
315
|
+
parameters: {
|
|
316
|
+
docs: {
|
|
317
|
+
description: {
|
|
318
|
+
story: "No icon slot content — the icon wrapper collapses to its minimum reserved height."
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
// ─── 9. Nine items ───────────────────────────────────────────────────────────
|
|
326
|
+
|
|
327
|
+
export const NineItems = {
|
|
328
|
+
name : "9. Nine Items",
|
|
329
|
+
render: () => html`
|
|
330
|
+
<bd-bento-grid>
|
|
331
|
+
${makeItems(9)}
|
|
332
|
+
</bd-bento-grid>
|
|
333
|
+
`,
|
|
334
|
+
parameters: {
|
|
335
|
+
docs: {
|
|
336
|
+
description: {
|
|
337
|
+
story: "9 items — pairs as (1,2)(3,4)(5,6)(7,8), with item 9 alone at full width on the last row."
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
// ─── 10. Mixed short/long text — shows the automatic asymmetry clearly ────
|
|
345
|
+
|
|
346
|
+
export const MixedLengths = {
|
|
347
|
+
name : "10. Mixed Short/Long Text (Asymmetry Demo)",
|
|
348
|
+
render: () => html`
|
|
349
|
+
<bd-bento-grid>
|
|
350
|
+
<bd-bento-item title="Short">
|
|
351
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
352
|
+
<bd-p>Brief.</bd-p>
|
|
353
|
+
</bd-bento-item>
|
|
354
|
+
<bd-bento-item title="A much longer title with more to say">
|
|
355
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
356
|
+
<bd-p>This card has considerably more text in its description, so it automatically claims more horizontal space in this row than its shorter neighbor.</bd-p>
|
|
357
|
+
</bd-bento-item>
|
|
358
|
+
<bd-bento-item title="Roughly equal length here">
|
|
359
|
+
<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
|
|
360
|
+
<bd-p>And this one also has a moderate amount of descriptive text to compare against.</bd-p>
|
|
361
|
+
</bd-bento-item>
|
|
362
|
+
<bd-bento-item title="About the same as its neighbor">
|
|
363
|
+
<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
|
|
364
|
+
<bd-p>Similar text length on both sides of this row, so the minimum forced asymmetry kicks in instead.</bd-p>
|
|
365
|
+
</bd-bento-item>
|
|
366
|
+
</bd-bento-grid>
|
|
367
|
+
`,
|
|
368
|
+
parameters: {
|
|
369
|
+
docs: {
|
|
370
|
+
description: {
|
|
371
|
+
story: "First row: a clearly longer card claims more width. Second row: near-equal text still produces the minimum-forced split instead of a flat 50/50."
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// ─── 11. Twenty-seven items (stress test) ──────────────────────────────────
|
|
378
|
+
|
|
379
|
+
const bigTitleSet = [
|
|
380
|
+
"AI Protection", "Multi-layer Security", "VPN Included", "Parental Controls",
|
|
381
|
+
"Identity Protection", "Password Manager", "Anti-tracker", "Webcam Protection",
|
|
382
|
+
"Privacy Firewall", "Dark Web Monitor", "Ransomware Shield", "Safe Files",
|
|
383
|
+
"Wi-Fi Security Advisor", "Anti-theft", "Vulnerability Assessment",
|
|
384
|
+
"Microphone Monitor", "App Anomaly Detection", "Payment Protection",
|
|
385
|
+
"Social Network Protection", "Device Optimizer", "Scam Alert",
|
|
386
|
+
"Digital Identity Protection", "Data Breach Monitor", "Autopilot",
|
|
387
|
+
"Battery Saver", "OneClick Optimizer", "Rescue Environment"
|
|
388
|
+
];
|
|
389
|
+
|
|
390
|
+
const bigDescriptionSet = [
|
|
391
|
+
"Powered by machine learning and behavioral analysis.",
|
|
392
|
+
"Multiple independent protection layers stop any attack.",
|
|
393
|
+
"Unlimited encrypted VPN traffic for all your devices.",
|
|
394
|
+
"Advanced controls to protect your children online.",
|
|
395
|
+
"Goes beyond credit monitoring to protect your identity.",
|
|
396
|
+
"Store and autofill passwords securely across all devices.",
|
|
397
|
+
"Block trackers and keep your browsing activity private.",
|
|
398
|
+
"Prevent unauthorized access to your webcam.",
|
|
399
|
+
"Advanced firewall protection for your network.",
|
|
400
|
+
"Get instant alerts if your data appears on the dark web.",
|
|
401
|
+
"Blocks encryption attempts and restores affected files automatically.",
|
|
402
|
+
"Keeps important files safe from unauthorized changes.",
|
|
403
|
+
"Analyzes your wireless network for security weaknesses.",
|
|
404
|
+
"Locate, lock, or wipe a lost or stolen device remotely.",
|
|
405
|
+
"Scans installed apps and the OS for missing patches.",
|
|
406
|
+
"Alerts you when an app tries to access your microphone.",
|
|
407
|
+
"Detects unusual app behavior that could signal malware.",
|
|
408
|
+
"Extra checks for online banking and shopping sessions.",
|
|
409
|
+
"Flags suspicious links shared on social platforms.",
|
|
410
|
+
"Cleans up junk files and speeds up your system.",
|
|
411
|
+
"Recognizes scam attempts across calls, texts, and email.",
|
|
412
|
+
"Monitors the web for exposure of your personal data.",
|
|
413
|
+
"Automatically adjusts settings for the best experience.",
|
|
414
|
+
"Extends battery life during gaming or streaming.",
|
|
415
|
+
"Runs a full system tune-up in a single click.",
|
|
416
|
+
"A recovery environment for cleaning severe infections."
|
|
417
|
+
];
|
|
418
|
+
|
|
419
|
+
const makeBigItems = (count) => Array.from({ length: count }, (_, i) => html`
|
|
420
|
+
<bd-bento-item title="${bigTitleSet[i % bigTitleSet.length]}">
|
|
421
|
+
${icons[i % icons.length]}
|
|
422
|
+
<bd-p>${bigDescriptionSet[i % bigDescriptionSet.length]}</bd-p>
|
|
423
|
+
</bd-bento-item>
|
|
424
|
+
`);
|
|
425
|
+
|
|
426
|
+
export const TwentySevenItems = {
|
|
427
|
+
name : "11. Twenty-Seven Items (Stress Test)",
|
|
428
|
+
render: () => html`
|
|
429
|
+
<bd-bento-grid eyebrow="Protection" title="All 27 protections">
|
|
430
|
+
${makeBigItems(27)}
|
|
431
|
+
</bd-bento-grid>
|
|
432
|
+
`,
|
|
433
|
+
parameters: {
|
|
434
|
+
docs: {
|
|
435
|
+
description: {
|
|
436
|
+
story: "27 items with a header block on top — pairs as 13 rows of 2 with automatic wide/narrow splits, plus a single full-width card on the final (27th, odd) row."
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
};
|