@wwtdev/bsds-css 1.0.1 → 1.1.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/README.md CHANGED
@@ -28,14 +28,15 @@ module.exports = {
28
28
 
29
29
  ### 2. Tailwind CSS Directives
30
30
 
31
- Because our CSS Framework includes its own reset and default styles, you will only need to include the `utilities` directive.
31
+ To prevent conflicts with our CSS Framework, only include the `base` and `utilities` directives.
32
+
33
+ Since our CSS has its own reset and default styles, we prevent Tailwind's `base` reset styles from loading, via a setting in our WWT Preset. The only styles that will be used from `base` are Tailwind CSS variables, which are needed in order to ensure all Tailwind classes work as expected.
32
34
 
33
35
  ```css
36
+ @tailwind base;
34
37
  @tailwind utilities;
35
38
  ```
36
39
 
37
- > Tailwind's base and component directives will cause conflicts with the CSS Framework.
38
-
39
40
  Once you have completed the Tailwind installation steps, you can use the classes generated from the preset.
40
41
 
41
42
  ### Browser Support
@@ -0,0 +1,111 @@
1
+ @mixin accordions() {
2
+ .bs-accordion {
3
+ --accordion-link-color: var(--bs-purple-400);
4
+ --accordion-link-outline-color: var(--bs-blue-400);
5
+ --accordion-outline-color: transparent;
6
+ --accordion-padding-inline: 0;
7
+ --accordion-text-size: var(--bs-text-sm);
8
+ border-block: 1px solid var(--bs-border);
9
+ display: block;
10
+ }
11
+
12
+ @media (min-width: 957px) {
13
+ .bs-accordion {
14
+ --accordion-padding-inline: var(--bs-space-2);
15
+ --accordion-text-size: var(--bs-text-base);
16
+ }
17
+ }
18
+
19
+ /* Accordion Panel (Icon, Title, Caret) */
20
+
21
+ .bs-accordion :where(header button) {
22
+ align-items: center;
23
+ background-color: var(--bs-bg-base);
24
+ border: 0px solid transparent;
25
+ border-radius: .25rem;
26
+ color: var(--bs-ink-base);
27
+ cursor: pointer;
28
+ display: grid;
29
+ font-size: var(--accordion-text-size);
30
+ font-weight: var(--bs-font-normal);
31
+ grid-template-columns: minmax(0px, auto) minmax(0px, 1fr) minmax(0px, auto);
32
+ grid-template-areas: "start main end";
33
+ line-height: 1.5;
34
+ outline: 2px solid var(--accordion-outline-color);
35
+ padding-block: var(--bs-space-f-2);
36
+ padding-inline: var(--accordion-padding-inline);
37
+ width: 100%;
38
+ }
39
+
40
+ .bs-accordion :where(header button:focus-visible) {
41
+ --accordion-outline-color: var(--bs-blue-400);
42
+ }
43
+
44
+ .bs-accordion :where(header button) > * {
45
+ font-size: inherit;
46
+ font-weight: inherit;
47
+ line-height: inherit;
48
+ }
49
+
50
+ .bs-accordion :where(header button) :where([data-position]) {
51
+ width: var(--accordion-text-size);
52
+ }
53
+
54
+ .bs-accordion :where(header button) > :where([data-position="start"]) {
55
+ grid-area: start;
56
+ margin-right: var(--bs-space-2);
57
+ }
58
+
59
+ .bs-accordion :where(header button) > :where([data-position="end"]) {
60
+ grid-area: end;
61
+ transform: rotate(0);
62
+ transition: transform 250ms ease-out;
63
+ }
64
+
65
+ .bs-accordion :where(header[data-open]:not([data-open="false"])) :where([data-position="end"]) {
66
+ transform: rotate(180deg);
67
+ }
68
+
69
+ .bs-accordion :where(header button) > :where(h2, h3, h4, h5) {
70
+ grid-area: main;
71
+ margin-right: var(--bs-space-2);
72
+ text-align: left;
73
+ }
74
+
75
+ .bs-accordion :where(header button) > :where(h2, h3, h4, h5) :where(*) {
76
+ vertical-align: middle;
77
+ }
78
+
79
+ @media (min-width: 957px) {
80
+ .bs-accordion :where(header button) > :where(h2, h3, h4, h5) {
81
+ margin-right: var(--bs-space-3);
82
+ }
83
+ }
84
+
85
+ /* Accordion Content (the collapsible / expandible part) */
86
+
87
+ .bs-accordion :where(.bs-accordion-content) {
88
+ display: grid;
89
+ font-size: var(--accordion-text-size);
90
+ grid-template-rows: 0fr;
91
+ overflow: hidden;
92
+ padding-inline: var(--accordion-padding-inline);
93
+ transition: grid-template-rows 250ms ease-out;
94
+ }
95
+
96
+ .bs-accordion :where(.bs-accordion-content) > :where(:first-child) {
97
+ overflow: hidden;
98
+ }
99
+
100
+ .bs-accordion :where(.bs-accordion-content[data-open]:not([data-open="false"])) {
101
+ grid-template-rows: 1fr;
102
+ padding-block-end: var(--bs-space-f-2);
103
+ }
104
+
105
+ /* Accordion Group */
106
+ :where(.bs-accordion[data-stacked]) + .bs-accordion:where([data-stacked]) {
107
+ border-block-start-color: transparent;
108
+ }
109
+
110
+ }
111
+
@@ -0,0 +1,66 @@
1
+ @mixin banner() {
2
+ .bs-banner {
3
+ background-color: var(--bs-bg-invert-subtle);
4
+ color: var(--bs-gray-100);
5
+ display: flex;
6
+ justify-content: center;
7
+ padding-bottom: 1rem;
8
+ padding-left: 1.25rem;
9
+ padding-right: 1.25rem;
10
+ padding-top: 1rem;
11
+ }
12
+
13
+ .bs-banner:where([data-dismissed]) {
14
+ display: none;
15
+ }
16
+
17
+ :where(.dark) .bs-banner {
18
+ color: var(--bs-black);
19
+ }
20
+
21
+ .bs-banner :where(.bs-banner-content) {
22
+ align-items: center;
23
+ display: flex;
24
+ /* Content locks at globally configured width */
25
+ max-width: var(--bs-content-max-width);
26
+ width: 100%;
27
+ }
28
+
29
+ .bs-banner :where(.bs-banner-content .bs-banner-warning-icon) {
30
+ /* Do not display warning icon on smaller screens */
31
+ display: none;
32
+ margin-right: 0.625rem;
33
+ }
34
+
35
+ .bs-banner :where(.bs-banner-content p) {
36
+ flex-grow: 1;
37
+ padding-right: 1.25rem;
38
+ }
39
+
40
+ .bs-banner :where(.bs-banner-content p a) {
41
+ color: var(--bs-pink-200);
42
+ text-decoration: none;
43
+ }
44
+
45
+ :where(.dark) .bs-banner :where(.bs-banner-content p a) {
46
+ color: var(--bs-pink-500);
47
+ }
48
+
49
+ .bs-banner :where(.bs-banner-content p a:hover) {
50
+ text-decoration: underline;
51
+ }
52
+
53
+ .bs-banner :where(.bs-banner-content button) {
54
+ background-color: inherit;
55
+ color: inherit;
56
+ cursor: pointer;
57
+ }
58
+
59
+ @media (min-width: 957px) {
60
+ .bs-banner :where(.bs-banner-content .bs-banner-warning-icon) {
61
+ display: inline-flex;
62
+ }
63
+ }
64
+
65
+ }
66
+
@@ -135,9 +135,13 @@
135
135
  line-height: 150%;
136
136
  }
137
137
  .bs-button:where([data-text]):hover {
138
+ color: var(--bs-blue-400);
138
139
  background-color: transparent;
139
140
  text-decoration: underline;
140
141
  }
142
+ .bs-button:where([data-text]):has(svg):hover {
143
+ text-decoration: none;
144
+ }
141
145
  .bs-button:where([data-text]):active {
142
146
  box-shadow: none;
143
147
  }
@@ -5,7 +5,6 @@
5
5
  align-items: center;
6
6
  font-size: var(--bs-text-base);
7
7
  font-weight: 400;
8
- gap: 0.5em;
9
8
  line-height: 115%;
10
9
  }
11
10
 
@@ -21,6 +20,15 @@
21
20
  width: auto;
22
21
  }
23
22
 
23
+ /* not using gap on .bs-boolean due to dead click zone */
24
+ .bs-boolean label {
25
+ padding-inline-end: 0.5em;
26
+ }
27
+
28
+ .bs-boolean input + label {
29
+ padding-inline: 0.5em 0;
30
+ }
31
+
24
32
  .bs-boolean:where([data-size='sm']),
25
33
  .bs-boolean:where([data-size='sm']) label {
26
34
  font-size: var(--bs-text-xs);
@@ -29,7 +37,7 @@
29
37
 
30
38
  /* Checkbox & Radio Input */
31
39
 
32
- :where(input[type^='checkbox'], input[type^='radio']) {
40
+ :where(input[type='checkbox'], input[type='radio']) {
33
41
  --box-shadow: var(--bs-ink-base);
34
42
 
35
43
  appearance: none;
@@ -43,20 +51,22 @@
43
51
  width: 1rem;
44
52
  }
45
53
 
46
- :where(input[type^='checkbox'], input[type^='radio']):focus {
54
+ :where(input[type='checkbox'], input[type='radio']):focus-visible {
47
55
  box-shadow: inset 0 0 0 0.125rem var(--box-shadow),
48
56
  0 0 0 2px var(--offset-color, var(--bs-bg-base)),
49
57
  0 0 0 4px var(--outline-color, var(--bs-blue-400));
58
+ outline: 2px solid transparent;
50
59
  }
51
60
 
52
- :where(input[type^='checkbox']) {
61
+ :where(input[type='checkbox']) {
53
62
  border-radius: 0.125rem;
54
63
  }
55
64
 
56
- :where(input[type^='radio']) {
65
+ :where(input[type='radio']) {
57
66
  border-radius: 50%;
58
67
  }
59
68
 
69
+ /* Checkbox's checkmark */
60
70
  input:where([type='checkbox'])::before {
61
71
  --filled-size: 1rem;
62
72
  --check-fill-color: var(--bs-blue-400);
@@ -69,7 +79,7 @@ input:where([type='checkbox'])::before {
69
79
  width: var(--filled-size);
70
80
  }
71
81
 
72
- input:where([type^='checkbox'])::after {
82
+ input:where([type='checkbox'])::after {
73
83
  border: solid var(--bs-white);
74
84
  border-width: 0 0.125rem 0.125rem 0;
75
85
  content: '';
@@ -83,6 +93,15 @@ input:where([type^='checkbox'])::after {
83
93
  width: 0.375em;
84
94
  }
85
95
 
96
+ input:where([type='checkbox']):where(:indeterminate)::after {
97
+ border: none;
98
+ background-color: var(--bs-white);
99
+ height: 0.125rem;
100
+ transform: translate(-50%, -0.0625rem) rotate(0deg);
101
+ width: 0.625em;
102
+ }
103
+
104
+ /* Radio's dot */
86
105
  input:where([type='radio'])::before {
87
106
  --filled-size: 1rem;
88
107
  --radio-fill-color: var(--bs-blue-400);
@@ -113,8 +132,8 @@ input:where([type='radio'])::after {
113
132
  width: var(--inner-size);
114
133
  }
115
134
 
116
- input:where([type='checkbox']:checked, [type='radio']:checked)::before,
117
- input:where([type='checkbox']:checked, [type='radio']:checked)::after {
135
+ input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::before,
136
+ input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::after {
118
137
  visibility: visible;
119
138
  }
120
139
 
@@ -127,6 +146,11 @@ input:where([type='checkbox']:checked, [type='radio']:checked)::after {
127
146
  width: 0.3125rem;
128
147
  }
129
148
 
149
+ .bs-boolean:where([data-size='sm']) input[type='checkbox']:where(:indeterminate)::after {
150
+ height: 0.125rem;
151
+ width: .75em;
152
+ }
153
+
130
154
  .bs-boolean:where([data-size='sm']) input[type='radio']::after {
131
155
  --inner-size: 0.25rem;
132
156
  }
@@ -139,7 +163,8 @@ input:where([type='checkbox'], [type='radio']):disabled {
139
163
  background-color: transparent;
140
164
  }
141
165
 
142
- input:where([type='checkbox']):checked:disabled::before {
166
+ input:where([type='checkbox']):checked:disabled::before,
167
+ input:where([type='checkbox']):indeterminate:disabled::before {
143
168
  --check-fill-color: var(--bs-gray-400);
144
169
  }
145
170
 
@@ -150,7 +175,7 @@ input:where([type='radio']):checked:disabled::before {
150
175
 
151
176
  /* Error state */
152
177
 
153
- input:where([type^='checkbox'], [type^='radio'])[data-error] {
178
+ input:where([type='checkbox'], [type='radio'])[data-error] {
154
179
  --box-shadow: var(--bs-red-400);
155
180
  }
156
181
 
@@ -4,6 +4,7 @@
4
4
  font-size: var(--bs-text-xs);
5
5
  font-weight: 400;
6
6
  text-align: right;
7
+ white-space: nowrap;
7
8
  }
8
9
 
9
10
  :where([disabled], [data-disabled]) + .bs-character-count,
@@ -1,19 +1,20 @@
1
1
  @mixin form-elements() {
2
2
  :where([data-required]) {
3
- color: var(--bs-red-400);
3
+ color: var(--bs-red-500);
4
+ font-weight: var(--bs-font-bold, 600);
4
5
  }
5
6
 
6
7
  :where([data-disabled], [data-disabled] [data-required]) {
7
8
  color: var(--bs-gray-400);
8
9
  }
9
10
 
10
- :where(label + input, label > input):not([type^='checkbox'], [type^='radio']),
11
+ :where(label + input, label > input):where(:not([type='checkbox'], [type='radio'])),
11
12
  :where(label + textarea, label > textarea),
12
13
  :where(label + select, label > select) {
13
14
  margin-top: 0.25rem;
14
15
  }
15
16
 
16
- input:not([type^='checkbox'], [type^='radio'], [type^='file'], [type^='range']),
17
+ input:where(:not([type='checkbox'], [type='radio'], [type='file'], [type='range'])),
17
18
  textarea, select {
18
19
  appearance: none;
19
20
  background-color: var(--input-bg, var(--bs-bg-base));
@@ -22,27 +23,35 @@ textarea, select {
22
23
  color: var(--bs-ink-base);
23
24
  font-size: var(--bs-text-base);
24
25
  font-weight: 400;
26
+ height: 2.5rem;
25
27
  line-height: var(--bs-leading-base);
26
- min-height: 40px;
27
- padding: 0.5rem 0.75rem;
28
+ min-height: 2.5rem;
29
+ padding-inline: 0.75rem;
28
30
  width: 100%;
29
31
  }
30
32
 
33
+ textarea {
34
+ height: auto;
35
+ padding-block: 0.5rem;
36
+ resize: vertical;
37
+ }
38
+
31
39
  /* Generally applicable (all input types) */
32
40
  :is(input, textarea, select)::placeholder {
33
41
  color: var(--bs-violet-200);
34
42
  opacity: 1;
35
43
  }
36
44
 
37
- :is(input, textarea, select):focus {
45
+
46
+ :is(input:where(:not([type='checkbox'], [type='radio']), textarea, select):where(:focus)) {
38
47
  box-shadow: 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
39
48
  0 0 0 4px var(--outline-color, var(--bs-blue-400));
40
49
  outline: 2px solid transparent;
41
50
  }
42
- :where(.box) :is(input, textarea, select):focus {
51
+ :where(.box) :is(input, textarea, select):where(:focus) {
43
52
  --offset-color: var(--bs-bg-subtle);
44
53
  }
45
- :where(.box[data-invert]) :is(input, textarea, select):focus {
54
+ :where(.box[data-invert]) :is(input, textarea, select):where(:focus) {
46
55
  --offset-color: var(--bs-bg-invert);
47
56
  }
48
57
 
@@ -50,7 +59,7 @@ textarea, select {
50
59
  --outline-color: var(--bs-red-200);
51
60
  }
52
61
 
53
- :is(input, textarea, select):disabled {
62
+ :is(input:where(:not([type='checkbox'],[type='radio'])), textarea, select):where(:disabled) {
54
63
  background-color: var(--bs-gray-200);
55
64
  border-color: var(--bs-gray-400);
56
65
  color: var(--bs-gray-400);
@@ -2,7 +2,8 @@
2
2
  .bs-field-details {
3
3
  display: flex;
4
4
  justify-content: space-between;
5
- align-items: center;
5
+ align-items: flex-start;
6
+ gap: var(--bs-space-2);
6
7
  padding: 0 0.75rem;
7
8
  margin-top: 0.5rem;
8
9
  }
@@ -11,7 +11,7 @@
11
11
  }
12
12
 
13
13
  :where([data-required]) {
14
- color: var(--bs-red-400);
14
+ color: var(--bs-red-500);
15
15
  }
16
16
 
17
17
  :where(label[data-disabled], [data-disabled] [data-required], [data-disabled] label) {
@@ -21,10 +21,6 @@
21
21
  --inner-text-padding: 0.375rem;
22
22
  }
23
23
 
24
- :where(.dark) .bs-switch:where(:not([data-disabled])) {
25
- --switch-background: var(--bs-blue-400);
26
- }
27
-
28
24
  .bs-switch input,
29
25
  .bs-switch:where([data-size="sm"]) input {
30
26
  cursor: pointer;
@@ -48,6 +44,11 @@
48
44
  height: calc(var(--ball-diameter) + var(--offset) * 2);
49
45
  }
50
46
 
47
+ .bs-switch input:where(:checked) ~ span,
48
+ .bs-switch:where([aria-pressed]):where(:not([aria-pressed="false"])) span {
49
+ --switch-background: var(--bs-blue-400);
50
+ }
51
+
51
52
  /* Toggle "ball" */
52
53
  .bs-switch span::before {
53
54
  background-color: var(--ball-background);
@@ -69,7 +70,6 @@
69
70
  transform: translate(var(--ball-diameter), -50%);
70
71
  }
71
72
 
72
-
73
73
  .bs-switch input:where(:checked) ~ span:where([data-inner-on-label][data-inner-off-label])::before,
74
74
  .bs-switch:where([aria-pressed]):where(:not([aria-pressed="false"])) span:where([data-inner-on-label][data-inner-off-label])::before {
75
75
  transform: translate(calc(var(--ball-diameter) + var(--inner-text-width)), -50%);
@@ -110,15 +110,15 @@
110
110
 
111
111
  /* Focus state */
112
112
 
113
- .bs-switch:where(:focus-within) span {
113
+ .bs-switch :where(input:focus-visible) + span {
114
114
  box-shadow: 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
115
115
  0 0 0 4px var(--outline-color, var(--bs-blue-400));
116
116
  outline: 2px solid transparent;
117
117
  }
118
- :where(.box) .bs-switch:where(:focus-within) span {
118
+ :where(.box) .bs-switch :where(input:focus-visible) + span {
119
119
  --offset-color: var(--bs-bg-subtle);
120
120
  }
121
- :where(.box[data-invert]) .bs-switch:where(:focus-within) span {
121
+ :where(.box[data-invert]) .bs-switch :where(input:focus-visible) + span {
122
122
  --offset-color: var(--bs-bg-invert);
123
123
  }
124
124
 
@@ -0,0 +1,204 @@
1
+ @mixin toast() {
2
+ /* Base Toast Styles */
3
+ .bs-toast {
4
+ background-color: var(--bs-white);
5
+ border-top: 4px solid var(--bs-blue-400);
6
+ bottom: 1.5rem;
7
+ box-shadow: var(--bs-shadow-contentMedium);
8
+ left: 0;
9
+ margin-left: 1.5rem;
10
+ margin-right: 1.5rem;
11
+ opacity: 0;
12
+ position: fixed;
13
+ right: 0;
14
+ transform: translateY(calc(100% + 1.5rem));
15
+ /* Clamp width for mobile -> full screen */
16
+ width: clamp(17rem, calc(100vw - 3rem), 25rem);
17
+ z-index: 999;
18
+ }
19
+
20
+ .bs-toast[data-stacked] {
21
+ bottom: auto;
22
+ left: auto;
23
+ position: static;
24
+ right: auto;
25
+ z-index: auto;
26
+ }
27
+
28
+ /* Mobile - Toast comes up from bottom */
29
+ @keyframes slideDown {
30
+ 0% {
31
+ opacity: 1;
32
+ transform: translateY(0);
33
+ }
34
+ 100% {
35
+ opacity: 0;
36
+ transform: translateY(calc(100% + 1.5rem));
37
+ }
38
+ }
39
+
40
+ @keyframes slideUp {
41
+ 0% {
42
+ opacity: 0;
43
+ transform: translateY(calc(100% + 1.5rem));
44
+ }
45
+ 100% {
46
+ opacity: 1;
47
+ transform: translateY(0);
48
+ }
49
+ }
50
+
51
+ /* Dark mode toast */
52
+ :where(.dark) .bs-toast {
53
+ background-color: var(--bs-navy-400);
54
+ }
55
+
56
+ .bs-toast:where([data-shown]) {
57
+ /* Small delay on load to alow for HTML element to exist */
58
+ animation-delay: 10ms;
59
+ animation-duration: 200ms;
60
+ animation-fill-mode: forwards;
61
+ animation-name: slideUp;
62
+ animation-timing-function: ease;
63
+ }
64
+
65
+ .bs-toast:where([data-dismissed]) {
66
+ animation-duration: 200ms;
67
+ animation-fill-mode: forwards;
68
+ animation-name: slideDown;
69
+ animation-timing-function: ease;
70
+ }
71
+
72
+ .bs-toast :where(.bs-toast-header) {
73
+ align-items: center;
74
+ color: var(--bs-ink-base);
75
+ display: flex;
76
+ gap: 0.5rem;
77
+ padding-left: 1rem;
78
+ padding-right: 1rem;
79
+ padding-top: 1rem;
80
+ }
81
+
82
+ .bs-toast :where(.bs-toast-header .bs-toast-header-icon) {
83
+ color: var(--bs-blue-400);
84
+ }
85
+
86
+ .bs-toast :where(h5) {
87
+ font-weight: 400;
88
+ }
89
+
90
+ .bs-toast :where(.bs-toast-content) {
91
+ border-bottom: 1px solid var(--bs-border);
92
+ color: var(--bs-ink-light);
93
+ padding-bottom: 1rem;
94
+ padding-left: 1rem;
95
+ padding-right: 1rem;
96
+ padding-top: 0.25rem;
97
+ }
98
+
99
+ .bs-toast :where(.bs-toast-actions) {
100
+ /* Mobile - Buttons will be stacked */
101
+ display: flex;
102
+ flex-direction: column-reverse;
103
+ gap: 1rem;
104
+ padding-bottom: 0.5rem;
105
+ padding-left: 1rem;
106
+ padding-right: 1rem;
107
+ padding-top: 0.5rem;
108
+ }
109
+
110
+ /* Warning Toast Styles */
111
+ .bs-toast:where([data-variant^='warning']) {
112
+ border-top: 4px solid var(--bs-orange-warning);
113
+ }
114
+
115
+ .bs-toast:where([data-variant^='warning']) :where(.bs-toast-header .bs-toast-header-icon) {
116
+ color: var(--bs-orange-warning);
117
+ }
118
+
119
+ /* Positive Toast Styles */
120
+ .bs-toast:where([data-variant^='positive']) {
121
+ border-top: 4px solid var(--bs-purple-400);
122
+ }
123
+
124
+ .bs-toast:where([data-variant^='positive']) :where(.bs-toast-header .bs-toast-header-icon) {
125
+ color: var(--bs-purple-400);
126
+ }
127
+
128
+ :where(.dark) .bs-toast:where([data-variant^='positive']) {
129
+ border-top: 4px solid var(--bs-purple-200);
130
+ }
131
+
132
+ :where(.dark) .bs-toast:where([data-variant^='positive']) :where(.bs-toast-header .bs-toast-header-icon) {
133
+ color: var(--bs-purple-200);
134
+ }
135
+
136
+ /* Negative Toast Styles */
137
+ .bs-toast:where([data-variant^='negative']) {
138
+ border-top: 4px solid var(--bs-red-400);
139
+ }
140
+
141
+ .bs-toast:where([data-variant^='negative']) :where(.bs-toast-header .bs-toast-header-icon) {
142
+ color: var(--bs-red-400);
143
+ }
144
+
145
+ @media (min-width: 440px) {
146
+
147
+ .bs-toast {
148
+ left: auto;
149
+ margin-left: 0;
150
+ margin-right: 0;
151
+ opacity: 0;
152
+ right: 1.5rem;
153
+ transform: translateX(calc(100% + 1.5rem));
154
+ }
155
+
156
+ .bs-toast:where([data-shown]) {
157
+ /* Small delay on load to alow for HTML element to exist */
158
+ animation-delay: 10ms;
159
+ animation-duration: 200ms;
160
+ animation-fill-mode: forwards;
161
+ animation-name: slideLeft;
162
+ animation-timing-function: ease;
163
+ }
164
+
165
+ .bs-toast:where([data-dismissed]) {
166
+ animation-duration: 200ms;
167
+ animation-fill-mode: forwards;
168
+ animation-name: slideRight;
169
+ animation-timing-function: ease;
170
+ }
171
+
172
+ /* Non-mobile toasts come in from the right */
173
+ @keyframes slideRight {
174
+ 0% {
175
+ opacity: 1;
176
+ transform: translateX(0);
177
+ }
178
+ 100% {
179
+ opacity: 0;
180
+ transform: translateX(calc(100% + 1.5rem));
181
+ }
182
+ }
183
+
184
+ @keyframes slideLeft {
185
+ 0% {
186
+ opacity: 0;
187
+ transform: translateX(calc(100% + 1.5rem));
188
+ }
189
+ 100% {
190
+ opacity: 1;
191
+ transform: translateX(0);
192
+ }
193
+ }
194
+
195
+ .bs-toast :where(.bs-toast-actions) {
196
+ /* Non-mobile - Buttons will be side-by-side */
197
+ flex-direction: row;
198
+ justify-content: flex-end;
199
+ }
200
+
201
+ }
202
+
203
+ }
204
+