@stacklist-app/brandkit 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -11
- package/bin/brandkit.js +4 -0
- package/cli/build.js +7 -2
- package/cli/export.js +64 -0
- package/cli/generate.js +35 -1
- package/cli/init.js +16 -0
- package/config.schema.json +253 -0
- package/dist/engine.js +49 -13
- package/dist/logos/brandkit-mark-white.svg +8 -0
- package/dist/logos/brandkit-mark.svg +14 -0
- package/dist/logos/brandkit-wordmark-dark.svg +15 -0
- package/dist/logos/brandkit-wordmark-light.svg +9 -0
- package/dist/styles.css +113 -30
- package/integrations/vite.js +20 -1
- package/lib/config-schema.js +124 -78
- package/lib/export.js +356 -0
- package/lib/extract-css.js +1 -1
- package/lib/generate-helpers.js +1 -1
- package/lib/template.js +26 -7
- package/package.json +3 -2
package/lib/config-schema.js
CHANGED
|
@@ -1,41 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Default showcase config — a complete, company-agnostic "Brandkit" brand guide.
|
|
3
|
+
*
|
|
4
|
+
* This is what `brandkit init` scaffolds and what the example/ demo renders, so
|
|
5
|
+
* a fresh standup looks polished immediately. It doubles as living documentation:
|
|
6
|
+
* every section is populated with real, neutral sample content (no __TODO), using
|
|
7
|
+
* the v1.1.2 accent convention (--accent / --accent-foreground / --accent-text).
|
|
8
|
+
*
|
|
9
|
+
* Swap the values for your own brand. `brandkit generate` overwrites the
|
|
10
|
+
* extractable fields (colors, fonts, spacing, logos) from your codebase and
|
|
11
|
+
* preserves the curated ones (voice, components, accessibility copy).
|
|
6
12
|
*/
|
|
7
13
|
function starterConfig() {
|
|
8
14
|
return {
|
|
9
15
|
brand: {
|
|
10
|
-
name: '
|
|
11
|
-
displayName: '
|
|
12
|
-
tagline: '
|
|
13
|
-
description: '
|
|
14
|
-
url: '
|
|
15
|
-
byline: '
|
|
16
|
+
name: 'brandkit',
|
|
17
|
+
displayName: 'Brandkit',
|
|
18
|
+
tagline: 'The config-driven brand guide',
|
|
19
|
+
description: 'Brandkit turns a single config.json into a complete, living brand guide — colors, typography, logos, voice, and components, all driven by design tokens. This is the default guide; swap the config and assets to make it your own.',
|
|
20
|
+
url: 'github.com/The-Stack-Lab/brandkit',
|
|
21
|
+
byline: 'Open source · MIT',
|
|
16
22
|
version: '1.0',
|
|
17
|
-
date: new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
|
|
23
|
+
date: new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' }),
|
|
24
|
+
// Renames the "Web Style Guide" label in the header + footer.
|
|
25
|
+
guideLabel: 'Web Style Guide',
|
|
26
|
+
// Optional logo images. headerLogo replaces the text wordmark on the
|
|
27
|
+
// gradient header (use a light/reversed logo); sidebarLogo replaces the
|
|
28
|
+
// brand name at the top of the left menu (use a dark logo). Leave empty
|
|
29
|
+
// to fall back to the brand name as text.
|
|
30
|
+
headerLogo: '',
|
|
31
|
+
sidebarLogo: 'logos/brandkit-wordmark-dark.svg'
|
|
18
32
|
},
|
|
19
33
|
fonts: {
|
|
20
34
|
display: {
|
|
21
|
-
family: '
|
|
22
|
-
googleImport: '
|
|
23
|
-
description: '
|
|
35
|
+
family: 'Space Grotesk',
|
|
36
|
+
googleImport: 'Space+Grotesk:wght@400;500;600;700',
|
|
37
|
+
description: 'Space Grotesk — a geometric sans with a little character. Used for headlines, the wordmark, and large display moments.'
|
|
24
38
|
},
|
|
25
39
|
body: {
|
|
26
40
|
family: 'Inter',
|
|
27
41
|
googleImport: 'Inter:wght@300;400;500;600;700',
|
|
28
|
-
description: '
|
|
42
|
+
description: 'Inter — a highly legible workhorse for body copy, UI labels, and long-form reading at every size.'
|
|
29
43
|
}
|
|
30
44
|
},
|
|
31
45
|
theme: {
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
// Accent fill vs. text split. --accent is the fill; --accent-foreground
|
|
47
|
+
// is text/icons ON the fill; --accent-text is the accent used AS text on
|
|
48
|
+
// a light surface. For a low-contrast fill (e.g. a bright orange), set
|
|
49
|
+
// --accent-foreground to a dark value and --accent-text to a darker shade.
|
|
50
|
+
'--accent': '#4F46E5',
|
|
51
|
+
'--accent-rgb': '79, 70, 229',
|
|
52
|
+
'--accent-foreground': '#FFFFFF',
|
|
53
|
+
'--accent-text': '#4338CA',
|
|
54
|
+
'--accent-2': '#7C3AED',
|
|
34
55
|
'--lavender': '#A5B4FC',
|
|
35
|
-
'--coral': '#
|
|
36
|
-
'--coral-dark': '#
|
|
37
|
-
'--coral-light': '#
|
|
38
|
-
'--magenta': '#
|
|
56
|
+
'--coral': '#FB7185',
|
|
57
|
+
'--coral-dark': '#E11D48',
|
|
58
|
+
'--coral-light': '#FDA4AF',
|
|
59
|
+
'--magenta': '#DB2777',
|
|
39
60
|
'--ink': '#111827',
|
|
40
61
|
'--graphite': '#374151',
|
|
41
62
|
'--slate': '#6B7280',
|
|
@@ -43,16 +64,15 @@ function starterConfig() {
|
|
|
43
64
|
'--mist': '#F3F4F6',
|
|
44
65
|
'--cloud': '#F9FAFB',
|
|
45
66
|
'--white': '#FFFFFF',
|
|
46
|
-
'--success': '#
|
|
47
|
-
'--warning': '#
|
|
48
|
-
'--error': '#
|
|
49
|
-
'--info': '#
|
|
50
|
-
'--gradient-brand': 'linear-gradient(135deg, #
|
|
51
|
-
'--gradient-brand-subtle': 'linear-gradient(135deg, rgba(
|
|
52
|
-
'--purple-rgb': '99, 102, 241',
|
|
67
|
+
'--success': '#16A34A',
|
|
68
|
+
'--warning': '#D97706',
|
|
69
|
+
'--error': '#DC2626',
|
|
70
|
+
'--info': '#2563EB',
|
|
71
|
+
'--gradient-brand': 'linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%)',
|
|
72
|
+
'--gradient-brand-subtle': 'linear-gradient(135deg, rgba(79, 70, 229, 0.06) 0%, rgba(124, 58, 237, 0.06) 100%)',
|
|
53
73
|
'--ink-rgb': '17, 24, 39',
|
|
54
|
-
'--error-rgb': '
|
|
55
|
-
'--success-rgb': '
|
|
74
|
+
'--error-rgb': '220, 38, 38',
|
|
75
|
+
'--success-rgb': '22, 163, 74'
|
|
56
76
|
},
|
|
57
77
|
nav: [
|
|
58
78
|
{ group: 'Colors', items: [
|
|
@@ -76,57 +96,62 @@ function starterConfig() {
|
|
|
76
96
|
],
|
|
77
97
|
colors: {
|
|
78
98
|
brand: { label: 'Brand', items: [
|
|
79
|
-
{ name: '
|
|
80
|
-
{ name: '
|
|
99
|
+
{ name: 'Indigo', hex: '#4F46E5', oklch: 'oklch(0.51 0.23 277)', cssVar: '--accent', role: 'Primary accent — buttons, links, focus', light: false },
|
|
100
|
+
{ name: 'Violet', hex: '#7C3AED', oklch: 'oklch(0.54 0.25 293)', cssVar: '--accent-2', role: 'Secondary accent, gradient end', light: false }
|
|
81
101
|
]},
|
|
82
102
|
neutrals: { label: 'Neutrals', items: [
|
|
83
|
-
{ name: 'Ink', hex: '#111827', oklch: 'oklch(0.
|
|
84
|
-
{ name: '
|
|
85
|
-
{ name: '
|
|
86
|
-
{ name: '
|
|
103
|
+
{ name: 'Ink', hex: '#111827', oklch: 'oklch(0.21 0.03 265)', cssVar: '--ink', role: 'Primary text, headings', light: false },
|
|
104
|
+
{ name: 'Graphite', hex: '#374151', oklch: 'oklch(0.37 0.03 260)', cssVar: '--graphite', role: 'Secondary text, descriptions', light: false },
|
|
105
|
+
{ name: 'Slate', hex: '#6B7280', oklch: 'oklch(0.55 0.02 264)', cssVar: '--slate', role: 'Tertiary text, captions', light: false },
|
|
106
|
+
{ name: 'Mist', hex: '#F3F4F6', oklch: 'oklch(0.97 0.00 265)', cssVar: '--mist', role: 'Borders, section backgrounds', light: true },
|
|
107
|
+
{ name: 'Cloud', hex: '#F9FAFB', oklch: 'oklch(0.98 0.00 248)', cssVar: '--cloud', role: 'Page background', light: true }
|
|
87
108
|
]},
|
|
88
109
|
semantic: { label: 'Semantic', items: [
|
|
89
|
-
{ name: 'Success', hex: '#
|
|
90
|
-
{ name: 'Warning', hex: '#
|
|
91
|
-
{ name: 'Error', hex: '#
|
|
110
|
+
{ name: 'Success', hex: '#16A34A', oklch: 'oklch(0.63 0.17 149)', cssVar: '--success', role: 'Confirmations, positive states', light: false },
|
|
111
|
+
{ name: 'Warning', hex: '#D97706', oklch: 'oklch(0.67 0.16 58)', cssVar: '--warning', role: 'Attention, caution states', light: false },
|
|
112
|
+
{ name: 'Error', hex: '#DC2626', oklch: 'oklch(0.58 0.22 27)', cssVar: '--error', role: 'Errors, destructive actions', light: false }
|
|
92
113
|
]}
|
|
93
114
|
},
|
|
94
115
|
gradients: [
|
|
95
116
|
{
|
|
96
117
|
name: 'Brand',
|
|
97
|
-
css: 'linear-gradient(135deg, #
|
|
98
|
-
description: '
|
|
118
|
+
css: 'linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%)',
|
|
119
|
+
description: 'Hero backgrounds, feature headers, the wordmark lockup',
|
|
99
120
|
stops: [
|
|
100
|
-
{ color: '#
|
|
101
|
-
{ color: '#
|
|
102
|
-
{ color: '#EC4899', position: '100%', name: 'Pink' }
|
|
121
|
+
{ color: '#4F46E5', position: '0%', name: 'Indigo' },
|
|
122
|
+
{ color: '#7C3AED', position: '100%', name: 'Violet' }
|
|
103
123
|
]
|
|
104
124
|
},
|
|
105
125
|
{
|
|
106
126
|
name: 'Subtle',
|
|
107
|
-
css: 'linear-gradient(135deg, rgba(
|
|
127
|
+
css: 'linear-gradient(135deg, rgba(79, 70, 229, 0.06) 0%, rgba(124, 58, 237, 0.06) 100%)',
|
|
108
128
|
description: 'Card tints, section backgrounds, hover states'
|
|
109
129
|
}
|
|
110
130
|
],
|
|
111
131
|
gradientUsage: {
|
|
112
|
-
do: ['
|
|
113
|
-
dont: ['
|
|
132
|
+
do: ['Hero and feature section backgrounds', 'Large display headlines (as gradient text)', 'Key stat numbers and accent moments'],
|
|
133
|
+
dont: ['Body copy or small text', 'Behind dense UI or data tables', 'More than one focal area per screen']
|
|
114
134
|
},
|
|
115
135
|
sections: {
|
|
116
|
-
gradients: '
|
|
117
|
-
gradientTextDemo: '
|
|
118
|
-
logos: 'Download logo
|
|
119
|
-
components: '
|
|
120
|
-
spacing: '
|
|
121
|
-
variables: '
|
|
136
|
+
gradients: 'One brand gradient, used sparingly for hero moments and large headlines. The subtle variant tints cards and section backgrounds without competing with content.',
|
|
137
|
+
gradientTextDemo: 'One config, every token.',
|
|
138
|
+
logos: 'Download the logo in the format and size you need. Select a variant, then download — raster formats can be resized on the fly.',
|
|
139
|
+
components: 'A small set of building blocks — buttons, cards, and stats — that inherit every brand token automatically. Change the config and they all update.',
|
|
140
|
+
spacing: 'A consistent spacing scale keeps layouts in rhythm. Use these tokens for padding, gaps, and margins instead of arbitrary values.',
|
|
141
|
+
variables: 'Every token below is a CSS custom property. Copy any line and drop it straight into your stylesheet.'
|
|
122
142
|
},
|
|
123
143
|
hierarchy: [
|
|
124
144
|
{ class: 'h-primary', label: 'Primary', colorVar: '--ink', colorName: 'Ink', hex: '#111827', description: 'Primary text — body copy, headings, and content where readability is critical.' },
|
|
125
145
|
{ class: 'h-secondary', label: 'Secondary', colorVar: '--graphite', colorName: 'Graphite', hex: '#374151', description: 'Secondary text — descriptions, supporting information, and labels.' },
|
|
126
146
|
{ class: 'h-tertiary', label: 'Tertiary', colorVar: '--slate', colorName: 'Slate', hex: '#6B7280', description: 'Tertiary text — captions, timestamps, footnotes, and metadata.' },
|
|
127
|
-
{ class: 'h-accent', label: 'Accent', colorVar: '--
|
|
147
|
+
{ class: 'h-accent', label: 'Accent', colorVar: '--accent-text', colorName: 'Indigo', hex: '#4338CA', description: 'Accent text — links, interactive labels, and calls to action.' }
|
|
148
|
+
],
|
|
149
|
+
logos: [
|
|
150
|
+
{ name: 'Wordmark', description: 'Primary lockup — use on light backgrounds.', variants: { svg: 'logos/brandkit-wordmark-dark.svg' }, background: 'light' },
|
|
151
|
+
{ name: 'Wordmark, reversed', description: 'For dark backgrounds and photography.', variants: { svg: 'logos/brandkit-wordmark-light.svg' }, background: 'dark' },
|
|
152
|
+
{ name: 'Monogram', description: 'Compact mark for avatars and favicons.', variants: { svg: 'logos/brandkit-mark.svg' }, background: 'light' },
|
|
153
|
+
{ name: 'Monogram on gradient', description: 'Reversed mark for the brand gradient.', variants: { svg: 'logos/brandkit-mark-white.svg' }, background: 'gradient' }
|
|
128
154
|
],
|
|
129
|
-
logos: [],
|
|
130
155
|
logoSizes: [
|
|
131
156
|
{ label: 'Original', width: null },
|
|
132
157
|
{ label: '800px', width: 800 },
|
|
@@ -134,34 +159,44 @@ function starterConfig() {
|
|
|
134
159
|
{ label: '200px', width: 200 }
|
|
135
160
|
],
|
|
136
161
|
typography: [
|
|
137
|
-
{ name: 'Display XL', font: 'display', size: '72px', weight: 700, tracking: '-0.03em', leading: '1.05', sample: '
|
|
138
|
-
{ name: 'Display', font: 'display', size: '56px', weight: 700, tracking: '-0.025em', leading: '1.1', sample: '
|
|
139
|
-
{ name: 'H1', font: 'display', size: '44px', weight: 700, tracking: '-0.02em', leading: '1.15', sample: '
|
|
140
|
-
{ name: 'H2', font: 'display', size: '36px', weight: 700, tracking: '-0.015em', leading: '1.2', sample: '
|
|
141
|
-
{ name: 'H3', font: 'display', size: '28px', weight: 600, tracking: '-0.01em', leading: '1.3', sample: '
|
|
142
|
-
{ name: 'H4', font: 'display', size: '22px', weight: 600, tracking: '-0.005em', leading: '1.35', sample: '
|
|
143
|
-
{ name: 'Body LG', font: 'body', size: '18px', weight: 400, tracking: '0', leading: '1.7', sample: '
|
|
144
|
-
{ name: 'Body', font: 'body', size: '16px', weight: 400, tracking: '0', leading: '1.7', sample: '
|
|
145
|
-
{ name: 'Body SM', font: 'body', size: '14px', weight: 400, tracking: '0', leading: '1.6', sample: '
|
|
146
|
-
{ name: 'Caption', font: 'body', size: '12px', weight: 500, tracking: '0.02em', leading: '1.5', sample: '
|
|
147
|
-
{ name: 'Overline', font: 'body', size: '11px', weight: 700, tracking: '0.1em', leading: '1.4', sample: '
|
|
162
|
+
{ name: 'Display XL', font: 'display', size: '72px', weight: 700, tracking: '-0.03em', leading: '1.05', sample: 'One config, every token' },
|
|
163
|
+
{ name: 'Display', font: 'display', size: '56px', weight: 700, tracking: '-0.025em', leading: '1.1', sample: 'A brand guide that builds itself' },
|
|
164
|
+
{ name: 'H1', font: 'display', size: '44px', weight: 700, tracking: '-0.02em', leading: '1.15', sample: 'Design tokens, end to end' },
|
|
165
|
+
{ name: 'H2', font: 'display', size: '36px', weight: 700, tracking: '-0.015em', leading: '1.2', sample: 'Colors, type, and components' },
|
|
166
|
+
{ name: 'H3', font: 'display', size: '28px', weight: 600, tracking: '-0.01em', leading: '1.3', sample: 'Consistent by construction' },
|
|
167
|
+
{ name: 'H4', font: 'display', size: '22px', weight: 600, tracking: '-0.005em', leading: '1.35', sample: 'A card heading, set in display' },
|
|
168
|
+
{ name: 'Body LG', font: 'body', size: '18px', weight: 400, tracking: '0', leading: '1.7', sample: 'Lead paragraphs and intros sit comfortably at this size with generous line height.' },
|
|
169
|
+
{ name: 'Body', font: 'body', size: '16px', weight: 400, tracking: '0', leading: '1.7', sample: 'The default for body copy — legible, neutral, and easy on the eyes at any length.' },
|
|
170
|
+
{ name: 'Body SM', font: 'body', size: '14px', weight: 400, tracking: '0', leading: '1.6', sample: 'Smaller supporting text for secondary details and helper copy.' },
|
|
171
|
+
{ name: 'Caption', font: 'body', size: '12px', weight: 500, tracking: '0.02em', leading: '1.5', sample: 'Captions, timestamps, and metadata' },
|
|
172
|
+
{ name: 'Overline', font: 'body', size: '11px', weight: 700, tracking: '0.1em', leading: '1.4', sample: 'Section label', uppercase: true }
|
|
148
173
|
],
|
|
149
174
|
voice: {
|
|
150
|
-
description: '
|
|
151
|
-
do: ['
|
|
152
|
-
dont: ['
|
|
175
|
+
description: 'Clear, confident, and friendly. Brandkit speaks like a thoughtful teammate — it explains the what and the why without jargon, and never talks down to the reader.',
|
|
176
|
+
do: ['Swap the config and your whole guide updates.', 'Every token is one source of truth.', 'Ship a polished brand guide in minutes.'],
|
|
177
|
+
dont: ['Leverage synergistic design paradigms.', 'It just works (somehow).', 'Refer to the documentation for further details.']
|
|
153
178
|
},
|
|
154
179
|
accessibility: [
|
|
155
|
-
{ fg: '#
|
|
156
|
-
{ fg: '#FFFFFF', bg: '#
|
|
180
|
+
{ fg: '#4338CA', bg: '#FFFFFF', fgName: 'Indigo Text', bgName: 'White', ratio: '7.9:1', rating: 'AAA', border: true, largeText: false },
|
|
181
|
+
{ fg: '#FFFFFF', bg: '#4F46E5', fgName: 'White', bgName: 'Indigo', ratio: '6.3:1', rating: 'AA', border: false, largeText: false },
|
|
182
|
+
{ fg: '#FFFFFF', bg: '#111827', fgName: 'White', bgName: 'Ink', ratio: '17.7:1', rating: 'AAA', border: false, largeText: false },
|
|
183
|
+
{ fg: '#374151', bg: '#F9FAFB', fgName: 'Graphite', bgName: 'Cloud', ratio: '9.9:1', rating: 'AAA', border: true, largeText: false },
|
|
184
|
+
{ fg: '#6B7280', bg: '#FFFFFF', fgName: 'Slate', bgName: 'White', ratio: '4.8:1', rating: 'AA', border: true, largeText: false },
|
|
185
|
+
{ fg: '#FFFFFF', bg: '#16A34A', fgName: 'White', bgName: 'Success', ratio: '3.3:1', rating: 'AA Large', border: false, largeText: true }
|
|
157
186
|
],
|
|
158
187
|
cssVariables: [
|
|
159
|
-
{ section: '
|
|
160
|
-
{ prop: '--
|
|
161
|
-
{ prop: '--foreground', value: '#
|
|
188
|
+
{ section: 'Accent', vars: [
|
|
189
|
+
{ prop: '--accent', value: '#4F46E5', comment: 'Fill — buttons, active states' },
|
|
190
|
+
{ prop: '--accent-foreground', value: '#FFFFFF', comment: 'Text/icons on the fill' },
|
|
191
|
+
{ prop: '--accent-text', value: '#4338CA', comment: 'Accent as text on light' }
|
|
192
|
+
]},
|
|
193
|
+
{ section: 'Neutrals', vars: [
|
|
194
|
+
{ prop: '--ink', value: '#111827', comment: 'Primary text' },
|
|
195
|
+
{ prop: '--slate', value: '#6B7280', comment: 'Tertiary text' },
|
|
196
|
+
{ prop: '--cloud', value: '#F9FAFB', comment: 'Page background' }
|
|
162
197
|
]},
|
|
163
198
|
{ section: 'Typography', vars: [
|
|
164
|
-
{ prop: '--font-display', value: "'
|
|
199
|
+
{ prop: '--font-display', value: "'Space Grotesk', sans-serif", comment: 'Display font' },
|
|
165
200
|
{ prop: '--font-body', value: "'Inter', sans-serif", comment: 'Body font' }
|
|
166
201
|
]}
|
|
167
202
|
],
|
|
@@ -175,14 +210,25 @@ function starterConfig() {
|
|
|
175
210
|
components: {
|
|
176
211
|
buttons: [
|
|
177
212
|
{ variant: 'Primary', items: [
|
|
178
|
-
{ class: 'btn-primary', sizes: ['sm', 'md', 'lg'], labels: ['
|
|
213
|
+
{ class: 'btn-primary', sizes: ['sm', 'md', 'lg'], labels: ['Get started', 'Get started', 'Get started'] }
|
|
214
|
+
]},
|
|
215
|
+
{ variant: 'Secondary & ghost', items: [
|
|
216
|
+
{ class: 'btn-secondary', sizes: ['md'], labels: ['Documentation'] },
|
|
217
|
+
{ class: 'btn-ghost', sizes: ['md'], labels: ['Learn more'] }
|
|
218
|
+
]},
|
|
219
|
+
{ variant: 'Gradient', items: [
|
|
220
|
+
{ class: 'btn-gradient', sizes: ['md'], labels: ['Try the demo'] }
|
|
179
221
|
]}
|
|
180
222
|
],
|
|
181
223
|
cards: [
|
|
182
|
-
{ title: '
|
|
224
|
+
{ title: 'One config', description: 'A single config.json drives every color, font, and component in the guide.', tag: 'Tokens' },
|
|
225
|
+
{ title: 'Zero dependencies', description: 'Vanilla JS and CSS variables — nothing to install, nothing to maintain.', tag: 'Lightweight' },
|
|
226
|
+
{ title: 'Bolts onto anything', description: 'Drop it into React, Vite, Astro, Next.js, or plain HTML in minutes.', tag: 'Portable' }
|
|
183
227
|
],
|
|
184
228
|
stats: [
|
|
185
|
-
{ value: '
|
|
229
|
+
{ value: '1', label: 'Config file to rule them all' },
|
|
230
|
+
{ value: '0', label: 'Runtime dependencies' },
|
|
231
|
+
{ value: '12', label: 'Sections, rendered from tokens' }
|
|
186
232
|
]
|
|
187
233
|
}
|
|
188
234
|
};
|