@codeforamerica/marcomms-design-system 1.19.0 → 1.20.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 (105) hide show
  1. package/dist/components/card.js +4 -0
  2. package/dist/components/label.js +4 -0
  3. package/dist/components/logo-card.js +4 -0
  4. package/dist/components/pager.js +7 -3
  5. package/dist/components/person-card.js +5 -1
  6. package/dist/components/promo.js +4 -0
  7. package/dist/components/stat.js +4 -0
  8. package/dist/components/tab-list.js +5 -1
  9. package/dist/components/tab.js +4 -0
  10. package/dist/components/tile.js +4 -0
  11. package/dist/components/transcript.js +4 -0
  12. package/dist/core.css +1 -1
  13. package/dist/index.js +4 -0
  14. package/dist/styles.css +1 -1
  15. package/package.json +2 -1
  16. package/src/components/accordion.js +141 -0
  17. package/src/components/accordion.stories.js +56 -0
  18. package/src/components/avatar.js +62 -0
  19. package/src/components/avatar.stories.js +27 -0
  20. package/src/components/bar.js +102 -0
  21. package/src/components/bar.stories.js +22 -0
  22. package/src/components/blob.js +128 -0
  23. package/src/components/blob.stories.js +73 -0
  24. package/src/components/box.js +55 -0
  25. package/src/components/box.stories.js +24 -0
  26. package/src/components/breadcrumbs.js +80 -0
  27. package/src/components/breadcrumbs.stories.js +27 -0
  28. package/src/components/button.js +163 -0
  29. package/src/components/button.scss +157 -0
  30. package/src/components/button.stories.js +49 -0
  31. package/src/components/callout.js +62 -0
  32. package/src/components/callout.stories.js +20 -0
  33. package/src/components/card.js +456 -0
  34. package/src/components/card.stories.js +227 -0
  35. package/src/components/carousel.js +662 -0
  36. package/src/components/carousel.stories.js +165 -0
  37. package/src/components/details.scss +71 -0
  38. package/src/components/details.stories.js +27 -0
  39. package/src/components/form-elements.scss +304 -0
  40. package/src/components/form-elements.stories.js +134 -0
  41. package/src/components/icon.js +44 -0
  42. package/src/components/icon.scss +32 -0
  43. package/src/components/icon.stories.js +38 -0
  44. package/src/components/label.js +63 -0
  45. package/src/components/label.stories.js +29 -0
  46. package/src/components/link-list.scss +80 -0
  47. package/src/components/link-list.stories.js +52 -0
  48. package/src/components/loader.scss +24 -0
  49. package/src/components/loader.stories.js +12 -0
  50. package/src/components/logo-card.js +93 -0
  51. package/src/components/logo-card.stories.js +48 -0
  52. package/src/components/nav.js +98 -0
  53. package/src/components/nav.stories.js +40 -0
  54. package/src/components/page-nav.js +171 -0
  55. package/src/components/page-nav.stories.js +112 -0
  56. package/src/components/pager.js +98 -0
  57. package/src/components/pager.stories.js +30 -0
  58. package/src/components/pagination.js +116 -0
  59. package/src/components/pagination.stories.js +30 -0
  60. package/src/components/person-card.js +240 -0
  61. package/src/components/person-card.stories.js +58 -0
  62. package/src/components/pill.js +33 -0
  63. package/src/components/pill.stories.js +25 -0
  64. package/src/components/placeholder.js +25 -0
  65. package/src/components/placeholder.stories.js +10 -0
  66. package/src/components/promo.js +82 -0
  67. package/src/components/promo.stories.js +37 -0
  68. package/src/components/pullquote.js +42 -0
  69. package/src/components/pullquote.stories.js +16 -0
  70. package/src/components/quote.js +111 -0
  71. package/src/components/quote.stories.js +23 -0
  72. package/src/components/reveal.js +83 -0
  73. package/src/components/reveal.stories.js +40 -0
  74. package/src/components/slide.js +122 -0
  75. package/src/components/slide.stories.js +49 -0
  76. package/src/components/social-icon.js +236 -0
  77. package/src/components/social-icon.stories.js +36 -0
  78. package/src/components/stat.js +92 -0
  79. package/src/components/stat.stories.js +28 -0
  80. package/src/components/tab-list.js +114 -0
  81. package/src/components/tab-list.stories.js +18 -0
  82. package/src/components/tab.js +95 -0
  83. package/src/components/tab.stories.js +29 -0
  84. package/src/components/tile.js +149 -0
  85. package/src/components/tile.stories.js +41 -0
  86. package/src/components/transcript.js +44 -0
  87. package/src/components/transcript.stories.js +103 -0
  88. package/src/core/base.scss +86 -0
  89. package/src/core/colors.mdx +100 -0
  90. package/src/core/grid.mdx +244 -0
  91. package/src/core/grid.scss +394 -0
  92. package/src/core/helpers.scss +111 -0
  93. package/src/core/layout.scss +103 -0
  94. package/src/core/layout.stories.js +145 -0
  95. package/src/core/reset.scss +53 -0
  96. package/src/core/shadows.mdx +108 -0
  97. package/src/core/tokens.scss +261 -0
  98. package/src/core/typography.mdx +79 -0
  99. package/src/core/typography.scss +415 -0
  100. package/src/core.js +10 -0
  101. package/src/index.js +43 -0
  102. package/src/shared/common.js +65 -0
  103. package/src/shared/layout.js +14 -0
  104. package/src/shared/typography.js +401 -0
  105. package/src/styles.scss +15 -0
@@ -0,0 +1,92 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Stat extends LitElement {
6
+ static properties = {
7
+ beforeLabel: {},
8
+ figure: {},
9
+ afterLabel: {},
10
+ animated: {},
11
+ };
12
+ static styles = [
13
+ commonStyles,
14
+ typographyStyles,
15
+ css`
16
+ :host {
17
+ --text-color: var(--text-dark);
18
+ --highlight-color: var(--purple-20);
19
+ --highlight-thickness: var(--spacing-layout-half);
20
+
21
+ align-self: center;
22
+ display: block;
23
+ margin-inline: auto;
24
+ }
25
+ .stat {
26
+ align-items: center;
27
+ color: var(--text-color);
28
+ display: flex;
29
+ flex-direction: column;
30
+ text-align: center;
31
+ }
32
+ .figure {
33
+ min-width: var(--spacing-layout-3);
34
+ padding-inline: var(--spacing-component-2);
35
+ }
36
+ .figure > span {
37
+ background-image: linear-gradient(
38
+ var(--highlight-color),
39
+ var(--highlight-color)
40
+ );
41
+ background-size: 100% var(--highlight-thickness);
42
+ background-position: bottom 0.15em left;
43
+ background-repeat: no-repeat;
44
+ padding-inline: 0.25em;
45
+ }
46
+ /* Animation */
47
+ @media (prefers-reduced-motion: no-preference) {
48
+ .stat.is-animated .figure > span {
49
+ background-size: 0% var(--highlight-thickness);
50
+ transition: background-size 1s ease;
51
+ }
52
+ .stat.is-animated.is-visible .figure > span {
53
+ background-size: 100% var(--highlight-thickness);
54
+ }
55
+ }
56
+ `,
57
+ ];
58
+ constructor() {
59
+ super();
60
+ this.animated = true;
61
+ }
62
+ firstUpdated() {
63
+ const stat = this.shadowRoot.querySelector(".stat");
64
+ const callback = (entries) => {
65
+ entries.forEach((entry) => {
66
+ if (entry.isIntersecting) {
67
+ entry.target.classList.add("is-visible");
68
+ }
69
+ });
70
+ };
71
+ const options = {
72
+ rootMargin: "0px 0px -20% 0px",
73
+ };
74
+ const myObserver = new IntersectionObserver(callback, options);
75
+ myObserver.observe(stat);
76
+ }
77
+ render() {
78
+ return html`
79
+ <div class="stat ${this.animated ? "is-animated" : ""}">
80
+ <div class="above-label strong">${this.beforeLabel}</div>
81
+ <div class="figure display-2">
82
+ <span>${this.figure}</span>
83
+ </div>
84
+ <div class="below-label strong">${this.afterLabel}</div>
85
+ </div>
86
+ `;
87
+ }
88
+ }
89
+
90
+ if (!customElements.get("cfa-stat")) {
91
+ customElements.define("cfa-stat", Stat);
92
+ }
@@ -0,0 +1,28 @@
1
+ import { html } from "lit-html";
2
+ import "./stat";
3
+
4
+ export default {
5
+ title: "Atoms/Stat",
6
+ argTypes: {
7
+ beforeLabel: { type: "string" },
8
+ figure: { type: "string" },
9
+ afterLabel: { type: "string" },
10
+ },
11
+ };
12
+
13
+ const Template = ({ beforeLabel, figure, afterLabel }) => html`
14
+ <cfa-stat
15
+ beforeLabel="${beforeLabel}"
16
+ figure="${figure}"
17
+ afterLabel="${afterLabel}"
18
+ >
19
+ ${beforeLabel} ${figure} ${afterLabel}
20
+ </cfa-stat>
21
+ `;
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ beforeLabel: "More than",
26
+ figure: "3.8 million",
27
+ afterLabel: "people helped",
28
+ };
@@ -0,0 +1,114 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+ import { buttonStyles } from "./button";
4
+ import "./tab";
5
+
6
+ class TabList extends LitElement {
7
+ static properties = {};
8
+ static styles = [
9
+ commonStyles,
10
+ buttonStyles,
11
+ css`
12
+ :host {
13
+ display: block;
14
+ width: calc(100% + var(--outer-margin));
15
+ }
16
+
17
+ .tab-list {
18
+ display: flex;
19
+ flex-direction: row;
20
+ line-height: 1;
21
+ margin-inline-start: calc(-1 * var(--outer-margin));
22
+ overflow-x: auto;
23
+ overflow-y: hidden;
24
+ scrollbar-width: none;
25
+ white-space: nowrap;
26
+ }
27
+
28
+ .tab-list::before {
29
+ content: "";
30
+ min-width: var(--outer-margin);
31
+ }
32
+
33
+ .tab-list::after {
34
+ border-bottom: var(--hairline) solid var(--gray-40);
35
+ content: "";
36
+ flex-grow: 1;
37
+ margin-right: var(--outer-margin);
38
+ }
39
+
40
+ ::slotted(*) {
41
+ max-width: none !important;
42
+ white-space: nowrap !important;
43
+ }
44
+ `,
45
+ ];
46
+
47
+ constructor() {
48
+ super();
49
+ }
50
+
51
+ firstUpdated() {
52
+ this.addEventListener("click", this._onTabClick);
53
+ this.setAttribute("role", "tablist");
54
+ this._setInitialAriaAttributes();
55
+ }
56
+
57
+ _setInitialAriaAttributes() {
58
+ const tabs = this.querySelectorAll("cfa-tab");
59
+ tabs.forEach((tab, index) => {
60
+ tab.setAttribute("role", "tab");
61
+ tab.setAttribute("aria-selected", "false");
62
+ tab.setAttribute("tabindex", "-1");
63
+ if (index === 0) {
64
+ tab.setAttribute("aria-selected", "true");
65
+ tab.setAttribute("tabindex", "0");
66
+ }
67
+ });
68
+ }
69
+
70
+ _onTabClick(event) {
71
+ const tab = event.target.closest("cfa-tab");
72
+ if (tab) {
73
+ this._setActiveTab(tab);
74
+ }
75
+ }
76
+
77
+ _setActiveTab(activeTab) {
78
+ const tabs = this.querySelectorAll("cfa-tab");
79
+ tabs.forEach((tab) => {
80
+ tab.removeAttribute("active");
81
+ tab.setAttribute("aria-selected", "false");
82
+ tab.setAttribute("tabindex", "-1");
83
+ });
84
+ activeTab.setAttribute("active", "");
85
+ activeTab.setAttribute("aria-selected", "true");
86
+ activeTab.setAttribute("tabindex", "0");
87
+
88
+ // Trigger a custom event with the ID for the new tab
89
+ let tabId = activeTab.id;
90
+ if (tabId && tabId.startsWith("tab-")) {
91
+ tabId = tabId.substring(4);
92
+ }
93
+ console.log("Tab changed event dispatched with ID:", tabId);
94
+ this.dispatchEvent(
95
+ new CustomEvent("tab-changed", {
96
+ detail: { id: tabId },
97
+ bubbles: true,
98
+ composed: true,
99
+ }),
100
+ );
101
+ }
102
+
103
+ render() {
104
+ return html`
105
+ <div class="tab-list" role="tablist">
106
+ <slot></slot>
107
+ </div>
108
+ `;
109
+ }
110
+ }
111
+
112
+ if (!customElements.get("cfa-tab-list")) {
113
+ customElements.define("cfa-tab-list", TabList);
114
+ }
@@ -0,0 +1,18 @@
1
+ import { html } from "lit-html";
2
+ import "./tab-list.js";
3
+
4
+ export default {
5
+ title: "Molecules/Tabs/TabList",
6
+ };
7
+
8
+ const Template = () => html`
9
+ <cfa-tab-list>
10
+ <cfa-tab id="tab-show-all" active>Show all stories</cfa-tab>
11
+ <cfa-tab id="tab-announcements">Announcements</cfa-tab>
12
+ <cfa-tab id="tab-blog-posts">Blog posts</cfa-tab>
13
+ <cfa-tab id="tab-press-releases">Press releases</cfa-tab>
14
+ </cfa-tab-list>
15
+ `;
16
+
17
+ export const Default = Template.bind({});
18
+ Default.args = {};
@@ -0,0 +1,95 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Tab extends LitElement {
6
+ static properties = {
7
+ active: { type: Boolean },
8
+ panelId: { type: String },
9
+ };
10
+
11
+ static styles = [
12
+ commonStyles,
13
+ typographyStyles,
14
+ css`
15
+ button {
16
+ background: none;
17
+ border: 0;
18
+ box-shadow: inset 0 calc(-1 * var(--hairline)) 0 0 var(--gray-40);
19
+ color: var(--gray-80);
20
+ cursor: pointer;
21
+ font-family: var(--font-family-sans-serif);
22
+ font-size: var(--font-size-small);
23
+ font-weight: normal;
24
+ padding: var(--spacing-component-2) var(--spacing-component-3)
25
+ calc(var(--spacing-component-2) + var(--medium));
26
+ }
27
+ button:focus {
28
+ background-color: var(--focus-color);
29
+ outline: none;
30
+ }
31
+ button:not(.active):hover {
32
+ box-shadow: inset 0 calc(-1 * var(--medium)) 0 0 var(--purple-40);
33
+ color: var(--black);
34
+ }
35
+ button.active {
36
+ box-shadow: inset 0 calc(-1 * var(--medium)) 0 0 var(--purple-60);
37
+ color: var(--black);
38
+ font-weight: bold;
39
+ }
40
+ `,
41
+ ];
42
+
43
+ constructor() {
44
+ super();
45
+ this.active = false;
46
+ this.panelId = "";
47
+ }
48
+
49
+ firstUpdated() {
50
+ this.addEventListener("keydown", this._onKeyDown);
51
+ }
52
+
53
+ _onKeyDown(event) {
54
+ const tabs = Array.from(this.parentElement.querySelectorAll("cfa-tab"));
55
+ const currentIndex = tabs.indexOf(this);
56
+ let newIndex;
57
+
58
+ switch (event.key) {
59
+ case "ArrowLeft":
60
+ newIndex = (currentIndex - 1 + tabs.length) % tabs.length;
61
+ tabs[newIndex].shadowRoot.querySelector("button").focus();
62
+ break;
63
+ case "ArrowRight":
64
+ newIndex = (currentIndex + 1) % tabs.length;
65
+ tabs[newIndex].shadowRoot.querySelector("button").focus();
66
+ break;
67
+ case "Home":
68
+ tabs[0].shadowRoot.querySelector("button").focus();
69
+ break;
70
+ case "End":
71
+ tabs[tabs.length - 1].shadowRoot.querySelector("button").focus();
72
+ break;
73
+ default:
74
+ break;
75
+ }
76
+ }
77
+
78
+ render() {
79
+ return html`
80
+ <button
81
+ role="tab"
82
+ aria-selected="${this.active ? "true" : "false"}"
83
+ aria-controls="${this.panelId}"
84
+ class="${this.active ? "active" : ""}"
85
+ tabindex="${this.active ? "0" : "-1"}"
86
+ >
87
+ <slot></slot>
88
+ </button>
89
+ `;
90
+ }
91
+ }
92
+
93
+ if (!customElements.get("cfa-tab")) {
94
+ customElements.define("cfa-tab", Tab);
95
+ }
@@ -0,0 +1,29 @@
1
+ import { html } from "lit-html";
2
+ import "./tab";
3
+
4
+ export default {
5
+ title: "Molecules/Tabs/Tab",
6
+ argTypes: {
7
+ content: { type: "string" },
8
+ state: {
9
+ control: { type: "radio" },
10
+ options: ["default", "active"],
11
+ },
12
+ },
13
+ };
14
+
15
+ const Template = ({ content, state }) => html`
16
+ <cfa-tab ?active=${state === "active"}>${content}</cfa-tab>
17
+ `;
18
+
19
+ export const Default = Template.bind({});
20
+ Default.args = {
21
+ content: "Click me",
22
+ state: "default",
23
+ };
24
+
25
+ export const Active = Template.bind({});
26
+ Active.args = {
27
+ content: "Click me",
28
+ state: "active",
29
+ };
@@ -0,0 +1,149 @@
1
+ import { LitElement, html, css, nothing } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+ import "./blob";
5
+ import "./icon";
6
+
7
+ class Tile extends LitElement {
8
+ static properties = {
9
+ title: { type: String },
10
+ description: { type: String },
11
+ actionLabel: { type: String },
12
+ linkUrl: { type: String },
13
+ linkTarget: { type: String },
14
+ imageUrl: { type: String },
15
+ imageThumbnailUrl: { type: String },
16
+ imageAltText: { type: String },
17
+ };
18
+ static styles = [
19
+ commonStyles,
20
+ typographyStyles,
21
+ css`
22
+ :host {
23
+ --bg-color: var(--white);
24
+ --title-color: var(--purple-60);
25
+ --text-color: var(--black);
26
+ --action-label-color: var(--purple-80);
27
+ --action-label-hover-highlight: var(--purple-20);
28
+ --blob-color: var(--purple-20);
29
+
30
+ align-items: stretch;
31
+ display: flex;
32
+ text-align: center;
33
+ width: 100%;
34
+ }
35
+
36
+ .tile {
37
+ background-color: var(--bg-color);
38
+ border-radius: var(--spacing-component-2);
39
+ border: var(--hairline) solid var(--black-20);
40
+ color: var(--text-color);
41
+ display: flex;
42
+ flex-direction: column;
43
+ padding: var(--spacing-component-4);
44
+ text-decoration: none;
45
+ transition:
46
+ box-shadow 0.5s ease-in-out,
47
+ border-color 0.5s ease-in-out;
48
+ width: 100%;
49
+ }
50
+
51
+ a.tile:hover {
52
+ box-shadow: var(--shadow-medium);
53
+ border-color: rgba(0, 0, 0, 0);
54
+ }
55
+
56
+ picture {
57
+ display: grid;
58
+ place-items: center;
59
+ padding-block-end: var(--spacing-layout-1);
60
+ }
61
+
62
+ picture > * {
63
+ height: var(--spacing-layout-4);
64
+ grid-area: 1 / 1;
65
+ }
66
+
67
+ cfa-blob {
68
+ transition: scale 0.5s ease-in-out;
69
+ }
70
+
71
+ a.tile:hover cfa-blob {
72
+ scale: 1.2;
73
+ }
74
+
75
+ img {
76
+ object-fit: contain;
77
+ z-index: 2;
78
+ }
79
+
80
+ .title {
81
+ color: var(--title-color);
82
+ }
83
+
84
+ .label {
85
+ color: var(--action-label-color);
86
+ display: inline-block;
87
+ margin-block-start: auto;
88
+ padding-block-start: var(--spacing-layout-half);
89
+ }
90
+ `,
91
+ ];
92
+ tileContentTemplate() {
93
+ return html`
94
+ ${this.imageUrl
95
+ ? html`
96
+ <picture>
97
+ <cfa-blob></cfa-blob>
98
+ <img
99
+ src="${this.imageUrl}"
100
+ alt="${this.imageAltText}"
101
+ load="lazy"
102
+ />
103
+ </picture>
104
+ `
105
+ : nothing}
106
+
107
+ <div class="title h3">${this.title}</div>
108
+
109
+ <!-- Description -->
110
+ ${this.description
111
+ ? html` <p class="small">${this.description}</p> `
112
+ : nothing}
113
+
114
+ <!-- Action label -->
115
+ ${this.actionLabel
116
+ ? html`
117
+ <div class="label small strong">
118
+ ${this.actionLabel}&nbsp;<cfa-icon>arrow_forward</cfa-icon>
119
+ </div>
120
+ `
121
+ : nothing}
122
+ `;
123
+ }
124
+ render() {
125
+ return html`
126
+ <style>
127
+ cfa-blob {
128
+ --color: var(--blob-color);
129
+ }
130
+ </style>
131
+ ${this.linkUrl
132
+ ? html`
133
+ <a
134
+ href="${this.linkUrl}"
135
+ target="${this.linkTarget}"
136
+ rel="${this.linkTarget == "_blank" ? "noopener" : nothing}"
137
+ class="tile"
138
+ >
139
+ ${this.tileContentTemplate()}
140
+ </a>
141
+ `
142
+ : html` <div class="tile">${this.tileContentTemplate()}</div> `}
143
+ `;
144
+ }
145
+ }
146
+
147
+ if (!customElements.get("cfa-tile")) {
148
+ customElements.define("cfa-tile", Tile);
149
+ }
@@ -0,0 +1,41 @@
1
+ import { html } from "lit-html";
2
+ import "./tile.js";
3
+
4
+ export default {
5
+ title: "Molecules/Tile",
6
+ argTypes: {},
7
+ };
8
+
9
+ const Template = ({
10
+ title,
11
+ description,
12
+ imageUrl,
13
+ imageAltText,
14
+ linkUrl,
15
+ linkTarget,
16
+ actionLabel,
17
+ }) => html`
18
+ <cfa-tile
19
+ title="${title}"
20
+ description="${description}"
21
+ imageUrl="${imageUrl}"
22
+ imageAltText="${imageAltText}"
23
+ linkUrl="${linkUrl}"
24
+ linkTarget="${linkTarget}"
25
+ actionLabel="${actionLabel}"
26
+ >
27
+ </cfa-tile>
28
+ `;
29
+
30
+ export const Default = Template.bind({});
31
+ Default.args = {
32
+ title: "Build equitable systems",
33
+ description:
34
+ "Government services should lead to outcomes that are just and equitable",
35
+ imageUrl: "https://files.codeforamerica.org/2021/05/28124726/equity.svg",
36
+ imageAltText:
37
+ "Icon representing equity, with three people of different heights and the two shorter people standing on a box to be the same height as the tallest person",
38
+ linkUrl: "#",
39
+ linkTarget: "_blank",
40
+ actionLabel: "Learn more",
41
+ };
@@ -0,0 +1,44 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Transcript extends LitElement {
6
+ static styles = [
7
+ commonStyles,
8
+ typographyStyles,
9
+ css`
10
+ :host {
11
+ --label-color: var(--purple-60);
12
+
13
+ display: block;
14
+ max-width: var(--column-span-8);
15
+ }
16
+
17
+ .label {
18
+ --text-color: var(--label-color);
19
+ }
20
+
21
+ .text {
22
+ background-color: var(--white);
23
+ border: var(--hairline) solid var(--black-20);
24
+ color: var(--black);
25
+ height: calc(12 * var(--spacing-layout-1));
26
+ overflow: auto;
27
+ padding: var(--spacing-component-3);
28
+ }
29
+ `,
30
+ ];
31
+
32
+ render() {
33
+ return html`
34
+ <div class="label eyebrow-with-line">Transcript</div>
35
+ <div class="text small">
36
+ <slot />
37
+ </div>
38
+ `;
39
+ }
40
+ }
41
+
42
+ if (!customElements.get("cfa-transcript")) {
43
+ customElements.define("cfa-transcript", Transcript);
44
+ }