@repobit/dex-system-design 0.23.94 → 0.23.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +4 -4
  3. package/src/blog/assets/articles/fbi-crypto-scam-1.jpeg +0 -0
  4. package/src/blog/assets/articles/fbi-crypto-scam-cover.png +0 -0
  5. package/src/blog/assets/fonts/IBMPlexSans-Bold.woff2 +0 -0
  6. package/src/blog/assets/fonts/IBMPlexSans-BoldItalic.woff2 +0 -0
  7. package/src/blog/assets/fonts/IBMPlexSans-Italic.woff2 +0 -0
  8. package/src/blog/assets/fonts/IBMPlexSans-Light.woff2 +0 -0
  9. package/src/blog/assets/fonts/IBMPlexSans-LightItalic.woff2 +0 -0
  10. package/src/blog/assets/fonts/IBMPlexSans-Medium.woff2 +0 -0
  11. package/src/blog/assets/fonts/IBMPlexSans-MediumItalic.woff2 +0 -0
  12. package/src/blog/assets/fonts/IBMPlexSans-Regular.woff2 +0 -0
  13. package/src/blog/assets/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
  14. package/src/blog/assets/fonts/IBMPlexSans-SemiBoldItalic.woff2 +0 -0
  15. package/src/blog/assets/fonts/IBMPlexSansCondensed-Bold.woff2 +0 -0
  16. package/src/blog/assets/fonts/IBMPlexSansCondensed-BoldItalic.woff2 +0 -0
  17. package/src/blog/assets/fonts/IBMPlexSansCondensed-Italic.woff2 +0 -0
  18. package/src/blog/assets/fonts/IBMPlexSansCondensed-Light.woff2 +0 -0
  19. package/src/blog/assets/fonts/IBMPlexSansCondensed-LightItalic.woff2 +0 -0
  20. package/src/blog/assets/fonts/IBMPlexSansCondensed-Medium.woff2 +0 -0
  21. package/src/blog/assets/fonts/IBMPlexSansCondensed-MediumItalic.woff2 +0 -0
  22. package/src/blog/assets/fonts/IBMPlexSansCondensed-Regular.woff2 +0 -0
  23. package/src/blog/assets/fonts/IBMPlexSansCondensed-SemiBold.woff2 +0 -0
  24. package/src/blog/assets/fonts/IBMPlexSansCondensed-SemiBoldItalic.woff2 +0 -0
  25. package/src/blog/assets/global-scam-intelligence-report-2026.png +0 -0
  26. package/src/blog/assets/psd-4.jpg +0 -0
  27. package/src/blog/src/articles/FBI warns of crypto investment scam that sends couriers to collect victims' cash-editedAB.docx +0 -0
  28. package/src/blog/src/articles/FBI-crypto-scam-courier-cash.png +0 -0
  29. package/src/blog/src/articles/fbi-crypto-scam.js +324 -0
  30. package/src/blog/src/articles/~$I warns of crypto investment scam that sends couriers to collect victims' cash-editedAB.docx +0 -0
  31. package/src/blog/src/atoms/blog-abstract.js +51 -0
  32. package/src/blog/src/atoms/blog-atoms.stories.js +519 -0
  33. package/src/blog/src/atoms/blog-authors.js +70 -0
  34. package/src/blog/src/atoms/blog-avatar.js +44 -0
  35. package/src/blog/src/atoms/blog-blockquote.js +92 -0
  36. package/src/blog/src/atoms/blog-caption.js +31 -0
  37. package/src/blog/src/atoms/blog-code-block.js +89 -0
  38. package/src/blog/src/atoms/blog-dek.js +30 -0
  39. package/src/blog/src/atoms/blog-featured-image.js +65 -0
  40. package/src/blog/src/atoms/blog-heading.js +63 -0
  41. package/src/blog/src/atoms/blog-image.js +50 -0
  42. package/src/blog/src/atoms/blog-key-takeaways.js +101 -0
  43. package/src/blog/src/atoms/blog-link.js +68 -0
  44. package/src/blog/src/atoms/blog-meta.js +87 -0
  45. package/src/blog/src/atoms/blog-most-popular.js +146 -0
  46. package/src/blog/src/atoms/blog-newsletter-signup.js +342 -0
  47. package/src/blog/src/atoms/blog-paragraph.js +61 -0
  48. package/src/blog/src/atoms/blog-product-upsell.js +168 -0
  49. package/src/blog/src/atoms/blog-related-articles.js +326 -0
  50. package/src/blog/src/atoms/blog-related-label.js +30 -0
  51. package/src/blog/src/atoms/blog-report-promo.js +250 -0
  52. package/src/blog/src/atoms/blog-standout.js +78 -0
  53. package/src/blog/src/atoms/blog-subhead.js +32 -0
  54. package/src/blog/src/atoms/blog-table-of-contents.js +447 -0
  55. package/src/blog/src/atoms/blog-tag.js +86 -0
  56. package/src/blog/src/atoms/blog-title.js +31 -0
  57. package/src/blog/src/base/blog-element.js +10 -0
  58. package/src/blog/src/breakpoints.js +23 -0
  59. package/src/blog/src/content/blog-article.js +736 -0
  60. package/src/blog/src/content/blog-atoms-showcase.js +401 -0
  61. package/src/blog/src/content/blog-page-layout.js +73 -0
  62. package/src/blog/src/content/blog-pages.stories.js +101 -0
  63. package/src/blog/src/content/render-inline-content.js +18 -0
  64. package/src/blog/src/data/popular-articles.js +43 -0
  65. package/src/blog/src/data/related-articles.js +58 -0
  66. package/src/blog/src/index.js +104 -0
  67. package/src/blog/src/lib/article-toc.js +206 -0
  68. package/src/blog/src/lib/load-prism.js +23 -0
  69. package/src/blog/src/shell/blog-shell.js +31 -0
  70. package/src/blog/src/styles/prism-theme.js +65 -0
  71. package/src/blog/src/tokens/blog.js +406 -0
  72. package/src/blog/src/tokens/core.js +811 -0
  73. package/src/blog/src/tokens/fonts.css +241 -0
  74. package/src/blog/src/tokens/index.js +27 -0
  75. package/src/blog/src/tokens/legacy.js +58 -0
  76. package/src/blog/tokens/blog.js +406 -0
  77. package/src/blog/tokens/core.js +811 -0
  78. package/src/blog/tokens/fonts.css +241 -0
  79. package/src/blog/tokens/index.js +27 -0
  80. package/src/blog/tokens/legacy.js +58 -0
  81. package/src/blog/tokens.css +1512 -0
  82. package/src/blog/tokens.js +1 -0
  83. package/src/blog/vendor/prism/prism.css +120 -0
  84. package/src/blog/vendor/prism/prism.js +300 -0
@@ -0,0 +1,168 @@
1
+ import { css, html, nothing, unsafeCSS } from 'lit';
2
+ import { BlogElement } from '../base/blog-element.js';
3
+ import { minWidth } from '../breakpoints.js';
4
+
5
+ /**
6
+ * In-article product upsell — copy, CTA, and optional social proof.
7
+ *
8
+ * @property {string} headline
9
+ * @property {string} description
10
+ * @property {string} ctaLabel
11
+ * @property {string} ctaHref
12
+ * @property {string} socialProof
13
+ */
14
+ export class BlogProductUpsell extends BlogElement {
15
+ static properties = {
16
+ headline : { type: String },
17
+ description: { type: String },
18
+ ctaLabel : { type: String, attribute: 'cta-label' },
19
+ ctaHref : { type: String, attribute: 'cta-href' },
20
+ socialProof: { type: String, attribute: 'social-proof' }
21
+ };
22
+
23
+ constructor() {
24
+ super();
25
+ this.headline = 'Want stronger protection against scams and online fraud?';
26
+ this.description =
27
+ 'Bitdefender helps block phishing, malicious links, and identity threats across your devices. Try it free for 30 days.';
28
+ this.ctaLabel = 'Get Bitdefender Total Security';
29
+ this.ctaHref = '#';
30
+ this.socialProof = '★ 4.8 · Trusted by millions worldwide';
31
+ }
32
+
33
+ static styles = [
34
+ ...BlogElement.styles,
35
+ css`
36
+ :host {
37
+ display: block;
38
+ }
39
+
40
+ .upsell {
41
+ display: flex;
42
+ flex-direction: column;
43
+ align-items: center;
44
+ gap: var(--blog-card-gap);
45
+ padding: var(--blog-card-padding);
46
+ border-radius: var(--blog-newsletter-borderRadius);
47
+ background: var(--color-surface-subtle);
48
+ text-align: center;
49
+ }
50
+
51
+ .upsell__copy {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: var(--spacing-4);
55
+ min-width: 0;
56
+ }
57
+
58
+ .upsell__headline {
59
+ margin: 0;
60
+ font-family: var(--blog-takeaways-title-fontFamily);
61
+ font-size: var(--blog-takeaways-title-fontSize);
62
+ font-weight: var(--blog-takeaways-title-fontWeight);
63
+ line-height: var(--blog-takeaways-title-lineHeight);
64
+ color: var(--blog-takeaways-title-color);
65
+ }
66
+
67
+ .upsell__description {
68
+ margin: 0;
69
+ font-family: var(--blog-newsletter-description-fontFamily);
70
+ font-size: var(--blog-newsletter-description-fontSize);
71
+ font-weight: var(--blog-newsletter-description-fontWeight);
72
+ line-height: var(--blog-newsletter-description-lineHeight);
73
+ color: var(--blog-prose-color);
74
+ }
75
+
76
+ .upsell__actions {
77
+ display: flex;
78
+ flex-direction: column;
79
+ align-items: center;
80
+ gap: var(--blog-newsletter-form-gap);
81
+ }
82
+
83
+ .upsell__cta {
84
+ display: inline-flex;
85
+ align-items: center;
86
+ justify-content: center;
87
+ gap: var(--button-size-small-gap);
88
+ box-sizing: border-box;
89
+ min-height: var(--button-size-small-height);
90
+ padding: var(--spacing-8) var(--spacing-16);
91
+ border: var(--button-shared-borderWidth) solid
92
+ var(--button-primary-border-default);
93
+ border-radius: var(--button-size-small-borderRadius);
94
+ background: var(--button-primary-background-default);
95
+ cursor: pointer;
96
+ font-family: var(--button-shared-fontFamily);
97
+ font-size: var(--button-size-small-fontSize);
98
+ font-weight: var(--button-shared-fontWeight);
99
+ line-height: var(--button-shared-lineHeight);
100
+ letter-spacing: var(--button-shared-letterSpacing);
101
+ color: var(--button-primary-text-default);
102
+ text-align: center;
103
+ text-decoration: none;
104
+ transition: var(--button-shared-transition-properties)
105
+ var(--button-shared-transition-duration)
106
+ var(--button-shared-transition-easing);
107
+ }
108
+
109
+ .upsell__cta:hover {
110
+ background: var(--button-primary-background-hover);
111
+ border-color: var(--button-primary-border-hover);
112
+ }
113
+
114
+ .upsell__cta:active {
115
+ background: var(--button-primary-background-active);
116
+ border-color: var(--button-primary-border-active);
117
+ }
118
+
119
+ .upsell__cta:focus-visible {
120
+ outline: var(--button-shared-focus-outline);
121
+ outline-offset: var(--button-shared-focus-outlineOffset);
122
+ }
123
+
124
+ .upsell__social {
125
+ margin: 0;
126
+ font-family: var(--blog-newsletter-disclaimer-fontFamily);
127
+ font-size: var(--blog-newsletter-disclaimer-fontSize);
128
+ font-weight: var(--blog-newsletter-disclaimer-fontWeight);
129
+ line-height: var(--blog-newsletter-disclaimer-lineHeight);
130
+ color: var(--blog-newsletter-disclaimer-color);
131
+ text-align: center;
132
+ }
133
+
134
+ ${unsafeCSS(minWidth('lg'))} {
135
+ .upsell {
136
+ flex-direction: row;
137
+ align-items: center;
138
+ text-align: left;
139
+ }
140
+
141
+ .upsell__actions {
142
+ flex: none;
143
+ align-items: center;
144
+ }
145
+ }
146
+ `
147
+ ];
148
+
149
+ render() {
150
+ return html`
151
+ <aside class="upsell" part="upsell" aria-label="Related product">
152
+ <div class="upsell__copy" part="copy">
153
+ <p class="upsell__headline" part="headline">${this.headline}</p>
154
+ <p class="upsell__description" part="description">${this.description}</p>
155
+ </div>
156
+
157
+ <div class="upsell__actions" part="actions">
158
+ <a class="upsell__cta" part="cta" href=${this.ctaHref}>${this.ctaLabel}</a>
159
+ ${this.socialProof
160
+ ? html`<p class="upsell__social" part="social">${this.socialProof}</p>`
161
+ : nothing}
162
+ </div>
163
+ </aside>
164
+ `;
165
+ }
166
+ }
167
+
168
+ customElements.define('blog-product-upsell', BlogProductUpsell);
@@ -0,0 +1,326 @@
1
+ import { css, html, unsafeCSS } from 'lit';
2
+ import { BlogElement } from '../base/blog-element.js';
3
+ import { minWidth } from '../breakpoints.js';
4
+ import './blog-meta.js';
5
+ import './blog-tag.js';
6
+
7
+ /**
8
+ * Post-article related articles — card grid with image, principle tag, meta, title, and excerpt.
9
+ *
10
+ * @property {string} title
11
+ * @property {string} seeAllLabel
12
+ * @property {Array<{ title: string, href: string, excerpt?: string, principle?: string, date?: string, datetime?: string, readingTime?: string, image?: string, imageAlt?: string }>} items
13
+ */
14
+ export class BlogRelatedArticles extends BlogElement {
15
+ static properties = {
16
+ title : { type: String },
17
+ seeAllLabel: { type: String, attribute: 'see-all-label' },
18
+ items : { type: Array },
19
+ _itemCount : { type: Number, attribute: 'item-count', reflect: true },
20
+ _expanded : { type: Boolean, state: true }
21
+ };
22
+
23
+ constructor() {
24
+ super();
25
+ this.title = 'Related articles';
26
+ this.seeAllLabel = 'See all related articles';
27
+ this.items = [];
28
+ this._itemCount = 0;
29
+ this._expanded = false;
30
+ }
31
+
32
+ willUpdate(changedProperties) {
33
+ if (changedProperties.has('items')) {
34
+ this._itemCount = Math.min(this.items.length, 4);
35
+ }
36
+ }
37
+
38
+ _expandAll() {
39
+ this._expanded = true;
40
+ }
41
+
42
+ static styles = [
43
+ ...BlogElement.styles,
44
+ css`
45
+ :host {
46
+ display: block;
47
+ }
48
+
49
+ .related__title {
50
+ margin: 0 0 var(--blog-related-title-spacing-bottom);
51
+ font-family: var(--blog-related-title-fontFamily);
52
+ font-size: var(--blog-related-title-fontSize);
53
+ font-weight: var(--blog-related-title-fontWeight);
54
+ line-height: var(--blog-related-title-lineHeight);
55
+ color: var(--blog-related-title-color);
56
+ }
57
+
58
+ .related__grid {
59
+ margin: 0;
60
+ padding: 0;
61
+ list-style: none;
62
+ display: grid;
63
+ gap: var(--blog-related-grid-gap-mobile);
64
+ grid-template-columns: 1fr;
65
+ }
66
+
67
+ .related__grid > li + li {
68
+ padding-top: var(--blog-related-grid-gap-mobile);
69
+ border-top: var(--blog-related-card-divider-width) solid
70
+ var(--blog-related-card-divider-color);
71
+ }
72
+
73
+ :host(:not([expanded])) .related__grid > li:nth-child(n + 3) {
74
+ display: none;
75
+ }
76
+
77
+ .related__see-all {
78
+ display: inline-block;
79
+ margin: var(--blog-related-see-all-spacing-top) 0 0;
80
+ padding: 0;
81
+ border: 0;
82
+ background: transparent;
83
+ cursor: pointer;
84
+ font-family: var(--blog-related-see-all-fontFamily);
85
+ font-size: var(--blog-related-see-all-fontSize);
86
+ font-weight: var(--blog-related-see-all-fontWeight);
87
+ line-height: var(--typography-lineHeight-normal);
88
+ color: var(--blog-related-see-all-color);
89
+ text-decoration: underline;
90
+ text-underline-offset: var(--blog-related-see-all-underline-offset);
91
+ }
92
+
93
+ .related__see-all:hover {
94
+ color: var(--blog-related-see-all-hover-color);
95
+ }
96
+
97
+ .related__see-all:focus-visible {
98
+ outline: var(--focus-outline-traditional);
99
+ outline-offset: var(--focus-outline-offset);
100
+ }
101
+
102
+ ${unsafeCSS(minWidth('md'))} {
103
+ .related__grid {
104
+ gap: var(--blog-related-grid-gap);
105
+ }
106
+
107
+ .related__grid > li + li {
108
+ padding-top: 0;
109
+ border-top: 0;
110
+ }
111
+
112
+ :host(:not([expanded])) .related__grid > li:nth-child(n + 3) {
113
+ display: block;
114
+ }
115
+
116
+ .related__see-all {
117
+ display: none;
118
+ }
119
+
120
+ .related__excerpt {
121
+ display: block;
122
+ }
123
+ }
124
+
125
+ ${unsafeCSS(minWidth('md'))} {
126
+ :host([item-count='4']) .related__grid {
127
+ grid-template-columns: repeat(2, minmax(0, 1fr));
128
+ }
129
+ }
130
+
131
+ ${unsafeCSS(minWidth('lg'))} {
132
+ :host([item-count='4']) .related__grid {
133
+ grid-template-columns: repeat(4, minmax(0, 1fr));
134
+ }
135
+
136
+ :host([item-count='3']) .related__grid {
137
+ grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
138
+ }
139
+
140
+ :host([item-count='3']) .related__grid > li {
141
+ grid-column: span calc(var(--grid-columns) / 3);
142
+ }
143
+
144
+ :host([item-count='2']) .related__grid {
145
+ grid-template-columns: repeat(2, minmax(0, 1fr));
146
+ }
147
+ }
148
+
149
+ .related__link {
150
+ display: flex;
151
+ flex-direction: column;
152
+ height: 100%;
153
+ gap: var(--blog-related-card-image-gap);
154
+ color: inherit;
155
+ text-decoration: none;
156
+ }
157
+
158
+ .related__link:hover .related__card-title {
159
+ color: var(--color-text-link-hover);
160
+ }
161
+
162
+ .related__link:focus-visible {
163
+ outline: var(--focus-outline-traditional);
164
+ outline-offset: var(--focus-outline-offset);
165
+ border-radius: var(--blog-related-card-image-borderRadius);
166
+ }
167
+
168
+ .related__media {
169
+ position: relative;
170
+ aspect-ratio: var(--blog-related-card-image-aspect-ratio-mobile);
171
+ border-radius: var(--blog-related-card-image-borderRadius);
172
+ background: var(--blog-content-image-background);
173
+ overflow: hidden;
174
+ }
175
+
176
+ ${unsafeCSS(minWidth('md'))} {
177
+ .related__media {
178
+ aspect-ratio: var(--blog-related-card-image-aspect-ratio);
179
+ }
180
+ }
181
+
182
+ .related__image {
183
+ display: block;
184
+ width: 100%;
185
+ height: 100%;
186
+ object-fit: cover;
187
+ }
188
+
189
+ .related__tag {
190
+ position: absolute;
191
+ top: var(--blog-related-card-tag-inset);
192
+ left: var(--blog-related-card-tag-inset);
193
+ z-index: 1;
194
+ }
195
+
196
+ .related__tag blog-tag {
197
+ pointer-events: none;
198
+ }
199
+
200
+ .related__body {
201
+ display: flex;
202
+ flex-direction: column;
203
+ flex: 1;
204
+ gap: var(--blog-related-card-body-gap);
205
+ }
206
+
207
+ .related__meta {
208
+ display: flex;
209
+ flex-wrap: wrap;
210
+ align-items: center;
211
+ gap: var(--blog-meta-gap);
212
+ margin: 0;
213
+ font-size: var(--blog-related-card-meta-fontSize);
214
+ }
215
+
216
+ .related__card-title {
217
+ margin: 0;
218
+ font-family: var(--blog-related-card-title-fontFamily);
219
+ font-size: var(--blog-related-card-title-fontSize);
220
+ font-weight: var(--blog-related-card-title-fontWeight);
221
+ line-height: var(--blog-related-card-title-lineHeight);
222
+ color: var(--blog-related-card-title-color);
223
+ }
224
+
225
+ .related__excerpt {
226
+ display: none;
227
+ margin: 0;
228
+ flex: 1;
229
+ font-family: var(--typography-fontFamily-sans);
230
+ font-size: var(--blog-related-card-excerpt-fontSize);
231
+ font-weight: var(--typography-fontWeight-normal);
232
+ line-height: var(--typography-lineHeight-relaxed);
233
+ color: var(--blog-related-card-excerpt-color);
234
+ }
235
+ `
236
+ ];
237
+
238
+ updated(changed) {
239
+ if (changed.has('_expanded')) {
240
+ this.toggleAttribute('expanded', this._expanded);
241
+ }
242
+ }
243
+
244
+ /** @param {import('lit').TemplateResult} item */
245
+ _renderCard(item) {
246
+ return html`
247
+ <li part="item">
248
+ <a class="related__link" part="link" href=${item.href}>
249
+ ${item.image
250
+ ? html`<div class="related__media" part="media">
251
+ <img
252
+ class="related__image"
253
+ part="image"
254
+ src=${item.image}
255
+ alt=${item.imageAlt ?? ''}
256
+ loading="lazy"
257
+ />
258
+ ${item.principle
259
+ ? html`<div class="related__tag" part="tag">
260
+ <blog-tag label=${item.principle} variant="brand"></blog-tag>
261
+ </div>`
262
+ : null}
263
+ </div>`
264
+ : null}
265
+ <div class="related__body" part="body">
266
+ ${item.date || item.readingTime
267
+ ? html`<footer class="related__meta" part="meta">
268
+ ${item.date
269
+ ? html`<blog-meta
270
+ type="date"
271
+ value=${item.date}
272
+ datetime=${item.datetime ?? ''}
273
+ ></blog-meta>`
274
+ : null}
275
+ ${item.date && item.readingTime
276
+ ? html`<blog-meta type="separator"></blog-meta>`
277
+ : null}
278
+ ${item.readingTime
279
+ ? html`<blog-meta
280
+ type="reading-time"
281
+ value=${item.readingTime}
282
+ ></blog-meta>`
283
+ : null}
284
+ </footer>`
285
+ : null}
286
+ <h3 class="related__card-title" part="card-title">${item.title}</h3>
287
+ ${item.excerpt
288
+ ? html`<p class="related__excerpt" part="excerpt">${item.excerpt}</p>`
289
+ : null}
290
+ </div>
291
+ </a>
292
+ </li>
293
+ `;
294
+ }
295
+
296
+ render() {
297
+ const items = this.items.slice(0, 4);
298
+
299
+ if (!items.length) {
300
+ return null;
301
+ }
302
+
303
+ const showSeeAll = items.length > 2 && !this._expanded;
304
+
305
+ return html`
306
+ <section class="related" part="related" aria-label=${this.title}>
307
+ <h2 class="related__title" part="title">${this.title}</h2>
308
+ <ul class="related__grid" part="grid">
309
+ ${items.map((item) => this._renderCard(item))}
310
+ </ul>
311
+ ${showSeeAll
312
+ ? html`<button
313
+ type="button"
314
+ class="related__see-all"
315
+ part="see-all"
316
+ @click=${this._expandAll}
317
+ >
318
+ ${this.seeAllLabel}
319
+ </button>`
320
+ : null}
321
+ </section>
322
+ `;
323
+ }
324
+ }
325
+
326
+ customElements.define('blog-related-articles', BlogRelatedArticles);
@@ -0,0 +1,30 @@
1
+ import { css, html } from 'lit';
2
+ import { BlogElement } from '../base/blog-element.js';
3
+
4
+ /** Italic section label before related links — Word: italic + colon at body size. */
5
+ export class BlogRelatedLabel extends BlogElement {
6
+ static styles = [
7
+ ...BlogElement.styles,
8
+ css`
9
+ :host {
10
+ display: block;
11
+ }
12
+
13
+ p {
14
+ margin: 0;
15
+ font-family: var(--blog-related-label-fontFamily);
16
+ font-size: var(--blog-related-label-fontSize);
17
+ font-weight: var(--blog-related-label-fontWeight);
18
+ font-style: var(--blog-related-label-fontStyle);
19
+ line-height: var(--blog-related-label-lineHeight);
20
+ color: var(--blog-related-label-color);
21
+ }
22
+ `
23
+ ];
24
+
25
+ render() {
26
+ return html`<p part="related-label"><slot></slot></p>`;
27
+ }
28
+ }
29
+
30
+ customElements.define('blog-related-label', BlogRelatedLabel);