@repobit/dex-system-design 0.25.11 → 0.26.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 +195 -0
- package/README.md +131 -8
- package/package.json +95 -13
- package/schemas/component-manifest.json +3294 -405
- package/schemas/manifest-omissions.json +173 -0
- package/src/blog/src/breakpoints.js +6 -6
- package/src/blog/src/content/blog-atoms-showcase.js +1 -1
- package/src/blog/src/content/blog-page-layout.js +2 -2
- package/src/blog/src/lib/article-toc.js +7 -7
- package/src/blog/src/shell/blog-shell.js +1 -1
- package/src/blog/src/tokens/blog.js +2 -2
- package/src/blog/src/tokens/core.js +34 -35
- package/src/blog/src/tokens/legacy.js +0 -9
- package/src/blog/tokens/blog.js +2 -2
- package/src/blog/tokens/core.js +34 -35
- package/src/blog/tokens/legacy.js +0 -9
- package/src/blog/tokens.css +36 -46
- package/src/components/accordion/accordion-bg.css.js +83 -59
- package/src/components/accordion/accordion-bg.js +29 -10
- package/src/components/accordion/accordion-bg.stories.js +67 -67
- package/src/components/accordion/accordion-keyboard.js +80 -0
- package/src/components/accordion/accordion.css.js +142 -80
- package/src/components/accordion/accordion.js +37 -10
- package/src/components/accordion/accordion.stories.js +7 -7
- package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
- package/src/components/agent-endpoints/agent-endpoints.js +30 -20
- package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
- package/src/components/ai-guardian-demo.stories.js +91 -91
- package/src/components/alert/alert.css.js +198 -0
- package/src/components/alert/alert.js +103 -0
- package/src/components/alert/alert.stories.js +206 -0
- package/src/components/anchor/anchor-nav.css.js +213 -101
- package/src/components/anchor/anchor-nav.js +26 -40
- package/src/components/anchor/anchor.stories.js +22 -12
- package/src/components/annotation/annotation.css.js +58 -0
- package/src/components/annotation/annotation.js +67 -0
- package/src/components/annotation/annotation.stories.js +63 -0
- package/src/components/architecture.stories.js +285 -0
- package/src/components/atoms.stories.js +342 -0
- package/src/components/avatar/avatar.css.js +67 -0
- package/src/components/avatar/avatar.js +42 -0
- package/src/components/avatar/avatar.stories.js +95 -0
- package/src/components/awards/awards-flex.css.js +209 -23
- package/src/components/awards/awards-flex.js +66 -7
- package/src/components/awards/awards-flex.stories.js +1 -1
- package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
- package/src/components/awards/awards.css.js +116 -58
- package/src/components/awards/awards.js +102 -28
- package/src/components/awards/awards.stories.js +1 -1
- package/src/components/back/back.css.js +51 -22
- package/src/components/back/back.js +28 -7
- package/src/components/back/back.stories.js +9 -3
- package/src/components/badge/badge.css.js +158 -46
- package/src/components/badge/badge.js +62 -74
- package/src/components/badge/badge.stories.js +176 -248
- package/src/components/bento-grid/bento-grid.css.js +21 -16
- package/src/components/bento-grid/bento-grid.js +16 -4
- package/src/components/bento-grid/bento-grid.stories.js +19 -18
- package/src/components/bento-grid/bento-item.css.js +52 -28
- package/src/components/bento-grid/bento-item.js +2 -2
- package/src/components/blockquote/blockquote.css.js +47 -0
- package/src/components/blockquote/blockquote.js +29 -0
- package/src/components/blockquote/blockquote.stories.js +62 -0
- package/src/components/breadcrumb/breadcrumb.css.js +92 -22
- package/src/components/breadcrumb/breadcrumb.js +56 -11
- package/src/components/button/button.css.js +531 -161
- package/src/components/button/button.js +206 -214
- package/src/components/button/button.stories.js +322 -174
- package/src/components/caption/caption.css.js +21 -0
- package/src/components/caption/caption.js +31 -0
- package/src/components/caption/caption.stories.js +62 -0
- package/src/components/card-features/card-features.css.js +14 -22
- package/src/components/card-features/card-features.js +68 -9
- package/src/components/card-features/card-features.stories.js +11 -11
- package/src/components/cards/card.css.js +60 -81
- package/src/components/cards/card.js +56 -25
- package/src/components/cards/card.stories.js +39 -39
- package/src/components/carousel/carousel.css.js +93 -99
- package/src/components/carousel/carousel.js +32 -4
- package/src/components/checkbox/checkbox.css.js +111 -93
- package/src/components/checkbox/checkbox.js +64 -90
- package/src/components/checkbox/checkbox.stories.js +96 -29
- package/src/components/code/code.css.js +70 -0
- package/src/components/code/code.js +40 -0
- package/src/components/code/code.stories.js +73 -0
- package/src/components/compare/compare.css.js +179 -43
- package/src/components/compare/compare.js +52 -25
- package/src/components/compare/compare.stories.js +61 -4
- package/src/components/comparison-panel/comparison-panel.css.js +38 -51
- package/src/components/comparison-panel/comparison-panel.js +5 -4
- package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
- package/src/components/compatibility-table/compatibility-table.css.js +180 -80
- package/src/components/compatibility-table/compatibility-table.js +37 -9
- package/src/components/control-alignment.stories.js +393 -0
- package/src/components/cta-banner/cta-banner.css.js +41 -13
- package/src/components/cta-banner/cta-banner.js +6 -5
- package/src/components/cta-banner/cta-banner.stories.js +43 -98
- package/src/components/display/display.css.js +25 -1
- package/src/components/display/display.js +46 -13
- package/src/components/display/display.stories.js +270 -40
- package/src/components/divider/divider-horizontal.js +21 -5
- package/src/components/divider/divider-vertical.js +15 -7
- package/src/components/divider/divider.css.js +2 -2
- package/src/components/divider/divider.stories.js +38 -34
- package/src/components/dropdown/dropdown.css.js +93 -126
- package/src/components/dropdown/dropdown.js +114 -34
- package/src/components/dropdown/dropdown.stories.js +56 -24
- package/src/components/features/features.css.js +24 -11
- package/src/components/features/features.js +7 -3
- package/src/components/features/features.stories.js +37 -37
- package/src/components/features-tab/features-tab.css.js +19 -8
- package/src/components/features-tab/features-tab.js +6 -5
- package/src/components/features-tab/features-tab.stories.js +23 -23
- package/src/components/fieldset/fieldset.css.js +30 -0
- package/src/components/fieldset/fieldset.js +28 -0
- package/src/components/fieldset/fieldset.stories.js +84 -0
- package/src/components/footer/footer-links-group.css.js +10 -14
- package/src/components/footer/footer-links-group.js +4 -3
- package/src/components/footer/footer-lp.css.js +59 -30
- package/src/components/footer/footer-lp.js +17 -12
- package/src/components/footer/footer-lp.stories.js +63 -75
- package/src/components/footer/footer-nav-menu.css.js +26 -4
- package/src/components/footer/footer-nav-menu.js +3 -2
- package/src/components/footer/footer.css.js +146 -264
- package/src/components/footer/footer.js +176 -106
- package/src/components/footer/footer.stories.js +9 -9
- package/src/components/footer/localeMap.js +1 -1
- package/src/components/grid/grid.css.js +1 -1
- package/src/components/grid/grid.js +49 -7
- package/src/components/grid/grid.stories.js +111 -0
- package/src/components/header/header-code.css.js +61 -51
- package/src/components/header/header-code.js +28 -14
- package/src/components/header/header-code.stories.js +5 -5
- package/src/components/header/header.css.js +655 -176
- package/src/components/header/header.js +269 -36
- package/src/components/header/header.stories.js +841 -18
- package/src/components/heading/heading.css.js +14 -17
- package/src/components/heading/heading.js +48 -33
- package/src/components/heading/heading.stories.js +27 -25
- package/src/components/help-text/help-text.css.js +21 -0
- package/src/components/help-text/help-text.js +25 -0
- package/src/components/help-text/help-text.stories.js +66 -0
- package/src/components/highlight/highlight.css.js +86 -64
- package/src/components/highlight/highlight.js +18 -27
- package/src/components/highlight/highlight.stories.js +14 -3
- package/src/components/icons/analysis-icon.js +6 -16
- package/src/components/icons/arrow-down-icon.js +6 -19
- package/src/components/icons/arrow-icon.js +44 -0
- package/src/components/icons/arrow-right-icon.js +30 -23
- package/src/components/icons/arrow-up-icon.js +19 -18
- package/src/components/icons/bd-ai-icon.js +1 -1
- package/src/components/icons/brand-marks.stories.js +279 -0
- package/src/components/icons/brand-signature-icon.js +42 -0
- package/src/components/icons/check-icon.js +27 -0
- package/src/components/icons/circle-info-icon.js +33 -0
- package/src/components/icons/close-icon.js +6 -18
- package/src/components/icons/family-icon.js +8 -20
- package/src/components/icons/globe-icon.js +6 -18
- package/src/components/icons/guide-icon.js +6 -18
- package/src/components/icons/icon-element.js +99 -0
- package/src/components/icons/icons.js +36 -0
- package/src/components/icons/icons.stories.js +184 -52
- package/src/components/icons/individual-icon.js +6 -18
- package/src/components/icons/laurel-icon.js +9 -19
- package/src/components/icons/machine-learning-icon.js +6 -17
- package/src/components/icons/marks.js +41 -0
- package/src/components/icons/minus-icon.js +7 -21
- package/src/components/icons/missing-icon.js +52 -0
- package/src/components/icons/plus-icon.js +7 -21
- package/src/components/icons/quote-icon.js +19 -19
- package/src/components/image/image.css.js +72 -25
- package/src/components/image/image.js +11 -6
- package/src/components/image/image.stories.js +2 -2
- package/src/components/input/custom-form.stories.js +214 -62
- package/src/components/input/input-clipboard.css.js +51 -144
- package/src/components/input/input-clipboard.js +31 -15
- package/src/components/input/input.css.js +8 -146
- package/src/components/input/input.js +93 -38
- package/src/components/install-options/install-options.css.js +84 -77
- package/src/components/install-options/install-options.js +33 -30
- package/src/components/install-options/install-options.stories.js +3 -3
- package/src/components/label/label.css.js +35 -0
- package/src/components/label/label.js +38 -0
- package/src/components/label/label.stories.js +82 -0
- package/src/components/light-carousel/light-carousel.css.js +111 -63
- package/src/components/light-carousel/light-carousel.js +85 -11
- package/src/components/light-carousel/light-carousel.stories.js +126 -82
- package/src/components/link/link.css.js +150 -99
- package/src/components/link/link.js +86 -11
- package/src/components/link/link.stories.js +124 -30
- package/src/components/list/list-item/list-item.css.js +74 -22
- package/src/components/list/list-item/list-item.js +32 -10
- package/src/components/list/list-item/list-item.stories.js +23 -23
- package/src/components/list/list.css.js +8 -2
- package/src/components/list/list.js +3 -2
- package/src/components/list/list.stories.js +222 -0
- package/src/components/modal/modal.css.js +114 -24
- package/src/components/modal/modal.js +83 -7
- package/src/components/modal/modal.stories.js +9 -9
- package/src/components/overview/overview.css.js +19 -14
- package/src/components/overview/overview.js +6 -5
- package/src/components/overview/overview.stories.js +10 -10
- package/src/components/page-switcher/page-switcher.css.js +97 -40
- package/src/components/page-switcher/page-switcher.js +28 -5
- package/src/components/page-switcher/page-switcher.stories.js +95 -0
- package/src/components/paragraph/paragraph.css.js +15 -10
- package/src/components/paragraph/paragraph.js +41 -44
- package/src/components/paragraph/paragraph.stories.js +56 -21
- package/src/components/picture/picture.css.js +103 -44
- package/src/components/picture/picture.js +100 -30
- package/src/components/picture/picture.stories.js +1 -1
- package/src/components/pricing-cards/new-pricing-card.js +3 -3
- package/src/components/pricing-cards/new-pricing.css.js +24 -15
- package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
- package/src/components/pricing-cards/pricing-card-actions.js +3 -4
- package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
- package/src/components/pricing-cards/pricing-card-container.js +3 -2
- package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
- package/src/components/pricing-cards/pricing-card-header.js +6 -7
- package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
- package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
- package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
- package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
- package/src/components/pricing-cards/pricing-card.css.js +244 -190
- package/src/components/pricing-cards/pricing-card.js +54 -70
- package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
- package/src/components/pricing-cards/pricing-feature-item.js +8 -3
- package/src/components/process-steps/process-steps.css.js +26 -14
- package/src/components/process-steps/process-steps.js +23 -6
- package/src/components/process-steps/process-steps.stories.js +1 -1
- package/src/components/progress/progress.css.js +80 -0
- package/src/components/progress/progress.js +42 -0
- package/src/components/progress/progress.stories.js +79 -0
- package/src/components/quick-answer/quick-answer.css.js +75 -13
- package/src/components/quick-answer/quick-answer.js +8 -3
- package/src/components/radio/radio.css.js +92 -128
- package/src/components/radio/radio.js +106 -127
- package/src/components/radio/radio.stories.js +54 -19
- package/src/components/review/review-grid.css.js +5 -6
- package/src/components/review/review-grid.js +14 -11
- package/src/components/review/review.css.js +11 -6
- package/src/components/review/review.js +3 -8
- package/src/components/shared/ensemble.css.js +93 -0
- package/src/components/shared/form-field.css.js +206 -0
- package/src/components/shared/prop-vocabulary.js +48 -0
- package/src/components/shared/token-scales.js +306 -0
- package/src/components/skeleton/skeleton.css.js +34 -0
- package/src/components/skeleton/skeleton.js +32 -0
- package/src/components/skeleton/skeleton.stories.js +70 -0
- package/src/components/spinner/spinner.css.js +62 -0
- package/src/components/spinner/spinner.js +38 -0
- package/src/components/spinner/spinner.stories.js +92 -0
- package/src/components/spotlight-section/spotlight-section.css.js +14 -13
- package/src/components/spotlight-section/spotlight-section.js +42 -39
- package/src/components/switch/switch.css.js +103 -0
- package/src/components/switch/switch.js +44 -0
- package/src/components/switch/switch.stories.js +86 -0
- package/src/components/tab-list/content-switcher.stories.js +189 -0
- package/src/components/tab-list/tab-list.css.js +250 -0
- package/src/components/tab-list/tab-list.js +184 -0
- package/src/components/tab-list/tab-list.stories.js +221 -0
- package/src/components/tabs/tabs.css.js +14 -123
- package/src/components/tabs/tabs.js +16 -19
- package/src/components/tabs/tabs.stories.js +95 -95
- package/src/components/tag/tag.css.js +54 -0
- package/src/components/tag/tag.js +32 -0
- package/src/components/tag/tag.stories.js +126 -0
- package/src/components/terminal/terminal-message.css.js +164 -60
- package/src/components/terminal/terminal-message.js +5 -5
- package/src/components/terminal/terminal-message.stories.js +70 -1
- package/src/components/termsOfUse/terms.css.js +25 -20
- package/src/components/termsOfUse/terms.js +13 -9
- package/src/components/termsOfUse/terms.stories.js +1 -1
- package/src/components/textarea/textarea.css.js +51 -0
- package/src/components/textarea/textarea.js +136 -0
- package/src/components/textarea/textarea.stories.js +191 -0
- package/src/components/tooltip/tooltip.css.js +75 -0
- package/src/components/tooltip/tooltip.js +156 -0
- package/src/components/tooltip/tooltip.stories.js +161 -0
- package/src/components/trust-panel/trust-panel.css.js +85 -33
- package/src/components/trust-panel/trust-panel.js +18 -10
- package/src/components/trust-panel/trust-panel.stories.js +1 -1
- package/src/components/ultimate-security-demo.stories.js +431 -0
- package/src/components/video/video.css.js +17 -0
- package/src/components/video/video.js +40 -0
- package/src/components/video/video.stories.js +106 -0
- package/src/components/video-player/video-player.css.js +67 -11
- package/src/components/video-player/video-player.js +35 -4
- package/src/components/video-player/video-player.stories.js +1 -1
- package/src/components/visual-alignment.stories.js +411 -0
- package/src/components/visually-hidden/visually-hidden.css.js +24 -0
- package/src/components/visually-hidden/visually-hidden.js +16 -0
- package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
- package/src/stories/Button.stories.js +17 -17
- package/src/stories/Header.stories.js +10 -10
- package/src/stories/Page.js +1 -1
- package/src/stories/Page.stories.js +6 -6
- package/src/tokens/borders.stories.js +339 -0
- package/src/tokens/color-responsibilities.stories.js +227 -0
- package/src/tokens/dark-derivation.js +309 -0
- package/src/tokens/dark-findings.js +197 -0
- package/src/tokens/dark-mode.stories.js +207 -0
- package/src/tokens/dimension.stories.js +251 -0
- package/src/tokens/elevation.stories.js +143 -0
- package/src/tokens/focus.stories.js +276 -0
- package/src/tokens/fonts.css +20 -20
- package/src/tokens/fonts.stories.js +354 -374
- package/src/tokens/layout.css +25 -11
- package/src/tokens/motion.stories.js +231 -0
- package/src/tokens/shape.stories.js +272 -0
- package/src/tokens/spacing-rhythm.stories.js +359 -0
- package/src/tokens/spacing.stories.js +208 -703
- package/src/tokens/story-chrome.js +503 -0
- package/src/tokens/surfaces.stories.js +224 -0
- package/src/tokens/text-on-surface.stories.js +164 -0
- package/src/tokens/token-map.js +220 -0
- package/src/tokens/token-map.stories.js +257 -0
- package/src/tokens/token-purposes.js +266 -0
- package/src/tokens/tokens-grid.stories.js +388 -900
- package/src/tokens/tokens.css +1633 -1045
- package/src/tokens/tokens.js +1130 -492
- package/src/tokens/tokens.stories.js +137 -47
- package/src/tokens/type-ceiling-words.js +299 -0
- package/src/tokens/typography.stories.js +1003 -965
- package/src/tokens/vertical-rhythm.stories.js +224 -0
- package/src/components/awards/awards-icon.js +0 -56
- package/src/components/awards/awards-light.js +0 -240
- package/src/components/banner/banner.js +0 -60
- package/src/components/banner/banner.stories.js +0 -51
- package/src/components/button/icons.js +0 -24
- package/src/components/input/index.js +0 -0
- package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
- package/src/components/light-carousel/light-carousel-simple.js +0 -74
- package/src/tokens/colors.js +0 -121
- package/src/tokens/typography.css.js +0 -207
- package/src/tokens/typography.js +0 -0
|
@@ -1,18 +1,44 @@
|
|
|
1
|
-
import { css } from "lit";
|
|
1
|
+
import { css, unsafeCSS } from "lit";
|
|
2
|
+
import { below } from "../shared/token-scales.js";
|
|
2
3
|
|
|
3
4
|
export default css`
|
|
4
5
|
|
|
5
6
|
:host(bd-compare-section) {
|
|
6
7
|
display: block;
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/* The brand fill and the ink that belongs to it. theme-green and theme-red
|
|
10
|
+
adopted --status-*-fill / --status-*-on-fill below with the argument that a
|
|
11
|
+
saturated fill carrying a label is exactly that pair's responsibility; the
|
|
12
|
+
default bar IS that shape and the migration skipped it, so it kept the
|
|
13
|
+
primitives. Value-identical -- --status-brand-fill is blue-500 and
|
|
14
|
+
--status-brand-on-fill is neutral-0 -- and the label measures 4.53:1 here,
|
|
15
|
+
which passes 4.5:1 with almost nothing spare. Worth knowing before anyone
|
|
16
|
+
retunes blue-500: green-500 and red-500 both failed this same test. */
|
|
17
|
+
--cs-bar-primary-fg: var(--status-brand-on-fill);
|
|
18
|
+
--cs-bar-primary-bg: var(--status-brand-fill);
|
|
19
|
+
/* no role: the competitor bar is a resting fill. The three roles at
|
|
20
|
+
neutral-100 are a state (surface-muted), a disabled control
|
|
21
|
+
(surface-disabled) and a surface in the neutral status family, whose FILL
|
|
22
|
+
is neutral-900 -- so the family that matches on job does not match on
|
|
23
|
+
value, and the ones that match on value do not match on job. */
|
|
10
24
|
--cs-bar-secondary-bg: var(--color-neutral-100);
|
|
11
25
|
--cs-bar-track-bg: transparent;
|
|
12
|
-
--cs-bar-track-border: var(--color-
|
|
13
|
-
--cs-bar-height: var(--dimension-
|
|
26
|
+
--cs-bar-track-border: var(--color-border-subtle);
|
|
27
|
+
--cs-bar-height: var(--dimension-48);
|
|
14
28
|
--cs-gap: var(--spacing-32);
|
|
15
|
-
|
|
29
|
+
|
|
30
|
+
/* The section's own text, which is the only text that sits on the page's
|
|
31
|
+
ground rather than on a card. .theme-dark recoloured the bars and the icon
|
|
32
|
+
and stopped there, so on a dark ground the section title kept
|
|
33
|
+
--color-text-primary and rendered at 1.05:1 -- a documented story whose
|
|
34
|
+
heading was invisible.
|
|
35
|
+
|
|
36
|
+
Deliberately section-scoped. .card sets its own --color-surface-container
|
|
37
|
+
and stays light under .theme-dark, so card titles, descriptions, footnotes
|
|
38
|
+
and bar labels must keep their light-surface roles; inverting those turned
|
|
39
|
+
white text onto a light card at 1.04:1 when it was tried. This is a
|
|
40
|
+
component-context fix, not a theme architecture. */
|
|
41
|
+
--cs-section-text: var(--color-text-primary);
|
|
16
42
|
}
|
|
17
43
|
|
|
18
44
|
:host(compare-card) {
|
|
@@ -39,30 +65,30 @@ export default css`
|
|
|
39
65
|
|
|
40
66
|
.cs-section {
|
|
41
67
|
background: transparent;
|
|
42
|
-
padding:
|
|
68
|
+
padding-block: var(--spacing-0);
|
|
43
69
|
box-sizing: border-box;
|
|
44
70
|
}
|
|
45
71
|
|
|
46
72
|
.cs-heading {
|
|
47
73
|
text-align: center;
|
|
74
|
+
/* not the column: a centred heading measure, one grid step narrower than the page */
|
|
48
75
|
max-width: var(--grid-container-max-md);
|
|
49
76
|
margin: 0 auto var(--spacing-40);
|
|
50
77
|
}
|
|
51
78
|
|
|
52
|
-
.cs-title { margin: 0 0 var(--spacing-8); }
|
|
53
|
-
.cs-subtitle { margin: 0; }
|
|
79
|
+
.cs-title { margin: 0 0 var(--spacing-8); color: var(--cs-section-text); }
|
|
80
|
+
.cs-subtitle { margin: 0; color: var(--cs-section-text); }
|
|
54
81
|
|
|
55
82
|
.cs-grid {
|
|
56
83
|
display: grid;
|
|
57
84
|
grid-template-columns: repeat(var(--_cols, 2), minmax(0, 598px));
|
|
58
85
|
gap: var(--cs-gap);
|
|
59
|
-
max-width: var(--cs-grid-max);
|
|
60
86
|
margin: 0 auto;
|
|
61
87
|
justify-content: center;
|
|
62
88
|
align-items: stretch;
|
|
63
89
|
}
|
|
64
90
|
|
|
65
|
-
@media (
|
|
91
|
+
@media ${unsafeCSS(below('md'))} {
|
|
66
92
|
.cs-grid {
|
|
67
93
|
grid-template-columns: 1fr !important;
|
|
68
94
|
}
|
|
@@ -73,9 +99,16 @@ export default css`
|
|
|
73
99
|
}
|
|
74
100
|
|
|
75
101
|
.card {
|
|
76
|
-
background: var(--color-
|
|
77
|
-
|
|
78
|
-
|
|
102
|
+
background: var(--color-surface-container);
|
|
103
|
+
/* --radius-2xl, the established card-family corner. This card sat at
|
|
104
|
+
--radius-3xl and was otherwise identical to the family: the same
|
|
105
|
+
--color-surface-container, the same 32px inset, no resting elevation and
|
|
106
|
+
no card-level interaction. P5G could find no responsibility, affordance or
|
|
107
|
+
recorded decision behind the extra 8px -- unlike the carousel item, whose
|
|
108
|
+
24px corner goes with a 2px border and real drag/modal behaviour and is a
|
|
109
|
+
recorded open question. */
|
|
110
|
+
border-radius: var(--card-radius);
|
|
111
|
+
padding: var(--card-padding);
|
|
79
112
|
display: flex;
|
|
80
113
|
flex-direction: column;
|
|
81
114
|
gap: var(--spacing-24);
|
|
@@ -94,8 +127,8 @@ export default css`
|
|
|
94
127
|
|
|
95
128
|
.card-icon-wrap {
|
|
96
129
|
flex-shrink: 0;
|
|
97
|
-
width: var(--icon-2xl-size
|
|
98
|
-
height: var(--icon-2xl-size
|
|
130
|
+
width: var(--icon-2xl-size);
|
|
131
|
+
height: var(--icon-2xl-size);
|
|
99
132
|
}
|
|
100
133
|
|
|
101
134
|
.card-icon-wrap bd-img {
|
|
@@ -124,7 +157,7 @@ export default css`
|
|
|
124
157
|
|
|
125
158
|
.card-footnote {
|
|
126
159
|
margin: 0;
|
|
127
|
-
color: var(--color-
|
|
160
|
+
color: var(--color-text-primary);
|
|
128
161
|
flex: 0 0 auto;
|
|
129
162
|
}
|
|
130
163
|
|
|
@@ -158,8 +191,8 @@ slot[name="header"] { display: contents; }
|
|
|
158
191
|
}
|
|
159
192
|
|
|
160
193
|
.card--horizontal .card-icon-wrap {
|
|
161
|
-
width: var(--dimension-
|
|
162
|
-
height: var(--dimension-
|
|
194
|
+
width: var(--dimension-40);
|
|
195
|
+
height: var(--dimension-40);
|
|
163
196
|
}
|
|
164
197
|
|
|
165
198
|
.card--horizontal .card-description { margin: 0; }
|
|
@@ -173,7 +206,7 @@ slot[name="header"] { display: contents; }
|
|
|
173
206
|
justify-content: center;
|
|
174
207
|
}
|
|
175
208
|
|
|
176
|
-
@media (
|
|
209
|
+
@media ${unsafeCSS(below('md'))} {
|
|
177
210
|
.card--horizontal {
|
|
178
211
|
grid-template-columns: 1fr;
|
|
179
212
|
}
|
|
@@ -181,13 +214,27 @@ slot[name="header"] { display: contents; }
|
|
|
181
214
|
.card--horizontal .card-footnote { margin-top: 0; }
|
|
182
215
|
}
|
|
183
216
|
|
|
217
|
+
/* Every --cs-bar-* read here carries a fallback, because all of them are
|
|
218
|
+
declared on :host(bd-compare-section) and none on :host(compare-bar). A
|
|
219
|
+
var() with no fallback is invalid at computed-value time, so a bar used
|
|
220
|
+
outside a section lost its height entirely: measured on CompareSection
|
|
221
|
+
"compare-bar (isolated)", which puts four bars in a plain div, the track
|
|
222
|
+
was 0px tall with no border and no fill, and the overflow: hidden below
|
|
223
|
+
clipped the label away with it. Four invisible bars in a story whose whole
|
|
224
|
+
job is to show the bar on its own -- and render-health cannot see it,
|
|
225
|
+
because other things on the page do occupy space.
|
|
226
|
+
|
|
227
|
+
The fallbacks are the same values the section declares, so a bar inside a
|
|
228
|
+
section is unchanged, and a themed section still wins: a custom property
|
|
229
|
+
inheriting from an ancestor beats a fallback, where a declaration on
|
|
230
|
+
:host(compare-bar) would have beaten the theme and pinned every bar. */
|
|
184
231
|
.bar-track {
|
|
185
232
|
position: relative;
|
|
186
|
-
height: var(--cs-bar-height);
|
|
233
|
+
height: var(--cs-bar-height, var(--dimension-48));
|
|
187
234
|
border-radius: var(--radius-xl);
|
|
188
235
|
overflow: hidden;
|
|
189
236
|
background: var(--cs-bar-track-bg, transparent);
|
|
190
|
-
border: var(--border-width-1) solid var(--cs-bar-track-border);
|
|
237
|
+
border: var(--border-width-1) solid var(--cs-bar-track-border, var(--color-border-subtle));
|
|
191
238
|
box-sizing: border-box;
|
|
192
239
|
}
|
|
193
240
|
|
|
@@ -234,52 +281,141 @@ slot[name="header"] { display: contents; }
|
|
|
234
281
|
|
|
235
282
|
.bar-score { font-variant-numeric: tabular-nums; }
|
|
236
283
|
|
|
284
|
+
/* The fallbacks matter: --cs-bar-primary-bg and -fg are declared on
|
|
285
|
+
:host(bd-compare-section) only, so a compare-bar used on its own has neither.
|
|
286
|
+
var() with no fallback is invalid at computed-value time, which made the fill
|
|
287
|
+
transparent and dropped the label back to inherited ink -- measured on
|
|
288
|
+
CompareSection "compare-bar (isolated)", a primary bar with
|
|
289
|
+
background rgba(0, 0, 0, 0) and a dark label, indistinguishable from a
|
|
290
|
+
secondary bar apart from its weight.
|
|
291
|
+
|
|
292
|
+
Fallbacks rather than a declaration on :host(compare-bar): a value set on the
|
|
293
|
+
bar's own host would override the one inheriting from a themed section and
|
|
294
|
+
pin every bar blue. */
|
|
237
295
|
:host(compare-bar[variant="primary"]) .bar-fill {
|
|
238
|
-
background: var(--cs-bar-primary-bg);
|
|
296
|
+
background: var(--cs-bar-primary-bg, var(--status-brand-fill));
|
|
239
297
|
}
|
|
240
298
|
:host(compare-bar[variant="primary"]) .bar-label,
|
|
241
299
|
:host(compare-bar[variant="primary"]) .bar-score {
|
|
242
|
-
color: var(--cs-bar-primary-fg);
|
|
300
|
+
color: var(--cs-bar-primary-fg, var(--status-brand-on-fill));
|
|
301
|
+
/* no role: this weight belongs to the primary VARIANT, not to the text --
|
|
302
|
+
the same bar reads 400 in every other variant. A variant is a UI state,
|
|
303
|
+
the category CLAUDE.md keeps apart from type when it says a focus ring is
|
|
304
|
+
never expressed by swapping a border colour. See button.css.js's
|
|
305
|
+
.button--bold for the argument. */
|
|
243
306
|
font-weight: var(--typography-fontWeight-semibold);
|
|
244
307
|
}
|
|
245
308
|
|
|
246
309
|
:host(compare-bar[variant="secondary"]) .bar-fill,
|
|
247
310
|
:host(compare-bar:not([variant])) .bar-fill {
|
|
248
|
-
|
|
311
|
+
/* no role: the same decision as --cs-bar-secondary-bg, which this repeats as
|
|
312
|
+
a fallback for a compare-bar used outside a bd-compare-section. */
|
|
313
|
+
background: var(--cs-bar-secondary-bg, var(--color-neutral-100));
|
|
249
314
|
}
|
|
250
315
|
:host(compare-bar[variant="secondary"]) .bar-label,
|
|
251
316
|
:host(compare-bar:not([variant])) .bar-label,
|
|
252
317
|
:host(compare-bar[variant="secondary"]) .bar-score,
|
|
253
318
|
:host(compare-bar:not([variant])) .bar-score {
|
|
254
|
-
color: var(--color-
|
|
319
|
+
color: var(--color-text-primary);
|
|
255
320
|
font-weight: var(--typography-body-regular-fontWeight);
|
|
256
321
|
}
|
|
257
322
|
|
|
323
|
+
/* theme-green and theme-red take --status-*-fill and --status-*-on-fill: a
|
|
324
|
+
saturated fill carrying a label on it is exactly the responsibility those
|
|
325
|
+
roles name, and bd-badge variant="fill" already draws it.
|
|
326
|
+
|
|
327
|
+
This is adopting a decision the system recorded rather than making a new one.
|
|
328
|
+
badge.css.js: "green-700 with a white label, rather than the design's
|
|
329
|
+
green-500 with a dark one. green-700 is the lightest step in the family that
|
|
330
|
+
carries white text at 4.5:1 -- it measures 4.75, where green-600 is only
|
|
331
|
+
3.20." So green-500-with-dark-ink was considered there and rejected.
|
|
332
|
+
|
|
333
|
+
Measured on the built stories, white label on the primary fill:
|
|
334
|
+
theme-green green-500 #15c14f 2.39:1 FAIL -> green-700 #0e8532 4.75:1
|
|
335
|
+
theme-red red-500 #ff0000 4.00:1 FAIL -> red-600 #d60000 5.44:1
|
|
336
|
+
Both are 16px/600, which is not WCAG large text, so the bar is 4.5:1.
|
|
337
|
+
|
|
338
|
+
Each theme also used to set --cs-icon-color and --cs-icon-filter, eight
|
|
339
|
+
declarations in all, and nothing read either one: the card icon is a <bd-img>
|
|
340
|
+
sized by .card-icon-wrap and given no colour treatment at all. git log -S on
|
|
341
|
+
the reading form finds no commit in the history where a consumer existed, so
|
|
342
|
+
they were written and never wired up rather than orphaned by a later change.
|
|
343
|
+
Removed. They were carrying a paragraph of contrast reasoning about the -500
|
|
344
|
+
steps that read as a live decision, and one of the two occurrences of the raw
|
|
345
|
+
#7c3aed literal -- the fill below is the only one left.
|
|
346
|
+
|
|
347
|
+
Worth recording so it is not re-derived: green-500 is 2.39:1 on white, which
|
|
348
|
+
is below the 3:1 non-text minimum, so tinting that icon green-500 would have
|
|
349
|
+
been a 1.4.11 question if it had ever happened. It would not have failed even
|
|
350
|
+
then -- compare.js renders the icon aria-hidden with alt="", which is the
|
|
351
|
+
exemption -- but the margin is why nothing should reach for -500 here later
|
|
352
|
+
on the strength of the deleted comment. */
|
|
258
353
|
:host(bd-compare-section.theme-green) {
|
|
259
|
-
--cs-bar-primary-bg: var(--
|
|
260
|
-
--cs-bar-primary-fg: var(--
|
|
261
|
-
--cs-icon-color: var(--color-green-500);
|
|
262
|
-
--cs-icon-filter: invert(35%) sepia(72%) saturate(500%) hue-rotate(100deg) brightness(95%) contrast(95%);
|
|
354
|
+
--cs-bar-primary-bg: var(--status-success-fill);
|
|
355
|
+
--cs-bar-primary-fg: var(--status-success-on-fill);
|
|
263
356
|
}
|
|
264
357
|
:host(bd-compare-section.theme-red) {
|
|
265
|
-
--cs-bar-primary-bg: var(--
|
|
266
|
-
--cs-bar-primary-fg: var(--
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
358
|
+
--cs-bar-primary-bg: var(--status-error-fill);
|
|
359
|
+
--cs-bar-primary-fg: var(--status-error-on-fill);
|
|
360
|
+
}
|
|
361
|
+
/* theme-dark and theme-purple have no --status-*-fill pair to adopt -- "dark"
|
|
362
|
+
and "purple" are themes, not statuses -- so the migration above does not
|
|
363
|
+
reach them. They are settled separately, and only one of them is settled.
|
|
364
|
+
|
|
365
|
+
theme-dark is D1, approved. The label measured 3.35:1 on the blue-400 fill
|
|
366
|
+
and failed. Two directions had precedent here and they look different:
|
|
367
|
+
darken the fill to blue-500 and keep the white label (4.53:1), or keep
|
|
368
|
+
blue-400 and flip the ink dark (5.37:1). The approved direction is the
|
|
369
|
+
second, because blue-400 is deliberately the brighter step so the fill still
|
|
370
|
+
reads on a dark ground -- darkening it to blue-500 would have spent the one
|
|
371
|
+
thing this theme exists for in order to fix the ink.
|
|
372
|
+
|
|
373
|
+
The ink is --color-text-primary, and that is a responsibility rather than a
|
|
374
|
+
value. Two tokens resolve to neutral-900 today and only one of them means
|
|
375
|
+
this. --status-warning-on-fill is the ink belonging to the *warning* fill,
|
|
376
|
+
and a compare bar is not a warning; taking it for the value would also tie
|
|
377
|
+
this theme to yellow-500's future, so a warning fill later dark enough to
|
|
378
|
+
carry white would turn this label white on light blue. --color-text-primary
|
|
379
|
+
is the default ink for copy on a light ground, which is what a label on a
|
|
380
|
+
light blue fill is, and it is already what the secondary bar's label uses on
|
|
381
|
+
--cs-bar-secondary-bg two rules above. Same job in the same file, same role.
|
|
382
|
+
|
|
383
|
+
Measured on the built stories at 16px/600, which is not WCAG large text, so
|
|
384
|
+
the bar is 4.5:1:
|
|
385
|
+
theme-dark blue-400 #338bff white #ffffff 3.35:1 FAIL
|
|
386
|
+
-> ink #151719 5.37:1 PASS
|
|
387
|
+
|
|
388
|
+
theme-purple measures 5.70:1 and passes, so there is no accessibility
|
|
389
|
+
pressure; #7c3aed is a raw hex for a colour the palette does not contain.
|
|
390
|
+
Giving it a token or retiring the theme is a product decision, still open.
|
|
391
|
+
|
|
392
|
+
This used to add "and lint:tokens does not report it", which reads as a gate
|
|
393
|
+
weakness and is not one. lint:tokens carries the literal in ALLOW.hex with
|
|
394
|
+
the reason on the line above it -- no purple in the palette, nearest token
|
|
395
|
+
34.6 deltaE away -- so the silence is a registered exception, not a miss.
|
|
396
|
+
Checked by probe: an unlisted off-scale hex reports hex-off-scale and fails
|
|
397
|
+
the build, a palette value reports hex-for-token, and this one stays quiet.
|
|
398
|
+
The check:color-coverage side needs its own record, which is what the
|
|
399
|
+
no token: marker below is; the two gates do not share an exemption. */
|
|
270
400
|
:host(bd-compare-section.theme-purple) {
|
|
401
|
+
/* no token: the open product decision recorded above -- purple is not in the
|
|
402
|
+
palette, so neither the fill nor the ink that belongs to it can resolve.
|
|
403
|
+
green and red take --status-*-fill / --status-*-on-fill because they ARE
|
|
404
|
+
statuses; there is no such pair to adopt here, and giving white ink a role
|
|
405
|
+
while its ground stays a literal would record half a decision. */
|
|
271
406
|
--cs-bar-primary-bg: #7c3aed;
|
|
272
|
-
--cs-bar-primary-fg: var(--color-neutral-0);
|
|
273
|
-
--cs-icon-color: #7c3aed;
|
|
274
|
-
--cs-icon-filter: invert(25%) sepia(80%) saturate(800%) hue-rotate(255deg) brightness(90%) contrast(95%);
|
|
407
|
+
--cs-bar-primary-fg: var(--color-neutral-0); /* no token: as above */
|
|
275
408
|
}
|
|
276
409
|
:host(bd-compare-section.theme-dark) {
|
|
410
|
+
/* no role: nothing in the semantic set resolves to blue-400. That is the
|
|
411
|
+
point of the D1 decision above -- blue-400 is deliberately the brighter
|
|
412
|
+
step so the fill still reads on a dark ground -- so the absence is the
|
|
413
|
+
theme working, not a gap to close. */
|
|
277
414
|
--cs-bar-primary-bg: var(--color-blue-400);
|
|
278
|
-
--cs-bar-primary-fg: var(--color-
|
|
279
|
-
--cs-
|
|
280
|
-
--cs-icon-filter: invert(65%) sepia(50%) saturate(500%) hue-rotate(195deg) brightness(105%) contrast(95%);
|
|
415
|
+
--cs-bar-primary-fg: var(--color-text-primary);
|
|
416
|
+
--cs-section-text: var(--color-text-inverse);
|
|
281
417
|
}
|
|
282
418
|
|
|
283
|
-
:host(bd-compare-section.bars-tall) { --cs-bar-height: var(--dimension-
|
|
284
|
-
:host(bd-compare-section.bars-compact) { --cs-bar-height: var(--dimension-
|
|
419
|
+
:host(bd-compare-section.bars-tall) { --cs-bar-height: var(--dimension-56); }
|
|
420
|
+
:host(bd-compare-section.bars-compact) { --cs-bar-height: var(--dimension-40); --cs-gap: var(--spacing-24); }
|
|
285
421
|
`;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
|
-
|
|
2
|
+
// Installs the design tokens into document scope; see src/tokens/tokens.js
|
|
3
|
+
import "../../tokens/tokens.js";
|
|
4
|
+
import "../heading/heading.js";
|
|
5
|
+
import "../image/image.js";
|
|
6
|
+
import "../link/link.js";
|
|
7
|
+
import "../paragraph/paragraph.js";
|
|
3
8
|
import compareCSS from "./compare.css.js";
|
|
9
|
+
import { ensembleCSS } from "../shared/ensemble.css.js";
|
|
10
|
+
import { matchesBelow } from "../shared/token-scales.js";
|
|
4
11
|
|
|
5
12
|
function readStretchVars(el) {
|
|
6
13
|
const styles = getComputedStyle(el);
|
|
@@ -49,7 +56,7 @@ class CompareBar extends LitElement {
|
|
|
49
56
|
_animatedScore: { state: true }
|
|
50
57
|
};
|
|
51
58
|
|
|
52
|
-
static styles = [
|
|
59
|
+
static styles = [compareCSS];
|
|
53
60
|
|
|
54
61
|
constructor() {
|
|
55
62
|
super();
|
|
@@ -230,7 +237,7 @@ class CompareCard extends LitElement {
|
|
|
230
237
|
chartScale : { type: Number, attribute: "chart-scale" }
|
|
231
238
|
};
|
|
232
239
|
|
|
233
|
-
static styles = [
|
|
240
|
+
static styles = [compareCSS];
|
|
234
241
|
|
|
235
242
|
constructor() {
|
|
236
243
|
super();
|
|
@@ -341,7 +348,7 @@ class CompareCard extends LitElement {
|
|
|
341
348
|
if (!this.footnote) return "";
|
|
342
349
|
|
|
343
350
|
if (!this.footnoteHref) {
|
|
344
|
-
return html`<bd-p
|
|
351
|
+
return html`<bd-p variant="xsmall" class="card-footnote">${this.footnote}</bd-p>`;
|
|
345
352
|
}
|
|
346
353
|
|
|
347
354
|
const splitOn = "Source ";
|
|
@@ -349,8 +356,8 @@ class CompareCard extends LitElement {
|
|
|
349
356
|
|
|
350
357
|
if (idx === -1) {
|
|
351
358
|
return html`
|
|
352
|
-
<bd-p
|
|
353
|
-
<bd-link href="${this.footnoteHref}" target="_blank" font-size="
|
|
359
|
+
<bd-p variant="xsmall" class="card-footnote">
|
|
360
|
+
<bd-link href="${this.footnoteHref}" target="_blank" font-size="xs" color="strong" underline>
|
|
354
361
|
${this.footnote}
|
|
355
362
|
</bd-link>
|
|
356
363
|
</bd-p>
|
|
@@ -361,12 +368,28 @@ class CompareCard extends LitElement {
|
|
|
361
368
|
const linkedText = this.footnote.slice(idx + splitOn.length);
|
|
362
369
|
|
|
363
370
|
return html`
|
|
364
|
-
<bd-p
|
|
365
|
-
${before}<bd-link href="${this.footnoteHref}" target="_blank" font-size="
|
|
371
|
+
<bd-p variant="xsmall" class="card-footnote">
|
|
372
|
+
${before}<bd-link href="${this.footnoteHref}" target="_blank" font-size="xs" color="strong" underline>${linkedText}</bd-link>
|
|
366
373
|
</bd-p>
|
|
367
374
|
`;
|
|
368
375
|
}
|
|
369
376
|
|
|
377
|
+
/* aria-labelledby resolves against the root it is written in, and a
|
|
378
|
+
plain id on the <bd-h> HOST is what makes that possible: the host
|
|
379
|
+
sits in this shadow root beside the element referring to it, while
|
|
380
|
+
the <h3> bd-h renders lives in bd-h's own shadow root where an IDREF
|
|
381
|
+
from here cannot reach it. Name computation walks the flattened
|
|
382
|
+
tree, so the host carries the slotted title text.
|
|
383
|
+
This used to be spelled heading-id, which bd-h has never had a
|
|
384
|
+
property for and has never read, so nothing carried the id at all
|
|
385
|
+
and all 43 references across 16 Compare stories pointed at nothing.
|
|
386
|
+
The <section> was not merely unnamed -- a section with no accessible
|
|
387
|
+
name gets no region role, so the landmark did not exist.
|
|
388
|
+
id, not a new bd-h attribute, because modal.js already does exactly
|
|
389
|
+
this two components over and it works: its role=dialog resolves
|
|
390
|
+
aria-labelledby="modal-title" to a <bd-h id="modal-title"> and
|
|
391
|
+
reports the accessible name "VPN Protection". The manifest never
|
|
392
|
+
claimed a headingId property either. */
|
|
370
393
|
_renderHorizontal() {
|
|
371
394
|
return html`
|
|
372
395
|
<div
|
|
@@ -382,7 +405,8 @@ class CompareCard extends LitElement {
|
|
|
382
405
|
<div class="card-left">
|
|
383
406
|
<slot name="header">
|
|
384
407
|
<div class="card-left-top">
|
|
385
|
-
${this.iconSrc
|
|
408
|
+
${this.iconSrc
|
|
409
|
+
? html`
|
|
386
410
|
<div class="card-icon-wrap" aria-hidden="true">
|
|
387
411
|
<bd-img
|
|
388
412
|
src="${this.iconSrc}"
|
|
@@ -395,12 +419,15 @@ class CompareCard extends LitElement {
|
|
|
395
419
|
loading="eager"
|
|
396
420
|
></bd-img>
|
|
397
421
|
</div>
|
|
398
|
-
`
|
|
399
|
-
|
|
422
|
+
`
|
|
423
|
+
: ""}
|
|
424
|
+
<bd-h as="h3" class="card-title" id="${this._headingId}">${this.title}</bd-h>
|
|
400
425
|
</div>
|
|
401
|
-
${this.description
|
|
402
|
-
|
|
403
|
-
|
|
426
|
+
${this.description
|
|
427
|
+
? html`
|
|
428
|
+
<bd-p variant="regular" class="card-description">${this.description}</bd-p>
|
|
429
|
+
`
|
|
430
|
+
: ""}
|
|
404
431
|
${this._renderFootnote()}
|
|
405
432
|
</slot>
|
|
406
433
|
</div>
|
|
@@ -417,7 +444,7 @@ class CompareCard extends LitElement {
|
|
|
417
444
|
render() {
|
|
418
445
|
if (this.layout === "horizontal") return this._renderHorizontal();
|
|
419
446
|
|
|
420
|
-
const isMobile =
|
|
447
|
+
const isMobile = matchesBelow('md');
|
|
421
448
|
|
|
422
449
|
return html`
|
|
423
450
|
<div
|
|
@@ -449,11 +476,11 @@ class CompareCard extends LitElement {
|
|
|
449
476
|
: ""}
|
|
450
477
|
<div class="card-text-wrap">
|
|
451
478
|
${isMobile
|
|
452
|
-
? html`<bd-h as="h5" class="card-title"
|
|
453
|
-
: html`<bd-h as="h4" class="card-title"
|
|
479
|
+
? html`<bd-h as="h5" class="card-title" id="${this._headingId}">${this.title}</bd-h>`
|
|
480
|
+
: html`<bd-h as="h4" class="card-title" id="${this._headingId}">${this.title}</bd-h>`}
|
|
454
481
|
${this.description
|
|
455
482
|
? html`
|
|
456
|
-
<bd-p
|
|
483
|
+
<bd-p variant="${isMobile ? "small" : "regular"}" class="card-description">
|
|
457
484
|
${this.description}
|
|
458
485
|
</bd-p>
|
|
459
486
|
`
|
|
@@ -484,7 +511,7 @@ class CompareSection extends LitElement {
|
|
|
484
511
|
gap : { type: String }
|
|
485
512
|
};
|
|
486
513
|
|
|
487
|
-
static styles = [
|
|
514
|
+
static styles = [ensembleCSS, compareCSS];
|
|
488
515
|
|
|
489
516
|
constructor() {
|
|
490
517
|
super();
|
|
@@ -527,7 +554,7 @@ class CompareSection extends LitElement {
|
|
|
527
554
|
this._syncRaf = requestAnimationFrame(() => {
|
|
528
555
|
this._syncRaf = 0;
|
|
529
556
|
|
|
530
|
-
const isMobile =
|
|
557
|
+
const isMobile = matchesBelow('md');
|
|
531
558
|
|
|
532
559
|
// Get all slotted compare-card elements
|
|
533
560
|
const slot = this.shadowRoot?.querySelector("slot");
|
|
@@ -560,14 +587,14 @@ class CompareSection extends LitElement {
|
|
|
560
587
|
}
|
|
561
588
|
|
|
562
589
|
render() {
|
|
563
|
-
const isMobile =
|
|
590
|
+
const isMobile = matchesBelow('md');
|
|
564
591
|
const gapStyle = this.gap
|
|
565
592
|
? `--_cols: ${this.columns}; --cs-gap: ${this.gap}`
|
|
566
593
|
: `--_cols: ${this.columns}`;
|
|
567
594
|
|
|
568
595
|
return html`
|
|
569
596
|
<section
|
|
570
|
-
class="cs-section"
|
|
597
|
+
class="bd-ensemble cs-section"
|
|
571
598
|
aria-labelledby="${this.title ? this._sectionTitleId : nothing}"
|
|
572
599
|
>
|
|
573
600
|
${this.title || this.subtitle
|
|
@@ -575,12 +602,12 @@ class CompareSection extends LitElement {
|
|
|
575
602
|
<div class="cs-heading">
|
|
576
603
|
${this.title
|
|
577
604
|
? isMobile
|
|
578
|
-
? html`<bd-h as="h4" class="cs-title"
|
|
579
|
-
: html`<bd-h as="h3" class="cs-title"
|
|
605
|
+
? html`<bd-h as="h4" class="cs-title" id="${this._sectionTitleId}">${this.title}</bd-h>`
|
|
606
|
+
: html`<bd-h as="h3" class="cs-title" id="${this._sectionTitleId}">${this.title}</bd-h>`
|
|
580
607
|
: ""}
|
|
581
608
|
${this.subtitle
|
|
582
609
|
? html`
|
|
583
|
-
<bd-p
|
|
610
|
+
<bd-p variant="${isMobile ? "small" : "regular"}" class="cs-subtitle">
|
|
584
611
|
${this.subtitle}
|
|
585
612
|
</bd-p>
|
|
586
613
|
`
|
|
@@ -80,7 +80,7 @@ Three Lit web components for building customizable comparison sections with anim
|
|
|
80
80
|
| \`--cs-bar-primary-fg\` | \`var(--color-neutral-0)\` | Primary bar text colour |
|
|
81
81
|
| \`--cs-bar-secondary-bg\` | \`var(--color-neutral-100)\` | Secondary bar fill colour |
|
|
82
82
|
| \`--cs-bar-track-border\` | \`var(--color-neutral-200)\` | Bar track border colour |
|
|
83
|
-
| \`--cs-bar-height\` | \`var(--dimension-
|
|
83
|
+
| \`--cs-bar-height\` | \`var(--dimension-48)\` | Height of every bar |
|
|
84
84
|
| \`--cs-gap\` | \`var(--spacing-32)\` | Gap between cards |
|
|
85
85
|
| \`--cs-grid-max\` | \`1228px\` | Max width of the card grid |
|
|
86
86
|
`
|
|
@@ -552,6 +552,46 @@ export const ThemeGreen = {
|
|
|
552
552
|
`
|
|
553
553
|
};
|
|
554
554
|
|
|
555
|
+
export const ThemeRed = {
|
|
556
|
+
name : "Theme — Red",
|
|
557
|
+
render: () => html`
|
|
558
|
+
<bd-compare-section
|
|
559
|
+
title="Red Theme"
|
|
560
|
+
gap="32px"
|
|
561
|
+
class="theme-red"
|
|
562
|
+
>
|
|
563
|
+
<compare-card
|
|
564
|
+
title="Best Protection"
|
|
565
|
+
description="Scale of 0–6. Higher is better."
|
|
566
|
+
footnote="Overall Score. July 2011 – February 2025. Source AV TEST.org"
|
|
567
|
+
footnote-href="${AV_TEST_URL}"
|
|
568
|
+
icon-src="${SHIELD_ICON}"
|
|
569
|
+
bar-stretch="false"
|
|
570
|
+
>
|
|
571
|
+
<compare-bar label="Bitdefender" score="5.95" max-score="6" variant="primary"></compare-bar>
|
|
572
|
+
<compare-bar label="Norton" score="5.59" max-score="6" variant="secondary" scale="0.93"></compare-bar>
|
|
573
|
+
<compare-bar label="McAfee" score="5.45" max-score="6" variant="secondary" scale="0.47"></compare-bar>
|
|
574
|
+
</compare-card>
|
|
575
|
+
</bd-compare-section>
|
|
576
|
+
`,
|
|
577
|
+
parameters: {
|
|
578
|
+
docs: {
|
|
579
|
+
description: {
|
|
580
|
+
story: `\`theme-red\` is a shipped variant of bd-compare-section and had no story, so
|
|
581
|
+
nothing rendered it and no gate opened it — which is how its primary bar label
|
|
582
|
+
sat at 4.00:1 unnoticed. P6C.5 measured that by applying the class at runtime,
|
|
583
|
+
because there was no story to measure.
|
|
584
|
+
|
|
585
|
+
It now takes \`--status-error-fill\` and \`--status-error-on-fill\`, the pair
|
|
586
|
+
the design system already defines for a saturated fill carrying a label, so
|
|
587
|
+
the label measures 5.44:1 against the 4.00:1 of the red-500 it replaced. The
|
|
588
|
+
other four themes are in the sibling stories; theme-dark's label was the one
|
|
589
|
+
remaining failure in this family and D1 has since fixed it.`
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
|
|
555
595
|
export const ThemePurple = {
|
|
556
596
|
name : "Theme — Purple",
|
|
557
597
|
render: () => html`
|
|
@@ -625,7 +665,24 @@ export const ThemeDark = {
|
|
|
625
665
|
</compare-card>
|
|
626
666
|
</bd-compare-section>
|
|
627
667
|
</div>
|
|
628
|
-
|
|
668
|
+
`,
|
|
669
|
+
parameters: {
|
|
670
|
+
docs: {
|
|
671
|
+
description: {
|
|
672
|
+
story: `The primary bar label used to be white on the blue-400 fill, which measured
|
|
673
|
+
3.35:1 and failed. D1 kept the fill and changed the ink: blue-400 is
|
|
674
|
+
deliberately the brighter blue so the fill still reads on a dark ground, and
|
|
675
|
+
darkening it to blue-500 to carry white would have spent the one thing this
|
|
676
|
+
theme exists for.
|
|
677
|
+
|
|
678
|
+
The ink is \`--color-text-primary\`, the default ink for copy on a light
|
|
679
|
+
ground — which is what a label on a light blue fill is, and already what the
|
|
680
|
+
secondary bars beside it use. It measures 5.37:1 at 16px/600, against a 4.5:1
|
|
681
|
+
bar. The card stays light under this theme on purpose, so only the section
|
|
682
|
+
title inverts.`
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
629
686
|
};
|
|
630
687
|
|
|
631
688
|
|
|
@@ -666,8 +723,8 @@ export const HorizontalLayoutCustomSlot = {
|
|
|
666
723
|
<bd-img src="${SHIELD_ICON}" alt="" width="40" height="40" fit="contain" radius="none" shadow="none" loading="eager"></bd-img>
|
|
667
724
|
<bd-h as="h3">Award-Winning Protection</bd-h>
|
|
668
725
|
</div>
|
|
669
|
-
<bd-p
|
|
670
|
-
<bd-p
|
|
726
|
+
<bd-p variant="regular">Scale of 0–6. Higher is better. Independently tested since 2011.</bd-p>
|
|
727
|
+
<bd-p variant="xsmall" style="margin-top:auto">Overall Score. July 2011 – February 2025. Source AV TEST.org</bd-p>
|
|
671
728
|
</div>
|
|
672
729
|
<compare-bar label="Bitdefender" score="5.95" max-score="6" variant="primary"></compare-bar>
|
|
673
730
|
<compare-bar label="Norton" score="5.89" max-score="6" variant="secondary" scale="0.93"></compare-bar>
|