@repobit/dex-system-design 0.23.87 → 0.23.89

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 CHANGED
@@ -3,6 +3,20 @@
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.23.89](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.88...@repobit/dex-system-design@0.23.89) (2026-07-16)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **DEX-1014:** card adjustments
11
+
12
+
13
+ ## [0.23.88](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.87...@repobit/dex-system-design@0.23.88) (2026-07-16)
14
+
15
+ ### Bug Fixes
16
+
17
+ * **DEX-1014:** card adjustments
18
+
19
+
6
20
  ## [0.23.87](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.86...@repobit/dex-system-design@0.23.87) (2026-07-16)
7
21
 
8
22
  **Note:** Version bump only for package @repobit/dex-system-design
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repobit/dex-system-design",
3
- "version": "0.23.87",
3
+ "version": "0.23.89",
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.3.83",
78
- "@repobit/dex-store-elements": "1.5.0",
77
+ "@repobit/dex-store": "1.3.85",
78
+ "@repobit/dex-store-elements": "1.5.2",
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": "4bdb34bc53c0ea3a5a7e4d9858dd6a5829a98adf"
95
+ "gitHead": "655316a0cdee9b7084c8bd4c8e85ca31b45ff55b"
96
96
  }
@@ -5,6 +5,7 @@ export default css`
5
5
  display: block;
6
6
  --background-card-grey: var(--color-neutral-25);
7
7
  --border-card-grey: var(--color-neutral-50);
8
+ --bd-card-cols: 4;
8
9
  max-width: 1290px;
9
10
  margin: 0 auto;
10
11
  }
@@ -16,6 +17,14 @@ export default css`
16
17
  display: block !important;
17
18
  }
18
19
 
20
+ ::slotted(bd-card-item) {
21
+ display: block;
22
+ width: var(--bd-card-width, 280px);
23
+ flex: 0 0 var(--bd-card-width, 280px);
24
+ min-width: 200px;
25
+ margin: 0 !important;
26
+ }
27
+
19
28
  .bd-section-title-s {
20
29
  font-family: var(--typography-fontFamily-sans);
21
30
  font-weight: var(--typography-fontWeight-semibold);
@@ -55,19 +64,13 @@ export default css`
55
64
  }
56
65
 
57
66
  .bd-light-carousel-track-s {
58
- position: relative;
59
- padding: var(--spacing-0) var(--spacing-20);
60
- scrollbar-width: none;
61
- -ms-overflow-style: none;
62
- z-index: 1;
63
- display: grid;
67
+ display: flex;
68
+ flex-wrap: wrap;
69
+ justify-content: center;
64
70
  gap: 1.5rem;
65
71
  width: 100%;
66
72
  box-sizing: border-box;
67
- }
68
-
69
- .bd-light-carousel-track-s::-webkit-scrollbar {
70
- display: none;
73
+ padding: 0;
71
74
  }
72
75
 
73
76
  .bd-light-box-s {
@@ -84,6 +87,8 @@ export default css`
84
87
  z-index: 2;
85
88
  font-family: var(--typography-fontFamily-sans);
86
89
  box-sizing: border-box;
90
+ width: 100%;
91
+ min-width: 0;
87
92
  }
88
93
 
89
94
  .bd-light-box-blue {
@@ -96,6 +101,23 @@ export default css`
96
101
  text-align: center !important;
97
102
  }
98
103
 
104
+ .bd-light-box-center .bd-light-box-header-s {
105
+ align-items: center;
106
+ }
107
+
108
+ .bd-light-box-center .bd-light-title-badge-wrapper-s {
109
+ justify-content: center;
110
+ }
111
+
112
+ .bd-light-box-center .bd-card-content-wrapper {
113
+ align-items: center;
114
+ text-align: center;
115
+ }
116
+
117
+ .bd-light-box-center .bd-card-cta-wrapper {
118
+ justify-content: center;
119
+ }
120
+
99
121
  .bd-light-box-s h3 {
100
122
  font-size: var(--heading-xsmall);
101
123
  margin: var(--spacing-0) var(--spacing-8) var(--spacing-8) var(--spacing-0);
@@ -104,12 +126,6 @@ export default css`
104
126
  text-align: start;
105
127
  }
106
128
 
107
- .bd-light-title-no-content h3 {
108
- margin: var(--spacing-0) !important;
109
- font-size: var(--heading-small) !important;
110
- text-align: center;
111
- }
112
-
113
129
  .bd-light-box-center h3 {
114
130
  text-align: center !important;
115
131
  margin: var(--spacing-0) var(--spacing-0) var(--spacing-8) var(--spacing-0) !important;
@@ -135,10 +151,6 @@ export default css`
135
151
  display: block;
136
152
  }
137
153
 
138
- .bd-light-box-no-content .bd-light-icon-s {
139
- margin: 0 !important;
140
- }
141
-
142
154
  .bd-light-box-header-s {
143
155
  display: flex;
144
156
  flex-direction: column;
@@ -149,15 +161,6 @@ export default css`
149
161
  position: relative;
150
162
  }
151
163
 
152
- .bd-light-box-no-content .bd-light-box-header-s {
153
- margin: 0 !important;
154
- }
155
-
156
- .bd-light-box-header-center {
157
- align-items: center !important;
158
- padding-bottom: var(--spacing-16);
159
- }
160
-
161
164
  .bd-light-title-badge-wrapper-s {
162
165
  display: flex;
163
166
  align-items: flex-start;
@@ -182,12 +185,6 @@ export default css`
182
185
  line-height: var(--typography-lineHeight-normal);
183
186
  }
184
187
 
185
- .bd-light-title-no-content {
186
- margin: 0 !important;
187
- width: 100%;
188
- justify-content: center;
189
- }
190
-
191
188
  .bd-card-content-wrapper {
192
189
  flex: 1;
193
190
  display: flex;
@@ -207,60 +204,31 @@ export default css`
207
204
  display: none;
208
205
  }
209
206
 
210
- @media (max-width: 1024px) {
211
- .bd-light-box-s {
212
- padding: 1.5em;
213
- }
214
-
215
- .bd-light-box-s h3 {
216
- font-size: 1.1em;
217
- }
218
-
219
- .bd-light-box-s p {
220
- font-size: 0.95em;
221
- }
222
-
223
- .bd-light-carousel-track-s {
224
- grid-template-columns: repeat(2, 1fr) !important;
225
- }
226
- }
227
207
 
228
208
  @media (max-width: 768px) {
229
209
  .bd-light-carousel-track-s {
230
- display: grid !important;
231
- grid-template-columns: 1fr !important;
210
+ flex-direction: column;
232
211
  gap: var(--spacing-20);
233
- overflow-x: hidden;
212
+ padding: 0;
213
+ align-items: stretch;
234
214
  }
235
215
 
236
- .bd-light-box-s,
237
- .bd-light-box-no-content {
238
- width: clamp(200px, 100%, 300px);
216
+ ::slotted(bd-card-item) {
217
+ width: 100% !important;
239
218
  max-width: 100% !important;
219
+ flex: 0 0 auto !important;
240
220
  min-width: 0 !important;
241
221
  margin: 0 !important;
242
- box-sizing: border-box !important;
243
222
  }
244
- }
245
223
 
246
- @media (max-width: 480px) {
247
224
  .bd-light-box-s {
248
- padding: 1em;
249
- }
250
- .bd-light-carousel-track-s{
251
- padding: 0 !important; }
252
- .bd-light-box-s h3 {
253
- font-size: 1em;
254
- }
255
-
256
- .bd-light-box-s p {
257
- font-size: 0.9em;
225
+ width: 100% !important;
226
+ max-width: 100% !important;
227
+ min-width: 0 !important;
228
+ flex: none !important;
229
+ margin: 0 !important;
230
+ box-sizing: border-box !important;
258
231
  }
259
232
  }
260
233
 
261
- @media (max-width: 600px) {
262
- .bd-light-carousel-track-s {
263
- grid-template-columns: 1fr !important;
264
- }
265
- }
266
234
  `;
@@ -25,8 +25,32 @@ class Card extends LitElement {
25
25
  return this.offsetWidth > 0 && this.offsetHeight > 0;
26
26
  }
27
27
 
28
+ _getColumnCount(itemCount) {
29
+ if (itemCount <= 4) return itemCount;
30
+ if (itemCount <= 6) return 3;
31
+ if (itemCount <= 8) return 4;
32
+ if (itemCount === 9) return 3;
33
+ return 4;
34
+ }
35
+
36
+ _updateCardWidth() {
37
+ const colCount = this._getColumnCount(this._itemCount);
38
+ const track = this.renderRoot?.querySelector(".bd-light-carousel-track-s");
39
+ if (!track) return;
40
+
41
+ const trackW = track.getBoundingClientRect().width;
42
+ const gap = 24;
43
+ const totalGaps = (colCount - 1) * gap;
44
+ const cardW = Math.floor((trackW - totalGaps) / colCount);
45
+
46
+ this.style.setProperty("--bd-card-cols", colCount);
47
+ this.style.setProperty("--bd-card-width", `${cardW}px`);
48
+ }
49
+
28
50
  _onSlotChange = () => {
29
51
  this._itemCount = this.querySelectorAll("bd-card-item").length;
52
+ this._updateCardWidth();
53
+ this.requestUpdate();
30
54
  this._equalizeHeights();
31
55
  }
32
56
 
@@ -36,6 +60,7 @@ class Card extends LitElement {
36
60
  const items = Array.from(this.querySelectorAll("bd-card-item"));
37
61
  if (!items.length) return;
38
62
 
63
+
39
64
  if (window.innerWidth <= 768) {
40
65
  items.forEach(item => {
41
66
  const box = item.renderRoot?.querySelector(".bd-light-box-s");
@@ -43,25 +68,11 @@ class Card extends LitElement {
43
68
  const titleW = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
44
69
  const contentW = item.renderRoot?.querySelector(".bd-card-content-wrapper");
45
70
 
46
- if (box) { box.style.cssText = ""; }
71
+ if (box) { box.style.cssText = ""; box.style.width = "100%"; box.style.boxSizing = "border-box"; }
47
72
  if (iconW) { iconW.style.height = ""; }
48
73
  if (titleW) { titleW.style.height = ""; }
49
74
  if (contentW) { contentW.style.height = ""; }
50
75
  });
51
-
52
- const sectionW = this.getBoundingClientRect().width;
53
- if (sectionW > 0) {
54
- requestAnimationFrame(() => {
55
- items.forEach(item => {
56
- const box = item.renderRoot?.querySelector(".bd-light-box-s");
57
- if (box) {
58
- box.style.width = `${sectionW}px`;
59
- box.style.minWidth = `${sectionW}px`;
60
- }
61
- });
62
- });
63
- }
64
-
65
76
  return;
66
77
  }
67
78
 
@@ -71,13 +82,14 @@ class Card extends LitElement {
71
82
  const titleW = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
72
83
  const contentW = item.renderRoot?.querySelector(".bd-card-content-wrapper");
73
84
 
74
- if (box) { box.style.height = "auto"; box.style.minHeight = "0"; box.style.width = "auto"; }
85
+ if (box) { box.style.height = "auto"; box.style.minHeight = "0"; }
75
86
  if (iconW) { iconW.style.height = "auto"; }
76
87
  if (titleW) { titleW.style.height = "auto"; }
77
88
  if (contentW) { contentW.style.height = "auto"; }
78
89
  });
79
90
 
80
91
  requestAnimationFrame(() => {
92
+ // Egalizare icon wrappers
81
93
  let maxIcon = 0;
82
94
  items.forEach(item => {
83
95
  const el = item.renderRoot?.querySelector(".bd-light-box-header-s");
@@ -92,6 +104,7 @@ class Card extends LitElement {
92
104
  });
93
105
  }
94
106
 
107
+ // Egalizare title wrappers
95
108
  let maxTitle = 0;
96
109
  items.forEach(item => {
97
110
  const el = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
@@ -106,6 +119,7 @@ class Card extends LitElement {
106
119
  });
107
120
  }
108
121
 
122
+ // Egalizare content wrappers
109
123
  let maxContent = 0;
110
124
  items.forEach(item => {
111
125
  const el = item.renderRoot?.querySelector(".bd-card-content-wrapper");
@@ -120,16 +134,14 @@ class Card extends LitElement {
120
134
  });
121
135
  }
122
136
 
123
- let maxW = 0;
137
+ // Egalizare height total
124
138
  let maxH = 0;
125
139
  items.forEach(item => {
126
140
  const box = item.renderRoot?.querySelector(".bd-light-box-s");
127
141
  if (!box) return;
128
- const rect = box.getBoundingClientRect();
129
- if (rect.height > maxH) maxH = rect.height;
130
- if (rect.width > maxW) maxW = rect.width;
142
+ const h = box.getBoundingClientRect().height;
143
+ if (h > maxH) maxH = h;
131
144
  });
132
-
133
145
  if (maxH > 0) {
134
146
  items.forEach(item => {
135
147
  const box = item.renderRoot?.querySelector(".bd-light-box-s");
@@ -139,16 +151,6 @@ class Card extends LitElement {
139
151
  }
140
152
  });
141
153
  }
142
-
143
- if (maxW > 0) {
144
- items.forEach(item => {
145
- const box = item.renderRoot?.querySelector(".bd-light-box-s");
146
- if (box) {
147
- box.style.width = `${maxW}px`;
148
- box.style.minWidth = `${maxW}px`;
149
- }
150
- });
151
- }
152
154
  });
153
155
  }
154
156
 
@@ -158,11 +160,13 @@ class Card extends LitElement {
158
160
  }
159
161
 
160
162
  await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
163
+ this._updateCardWidth();
161
164
  this._equalizeHeights();
162
165
 
163
166
  const track = this.renderRoot.querySelector(".bd-light-carousel-track-s");
164
167
  if (track) {
165
168
  this._resizeObserver = new ResizeObserver(() => {
169
+ this._updateCardWidth();
166
170
  this._equalizeHeights();
167
171
  });
168
172
  this._resizeObserver.observe(track);
@@ -187,12 +191,11 @@ class Card extends LitElement {
187
191
  </div>
188
192
  `
189
193
  : ""}
190
- <div
191
- class="bd-light-carousel-track-s"
192
- style="grid-template-columns: repeat(${this._itemCount || 1}, 1fr);"
193
- >
194
+
195
+ <div class="bd-light-carousel-track-s">
194
196
  <slot @slotchange=${this._onSlotChange}></slot>
195
197
  </div>
198
+
196
199
  </section>
197
200
  `;
198
201
  }
@@ -223,24 +226,47 @@ class CardItem extends LitElement {
223
226
 
224
227
  if (iconEl) {
225
228
  const clone = iconEl.cloneNode(true);
226
- const originalW = iconEl.getAttribute("width");
227
- const originalH = iconEl.getAttribute("height");
229
+ const originalW = parseInt(iconEl.getAttribute("width") || "0");
230
+ const originalH = parseInt(iconEl.getAttribute("height") || "0");
231
+
232
+ const _calcSize = (w, h, el) => {
233
+ // Daca nu are atribute, incearca sa citeasca dimensiunile reale
234
+ if (!w && !h && el) {
235
+ const rect = el.getBoundingClientRect();
236
+ w = Math.round(rect.width);
237
+ h = Math.round(rect.height);
238
+ console.log('[bd-card-icon] fallback dimensions from rect:', { w, h });
239
+ }
240
+
241
+ // Daca tot nu stim dimensiunile, lasam ca e imagine mare
242
+ if (!w && !h) return { w: 120, h: 120 };
243
+
244
+ const dim = Math.max(w, h);
245
+ if (dim <= 50) return { w, h };
246
+ if (dim <= 100) return { w: 48, h: 48 };
247
+ return { w: 120, h: 120 };
248
+ };
249
+
250
+ const { w: finalW, h: finalH } = _calcSize(originalW, originalH, iconEl);
251
+
228
252
 
229
253
  clone.style.maxWidth = "120px";
230
254
  clone.style.maxHeight = "120px";
231
- clone.style.width = originalW ? `${originalW}px` : "auto";
232
- clone.style.height = originalH ? `${originalH}px` : "auto";
255
+ clone.style.width = `${finalW}px`;
256
+ clone.style.height = `${finalH}px`;
233
257
  clone.style.objectFit = "contain";
234
258
  clone.style.display = "block";
235
259
 
236
260
  const innerImg = clone.querySelector("img");
237
261
  if (innerImg) {
238
- const imgW = innerImg.getAttribute("width");
239
- const imgH = innerImg.getAttribute("height");
262
+ const imgW = parseInt(innerImg.getAttribute("width") || "0");
263
+ const imgH = parseInt(innerImg.getAttribute("height") || "0");
264
+ const { w: imgFinalW, h: imgFinalH } = _calcSize(imgW, imgH);
265
+
240
266
  innerImg.style.maxWidth = "120px";
241
267
  innerImg.style.maxHeight = "120px";
242
- innerImg.style.width = imgW ? `${Math.min(parseInt(imgW), 120)}px` : "auto";
243
- innerImg.style.height = imgH ? `${Math.min(parseInt(imgH), 120)}px` : "auto";
268
+ innerImg.style.width = `${imgFinalW}px`;
269
+ innerImg.style.height = `${imgFinalH}px`;
244
270
  innerImg.style.objectFit = "contain";
245
271
  innerImg.style.display = "block";
246
272
  innerImg.removeAttribute("width");
@@ -252,15 +278,14 @@ class CardItem extends LitElement {
252
278
 
253
279
  if (this.icon) {
254
280
  return html`<img
255
- src="${this.icon}"
256
- alt="icon"
257
- class="bd-light-icon-s"
258
- />`;
281
+ src="${this.icon}"
282
+ alt="icon"
283
+ class="bd-light-icon-s"
284
+ />`;
259
285
  }
260
286
 
261
287
  return "";
262
288
  }
263
-
264
289
  _hasContent() {
265
290
  const slottedNodes = [...this.childNodes].filter((node) => {
266
291
  if (node.nodeType === Node.ELEMENT_NODE) {
@@ -287,7 +312,6 @@ class CardItem extends LitElement {
287
312
  <div
288
313
  class="bd-light-box-s
289
314
  ${isCentered ? "bd-light-box-center" : ""}
290
- ${!hasContent ? "bd-light-box-no-content" : ""}
291
315
  ${this.bgBlue ? "bd-light-box-blue" : ""}"
292
316
  >
293
317
  <div class="bd-light-box-header-s ${isCentered ? "bd-light-box-header-center" : ""}">
@@ -19,345 +19,228 @@ export default {
19
19
  component: `
20
20
  **Card** and **CardItem** are Lit components for a static card grid layout.
21
21
 
22
- - \`<bd-card-section>\` — section wrapper with optional title and subtitle
23
- - \`<bd-card-item>\` — individual card with optional icon, title, subtitle, alignment, slotted content, CTA button, and blue background
24
-
25
- ### Usage
26
- \`\`\`html
27
- <bd-card-section title="Why Bitdefender" subtitle="Optional subtitle">
28
- <bd-card-item title="AI Protection" align="center" bg-blue cta-align="center">
29
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
30
- <bd-p>Powered by machine learning.</bd-p>
31
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
32
- </bd-card-item>
33
- </bd-card-section>
34
- \`\`\`
35
-
36
- ### CardItem Slots
37
- | Slot | Descriere |
38
- |---|---|
39
- | \`icon\` | Iconiță sau imagine (max 120x120px automat) |
40
- | default | Conținut text |
41
- | \`cta\` | Buton CTA jos |
42
-
43
- ### CardItem Props
44
- | Prop | Valori | Default |
22
+ Grid columns are calculated automatically:
23
+ | Items | Columns | Layout |
45
24
  |---|---|---|
46
- | \`title\` | String | \`''\` |
47
- | \`subtitle\` | String | \`''\` |
48
- | \`align\` | \`start\`, \`center\` | \`start\` |
49
- | \`bg-blue\` | Boolean | \`false\` |
50
- | \`cta-align\` | \`start\`, \`center\`, \`end\` | \`start\` |
25
+ | 1–4 | = items | 1, 2, 3, 4 |
26
+ | 5–6 | 3 | 3+2, 3+3 |
27
+ | 7–8 | 4 | 4+3, 4+4 |
28
+ | 9 | 3 | 3+3+3 |
29
+ | 10+ | 4 | 4+4+... |
51
30
  `
52
31
  }
53
32
  }
54
- },
55
- argTypes: {
56
- sectionTitle: {
57
- control : 'text',
58
- description: 'Optional title for the card section',
59
- table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CardSection' }
60
- },
61
- sectionSubtitle: {
62
- control : 'text',
63
- description: 'Optional subtitle for the card section',
64
- table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CardSection' }
65
- },
66
- itemTitle: {
67
- control : 'text',
68
- description: 'Title of the card item',
69
- table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CardItem' }
70
- },
71
- align: {
72
- control : { type: 'select' },
73
- options : ['start', 'center'],
74
- description: 'Alignment of card content',
75
- table : { type: { summary: "'start' | 'center'" }, defaultValue: { summary: 'start' }, category: 'CardItem' }
76
- },
77
- bgBlue: {
78
- control : 'boolean',
79
- description: 'Blue background (#E4F2FF) on card',
80
- table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'CardItem' }
81
- },
82
- ctaAlign: {
83
- control : { type: 'select' },
84
- options : ['start', 'center', 'end'],
85
- description: 'CTA button alignment',
86
- table : { type: { summary: "'start' | 'center' | 'end'" }, defaultValue: { summary: 'start' }, category: 'CardItem' }
87
- }
88
33
  }
89
34
  };
90
35
 
36
+ // ─── Shared data ──────────────────────────────────────────────────────────────
37
+
38
+ const icons = [
39
+ html`<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>`,
40
+ html`<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>`,
41
+ html`<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>`,
42
+ html`<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>`,
43
+ html`<bd-family-icon slot="icon" width="32" height="32" color="#006DFF"></bd-family-icon>`,
44
+ html`<bd-arrow-up-icon slot="icon" width="32" height="32" color="#006DFF"></bd-arrow-up-icon>`,
45
+ html`<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>`,
46
+ html`<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>`,
47
+ html`<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>`,
48
+ html`<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>`
49
+ ];
50
+
51
+ const titles = [
52
+ 'AI Protection', 'Multi-layer Security', 'VPN Included', 'Parental Controls',
53
+ 'Identity Protection', 'Password Manager', 'Anti-tracker', 'Webcam Protection',
54
+ 'Privacy Firewall', 'Dark Web Monitor'
55
+ ];
56
+
57
+ const descriptions = [
58
+ 'Powered by machine learning and behavioral analysis.',
59
+ 'Multiple independent protection layers stop any attack.',
60
+ 'Unlimited encrypted VPN traffic for all your devices.',
61
+ 'Advanced controls to protect your children online.',
62
+ 'Goes beyond credit monitoring to protect your identity.',
63
+ 'Store and autofill passwords securely across all devices.',
64
+ 'Block trackers and keep your browsing activity private.',
65
+ 'Prevent unauthorized access to your webcam.',
66
+ 'Advanced firewall protection for your network.',
67
+ 'Get instant alerts if your data appears on the dark web.'
68
+ ];
69
+
70
+ const makeCards = (count) => Array.from({ length: count }, (_, i) => html`
71
+ <bd-card-item title="${titles[i % titles.length]}">
72
+ ${icons[i % icons.length]}
73
+ <bd-p>${descriptions[i % descriptions.length]}</bd-p>
74
+ </bd-card-item>
75
+ `);
76
+
91
77
  // ─── Default ──────────────────────────────────────────────────────────────────
92
78
 
93
79
  export const Default = {
94
80
  name : 'Default (4 items)',
95
81
  render: () => html`
96
82
  <bd-card-section title="Why Bitdefender">
97
- <bd-card-item title="AI Protection">
98
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
99
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
100
- </bd-card-item>
101
- <bd-card-item title="Multi-layer Security">
102
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
103
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
104
- </bd-card-item>
105
- <bd-card-item title="VPN Included">
106
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
107
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
108
- </bd-card-item>
109
- <bd-card-item title="Parental Controls">
110
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
111
- <bd-p>Advanced controls to protect your children online.</bd-p>
112
- </bd-card-item>
83
+ ${makeCards(4)}
113
84
  </bd-card-section>
114
85
  `,
115
- parameters: { docs: { description: { story: '4 card items cu iconițe, titluri și conținut.' } } }
86
+ parameters: { docs: { description: { story: '4 carduri — 4 coloane pe un rând.' } } }
116
87
  };
117
88
 
118
- // ─── With Blue Background ─────────────────────────────────────────────────────
89
+ // ─── 5 items ──────────────────────────────────────────────────────────────────
119
90
 
120
- export const WithBlueBg = {
121
- name : 'With Blue Background',
91
+ export const FiveItems = {
92
+ name : '5 Items — 3+2',
122
93
  render: () => html`
123
- <bd-card-section title="Why Bitdefender">
124
- <bd-card-item title="AI Protection" bg-blue>
125
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
126
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
127
- </bd-card-item>
128
- <bd-card-item title="Multi-layer Security" bg-blue>
129
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
130
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
131
- </bd-card-item>
132
- <bd-card-item title="VPN Included" bg-blue>
133
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
134
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
135
- </bd-card-item>
136
- <bd-card-item title="Parental Controls" bg-blue>
137
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
138
- <bd-p>Advanced controls to protect your children online.</bd-p>
139
- </bd-card-item>
94
+ <bd-card-section title="5 Cards — 3+2 layout">
95
+ ${makeCards(5)}
140
96
  </bd-card-section>
141
97
  `,
142
- parameters: { docs: { description: { story: 'Toate cardurile cu `bg-blue` — fundal #E4F2FF.' } } }
98
+ parameters: { docs: { description: { story: '5 carduri → 3 coloane → layout 3+2, rândul 2 centrat.' } } }
143
99
  };
144
100
 
145
- // ─── Mixed Blue Background ────────────────────────────────────────────────────
101
+ // ─── 6 items ──────────────────────────────────────────────────────────────────
146
102
 
147
- export const MixedBlueBg = {
148
- name : 'Mixed — Some Blue',
103
+ export const SixItems = {
104
+ name : '6 Items — 3+3',
149
105
  render: () => html`
150
- <bd-card-section title="Features">
151
- <bd-card-item title="AI Protection" bg-blue>
152
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
153
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
154
- </bd-card-item>
155
- <bd-card-item title="Multi-layer Security">
156
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
157
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
158
- </bd-card-item>
159
- <bd-card-item title="VPN Included" bg-blue>
160
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
161
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
162
- </bd-card-item>
163
- <bd-card-item title="Parental Controls">
164
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
165
- <bd-p>Advanced controls to protect your children online.</bd-p>
166
- </bd-card-item>
106
+ <bd-card-section title="6 Cards — 3+3 layout">
107
+ ${makeCards(6)}
167
108
  </bd-card-section>
168
109
  `,
169
- parameters: { docs: { description: { story: 'Mix de carduri cu și fără `bg-blue`.' } } }
110
+ parameters: { docs: { description: { story: '6 carduri → 3 coloane → layout 3+3.' } } }
170
111
  };
171
112
 
172
- // ─── With CTA ─────────────────────────────────────────────────────────────────
113
+ // ─── 7 items ──────────────────────────────────────────────────────────────────
173
114
 
174
- export const WithCTA = {
175
- name : 'With CTA Button',
115
+ export const SevenItems = {
116
+ name : '7 Items — 4+3',
176
117
  render: () => html`
177
- <bd-card-section title="Why Bitdefender">
178
- <bd-card-item title="AI Protection">
179
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
180
- <bd-p>Powered by machine learning and behavioral analysis to stop threats before they reach you.</bd-p>
181
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
182
- </bd-card-item>
183
- <bd-card-item title="Multi-layer Security">
184
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
185
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
186
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
187
- </bd-card-item>
188
- <bd-card-item title="VPN Included">
189
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
190
- <bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere.</bd-p>
191
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
192
- </bd-card-item>
193
- <bd-card-item title="Parental Controls">
194
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
195
- <bd-p>Advanced controls to protect your children online.</bd-p>
196
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
197
- </bd-card-item>
118
+ <bd-card-section title="7 Cards — 4+3 layout">
119
+ ${makeCards(7)}
198
120
  </bd-card-section>
199
121
  `,
200
- parameters: { docs: { description: { story: 'Cards cu buton CTA via `slot="cta"`.' } } }
122
+ parameters: { docs: { description: { story: '7 carduri → 4 coloane → layout 4+3, rândul 2 centrat.' } } }
201
123
  };
202
124
 
203
- // ─── With CTA Centered ────────────────────────────────────────────────────────
125
+ // ─── 8 items ──────────────────────────────────────────────────────────────────
204
126
 
205
- export const WithCTACentered = {
206
- name : 'With CTA — Centered',
127
+ export const EightItems = {
128
+ name : '8 Items — 4+4',
207
129
  render: () => html`
208
- <bd-card-section title="Features">
209
- <bd-card-item title="AI Protection" cta-align="center">
210
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
211
- <bd-p>Powered by machine learning.</bd-p>
212
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
213
- </bd-card-item>
214
- <bd-card-item title="Multi-layer Security" cta-align="center">
215
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
216
- <bd-p>Multiple protection layers.</bd-p>
217
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
218
- </bd-card-item>
219
- <bd-card-item title="VPN Included" cta-align="center">
220
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
221
- <bd-p>Unlimited encrypted VPN traffic.</bd-p>
222
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
223
- </bd-card-item>
130
+ <bd-card-section title="8 Cards — 4+4 layout">
131
+ ${makeCards(8)}
224
132
  </bd-card-section>
225
133
  `,
226
- parameters: { docs: { description: { story: 'CTA centrat cu `cta-align="center"`.' } } }
134
+ parameters: { docs: { description: { story: '8 carduri → 4 coloane → layout 4+4.' } } }
227
135
  };
228
136
 
229
- // ─── With Subtitle ────────────────────────────────────────────────────────────
137
+ // ─── 9 items ──────────────────────────────────────────────────────────────────
230
138
 
231
- export const WithSubtitle = {
232
- name : 'With Section Subtitle',
139
+ export const NineItems = {
140
+ name : '9 Items — 3+3+3',
233
141
  render: () => html`
234
- <bd-card-section
235
- title="Why Bitdefender"
236
- subtitle="Trusted by millions worldwide for over 20 years."
237
- >
238
- <bd-card-item title="AI Protection" subtitle="Machine learning powered">
239
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
240
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
241
- </bd-card-item>
242
- <bd-card-item title="Multi-layer Security" subtitle="Independent protection layers">
243
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
244
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
245
- </bd-card-item>
246
- <bd-card-item title="VPN Included" subtitle="Unlimited traffic">
247
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
248
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
249
- </bd-card-item>
142
+ <bd-card-section title="9 Cards — 3+3+3 layout">
143
+ ${makeCards(9)}
250
144
  </bd-card-section>
251
145
  `,
252
- parameters: { docs: { description: { story: 'Section cu subtitlu și card items cu subtitlu sub titlu.' } } }
146
+ parameters: { docs: { description: { story: '9 carduri → 3 coloane → layout 3+3+3.' } } }
253
147
  };
254
148
 
255
- // ─── Uneven Content Alignment Test ────────────────────────────────────────────
149
+ // ─── 10 items ─────────────────────────────────────────────────────────────────
256
150
 
257
- export const WithCTAUnevenContent = {
258
- name : 'Uneven Content — Alignment Test',
151
+ export const TenItems = {
152
+ name : '10 Items — 4+4+2',
259
153
  render: () => html`
260
- <bd-card-section title="Features">
261
- <bd-card-item title="AI Protection">
262
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
263
- <bd-p>Powered by machine learning and behavioral analysis to stop threats before they reach you. Our AI engine learns from billions of threat signals every day.</bd-p>
264
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
265
- </bd-card-item>
266
- <bd-card-item title="Multi-layer Security — Advanced Protection Suite">
267
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
268
- <bd-p>Stop any attack.</bd-p>
269
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
270
- </bd-card-item>
271
- <bd-card-item title="VPN">
272
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
273
- <bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere in the world, at any time.</bd-p>
274
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
275
- </bd-card-item>
276
- <bd-card-item title="Parental Controls">
277
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
278
- <bd-p>Advanced controls to protect your children online and monitor their activity.</bd-p>
279
- <bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
280
- </bd-card-item>
154
+ <bd-card-section title="10 Cards — 4+4+2 layout">
155
+ ${makeCards(10)}
281
156
  </bd-card-section>
282
157
  `,
283
- parameters: { docs: { description: { story: 'Conținut inegal — testează egalizarea rândurilor. Butoanele CTA trebuie să fie la aceeași înălțime.' } } }
158
+ parameters: { docs: { description: { story: '10 carduri → 4 coloane → layout 4+4+2, ultimul rând centrat.' } } }
284
159
  };
285
160
 
286
- // ─── No Section Title ─────────────────────────────────────────────────────────
161
+ // ─── With Blue Background ─────────────────────────────────────────────────────
287
162
 
288
- export const NoSectionTitle = {
289
- name : 'No Section Title',
163
+ export const WithBlueBg = {
164
+ name : 'With Blue Background',
290
165
  render: () => html`
291
- <bd-card-section>
292
- <bd-card-item title="AI Protection">
166
+ <bd-card-section title="Why Bitdefender">
167
+ <bd-card-item title="AI Protection" bg-blue>
293
168
  <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
294
169
  <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
295
170
  </bd-card-item>
296
- <bd-card-item title="Multi-layer Security">
171
+ <bd-card-item title="Multi-layer Security" bg-blue>
297
172
  <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
298
173
  <bd-p>Multiple independent protection layers stop any attack.</bd-p>
299
174
  </bd-card-item>
300
- <bd-card-item title="VPN Included">
175
+ <bd-card-item title="VPN Included" bg-blue>
301
176
  <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
302
177
  <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
303
178
  </bd-card-item>
304
- <bd-card-item title="Parental Controls">
179
+ <bd-card-item title="Parental Controls" bg-blue>
305
180
  <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
306
181
  <bd-p>Advanced controls to protect your children online.</bd-p>
307
182
  </bd-card-item>
308
183
  </bd-card-section>
309
184
  `,
310
- parameters: { docs: { description: { story: 'Section fără `title` — header div omis.' } } }
185
+ parameters: { docs: { description: { story: 'Toate cardurile cu `bg-blue` — fundal #E4F2FF.' } } }
311
186
  };
312
187
 
313
- // ─── Centered Alignment ───────────────────────────────────────────────────────
188
+ // ─── Mixed Blue ───────────────────────────────────────────────────────────────
314
189
 
315
- export const CenteredAlignment = {
316
- name : 'Centered Alignment',
190
+ export const MixedBlueBg = {
191
+ name : 'Mixed — Some Blue',
317
192
  render: () => html`
318
193
  <bd-card-section title="Features">
319
- <bd-card-item title="AI Protection" align="center">
194
+ <bd-card-item title="AI Protection" bg-blue>
320
195
  <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
321
196
  <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
322
197
  </bd-card-item>
323
- <bd-card-item title="Multi-layer Security" align="center">
198
+ <bd-card-item title="Multi-layer Security">
324
199
  <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
325
200
  <bd-p>Multiple independent protection layers stop any attack.</bd-p>
326
201
  </bd-card-item>
327
- <bd-card-item title="VPN Included" align="center">
202
+ <bd-card-item title="VPN Included" bg-blue>
328
203
  <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
329
204
  <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
330
205
  </bd-card-item>
331
- <bd-card-item title="Parental Controls" align="center">
206
+ <bd-card-item title="Parental Controls">
332
207
  <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
333
208
  <bd-p>Advanced controls to protect your children online.</bd-p>
334
209
  </bd-card-item>
335
210
  </bd-card-section>
336
211
  `,
337
- parameters: { docs: { description: { story: '`align="center"` pe toate itemele.' } } }
212
+ parameters: { docs: { description: { story: 'Mix de carduri cu și fără `bg-blue`.' } } }
338
213
  };
339
214
 
340
- // ─── No Icon ──────────────────────────────────────────────────────────────────
215
+ // ─── With CTA ─────────────────────────────────────────────────────────────────
341
216
 
342
- export const NoIcon = {
343
- name : 'No Icons',
217
+ export const WithCTA = {
218
+ name : 'With CTA Button',
344
219
  render: () => html`
345
- <bd-card-section title="Features">
220
+ <bd-card-section title="Why Bitdefender">
346
221
  <bd-card-item title="AI Protection">
222
+ <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
347
223
  <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
224
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
348
225
  </bd-card-item>
349
226
  <bd-card-item title="Multi-layer Security">
227
+ <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
350
228
  <bd-p>Multiple independent protection layers stop any attack.</bd-p>
229
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
351
230
  </bd-card-item>
352
231
  <bd-card-item title="VPN Included">
232
+ <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
353
233
  <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
234
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
354
235
  </bd-card-item>
355
236
  <bd-card-item title="Parental Controls">
237
+ <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
356
238
  <bd-p>Advanced controls to protect your children online.</bd-p>
239
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
357
240
  </bd-card-item>
358
241
  </bd-card-section>
359
242
  `,
360
- parameters: { docs: { description: { story: 'Carduri fără iconițe.' } } }
243
+ parameters: { docs: { description: { story: 'Cards cu buton CTA via `slot="cta"`.' } } }
361
244
  };
362
245
 
363
246
  // ─── No Slotted Content ───────────────────────────────────────────────────────
@@ -366,7 +249,7 @@ export const NoSlottedContent = {
366
249
  name : 'No Slotted Content',
367
250
  render: () => html`
368
251
  <bd-card-section title="Features">
369
- <bd-card-item title="AI Protection">
252
+ <bd-card-item align="center" title="AI Protection">
370
253
  <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
371
254
  </bd-card-item>
372
255
  <bd-card-item title="Multi-layer Security">
@@ -380,67 +263,56 @@ export const NoSlottedContent = {
380
263
  </bd-card-item>
381
264
  </bd-card-section>
382
265
  `,
383
- parameters: { docs: { description: { story: 'Carduri cu doar iconițe și titlu — fără conținut slotted.' } } }
266
+ parameters: { docs: { description: { story: 'Carduri cu doar iconițe și titlu.' } } }
384
267
  };
385
-
386
- // ─── Two Columns ──────────────────────────────────────────────────────────────
387
-
388
- export const TwoColumns = {
389
- name : 'Two Columns',
268
+ export const WithImages = {
269
+ name : 'With Images',
390
270
  render: () => html`
391
- <bd-card-section title="Features">
392
- <bd-card-item title="AI Protection">
393
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
394
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
271
+ <bd-card-section title="Our Products">
272
+ <bd-card-item title="Total Security">
273
+ <img slot="icon" src="/assets/tabs-img1.png" alt="Total Security" />
274
+ <bd-p>Complete protection for all your devices with advanced threat detection.</bd-p>
275
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
395
276
  </bd-card-item>
396
- <bd-card-item title="Multi-layer Security">
397
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
398
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
277
+ <bd-card-item title="Internet Security">
278
+ <img slot="icon" src="/assets/tabs-img2.png" alt="Internet Security" />
279
+ <bd-p>Stay safe online.</bd-p>
280
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
281
+ </bd-card-item>
282
+ <bd-card-item title="Antivirus Plus">
283
+ <img slot="icon" src="/assets/tabs-img3.png" alt="Antivirus Plus" />
284
+ <bd-p>Essential protection for your Windows PC with real-time antivirus and anti-phishing.</bd-p>
285
+ <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
399
286
  </bd-card-item>
400
287
  </bd-card-section>
401
288
  `,
402
- parameters: { docs: { description: { story: 'Două coloane — grid se ajustează automat.' } } }
289
+ parameters: { docs: { description: { story: 'Cards cu imagini via `slot="icon"` — max-width/max-height 120px aplicat automat.' } } }
403
290
  };
404
291
 
405
- // ─── Three Columns ────────────────────────────────────────────────────────────
406
-
407
- export const ThreeColumns = {
408
- name : 'Three Columns',
292
+ export const MixedIconsAndImages = {
293
+ name : 'Mixed — Icons and Images',
409
294
  render: () => html`
410
- <bd-card-section title="Features">
295
+ <bd-card-section title="Mixed Media">
411
296
  <bd-card-item title="AI Protection">
412
297
  <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
413
298
  <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
414
299
  </bd-card-item>
415
- <bd-card-item title="Multi-layer Security">
416
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
417
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
300
+ <bd-card-item title="Total Security">
301
+ <img slot="icon" src="/assets/tabs-img1.png" alt="Total Security" />
302
+ <bd-p>Complete protection for all your devices.</bd-p>
418
303
  </bd-card-item>
419
304
  <bd-card-item title="VPN Included">
420
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
421
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
305
+ <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
306
+ <bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere.</bd-p>
422
307
  </bd-card-item>
423
- </bd-card-section>
424
- `,
425
- parameters: { docs: { description: { story: 'Trei coloane — grid se ajustează automat.' } } }
426
- };
427
-
428
- // ─── Single Item ──────────────────────────────────────────────────────────────
429
-
430
- export const SingleItem = {
431
- name : 'Single Item (edge case)',
432
- render: () => html`
433
- <bd-card-section title="Feature">
434
- <bd-card-item title="AI Protection">
435
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
436
- <bd-p>Machine learning-powered protection.</bd-p>
437
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
308
+ <bd-card-item title="Internet Security">
309
+ <img slot="icon" src="/assets/tabs-img2.png" alt="Internet Security" />
310
+ <bd-p>Stay safe online with advanced threat detection.</bd-p>
438
311
  </bd-card-item>
439
312
  </bd-card-section>
440
313
  `,
441
- parameters: { docs: { description: { story: 'Edge case — un singur card.' } } }
314
+ parameters: { docs: { description: { story: 'Mix de SVG icons și imagini mari în același grid — testează egalizarea icon row height.' } } }
442
315
  };
443
-
444
316
  // ─── Mobile View ──────────────────────────────────────────────────────────────
445
317
 
446
318
  export const MobileView = {
@@ -448,26 +320,7 @@ export const MobileView = {
448
320
  parameters: { viewport: { defaultViewport: 'mobile1' } },
449
321
  render : () => html`
450
322
  <bd-card-section title="Why Bitdefender">
451
- <bd-card-item title="AI Protection">
452
- <bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
453
- <bd-p>Powered by machine learning and behavioral analysis.</bd-p>
454
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
455
- </bd-card-item>
456
- <bd-card-item title="Multi-layer Security">
457
- <bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
458
- <bd-p>Multiple independent protection layers stop any attack.</bd-p>
459
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
460
- </bd-card-item>
461
- <bd-card-item title="VPN Included">
462
- <bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
463
- <bd-p>Unlimited encrypted VPN traffic for all your devices.</bd-p>
464
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
465
- </bd-card-item>
466
- <bd-card-item title="Parental Controls">
467
- <bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
468
- <bd-p>Advanced controls to protect your children online.</bd-p>
469
- <bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
470
- </bd-card-item>
323
+ ${makeCards(4)}
471
324
  </bd-card-section>
472
325
  ` };
473
326