@codeforamerica/marcomms-design-system 1.0.0 → 1.0.1

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 (91) hide show
  1. package/package.json +2 -1
  2. package/src/components/accordion.js +141 -0
  3. package/src/components/accordion.stories.js +56 -0
  4. package/src/components/avatar.js +62 -0
  5. package/src/components/avatar.stories.js +27 -0
  6. package/src/components/banner.js +152 -0
  7. package/src/components/banner.stories.js +115 -0
  8. package/src/components/bar.js +102 -0
  9. package/src/components/bar.stories.js +22 -0
  10. package/src/components/blob.js +119 -0
  11. package/src/components/blob.stories.js +64 -0
  12. package/src/components/box.js +55 -0
  13. package/src/components/box.stories.js +24 -0
  14. package/src/components/breadcrumbs.js +80 -0
  15. package/src/components/breadcrumbs.stories.js +27 -0
  16. package/src/components/button.js +167 -0
  17. package/src/components/button.scss +162 -0
  18. package/src/components/button.stories.js +49 -0
  19. package/src/components/callout.js +62 -0
  20. package/src/components/callout.stories.js +20 -0
  21. package/src/components/card.js +403 -0
  22. package/src/components/card.stories.js +170 -0
  23. package/src/components/carousel.js +182 -0
  24. package/src/components/carousel.stories.js +61 -0
  25. package/src/components/cta.js +99 -0
  26. package/src/components/cta.stories.js +22 -0
  27. package/src/components/details.scss +71 -0
  28. package/src/components/details.stories.js +27 -0
  29. package/src/components/flexible-layout.js +126 -0
  30. package/src/components/flexible-layout.stories.js +48 -0
  31. package/src/components/form-elements.scss +305 -0
  32. package/src/components/form-elements.stories.js +134 -0
  33. package/src/components/icon.js +41 -0
  34. package/src/components/icon.scss +31 -0
  35. package/src/components/icon.stories.js +16 -0
  36. package/src/components/label.js +63 -0
  37. package/src/components/label.stories.js +29 -0
  38. package/src/components/link-list.scss +80 -0
  39. package/src/components/link-list.stories.js +52 -0
  40. package/src/components/loader.scss +24 -0
  41. package/src/components/loader.stories.js +12 -0
  42. package/src/components/logo-card.js +93 -0
  43. package/src/components/logo-card.stories.js +48 -0
  44. package/src/components/nav.js +99 -0
  45. package/src/components/nav.stories.js +40 -0
  46. package/src/components/page-nav.js +171 -0
  47. package/src/components/page-nav.stories.js +112 -0
  48. package/src/components/pager.js +98 -0
  49. package/src/components/pager.stories.js +30 -0
  50. package/src/components/pagination.js +116 -0
  51. package/src/components/pagination.stories.js +30 -0
  52. package/src/components/person-card.js +240 -0
  53. package/src/components/person-card.stories.js +58 -0
  54. package/src/components/pill.js +33 -0
  55. package/src/components/pill.stories.js +23 -0
  56. package/src/components/promo.js +83 -0
  57. package/src/components/promo.stories.js +37 -0
  58. package/src/components/pullquote.js +42 -0
  59. package/src/components/pullquote.stories.js +16 -0
  60. package/src/components/quote.js +84 -0
  61. package/src/components/quote.stories.js +23 -0
  62. package/src/components/reveal.js +83 -0
  63. package/src/components/reveal.stories.js +40 -0
  64. package/src/components/slide.js +121 -0
  65. package/src/components/slide.stories.js +53 -0
  66. package/src/components/social-icon.js +233 -0
  67. package/src/components/social-icon.stories.js +36 -0
  68. package/src/components/stat.js +92 -0
  69. package/src/components/stat.stories.js +28 -0
  70. package/src/components/tab-list.js +114 -0
  71. package/src/components/tab-list.stories.js +18 -0
  72. package/src/components/tab.js +95 -0
  73. package/src/components/tab.stories.js +29 -0
  74. package/src/components/tile.js +150 -0
  75. package/src/components/tile.stories.js +41 -0
  76. package/src/components/transcript.js +44 -0
  77. package/src/components/transcript.stories.js +167 -0
  78. package/src/core/_base.scss +86 -0
  79. package/src/core/_grid.scss +295 -0
  80. package/src/core/_helpers.scss +111 -0
  81. package/src/core/_layout.scss +79 -0
  82. package/src/core/_reset.scss +53 -0
  83. package/src/core/_tokens.scss +251 -0
  84. package/src/core/_typography.scss +426 -0
  85. package/src/core/_wordpress.scss +27 -0
  86. package/src/core/colors.mdx +100 -0
  87. package/src/core/typography.mdx +66 -0
  88. package/src/shared/common.js +15 -0
  89. package/src/shared/layout.js +14 -0
  90. package/src/shared/typography.js +111 -0
  91. package/src/styles.scss +16 -0
@@ -0,0 +1,305 @@
1
+ @use './icon';
2
+
3
+ // Form
4
+
5
+ .cfa-form {
6
+ --bg-color: var(--white);
7
+
8
+ background-color: var(--bg-color);
9
+ box-shadow: var(--shadow-medium);
10
+ }
11
+
12
+ // Fieldset
13
+
14
+ .cfa-fieldset {
15
+ border: 0;
16
+ margin: 0;
17
+ padding: 0;
18
+
19
+ & > * + * {
20
+ margin-block-start: var(--spacing-layout-half);
21
+ }
22
+
23
+ legend {
24
+ font-weight: bold;
25
+ }
26
+ }
27
+
28
+ // Form group
29
+
30
+ .cfa-form-group {
31
+ & > * {
32
+ display: block;
33
+ }
34
+ & + & {
35
+ margin-block-start: var(--spacing-layout-1);
36
+ }
37
+ }
38
+
39
+ // Input container
40
+
41
+ .cfa-input-container {
42
+ max-width: 100%;
43
+ width: min(var(--column-span-6), 100%);
44
+
45
+ &:focus-within {
46
+ outline: var(--focus-outline);
47
+ }
48
+
49
+ & > * {
50
+ display: block;
51
+ width: 100%;
52
+ }
53
+ }
54
+
55
+ // Label
56
+
57
+ .cfa-label {
58
+ flex: 1;
59
+ flex-grow: 1;
60
+ font-weight: bold;
61
+ padding-inline-end: var(--spacing-component-2);
62
+ padding-block: var(--spacing-component-2)
63
+ }
64
+
65
+ // Select
66
+
67
+ .cfa-select {
68
+ appearance: none;
69
+ background-color: var(--white, #fff);
70
+ background-image: url("data:image/svg+xml;utf8,<svg fill='black' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>");
71
+ background-position-x: calc(100% - 5px);
72
+ background-position-y: 50%;
73
+ background-repeat: no-repeat;
74
+ border-radius: 0;
75
+ border: var(--thin) solid var(--black, #000);
76
+ color: var(--black, #fff);
77
+ display: block;
78
+ font-family: var(--font-family-sans-serif);
79
+ font-size: 1rem;
80
+ font-weight: normal;
81
+ padding-block: var(--spacing-component-2);
82
+ padding-inline: var(--spacing-component-3);
83
+ max-width: 100%;
84
+ position: relative;
85
+
86
+ &:focus {
87
+ outline: none;
88
+ }
89
+ }
90
+
91
+ // Multiselect
92
+
93
+ .cfa-multiselect {
94
+ background-color: var(--white);
95
+ border-radius: 0;
96
+ border: var(--thin) solid var(--black);
97
+ box-shadow: inset 0 var(--thin) 0 rgb(0 0 0 / 15%);
98
+ font-family: var(--font-family-sans-serif);
99
+ font-size: 1rem;
100
+ font-weight: bold;
101
+ min-width: var(--column-span-3);
102
+ max-width: 100%;
103
+
104
+ &:focus {
105
+ outline: none;
106
+ }
107
+
108
+ option {
109
+ padding-block: var(--spacing-component-2);
110
+ padding-inline: var(--spacing-component-3);
111
+ }
112
+
113
+ option:focus,
114
+ option:checked {
115
+ background-color: var(--green-20);
116
+ }
117
+
118
+ }
119
+
120
+ // Text field
121
+
122
+ %text-field {
123
+ background-color: var(--white);
124
+ border-radius: 0;
125
+ border: var(--thin) solid var(--black);
126
+ box-shadow: inset 0px var(--thin) 0px rgb(0 0 0 / 15%);
127
+ font-family: var(--font-family-sans-serif);
128
+ font-size: 1rem;
129
+ font-weight: normal;
130
+ padding-block: var(--spacing-component-2);
131
+ padding-inline: var(--spacing-component-3);
132
+ max-width: 100%;
133
+ }
134
+
135
+ // Text input
136
+
137
+ .cfa-text-input {
138
+ @extend %text-field;
139
+
140
+ &:focus {
141
+ outline: none;
142
+ }
143
+ }
144
+
145
+ // Text area
146
+
147
+ .cfa-text-area {
148
+ @extend %text-field;
149
+
150
+ height: var(--spacing-layout-4);
151
+ padding: var(--spacing-component-3);
152
+
153
+ &:focus {
154
+ outline: none;
155
+ }
156
+ }
157
+
158
+ // Checkbox
159
+
160
+ .cfa-checkbox {
161
+ align-items: start;
162
+ background-color: var(--white);
163
+ border: var(--thin) solid var(--black);
164
+ display: flex;
165
+ flex-direction: row;
166
+ font-size: var(--font-size-base);
167
+ gap: var(--spacing-component-2);
168
+ line-height: var(--line-height-base);
169
+
170
+ &:has(input:checked){
171
+ background-color: var(--green-20);
172
+ }
173
+
174
+ & + & {
175
+ margin-block-start: var(--spacing-layout-half);
176
+ }
177
+
178
+ input {
179
+ appearance: none;
180
+ flex-basis: 1.5rem;
181
+ flex-grow: 0;
182
+ }
183
+
184
+ input:focus {
185
+ outline: none;
186
+ }
187
+
188
+ input::before {
189
+ @include icon.icon;
190
+
191
+ background-color: var(--white);
192
+ border-radius: 10%;
193
+ content: "check_box_outline_blank";
194
+ flex-basis: 1.5rem;
195
+ flex-grow: 0;
196
+ font-size: 1.2rem;
197
+ line-height: 1em;
198
+ margin-block-start: calc(var(--line-height-base)/2 - 0.25rem);
199
+ margin-inline-start: var(--spacing-component-2);
200
+ text-align: center;
201
+ width: 1.2rem;
202
+ }
203
+
204
+ input:checked::before {
205
+ content: "check_box";
206
+ }
207
+
208
+ label {
209
+ font-weight: normal;
210
+ }
211
+ }
212
+
213
+ // Radio button
214
+
215
+ .cfa-radio-button {
216
+ align-items: start;
217
+ background-color: var(--white);
218
+ border: var(--thin) solid var(--black);
219
+ display: flex;
220
+ flex-direction: row;
221
+ font-size: var(--font-size-base);
222
+ gap: var(--spacing-component-2);
223
+ line-height: var(--line-height-base);
224
+
225
+ &:has(input:checked){
226
+ background-color: var(--green-20);
227
+ }
228
+
229
+ & + & {
230
+ margin-block-start: var(--spacing-layout-half);
231
+ }
232
+
233
+ input {
234
+ appearance: none;
235
+ flex-basis: 1.5rem;
236
+ flex-grow: 0;
237
+ }
238
+
239
+ input:focus {
240
+ outline: none;
241
+ }
242
+
243
+ input::before {
244
+ @include icon.icon;
245
+
246
+ background-color: var(--white);
247
+ border-radius: 50%;
248
+ content: "radio_button_unchecked";
249
+ margin-inline: var(--spacing-component-2);
250
+ overflow: hidden;
251
+ flex-basis: 1.5rem;
252
+ font-size: 1.2rem;
253
+ line-height: 1.2rem;
254
+ margin-block-start: calc(var(--line-height-base)/2 - 0.25rem);
255
+ margin-inline: var(--spacing-component-2);
256
+ text-align: center;
257
+ width: 1.2rem;
258
+ }
259
+
260
+ input:checked::before {
261
+ content: "radio_button_checked";
262
+ }
263
+
264
+ label {
265
+ font-weight: normal;
266
+ }
267
+ }
268
+
269
+ // =====
270
+
271
+ // Date picker
272
+
273
+ .ui-datepicker {
274
+ background-color: var(--white);
275
+ border: solid 1px var(--gray-20);
276
+ box-shadow: var(--shadow-slight);
277
+ font-size: var(--font-size-small);
278
+ letter-spacing: var(--letter-spacing-small);
279
+ padding: var(--spacing-component-3);
280
+ text-align: center;
281
+
282
+ a:link {
283
+ text-decoration: none;
284
+ }
285
+ }
286
+
287
+ .ui-datepicker-header {
288
+ display: flex;
289
+ flex-direction: row;
290
+ margin-block-end: var(--spacing-component-3);
291
+
292
+ & > * {
293
+ flex-grow: 1;
294
+ }
295
+
296
+ .ui-datepicker-title {
297
+ flex-grow: 0;
298
+ }
299
+ }
300
+
301
+ .ui-datepicker-calendar {
302
+ td {
303
+ padding: var(--spacing-component-2);
304
+ }
305
+ }
@@ -0,0 +1,134 @@
1
+ import { html } from "lit-html";
2
+ import "./form-elements.scss";
3
+
4
+ export default {
5
+ title: "Atoms/FormElements",
6
+ argTypes: {},
7
+ };
8
+
9
+ const Template = () => html`
10
+ <div class="row">
11
+ <div class="col-xs-12 col-md-6">
12
+ <div class="cfa-form-group">
13
+ <label for="text-input-example" class="cfa-label"
14
+ >What would you like to tell us about apples?</label
15
+ >
16
+ <div class="cfa-input-container">
17
+ <input id="text-input-example" class="cfa-text-input" type="text" />
18
+ </div>
19
+ </div>
20
+ <div class="cfa-form-group">
21
+ <div class="cfa-input-container">
22
+ <select class="cfa-select">
23
+ <option value="" disabled selected>Select your option</option>
24
+ <option value="1">Option 1</option>
25
+ <option value="2">Option 2</option>
26
+ </select>
27
+ </div>
28
+ </div>
29
+ <div class="cfa-form-group">
30
+ <div class="cfa-input-container">
31
+ <select class="cfa-multiselect" multiple>
32
+ <option value="" disabled selected>Select your option</option>
33
+ <option value="1">Option 1</option>
34
+ <option value="2">Option 2</option>
35
+ </select>
36
+ </div>
37
+ </div>
38
+ <div class="cfa-form-group">
39
+ <div class="cfa-input-container">
40
+ <textarea class="cfa-text-area" placeholder="Text Area"></textarea>
41
+ </div>
42
+ </div>
43
+ <div class="cfa-form-group">
44
+ <fieldset class="cfa-fieldset">
45
+ <legend>Which newsletters would you like to receive?</legend>
46
+ <div class="cfa-input-container cfa-checkbox">
47
+ <input
48
+ type="checkbox"
49
+ id="checkbox-example-1"
50
+ name="checkbox1"
51
+ value="marketing"
52
+ />
53
+ <label for="checkbox-example-1" class="cfa-label"
54
+ >Marketing updates</label
55
+ >
56
+ </div>
57
+ <div class="cfa-input-container cfa-checkbox">
58
+ <input
59
+ type="checkbox"
60
+ id="checkbox-example-2"
61
+ name="checkbox2"
62
+ value="safety-net"
63
+ />
64
+ <label for="checkbox-example-2" class="cfa-label"
65
+ >Safety net updates</label
66
+ >
67
+ </div>
68
+ <div class="cfa-input-container cfa-checkbox">
69
+ <input
70
+ type="checkbox"
71
+ id="checkbox-example-3"
72
+ name="checkbox3"
73
+ value="tax-benefits"
74
+ />
75
+ <label for="checkbox-example-3" class="cfa-label"
76
+ >Tax benefits updates</label
77
+ >
78
+ </div>
79
+ </fieldset>
80
+ </div>
81
+ <div class="cfa-form-group">
82
+ <fieldset class="cfa-fieldset">
83
+ <div class="cfa-input-container cfa-checkbox">
84
+ <input
85
+ type="checkbox"
86
+ id="checkbox-example-4"
87
+ name="checkbox1"
88
+ value="consent"
89
+ />
90
+ <label for="checkbox-example-4" class="cfa-label"
91
+ >I agree to receive direct communications from Code for America,
92
+ and to the privacy policy.</label
93
+ >
94
+ </div>
95
+ </fieldset>
96
+ </div>
97
+ <div class="cfa-form-group">
98
+ <fieldset class="cfa-fieldset">
99
+ <legend>What's the best way to reach you?</legend>
100
+ <div class="cfa-input-container cfa-radio-button">
101
+ <input
102
+ type="radio"
103
+ id="radio-example-1"
104
+ name="radio1"
105
+ value="email"
106
+ />
107
+ <label for="radio-example-1" class="cfa-label">Email</label>
108
+ </div>
109
+ <div class="cfa-input-container cfa-radio-button">
110
+ <input
111
+ type="radio"
112
+ id="radio-example-2"
113
+ name="radio1"
114
+ value="text-message"
115
+ />
116
+ <label for="radio-example-2" class="cfa-label">Text message</label>
117
+ </div>
118
+ <div class="cfa-input-container cfa-radio-button">
119
+ <input
120
+ type="radio"
121
+ id="radio-example-3"
122
+ name="radio1"
123
+ value="phone-call"
124
+ />
125
+ <label for="radio-example-3" class="cfa-label">Phone call</label>
126
+ </div>
127
+ </fieldset>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ `;
132
+
133
+ export const Default = Template.bind({});
134
+ Default.args = {};
@@ -0,0 +1,41 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+
4
+ class Icon extends LitElement {
5
+ static styles = [
6
+ commonStyles,
7
+ css`
8
+ :host {
9
+ --size: 1.2em;
10
+
11
+ vertical-align: middle;
12
+ }
13
+
14
+ .icon {
15
+ -webkit-font-feature-settings: "liga";
16
+ direction: ltr;
17
+ display: inline-block;
18
+ font-family: "Material Symbols Rounded";
19
+ font-size: var(--size);
20
+ font-style: normal;
21
+ font-weight: normal;
22
+ letter-spacing: normal;
23
+ text-transform: none;
24
+ white-space: nowrap;
25
+ word-wrap: normal;
26
+ }
27
+ `,
28
+ ];
29
+
30
+ render() {
31
+ return html`
32
+ <span class="icon">
33
+ <slot></slot>
34
+ </span>
35
+ `;
36
+ }
37
+ }
38
+
39
+ if (!customElements.get("cfa-icon")) {
40
+ customElements.define("cfa-icon", Icon);
41
+ }
@@ -0,0 +1,31 @@
1
+ .cfa-icon {
2
+ height: var(--spacing-layout-5);
3
+ margin-left: auto;
4
+ margin-right: auto;
5
+ width: var(--spacing-layout-5);
6
+
7
+ img {
8
+ display: block;
9
+ height: 100%;
10
+ object-fit: contain;
11
+ object-position: center center;
12
+ width: 100%;
13
+ }
14
+ }
15
+
16
+ // Mixin
17
+
18
+ @mixin icon {
19
+ -webkit-font-feature-settings: 'liga';
20
+ direction: ltr;
21
+ display: inline-block;
22
+ font-family: 'Material Symbols Rounded';
23
+ font-size: 1.4em;
24
+ font-style: normal;
25
+ font-weight: normal;
26
+ letter-spacing: normal;
27
+ text-transform: none;
28
+ vertical-align: middle;
29
+ white-space: nowrap;
30
+ word-wrap: normal;
31
+ }
@@ -0,0 +1,16 @@
1
+ import { html } from "lit-html";
2
+ import "./icon";
3
+
4
+ export default {
5
+ title: "Atoms/Icon",
6
+ argTypes: {
7
+ icon: { type: "string" },
8
+ },
9
+ };
10
+
11
+ const Template = ({ icon }) => html` <cfa-icon>${icon}</cfa-icon> `;
12
+
13
+ export const Default = Template.bind({});
14
+ Default.args = {
15
+ icon: "info",
16
+ };
@@ -0,0 +1,63 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Label extends LitElement {
6
+ static properties = {
7
+ color: "",
8
+ };
9
+
10
+ static styles = [
11
+ commonStyles,
12
+ typographyStyles,
13
+ css`
14
+ .label {
15
+ --background-color: var(--gray-20);
16
+ --text-color: var(--black, #000);
17
+
18
+ background-color: var(--background-color);
19
+ color: var(--text-color);
20
+ display: inline-block;
21
+ line-height: 1em;
22
+ padding: var(--spacing-component-2) var(--spacing-component-3);
23
+ }
24
+
25
+ .label[color="white"] {
26
+ --background-color: var(--white, #fff);
27
+ box-shadow: var(--shadow-small);
28
+ }
29
+
30
+ .label[color="purple"] {
31
+ --background-color: var(--purple-20);
32
+ }
33
+
34
+ .label[color="red"] {
35
+ --background-color: var(--red-20);
36
+ }
37
+
38
+ .label[color="blue"] {
39
+ --background-color: var(--blue-20);
40
+ }
41
+
42
+ .label[color="green"] {
43
+ --background-color: var(--green-20);
44
+ }
45
+
46
+ .label[color="yellow"] {
47
+ --background-color: var(--yellow-20);
48
+ }
49
+ `,
50
+ ];
51
+
52
+ render() {
53
+ return html`
54
+ <div class="label small strong" color="${this.color}">
55
+ <slot />
56
+ </div>
57
+ `;
58
+ }
59
+ }
60
+
61
+ if (!customElements.get("cfa-label")) {
62
+ customElements.define("cfa-label", Label);
63
+ }
@@ -0,0 +1,29 @@
1
+ import { html } from "lit-html";
2
+ import "./label";
3
+
4
+ export default {
5
+ title: "Atoms/Label",
6
+ argTypes: {
7
+ text: { type: "string" },
8
+ color: {
9
+ defaultValue: "default",
10
+ control: {
11
+ type: "radio",
12
+ options: ["default", "white", "purple", "red", "blue", "green"],
13
+ },
14
+ },
15
+ },
16
+ };
17
+
18
+ const Template = ({ text, color }) => html`
19
+ <cfa-label color="${color}"> ${text} </cfa-label>
20
+ `;
21
+
22
+ export const Default = Template.bind({});
23
+ Default.args = {
24
+ text: "Recording available",
25
+ color: "default",
26
+ };
27
+ Default.parameters = {
28
+ backgrounds: { default: "white" },
29
+ };
@@ -0,0 +1,80 @@
1
+ .link-list,
2
+ ul.is-style-link-list, /* WordPress list style class */
3
+ .content ul.is-style-link-list /* WordPress list style class */
4
+ {
5
+ --bg-color: var(--white);
6
+ --bg-hover-color: var(--purple-10);
7
+ --border-color: var(--gray-40);
8
+ --border-hover-color: var(--purple-60);
9
+ --text-color: var(--black);
10
+ --text-hover-color: var(--purple-80);
11
+ --icon-color: var(--gray-40);
12
+ --icon-hover-color: var(--purple-60);
13
+
14
+ list-style: none;
15
+ padding: 0;
16
+
17
+ & > li {
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+
22
+ & > li > a {
23
+ background-color: var(--bg-color);
24
+ border: var(--hairline) solid var(--border-color);
25
+ color: var(--text-color);
26
+ display: block;
27
+ padding: var(--spacing-component-3);
28
+ text-decoration: none;
29
+ }
30
+
31
+ & > li > a:hover,
32
+ & > li > a:focus {
33
+ background-color: var(--bg-hover-color);
34
+ border-color: var(--border-hover-color);
35
+ color: var(--text-hover-color);
36
+ position: relative;
37
+ z-index: 2;
38
+ }
39
+
40
+ & > li:first-child > a {
41
+ border-top-left-radius: var(--rounded-corners);
42
+ border-top-right-radius: var(--rounded-corners);
43
+ }
44
+
45
+ & > li:last-child > a {
46
+ border-bottom-left-radius: var(--rounded-corners);
47
+ border-bottom-right-radius: var(--rounded-corners);
48
+ }
49
+
50
+ & > li:not(:has(a)) {
51
+ background-color: var(--gray-20);
52
+ border: var(--hairline) solid var(--border-color);
53
+ color: var(--text-color);
54
+ display: block;
55
+ padding: var(--spacing-component-3);
56
+ }
57
+
58
+ & > li + li {
59
+ margin-block-start: calc(-1 * var(--hairline));
60
+ }
61
+
62
+ &:has(cfa-icon) > li > a {
63
+ padding-left: var(--spacing-component-5);
64
+ position: relative;
65
+ }
66
+
67
+ & > li > a cfa-icon {
68
+ color: var(--icon-color);
69
+ display: block;
70
+ left: var(--spacing-component-3);
71
+ position: absolute;
72
+ text-align: center;
73
+ width: var(--spacing-component-4);
74
+ }
75
+
76
+ & > li > a:hover cfa-icon,
77
+ & > li > a:focus cfa-icon {
78
+ color: var(--icon-hover-color);
79
+ }
80
+ }