@repobit/dex-system-design 0.2.0
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 +11 -0
- package/README.md +15 -0
- package/package.json +57 -0
- package/src/assets/fonts/IBMPlexMono-Bold.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-BoldItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-Italic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-Light.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-LightItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-Medium.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-MediumItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-Regular.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-SemiBold.woff2 +0 -0
- package/src/assets/fonts/IBMPlexMono-SemiBoldItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-Bold.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-BoldItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-Italic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-Light.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-LightItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-Medium.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-MediumItalic.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-Regular.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
- package/src/assets/fonts/IBMPlexSans-SemiBoldItalic.woff2 +0 -0
- package/src/assets/fonts/bd-ibm-plex-mono.zip +0 -0
- package/src/assets/fonts/bd-ibm-plex-sans.zip +0 -0
- package/src/assets/icons/badge-icon-individual.png +0 -0
- package/src/assets/icons/bd-icon-family-white.png +0 -0
- package/src/assets/icons/bd-icon-family.png +0 -0
- package/src/assets/icons/bd-icon-user.png +0 -0
- package/src/assets/icons/left_clicked.png +0 -0
- package/src/assets/icons/left_disabled.png +0 -0
- package/src/assets/icons/left_hover.png +0 -0
- package/src/assets/icons/left_normal.png +0 -0
- package/src/assets/icons/light-carousel-img1.png +0 -0
- package/src/assets/icons/light-carousel-img2.png +0 -0
- package/src/assets/icons/light-carousel-img3.png +0 -0
- package/src/assets/icons/more_hover.png +0 -0
- package/src/assets/icons/more_normal.png +0 -0
- package/src/assets/icons/more_pressed.png +0 -0
- package/src/assets/icons/pic1.png +0 -0
- package/src/assets/icons/pic2.png +0 -0
- package/src/assets/icons/pic3.png +0 -0
- package/src/assets/icons/right_clicked.png +0 -0
- package/src/assets/icons/right_disabled.png +0 -0
- package/src/assets/icons/right_hover.png +0 -0
- package/src/assets/icons/right_normal.png +0 -0
- package/src/assets/icons/tabs-img1.png +0 -0
- package/src/assets/icons/tabs-img2.png +0 -0
- package/src/assets/icons/tabs-img3.png +0 -0
- package/src/assets/icons/verified_arrow.png +0 -0
- package/src/components/Button/Button.js +120 -0
- package/src/components/Button/button.css.js +137 -0
- package/src/components/Button/button.stories.js +56 -0
- package/src/components/Button/icons.css +5 -0
- package/src/components/Button/icons.js +24 -0
- package/src/components/Button/index.js +0 -0
- package/src/components/FAQ/faq.css.js +107 -0
- package/src/components/FAQ/faq.js +176 -0
- package/src/components/FAQ/faq.stories.js +45 -0
- package/src/components/Input/Input.js +27 -0
- package/src/components/Input/index.js +0 -0
- package/src/components/Input/input.css.js +68 -0
- package/src/components/carousel/carousel.css.js +304 -0
- package/src/components/carousel/carousel.js +226 -0
- package/src/components/carousel/carousel.stories.js +73 -0
- package/src/components/light-carousel/light-carousel.css.js +149 -0
- package/src/components/light-carousel/light-carousel.js +108 -0
- package/src/components/light-carousel/light-carousel.stories.js +43 -0
- package/src/components/paragraph/paragraph.css.js +16 -0
- package/src/components/paragraph/paragraph.js +59 -0
- package/src/components/pricing-cards/pricing-card.css.js +409 -0
- package/src/components/pricing-cards/pricing-card.js +764 -0
- package/src/components/pricing-cards/pricing-card.stories.js +12 -0
- package/src/components/tabs/tabs.css.js +239 -0
- package/src/components/tabs/tabs.js +183 -0
- package/src/components/tabs/tabs.stories.js +18 -0
- package/src/components/termsOfUse/terms.css.js +38 -0
- package/src/components/termsOfUse/terms.js +226 -0
- package/src/components/termsOfUse/terms.stories.js +14 -0
- package/src/index.js +0 -0
- package/src/stories/Button.js +20 -0
- package/src/stories/Button.stories.js +46 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/Header.js +45 -0
- package/src/stories/Header.stories.js +24 -0
- package/src/stories/Page.js +62 -0
- package/src/stories/Page.stories.js +20 -0
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +1 -0
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +1 -0
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +1 -0
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +1 -0
- package/src/stories/assets/youtube.svg +1 -0
- package/src/stories/button.css +30 -0
- package/src/stories/header.css +32 -0
- package/src/stories/page.css +68 -0
- package/src/tokens/colors.js +121 -0
- package/src/tokens/layout.css +46 -0
- package/src/tokens/tokens.css +297 -0
- package/src/tokens/typography.css.js +207 -0
- package/src/tokens/typography.js +0 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import pricingCardsCSS from "../pricing-cards/pricing-card.css.js";
|
|
3
|
+
|
|
4
|
+
import "/src/components/button/button.js";
|
|
5
|
+
|
|
6
|
+
class PricingContainer extends LitElement {
|
|
7
|
+
static properties = {
|
|
8
|
+
planType: { type: String },
|
|
9
|
+
locale: { type: String },
|
|
10
|
+
currency: { type: String },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.planType = "individual";
|
|
16
|
+
this.locale = "en-US";
|
|
17
|
+
this.currency = "EUR";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handleSwitch(event) {
|
|
21
|
+
console.log("Plan switched to:", event.detail.planType);
|
|
22
|
+
this.planType = event.detail.planType;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
formatCurrency(value) {
|
|
26
|
+
const numericValue =
|
|
27
|
+
typeof value === "number"
|
|
28
|
+
? value
|
|
29
|
+
: parseFloat(value.replace(/[^\d.-]/g, ""));
|
|
30
|
+
|
|
31
|
+
if (isNaN(numericValue)) return "";
|
|
32
|
+
|
|
33
|
+
// Foloseste Intl fara separator de mii
|
|
34
|
+
const formattedValue = new Intl.NumberFormat(this.locale, {
|
|
35
|
+
style: "currency",
|
|
36
|
+
currency: this.currency,
|
|
37
|
+
minimumFractionDigits: 2,
|
|
38
|
+
maximumFractionDigits: 2,
|
|
39
|
+
}).format(numericValue);
|
|
40
|
+
|
|
41
|
+
return formattedValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
render() {
|
|
45
|
+
return html`
|
|
46
|
+
<div class="pricing-container">
|
|
47
|
+
<pricing-switch
|
|
48
|
+
.planType=${this.planType}
|
|
49
|
+
@plan-switch=${this.handleSwitch}
|
|
50
|
+
></pricing-switch>
|
|
51
|
+
|
|
52
|
+
<div class="pricing-cards">
|
|
53
|
+
${this.planType === "individual"
|
|
54
|
+
? html`
|
|
55
|
+
<pricing-card
|
|
56
|
+
title="Bitdefender Ultimate Security"
|
|
57
|
+
price=${this.formatCurrency(79.99)}
|
|
58
|
+
discount="Save 50%"
|
|
59
|
+
originalPrice=${this.formatCurrency(159.99)}
|
|
60
|
+
features
|
|
61
|
+
.planType=${this.planType}
|
|
62
|
+
></pricing-card>
|
|
63
|
+
|
|
64
|
+
<pricing-card
|
|
65
|
+
highlight
|
|
66
|
+
features
|
|
67
|
+
identity
|
|
68
|
+
.planType=${this.planType}
|
|
69
|
+
></pricing-card>
|
|
70
|
+
|
|
71
|
+
<pricing-card
|
|
72
|
+
title="Bitdefender Total Security"
|
|
73
|
+
price=${this.formatCurrency(49.99)}
|
|
74
|
+
discount="Save 55%"
|
|
75
|
+
originalPrice=${this.formatCurrency(159.99)}
|
|
76
|
+
features
|
|
77
|
+
privacy
|
|
78
|
+
identity
|
|
79
|
+
.planType=${this.planType}
|
|
80
|
+
></pricing-card>
|
|
81
|
+
`
|
|
82
|
+
: html`<pricing-card-family
|
|
83
|
+
title="Bitdefender Ultimate Security"
|
|
84
|
+
price=${this.formatCurrency(119.99)}
|
|
85
|
+
discount="Save 40%"
|
|
86
|
+
originalPrice=${this.formatCurrency(199.99)}
|
|
87
|
+
features
|
|
88
|
+
privacy
|
|
89
|
+
identityExtended
|
|
90
|
+
parentalControl
|
|
91
|
+
></pricing-card-family>
|
|
92
|
+
<pricing-card-family
|
|
93
|
+
highlight
|
|
94
|
+
features
|
|
95
|
+
identity
|
|
96
|
+
></pricing-card-family>
|
|
97
|
+
<pricing-card-family
|
|
98
|
+
title="Bitdefender Total Security"
|
|
99
|
+
price=${this.formatCurrency(79.99)}
|
|
100
|
+
discount="Save 43%"
|
|
101
|
+
originalPrice=${this.formatCurrency(139.99)}
|
|
102
|
+
features
|
|
103
|
+
privacy
|
|
104
|
+
identity
|
|
105
|
+
></pricing-card-family>`}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
class PricingCard extends LitElement {
|
|
113
|
+
static properties = {
|
|
114
|
+
title: { type: String },
|
|
115
|
+
price: { type: String },
|
|
116
|
+
discount: { type: String },
|
|
117
|
+
originalPrice: { type: String },
|
|
118
|
+
features: { type: Boolean },
|
|
119
|
+
privacy: { type: Boolean },
|
|
120
|
+
highlight: { type: Boolean },
|
|
121
|
+
identity: { type: Boolean },
|
|
122
|
+
identityExtended: { type: Boolean },
|
|
123
|
+
parentalControl: { type: Boolean },
|
|
124
|
+
planType: { type: String },
|
|
125
|
+
locale: { type: String },
|
|
126
|
+
currency: { type: String },
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
constructor() {
|
|
130
|
+
super();
|
|
131
|
+
this.title = "Bitdefender Premium Security";
|
|
132
|
+
this.price = "69.99";
|
|
133
|
+
this.discount = "Save 46%";
|
|
134
|
+
this.originalPrice = "$129.99";
|
|
135
|
+
this.features = false;
|
|
136
|
+
this.privacy = false;
|
|
137
|
+
this.highlight = false;
|
|
138
|
+
this.identity = false;
|
|
139
|
+
this.identityExtended = false;
|
|
140
|
+
this.parentalControl = false;
|
|
141
|
+
this.planType = "individual";
|
|
142
|
+
this.locale = "en-US";
|
|
143
|
+
this.currency = "EUR";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
formatCurrency(value) {
|
|
147
|
+
const numberValue = parseFloat(value.replace(/[^\d.-]/g, ""));
|
|
148
|
+
|
|
149
|
+
if (isNaN(numberValue)) return value;
|
|
150
|
+
|
|
151
|
+
return new Intl.NumberFormat(this.locale, {
|
|
152
|
+
style: "currency",
|
|
153
|
+
currency: this.currency,
|
|
154
|
+
}).format(numberValue);
|
|
155
|
+
}
|
|
156
|
+
render() {
|
|
157
|
+
return html`
|
|
158
|
+
${this.planType === "individual"
|
|
159
|
+
? html`
|
|
160
|
+
<div class="card ${this.highlight ? "highlight" : ""}">
|
|
161
|
+
${this.highlight
|
|
162
|
+
? html`<div class="highlight-banner">Best value</div>`
|
|
163
|
+
: ""}
|
|
164
|
+
<div class="card-header">
|
|
165
|
+
<p class="card-title">${this.title}</p>
|
|
166
|
+
<span class="badge">
|
|
167
|
+
<img
|
|
168
|
+
src="src/assets/icons/badge-icon-individual.png"
|
|
169
|
+
alt="icon"
|
|
170
|
+
class="badge-icon"
|
|
171
|
+
/>
|
|
172
|
+
Individual</span
|
|
173
|
+
>
|
|
174
|
+
<p class="badge-subtitle">1 account & 5 devices</p>
|
|
175
|
+
<hr class="hr-line" />
|
|
176
|
+
</div>
|
|
177
|
+
<div class="pricing">
|
|
178
|
+
<div class="pricing-info">
|
|
179
|
+
<p class="original-price">
|
|
180
|
+
${this.formatCurrency(this.originalPrice)}
|
|
181
|
+
</p>
|
|
182
|
+
<p class="discount">${this.discount}</p>
|
|
183
|
+
</div>
|
|
184
|
+
<p class="price">${this.formatCurrency(this.price)}</p>
|
|
185
|
+
<p class="terms">
|
|
186
|
+
First year price. Plus applicable sales tax. See
|
|
187
|
+
<a href="#">terms of use</a> below.
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
<div class="actions">
|
|
191
|
+
<bd-button
|
|
192
|
+
label="Buy Now"
|
|
193
|
+
kind="danger"
|
|
194
|
+
size="md"
|
|
195
|
+
fullWidth
|
|
196
|
+
strong
|
|
197
|
+
>Buy Now</bd-button>
|
|
198
|
+
|
|
199
|
+
<bd-button
|
|
200
|
+
label="Learn More"
|
|
201
|
+
kind="outline"
|
|
202
|
+
size="md"
|
|
203
|
+
fullWidth
|
|
204
|
+
strong
|
|
205
|
+
>Learn More</bd-button>
|
|
206
|
+
</div>
|
|
207
|
+
<hr class="hr-line" />
|
|
208
|
+
${this.features
|
|
209
|
+
? html`<pricing-card-features></pricing-card-features>`
|
|
210
|
+
: ""}
|
|
211
|
+
${this.privacy
|
|
212
|
+
? html`<pricing-card-privacy></pricing-card-privacy>`
|
|
213
|
+
: ""}
|
|
214
|
+
${this.identity
|
|
215
|
+
? html`<pricing-card-identity></pricing-card-identity>`
|
|
216
|
+
: ""}
|
|
217
|
+
${this.identityExtended
|
|
218
|
+
? html`<pricing-card-identity-extended></pricing-card-identity-extended>`
|
|
219
|
+
: ""}
|
|
220
|
+
${this.parentalControl
|
|
221
|
+
? html`<pricing-card-parental-control></pricing-card-parental-control>`
|
|
222
|
+
: ""}
|
|
223
|
+
</div>
|
|
224
|
+
`
|
|
225
|
+
: ""}
|
|
226
|
+
`;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
class PricingCardFamily extends LitElement {
|
|
230
|
+
static properties = {
|
|
231
|
+
title: { type: String },
|
|
232
|
+
price: { type: String },
|
|
233
|
+
discount: { type: String },
|
|
234
|
+
originalPrice: { type: String },
|
|
235
|
+
features: { type: Boolean },
|
|
236
|
+
privacy: { type: Boolean },
|
|
237
|
+
highlight: { type: Boolean },
|
|
238
|
+
identity: { type: Boolean },
|
|
239
|
+
identityExtended: { type: Boolean },
|
|
240
|
+
parentalControl: { type: Boolean },
|
|
241
|
+
planType: { type: String },
|
|
242
|
+
locale: { type: String },
|
|
243
|
+
currency: { type: String },
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
constructor() {
|
|
247
|
+
super();
|
|
248
|
+
this.title = "Bitdefender Premium Security";
|
|
249
|
+
this.price = "$99.99";
|
|
250
|
+
this.discount = "Save 41%";
|
|
251
|
+
this.originalPrice = "$169.99";
|
|
252
|
+
this.features = false;
|
|
253
|
+
this.privacy = false;
|
|
254
|
+
this.highlight = false;
|
|
255
|
+
this.identity = false;
|
|
256
|
+
this.identityExtended = false;
|
|
257
|
+
this.parentalControl = false;
|
|
258
|
+
this.planType = "family";
|
|
259
|
+
this.locale = "en-US";
|
|
260
|
+
this.currency = "EUR";
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
formatCurrency(value) {
|
|
264
|
+
const numberValue = parseFloat(value.replace(/[^\d.-]/g, ""));
|
|
265
|
+
|
|
266
|
+
if (isNaN(numberValue)) return value;
|
|
267
|
+
|
|
268
|
+
return new Intl.NumberFormat(this.locale, {
|
|
269
|
+
style: "currency",
|
|
270
|
+
currency: this.currency,
|
|
271
|
+
}).format(numberValue);
|
|
272
|
+
}
|
|
273
|
+
render() {
|
|
274
|
+
return html`
|
|
275
|
+
${this.planType === "family"
|
|
276
|
+
? html`
|
|
277
|
+
<div class="card ${this.highlight ? "highlight" : ""}">
|
|
278
|
+
${this.highlight
|
|
279
|
+
? html`<div class="highlight-banner">Best value</div>`
|
|
280
|
+
: ""}
|
|
281
|
+
<div class="card-header">
|
|
282
|
+
<p class="card-title">${this.title}</p>
|
|
283
|
+
<span class="badge">
|
|
284
|
+
<img
|
|
285
|
+
src="src/assets/icons/bd-icon-family-white.png"
|
|
286
|
+
alt="icon"
|
|
287
|
+
class="badge-icon-family-subtitle"
|
|
288
|
+
/>
|
|
289
|
+
<span class="family-text"> Family</span></span
|
|
290
|
+
>
|
|
291
|
+
<p class="badge-subtitle">5 accounts & 25 devices</p>
|
|
292
|
+
<hr class="hr-line" />
|
|
293
|
+
</div>
|
|
294
|
+
<div class="pricing">
|
|
295
|
+
<div class="pricing-info">
|
|
296
|
+
<p class="original-price">
|
|
297
|
+
${this.formatCurrency(this.originalPrice)}
|
|
298
|
+
</p>
|
|
299
|
+
<p class="discount">${this.discount}</p>
|
|
300
|
+
</div>
|
|
301
|
+
<p class="price">${this.formatCurrency(this.price)}</p>
|
|
302
|
+
<p class="terms">
|
|
303
|
+
First year price. Plus applicable sales tax. See
|
|
304
|
+
<a href="#">terms of use</a> below.
|
|
305
|
+
</p>
|
|
306
|
+
</div>
|
|
307
|
+
<div class="actions">
|
|
308
|
+
<bd-button
|
|
309
|
+
label="Buy Now"
|
|
310
|
+
kind="danger"
|
|
311
|
+
size="md"
|
|
312
|
+
fullWidth
|
|
313
|
+
strong
|
|
314
|
+
>Buy Now</bd-button>
|
|
315
|
+
|
|
316
|
+
<bd-button
|
|
317
|
+
label="Learn More"
|
|
318
|
+
kind="outline"
|
|
319
|
+
size="md"
|
|
320
|
+
fullWidth
|
|
321
|
+
strong
|
|
322
|
+
>Learn More</bd-button>
|
|
323
|
+
</div>
|
|
324
|
+
<hr class="hr-line" />
|
|
325
|
+
${this.features
|
|
326
|
+
? html`<pricing-card-features></pricing-card-features>`
|
|
327
|
+
: ""}
|
|
328
|
+
${this.privacy
|
|
329
|
+
? html`<pricing-card-privacy></pricing-card-privacy>`
|
|
330
|
+
: ""}
|
|
331
|
+
${this.identity
|
|
332
|
+
? html`<pricing-card-identity></pricing-card-identity>`
|
|
333
|
+
: ""}
|
|
334
|
+
${this.identityExtended
|
|
335
|
+
? html`<pricing-card-identity-extended></pricing-card-identity-extended>`
|
|
336
|
+
: ""}
|
|
337
|
+
${this.parentalControl
|
|
338
|
+
? html`<pricing-card-parental-control></pricing-card-parental-control>`
|
|
339
|
+
: ""}
|
|
340
|
+
</div>
|
|
341
|
+
`
|
|
342
|
+
: ""}
|
|
343
|
+
`;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
class PricingSwitch extends LitElement {
|
|
348
|
+
static properties = {
|
|
349
|
+
planType: { type: String },
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
constructor() {
|
|
353
|
+
super();
|
|
354
|
+
this.planType = "individual";
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
handleSwitch(event) {
|
|
358
|
+
const newPlanType = event.target.checked ? "family" : "individual";
|
|
359
|
+
console.log("Switch to:", newPlanType);
|
|
360
|
+
this.planType = newPlanType;
|
|
361
|
+
|
|
362
|
+
this.dispatchEvent(
|
|
363
|
+
new CustomEvent("plan-switch", {
|
|
364
|
+
detail: { planType: this.planType },
|
|
365
|
+
bubbles: true,
|
|
366
|
+
composed: true,
|
|
367
|
+
})
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
render() {
|
|
372
|
+
return html`
|
|
373
|
+
<div class="switchBox">
|
|
374
|
+
<label class="switch">
|
|
375
|
+
<input
|
|
376
|
+
type="checkbox"
|
|
377
|
+
id="switchCheckbox"
|
|
378
|
+
@input=${this.handleSwitch}
|
|
379
|
+
?checked=${this.planType === "family"}
|
|
380
|
+
/>
|
|
381
|
+
<span class="slider round"></span>
|
|
382
|
+
<span class="label right">
|
|
383
|
+
<span class="icon icon-user-sharp-regular">
|
|
384
|
+
<img
|
|
385
|
+
src="src/assets/icons/bd-icon-user.png"
|
|
386
|
+
alt="icon"
|
|
387
|
+
class="badge-icon-user"
|
|
388
|
+
height="22"
|
|
389
|
+
width="22"
|
|
390
|
+
/>
|
|
391
|
+
</span>
|
|
392
|
+
Individual
|
|
393
|
+
</span>
|
|
394
|
+
<span class="label left">
|
|
395
|
+
<span class="icon icon-family-pants-sharp-regular">
|
|
396
|
+
<img
|
|
397
|
+
src="src/assets/icons/bd-icon-family.png"
|
|
398
|
+
alt="icon"
|
|
399
|
+
class="badge-icon-family"
|
|
400
|
+
height="24"
|
|
401
|
+
width="24"
|
|
402
|
+
/>
|
|
403
|
+
</span>
|
|
404
|
+
Family
|
|
405
|
+
</span>
|
|
406
|
+
</label>
|
|
407
|
+
</div>
|
|
408
|
+
`;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
class PricingCardFeatures extends LitElement {
|
|
413
|
+
static properties = {
|
|
414
|
+
features: { type: Array },
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
constructor() {
|
|
418
|
+
super();
|
|
419
|
+
this.features = [
|
|
420
|
+
{
|
|
421
|
+
name: "Multiplatform Windows®, macOS®, Android™, iOS®",
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: "Multi-Awarded Antivirus, Malware, Ransomware Protection",
|
|
425
|
+
description: "Consistent results in independent tests for 10+ years",
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
name: "Scam Prevention & Detection",
|
|
429
|
+
description:
|
|
430
|
+
"Outsmart scammers and keep your money, your credentials, identity, and digital assets",
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
name: "Cryptomining Protection",
|
|
434
|
+
description:
|
|
435
|
+
"Bad actors can make money using your hardware and power connection without your consent. Protect yourself against “leech” software!",
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: "Innovative Email Protection",
|
|
439
|
+
description:
|
|
440
|
+
"Scans all incoming email and marks them as “safe” or “unsafe”",
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: "Scam Copilot",
|
|
444
|
+
description:
|
|
445
|
+
"Scam Copilot: Get protection against online scams with AI-powered anti-scam features.",
|
|
446
|
+
},
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
render() {
|
|
451
|
+
const features = this.features || [];
|
|
452
|
+
return html`
|
|
453
|
+
<div class="features">
|
|
454
|
+
<h4>Device Security</h4>
|
|
455
|
+
<ul class="additional-info">
|
|
456
|
+
${features.map(
|
|
457
|
+
(feature) => html` <li class="feature-item">
|
|
458
|
+
<img
|
|
459
|
+
src="src/assets/icons/verified_arrow.png"
|
|
460
|
+
alt="icon"
|
|
461
|
+
class="badge-icon"
|
|
462
|
+
/>
|
|
463
|
+
${feature.name}
|
|
464
|
+
${feature.description
|
|
465
|
+
? html`<div class="tooltip">${feature.description}</div>`
|
|
466
|
+
: ""}
|
|
467
|
+
</li>`
|
|
468
|
+
)}
|
|
469
|
+
</ul>
|
|
470
|
+
</div>
|
|
471
|
+
`;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
class PricingCardPrivacy extends LitElement {
|
|
476
|
+
static properties = {
|
|
477
|
+
privacy: { type: Array },
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
constructor() {
|
|
481
|
+
super();
|
|
482
|
+
this.privacy = [
|
|
483
|
+
{
|
|
484
|
+
name: "Password Manager 1x",
|
|
485
|
+
description:
|
|
486
|
+
"Ultra-secure, feature-rich password manager. The last password you will ever need for hundreds of online accounts",
|
|
487
|
+
badge: "1x",
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "Unlimited VPN traffic 1x",
|
|
491
|
+
description:
|
|
492
|
+
"Keep your internet connections private & secure with VPN. Enjoy total anonymity on public & shared WI-FIs",
|
|
493
|
+
badge: "1x",
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
name: "Choose from 4000+ VPN servers in 50+ countries",
|
|
497
|
+
description:
|
|
498
|
+
"Our entire fleet of servers uses the latest available hardware, high-speed 10Gbps connections, and dedicated DNS servers.",
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
name: "System-wide Ad blocker & Anti-tracker",
|
|
502
|
+
description:
|
|
503
|
+
"Blocks ads, hinders ad targeting, and prevents online behavior profiling.",
|
|
504
|
+
},
|
|
505
|
+
];
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
render() {
|
|
509
|
+
const privacy = this.privacy || [];
|
|
510
|
+
return html`
|
|
511
|
+
<div class="features">
|
|
512
|
+
<h4>Privacy</h4>
|
|
513
|
+
<ul class="additional-info">
|
|
514
|
+
${privacy.map(
|
|
515
|
+
(priv) => html` <li class="feature-item">
|
|
516
|
+
<img
|
|
517
|
+
src="src/assets/icons/verified_arrow.png"
|
|
518
|
+
alt="icon"
|
|
519
|
+
class="badge-icon"
|
|
520
|
+
/>
|
|
521
|
+
${priv.name.replace(" 1x", "")}
|
|
522
|
+
${priv.badge
|
|
523
|
+
? html`<span class="badge-feature"
|
|
524
|
+
>${priv.badge}
|
|
525
|
+
<img
|
|
526
|
+
src="src/assets/icons/badge-icon-individual.png"
|
|
527
|
+
alt="icon"
|
|
528
|
+
class="badge-feature-icon"
|
|
529
|
+
/></span>`
|
|
530
|
+
: ""}
|
|
531
|
+
${priv.description
|
|
532
|
+
? html`<div class="tooltip">${priv.description}</div>`
|
|
533
|
+
: ""}
|
|
534
|
+
</li>`
|
|
535
|
+
)}
|
|
536
|
+
</ul>
|
|
537
|
+
</div>
|
|
538
|
+
`;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
class PricingCardIdentify extends LitElement {
|
|
543
|
+
static properties = {
|
|
544
|
+
identity: { type: Array },
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
constructor() {
|
|
548
|
+
super();
|
|
549
|
+
this.identity = [
|
|
550
|
+
{
|
|
551
|
+
name: "Data Breach Detection",
|
|
552
|
+
description:
|
|
553
|
+
"Ultra-secure, feature-rich password manager. The last password you will ever need for hundreds of online accounts",
|
|
554
|
+
badge: "1x",
|
|
555
|
+
},
|
|
556
|
+
];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
render() {
|
|
560
|
+
const identity = this.identity || [];
|
|
561
|
+
return html`
|
|
562
|
+
<div class="features">
|
|
563
|
+
<h4>Identity Protection</h4>
|
|
564
|
+
<ul class="additional-info">
|
|
565
|
+
${identity.map(
|
|
566
|
+
(ident) => html` <li class="feature-item">
|
|
567
|
+
<img
|
|
568
|
+
src="src/assets/icons/verified_arrow.png"
|
|
569
|
+
alt="icon"
|
|
570
|
+
class="badge-icon"
|
|
571
|
+
/>
|
|
572
|
+
${ident.name}
|
|
573
|
+
${ident.badge
|
|
574
|
+
? html`<span class="badge-feature"
|
|
575
|
+
>${ident.badge}
|
|
576
|
+
<img
|
|
577
|
+
src="src/assets/icons/badge-icon-individual.png"
|
|
578
|
+
alt="icon"
|
|
579
|
+
class="badge-feature-icon"
|
|
580
|
+
/></span>`
|
|
581
|
+
: ""}
|
|
582
|
+
${ident.description
|
|
583
|
+
? html`<div class="tooltip">${ident.description}</div>`
|
|
584
|
+
: ""}
|
|
585
|
+
</li>`
|
|
586
|
+
)}
|
|
587
|
+
</ul>
|
|
588
|
+
</div>
|
|
589
|
+
`;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
class PricingCardIdentityExtend extends LitElement {
|
|
594
|
+
static properties = {
|
|
595
|
+
identity: { type: Array },
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
constructor() {
|
|
599
|
+
super();
|
|
600
|
+
this.identity = [
|
|
601
|
+
{
|
|
602
|
+
name: "Digital Identity Protection",
|
|
603
|
+
description:
|
|
604
|
+
"Don't get caught off guard by future data leaks. Every time your personal information ends up in a breach, Bitdefender Digital Identity Protection notifies you so you can act quickly and minimize the impact.",
|
|
605
|
+
badge: "1x",
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
name: "Data Breach Detection",
|
|
609
|
+
description:
|
|
610
|
+
"Access a comprehensive list detailing organizations that exposed your personal information and get actionable tips to address each breach and fortify your online security.",
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: "Dark Web Monitoring",
|
|
614
|
+
description:
|
|
615
|
+
"We constantly scan the web (including dark web) for unauthorized leaks of personal data and give real-time alerts so you can act quickly by changing passwords, deleting accounts, or freezing credit cards before a serious incident occurs.",
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
name: "Digital Footprint Visualization",
|
|
619
|
+
description:
|
|
620
|
+
"Identify precisely which websites or services have compromised your sensitive information, and see how you can undo the damage.",
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
name: "Real Time Breach Notifications",
|
|
624
|
+
description:
|
|
625
|
+
"Stay one step ahead with our real-time breach notification feature. Instant alerts empower you to take immediate action, protecting your sensitive information and maintaining peace of mind effortlessly.",
|
|
626
|
+
},
|
|
627
|
+
];
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
render() {
|
|
631
|
+
const identity = this.identity || [];
|
|
632
|
+
return html`
|
|
633
|
+
<div class="features">
|
|
634
|
+
<h4>Identity Protection</h4>
|
|
635
|
+
<ul class="additional-info">
|
|
636
|
+
${identity.map(
|
|
637
|
+
(ident) => html` <li class="feature-item">
|
|
638
|
+
<img
|
|
639
|
+
src="src/assets/icons/verified_arrow.png"
|
|
640
|
+
alt="icon"
|
|
641
|
+
class="badge-icon"
|
|
642
|
+
/>
|
|
643
|
+
${ident.name}
|
|
644
|
+
${ident.badge
|
|
645
|
+
? html`<span class="badge-feature"
|
|
646
|
+
>${ident.badge}
|
|
647
|
+
<img
|
|
648
|
+
src="src/assets/icons/badge-icon-individual.png"
|
|
649
|
+
alt="icon"
|
|
650
|
+
class="badge-feature-icon"
|
|
651
|
+
/></span>`
|
|
652
|
+
: ""}
|
|
653
|
+
${ident.description
|
|
654
|
+
? html`<div class="tooltip">${ident.description}</div>`
|
|
655
|
+
: ""}
|
|
656
|
+
</li>`
|
|
657
|
+
)}
|
|
658
|
+
</ul>
|
|
659
|
+
</div>
|
|
660
|
+
`;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
class PricingCardParentalControl extends LitElement {
|
|
665
|
+
static properties = {
|
|
666
|
+
parentalControl: { type: Array },
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
constructor() {
|
|
670
|
+
super();
|
|
671
|
+
this.parentalControl = [
|
|
672
|
+
{
|
|
673
|
+
name: "Internet time limit",
|
|
674
|
+
description:
|
|
675
|
+
"Set healthy limits on the time your child can spend online on a certain device.",
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
name: "Content filtering",
|
|
679
|
+
description:
|
|
680
|
+
"Select the content categories you want to keep away from your child.",
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
name: "Routines/Schedules",
|
|
684
|
+
description:
|
|
685
|
+
"Manage your child's internet time with customizable daily limits, structured routines like Focus time, Family time and Bedtime",
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
name: "Location",
|
|
689
|
+
description: "Track child location.",
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "Rewards",
|
|
693
|
+
description:
|
|
694
|
+
"Interact with children by responding to their requests for extending daily internet time.",
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
name: "Activity reports",
|
|
698
|
+
description:
|
|
699
|
+
"Unified reporting and easier management across all devices, providing you with a better overview of your child’s online activities.",
|
|
700
|
+
},
|
|
701
|
+
];
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
render() {
|
|
705
|
+
const parentalControl = this.parentalControl || [];
|
|
706
|
+
return html`
|
|
707
|
+
<div class="features">
|
|
708
|
+
<h4>Parental Control</h4>
|
|
709
|
+
<ul class="additional-info">
|
|
710
|
+
${parentalControl.map(
|
|
711
|
+
(parental) => html` <li class="feature-item">
|
|
712
|
+
<img
|
|
713
|
+
src="src/assets/icons/verified_arrow.png"
|
|
714
|
+
alt="icon"
|
|
715
|
+
class="badge-icon"
|
|
716
|
+
/>
|
|
717
|
+
${parental.name}
|
|
718
|
+
${parental.badge
|
|
719
|
+
? html`<span class="badge-feature"
|
|
720
|
+
>${parental.badge}
|
|
721
|
+
<img
|
|
722
|
+
src="src/assets/icons/badge-icon-individual.png"
|
|
723
|
+
alt="icon"
|
|
724
|
+
class="badge-feature-icon"
|
|
725
|
+
/></span>`
|
|
726
|
+
: ""}
|
|
727
|
+
${parental.description
|
|
728
|
+
? html`<div class="tooltip">${parental.description}</div>`
|
|
729
|
+
: ""}
|
|
730
|
+
</li>`
|
|
731
|
+
)}
|
|
732
|
+
</ul>
|
|
733
|
+
</div>
|
|
734
|
+
`;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
PricingCardIdentify.styles = [pricingCardsCSS];
|
|
739
|
+
PricingCardIdentityExtend.styles = [pricingCardsCSS];
|
|
740
|
+
PricingCardParentalControl.styles = [pricingCardsCSS];
|
|
741
|
+
|
|
742
|
+
PricingCardPrivacy.styles = [pricingCardsCSS];
|
|
743
|
+
PricingCardFeatures.styles = [pricingCardsCSS];
|
|
744
|
+
PricingCard.styles = [pricingCardsCSS];
|
|
745
|
+
PricingCardFamily.styles = [pricingCardsCSS];
|
|
746
|
+
PricingContainer.styles = [pricingCardsCSS];
|
|
747
|
+
PricingSwitch.styles = [pricingCardsCSS];
|
|
748
|
+
|
|
749
|
+
customElements.define("pricing-card-identity", PricingCardIdentify);
|
|
750
|
+
customElements.define(
|
|
751
|
+
"pricing-card-identity-extended",
|
|
752
|
+
PricingCardIdentityExtend
|
|
753
|
+
);
|
|
754
|
+
customElements.define(
|
|
755
|
+
"pricing-card-parental-control",
|
|
756
|
+
PricingCardParentalControl
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
customElements.define("pricing-card-privacy", PricingCardPrivacy);
|
|
760
|
+
customElements.define("pricing-card-features", PricingCardFeatures);
|
|
761
|
+
customElements.define("pricing-card", PricingCard);
|
|
762
|
+
customElements.define("pricing-card-family", PricingCardFamily);
|
|
763
|
+
customElements.define("bd-pricing-container", PricingContainer);
|
|
764
|
+
customElements.define("pricing-switch", PricingSwitch);
|