@viasat/beam-styles 2.0.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.
Files changed (76) hide show
  1. package/README.md +150 -0
  2. package/all.scss +3 -0
  3. package/components/accordion.module.scss +166 -0
  4. package/components/accordion.vars.scss +3 -0
  5. package/components/actionList.module.scss +211 -0
  6. package/components/actionList.vars.scss +6 -0
  7. package/components/alert.module.scss +158 -0
  8. package/components/aspectRatio.module.scss +21 -0
  9. package/components/avatar.module.scss +204 -0
  10. package/components/badge.module.scss +166 -0
  11. package/components/badgeDot.module.scss +90 -0
  12. package/components/box.module.scss +127 -0
  13. package/components/breadcrumbs.module.scss +149 -0
  14. package/components/button.module.scss +179 -0
  15. package/components/button.vars.scss +129 -0
  16. package/components/card.module.scss +232 -0
  17. package/components/checkbox.module.scss +123 -0
  18. package/components/chip.module.scss +173 -0
  19. package/components/chipsGroup.module.scss +13 -0
  20. package/components/closeButton.module.scss +52 -0
  21. package/components/combobox.module.scss +243 -0
  22. package/components/dialog.module.scss +199 -0
  23. package/components/divider.module.scss +255 -0
  24. package/components/emptyState.module.scss +61 -0
  25. package/components/fileUpload.module.scss +282 -0
  26. package/components/flag.module.scss +11 -0
  27. package/components/floatingui.module.scss +40 -0
  28. package/components/header.module.scss +123 -0
  29. package/components/helperText.module.scss +86 -0
  30. package/components/icon.module.scss +46 -0
  31. package/components/icon.vars.scss +31 -0
  32. package/components/index.scss +40 -0
  33. package/components/inputChoiceGroup.module.scss +46 -0
  34. package/components/label.module.scss +67 -0
  35. package/components/link.module.scss +118 -0
  36. package/components/list.module.scss +204 -0
  37. package/components/logo.module.scss +11 -0
  38. package/components/menu.module.scss +13 -0
  39. package/components/nativeSelect.module.scss +139 -0
  40. package/components/navigation.module.scss +156 -0
  41. package/components/pageHeader.module.scss +93 -0
  42. package/components/pageLayout.module.scss +38 -0
  43. package/components/pagination.module.scss +71 -0
  44. package/components/popover.module.scss +71 -0
  45. package/components/progressBar.module.scss +107 -0
  46. package/components/radioButton.module.scss +115 -0
  47. package/components/segmentedControl.module.scss +212 -0
  48. package/components/sideNav.module.scss +355 -0
  49. package/components/slider.module.scss +240 -0
  50. package/components/spinner.module.scss +261 -0
  51. package/components/spinner.vars.scss +85 -0
  52. package/components/stepper.module.scss +255 -0
  53. package/components/switch.module.scss +194 -0
  54. package/components/tabs.module.scss +412 -0
  55. package/components/text.module.scss +112 -0
  56. package/components/textArea.module.scss +183 -0
  57. package/components/textField.module.scss +162 -0
  58. package/components/toast.module.scss +235 -0
  59. package/components/toastContainer.module.scss +68 -0
  60. package/components/tooltip.module.scss +112 -0
  61. package/package.json +47 -0
  62. package/styles.css +11719 -0
  63. package/styles.css.map +1 -0
  64. package/styles.min.css +20 -0
  65. package/styles.min.css.map +1 -0
  66. package/utils/animation.scss +13 -0
  67. package/utils/constants.scss +1 -0
  68. package/utils/cursors.scss +35 -0
  69. package/utils/globals.scss +17 -0
  70. package/utils/helpers.scss +14 -0
  71. package/utils/index.scss +10 -0
  72. package/utils/mixins.scss +93 -0
  73. package/utils/spacing.scss +82 -0
  74. package/utils/stateLayer.module.scss +55 -0
  75. package/utils/stateLayerVars.scss +75 -0
  76. package/utils/tokens.scss +14 -0
@@ -0,0 +1,149 @@
1
+ @use 'sass:map';
2
+ @use '../utils/tokens.scss';
3
+ @use '../utils/constants.scss';
4
+
5
+ @import '../../../../tokens/src/lib/components/Breadcrumb';
6
+
7
+ $breadcrumbsBaseClass: '#{constants.$prefix}breadcrumbs';
8
+ $truncation-width: var(
9
+ --#{constants.$prefix}comp-breadcrumbs-truncation-width,
10
+ auto
11
+ );
12
+ $linkSecondaryColor: '--#{constants.$prefix}sem-color-link-secondary';
13
+ $linkPrimaryHoverColor: '--#{constants.$prefix}comp-link-color-primary-hover';
14
+ $linkSecondaryActiveColor: '--#{constants.$prefix}comp-link-color-secondary-active';
15
+ $semOpacityDisabled: '--#{constants.$prefix}sem-opacity-disabled';
16
+
17
+ .#{$breadcrumbsBaseClass} {
18
+ &__list {
19
+ display: flex;
20
+ align-items: center;
21
+ list-style: none;
22
+ padding: 0;
23
+ margin: 0;
24
+ gap: tokens.$bm-comp-breadcrumb-space-gap;
25
+ }
26
+
27
+ &__item {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: tokens.$bm-comp-breadcrumb-space-gap;
31
+ }
32
+
33
+ &__link {
34
+ #{$linkSecondaryColor}: #{tokens.$bm-comp-breadcrumb-color-enabled};
35
+
36
+ &:hover {
37
+ #{$linkPrimaryHoverColor}: #{tokens.$bm-comp-breadcrumb-color-hover};
38
+ }
39
+
40
+ &:active {
41
+ #{$linkSecondaryActiveColor}: #{tokens.$bm-comp-breadcrumb-color-active};
42
+ }
43
+
44
+ &.bm-link--disabled {
45
+ cursor: pointer;
46
+ #{$semOpacityDisabled}: 1;
47
+
48
+ &:hover {
49
+ text-decoration: underline;
50
+ }
51
+ }
52
+ }
53
+
54
+ &__icon {
55
+ flex-shrink: 0;
56
+ display: inline-flex;
57
+
58
+ ::slotted([slot='icon']) {
59
+ color: tokens.$bm-comp-breadcrumb-color-enabled;
60
+ width: tokens.$bm-comp-link-size-sm-icon;
61
+ height: tokens.$bm-comp-link-size-sm-icon;
62
+ display: inline-flex;
63
+ }
64
+
65
+ &--current {
66
+ // Since we use link under the hood, we need to make sure the icon is the same size as the links
67
+ width: tokens.$bm-comp-link-size-sm-icon;
68
+ height: tokens.$bm-comp-link-size-sm-icon;
69
+ color: tokens.$bm-comp-breadcrumb-color-selected;
70
+ }
71
+ }
72
+
73
+ &__separator {
74
+ min-width: tokens.$bm-comp-breadcrumb-size-icon-chevron;
75
+ min-height: tokens.$bm-comp-breadcrumb-size-icon-chevron;
76
+ max-width: tokens.$bm-comp-breadcrumb-size-icon-chevron;
77
+ max-height: tokens.$bm-comp-breadcrumb-size-icon-chevron;
78
+ color: tokens.$bm-comp-breadcrumb-color-enabled;
79
+
80
+ [dir='rtl'] & {
81
+ transform: rotate(180deg);
82
+ }
83
+ }
84
+
85
+ &__text {
86
+ white-space: nowrap;
87
+ overflow: hidden;
88
+ text-overflow: ellipsis;
89
+ display: block;
90
+
91
+ [dir='rtl'] & {
92
+ unicode-bidi: plaintext;
93
+ }
94
+ }
95
+
96
+ &__current {
97
+ color: tokens.$bm-comp-breadcrumb-color-selected;
98
+ font: tokens.$bm-comp-breadcrumb-typo-default;
99
+
100
+ display: flex;
101
+ align-items: center;
102
+ gap: tokens.$bm-comp-breadcrumb-space-gap;
103
+ }
104
+
105
+ &__item--ellipsis {
106
+ color: tokens.$bm-comp-breadcrumb-color-enabled;
107
+
108
+ :focus-visible {
109
+ outline: tokens.$bm-sem-border-width-focus solid
110
+ tokens.$bm-sem-color-border-focus;
111
+ border-radius: tokens.$bm-sem-radius-focus-md;
112
+ }
113
+ }
114
+
115
+ &--wrap {
116
+ .#{$breadcrumbsBaseClass}__list {
117
+ flex-wrap: wrap;
118
+ }
119
+ }
120
+
121
+ :host(*) &__text {
122
+ color: tokens.$bm-comp-breadcrumb-color-enabled;
123
+
124
+ &:hover {
125
+ color: tokens.$bm-comp-breadcrumb-color-hover;
126
+ }
127
+
128
+ &:active {
129
+ color: tokens.$bm-comp-breadcrumb-color-active;
130
+ }
131
+ }
132
+ }
133
+
134
+ ::part(link) {
135
+ max-width: $truncation-width;
136
+ #{$linkSecondaryColor}: #{tokens.$bm-comp-breadcrumb-color-enabled};
137
+ }
138
+
139
+ :host-context([dir='rtl']) {
140
+ .#{$breadcrumbsBaseClass} {
141
+ &__text {
142
+ unicode-bidi: plaintext;
143
+ }
144
+
145
+ &__separator {
146
+ transform: rotate(180deg);
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,179 @@
1
+ @use 'sass:map';
2
+ @use '../utils/constants.scss';
3
+ @use '../utils/tokens.scss' as tokens;
4
+ @use '../utils/stateLayerVars.scss' as state-layer-vars;
5
+ @use '../utils/mixins.scss';
6
+ @use './button.vars.scss' as vars;
7
+ @use './spinner.vars.scss' as spinner;
8
+
9
+ @import '../../../../tokens/src/lib/components/Button';
10
+
11
+ %icon-size {
12
+ display: block;
13
+ width: var(#{vars.$buttonIconSizeVarName});
14
+ height: var(#{vars.$buttonIconSizeVarName});
15
+ }
16
+
17
+ .#{vars.$buttonBaseClass} {
18
+ cursor: pointer;
19
+ position: relative;
20
+ display: inline-flex;
21
+ flex-direction: row;
22
+ width: fit-content;
23
+ padding: var(#{vars.$buttonPaddingYVarName}) var(#{vars.$buttonPaddingXVarName});
24
+ justify-content: center;
25
+ align-items: center;
26
+ gap: tokens.$bm-comp-btn-space-gap;
27
+ border: none;
28
+ border-radius: tokens.$bm-comp-btn-radius-container;
29
+ max-width: 100%;
30
+
31
+ // Sizes
32
+ $defaultSize: map.get(vars.$sizes, 'md');
33
+ font: #{map.get($defaultSize, 'font')};
34
+ min-width: #{map.get($defaultSize, 'min-width')};
35
+ min-height: #{map.get($defaultSize, 'min-height')};
36
+ #{vars.$buttonPaddingYVarName}: #{map.get($defaultSize, 'padding-y')};
37
+ #{vars.$buttonPaddingXVarName}: #{map.get($defaultSize, 'padding-x')};
38
+ #{vars.$buttonIconSizeVarName}: #{map.get($defaultSize, 'icon')};
39
+
40
+ @each $size, $props in vars.$sizes {
41
+ &--#{$size} {
42
+ font: #{map.get($props, 'font')};
43
+ min-width: #{map.get($props, 'min-width')};
44
+ min-height: #{map.get($props, 'min-height')};
45
+ #{vars.$buttonPaddingYVarName}: #{map.get($props, 'padding-y')};
46
+ #{vars.$buttonPaddingXVarName}: #{map.get($props, 'padding-x')};
47
+ #{vars.$buttonIconSizeVarName}: #{map.get($props, 'icon')};
48
+ }
49
+ }
50
+
51
+ &--icon-only {
52
+ padding: unset;
53
+ }
54
+
55
+ &__label {
56
+ z-index: 1;
57
+ position: relative;
58
+ padding: 0 tokens.$bm-comp-btn-space-label-x;
59
+ text-align: start;
60
+ }
61
+
62
+ // Appearance & Kinds
63
+ $defaultAppearance: 'accent';
64
+ $defaultKind: 'filled';
65
+ $defaultProps: map.get(
66
+ map.get(vars.$appearancesAndKinds, $defaultAppearance),
67
+ $defaultKind
68
+ );
69
+
70
+ & {
71
+ background: map.get($defaultProps, 'background');
72
+ color: map.get($defaultProps, 'color');
73
+ border-color: map.get($defaultProps, 'border-color');
74
+ }
75
+
76
+ @each $appearance, $kinds in vars.$appearancesAndKinds {
77
+ @each $kind, $props in $kinds {
78
+ &--#{$appearance}-#{$kind} {
79
+ background: map.get($props, 'background');
80
+ color: map.get($props, 'color');
81
+ @include mixins.simulated-inset-outline(
82
+ tokens.$bm-comp-btn-border-width,
83
+ solid,
84
+ map.get($props, 'border-color'),
85
+ -0.0625rem
86
+ );
87
+
88
+ .#{vars.$buttonLoadingSpinner} {
89
+ .#{spinner.$circleSvgClassBase} {
90
+ stroke: map.get($props, 'color');
91
+ }
92
+
93
+ .#{spinner.$circleBgClassBase} {
94
+ stroke: map.get($props, 'color');
95
+ opacity: tokens.$bm-comp-btn-opacity-spinner-track;
96
+ }
97
+ }
98
+
99
+ @if ($appearance == 'accent' or $appearance == 'destructive') and
100
+ $kind ==
101
+ 'filled'
102
+ {
103
+ #{state-layer-vars.getStateLayerSelector('&', 'hover')} {
104
+ #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-hover-strong;
105
+ }
106
+
107
+ #{state-layer-vars.getStateLayerSelector('&', 'active')} {
108
+ #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-active-strong;
109
+ }
110
+ }
111
+
112
+ @if $appearance == 'neutral' and $kind == 'filled' {
113
+ #{state-layer-vars.getStateLayerSelector('&', 'hover')} {
114
+ #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-hover-inverse;
115
+ }
116
+
117
+ #{state-layer-vars.getStateLayerSelector('&', 'active')} {
118
+ #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-active-inverse;
119
+ }
120
+ }
121
+
122
+ @if $kind == 'bare' {
123
+ min-height: unset !important;
124
+ min-width: unset !important;
125
+ padding: tokens.$bm-comp-btn-space-bare-y tokens.$bm-comp-btn-space-bare-x;
126
+ border-radius: tokens.$bm-sem-radius-sm;
127
+ gap: tokens.$bm-comp-btn-space-bare-gap;
128
+
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+
133
+ .#{vars.$buttonBaseClass}__label {
134
+ padding: 0 tokens.$bm-comp-btn-space-bare-label-x;
135
+ }
136
+
137
+ .#{state-layer-vars.$stateLayerBaseClass} {
138
+ $offset: calc(0px - tokens.$bm-sem-size-focus-offset);
139
+ #{state-layer-vars.$top}: $offset;
140
+ #{state-layer-vars.$right}: $offset;
141
+ #{state-layer-vars.$bottom}: $offset;
142
+ #{state-layer-vars.$left}: $offset;
143
+ #{state-layer-vars.$outline-offset}: 0 !important;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ &[class*='filled'] {
151
+ box-shadow: tokens.$bm-comp-btn-shadow;
152
+ }
153
+
154
+ // Disabled
155
+ &:disabled {
156
+ cursor: not-allowed;
157
+ opacity: tokens.$bm-sem-opacity-disabled;
158
+ }
159
+
160
+ // Loading
161
+ &--loading {
162
+ cursor: not-allowed;
163
+ .#{spinner.$spinnerWrapClassBase} {
164
+ margin: unset;
165
+ }
166
+ }
167
+
168
+ // Fluid
169
+ &--fluid {
170
+ width: 100%;
171
+ }
172
+
173
+ // With Icon
174
+ &__icon-wrap svg,
175
+ ::slotted([slot='iconBefore']),
176
+ ::slotted([slot='iconAfter']) {
177
+ @extend %icon-size;
178
+ }
179
+ }
@@ -0,0 +1,129 @@
1
+ @use '../utils/constants.scss';
2
+ @use '../utils/tokens.scss' as tokens;
3
+
4
+ $buttonBaseClass: '#{constants.$prefix}button';
5
+ $buttonLoadingSpinner: '#{$buttonBaseClass}__loading-spinner';
6
+
7
+ $buttonIconSizeVarName: '--#{constants.$prefix}-comp-btn-size-icon';
8
+ $buttonPaddingYVarName: '--#{constants.$prefix}-comp-btn-space-padding-y';
9
+ $buttonPaddingXVarName: '--#{constants.$prefix}-comp-btn-space-padding-x';
10
+
11
+ $btn-appearance-kind-var-prefix: '-#{constants.$prefix}-comp-btn-color-';
12
+
13
+ $appearancesAndKinds: (
14
+ 'accent': (
15
+ 'filled': (
16
+ 'background': tokens.$bm-comp-btn-color-accent-filled-bg,
17
+ 'color': tokens.$bm-comp-btn-color-accent-filled-fg,
18
+ 'border-color': tokens.$bm-comp-btn-color-accent-filled-border,
19
+ ),
20
+ 'outline': (
21
+ 'background': tokens.$bm-comp-btn-color-accent-outline-bg,
22
+ 'color': tokens.$bm-comp-btn-color-accent-outline-fg,
23
+ 'border-color': tokens.$bm-comp-btn-color-accent-outline-border,
24
+ ),
25
+ 'ghost': (
26
+ 'background': tokens.$bm-comp-btn-color-accent-ghost-bg,
27
+ 'color': tokens.$bm-comp-btn-color-accent-ghost-fg,
28
+ 'border-color': tokens.$bm-comp-btn-color-accent-ghost-border,
29
+ ),
30
+ 'bare': (
31
+ 'background': tokens.$bm-comp-btn-color-accent-bare-bg,
32
+ 'color': tokens.$bm-comp-btn-color-accent-bare-fg,
33
+ 'border-color': tokens.$bm-comp-btn-color-accent-bare-border,
34
+ ),
35
+ ),
36
+ 'neutral': (
37
+ 'filled': (
38
+ 'background': tokens.$bm-comp-btn-color-neutral-filled-bg,
39
+ 'color': tokens.$bm-comp-btn-color-neutral-filled-fg,
40
+ 'border-color': tokens.$bm-comp-btn-color-neutral-filled-border,
41
+ ),
42
+ 'outline': (
43
+ 'background': tokens.$bm-comp-btn-color-neutral-outline-bg,
44
+ 'color': tokens.$bm-comp-btn-color-neutral-outline-fg,
45
+ 'border-color': tokens.$bm-comp-btn-color-neutral-outline-border,
46
+ ),
47
+ 'ghost': (
48
+ 'background': tokens.$bm-comp-btn-color-neutral-ghost-bg,
49
+ 'color': tokens.$bm-comp-btn-color-neutral-ghost-fg,
50
+ 'border-color': tokens.$bm-comp-btn-color-neutral-ghost-border,
51
+ ),
52
+ 'bare': (
53
+ 'background': tokens.$bm-comp-btn-color-neutral-bare-bg,
54
+ 'color': tokens.$bm-comp-btn-color-neutral-bare-fg,
55
+ 'border-color': tokens.$bm-comp-btn-color-neutral-bare-border,
56
+ ),
57
+ ),
58
+ 'neutral-subtle': (
59
+ 'filled': (
60
+ 'background': tokens.$bm-comp-btn-color-neutral-subtle-filled-bg,
61
+ 'color': tokens.$bm-comp-btn-color-neutral-subtle-filled-fg,
62
+ 'border-color': tokens.$bm-comp-btn-color-neutral-subtle-filled-border,
63
+ ),
64
+ 'outline': (
65
+ 'background': tokens.$bm-comp-btn-color-neutral-subtle-outline-bg,
66
+ 'color': tokens.$bm-comp-btn-color-neutral-subtle-outline-fg,
67
+ 'border-color': tokens.$bm-comp-btn-color-neutral-subtle-outline-border,
68
+ ),
69
+ 'ghost': (
70
+ 'background': tokens.$bm-comp-btn-color-neutral-subtle-ghost-bg,
71
+ 'color': tokens.$bm-comp-btn-color-neutral-subtle-ghost-fg,
72
+ 'border-color': tokens.$bm-comp-btn-color-neutral-subtle-ghost-border,
73
+ ),
74
+ 'bare': (
75
+ 'background': tokens.$bm-comp-btn-color-neutral-subtle-bare-bg,
76
+ 'color': tokens.$bm-comp-btn-color-neutral-subtle-bare-fg,
77
+ 'border-color': tokens.$bm-comp-btn-color-neutral-subtle-bare-border,
78
+ ),
79
+ ),
80
+ 'destructive': (
81
+ 'filled': (
82
+ 'background': tokens.$bm-comp-btn-color-destructive-filled-bg,
83
+ 'color': tokens.$bm-comp-btn-color-destructive-filled-fg,
84
+ 'border-color': tokens.$bm-comp-btn-color-destructive-filled-border,
85
+ ),
86
+ 'outline': (
87
+ 'background': tokens.$bm-comp-btn-color-destructive-outline-bg,
88
+ 'color': tokens.$bm-comp-btn-color-destructive-outline-fg,
89
+ 'border-color': tokens.$bm-comp-btn-color-destructive-outline-border,
90
+ ),
91
+ 'ghost': (
92
+ 'background': tokens.$bm-comp-btn-color-destructive-ghost-bg,
93
+ 'color': tokens.$bm-comp-btn-color-destructive-ghost-fg,
94
+ 'border-color': tokens.$bm-comp-btn-color-destructive-ghost-border,
95
+ ),
96
+ 'bare': (
97
+ 'background': tokens.$bm-comp-btn-color-destructive-bare-bg,
98
+ 'color': tokens.$bm-comp-btn-color-destructive-bare-fg,
99
+ 'border-color': tokens.$bm-comp-btn-color-destructive-bare-border,
100
+ ),
101
+ ),
102
+ );
103
+
104
+ $sizes: (
105
+ 'sm': (
106
+ 'min-width': tokens.$bm-comp-btn-size-sm-width,
107
+ 'min-height': tokens.$bm-comp-btn-size-sm-height,
108
+ 'icon': tokens.$bm-comp-btn-size-sm-icon,
109
+ 'padding-y': tokens.$bm-comp-btn-space-sm-y,
110
+ 'padding-x': tokens.$bm-comp-btn-space-sm-x,
111
+ 'font': tokens.$bm-comp-btn-typo-sm,
112
+ ),
113
+ 'md': (
114
+ 'min-width': tokens.$bm-comp-btn-size-md-width,
115
+ 'min-height': tokens.$bm-comp-btn-size-md-height,
116
+ 'icon': tokens.$bm-comp-btn-size-md-icon,
117
+ 'padding-y': tokens.$bm-comp-btn-space-md-y,
118
+ 'padding-x': tokens.$bm-comp-btn-space-md-x,
119
+ 'font': tokens.$bm-comp-btn-typo-md,
120
+ ),
121
+ 'lg': (
122
+ 'min-width': tokens.$bm-comp-btn-size-lg-width,
123
+ 'min-height': tokens.$bm-comp-btn-size-lg-height,
124
+ 'icon': tokens.$bm-comp-btn-size-lg-icon,
125
+ 'padding-y': tokens.$bm-comp-btn-space-lg-y,
126
+ 'padding-x': tokens.$bm-comp-btn-space-lg-x,
127
+ 'font': tokens.$bm-comp-btn-typo-lg,
128
+ ),
129
+ );
@@ -0,0 +1,232 @@
1
+ @use 'sass:map';
2
+ @use '../utils/constants.scss';
3
+ @use '../utils/mixins.scss' as mixins;
4
+ @use '../utils/tokens.scss' as tokens;
5
+
6
+ @import '../../../../tokens/src/lib/components/Card';
7
+
8
+ $cardBaseClass: '#{constants.$prefix}card';
9
+
10
+ @mixin backdrop-overlay($color) {
11
+ position: relative;
12
+
13
+ &::before {
14
+ content: '';
15
+ position: absolute;
16
+ top: 0;
17
+ left: 0;
18
+ right: 0;
19
+ bottom: 0;
20
+
21
+ background: $color;
22
+
23
+ background-size: cover;
24
+ background-repeat: no-repeat;
25
+ z-index: 1;
26
+ pointer-events: none;
27
+ }
28
+ }
29
+
30
+ @mixin media-overlays {
31
+ &__overlay-top,
32
+ &__overlay-middle,
33
+ &__overlay-bottom {
34
+ position: absolute;
35
+ left: 0;
36
+ right: 0;
37
+ z-index: 2;
38
+ }
39
+
40
+ &__overlay-top {
41
+ top: 0;
42
+ }
43
+
44
+ &__overlay-middle {
45
+ top: 50%;
46
+ transform: translateY(-50%);
47
+ }
48
+
49
+ &__overlay-bottom {
50
+ bottom: 0;
51
+ }
52
+ }
53
+
54
+ $cardDensity: (
55
+ density-sm: (
56
+ gap: tokens.$bm-comp-card-space-gap-sm,
57
+ inset: tokens.$bm-comp-card-space-pad-sm,
58
+ ),
59
+ density-md: (
60
+ gap: tokens.$bm-comp-card-space-gap-md,
61
+ inset: tokens.$bm-comp-card-space-pad-md,
62
+ ),
63
+ density-lg: (
64
+ gap: tokens.$bm-comp-card-space-gap-lg,
65
+ inset: tokens.$bm-comp-card-space-pad-lg,
66
+ ),
67
+ );
68
+
69
+ // Main Card component
70
+ .#{$cardBaseClass} {
71
+ display: flex;
72
+ flex-direction: column;
73
+ overflow: hidden;
74
+
75
+ &--default-background {
76
+ background: tokens.$bm-comp-card-color-bg;
77
+ }
78
+ &--default-shadow {
79
+ box-shadow: tokens.$bm-comp-card-shadow;
80
+ }
81
+ &--default-border {
82
+ border-color: tokens.$bm-comp-card-color-border;
83
+ }
84
+ &--default-border-radius {
85
+ border-radius: tokens.$bm-comp-card-radius-outer;
86
+ }
87
+ }
88
+
89
+ // Card.Content
90
+ .#{$cardBaseClass}__content {
91
+ display: flex;
92
+ flex-direction: column;
93
+
94
+ @each $density, $values in $cardDensity {
95
+ &--#{$density} {
96
+ gap: map.get($values, gap);
97
+ padding: map.get($values, inset);
98
+ }
99
+ }
100
+ }
101
+
102
+ // Card.Header
103
+ .#{$cardBaseClass}__header {
104
+ display: flex;
105
+ flex-direction: row;
106
+ gap: tokens.$bm-comp-card-space-header-gap;
107
+
108
+ &__content-before {
109
+ order: 1;
110
+ display: flex;
111
+ gap: tokens.$bm-comp-card-space-header-actions-gap;
112
+ color: tokens.$bm-comp-card-color-heading;
113
+ }
114
+
115
+ &__heading {
116
+ order: 2;
117
+ display: flex;
118
+ flex-direction: column;
119
+ flex: 1;
120
+ min-width: 0;
121
+
122
+ font: tokens.$bm-comp-card-typo-heading;
123
+ color: tokens.$bm-comp-card-color-heading;
124
+
125
+ // ensure anything slotted will always come after Eyebrow, Text, Supporting text
126
+ * {
127
+ order: 999;
128
+ }
129
+
130
+ &__eyebrow {
131
+ order: 0;
132
+ display: flex;
133
+ font: tokens.$bm-comp-card-typo-eyebrow;
134
+ color: tokens.$bm-comp-card-color-eyebrow;
135
+ gap: tokens.$bm-comp-card-space-header-actions-gap;
136
+ overflow: hidden;
137
+ text-overflow: ellipsis;
138
+ white-space: nowrap;
139
+ }
140
+
141
+ &__text {
142
+ order: 1;
143
+ display: flex;
144
+ }
145
+
146
+ &__supporting-text {
147
+ order: 2;
148
+ display: flex;
149
+ color: tokens.$bm-comp-card-color-supporting;
150
+ font: tokens.$bm-comp-card-typo-supporting;
151
+ }
152
+ }
153
+
154
+ &__content-after {
155
+ order: 3;
156
+ display: flex;
157
+ padding-top: tokens.$bm-sem-space-12;
158
+ justify-content: flex-end;
159
+ align-items: flex-start;
160
+ gap: tokens.$bm-comp-card-space-header-actions-gap;
161
+ align-self: stretch;
162
+ color: tokens.$bm-comp-card-color-icon;
163
+ }
164
+ }
165
+
166
+ .#{$cardBaseClass}__media-below {
167
+ border-radius: tokens.$bm-comp-card-radius-inner;
168
+ }
169
+
170
+ .#{$cardBaseClass}__media-above,
171
+ .#{$cardBaseClass}__media-below {
172
+ display: flex;
173
+ overflow: hidden;
174
+ width: 100%;
175
+ isolation: isolate;
176
+
177
+ @each $color in black, white {
178
+ @each $opacity in 10, 20, 30, 40 {
179
+ &--overlay-color-#{$color}-#{$opacity} {
180
+ @include backdrop-overlay(
181
+ var(--#{constants.$prefix}sem-color-overlay-#{$color}-#{$opacity})
182
+ );
183
+ }
184
+ }
185
+ }
186
+
187
+ @include media-overlays;
188
+ }
189
+
190
+ // Card.Body
191
+ .#{$cardBaseClass}__body {
192
+ display: flex;
193
+ flex-direction: column;
194
+ color: tokens.$bm-comp-card-color-body;
195
+ font: tokens.$bm-comp-card-typo-body;
196
+ gap: tokens.$bm-sem-space-100;
197
+ }
198
+
199
+ // Card.Footer
200
+ .#{$cardBaseClass}__footer {
201
+ display: flex;
202
+ gap: tokens.$bm-sem-space-50;
203
+ flex-direction: column;
204
+
205
+ &__actions {
206
+ display: flex;
207
+ padding-top: tokens.$bm-comp-card-space-footer-actions-top;
208
+ gap: tokens.$bm-comp-card-space-footer-actions-gap;
209
+ flex-shrink: 0;
210
+ flex-wrap: wrap;
211
+ align-items: center;
212
+ align-content: center;
213
+
214
+ &--start {
215
+ justify-content: flex-start;
216
+ }
217
+
218
+ &--end {
219
+ justify-content: flex-end;
220
+ }
221
+
222
+ &--spaceBetween {
223
+ justify-content: space-between;
224
+ }
225
+
226
+ &--stacked {
227
+ justify-content: center;
228
+ flex-direction: column;
229
+ gap: tokens.$bm-comp-card-space-footer-actions-gap-stacked;
230
+ }
231
+ }
232
+ }