@repobit/dex-system-design 0.23.10 → 0.23.12
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 +16 -0
- package/package.json +5 -2
- package/schemas/README.md +33 -0
- package/schemas/component-manifest.json +695 -0
- package/schemas/page-schema.json +128 -0
- package/src/components/anchor/anchor-nav.css.js +333 -84
- package/src/components/anchor/anchor-nav.js +333 -58
- package/src/components/awards/awards-light.js +8 -2
- package/src/components/awards/awards-light.stories.js +25 -107
- package/src/components/awards/awards.css.js +1 -1
- package/src/components/compare/compare.css.js +29 -26
- package/src/components/compare/compare.stories.js +1 -1
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import { LitElement, html } from "lit";
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
2
|
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
-
import "../Button/Button.js";
|
|
4
3
|
import { anchorNavStyles } from "./anchor-nav.css.js";
|
|
5
4
|
|
|
5
|
+
/** Parse token length from computed style (e.g. `8rem` → px). */
|
|
6
|
+
function parseLengthToPx(value) {
|
|
7
|
+
const s = (value || "").trim();
|
|
8
|
+
if (!s) return 0;
|
|
9
|
+
if (s.endsWith("px")) return parseFloat(s);
|
|
10
|
+
if (s.endsWith("rem")) {
|
|
11
|
+
const root =
|
|
12
|
+
parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
|
13
|
+
return parseFloat(s) * root;
|
|
14
|
+
}
|
|
15
|
+
return parseFloat(s) || 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
class BdAnchorNavItem extends HTMLElement {
|
|
7
19
|
constructor() {
|
|
8
20
|
super();
|
|
@@ -14,67 +26,267 @@ class BdAnchorNavItem extends HTMLElement {
|
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
render() {
|
|
17
|
-
this.shadowRoot.innerHTML =
|
|
18
|
-
<nav>
|
|
19
|
-
<slot></slot>
|
|
20
|
-
</nav>
|
|
21
|
-
`;
|
|
29
|
+
this.shadowRoot.innerHTML = `<slot></slot>`;
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
|
|
26
33
|
class BdAnchorNav extends LitElement {
|
|
34
|
+
static properties = {
|
|
35
|
+
activeId : { type: String, state: true },
|
|
36
|
+
/** Landmark label for the outer `<nav>` (screen readers). */
|
|
37
|
+
navLabel : { type: String, attribute: "aria-label" },
|
|
38
|
+
/** Mobile dropdown open state */
|
|
39
|
+
_dropdownOpen : { type: Boolean, state: true },
|
|
40
|
+
/** Mobile: show Buy now only after first anchor section has been scrolled past */
|
|
41
|
+
_mobileCtaRevealed: { type: Boolean, state: true }
|
|
42
|
+
};
|
|
43
|
+
|
|
27
44
|
static styles = [tokens, anchorNavStyles];
|
|
28
45
|
|
|
29
46
|
constructor() {
|
|
30
47
|
super();
|
|
31
48
|
this.activeId = "";
|
|
49
|
+
this.navLabel = "Section navigation";
|
|
50
|
+
this._dropdownOpen = false;
|
|
51
|
+
this._mobileCtaRevealed = false;
|
|
52
|
+
this._panelId = `bd-anchor-nav-panel-${Math.random().toString(36)
|
|
53
|
+
.slice(2, 11)}`;
|
|
54
|
+
this._onScrollSpy = this._onScrollSpy.bind(this);
|
|
55
|
+
this._onDocumentPointerDown = this._onDocumentPointerDown.bind(this);
|
|
56
|
+
this._onKeydown = this._onKeydown.bind(this);
|
|
57
|
+
this._scrollPending = false;
|
|
58
|
+
/** While set, scrollspy must not overwrite activeId during smooth scroll to a clicked section */
|
|
59
|
+
this._programmaticScrollTargetId = null;
|
|
60
|
+
this._unlockScrollSpyTimer = null;
|
|
61
|
+
this._scrollEndUnlockHandler = null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
connectedCallback() {
|
|
65
|
+
super.connectedCallback();
|
|
66
|
+
window.addEventListener("scroll", this._onScrollSpy, { passive: true });
|
|
67
|
+
window.addEventListener("resize", this._onScrollSpy, { passive: true });
|
|
68
|
+
document.addEventListener("pointerdown", this._onDocumentPointerDown, true);
|
|
69
|
+
document.addEventListener("keydown", this._onKeydown, true);
|
|
70
|
+
queueMicrotask(() => this._runScrollSpy());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
disconnectedCallback() {
|
|
74
|
+
super.disconnectedCallback();
|
|
75
|
+
this._cancelScrollSpyUnlock();
|
|
76
|
+
window.removeEventListener("scroll", this._onScrollSpy);
|
|
77
|
+
window.removeEventListener("resize", this._onScrollSpy);
|
|
78
|
+
document.removeEventListener("pointerdown", this._onDocumentPointerDown, true);
|
|
79
|
+
document.removeEventListener("keydown", this._onKeydown, true);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_cancelScrollSpyUnlock() {
|
|
83
|
+
if (this._unlockScrollSpyTimer != null) {
|
|
84
|
+
clearTimeout(this._unlockScrollSpyTimer);
|
|
85
|
+
this._unlockScrollSpyTimer = null;
|
|
86
|
+
}
|
|
87
|
+
if (this._scrollEndUnlockHandler) {
|
|
88
|
+
window.removeEventListener("scrollend", this._scrollEndUnlockHandler);
|
|
89
|
+
this._scrollEndUnlockHandler = null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** After in-nav navigation, ignore scrollspy until scroll finishes (avoids flashing 2→3→4). */
|
|
94
|
+
_scheduleScrollSpyUnlock() {
|
|
95
|
+
this._cancelScrollSpyUnlock();
|
|
96
|
+
const onScrollEnd = () => {
|
|
97
|
+
if (this._unlockScrollSpyTimer != null) {
|
|
98
|
+
clearTimeout(this._unlockScrollSpyTimer);
|
|
99
|
+
this._unlockScrollSpyTimer = null;
|
|
100
|
+
}
|
|
101
|
+
window.removeEventListener("scrollend", onScrollEnd);
|
|
102
|
+
this._scrollEndUnlockHandler = null;
|
|
103
|
+
this._programmaticScrollTargetId = null;
|
|
104
|
+
this._runScrollSpy();
|
|
105
|
+
};
|
|
106
|
+
this._scrollEndUnlockHandler = onScrollEnd;
|
|
107
|
+
window.addEventListener("scrollend", onScrollEnd, { passive: true });
|
|
108
|
+
this._unlockScrollSpyTimer = window.setTimeout(() => {
|
|
109
|
+
this._unlockScrollSpyTimer = null;
|
|
110
|
+
if (this._scrollEndUnlockHandler) {
|
|
111
|
+
window.removeEventListener("scrollend", this._scrollEndUnlockHandler);
|
|
112
|
+
this._scrollEndUnlockHandler = null;
|
|
113
|
+
}
|
|
114
|
+
if (this._programmaticScrollTargetId) {
|
|
115
|
+
this._programmaticScrollTargetId = null;
|
|
116
|
+
this._runScrollSpy();
|
|
117
|
+
}
|
|
118
|
+
}, 1000);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
_onKeydown(e) {
|
|
122
|
+
if (e.key === "Escape" && this._dropdownOpen) {
|
|
123
|
+
this._dropdownOpen = false;
|
|
124
|
+
this.requestUpdate();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
_onDocumentPointerDown(e) {
|
|
129
|
+
if (!this._dropdownOpen) return;
|
|
130
|
+
const path = e.composedPath();
|
|
131
|
+
if (path.includes(this)) return;
|
|
132
|
+
this._dropdownOpen = false;
|
|
133
|
+
this.requestUpdate();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
_onScrollSpy() {
|
|
137
|
+
if (this._scrollPending) return;
|
|
138
|
+
this._scrollPending = true;
|
|
139
|
+
requestAnimationFrame(() => {
|
|
140
|
+
this._scrollPending = false;
|
|
141
|
+
this._runScrollSpy();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_runScrollSpy() {
|
|
146
|
+
const count = this._navItemCount();
|
|
147
|
+
let next = this.activeId;
|
|
148
|
+
if (count && !this._programmaticScrollTargetId) {
|
|
149
|
+
const y = window.scrollY + this._stickyOffsetPx() + 2;
|
|
150
|
+
next = "anchor-1";
|
|
151
|
+
for (let i = 0; i < count; i++) {
|
|
152
|
+
const el = document.getElementById(`anchor-${i + 1}-section`);
|
|
153
|
+
if (!el) continue;
|
|
154
|
+
const top = el.getBoundingClientRect().top + window.scrollY;
|
|
155
|
+
if (top <= y) next = `anchor-${i + 1}`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const isMobile = window.matchMedia("(max-width: 768px)").matches;
|
|
160
|
+
const first = document.getElementById("anchor-1-section");
|
|
161
|
+
let nextCta;
|
|
162
|
+
if (!isMobile) {
|
|
163
|
+
nextCta = true;
|
|
164
|
+
} else if (!first) {
|
|
165
|
+
nextCta = true;
|
|
166
|
+
} else {
|
|
167
|
+
/* Show only while first section is fully scrolled past; hide again when it scrolls back into view */
|
|
168
|
+
nextCta = first.getBoundingClientRect().bottom <= 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (this.activeId !== next || this._mobileCtaRevealed !== nextCta) {
|
|
172
|
+
this.activeId = next;
|
|
173
|
+
this._mobileCtaRevealed = nextCta;
|
|
174
|
+
this.requestUpdate();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
_navItemCount() {
|
|
179
|
+
return Array.from(this.children).filter(
|
|
180
|
+
(el) => el.tagName === "BD-ANCHOR-NAV-ITEM"
|
|
181
|
+
).length;
|
|
32
182
|
}
|
|
33
183
|
|
|
34
184
|
firstUpdated() {
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
this.activeId =
|
|
185
|
+
const n = this._navItemCount();
|
|
186
|
+
if (n) {
|
|
187
|
+
this.activeId = "anchor-1";
|
|
38
188
|
this.requestUpdate();
|
|
39
189
|
}
|
|
190
|
+
queueMicrotask(() => this._runScrollSpy());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
updated(changedProperties) {
|
|
194
|
+
super.updated(changedProperties);
|
|
195
|
+
if (!changedProperties.has("activeId")) return;
|
|
196
|
+
const prev = changedProperties.get("activeId");
|
|
197
|
+
if (prev === undefined || prev === "") return;
|
|
198
|
+
if (prev === this.activeId) return;
|
|
199
|
+
queueMicrotask(() => this._playMobileDropdownLabelSwap());
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Mobile dropdown title: subtle fade + slide when scrollspy (or tap) changes section. */
|
|
203
|
+
_playMobileDropdownLabelSwap() {
|
|
204
|
+
if (typeof window === "undefined") return;
|
|
205
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
206
|
+
if (!window.matchMedia("(max-width: 768px)").matches) return;
|
|
207
|
+
const el = this.renderRoot?.querySelector(".bd-anchor-nav__dropdown-label");
|
|
208
|
+
if (!el) return;
|
|
209
|
+
el.classList.remove("bd-anchor-nav__dropdown-label--swap");
|
|
210
|
+
void el.offsetWidth;
|
|
211
|
+
el.classList.add("bd-anchor-nav__dropdown-label--swap");
|
|
212
|
+
el.addEventListener(
|
|
213
|
+
"animationend",
|
|
214
|
+
() => el.classList.remove("bd-anchor-nav__dropdown-label--swap"),
|
|
215
|
+
{ once: true }
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Scroll clearance = actual sticky bar height + small inset (not a fixed 128px token).
|
|
221
|
+
* Matches best practice: target headings sit just under the bar, not with extra dead space.
|
|
222
|
+
*/
|
|
223
|
+
_stickyOffsetPx() {
|
|
224
|
+
const barPx = this.offsetHeight;
|
|
225
|
+
const insetRaw = getComputedStyle(this).getPropertyValue("--spacing-8")
|
|
226
|
+
.trim();
|
|
227
|
+
const insetPx = parseLengthToPx(insetRaw) || 8;
|
|
228
|
+
if (barPx > 0) return barPx + insetPx;
|
|
229
|
+
const fallback = getComputedStyle(this).getPropertyValue("--spacing-128")
|
|
230
|
+
.trim();
|
|
231
|
+
return parseLengthToPx(fallback) || 128;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
_scrollToY(event, getTarget) {
|
|
235
|
+
if (event?.preventDefault) event.preventDefault();
|
|
236
|
+
const el = getTarget();
|
|
237
|
+
if (!el) return;
|
|
238
|
+
const offset = this._stickyOffsetPx();
|
|
239
|
+
const rect = el.getBoundingClientRect();
|
|
240
|
+
const scrollTop = window.scrollY ?? window.pageYOffset;
|
|
241
|
+
const elementY = rect.top + scrollTop;
|
|
242
|
+
const prefersReduced =
|
|
243
|
+
typeof window !== "undefined" &&
|
|
244
|
+
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
245
|
+
window.scrollTo({
|
|
246
|
+
top : elementY - offset,
|
|
247
|
+
behavior: prefersReduced ? "auto" : "smooth"
|
|
248
|
+
});
|
|
40
249
|
}
|
|
41
250
|
|
|
42
251
|
handleClick(event, id) {
|
|
43
252
|
event.preventDefault();
|
|
253
|
+
this._cancelScrollSpyUnlock();
|
|
254
|
+
this._programmaticScrollTargetId = id;
|
|
44
255
|
this.activeId = id;
|
|
45
256
|
|
|
46
|
-
const sectionEl = document.
|
|
257
|
+
const sectionEl = document.getElementById(`${id}-section`);
|
|
47
258
|
if (sectionEl) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const offsetY = elementY - offset;
|
|
53
|
-
|
|
54
|
-
window.scrollTo({
|
|
55
|
-
top : offsetY,
|
|
56
|
-
behavior: "smooth"
|
|
57
|
-
});
|
|
259
|
+
this._scrollToY(event, () => sectionEl);
|
|
260
|
+
this._scheduleScrollSpyUnlock();
|
|
261
|
+
} else {
|
|
262
|
+
this._programmaticScrollTargetId = null;
|
|
58
263
|
}
|
|
59
264
|
|
|
60
265
|
this.requestUpdate();
|
|
61
266
|
}
|
|
62
267
|
|
|
268
|
+
_toggleDropdown(e) {
|
|
269
|
+
e.preventDefault();
|
|
270
|
+
e.stopPropagation();
|
|
271
|
+
this._dropdownOpen = !this._dropdownOpen;
|
|
272
|
+
this.requestUpdate();
|
|
273
|
+
}
|
|
63
274
|
|
|
275
|
+
_selectFromDropdown(e, id) {
|
|
276
|
+
this.handleClick(e, id);
|
|
277
|
+
this._dropdownOpen = false;
|
|
278
|
+
this.requestUpdate();
|
|
279
|
+
}
|
|
64
280
|
|
|
65
281
|
scrollToPricing(event) {
|
|
66
|
-
event.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
top : offsetY,
|
|
75
|
-
behavior: "smooth"
|
|
76
|
-
});
|
|
77
|
-
}
|
|
282
|
+
this._scrollToY(event, () => document.getElementById("section-pricing"));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
_activeLabel(items) {
|
|
286
|
+
const m = /^anchor-(\d+)$/.exec(this.activeId || "");
|
|
287
|
+
const n = m ? parseInt(m[1], 10) : 1;
|
|
288
|
+
const idx = Math.min(Math.max(n - 1, 0), Math.max(0, items.length - 1));
|
|
289
|
+
return items[idx]?.getAttribute("title") || items[0]?.getAttribute("title") || "Section";
|
|
78
290
|
}
|
|
79
291
|
|
|
80
292
|
render() {
|
|
@@ -82,39 +294,102 @@ class BdAnchorNav extends LitElement {
|
|
|
82
294
|
(el) => el.tagName === "BD-ANCHOR-NAV-ITEM"
|
|
83
295
|
);
|
|
84
296
|
|
|
297
|
+
const linkRow = (cls) => html`
|
|
298
|
+
<div class="${cls}">
|
|
299
|
+
${items.map((item, index) => {
|
|
300
|
+
const id = `anchor-${index + 1}`;
|
|
301
|
+
const isActive = this.activeId === id;
|
|
302
|
+
return html`
|
|
303
|
+
<a
|
|
304
|
+
href="#${id}-section"
|
|
305
|
+
class="${isActive ? "active" : ""}"
|
|
306
|
+
aria-current=${isActive ? "true" : nothing}
|
|
307
|
+
@click=${(e) => this.handleClick(e, id)}
|
|
308
|
+
>
|
|
309
|
+
${item.getAttribute("title")}
|
|
310
|
+
</a>
|
|
311
|
+
`;
|
|
312
|
+
})}
|
|
313
|
+
</div>
|
|
314
|
+
`;
|
|
315
|
+
|
|
316
|
+
const dropdownLabel = this._activeLabel(items);
|
|
317
|
+
|
|
85
318
|
return html`
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
319
|
+
<nav aria-label=${this.navLabel}>
|
|
320
|
+
<div
|
|
321
|
+
class="bd-anchor-nav__inner"
|
|
322
|
+
part="inner"
|
|
323
|
+
?data-mobile-cta-visible=${this._mobileCtaRevealed}
|
|
324
|
+
>
|
|
325
|
+
${linkRow("anchor-links anchor-links--desktop")}
|
|
326
|
+
|
|
327
|
+
<div class="bd-anchor-nav__dropdown" part="dropdown">
|
|
328
|
+
<button
|
|
329
|
+
type="button"
|
|
330
|
+
class="bd-anchor-nav__dropdown-toggle"
|
|
331
|
+
aria-expanded=${this._dropdownOpen ? "true" : "false"}
|
|
332
|
+
aria-controls=${this._panelId}
|
|
333
|
+
aria-haspopup="listbox"
|
|
334
|
+
@click=${this._toggleDropdown}
|
|
335
|
+
>
|
|
336
|
+
<span class="bd-anchor-nav__dropdown-label">${dropdownLabel}</span>
|
|
337
|
+
<span class="bd-anchor-nav__dropdown-chevron" aria-hidden="true">
|
|
338
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
339
|
+
<path
|
|
340
|
+
d="M5 8l5 5 5-5"
|
|
341
|
+
stroke="currentColor"
|
|
342
|
+
stroke-width="2"
|
|
343
|
+
stroke-linecap="round"
|
|
344
|
+
stroke-linejoin="round"
|
|
345
|
+
/>
|
|
346
|
+
</svg>
|
|
347
|
+
</span>
|
|
348
|
+
</button>
|
|
349
|
+
<div
|
|
350
|
+
class="bd-anchor-nav__dropdown-panel"
|
|
351
|
+
id=${this._panelId}
|
|
352
|
+
role="listbox"
|
|
353
|
+
aria-label=${this.navLabel}
|
|
354
|
+
?hidden=${!this._dropdownOpen}
|
|
355
|
+
>
|
|
356
|
+
<ul class="bd-anchor-nav__dropdown-list" role="presentation">
|
|
357
|
+
${items.map((item, index) => {
|
|
358
|
+
const id = `anchor-${index + 1}`;
|
|
359
|
+
const isActive = this.activeId === id;
|
|
360
|
+
return html`
|
|
361
|
+
<li role="presentation">
|
|
362
|
+
<button
|
|
363
|
+
type="button"
|
|
364
|
+
role="option"
|
|
365
|
+
class="bd-anchor-nav__dropdown-option ${isActive
|
|
366
|
+
? "bd-anchor-nav__dropdown-option--active"
|
|
367
|
+
: ""}"
|
|
368
|
+
aria-selected=${isActive ? "true" : "false"}
|
|
369
|
+
@click=${(e) => this._selectFromDropdown(e, id)}
|
|
370
|
+
>
|
|
371
|
+
${item.getAttribute("title")}
|
|
372
|
+
</button>
|
|
373
|
+
</li>
|
|
374
|
+
`;
|
|
375
|
+
})}
|
|
376
|
+
</ul>
|
|
377
|
+
</div>
|
|
101
378
|
</div>
|
|
102
379
|
|
|
103
380
|
<div class="bd-cta">
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
size="md"
|
|
381
|
+
<button
|
|
382
|
+
type="button"
|
|
383
|
+
class="bd-anchor-nav__cta"
|
|
108
384
|
part="buy-button"
|
|
109
|
-
font-size="18px"
|
|
110
|
-
font-weight="600"
|
|
111
385
|
@click=${(e) => this.scrollToPricing(e)}
|
|
112
386
|
>
|
|
113
387
|
Buy now
|
|
114
|
-
</
|
|
388
|
+
</button>
|
|
115
389
|
</div>
|
|
116
|
-
</
|
|
117
|
-
|
|
390
|
+
</div>
|
|
391
|
+
</nav>
|
|
392
|
+
`;
|
|
118
393
|
}
|
|
119
394
|
}
|
|
120
395
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { LitElement, html } from "lit";
|
|
1
|
+
import { LitElement, css, html } from "lit";
|
|
2
2
|
import { tokens } from "../../tokens/tokens.js";
|
|
3
3
|
import "../awards/awards-icon.js";
|
|
4
4
|
import { awardsCSS } from "./awards.css.js";
|
|
5
5
|
|
|
6
|
+
const awardslightOverride = css`
|
|
7
|
+
.bd-awards-root {
|
|
8
|
+
gap: 0;
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
6
11
|
export class AwardsSection extends LitElement {
|
|
7
12
|
static properties = {
|
|
8
13
|
tagline : { type: String },
|
|
@@ -16,7 +21,8 @@ export class AwardsSection extends LitElement {
|
|
|
16
21
|
_featureNarrow: { state: true }
|
|
17
22
|
};
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
|
|
25
|
+
static styles = [tokens, awardsCSS, awardslightOverride];
|
|
20
26
|
|
|
21
27
|
/** @type {MediaQueryList | null} */
|
|
22
28
|
_mql599 = null;
|