@forumone/throughline-reference-ds 0.0.2 → 0.3.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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +102 -28
- package/dist/components/CTASection/CTASection.contract.d.ts +3 -0
- package/dist/components/CTASection/CTASection.contract.d.ts.map +1 -0
- package/dist/components/CTASection/CTASection.contract.js +117 -0
- package/dist/components/CTASection/CTASection.contract.js.map +1 -0
- package/dist/components/CTASection/CTASection.d.ts +17 -0
- package/dist/components/CTASection/CTASection.d.ts.map +1 -0
- package/dist/components/CTASection/CTASection.js +7 -0
- package/dist/components/CTASection/CTASection.js.map +1 -0
- package/dist/components/CTASection/index.d.ts +3 -0
- package/dist/components/CTASection/index.d.ts.map +1 -0
- package/dist/components/CTASection/index.js +3 -0
- package/dist/components/CTASection/index.js.map +1 -0
- package/dist/components/Card/Card.contract.d.ts +3 -0
- package/dist/components/Card/Card.contract.d.ts.map +1 -0
- package/dist/components/Card/Card.contract.js +111 -0
- package/dist/components/Card/Card.contract.js.map +1 -0
- package/dist/components/Card/Card.d.ts +16 -0
- package/dist/components/Card/Card.d.ts.map +1 -0
- package/dist/components/Card/Card.js +11 -0
- package/dist/components/Card/Card.js.map +1 -0
- package/dist/components/Card/index.d.ts +3 -0
- package/dist/components/Card/index.d.ts.map +1 -0
- package/dist/components/Card/index.js +3 -0
- package/dist/components/Card/index.js.map +1 -0
- package/dist/components/CardGrid/CardGrid.contract.d.ts +3 -0
- package/dist/components/CardGrid/CardGrid.contract.d.ts.map +1 -0
- package/dist/components/CardGrid/CardGrid.contract.js +67 -0
- package/dist/components/CardGrid/CardGrid.contract.js.map +1 -0
- package/dist/components/CardGrid/CardGrid.d.ts +9 -0
- package/dist/components/CardGrid/CardGrid.d.ts.map +1 -0
- package/dist/components/CardGrid/CardGrid.js +7 -0
- package/dist/components/CardGrid/CardGrid.js.map +1 -0
- package/dist/components/CardGrid/index.d.ts +3 -0
- package/dist/components/CardGrid/index.d.ts.map +1 -0
- package/dist/components/CardGrid/index.js +3 -0
- package/dist/components/CardGrid/index.js.map +1 -0
- package/dist/components/Divider/Divider.contract.d.ts +3 -0
- package/dist/components/Divider/Divider.contract.d.ts.map +1 -0
- package/dist/components/Divider/Divider.contract.js +77 -0
- package/dist/components/Divider/Divider.contract.js.map +1 -0
- package/dist/components/Divider/Divider.d.ts +8 -0
- package/dist/components/Divider/Divider.d.ts.map +1 -0
- package/dist/components/Divider/Divider.js +10 -0
- package/dist/components/Divider/Divider.js.map +1 -0
- package/dist/components/Divider/index.d.ts +3 -0
- package/dist/components/Divider/index.d.ts.map +1 -0
- package/dist/components/Divider/index.js +3 -0
- package/dist/components/Divider/index.js.map +1 -0
- package/dist/components/FAQ/FAQ.contract.d.ts +3 -0
- package/dist/components/FAQ/FAQ.contract.d.ts.map +1 -0
- package/dist/components/FAQ/FAQ.contract.js +93 -0
- package/dist/components/FAQ/FAQ.contract.js.map +1 -0
- package/dist/components/FAQ/FAQ.d.ts +14 -0
- package/dist/components/FAQ/FAQ.d.ts.map +1 -0
- package/dist/components/FAQ/FAQ.js +7 -0
- package/dist/components/FAQ/FAQ.js.map +1 -0
- package/dist/components/FAQ/index.d.ts +3 -0
- package/dist/components/FAQ/index.d.ts.map +1 -0
- package/dist/components/FAQ/index.js +3 -0
- package/dist/components/FAQ/index.js.map +1 -0
- package/dist/components/Hero/Hero.contract.d.ts +3 -0
- package/dist/components/Hero/Hero.contract.d.ts.map +1 -0
- package/dist/components/Hero/Hero.contract.js +171 -0
- package/dist/components/Hero/Hero.contract.js.map +1 -0
- package/dist/components/Hero/Hero.d.ts +24 -0
- package/dist/components/Hero/Hero.d.ts.map +1 -0
- package/dist/components/Hero/Hero.js +7 -0
- package/dist/components/Hero/Hero.js.map +1 -0
- package/dist/components/Hero/index.d.ts +3 -0
- package/dist/components/Hero/index.d.ts.map +1 -0
- package/dist/components/Hero/index.js +3 -0
- package/dist/components/Hero/index.js.map +1 -0
- package/dist/components/MediaBlock/MediaBlock.contract.d.ts +3 -0
- package/dist/components/MediaBlock/MediaBlock.contract.d.ts.map +1 -0
- package/dist/components/MediaBlock/MediaBlock.contract.js +83 -0
- package/dist/components/MediaBlock/MediaBlock.contract.js.map +1 -0
- package/dist/components/MediaBlock/MediaBlock.d.ts +23 -0
- package/dist/components/MediaBlock/MediaBlock.d.ts.map +1 -0
- package/dist/components/MediaBlock/MediaBlock.js +8 -0
- package/dist/components/MediaBlock/MediaBlock.js.map +1 -0
- package/dist/components/MediaBlock/index.d.ts +3 -0
- package/dist/components/MediaBlock/index.d.ts.map +1 -0
- package/dist/components/MediaBlock/index.js +3 -0
- package/dist/components/MediaBlock/index.js.map +1 -0
- package/dist/components/Prose/Prose.contract.d.ts +3 -0
- package/dist/components/Prose/Prose.contract.d.ts.map +1 -0
- package/dist/components/Prose/Prose.contract.js +95 -0
- package/dist/components/Prose/Prose.contract.js.map +1 -0
- package/dist/components/Prose/Prose.d.ts +9 -0
- package/dist/components/Prose/Prose.d.ts.map +1 -0
- package/dist/components/Prose/Prose.js +7 -0
- package/dist/components/Prose/Prose.js.map +1 -0
- package/dist/components/Prose/index.d.ts +3 -0
- package/dist/components/Prose/index.d.ts.map +1 -0
- package/dist/components/Prose/index.js +3 -0
- package/dist/components/Prose/index.js.map +1 -0
- package/dist/components/Quote/Quote.contract.d.ts +3 -0
- package/dist/components/Quote/Quote.contract.d.ts.map +1 -0
- package/dist/components/Quote/Quote.contract.js +90 -0
- package/dist/components/Quote/Quote.contract.js.map +1 -0
- package/dist/components/Quote/Quote.d.ts +16 -0
- package/dist/components/Quote/Quote.d.ts.map +1 -0
- package/dist/components/Quote/Quote.js +7 -0
- package/dist/components/Quote/Quote.js.map +1 -0
- package/dist/components/Quote/index.d.ts +3 -0
- package/dist/components/Quote/index.d.ts.map +1 -0
- package/dist/components/Quote/index.js +3 -0
- package/dist/components/Quote/index.js.map +1 -0
- package/dist/components/SectionIntro/SectionIntro.contract.d.ts +3 -0
- package/dist/components/SectionIntro/SectionIntro.contract.d.ts.map +1 -0
- package/dist/components/SectionIntro/SectionIntro.contract.js +97 -0
- package/dist/components/SectionIntro/SectionIntro.contract.js.map +1 -0
- package/dist/components/SectionIntro/SectionIntro.d.ts +10 -0
- package/dist/components/SectionIntro/SectionIntro.d.ts.map +1 -0
- package/dist/components/SectionIntro/SectionIntro.js +7 -0
- package/dist/components/SectionIntro/SectionIntro.js.map +1 -0
- package/dist/components/SectionIntro/index.d.ts +3 -0
- package/dist/components/SectionIntro/index.d.ts.map +1 -0
- package/dist/components/SectionIntro/index.js +3 -0
- package/dist/components/SectionIntro/index.js.map +1 -0
- package/dist/components/Spacer/Spacer.contract.d.ts +3 -0
- package/dist/components/Spacer/Spacer.contract.d.ts.map +1 -0
- package/dist/components/Spacer/Spacer.contract.js +66 -0
- package/dist/components/Spacer/Spacer.contract.js.map +1 -0
- package/dist/components/Spacer/Spacer.d.ts +7 -0
- package/dist/components/Spacer/Spacer.d.ts.map +1 -0
- package/dist/components/Spacer/Spacer.js +7 -0
- package/dist/components/Spacer/Spacer.js.map +1 -0
- package/dist/components/Spacer/index.d.ts +3 -0
- package/dist/components/Spacer/index.d.ts.map +1 -0
- package/dist/components/Spacer/index.js +3 -0
- package/dist/components/Spacer/index.js.map +1 -0
- package/dist/components/Stats/Stats.contract.d.ts +3 -0
- package/dist/components/Stats/Stats.contract.d.ts.map +1 -0
- package/dist/components/Stats/Stats.contract.js +92 -0
- package/dist/components/Stats/Stats.contract.js.map +1 -0
- package/dist/components/Stats/Stats.d.ts +13 -0
- package/dist/components/Stats/Stats.d.ts.map +1 -0
- package/dist/components/Stats/Stats.js +7 -0
- package/dist/components/Stats/Stats.js.map +1 -0
- package/dist/components/Stats/index.d.ts +3 -0
- package/dist/components/Stats/index.d.ts.map +1 -0
- package/dist/components/Stats/index.js +3 -0
- package/dist/components/Stats/index.js.map +1 -0
- package/dist/foundations/_helpers.d.ts +16 -0
- package/dist/foundations/_helpers.d.ts.map +1 -0
- package/dist/foundations/_helpers.js +31 -0
- package/dist/foundations/_helpers.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +2059 -0
- package/dist/styles/base.css +55 -0
- package/dist/styles/index.css +224 -0
- package/dist/styles/reset.css +48 -0
- package/dist/styles/tokens.css +116 -0
- package/dist/tokens/colors.d.ts +48 -0
- package/dist/tokens/colors.d.ts.map +1 -0
- package/dist/tokens/colors.js +47 -0
- package/dist/tokens/colors.js.map +1 -0
- package/dist/tokens/index.d.ts +110 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +23 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/layout.d.ts +24 -0
- package/dist/tokens/layout.d.ts.map +1 -0
- package/dist/tokens/layout.js +23 -0
- package/dist/tokens/layout.js.map +1 -0
- package/dist/tokens/radii.d.ts +11 -0
- package/dist/tokens/radii.d.ts.map +1 -0
- package/dist/tokens/radii.js +10 -0
- package/dist/tokens/radii.js.map +1 -0
- package/dist/tokens/spacing.d.ts +26 -0
- package/dist/tokens/spacing.d.ts.map +1 -0
- package/dist/tokens/spacing.js +25 -0
- package/dist/tokens/spacing.js.map +1 -0
- package/dist/tokens/typography.d.ts +28 -0
- package/dist/tokens/typography.d.ts.map +1 -0
- package/dist/tokens/typography.js +27 -0
- package/dist/tokens/typography.js.map +1 -0
- package/package.json +88 -7
|
@@ -0,0 +1,2059 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contractVersion": "1.0.0",
|
|
3
|
+
"designSystem": {
|
|
4
|
+
"name": "@forumone/throughline-reference-ds",
|
|
5
|
+
"version": "0.3.0",
|
|
6
|
+
"description": "A brand-neutral reference design system demonstrating contract compliance for Throughline."
|
|
7
|
+
},
|
|
8
|
+
"tokens": [
|
|
9
|
+
{
|
|
10
|
+
"name": "color.neutral.0",
|
|
11
|
+
"value": "#FFFFFF",
|
|
12
|
+
"category": "color"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "color.neutral.50",
|
|
16
|
+
"value": "#FAFAFA",
|
|
17
|
+
"category": "color"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "color.neutral.100",
|
|
21
|
+
"value": "#F4F4F5",
|
|
22
|
+
"category": "color"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "color.neutral.200",
|
|
26
|
+
"value": "#E4E4E7",
|
|
27
|
+
"category": "color"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "color.neutral.300",
|
|
31
|
+
"value": "#D4D4D8",
|
|
32
|
+
"category": "color"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "color.neutral.400",
|
|
36
|
+
"value": "#A1A1AA",
|
|
37
|
+
"category": "color"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "color.neutral.500",
|
|
41
|
+
"value": "#71717A",
|
|
42
|
+
"category": "color"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "color.neutral.600",
|
|
46
|
+
"value": "#52525B",
|
|
47
|
+
"category": "color"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "color.neutral.700",
|
|
51
|
+
"value": "#3F3F46",
|
|
52
|
+
"category": "color"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "color.neutral.800",
|
|
56
|
+
"value": "#27272A",
|
|
57
|
+
"category": "color"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "color.neutral.900",
|
|
61
|
+
"value": "#18181B",
|
|
62
|
+
"category": "color"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "color.neutral.1000",
|
|
66
|
+
"value": "#000000",
|
|
67
|
+
"category": "color"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "color.brand.primary",
|
|
71
|
+
"value": "#2563EB",
|
|
72
|
+
"category": "color"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "color.brand.primaryHover",
|
|
76
|
+
"value": "#1D4ED8",
|
|
77
|
+
"category": "color"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "color.brand.secondary",
|
|
81
|
+
"value": "#0891B2",
|
|
82
|
+
"category": "color"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "color.text.primary",
|
|
86
|
+
"value": "#18181B",
|
|
87
|
+
"category": "color"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "color.text.secondary",
|
|
91
|
+
"value": "#52525B",
|
|
92
|
+
"category": "color"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "color.text.muted",
|
|
96
|
+
"value": "#71717A",
|
|
97
|
+
"category": "color"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "color.text.inverse",
|
|
101
|
+
"value": "#FFFFFF",
|
|
102
|
+
"category": "color"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "color.bg.primary",
|
|
106
|
+
"value": "#FFFFFF",
|
|
107
|
+
"category": "color"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "color.bg.secondary",
|
|
111
|
+
"value": "#FAFAFA",
|
|
112
|
+
"category": "color"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "color.bg.tertiary",
|
|
116
|
+
"value": "#F4F4F5",
|
|
117
|
+
"category": "color"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "color.bg.inverse",
|
|
121
|
+
"value": "#18181B",
|
|
122
|
+
"category": "color"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "color.border.default",
|
|
126
|
+
"value": "#E4E4E7",
|
|
127
|
+
"category": "color"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "color.border.strong",
|
|
131
|
+
"value": "#D4D4D8",
|
|
132
|
+
"category": "color"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "color.state.success",
|
|
136
|
+
"value": "#16A34A",
|
|
137
|
+
"category": "color"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "color.state.warning",
|
|
141
|
+
"value": "#CA8A04",
|
|
142
|
+
"category": "color"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "color.state.error",
|
|
146
|
+
"value": "#DC2626",
|
|
147
|
+
"category": "color"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"name": "color.state.info",
|
|
151
|
+
"value": "#2563EB",
|
|
152
|
+
"category": "color"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "font.family.sans",
|
|
156
|
+
"value": "Inter, system-ui, -apple-system, BlinkMacSystemFont, sans-serif",
|
|
157
|
+
"category": "font"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"name": "font.family.mono",
|
|
161
|
+
"value": "ui-monospace, \"SF Mono\", Monaco, Consolas, monospace",
|
|
162
|
+
"category": "font"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "font.size.xs",
|
|
166
|
+
"value": "0.75rem",
|
|
167
|
+
"category": "font"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"name": "font.size.sm",
|
|
171
|
+
"value": "0.875rem",
|
|
172
|
+
"category": "font"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "font.size.base",
|
|
176
|
+
"value": "1rem",
|
|
177
|
+
"category": "font"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "font.size.lg",
|
|
181
|
+
"value": "1.125rem",
|
|
182
|
+
"category": "font"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"name": "font.size.xl",
|
|
186
|
+
"value": "1.25rem",
|
|
187
|
+
"category": "font"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"name": "font.size.2xl",
|
|
191
|
+
"value": "1.5rem",
|
|
192
|
+
"category": "font"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"name": "font.size.3xl",
|
|
196
|
+
"value": "1.875rem",
|
|
197
|
+
"category": "font"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "font.size.4xl",
|
|
201
|
+
"value": "2.25rem",
|
|
202
|
+
"category": "font"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"name": "font.size.5xl",
|
|
206
|
+
"value": "3rem",
|
|
207
|
+
"category": "font"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"name": "font.size.6xl",
|
|
211
|
+
"value": "3.75rem",
|
|
212
|
+
"category": "font"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "font.weight.normal",
|
|
216
|
+
"value": "400",
|
|
217
|
+
"category": "font"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "font.weight.medium",
|
|
221
|
+
"value": "500",
|
|
222
|
+
"category": "font"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"name": "font.weight.semibold",
|
|
226
|
+
"value": "600",
|
|
227
|
+
"category": "font"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"name": "font.weight.bold",
|
|
231
|
+
"value": "700",
|
|
232
|
+
"category": "font"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"name": "line.height.tight",
|
|
236
|
+
"value": "1.15",
|
|
237
|
+
"category": "line"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"name": "line.height.snug",
|
|
241
|
+
"value": "1.3",
|
|
242
|
+
"category": "line"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"name": "line.height.normal",
|
|
246
|
+
"value": "1.5",
|
|
247
|
+
"category": "line"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"name": "line.height.relaxed",
|
|
251
|
+
"value": "1.65",
|
|
252
|
+
"category": "line"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "line.height.loose",
|
|
256
|
+
"value": "1.8",
|
|
257
|
+
"category": "line"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "letter.spacing.tight",
|
|
261
|
+
"value": "-0.025em",
|
|
262
|
+
"category": "letter"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"name": "letter.spacing.normal",
|
|
266
|
+
"value": "0",
|
|
267
|
+
"category": "letter"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"name": "letter.spacing.wide",
|
|
271
|
+
"value": "0.025em",
|
|
272
|
+
"category": "letter"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"name": "spacing.0",
|
|
276
|
+
"value": "0",
|
|
277
|
+
"category": "spacing"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "spacing.px",
|
|
281
|
+
"value": "1px",
|
|
282
|
+
"category": "spacing"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"name": "spacing.0.5",
|
|
286
|
+
"value": "0.125rem",
|
|
287
|
+
"category": "spacing"
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"name": "spacing.1",
|
|
291
|
+
"value": "0.25rem",
|
|
292
|
+
"category": "spacing"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"name": "spacing.2",
|
|
296
|
+
"value": "0.5rem",
|
|
297
|
+
"category": "spacing"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"name": "spacing.3",
|
|
301
|
+
"value": "0.75rem",
|
|
302
|
+
"category": "spacing"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "spacing.4",
|
|
306
|
+
"value": "1rem",
|
|
307
|
+
"category": "spacing"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"name": "spacing.5",
|
|
311
|
+
"value": "1.25rem",
|
|
312
|
+
"category": "spacing"
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"name": "spacing.6",
|
|
316
|
+
"value": "1.5rem",
|
|
317
|
+
"category": "spacing"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"name": "spacing.8",
|
|
321
|
+
"value": "2rem",
|
|
322
|
+
"category": "spacing"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"name": "spacing.10",
|
|
326
|
+
"value": "2.5rem",
|
|
327
|
+
"category": "spacing"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"name": "spacing.12",
|
|
331
|
+
"value": "3rem",
|
|
332
|
+
"category": "spacing"
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"name": "spacing.16",
|
|
336
|
+
"value": "4rem",
|
|
337
|
+
"category": "spacing"
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"name": "spacing.20",
|
|
341
|
+
"value": "5rem",
|
|
342
|
+
"category": "spacing"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"name": "spacing.24",
|
|
346
|
+
"value": "6rem",
|
|
347
|
+
"category": "spacing"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
"name": "spacing.32",
|
|
351
|
+
"value": "8rem",
|
|
352
|
+
"category": "spacing"
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"name": "spacing.40",
|
|
356
|
+
"value": "10rem",
|
|
357
|
+
"category": "spacing"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"name": "spacing.48",
|
|
361
|
+
"value": "12rem",
|
|
362
|
+
"category": "spacing"
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"name": "spacing.section",
|
|
366
|
+
"value": "5rem",
|
|
367
|
+
"category": "spacing"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"name": "spacing.container",
|
|
371
|
+
"value": "1.5rem",
|
|
372
|
+
"category": "spacing"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"name": "radius.none",
|
|
376
|
+
"value": "0",
|
|
377
|
+
"category": "radius"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"name": "radius.sm",
|
|
381
|
+
"value": "0.25rem",
|
|
382
|
+
"category": "radius"
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"name": "radius.md",
|
|
386
|
+
"value": "0.375rem",
|
|
387
|
+
"category": "radius"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"name": "radius.lg",
|
|
391
|
+
"value": "0.5rem",
|
|
392
|
+
"category": "radius"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"name": "radius.xl",
|
|
396
|
+
"value": "0.75rem",
|
|
397
|
+
"category": "radius"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"name": "radius.2xl",
|
|
401
|
+
"value": "1rem",
|
|
402
|
+
"category": "radius"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"name": "radius.full",
|
|
406
|
+
"value": "9999px",
|
|
407
|
+
"category": "radius"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"name": "layout.container.sm",
|
|
411
|
+
"value": "40rem",
|
|
412
|
+
"category": "layout"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"name": "layout.container.md",
|
|
416
|
+
"value": "64rem",
|
|
417
|
+
"category": "layout"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"name": "layout.container.lg",
|
|
421
|
+
"value": "80rem",
|
|
422
|
+
"category": "layout"
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"name": "layout.gutter",
|
|
426
|
+
"value": "1.5rem",
|
|
427
|
+
"category": "layout"
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"name": "layout.margin",
|
|
431
|
+
"value": "1rem",
|
|
432
|
+
"category": "layout"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"name": "layout.breakpoint.sm",
|
|
436
|
+
"value": "40rem",
|
|
437
|
+
"category": "layout"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"name": "layout.breakpoint.md",
|
|
441
|
+
"value": "48rem",
|
|
442
|
+
"category": "layout"
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"name": "layout.breakpoint.lg",
|
|
446
|
+
"value": "64rem",
|
|
447
|
+
"category": "layout"
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
"name": "layout.breakpoint.xl",
|
|
451
|
+
"value": "80rem",
|
|
452
|
+
"category": "layout"
|
|
453
|
+
}
|
|
454
|
+
],
|
|
455
|
+
"components": {
|
|
456
|
+
"CTASection": {
|
|
457
|
+
"name": "CTASection",
|
|
458
|
+
"category": "cta",
|
|
459
|
+
"description": "A page-bottom call to action with a headline, optional supporting copy, and one or two buttons.",
|
|
460
|
+
"intent": "Close a page with a clear next step. Use at the end of program pages, campaigns, and marketing pages where the reader has enough context to act. Do not use at the top of a page (that is Hero's job) or as a section opener (that is SectionIntro's).",
|
|
461
|
+
"composition": {
|
|
462
|
+
"placement": [
|
|
463
|
+
"page",
|
|
464
|
+
"section"
|
|
465
|
+
],
|
|
466
|
+
"maxPerPage": 2,
|
|
467
|
+
"requiredSiblings": [],
|
|
468
|
+
"forbiddenAdjacent": [
|
|
469
|
+
"CTASection"
|
|
470
|
+
]
|
|
471
|
+
},
|
|
472
|
+
"content": {
|
|
473
|
+
"fields": [
|
|
474
|
+
{
|
|
475
|
+
"name": "headline",
|
|
476
|
+
"type": "text",
|
|
477
|
+
"required": true,
|
|
478
|
+
"maxLength": 100,
|
|
479
|
+
"constraints": "Direct, imperative; reads like an invitation"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"name": "body",
|
|
483
|
+
"type": "text",
|
|
484
|
+
"required": false,
|
|
485
|
+
"maxLength": 200,
|
|
486
|
+
"constraints": "One sentence that reduces friction to clicking"
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"name": "cta",
|
|
490
|
+
"type": "group",
|
|
491
|
+
"required": true,
|
|
492
|
+
"of": [
|
|
493
|
+
{
|
|
494
|
+
"name": "label",
|
|
495
|
+
"type": "text",
|
|
496
|
+
"required": true,
|
|
497
|
+
"maxLength": 30
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"name": "url",
|
|
501
|
+
"type": "link",
|
|
502
|
+
"required": true
|
|
503
|
+
}
|
|
504
|
+
]
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"name": "secondaryCta",
|
|
508
|
+
"type": "group",
|
|
509
|
+
"required": false,
|
|
510
|
+
"of": [
|
|
511
|
+
{
|
|
512
|
+
"name": "label",
|
|
513
|
+
"type": "text",
|
|
514
|
+
"required": true,
|
|
515
|
+
"maxLength": 30
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"name": "url",
|
|
519
|
+
"type": "link",
|
|
520
|
+
"required": true
|
|
521
|
+
}
|
|
522
|
+
]
|
|
523
|
+
}
|
|
524
|
+
],
|
|
525
|
+
"variants": [
|
|
526
|
+
{
|
|
527
|
+
"name": "primary",
|
|
528
|
+
"description": "Standard background",
|
|
529
|
+
"whenToUse": "Default"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"name": "secondary",
|
|
533
|
+
"description": "Subtle grey background",
|
|
534
|
+
"whenToUse": "Most page closes — less visual weight than Hero"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"name": "inverse",
|
|
538
|
+
"description": "Dark background",
|
|
539
|
+
"whenToUse": "Campaign pages or high-stakes calls to action"
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
},
|
|
543
|
+
"tokens": {
|
|
544
|
+
"consumes": [
|
|
545
|
+
"color.bg.primary",
|
|
546
|
+
"color.bg.secondary",
|
|
547
|
+
"color.bg.inverse",
|
|
548
|
+
"color.text.primary",
|
|
549
|
+
"color.text.secondary",
|
|
550
|
+
"color.text.inverse",
|
|
551
|
+
"color.brand.primary",
|
|
552
|
+
"color.brand.primaryHover",
|
|
553
|
+
"color.border.strong",
|
|
554
|
+
"spacing.section",
|
|
555
|
+
"spacing.container",
|
|
556
|
+
"spacing.8",
|
|
557
|
+
"spacing.6",
|
|
558
|
+
"spacing.4",
|
|
559
|
+
"spacing.3",
|
|
560
|
+
"font.size.4xl",
|
|
561
|
+
"font.size.lg",
|
|
562
|
+
"font.weight.bold",
|
|
563
|
+
"font.weight.semibold",
|
|
564
|
+
"line.height.tight",
|
|
565
|
+
"line.height.relaxed",
|
|
566
|
+
"radius.md"
|
|
567
|
+
],
|
|
568
|
+
"configurable": [
|
|
569
|
+
{
|
|
570
|
+
"prop": "background",
|
|
571
|
+
"tokenGroup": "color.bg",
|
|
572
|
+
"allowedValues": [
|
|
573
|
+
"primary",
|
|
574
|
+
"secondary",
|
|
575
|
+
"inverse"
|
|
576
|
+
]
|
|
577
|
+
}
|
|
578
|
+
]
|
|
579
|
+
},
|
|
580
|
+
"accessibility": {
|
|
581
|
+
"keyboardSupport": [
|
|
582
|
+
"Tab to primary CTA",
|
|
583
|
+
"Tab to secondary CTA"
|
|
584
|
+
],
|
|
585
|
+
"screenReaderBehavior": "The headline is announced as an h2. CTAs are standard links; their label text is announced as the link name.",
|
|
586
|
+
"contentWarnings": [
|
|
587
|
+
"Avoid verb-only labels (\"Click\", \"Go\") — include the destination (\"Start building\", \"Read the docs\")"
|
|
588
|
+
]
|
|
589
|
+
},
|
|
590
|
+
"examples": [
|
|
591
|
+
{
|
|
592
|
+
"label": "Default",
|
|
593
|
+
"intent": "Two-button page close",
|
|
594
|
+
"storyId": "cta-section--default"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"label": "Primary only",
|
|
598
|
+
"intent": "Single-action CTA",
|
|
599
|
+
"storyId": "cta-section--primary-only"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"label": "Inverse",
|
|
603
|
+
"intent": "High-contrast campaign CTA",
|
|
604
|
+
"storyId": "cta-section--inverse"
|
|
605
|
+
}
|
|
606
|
+
],
|
|
607
|
+
"antiExamples": [
|
|
608
|
+
{
|
|
609
|
+
"label": "Three or more CTAs",
|
|
610
|
+
"why": "Too many options reduces conversion; pick the top one, put the rest on a detail page",
|
|
611
|
+
"useInstead": "One primary + optional secondary"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
"label": "Using CTASection as a page opener",
|
|
615
|
+
"why": "Readers cannot convert without context; CTA belongs at the end",
|
|
616
|
+
"useInstead": "Hero"
|
|
617
|
+
}
|
|
618
|
+
],
|
|
619
|
+
"behavior": {
|
|
620
|
+
"fetchesData": false,
|
|
621
|
+
"hasClientState": false,
|
|
622
|
+
"animates": false,
|
|
623
|
+
"requiresAnalytics": true
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
"Card": {
|
|
627
|
+
"name": "Card",
|
|
628
|
+
"category": "card",
|
|
629
|
+
"description": "A single content card with optional image, eyebrow, title, description, and link. Renders as a link when a link target is provided.",
|
|
630
|
+
"intent": "Surface a single piece of content in a scannable, consistent shape — a program page, a blog post, a case study, a staff bio. Cards are typically laid out in a CardGrid, but a single Card can appear alone inside a section when the content warrants singular emphasis.",
|
|
631
|
+
"composition": {
|
|
632
|
+
"placement": [
|
|
633
|
+
"section",
|
|
634
|
+
"inline"
|
|
635
|
+
],
|
|
636
|
+
"maxPerPage": null,
|
|
637
|
+
"requiredSiblings": [],
|
|
638
|
+
"forbiddenAdjacent": []
|
|
639
|
+
},
|
|
640
|
+
"content": {
|
|
641
|
+
"fields": [
|
|
642
|
+
{
|
|
643
|
+
"name": "eyebrow",
|
|
644
|
+
"type": "text",
|
|
645
|
+
"required": false,
|
|
646
|
+
"maxLength": 30,
|
|
647
|
+
"constraints": "Short label such as the content type (\"Case study\", \"Program update\")"
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
"name": "image",
|
|
651
|
+
"type": "image",
|
|
652
|
+
"required": false,
|
|
653
|
+
"constraints": "Landscape orientation; framing works best for images that read at small sizes"
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
"name": "title",
|
|
657
|
+
"type": "text",
|
|
658
|
+
"required": true,
|
|
659
|
+
"maxLength": 100,
|
|
660
|
+
"constraints": "Sentence case; reads like a headline"
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"name": "description",
|
|
664
|
+
"type": "text",
|
|
665
|
+
"required": false,
|
|
666
|
+
"maxLength": 200,
|
|
667
|
+
"constraints": "One to two sentences that give the reader a reason to click"
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"name": "link",
|
|
671
|
+
"type": "group",
|
|
672
|
+
"required": false,
|
|
673
|
+
"of": [
|
|
674
|
+
{
|
|
675
|
+
"name": "label",
|
|
676
|
+
"type": "text",
|
|
677
|
+
"required": true,
|
|
678
|
+
"maxLength": 30
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
"name": "url",
|
|
682
|
+
"type": "link",
|
|
683
|
+
"required": true
|
|
684
|
+
}
|
|
685
|
+
]
|
|
686
|
+
}
|
|
687
|
+
],
|
|
688
|
+
"variants": [
|
|
689
|
+
{
|
|
690
|
+
"name": "linked",
|
|
691
|
+
"description": "Entire card is clickable",
|
|
692
|
+
"whenToUse": "Teaser for a single piece of content"
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
"name": "static",
|
|
696
|
+
"description": "No link; presentational only",
|
|
697
|
+
"whenToUse": "Inline informational cards (team bios, program descriptions) that do not link elsewhere"
|
|
698
|
+
}
|
|
699
|
+
]
|
|
700
|
+
},
|
|
701
|
+
"tokens": {
|
|
702
|
+
"consumes": [
|
|
703
|
+
"color.bg.primary",
|
|
704
|
+
"color.bg.tertiary",
|
|
705
|
+
"color.text.primary",
|
|
706
|
+
"color.text.secondary",
|
|
707
|
+
"color.border.default",
|
|
708
|
+
"color.border.strong",
|
|
709
|
+
"color.brand.primary",
|
|
710
|
+
"spacing.6",
|
|
711
|
+
"spacing.2",
|
|
712
|
+
"font.size.xl",
|
|
713
|
+
"font.size.base",
|
|
714
|
+
"font.size.sm",
|
|
715
|
+
"font.size.xs",
|
|
716
|
+
"font.weight.semibold",
|
|
717
|
+
"line.height.snug",
|
|
718
|
+
"line.height.normal",
|
|
719
|
+
"letter.spacing.wide",
|
|
720
|
+
"radius.lg"
|
|
721
|
+
]
|
|
722
|
+
},
|
|
723
|
+
"accessibility": {
|
|
724
|
+
"keyboardSupport": [
|
|
725
|
+
"When linked, the whole card is a single tab stop"
|
|
726
|
+
],
|
|
727
|
+
"screenReaderBehavior": "Linked cards render as a single <a> element announcing the title + description + link label as one unit. Static cards render as <article> with an h3 title.",
|
|
728
|
+
"contentWarnings": [
|
|
729
|
+
"Avoid nested interactive elements inside a linked card (buttons, additional links)",
|
|
730
|
+
"Always author alt text for card images or omit the image entirely"
|
|
731
|
+
]
|
|
732
|
+
},
|
|
733
|
+
"examples": [
|
|
734
|
+
{
|
|
735
|
+
"label": "Default",
|
|
736
|
+
"intent": "Content teaser with image and link",
|
|
737
|
+
"storyId": "card--default"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
"label": "With eyebrow",
|
|
741
|
+
"intent": "Labeled teaser highlighting content type",
|
|
742
|
+
"storyId": "card--with-eyebrow"
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
"label": "No image",
|
|
746
|
+
"intent": "Text-only teaser for resources or downloads",
|
|
747
|
+
"storyId": "card--no-image"
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"label": "Static",
|
|
751
|
+
"intent": "Presentational card without a link target",
|
|
752
|
+
"storyId": "card--static"
|
|
753
|
+
}
|
|
754
|
+
],
|
|
755
|
+
"antiExamples": [
|
|
756
|
+
{
|
|
757
|
+
"label": "Nesting interactive controls inside a linked card",
|
|
758
|
+
"why": "A linked card is a single tab stop; adding buttons or additional links creates nested interactive regions that confuse assistive technology",
|
|
759
|
+
"useInstead": "Use a static card with explicit nested controls, or move secondary actions to a detail page"
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"label": "Using Card as a navigation menu item",
|
|
763
|
+
"why": "Cards are for content teasers; site navigation belongs in a Menu or Nav component",
|
|
764
|
+
"useInstead": "A dedicated navigation component"
|
|
765
|
+
}
|
|
766
|
+
],
|
|
767
|
+
"behavior": {
|
|
768
|
+
"fetchesData": false,
|
|
769
|
+
"hasClientState": false,
|
|
770
|
+
"animates": false,
|
|
771
|
+
"requiresAnalytics": false
|
|
772
|
+
}
|
|
773
|
+
},
|
|
774
|
+
"CardGrid": {
|
|
775
|
+
"name": "CardGrid",
|
|
776
|
+
"category": "section",
|
|
777
|
+
"description": "A responsive layout container for two, three, or four Cards per row. Reflows to fewer columns on narrow viewports.",
|
|
778
|
+
"intent": "Lay out multiple Card components inside a section. Use for program lists, blog indexes, staff directories, and any collection of similarly-shaped content. CardGrid is purely layout; it does not fetch data or filter — authors list the Cards they want.",
|
|
779
|
+
"composition": {
|
|
780
|
+
"placement": [
|
|
781
|
+
"section"
|
|
782
|
+
],
|
|
783
|
+
"maxPerPage": null,
|
|
784
|
+
"requiredSiblings": [
|
|
785
|
+
"Card"
|
|
786
|
+
],
|
|
787
|
+
"forbiddenAdjacent": [],
|
|
788
|
+
"allowedSlots": {
|
|
789
|
+
"children": [
|
|
790
|
+
"Card"
|
|
791
|
+
]
|
|
792
|
+
}
|
|
793
|
+
},
|
|
794
|
+
"content": {
|
|
795
|
+
"fields": [
|
|
796
|
+
{
|
|
797
|
+
"name": "children",
|
|
798
|
+
"type": "array",
|
|
799
|
+
"required": true,
|
|
800
|
+
"constraints": "An array of Card components",
|
|
801
|
+
"of": [
|
|
802
|
+
{
|
|
803
|
+
"name": "card",
|
|
804
|
+
"type": "group",
|
|
805
|
+
"required": true
|
|
806
|
+
}
|
|
807
|
+
]
|
|
808
|
+
}
|
|
809
|
+
],
|
|
810
|
+
"variants": [
|
|
811
|
+
{
|
|
812
|
+
"name": "2",
|
|
813
|
+
"description": "Two columns",
|
|
814
|
+
"whenToUse": "Lists of 2-4 prominent items"
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
"name": "3",
|
|
818
|
+
"description": "Three columns",
|
|
819
|
+
"whenToUse": "Default — works for most collections"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
"name": "4",
|
|
823
|
+
"description": "Four columns",
|
|
824
|
+
"whenToUse": "Denser lists of 8 or more short cards"
|
|
825
|
+
}
|
|
826
|
+
]
|
|
827
|
+
},
|
|
828
|
+
"tokens": {
|
|
829
|
+
"consumes": [
|
|
830
|
+
"spacing.container",
|
|
831
|
+
"spacing.6"
|
|
832
|
+
],
|
|
833
|
+
"configurable": [
|
|
834
|
+
{
|
|
835
|
+
"prop": "columns",
|
|
836
|
+
"tokenGroup": "layout",
|
|
837
|
+
"allowedValues": [
|
|
838
|
+
"2",
|
|
839
|
+
"3",
|
|
840
|
+
"4"
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
]
|
|
844
|
+
},
|
|
845
|
+
"accessibility": {
|
|
846
|
+
"keyboardSupport": [],
|
|
847
|
+
"screenReaderBehavior": "Purely visual layout. Screen readers traverse children in source order; CardGrid itself adds no ARIA.",
|
|
848
|
+
"contentWarnings": [
|
|
849
|
+
"Children must be Cards; mixing other components breaks the visual rhythm",
|
|
850
|
+
"Keep all cards roughly the same content length — dramatically unequal cards look broken"
|
|
851
|
+
]
|
|
852
|
+
},
|
|
853
|
+
"examples": [
|
|
854
|
+
{
|
|
855
|
+
"label": "Two columns",
|
|
856
|
+
"intent": "Featured program pair",
|
|
857
|
+
"storyId": "card-grid--two-column"
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
"label": "Three columns",
|
|
861
|
+
"intent": "Standard content index",
|
|
862
|
+
"storyId": "card-grid--three-column"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
"label": "Four columns",
|
|
866
|
+
"intent": "Dense staff directory",
|
|
867
|
+
"storyId": "card-grid--four-column"
|
|
868
|
+
}
|
|
869
|
+
],
|
|
870
|
+
"antiExamples": [
|
|
871
|
+
{
|
|
872
|
+
"label": "Mixing Cards and non-Card children",
|
|
873
|
+
"why": "The grid assumes uniform children; mixing Stats or MediaBlocks produces broken columns",
|
|
874
|
+
"useInstead": "Group by type — one CardGrid, then the other components below"
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
"label": "Using CardGrid with a single Card",
|
|
878
|
+
"why": "A CardGrid wrapping one Card is overhead without benefit",
|
|
879
|
+
"useInstead": "Render the Card directly"
|
|
880
|
+
}
|
|
881
|
+
],
|
|
882
|
+
"behavior": {
|
|
883
|
+
"fetchesData": false,
|
|
884
|
+
"hasClientState": false,
|
|
885
|
+
"animates": false,
|
|
886
|
+
"requiresAnalytics": false
|
|
887
|
+
}
|
|
888
|
+
},
|
|
889
|
+
"Divider": {
|
|
890
|
+
"name": "Divider",
|
|
891
|
+
"category": "utility",
|
|
892
|
+
"description": "A horizontal rule for separating sections of content.",
|
|
893
|
+
"intent": "Mark a visual pause between two blocks of content without introducing a new section header. Use sparingly — a SectionIntro is usually a better signal of a new topic. Divider is for rhythm, not hierarchy.",
|
|
894
|
+
"composition": {
|
|
895
|
+
"placement": [
|
|
896
|
+
"page",
|
|
897
|
+
"section",
|
|
898
|
+
"inline"
|
|
899
|
+
],
|
|
900
|
+
"maxPerPage": null,
|
|
901
|
+
"requiredSiblings": [],
|
|
902
|
+
"forbiddenAdjacent": [
|
|
903
|
+
"Divider"
|
|
904
|
+
]
|
|
905
|
+
},
|
|
906
|
+
"content": {
|
|
907
|
+
"fields": [
|
|
908
|
+
{
|
|
909
|
+
"name": "spacing",
|
|
910
|
+
"type": "select",
|
|
911
|
+
"required": false,
|
|
912
|
+
"constraints": "compact | default | spacious"
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
"name": "decorative",
|
|
916
|
+
"type": "boolean",
|
|
917
|
+
"required": false,
|
|
918
|
+
"constraints": "When true (default), the divider is aria-hidden"
|
|
919
|
+
}
|
|
920
|
+
],
|
|
921
|
+
"variants": [
|
|
922
|
+
{
|
|
923
|
+
"name": "compact",
|
|
924
|
+
"description": "Small vertical margin",
|
|
925
|
+
"whenToUse": "Between tight pieces of content inside a list"
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"name": "default",
|
|
929
|
+
"description": "Standard vertical margin",
|
|
930
|
+
"whenToUse": "Most cases"
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
"name": "spacious",
|
|
934
|
+
"description": "Large vertical margin",
|
|
935
|
+
"whenToUse": "Between major sections of a page"
|
|
936
|
+
}
|
|
937
|
+
]
|
|
938
|
+
},
|
|
939
|
+
"tokens": {
|
|
940
|
+
"consumes": [
|
|
941
|
+
"color.border.default",
|
|
942
|
+
"spacing.24",
|
|
943
|
+
"spacing.12",
|
|
944
|
+
"spacing.6"
|
|
945
|
+
],
|
|
946
|
+
"configurable": [
|
|
947
|
+
{
|
|
948
|
+
"prop": "spacing",
|
|
949
|
+
"tokenGroup": "spacing",
|
|
950
|
+
"allowedValues": [
|
|
951
|
+
"compact",
|
|
952
|
+
"default",
|
|
953
|
+
"spacious"
|
|
954
|
+
]
|
|
955
|
+
}
|
|
956
|
+
]
|
|
957
|
+
},
|
|
958
|
+
"accessibility": {
|
|
959
|
+
"role": "separator",
|
|
960
|
+
"keyboardSupport": [],
|
|
961
|
+
"screenReaderBehavior": "When decorative=true (default) the divider is marked aria-hidden and assistive tech skips it. When decorative=false it announces as a separator.",
|
|
962
|
+
"contentWarnings": [
|
|
963
|
+
"Do not stack two Dividers in a row"
|
|
964
|
+
]
|
|
965
|
+
},
|
|
966
|
+
"examples": [
|
|
967
|
+
{
|
|
968
|
+
"label": "Default",
|
|
969
|
+
"intent": "Standard section break",
|
|
970
|
+
"storyId": "divider--default"
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
"label": "Compact",
|
|
974
|
+
"intent": "Between related list items",
|
|
975
|
+
"storyId": "divider--compact"
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
"label": "Spacious",
|
|
979
|
+
"intent": "Between major page sections",
|
|
980
|
+
"storyId": "divider--spacious"
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
"label": "Meaningful",
|
|
984
|
+
"intent": "Semantic section break announced by screen readers",
|
|
985
|
+
"storyId": "divider--meaningful"
|
|
986
|
+
}
|
|
987
|
+
],
|
|
988
|
+
"antiExamples": [
|
|
989
|
+
{
|
|
990
|
+
"label": "Using Divider instead of SectionIntro",
|
|
991
|
+
"why": "Dividers carry no semantic meaning; readers cannot tell a new section has started without the accompanying headline",
|
|
992
|
+
"useInstead": "SectionIntro"
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
"label": "Decorative dividers announced to screen readers",
|
|
996
|
+
"why": "Adds noise without value",
|
|
997
|
+
"useInstead": "Leave decorative=true (the default)"
|
|
998
|
+
}
|
|
999
|
+
],
|
|
1000
|
+
"behavior": {
|
|
1001
|
+
"fetchesData": false,
|
|
1002
|
+
"hasClientState": false,
|
|
1003
|
+
"animates": false,
|
|
1004
|
+
"requiresAnalytics": false
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
"FAQ": {
|
|
1008
|
+
"name": "FAQ",
|
|
1009
|
+
"category": "data",
|
|
1010
|
+
"description": "A disclosure-style question and answer list using native <details>/<summary> for keyboard accessibility with no JavaScript.",
|
|
1011
|
+
"intent": "Answer the predictable questions readers arrive with. Use for program applications, purchase funnels, onboarding pages — anywhere the same three to ten questions come up repeatedly. Not for searchable knowledge bases (those need their own search UI).",
|
|
1012
|
+
"composition": {
|
|
1013
|
+
"placement": [
|
|
1014
|
+
"section"
|
|
1015
|
+
],
|
|
1016
|
+
"maxPerPage": 2,
|
|
1017
|
+
"requiredSiblings": [],
|
|
1018
|
+
"forbiddenAdjacent": []
|
|
1019
|
+
},
|
|
1020
|
+
"content": {
|
|
1021
|
+
"fields": [
|
|
1022
|
+
{
|
|
1023
|
+
"name": "headline",
|
|
1024
|
+
"type": "text",
|
|
1025
|
+
"required": false,
|
|
1026
|
+
"maxLength": 100
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
"name": "items",
|
|
1030
|
+
"type": "array",
|
|
1031
|
+
"required": true,
|
|
1032
|
+
"constraints": "Three to ten items; more than that needs its own dedicated page",
|
|
1033
|
+
"of": [
|
|
1034
|
+
{
|
|
1035
|
+
"name": "question",
|
|
1036
|
+
"type": "text",
|
|
1037
|
+
"required": true,
|
|
1038
|
+
"maxLength": 200
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
"name": "answer",
|
|
1042
|
+
"type": "richtext",
|
|
1043
|
+
"required": true
|
|
1044
|
+
}
|
|
1045
|
+
]
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
"name": "defaultOpenFirst",
|
|
1049
|
+
"type": "boolean",
|
|
1050
|
+
"required": false,
|
|
1051
|
+
"constraints": "Set true when the first question is one readers always ask"
|
|
1052
|
+
}
|
|
1053
|
+
]
|
|
1054
|
+
},
|
|
1055
|
+
"tokens": {
|
|
1056
|
+
"consumes": [
|
|
1057
|
+
"color.bg.primary",
|
|
1058
|
+
"color.text.primary",
|
|
1059
|
+
"color.text.secondary",
|
|
1060
|
+
"color.border.default",
|
|
1061
|
+
"color.border.strong",
|
|
1062
|
+
"spacing.16",
|
|
1063
|
+
"spacing.8",
|
|
1064
|
+
"spacing.5",
|
|
1065
|
+
"spacing.4",
|
|
1066
|
+
"spacing.2",
|
|
1067
|
+
"spacing.container",
|
|
1068
|
+
"font.size.3xl",
|
|
1069
|
+
"font.size.xl",
|
|
1070
|
+
"font.weight.semibold",
|
|
1071
|
+
"line.height.relaxed",
|
|
1072
|
+
"radius.md"
|
|
1073
|
+
]
|
|
1074
|
+
},
|
|
1075
|
+
"accessibility": {
|
|
1076
|
+
"keyboardSupport": [
|
|
1077
|
+
"Tab to each question summary",
|
|
1078
|
+
"Enter or Space opens/closes the current item"
|
|
1079
|
+
],
|
|
1080
|
+
"screenReaderBehavior": "Each question is a <summary> inside <details>, so screen readers announce open/closed state natively. The answer becomes available to assistive tech when the item is expanded.",
|
|
1081
|
+
"contentWarnings": [
|
|
1082
|
+
"Keep answers short and scannable — a paragraph at most",
|
|
1083
|
+
"Do not nest FAQs inside FAQs"
|
|
1084
|
+
]
|
|
1085
|
+
},
|
|
1086
|
+
"examples": [
|
|
1087
|
+
{
|
|
1088
|
+
"label": "Default",
|
|
1089
|
+
"intent": "Program application FAQ",
|
|
1090
|
+
"storyId": "faq--default"
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
"label": "First item open",
|
|
1094
|
+
"intent": "Lead with the most common question already answered",
|
|
1095
|
+
"storyId": "faq--open-first"
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
"label": "Without headline",
|
|
1099
|
+
"intent": "Inline FAQ under a larger section",
|
|
1100
|
+
"storyId": "faq--no-headline"
|
|
1101
|
+
}
|
|
1102
|
+
],
|
|
1103
|
+
"antiExamples": [
|
|
1104
|
+
{
|
|
1105
|
+
"label": "Twenty-question FAQ",
|
|
1106
|
+
"why": "Past about ten items the disclosure pattern breaks down; readers cannot scan the list",
|
|
1107
|
+
"useInstead": "Split into topic-specific FAQs across multiple pages, or build a searchable knowledge base"
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
"label": "Using FAQ to hide primary content",
|
|
1111
|
+
"why": "Important content should be visible by default, not hidden behind a click",
|
|
1112
|
+
"useInstead": "Prose or a proper section with a SectionIntro"
|
|
1113
|
+
}
|
|
1114
|
+
],
|
|
1115
|
+
"behavior": {
|
|
1116
|
+
"fetchesData": false,
|
|
1117
|
+
"hasClientState": true,
|
|
1118
|
+
"animates": false,
|
|
1119
|
+
"requiresAnalytics": false
|
|
1120
|
+
}
|
|
1121
|
+
},
|
|
1122
|
+
"Hero": {
|
|
1123
|
+
"name": "Hero",
|
|
1124
|
+
"category": "hero",
|
|
1125
|
+
"description": "A page opener with prominent headline, supporting copy, and primary call to action.",
|
|
1126
|
+
"intent": "Establish what a page is about within the first viewport. Use when the page introduces a new topic, program, or initiative that deserves prominent editorial framing. Typically appears once at the top of a page.",
|
|
1127
|
+
"composition": {
|
|
1128
|
+
"placement": [
|
|
1129
|
+
"page"
|
|
1130
|
+
],
|
|
1131
|
+
"maxPerPage": 1,
|
|
1132
|
+
"requiredSiblings": [],
|
|
1133
|
+
"forbiddenAdjacent": [
|
|
1134
|
+
"Hero",
|
|
1135
|
+
"SectionIntro"
|
|
1136
|
+
]
|
|
1137
|
+
},
|
|
1138
|
+
"content": {
|
|
1139
|
+
"fields": [
|
|
1140
|
+
{
|
|
1141
|
+
"name": "eyebrow",
|
|
1142
|
+
"type": "text",
|
|
1143
|
+
"required": false,
|
|
1144
|
+
"maxLength": 40,
|
|
1145
|
+
"constraints": "Short kicker label, typically the section or program name"
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
"name": "headline",
|
|
1149
|
+
"type": "text",
|
|
1150
|
+
"required": true,
|
|
1151
|
+
"maxLength": 80,
|
|
1152
|
+
"constraints": "Sentence case; avoid all caps; keep scannable"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
"name": "body",
|
|
1156
|
+
"type": "text",
|
|
1157
|
+
"required": false,
|
|
1158
|
+
"maxLength": 240,
|
|
1159
|
+
"constraints": "Two to three sentences that support the headline without repeating it"
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
"name": "cta",
|
|
1163
|
+
"type": "group",
|
|
1164
|
+
"required": false,
|
|
1165
|
+
"of": [
|
|
1166
|
+
{
|
|
1167
|
+
"name": "label",
|
|
1168
|
+
"type": "text",
|
|
1169
|
+
"required": true,
|
|
1170
|
+
"maxLength": 30
|
|
1171
|
+
},
|
|
1172
|
+
{
|
|
1173
|
+
"name": "url",
|
|
1174
|
+
"type": "link",
|
|
1175
|
+
"required": true
|
|
1176
|
+
}
|
|
1177
|
+
]
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
"name": "secondaryCta",
|
|
1181
|
+
"type": "group",
|
|
1182
|
+
"required": false,
|
|
1183
|
+
"of": [
|
|
1184
|
+
{
|
|
1185
|
+
"name": "label",
|
|
1186
|
+
"type": "text",
|
|
1187
|
+
"required": true,
|
|
1188
|
+
"maxLength": 30
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
"name": "url",
|
|
1192
|
+
"type": "link",
|
|
1193
|
+
"required": true
|
|
1194
|
+
}
|
|
1195
|
+
]
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
"name": "media",
|
|
1199
|
+
"type": "image",
|
|
1200
|
+
"required": false,
|
|
1201
|
+
"constraints": "Required when variant is \"split\"; otherwise optional"
|
|
1202
|
+
}
|
|
1203
|
+
],
|
|
1204
|
+
"variants": [
|
|
1205
|
+
{
|
|
1206
|
+
"name": "default",
|
|
1207
|
+
"description": "Centered text, no media",
|
|
1208
|
+
"whenToUse": "Editorial pages and mission statements where content carries the weight"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
"name": "compact",
|
|
1212
|
+
"description": "Reduced vertical padding",
|
|
1213
|
+
"whenToUse": "Subpages where the hero is contextual framing rather than primary introduction"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
"name": "split",
|
|
1217
|
+
"description": "Text on one side, media on the other",
|
|
1218
|
+
"whenToUse": "Program pages or anywhere a single supporting image carries meaning"
|
|
1219
|
+
}
|
|
1220
|
+
]
|
|
1221
|
+
},
|
|
1222
|
+
"tokens": {
|
|
1223
|
+
"consumes": [
|
|
1224
|
+
"color.bg.primary",
|
|
1225
|
+
"color.bg.secondary",
|
|
1226
|
+
"color.bg.inverse",
|
|
1227
|
+
"color.text.primary",
|
|
1228
|
+
"color.text.secondary",
|
|
1229
|
+
"color.text.inverse",
|
|
1230
|
+
"color.brand.primary",
|
|
1231
|
+
"color.brand.primaryHover",
|
|
1232
|
+
"color.border.strong",
|
|
1233
|
+
"spacing.section",
|
|
1234
|
+
"spacing.container",
|
|
1235
|
+
"spacing.12",
|
|
1236
|
+
"spacing.8",
|
|
1237
|
+
"spacing.6",
|
|
1238
|
+
"spacing.4",
|
|
1239
|
+
"spacing.3",
|
|
1240
|
+
"font.size.5xl",
|
|
1241
|
+
"font.size.4xl",
|
|
1242
|
+
"font.size.xl",
|
|
1243
|
+
"font.size.sm",
|
|
1244
|
+
"font.weight.bold",
|
|
1245
|
+
"font.weight.semibold",
|
|
1246
|
+
"line.height.tight",
|
|
1247
|
+
"line.height.relaxed",
|
|
1248
|
+
"letter.spacing.tight",
|
|
1249
|
+
"letter.spacing.wide",
|
|
1250
|
+
"radius.md",
|
|
1251
|
+
"radius.lg"
|
|
1252
|
+
],
|
|
1253
|
+
"configurable": [
|
|
1254
|
+
{
|
|
1255
|
+
"prop": "background",
|
|
1256
|
+
"tokenGroup": "color.bg",
|
|
1257
|
+
"allowedValues": [
|
|
1258
|
+
"primary",
|
|
1259
|
+
"secondary",
|
|
1260
|
+
"inverse"
|
|
1261
|
+
]
|
|
1262
|
+
}
|
|
1263
|
+
]
|
|
1264
|
+
},
|
|
1265
|
+
"accessibility": {
|
|
1266
|
+
"keyboardSupport": [
|
|
1267
|
+
"Tab to primary CTA",
|
|
1268
|
+
"Tab to secondary CTA"
|
|
1269
|
+
],
|
|
1270
|
+
"screenReaderBehavior": "The headline is announced as an h1 element. The eyebrow is read as supplementary text before the headline. Decorative media is treated as presentational when the alt attribute is empty.",
|
|
1271
|
+
"contentWarnings": [
|
|
1272
|
+
"Avoid text overlay on busy images",
|
|
1273
|
+
"Ensure sufficient color contrast between headline and background"
|
|
1274
|
+
]
|
|
1275
|
+
},
|
|
1276
|
+
"examples": [
|
|
1277
|
+
{
|
|
1278
|
+
"label": "Default",
|
|
1279
|
+
"intent": "Standard editorial page opener with CTA",
|
|
1280
|
+
"storyId": "hero--default"
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
"label": "Program landing page",
|
|
1284
|
+
"intent": "Introduce a new fellowship program",
|
|
1285
|
+
"storyId": "hero--program-landing"
|
|
1286
|
+
},
|
|
1287
|
+
{
|
|
1288
|
+
"label": "Compact subpage",
|
|
1289
|
+
"intent": "Open a secondary page with light framing",
|
|
1290
|
+
"storyId": "hero--compact"
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
"label": "Split with media",
|
|
1294
|
+
"intent": "Open a content page with supporting visual context",
|
|
1295
|
+
"storyId": "hero--split"
|
|
1296
|
+
}
|
|
1297
|
+
],
|
|
1298
|
+
"antiExamples": [
|
|
1299
|
+
{
|
|
1300
|
+
"label": "Multiple heroes on one page",
|
|
1301
|
+
"why": "A page should have a single primary opener; multiple heroes flatten hierarchy and confuse screen readers with multiple h1s",
|
|
1302
|
+
"useInstead": "Use SectionIntro for secondary section headers"
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
"label": "Hero at the bottom of a page",
|
|
1306
|
+
"why": "Heroes are editorial openers, not closers",
|
|
1307
|
+
"useInstead": "Use CTASection for page-bottom calls to action"
|
|
1308
|
+
},
|
|
1309
|
+
{
|
|
1310
|
+
"label": "Split variant without media",
|
|
1311
|
+
"why": "The split layout allocates half the space for media; leaving it empty creates awkward whitespace",
|
|
1312
|
+
"useInstead": "Use the default variant when media is not available"
|
|
1313
|
+
}
|
|
1314
|
+
],
|
|
1315
|
+
"behavior": {
|
|
1316
|
+
"fetchesData": false,
|
|
1317
|
+
"hasClientState": false,
|
|
1318
|
+
"animates": false,
|
|
1319
|
+
"requiresAnalytics": false
|
|
1320
|
+
}
|
|
1321
|
+
},
|
|
1322
|
+
"MediaBlock": {
|
|
1323
|
+
"name": "MediaBlock",
|
|
1324
|
+
"category": "media",
|
|
1325
|
+
"description": "A full-width image or video block with optional caption and configurable aspect ratio.",
|
|
1326
|
+
"intent": "Insert a single piece of featured media inside a content flow. Use for editorial imagery that deserves its own moment — a photograph illustrating a story, a portrait accompanying a quote, or a video introducing a program. Not a gallery; for multiple items compose a custom layout.",
|
|
1327
|
+
"composition": {
|
|
1328
|
+
"placement": [
|
|
1329
|
+
"section"
|
|
1330
|
+
],
|
|
1331
|
+
"maxPerPage": null,
|
|
1332
|
+
"requiredSiblings": [],
|
|
1333
|
+
"forbiddenAdjacent": []
|
|
1334
|
+
},
|
|
1335
|
+
"content": {
|
|
1336
|
+
"fields": [
|
|
1337
|
+
{
|
|
1338
|
+
"name": "media",
|
|
1339
|
+
"type": "group",
|
|
1340
|
+
"required": true,
|
|
1341
|
+
"of": [
|
|
1342
|
+
{
|
|
1343
|
+
"name": "type",
|
|
1344
|
+
"type": "select",
|
|
1345
|
+
"required": true
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
"name": "url",
|
|
1349
|
+
"type": "link",
|
|
1350
|
+
"required": true
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
"name": "alt",
|
|
1354
|
+
"type": "text",
|
|
1355
|
+
"required": false,
|
|
1356
|
+
"maxLength": 200
|
|
1357
|
+
},
|
|
1358
|
+
{
|
|
1359
|
+
"name": "poster",
|
|
1360
|
+
"type": "image",
|
|
1361
|
+
"required": false
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
"name": "ariaLabel",
|
|
1365
|
+
"type": "text",
|
|
1366
|
+
"required": false,
|
|
1367
|
+
"maxLength": 120
|
|
1368
|
+
}
|
|
1369
|
+
]
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
"name": "caption",
|
|
1373
|
+
"type": "text",
|
|
1374
|
+
"required": false,
|
|
1375
|
+
"maxLength": 200,
|
|
1376
|
+
"constraints": "One sentence that adds context the image alone cannot carry"
|
|
1377
|
+
}
|
|
1378
|
+
],
|
|
1379
|
+
"variants": [
|
|
1380
|
+
{
|
|
1381
|
+
"name": "16:9",
|
|
1382
|
+
"description": "Cinematic widescreen",
|
|
1383
|
+
"whenToUse": "Most photographs and video"
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
"name": "4:3",
|
|
1387
|
+
"description": "Classic television ratio",
|
|
1388
|
+
"whenToUse": "Vintage or squared compositions"
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"name": "square",
|
|
1392
|
+
"description": "1:1",
|
|
1393
|
+
"whenToUse": "Portraits or product shots"
|
|
1394
|
+
},
|
|
1395
|
+
{
|
|
1396
|
+
"name": "auto",
|
|
1397
|
+
"description": "Media's native ratio",
|
|
1398
|
+
"whenToUse": "Diagrams, infographics, or tall images"
|
|
1399
|
+
}
|
|
1400
|
+
]
|
|
1401
|
+
},
|
|
1402
|
+
"tokens": {
|
|
1403
|
+
"consumes": [
|
|
1404
|
+
"color.bg.tertiary",
|
|
1405
|
+
"color.text.secondary",
|
|
1406
|
+
"spacing.container",
|
|
1407
|
+
"spacing.3",
|
|
1408
|
+
"font.size.sm",
|
|
1409
|
+
"radius.lg"
|
|
1410
|
+
]
|
|
1411
|
+
},
|
|
1412
|
+
"accessibility": {
|
|
1413
|
+
"keyboardSupport": [
|
|
1414
|
+
"Video: native play/pause/seek controls"
|
|
1415
|
+
],
|
|
1416
|
+
"screenReaderBehavior": "Images announce their alt text. Videos announce their aria-label (or fall back to native labeling). Captions are associated with the figure semantically via <figcaption>.",
|
|
1417
|
+
"contentWarnings": [
|
|
1418
|
+
"Always author alt text for images that carry information; use empty alt (\"\") for purely decorative media",
|
|
1419
|
+
"Videos with spoken content must ship captions"
|
|
1420
|
+
]
|
|
1421
|
+
},
|
|
1422
|
+
"examples": [
|
|
1423
|
+
{
|
|
1424
|
+
"label": "Image with caption",
|
|
1425
|
+
"intent": "Editorial photograph",
|
|
1426
|
+
"storyId": "media-block--image"
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
"label": "Square crop",
|
|
1430
|
+
"intent": "Portrait or product shot",
|
|
1431
|
+
"storyId": "media-block--square"
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
"label": "Video",
|
|
1435
|
+
"intent": "Introductory video with poster",
|
|
1436
|
+
"storyId": "media-block--video"
|
|
1437
|
+
}
|
|
1438
|
+
],
|
|
1439
|
+
"antiExamples": [
|
|
1440
|
+
{
|
|
1441
|
+
"label": "Stacking three MediaBlocks for a gallery",
|
|
1442
|
+
"why": "MediaBlock is a spotlight element; stacking them creates awkward repetition without true gallery ergonomics",
|
|
1443
|
+
"useInstead": "Build a dedicated gallery component in your client DS"
|
|
1444
|
+
},
|
|
1445
|
+
{
|
|
1446
|
+
"label": "Decorative image with invented alt text",
|
|
1447
|
+
"why": "Screen readers read the alt text; inventing \"people smiling\" for decorative media wastes listener attention",
|
|
1448
|
+
"useInstead": "Use alt=\"\" for purely decorative media"
|
|
1449
|
+
}
|
|
1450
|
+
],
|
|
1451
|
+
"behavior": {
|
|
1452
|
+
"fetchesData": false,
|
|
1453
|
+
"hasClientState": false,
|
|
1454
|
+
"animates": false,
|
|
1455
|
+
"requiresAnalytics": false
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
"Prose": {
|
|
1459
|
+
"name": "Prose",
|
|
1460
|
+
"category": "section",
|
|
1461
|
+
"description": "A typographic container for long-form content — articles, policies, documentation, any flowing prose with headings and lists.",
|
|
1462
|
+
"intent": "Wrap free-flowing editorial content with sensible typography defaults (heading hierarchy, paragraph rhythm, list styling, blockquote treatment). Use any time you have a block of content authored as rich text and you want it to read well without styling each element individually.",
|
|
1463
|
+
"composition": {
|
|
1464
|
+
"placement": [
|
|
1465
|
+
"section"
|
|
1466
|
+
],
|
|
1467
|
+
"maxPerPage": null,
|
|
1468
|
+
"requiredSiblings": [],
|
|
1469
|
+
"forbiddenAdjacent": []
|
|
1470
|
+
},
|
|
1471
|
+
"content": {
|
|
1472
|
+
"fields": [
|
|
1473
|
+
{
|
|
1474
|
+
"name": "children",
|
|
1475
|
+
"type": "richtext",
|
|
1476
|
+
"required": true,
|
|
1477
|
+
"constraints": "Rich text content authored in the CMS; can include h2-h4, paragraphs, lists, blockquotes, links"
|
|
1478
|
+
}
|
|
1479
|
+
],
|
|
1480
|
+
"variants": [
|
|
1481
|
+
{
|
|
1482
|
+
"name": "default",
|
|
1483
|
+
"description": "Standard reading rhythm",
|
|
1484
|
+
"whenToUse": "Most articles and editorial content"
|
|
1485
|
+
},
|
|
1486
|
+
{
|
|
1487
|
+
"name": "compact",
|
|
1488
|
+
"description": "Tighter spacing and line height",
|
|
1489
|
+
"whenToUse": "Denser reference content, product docs, or reading-room pages"
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
"name": "spacious",
|
|
1493
|
+
"description": "Looser spacing and line height",
|
|
1494
|
+
"whenToUse": "Long-form essays where the reader benefits from breathing room"
|
|
1495
|
+
}
|
|
1496
|
+
]
|
|
1497
|
+
},
|
|
1498
|
+
"tokens": {
|
|
1499
|
+
"consumes": [
|
|
1500
|
+
"color.text.primary",
|
|
1501
|
+
"color.text.secondary",
|
|
1502
|
+
"color.border.strong",
|
|
1503
|
+
"color.brand.primary",
|
|
1504
|
+
"spacing.container",
|
|
1505
|
+
"spacing.10",
|
|
1506
|
+
"spacing.8",
|
|
1507
|
+
"spacing.6",
|
|
1508
|
+
"spacing.5",
|
|
1509
|
+
"spacing.4",
|
|
1510
|
+
"spacing.2",
|
|
1511
|
+
"font.size.3xl",
|
|
1512
|
+
"font.size.2xl",
|
|
1513
|
+
"font.size.xl",
|
|
1514
|
+
"font.size.lg",
|
|
1515
|
+
"font.weight.semibold",
|
|
1516
|
+
"line.height.snug",
|
|
1517
|
+
"line.height.normal",
|
|
1518
|
+
"line.height.relaxed",
|
|
1519
|
+
"line.height.loose"
|
|
1520
|
+
]
|
|
1521
|
+
},
|
|
1522
|
+
"accessibility": {
|
|
1523
|
+
"keyboardSupport": [],
|
|
1524
|
+
"screenReaderBehavior": "Children render as their native semantic HTML (h2, h3, p, ul, ol, blockquote, a). Prose adds no ARIA beyond what the authored content provides.",
|
|
1525
|
+
"contentWarnings": [
|
|
1526
|
+
"Author h2 and below inside Prose; never h1 (the page already has one)",
|
|
1527
|
+
"Use real list markup, not paragraphs with bullets"
|
|
1528
|
+
]
|
|
1529
|
+
},
|
|
1530
|
+
"examples": [
|
|
1531
|
+
{
|
|
1532
|
+
"label": "Default",
|
|
1533
|
+
"intent": "Standard article body",
|
|
1534
|
+
"storyId": "prose--default"
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
"label": "Compact",
|
|
1538
|
+
"intent": "Reference or documentation page",
|
|
1539
|
+
"storyId": "prose--compact"
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
"label": "Spacious",
|
|
1543
|
+
"intent": "Long-form essay or manifesto",
|
|
1544
|
+
"storyId": "prose--spacious"
|
|
1545
|
+
}
|
|
1546
|
+
],
|
|
1547
|
+
"antiExamples": [
|
|
1548
|
+
{
|
|
1549
|
+
"label": "Nesting Prose inside Prose",
|
|
1550
|
+
"why": "Creates duplicate typography scales and unpredictable spacing",
|
|
1551
|
+
"useInstead": "Use a single Prose at the outermost level"
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
"label": "Putting interactive components inside Prose",
|
|
1555
|
+
"why": "Prose is for flowing editorial content; components like Stats or CardGrid have their own layout",
|
|
1556
|
+
"useInstead": "Close the Prose, render the component, open another Prose for continuing text"
|
|
1557
|
+
}
|
|
1558
|
+
],
|
|
1559
|
+
"behavior": {
|
|
1560
|
+
"fetchesData": false,
|
|
1561
|
+
"hasClientState": false,
|
|
1562
|
+
"animates": false,
|
|
1563
|
+
"requiresAnalytics": false
|
|
1564
|
+
}
|
|
1565
|
+
},
|
|
1566
|
+
"Quote": {
|
|
1567
|
+
"name": "Quote",
|
|
1568
|
+
"category": "media",
|
|
1569
|
+
"description": "A pullquote or testimonial rendered as a <figure> with a <blockquote> and optional figcaption attribution.",
|
|
1570
|
+
"intent": "Surface a single human-scale quotation — a testimonial, a pullquote, a foundational claim. Use sparingly; quotes lose weight when stacked. The attribution is optional because some quotes stand on their own without a named author.",
|
|
1571
|
+
"composition": {
|
|
1572
|
+
"placement": [
|
|
1573
|
+
"section"
|
|
1574
|
+
],
|
|
1575
|
+
"maxPerPage": null,
|
|
1576
|
+
"requiredSiblings": [],
|
|
1577
|
+
"forbiddenAdjacent": [
|
|
1578
|
+
"Quote"
|
|
1579
|
+
]
|
|
1580
|
+
},
|
|
1581
|
+
"content": {
|
|
1582
|
+
"fields": [
|
|
1583
|
+
{
|
|
1584
|
+
"name": "quote",
|
|
1585
|
+
"type": "text",
|
|
1586
|
+
"required": true,
|
|
1587
|
+
"maxLength": 400,
|
|
1588
|
+
"constraints": "One or two sentences; longer belongs in Prose"
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
"name": "attribution",
|
|
1592
|
+
"type": "group",
|
|
1593
|
+
"required": false,
|
|
1594
|
+
"of": [
|
|
1595
|
+
{
|
|
1596
|
+
"name": "name",
|
|
1597
|
+
"type": "text",
|
|
1598
|
+
"required": true,
|
|
1599
|
+
"maxLength": 80
|
|
1600
|
+
},
|
|
1601
|
+
{
|
|
1602
|
+
"name": "role",
|
|
1603
|
+
"type": "text",
|
|
1604
|
+
"required": false,
|
|
1605
|
+
"maxLength": 100
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
"name": "avatar",
|
|
1609
|
+
"type": "image",
|
|
1610
|
+
"required": false
|
|
1611
|
+
}
|
|
1612
|
+
]
|
|
1613
|
+
}
|
|
1614
|
+
],
|
|
1615
|
+
"variants": [
|
|
1616
|
+
{
|
|
1617
|
+
"name": "default",
|
|
1618
|
+
"description": "Standard size",
|
|
1619
|
+
"whenToUse": "Most testimonials and pullquotes"
|
|
1620
|
+
},
|
|
1621
|
+
{
|
|
1622
|
+
"name": "large",
|
|
1623
|
+
"description": "Oversized display treatment",
|
|
1624
|
+
"whenToUse": "Editorial openers or mission-page quotes that carry real weight"
|
|
1625
|
+
}
|
|
1626
|
+
]
|
|
1627
|
+
},
|
|
1628
|
+
"tokens": {
|
|
1629
|
+
"consumes": [
|
|
1630
|
+
"color.text.primary",
|
|
1631
|
+
"color.text.secondary",
|
|
1632
|
+
"spacing.10",
|
|
1633
|
+
"spacing.6",
|
|
1634
|
+
"spacing.3",
|
|
1635
|
+
"spacing.container",
|
|
1636
|
+
"font.size.4xl",
|
|
1637
|
+
"font.size.2xl",
|
|
1638
|
+
"font.size.sm",
|
|
1639
|
+
"font.weight.semibold",
|
|
1640
|
+
"line.height.tight",
|
|
1641
|
+
"line.height.snug",
|
|
1642
|
+
"radius.full"
|
|
1643
|
+
],
|
|
1644
|
+
"configurable": [
|
|
1645
|
+
{
|
|
1646
|
+
"prop": "size",
|
|
1647
|
+
"tokenGroup": "layout",
|
|
1648
|
+
"allowedValues": [
|
|
1649
|
+
"default",
|
|
1650
|
+
"large"
|
|
1651
|
+
]
|
|
1652
|
+
}
|
|
1653
|
+
]
|
|
1654
|
+
},
|
|
1655
|
+
"accessibility": {
|
|
1656
|
+
"keyboardSupport": [],
|
|
1657
|
+
"screenReaderBehavior": "Rendered as <figure> containing a <blockquote>; attribution is read as the figcaption. Decorative quotation marks are generated via CSS and are not in the accessible name.",
|
|
1658
|
+
"contentWarnings": [
|
|
1659
|
+
"Do not quote someone without permission",
|
|
1660
|
+
"Use their actual words; a paraphrase inside quotation marks misrepresents them"
|
|
1661
|
+
]
|
|
1662
|
+
},
|
|
1663
|
+
"examples": [
|
|
1664
|
+
{
|
|
1665
|
+
"label": "Default",
|
|
1666
|
+
"intent": "Testimonial with role",
|
|
1667
|
+
"storyId": "quote--default"
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
"label": "With avatar",
|
|
1671
|
+
"intent": "Testimonial with portrait",
|
|
1672
|
+
"storyId": "quote--with-avatar"
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
"label": "Large",
|
|
1676
|
+
"intent": "Editorial mission statement",
|
|
1677
|
+
"storyId": "quote--large"
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
"label": "Without attribution",
|
|
1681
|
+
"intent": "Aphoristic pullquote",
|
|
1682
|
+
"storyId": "quote--without-attribution"
|
|
1683
|
+
}
|
|
1684
|
+
],
|
|
1685
|
+
"antiExamples": [
|
|
1686
|
+
{
|
|
1687
|
+
"label": "Four quotes in a row",
|
|
1688
|
+
"why": "Quote is meant to punctuate content, not fill a page",
|
|
1689
|
+
"useInstead": "Pick the strongest quote; move the rest into Prose or a CardGrid of Cards"
|
|
1690
|
+
},
|
|
1691
|
+
{
|
|
1692
|
+
"label": "Using Quote for product blurbs",
|
|
1693
|
+
"why": "Quote implies a real human author; marketing copy without a source undermines trust",
|
|
1694
|
+
"useInstead": "CTASection or Prose"
|
|
1695
|
+
}
|
|
1696
|
+
],
|
|
1697
|
+
"behavior": {
|
|
1698
|
+
"fetchesData": false,
|
|
1699
|
+
"hasClientState": false,
|
|
1700
|
+
"animates": false,
|
|
1701
|
+
"requiresAnalytics": false
|
|
1702
|
+
}
|
|
1703
|
+
},
|
|
1704
|
+
"SectionIntro": {
|
|
1705
|
+
"name": "SectionIntro",
|
|
1706
|
+
"category": "section",
|
|
1707
|
+
"description": "A section opener that establishes what the next block of content is about without competing with the page hero.",
|
|
1708
|
+
"intent": "Introduce a new section inside a page. Use when you need an h2-level heading with optional eyebrow and supporting body copy, such as \"Our approach\", \"Recent work\", or \"What we believe\". Pairs with any content block below it.",
|
|
1709
|
+
"composition": {
|
|
1710
|
+
"placement": [
|
|
1711
|
+
"section"
|
|
1712
|
+
],
|
|
1713
|
+
"maxPerPage": null,
|
|
1714
|
+
"requiredSiblings": [],
|
|
1715
|
+
"forbiddenAdjacent": [
|
|
1716
|
+
"SectionIntro"
|
|
1717
|
+
]
|
|
1718
|
+
},
|
|
1719
|
+
"content": {
|
|
1720
|
+
"fields": [
|
|
1721
|
+
{
|
|
1722
|
+
"name": "eyebrow",
|
|
1723
|
+
"type": "text",
|
|
1724
|
+
"required": false,
|
|
1725
|
+
"maxLength": 40,
|
|
1726
|
+
"constraints": "Short kicker label above the headline"
|
|
1727
|
+
},
|
|
1728
|
+
{
|
|
1729
|
+
"name": "headline",
|
|
1730
|
+
"type": "text",
|
|
1731
|
+
"required": true,
|
|
1732
|
+
"maxLength": 100,
|
|
1733
|
+
"constraints": "Sentence case; scannable; reads like a chapter title"
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
"name": "body",
|
|
1737
|
+
"type": "text",
|
|
1738
|
+
"required": false,
|
|
1739
|
+
"maxLength": 240,
|
|
1740
|
+
"constraints": "One or two sentences that set up the section"
|
|
1741
|
+
}
|
|
1742
|
+
],
|
|
1743
|
+
"variants": [
|
|
1744
|
+
{
|
|
1745
|
+
"name": "start",
|
|
1746
|
+
"description": "Left-aligned",
|
|
1747
|
+
"whenToUse": "Default — pairs with left-aligned content blocks below"
|
|
1748
|
+
},
|
|
1749
|
+
{
|
|
1750
|
+
"name": "center",
|
|
1751
|
+
"description": "Center-aligned",
|
|
1752
|
+
"whenToUse": "Landing pages and marketing sections where the intro anchors a centered layout"
|
|
1753
|
+
}
|
|
1754
|
+
]
|
|
1755
|
+
},
|
|
1756
|
+
"tokens": {
|
|
1757
|
+
"consumes": [
|
|
1758
|
+
"color.text.primary",
|
|
1759
|
+
"color.text.secondary",
|
|
1760
|
+
"spacing.container",
|
|
1761
|
+
"spacing.3",
|
|
1762
|
+
"spacing.2",
|
|
1763
|
+
"font.size.3xl",
|
|
1764
|
+
"font.size.lg",
|
|
1765
|
+
"font.size.sm",
|
|
1766
|
+
"font.weight.semibold",
|
|
1767
|
+
"line.height.snug",
|
|
1768
|
+
"line.height.relaxed",
|
|
1769
|
+
"letter.spacing.wide"
|
|
1770
|
+
]
|
|
1771
|
+
},
|
|
1772
|
+
"accessibility": {
|
|
1773
|
+
"role": "region",
|
|
1774
|
+
"keyboardSupport": [],
|
|
1775
|
+
"screenReaderBehavior": "The headline is announced as an h2 element. The eyebrow is supplementary text read before the headline. No interactive controls.",
|
|
1776
|
+
"contentWarnings": [
|
|
1777
|
+
"Do not use SectionIntro before Hero on the same page — the page must start with a single h1"
|
|
1778
|
+
]
|
|
1779
|
+
},
|
|
1780
|
+
"examples": [
|
|
1781
|
+
{
|
|
1782
|
+
"label": "Default",
|
|
1783
|
+
"intent": "Introduce a section inside a content page",
|
|
1784
|
+
"storyId": "section-intro--default"
|
|
1785
|
+
},
|
|
1786
|
+
{
|
|
1787
|
+
"label": "Centered",
|
|
1788
|
+
"intent": "Anchor a centered marketing section",
|
|
1789
|
+
"storyId": "section-intro--centered"
|
|
1790
|
+
},
|
|
1791
|
+
{
|
|
1792
|
+
"label": "Headline only",
|
|
1793
|
+
"intent": "Minimal section divider with just a heading",
|
|
1794
|
+
"storyId": "section-intro--headline-only"
|
|
1795
|
+
}
|
|
1796
|
+
],
|
|
1797
|
+
"antiExamples": [
|
|
1798
|
+
{
|
|
1799
|
+
"label": "Using SectionIntro as the page opener",
|
|
1800
|
+
"why": "SectionIntro renders h2; a page should begin with an h1 for accessibility and SEO",
|
|
1801
|
+
"useInstead": "Hero"
|
|
1802
|
+
},
|
|
1803
|
+
{
|
|
1804
|
+
"label": "Stacking two SectionIntros with no content between them",
|
|
1805
|
+
"why": "Creates a visual and semantic duplicate that signals nothing new",
|
|
1806
|
+
"useInstead": "Merge into a single SectionIntro with a longer body"
|
|
1807
|
+
}
|
|
1808
|
+
],
|
|
1809
|
+
"behavior": {
|
|
1810
|
+
"fetchesData": false,
|
|
1811
|
+
"hasClientState": false,
|
|
1812
|
+
"animates": false,
|
|
1813
|
+
"requiresAnalytics": false
|
|
1814
|
+
}
|
|
1815
|
+
},
|
|
1816
|
+
"Spacer": {
|
|
1817
|
+
"name": "Spacer",
|
|
1818
|
+
"category": "utility",
|
|
1819
|
+
"description": "An explicit vertical spacing block that inserts a token-sized gap between adjacent components.",
|
|
1820
|
+
"intent": "Add breathing room between two components when neither component's own margins produce the right rhythm. Prefer component-owned spacing when possible; reach for Spacer only when layout composition requires it, such as between Stats and a following CardGrid on a dense page.",
|
|
1821
|
+
"composition": {
|
|
1822
|
+
"placement": [
|
|
1823
|
+
"page",
|
|
1824
|
+
"section"
|
|
1825
|
+
],
|
|
1826
|
+
"maxPerPage": null,
|
|
1827
|
+
"requiredSiblings": [],
|
|
1828
|
+
"forbiddenAdjacent": [
|
|
1829
|
+
"Spacer"
|
|
1830
|
+
]
|
|
1831
|
+
},
|
|
1832
|
+
"content": {
|
|
1833
|
+
"fields": [
|
|
1834
|
+
{
|
|
1835
|
+
"name": "size",
|
|
1836
|
+
"type": "select",
|
|
1837
|
+
"required": false,
|
|
1838
|
+
"constraints": "xs | sm | md | lg | xl"
|
|
1839
|
+
}
|
|
1840
|
+
],
|
|
1841
|
+
"variants": [
|
|
1842
|
+
{
|
|
1843
|
+
"name": "xs",
|
|
1844
|
+
"description": "Extra small",
|
|
1845
|
+
"whenToUse": "Fine-grained adjustment"
|
|
1846
|
+
},
|
|
1847
|
+
{
|
|
1848
|
+
"name": "sm",
|
|
1849
|
+
"description": "Small",
|
|
1850
|
+
"whenToUse": "Between closely related elements"
|
|
1851
|
+
},
|
|
1852
|
+
{
|
|
1853
|
+
"name": "md",
|
|
1854
|
+
"description": "Medium (default)",
|
|
1855
|
+
"whenToUse": "Most cases"
|
|
1856
|
+
},
|
|
1857
|
+
{
|
|
1858
|
+
"name": "lg",
|
|
1859
|
+
"description": "Large",
|
|
1860
|
+
"whenToUse": "Between page sections that need visual separation"
|
|
1861
|
+
},
|
|
1862
|
+
{
|
|
1863
|
+
"name": "xl",
|
|
1864
|
+
"description": "Extra large",
|
|
1865
|
+
"whenToUse": "Major visual pauses on long landing pages"
|
|
1866
|
+
}
|
|
1867
|
+
]
|
|
1868
|
+
},
|
|
1869
|
+
"tokens": {
|
|
1870
|
+
"consumes": [
|
|
1871
|
+
"spacing.2",
|
|
1872
|
+
"spacing.4",
|
|
1873
|
+
"spacing.8",
|
|
1874
|
+
"spacing.16",
|
|
1875
|
+
"spacing.24"
|
|
1876
|
+
],
|
|
1877
|
+
"configurable": [
|
|
1878
|
+
{
|
|
1879
|
+
"prop": "size",
|
|
1880
|
+
"tokenGroup": "spacing",
|
|
1881
|
+
"allowedValues": [
|
|
1882
|
+
"xs",
|
|
1883
|
+
"sm",
|
|
1884
|
+
"md",
|
|
1885
|
+
"lg",
|
|
1886
|
+
"xl"
|
|
1887
|
+
]
|
|
1888
|
+
}
|
|
1889
|
+
]
|
|
1890
|
+
},
|
|
1891
|
+
"accessibility": {
|
|
1892
|
+
"keyboardSupport": [],
|
|
1893
|
+
"screenReaderBehavior": "Spacer is a presentational div marked aria-hidden. Assistive technology skips it entirely.",
|
|
1894
|
+
"contentWarnings": [
|
|
1895
|
+
"Do not use Spacer to replace paragraph margins inside Prose — the typography already handles that"
|
|
1896
|
+
]
|
|
1897
|
+
},
|
|
1898
|
+
"examples": [
|
|
1899
|
+
{
|
|
1900
|
+
"label": "Small",
|
|
1901
|
+
"intent": "Subtle gap",
|
|
1902
|
+
"storyId": "spacer--small"
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
"label": "Medium",
|
|
1906
|
+
"intent": "Standard gap",
|
|
1907
|
+
"storyId": "spacer--medium"
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
"label": "Large",
|
|
1911
|
+
"intent": "Major section break",
|
|
1912
|
+
"storyId": "spacer--large"
|
|
1913
|
+
}
|
|
1914
|
+
],
|
|
1915
|
+
"antiExamples": [
|
|
1916
|
+
{
|
|
1917
|
+
"label": "Stacking multiple Spacers to achieve a custom size",
|
|
1918
|
+
"why": "Nesting spacers bypasses the token scale and makes spacing unauditable",
|
|
1919
|
+
"useInstead": "Pick the nearest size in the scale or adjust the neighboring components"
|
|
1920
|
+
},
|
|
1921
|
+
{
|
|
1922
|
+
"label": "Using Spacer for semantic breaks",
|
|
1923
|
+
"why": "Spacer has no semantic meaning; readers cannot tell one section has ended and another begun",
|
|
1924
|
+
"useInstead": "Divider (decorative=false) or SectionIntro"
|
|
1925
|
+
}
|
|
1926
|
+
],
|
|
1927
|
+
"behavior": {
|
|
1928
|
+
"fetchesData": false,
|
|
1929
|
+
"hasClientState": false,
|
|
1930
|
+
"animates": false,
|
|
1931
|
+
"requiresAnalytics": false
|
|
1932
|
+
}
|
|
1933
|
+
},
|
|
1934
|
+
"Stats": {
|
|
1935
|
+
"name": "Stats",
|
|
1936
|
+
"category": "data",
|
|
1937
|
+
"description": "A numerical data display with two to four stat items, each with a value, a label, and an optional description.",
|
|
1938
|
+
"intent": "Surface a small set of headline metrics in a scannable row. Use for impact reports, program highlights, and annual summaries where numbers tell the story. Not appropriate for dense tabular data — that needs a real table component.",
|
|
1939
|
+
"composition": {
|
|
1940
|
+
"placement": [
|
|
1941
|
+
"section"
|
|
1942
|
+
],
|
|
1943
|
+
"maxPerPage": null,
|
|
1944
|
+
"requiredSiblings": [],
|
|
1945
|
+
"forbiddenAdjacent": []
|
|
1946
|
+
},
|
|
1947
|
+
"content": {
|
|
1948
|
+
"fields": [
|
|
1949
|
+
{
|
|
1950
|
+
"name": "eyebrow",
|
|
1951
|
+
"type": "text",
|
|
1952
|
+
"required": false,
|
|
1953
|
+
"maxLength": 40
|
|
1954
|
+
},
|
|
1955
|
+
{
|
|
1956
|
+
"name": "headline",
|
|
1957
|
+
"type": "text",
|
|
1958
|
+
"required": false,
|
|
1959
|
+
"maxLength": 100
|
|
1960
|
+
},
|
|
1961
|
+
{
|
|
1962
|
+
"name": "items",
|
|
1963
|
+
"type": "array",
|
|
1964
|
+
"required": true,
|
|
1965
|
+
"constraints": "Two to four items",
|
|
1966
|
+
"of": [
|
|
1967
|
+
{
|
|
1968
|
+
"name": "value",
|
|
1969
|
+
"type": "text",
|
|
1970
|
+
"required": true,
|
|
1971
|
+
"maxLength": 20
|
|
1972
|
+
},
|
|
1973
|
+
{
|
|
1974
|
+
"name": "label",
|
|
1975
|
+
"type": "text",
|
|
1976
|
+
"required": true,
|
|
1977
|
+
"maxLength": 60
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
"name": "description",
|
|
1981
|
+
"type": "text",
|
|
1982
|
+
"required": false,
|
|
1983
|
+
"maxLength": 80
|
|
1984
|
+
}
|
|
1985
|
+
]
|
|
1986
|
+
}
|
|
1987
|
+
]
|
|
1988
|
+
},
|
|
1989
|
+
"tokens": {
|
|
1990
|
+
"consumes": [
|
|
1991
|
+
"color.text.primary",
|
|
1992
|
+
"color.text.secondary",
|
|
1993
|
+
"color.brand.primary",
|
|
1994
|
+
"spacing.16",
|
|
1995
|
+
"spacing.10",
|
|
1996
|
+
"spacing.8",
|
|
1997
|
+
"spacing.3",
|
|
1998
|
+
"spacing.2",
|
|
1999
|
+
"spacing.1",
|
|
2000
|
+
"spacing.container",
|
|
2001
|
+
"font.size.5xl",
|
|
2002
|
+
"font.size.3xl",
|
|
2003
|
+
"font.size.sm",
|
|
2004
|
+
"font.weight.bold",
|
|
2005
|
+
"font.weight.semibold",
|
|
2006
|
+
"line.height.tight",
|
|
2007
|
+
"letter.spacing.wide"
|
|
2008
|
+
]
|
|
2009
|
+
},
|
|
2010
|
+
"accessibility": {
|
|
2011
|
+
"keyboardSupport": [],
|
|
2012
|
+
"screenReaderBehavior": "Statistics are rendered as a <dl> with <dt>/<dd> pairs. Screen readers traverse each value + label + description as a definition list entry.",
|
|
2013
|
+
"contentWarnings": [
|
|
2014
|
+
"Keep values concise — \"4,200\" instead of \"4,200,000,000 dollars\"",
|
|
2015
|
+
"Never invent numbers to fill the grid; use the real count even if unequal"
|
|
2016
|
+
]
|
|
2017
|
+
},
|
|
2018
|
+
"examples": [
|
|
2019
|
+
{
|
|
2020
|
+
"label": "Three stats",
|
|
2021
|
+
"intent": "Annual report highlights",
|
|
2022
|
+
"storyId": "stats--three-stats"
|
|
2023
|
+
},
|
|
2024
|
+
{
|
|
2025
|
+
"label": "Two stats",
|
|
2026
|
+
"intent": "Minimal impact summary",
|
|
2027
|
+
"storyId": "stats--two-stats"
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
"label": "Four stats",
|
|
2031
|
+
"intent": "Dense overview",
|
|
2032
|
+
"storyId": "stats--four-stats"
|
|
2033
|
+
}
|
|
2034
|
+
],
|
|
2035
|
+
"antiExamples": [
|
|
2036
|
+
{
|
|
2037
|
+
"label": "Five or more stats",
|
|
2038
|
+
"why": "Beyond four items the layout cramps on mobile and the individual numbers lose impact",
|
|
2039
|
+
"useInstead": "Pick the top four; move the rest to a full report page"
|
|
2040
|
+
},
|
|
2041
|
+
{
|
|
2042
|
+
"label": "Paragraph-length values",
|
|
2043
|
+
"why": "Stats are designed for at-a-glance reading; long values overwhelm the layout",
|
|
2044
|
+
"useInstead": "Use Prose for extended narrative"
|
|
2045
|
+
}
|
|
2046
|
+
],
|
|
2047
|
+
"behavior": {
|
|
2048
|
+
"fetchesData": false,
|
|
2049
|
+
"hasClientState": false,
|
|
2050
|
+
"animates": false,
|
|
2051
|
+
"requiresAnalytics": false
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
},
|
|
2055
|
+
"build": {
|
|
2056
|
+
"timestamp": "2026-08-12T16:16:55.507Z",
|
|
2057
|
+
"source": "scripts/build-manifest.ts"
|
|
2058
|
+
}
|
|
2059
|
+
}
|