@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,182 @@
1
+ // TODO: Add mouse click and drag support to scroll carousel
2
+ import { LitElement, html, css } from "lit";
3
+ import { commonStyles } from "../shared/common";
4
+
5
+ class Carousel extends LitElement {
6
+ static properties = {
7
+ atScrollStart: { type: Boolean },
8
+ atScrollEnd: { type: Boolean },
9
+ };
10
+ static styles = [
11
+ commonStyles,
12
+ css`
13
+ :host {
14
+ --slide-width-mobile: 75vw;
15
+ --slide-width-desktop: var(--column-span-3);
16
+
17
+ display: block;
18
+ scrollbar-color: transparent transparent;
19
+ scrollbar-width: 0px;
20
+ scroll-behavior: smooth;
21
+ overflow: hidden;
22
+ -webkit-overflow-scrolling: touch;
23
+ }
24
+
25
+ :host(:focus) {
26
+ outline: none !important;
27
+ }
28
+
29
+ ::-webkit-scrollbar {
30
+ background: transparent;
31
+ width: 0px;
32
+ }
33
+
34
+ .carousel {
35
+ display: flex;
36
+ gap: var(--spacing-layout-1);
37
+ overflow-x: scroll;
38
+ scroll-snap-type: x mandatory;
39
+ padding-block-start: var(--spacing-layout-half);
40
+ padding-block-end: var(--spacing-layout-1);
41
+ }
42
+
43
+ .controls {
44
+ margin-block-start: calc(-1 * var(--spacing-layout-half));
45
+ margin-block-end: var(--spacing-layout-1);
46
+ text-align: center;
47
+ }
48
+
49
+ .controls > * + * {
50
+ margin-inline-start: var(--spacing-layout-half);
51
+ }
52
+
53
+ .controls button {
54
+ background: transparent;
55
+ border: none;
56
+ border-radius: 50%;
57
+ color: var(--purple-80);
58
+ cursor: pointer;
59
+ font-size: var(--font-size-large, 1.25rem);
60
+ height: var(--spacing-layout-2);
61
+ transition: background-color 0.2s ease-in-out;
62
+ width: var(--spacing-layout-2);
63
+ }
64
+
65
+ .controls button:hover,
66
+ .controls button:focus {
67
+ background-color: var(--white, #fff);
68
+ }
69
+
70
+ .controls button:focus {
71
+ outline: var(--focus-outline);
72
+ }
73
+
74
+ .controls button.disabled {
75
+ color: var(--black-20);
76
+ cursor: default;
77
+ }
78
+
79
+ .controls button.disabled:hover,
80
+ .controls button.disabled:focus {
81
+ background: transparent;
82
+ outline: none;
83
+ }
84
+
85
+ ::slotted(*) {
86
+ flex: 0 0 var(--slide-width-mobile);
87
+ margin-block: var(--spacing-layout-1);
88
+ scroll-snap-align: center;
89
+ }
90
+
91
+ @media (min-width: 1024px) {
92
+ ::slotted(*) {
93
+ flex: 0 0 var(--slide-width-desktop);
94
+ }
95
+
96
+ .spacer {
97
+ flex: 0 0
98
+ calc((100vw - var(--column-span-12)) / 2 - var(--outer-margin));
99
+ }
100
+ }
101
+ `,
102
+ ];
103
+ constructor() {
104
+ super();
105
+ this.atScrollStart = true;
106
+ this.atScrollEnd = false;
107
+ }
108
+ connectedCallback() {
109
+ super.connectedCallback();
110
+
111
+ // Scroll slot element with focus into view
112
+ this.addEventListener("focusin", (event) => {
113
+ if (event.target.slot === "") {
114
+ event.target.scrollIntoView({
115
+ behavior: "smooth",
116
+ block: "nearest",
117
+ inline: "center",
118
+ });
119
+ }
120
+ });
121
+ }
122
+ scrollPrevious() {
123
+ const carousel = this.shadowRoot.querySelector(".carousel");
124
+ const slotItem = this.shadowRoot
125
+ .querySelector("slot")
126
+ .assignedElements()[0];
127
+ const slotItemWidth = slotItem.clientWidth;
128
+ carousel.scrollBy({ left: -slotItemWidth, behavior: "smooth" });
129
+ }
130
+ scrollNext() {
131
+ const carousel = this.shadowRoot.querySelector(".carousel");
132
+ const slotItem = this.shadowRoot
133
+ .querySelector("slot")
134
+ .assignedElements()[0];
135
+ const slotItemWidth = slotItem.clientWidth;
136
+ carousel.scrollBy({ left: slotItemWidth, behavior: "smooth" });
137
+ }
138
+ handleScroll(event) {
139
+ // Check if at start of scroll
140
+ if (event.target.scrollLeft === 0) {
141
+ this.atScrollStart = true;
142
+ } else {
143
+ this.atScrollStart = false;
144
+ }
145
+ // Check if at end of scroll
146
+ if (
147
+ Math.round(event.target.scrollLeft + event.target.clientWidth) >=
148
+ Math.round(event.target.scrollWidth)
149
+ ) {
150
+ this.atScrollEnd = true;
151
+ } else {
152
+ this.atScrollEnd = false;
153
+ }
154
+ }
155
+ render() {
156
+ return html`
157
+ <div class="carousel" @scroll=${this.handleScroll}>
158
+ <div class="spacer"></div>
159
+ <slot></slot>
160
+ <div class="spacer"></div>
161
+ </div>
162
+ <div class="controls">
163
+ <button
164
+ class="previous ${this.atScrollStart ? "disabled" : ""}"
165
+ @click="${this.scrollPrevious}"
166
+ >
167
+ <cfa-icon>arrow_back</cfa-icon>
168
+ </button>
169
+ <button
170
+ class="next ${this.atScrollEnd ? "disabled" : ""}"
171
+ @click="${this.scrollNext}"
172
+ >
173
+ <cfa-icon>arrow_forward</cfa-icon>
174
+ </button>
175
+ </div>
176
+ `;
177
+ }
178
+ }
179
+
180
+ if (!customElements.get("cfa-carousel")) {
181
+ customElements.define("cfa-carousel", Carousel);
182
+ }
@@ -0,0 +1,61 @@
1
+ import { html } from "lit-html";
2
+ import "./carousel";
3
+ import "./card";
4
+ import "./icon";
5
+
6
+ export default {
7
+ title: "Organisms/Carousel",
8
+ };
9
+
10
+ const Template = () => html`
11
+ <cfa-carousel>
12
+ <cfa-card
13
+ visualType="image"
14
+ visualUrl="https://codeforamerica.org/wp-content/uploads/2022/03/parents-with-child-768x427.png"
15
+ visualAltText="Illustration of three adults embracing and smiling"
16
+ title="Automatic record clearance"
17
+ text="Working with communities and government to fundamentally transform the process of clearing records."
18
+ actionLabel="Learn more"
19
+ >
20
+ </cfa-card>
21
+ <cfa-card
22
+ visualType="image"
23
+ visualUrl="https://files.codeforamerica.org/2021/05/28124702/illustration_grocery-768x576.png"
24
+ visualAltText="Illustration of groceries in a shopping basket and paper bag"
25
+ title="Food benefits"
26
+ text="Improving access to food assistance and delivery of benefits."
27
+ actionLabel="Learn more"
28
+ >
29
+ </cfa-card>
30
+ <cfa-card
31
+ visualType="image"
32
+ visualUrl="https://files.codeforamerica.org/2021/05/28124702/illustration_family-dinner-768x505.png"
33
+ visualAltText="Illustration of two children and a child seated at a table, with a notebook and a pencil on the table, the adult pouring into a glass from a pitcher"
34
+ title="Integrated benefits applications"
35
+ text="Making it easier for people and families to access all their benefits in one place."
36
+ actionLabel="Learn more"
37
+ >
38
+ </cfa-card>
39
+ <cfa-card
40
+ visualType="image"
41
+ visualUrl="https://files.codeforamerica.org/2021/05/28124704/illustration_friends-talking-768x518.png"
42
+ visualAltText="Illustration of three adults having a conversation"
43
+ title="Training and capacity building"
44
+ text="Helping government serve people in a more human-centered way."
45
+ actionLabel="Learn more"
46
+ >
47
+ </cfa-card>
48
+ <cfa-card
49
+ visualType="image"
50
+ visualUrl="https://files.codeforamerica.org/2021/05/28124702/illustration_on-the-phone-2-768x576.png"
51
+ visualAltText="Illustration of an adult and child reading together"
52
+ title="Free, trustworthy tax services"
53
+ text="Helping people achieve the financial stability they deserve."
54
+ actionLabel="Learn more"
55
+ >
56
+ </cfa-card>
57
+ </cfa-carousel>
58
+ `;
59
+
60
+ export const Default = Template.bind({});
61
+ Default.args = {};
@@ -0,0 +1,99 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+ import "./blob";
4
+
5
+ class CTA extends LitElement {
6
+ static properties = {};
7
+ static styles = [
8
+ commonStyles,
9
+ css`
10
+ :host {
11
+ --bg-color: var(--purple-60);
12
+ --link-color: var(--white);
13
+ --link-hover-color: var(--white);
14
+ --spacing: var(--spacing-layout-1);
15
+ --text-color: var(--white);
16
+
17
+ background-color: var(--bg-color);
18
+ display: block;
19
+ }
20
+
21
+ a {
22
+ color: var(--link-color);
23
+ }
24
+
25
+ a:hover {
26
+ color: var(--link-hover-color);
27
+ }
28
+
29
+ .cta {
30
+ display: grid;
31
+ }
32
+
33
+ .cta > * {
34
+ grid-area: 1 / 1;
35
+ }
36
+
37
+ .content {
38
+ color: var(--text-color);
39
+ display: flex;
40
+ flex-direction: column;
41
+ gap: var(--spacing);
42
+ margin-inline: auto;
43
+ max-width: var(--column-span-8);
44
+ padding: var(--spacing-layout-4) var(--outer-margin);
45
+ position: relative;
46
+ spacing: var(--spacing-layout-2);
47
+ text-align: center;
48
+ }
49
+
50
+ .blob {
51
+ position: relative;
52
+ overflow: hidden;
53
+ height: 100%;
54
+ width: 100%;
55
+ }
56
+
57
+ cfa-blob {
58
+ --color: var(--purple-80);
59
+
60
+ overflow: hidden;
61
+ position: absolute;
62
+ height: 120%;
63
+ width: 140%;
64
+ top: -10%;
65
+ left: -20%;
66
+ }
67
+
68
+ @media (min-width: 768px) {
69
+ cfa-blob {
70
+ left: auto;
71
+ width: 100%;
72
+ height: 200%;
73
+ top: -50%;
74
+ }
75
+ }
76
+
77
+ ::slotted(*) {
78
+ margin-block: 0 !important;
79
+ }
80
+ `,
81
+ ];
82
+
83
+ render() {
84
+ return html`
85
+ <div class="cta">
86
+ <div class="blob">
87
+ <cfa-blob></cfa-blob>
88
+ </div>
89
+ <div class="content">
90
+ <slot />
91
+ </div>
92
+ </div>
93
+ `;
94
+ }
95
+ }
96
+
97
+ if (!customElements.get("cfa-cta")) {
98
+ customElements.define("cfa-cta", CTA);
99
+ }
@@ -0,0 +1,22 @@
1
+ import { html } from "lit-html";
2
+ import "./cta";
3
+
4
+ export default {
5
+ title: "Organisms/CTA",
6
+ argTypes: {
7
+ content: { type: "string" },
8
+ },
9
+ parameters: {
10
+ layout: "fullscreen",
11
+ },
12
+ };
13
+
14
+ const Template = ({ content }) => html`
15
+ <cfa-cta .innerHTML="${content}"> </cfa-cta>
16
+ `;
17
+
18
+ export const Default = Template.bind({});
19
+ Default.args = {
20
+ content:
21
+ '<div class="h3">Is your state ready to transform food assistance delivery?</div><p>Let’s work together to improve government in meaningful ways.</p><div><a href="#" class="cfa-button cfa-button--white">Partner with us</a></div>',
22
+ };
@@ -0,0 +1,71 @@
1
+ @use './icon';
2
+
3
+ details {
4
+ --color: var(--purple-60);
5
+ --hover-bg-color: var(--blue-20);
6
+
7
+ display: block;
8
+ max-width: var(--column-span-8);
9
+ margin-inline: auto;
10
+ border-block: var(--hairline) solid var(--gray-40);
11
+ padding-inline: var(--spacing-component-3);
12
+ }
13
+
14
+ details[open] {
15
+ padding-block-end: var(--spacing-layout-half);
16
+ }
17
+
18
+ details[open] > summary {
19
+ margin-block-end: var(--spacing-layout-half);
20
+ }
21
+
22
+ details + details {
23
+ margin-block-start: -1px !important;
24
+ }
25
+
26
+ details > summary {
27
+ align-items: center;
28
+ color: var(--color);
29
+ cursor: pointer;
30
+ display: block;
31
+ flex-direction: row;
32
+ font-weight: bold;
33
+ padding-block: var(--spacing-component-3);
34
+ padding-right: var(--spacing-component-4);
35
+ position: relative;
36
+ }
37
+
38
+ details > summary:hover {
39
+ background-color: var(--hover-bg-color);
40
+ box-shadow:
41
+ var(--spacing-component-3) 0 var(--blue-20),
42
+ calc(-1 * var(--spacing-component-3)) 0 var(--blue-20);
43
+ }
44
+
45
+ summary::after {
46
+ @include icon.icon;
47
+
48
+ content: 'expand_more';
49
+ display: block;
50
+ height: 1rem;
51
+ line-height: 1rem;
52
+ margin-top: -0.5rem;
53
+ position: absolute;
54
+ right: 0;
55
+ text-align: right;
56
+ top: 50%;
57
+ }
58
+
59
+ @media (prefers-reduced-motion: no-preference) {
60
+ summary::after {
61
+ transition: transform 0.2s;
62
+ }
63
+ }
64
+
65
+ details[open] > summary::after {
66
+ transform: rotate(180deg);
67
+ }
68
+
69
+ details > summary + * {
70
+ margin-block-start: 0 !important;
71
+ }
@@ -0,0 +1,27 @@
1
+ import { html } from "lit-html";
2
+ import "./details.scss";
3
+
4
+ export default {
5
+ title: "Molecules/Details",
6
+ argTypes: {
7
+ summary: { type: "string" },
8
+ text: { type: "string" },
9
+ },
10
+ };
11
+
12
+ const Template = ({ summary, text }) => html`
13
+ <details>
14
+ <summary>${summary}</summary>
15
+ <p>${text}</p>
16
+ </details>
17
+ <details>
18
+ <summary>${summary}</summary>
19
+ <p>${text}</p>
20
+ </details>
21
+ `;
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ summary: "Details",
26
+ text: "Something small enough to escape casual notice.",
27
+ };
@@ -0,0 +1,126 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+ import { layoutStyles } from "../shared/layout";
4
+
5
+ class FlexibleLayout extends LitElement {
6
+ static properties = {
7
+ theme: {},
8
+ };
9
+ static styles = [
10
+ commonStyles,
11
+ layoutStyles,
12
+ css`
13
+ :host {
14
+ --column-gap: var(--gutter-width);
15
+ --row-gap: var(--spacing-layout-1);
16
+
17
+ display: block;
18
+ }
19
+
20
+ .layout {
21
+ display: flex;
22
+ flex-direction: column;
23
+ row-gap: var(--row-gap);
24
+ }
25
+
26
+ /* Theme: one (full-width) */
27
+ @media (min-width: 768px) {
28
+ .layout {
29
+ column-gap: var(--column-gap);
30
+ display: grid;
31
+ grid-template-areas: "content-area-1" "content-area-2" "content-area-3" "content-area-4";
32
+ row-gap: var(--row-gap);
33
+ }
34
+
35
+ .content-area-1 {
36
+ grid-area: content-area-1;
37
+ }
38
+ .content-area-2 {
39
+ grid-area: content-area-2;
40
+ }
41
+ .content-area-3 {
42
+ grid-area: content-area-3;
43
+ }
44
+ }
45
+
46
+ @media (min-width: 768px) {
47
+ .layout--one {
48
+ grid-template-columns: 1fr;
49
+ grid-template-areas: "content-area-1";
50
+ }
51
+ }
52
+
53
+ /* Theme: one-one */
54
+ @media (min-width: 768px) {
55
+ .layout--one-one {
56
+ grid-template-columns: 1fr 1fr;
57
+ grid-template-areas: "content-area-1 content-area-2";
58
+ }
59
+ }
60
+
61
+ /* Theme: one-two */
62
+ @media (min-width: 768px) {
63
+ .layout--one-two {
64
+ grid-template-columns: 1fr 2fr;
65
+ grid-template-areas: "content-area-1 content-area-2";
66
+ }
67
+ }
68
+
69
+ /* Theme: two-one */
70
+ @media (min-width: 768px) {
71
+ .layout--two-one {
72
+ grid-template-columns: 2fr 1fr;
73
+ grid-template-areas: "content-area-1 content-area-2";
74
+ }
75
+ }
76
+
77
+ /* Theme: one-one-one */
78
+ @media (min-width: 768px) {
79
+ .layout--one-one-one {
80
+ grid-template-columns: 1fr 1fr 1fr;
81
+ grid-template-areas: "content-area-1 content-area-2 content-area-3";
82
+ }
83
+ }
84
+
85
+ /* Theme: one-one-two */
86
+ @media (min-width: 768px) {
87
+ .layout--one-one-two {
88
+ grid-template-columns: 1fr 1fr 2fr;
89
+ grid-template-areas: "content-area-1 content-area-2 content-area-3";
90
+ }
91
+ }
92
+
93
+ /* Theme: one-two-one */
94
+ @media (min-width: 768px) {
95
+ .layout--one-two-one {
96
+ grid-template-columns: 1fr 2fr 1fr;
97
+ grid-template-areas: "content-area-1 content-area-2 content-area-3";
98
+ }
99
+ }
100
+
101
+ /* Theme: two-one-one */
102
+ @media (min-width: 768px) {
103
+ .layout--two-one-one {
104
+ grid-template-columns: 2fr 1fr 1fr;
105
+ grid-template-areas: "content-area-1 content-area-2 content-area-3";
106
+ }
107
+ }
108
+ `,
109
+ ];
110
+ render() {
111
+ return html`
112
+ <div class="container-fluid wrapper">
113
+ <div class="layout layout--${this.theme}">
114
+ <slot name="content-area-1"></slot>
115
+ <slot name="content-area-2"></slot>
116
+ <slot name="content-area-3"></slot>
117
+ </div>
118
+ </div>
119
+ `;
120
+ }
121
+ }
122
+ customElements.define("cfa-flexible-layout", FlexibleLayout);
123
+
124
+ if (!customElements.get("cfa-flexible-layout")) {
125
+ customElements.define("cfa-flexible-layout", FlexibleLayout);
126
+ }
@@ -0,0 +1,48 @@
1
+ import { html } from "lit-html";
2
+ import "./flexible-layout";
3
+
4
+ export default {
5
+ title: "Organisms/FlexibleLayout",
6
+ argTypes: {
7
+ theme: {
8
+ defaultValue: "one-one",
9
+ options: [
10
+ "one",
11
+ "one-one",
12
+ "one-two",
13
+ "two-one",
14
+ "one-one-one",
15
+ "one-two-one",
16
+ "one-one-two",
17
+ "two-one-one",
18
+ ],
19
+ control: { type: "radio" },
20
+ },
21
+ },
22
+ };
23
+
24
+ const Template = ({ theme }) => html`
25
+ <cfa-flexible-layout theme=${theme}>
26
+ <div slot="content-area-1" class="stack">
27
+ <div class="cfa-text">
28
+ <h1>Government can, and should, work well for everyone.</h1>
29
+ <p>We’ve been working for more than a decade with governments and communities across the country to break down barriers and find real solutions.</p>
30
+ </div>
31
+ </div>
32
+ <div slot="content-area-2" class="stack">
33
+ <cfa-box>
34
+ <p>The past several years have shown us the stakes when it doesn’t—and what’s possible when it does. Economic volatility and the ongoing effects of the pandemic have made government services more important than ever, and digital delivery of those services has delivered stability to millions of families in an unstable time.</p>
35
+ </cfa-box>
36
+ <cfa-box>
37
+ <p>The public interest tech community has shown that it’s possible for government to reach people equitably, and to serve them with dignity and respect. </p>
38
+ </cfa-box>
39
+ </div>
40
+ <div slot="content-area-3" class="stack">
41
+ <div class="cfa-text">
42
+ <p class="small">We’ve never been as poised as we are right now to drive meaningful, lasting change in government.</p>
43
+ </div>
44
+ </cfa-flexible-layout>
45
+ `;
46
+
47
+ export const Default = Template.bind({});
48
+ Default.args = {};