@se-studio/project-build 1.0.117 → 1.0.119
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 +12 -0
- package/dist/cms-generate-html-style-guide.d.ts +4 -0
- package/dist/cms-generate-html-style-guide.d.ts.map +1 -0
- package/dist/cms-generate-html-style-guide.js +597 -0
- package/dist/cms-generate-html-style-guide.js.map +1 -0
- package/dist/cms-merge-guidelines.js +10 -3
- package/dist/cms-merge-guidelines.js.map +1 -1
- package/package.json +6 -5
- package/skills/contentful-cms/cms-guidelines/README.md +22 -3
- package/skills/contentful-cms/cms-guidelines/html-component-authoring.md +259 -0
- package/skills/contentful-cms/update-cms-guidelines/SKILL.md +16 -3
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms-generate-html-style-guide.d.ts","sourceRoot":"","sources":["../src/cms-generate-html-style-guide.ts"],"names":[],"mappings":";AACA,uFAAuF"}
|
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
|
|
3
|
+
/**
|
|
4
|
+
* cms-generate-html-style-guide
|
|
5
|
+
*
|
|
6
|
+
* Generates a comprehensive HTML authoring style guide for HtmlComponent entries.
|
|
7
|
+
* Reads the project's design tokens from tailwind.config.json and globals.css and
|
|
8
|
+
* produces a self-contained markdown reference document.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* cms-generate-html-style-guide [--app-dir <path>]
|
|
12
|
+
*
|
|
13
|
+
* Output:
|
|
14
|
+
* <app-dir>/docs/cms-guidelines/html-component-style-guide.md
|
|
15
|
+
*
|
|
16
|
+
* The output file is picked up automatically by cms-merge-guidelines and included
|
|
17
|
+
* as the "Design System Reference" preamble in COMPONENT_GUIDELINES_FOR_LLM.md.
|
|
18
|
+
*
|
|
19
|
+
* Run this whenever tailwind.config.json or globals.css changes, or as part of
|
|
20
|
+
* the update-cms-guidelines workflow.
|
|
21
|
+
*/
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
23
|
+
import { basename, join } from 'node:path';
|
|
24
|
+
import { loadTailwindConfig } from './loadTailwindConfig.js';
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// CLI parsing
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function parseAppDir() {
|
|
29
|
+
const args = process.argv.slice(2);
|
|
30
|
+
const idx = args.indexOf('--app-dir');
|
|
31
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : process.cwd();
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// CSS parsing helpers
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/**
|
|
37
|
+
* Extracts all @utility names from a globals.css string.
|
|
38
|
+
* Returns a list of { name, body } where body is the raw CSS inside the braces.
|
|
39
|
+
*/
|
|
40
|
+
function extractUtilities(css) {
|
|
41
|
+
const results = [];
|
|
42
|
+
// Match @utility <name> { ... } — handle nested braces via depth counting
|
|
43
|
+
const utilityRe = /@utility\s+([\w-]+)\s*\{/g;
|
|
44
|
+
let match = utilityRe.exec(css);
|
|
45
|
+
while (match !== null) {
|
|
46
|
+
const name = match[1];
|
|
47
|
+
const start = utilityRe.lastIndex;
|
|
48
|
+
let depth = 1;
|
|
49
|
+
let i = start;
|
|
50
|
+
while (i < css.length && depth > 0) {
|
|
51
|
+
if (css[i] === '{')
|
|
52
|
+
depth++;
|
|
53
|
+
else if (css[i] === '}')
|
|
54
|
+
depth--;
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
const body = css.slice(start, i - 1).trim();
|
|
58
|
+
results.push({ name, body });
|
|
59
|
+
match = utilityRe.exec(css);
|
|
60
|
+
}
|
|
61
|
+
return results;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extracts .rtf-* class names present in the CSS.
|
|
65
|
+
*/
|
|
66
|
+
function extractRtfClasses(css) {
|
|
67
|
+
const names = new Set();
|
|
68
|
+
const rtfRe = /\.(rtf-[\w-]+)/g;
|
|
69
|
+
let m = rtfRe.exec(css);
|
|
70
|
+
while (m !== null) {
|
|
71
|
+
names.add(m[1]);
|
|
72
|
+
m = rtfRe.exec(css);
|
|
73
|
+
}
|
|
74
|
+
return [...names].sort();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extracts CSS custom property declarations from :root blocks.
|
|
78
|
+
*/
|
|
79
|
+
function extractRootVars(css) {
|
|
80
|
+
const results = [];
|
|
81
|
+
// Find :root { ... } blocks
|
|
82
|
+
const rootRe = /:root\s*\{([^}]+)\}/g;
|
|
83
|
+
let m = rootRe.exec(css);
|
|
84
|
+
while (m !== null) {
|
|
85
|
+
const block = m[1];
|
|
86
|
+
const varRe = /--([\w-]+)\s*:\s*([^;]+);/g;
|
|
87
|
+
let v = varRe.exec(block);
|
|
88
|
+
while (v !== null) {
|
|
89
|
+
results.push({ name: `--${v[1]}`, value: v[2].trim() });
|
|
90
|
+
v = varRe.exec(block);
|
|
91
|
+
}
|
|
92
|
+
m = rootRe.exec(css);
|
|
93
|
+
}
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
function resolveSizePx(value) {
|
|
97
|
+
if (typeof value === 'number')
|
|
98
|
+
return value;
|
|
99
|
+
if (value !== null && typeof value === 'object') {
|
|
100
|
+
const v = value;
|
|
101
|
+
if (typeof v['sizePixels'] === 'number')
|
|
102
|
+
return v['sizePixels'];
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
function buildBreakpointsSection(config) {
|
|
107
|
+
const sizes = config.sizes ?? {};
|
|
108
|
+
const lines = ['## Breakpoints', ''];
|
|
109
|
+
lines.push('All breakpoints are **mobile-first**. Default styles apply to all sizes; use prefixes to override at larger breakpoints.');
|
|
110
|
+
lines.push('');
|
|
111
|
+
lines.push('| Prefix | Min-width | Columns |');
|
|
112
|
+
lines.push('|--------|-----------|---------|');
|
|
113
|
+
lines.push('| *(none)* | 0px (mobile) | ' + (sizes['mobile']?.cols ?? '—') + ' |');
|
|
114
|
+
for (const [name, s] of Object.entries(sizes)) {
|
|
115
|
+
if (name === 'mobile' || s.breakpoint === undefined)
|
|
116
|
+
continue;
|
|
117
|
+
lines.push(`| \`${name}:\` | ${s.breakpoint}px | ${s.cols ?? '—'} |`);
|
|
118
|
+
}
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push('```html');
|
|
121
|
+
lines.push('<!-- Example: stacked on mobile, side-by-side on laptop -->');
|
|
122
|
+
lines.push('<div class="flex flex-col laptop:flex-row gap-6">...</div>');
|
|
123
|
+
lines.push('```');
|
|
124
|
+
return lines.join('\n');
|
|
125
|
+
}
|
|
126
|
+
function buildColourSection(config) {
|
|
127
|
+
const colorOptions = config.colorOptions ?? {};
|
|
128
|
+
const gradients = config.gradients ?? {};
|
|
129
|
+
const foregroundColors = new Set(config.foregroundColors ?? []);
|
|
130
|
+
const colorOpposites = config.colorOpposites ?? {};
|
|
131
|
+
const lines = ['## Colour Palette', ''];
|
|
132
|
+
lines.push('Use **lowercase** colour names in Tailwind classes (e.g. colour `Dark` → class `text-dark`).');
|
|
133
|
+
lines.push('');
|
|
134
|
+
if (Object.keys(colorOptions).length > 0) {
|
|
135
|
+
lines.push('| Name | Hex | `bg-*` class | `text-*` class | `border-*` class | Contrast pair |');
|
|
136
|
+
lines.push('|------|-----|-------------|----------------|-----------------|---------------|');
|
|
137
|
+
for (const [name, hex] of Object.entries(colorOptions)) {
|
|
138
|
+
const lc = name.toLowerCase();
|
|
139
|
+
const opposite = colorOpposites[name] ?? '—';
|
|
140
|
+
const foreground = foregroundColors.has(name) ? '*(text colour)*' : '';
|
|
141
|
+
lines.push(`| **${name}** ${foreground} | \`${hex}\` | \`bg-${lc}\` | \`text-${lc}\` | \`border-${lc}\` | ${opposite} |`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (Object.keys(gradients).length > 0) {
|
|
145
|
+
lines.push('');
|
|
146
|
+
lines.push('**Gradients:**');
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push('| Name | Value | `bg-*` class |');
|
|
149
|
+
lines.push('|------|-------|-------------|');
|
|
150
|
+
for (const [name, value] of Object.entries(gradients)) {
|
|
151
|
+
const lc = name.toLowerCase();
|
|
152
|
+
lines.push(`| ${name} | \`${value}\` | \`bg-${lc}\` |`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
lines.push('');
|
|
156
|
+
lines.push('**Rules:**');
|
|
157
|
+
lines.push('- Never use hardcoded hex values. Always use the named classes above.');
|
|
158
|
+
lines.push('- For body copy on a dark background use the contrast pair (e.g. `bg-dark text-light`).');
|
|
159
|
+
lines.push('- Accent colours (Orange, Blue, Yellow) work as backgrounds and highlights.');
|
|
160
|
+
return lines.join('\n');
|
|
161
|
+
}
|
|
162
|
+
function buildTypographySection(config) {
|
|
163
|
+
const fontTable = config.fontTable;
|
|
164
|
+
const styles = fontTable?.styles;
|
|
165
|
+
if (!styles || Object.keys(styles).length === 0) {
|
|
166
|
+
return '## Typography\n\nNo typography styles defined in tailwind.config.json.';
|
|
167
|
+
}
|
|
168
|
+
// After the guard above, styles is guaranteed defined. Alias for closure access.
|
|
169
|
+
const definedStyles = styles;
|
|
170
|
+
const baseFont = fontTable?.font ?? 'sans-serif';
|
|
171
|
+
const baseWeight = fontTable?.weight ?? 400;
|
|
172
|
+
const lines = ['## Typography', ''];
|
|
173
|
+
lines.push(`Base font: **${baseFont}** | Base weight: **${baseWeight}**`);
|
|
174
|
+
lines.push('');
|
|
175
|
+
lines.push('Use the class name directly on any HTML element — the class controls font-size, weight, line-height, and letter-spacing across breakpoints.');
|
|
176
|
+
lines.push('');
|
|
177
|
+
// Categorise by approximate usage
|
|
178
|
+
const displayClasses = [];
|
|
179
|
+
const headingClasses = [];
|
|
180
|
+
const bodyClasses = [];
|
|
181
|
+
const specialClasses = [];
|
|
182
|
+
for (const name of Object.keys(styles)) {
|
|
183
|
+
if (name.startsWith('h1'))
|
|
184
|
+
displayClasses.push(name);
|
|
185
|
+
else if (name.startsWith('h2') || name.startsWith('h3') || name.startsWith('h4'))
|
|
186
|
+
headingClasses.push(name);
|
|
187
|
+
else if (name.startsWith('p'))
|
|
188
|
+
bodyClasses.push(name);
|
|
189
|
+
else
|
|
190
|
+
specialClasses.push(name);
|
|
191
|
+
}
|
|
192
|
+
function buildTypographyTable(names) {
|
|
193
|
+
const rows = [
|
|
194
|
+
'| Class | Mobile | Tablet | Laptop | Desktop | Weight | Notes |',
|
|
195
|
+
'|-------|--------|--------|--------|---------|--------|-------|',
|
|
196
|
+
];
|
|
197
|
+
for (const name of names) {
|
|
198
|
+
const e = definedStyles[name];
|
|
199
|
+
const defaultPx = resolveSizePx(e['default']);
|
|
200
|
+
const tabletPx = resolveSizePx(e['tablet']);
|
|
201
|
+
const laptopVal = e['laptop'];
|
|
202
|
+
const laptopPx = laptopVal !== undefined ? resolveSizePx(laptopVal) : null;
|
|
203
|
+
const desktopVal = e['desktop'];
|
|
204
|
+
const desktopPx = desktopVal !== undefined ? resolveSizePx(desktopVal) : null;
|
|
205
|
+
const weight = typeof e['weight'] === 'number' ? e['weight'] : (baseWeight ?? '—');
|
|
206
|
+
const additional = e['additional'];
|
|
207
|
+
const notes = [];
|
|
208
|
+
if (additional?.['text-transform'] === 'uppercase')
|
|
209
|
+
notes.push('UPPERCASE');
|
|
210
|
+
if (typeof e['letterSpacing'] === 'number' && e['letterSpacing'] !== 0)
|
|
211
|
+
notes.push(`tracking ${e['letterSpacing']}px`);
|
|
212
|
+
rows.push(`| \`${name}\` | ${defaultPx !== null ? `${defaultPx}px` : '—'} | ${tabletPx !== null ? `${tabletPx}px` : '—'} | ${laptopPx !== null ? `${laptopPx}px` : '—'} | ${desktopPx !== null ? `${desktopPx}px` : '—'} | ${weight} | ${notes.join(', ')} |`);
|
|
213
|
+
}
|
|
214
|
+
return rows.join('\n');
|
|
215
|
+
}
|
|
216
|
+
if (displayClasses.length > 0) {
|
|
217
|
+
lines.push('### Display Headings');
|
|
218
|
+
lines.push('');
|
|
219
|
+
lines.push(buildTypographyTable(displayClasses));
|
|
220
|
+
lines.push('');
|
|
221
|
+
}
|
|
222
|
+
if (headingClasses.length > 0) {
|
|
223
|
+
lines.push('### Section & Sub-Headings');
|
|
224
|
+
lines.push('');
|
|
225
|
+
lines.push(buildTypographyTable(headingClasses));
|
|
226
|
+
lines.push('');
|
|
227
|
+
}
|
|
228
|
+
if (bodyClasses.length > 0) {
|
|
229
|
+
lines.push('### Body Text');
|
|
230
|
+
lines.push('');
|
|
231
|
+
lines.push(buildTypographyTable(bodyClasses));
|
|
232
|
+
lines.push('');
|
|
233
|
+
}
|
|
234
|
+
if (specialClasses.length > 0) {
|
|
235
|
+
lines.push('### Special Styles');
|
|
236
|
+
lines.push('');
|
|
237
|
+
lines.push(buildTypographyTable(specialClasses));
|
|
238
|
+
lines.push('');
|
|
239
|
+
}
|
|
240
|
+
lines.push('**Rules:**');
|
|
241
|
+
lines.push('- Apply the class directly: `<h2 class="h2">Heading</h2>`');
|
|
242
|
+
lines.push('- Never use `text-[Npx]`, `font-size`, or `font-weight` inline styles.');
|
|
243
|
+
lines.push('- For body copy, use `p1` (large) or `p2` (standard). Reserve `h*` classes for actual headings.');
|
|
244
|
+
return lines.join('\n');
|
|
245
|
+
}
|
|
246
|
+
function buildGridSection(config) {
|
|
247
|
+
const sizes = config.sizes ?? {};
|
|
248
|
+
const lines = ['## Grid & Layout', ''];
|
|
249
|
+
lines.push('Content is placed on a CSS grid. The grid column count changes per breakpoint; gaps and margins are fixed.');
|
|
250
|
+
lines.push('');
|
|
251
|
+
lines.push('| Breakpoint | Columns | Gap | Margin |');
|
|
252
|
+
lines.push('|------------|---------|-----|--------|');
|
|
253
|
+
for (const [name, s] of Object.entries(sizes)) {
|
|
254
|
+
const bp = s.breakpoint !== undefined ? `${s.breakpoint}px` : 'default';
|
|
255
|
+
const cols = s.cols !== undefined ? String(s.cols) : '—';
|
|
256
|
+
const gap = s.gap !== undefined ? `${s.gap}px` : '—';
|
|
257
|
+
const margin = s.margin !== undefined ? `${s.margin}px` : '—';
|
|
258
|
+
lines.push(`| ${name} (${bp}) | ${cols} | ${gap} | ${margin} |`);
|
|
259
|
+
}
|
|
260
|
+
lines.push('');
|
|
261
|
+
lines.push('### Grid Container Classes');
|
|
262
|
+
lines.push('');
|
|
263
|
+
lines.push("`HtmlComponent` content is placed inside the site's 12-column grid automatically. Use these classes to position content within it:");
|
|
264
|
+
lines.push('');
|
|
265
|
+
lines.push('| Class | Description |');
|
|
266
|
+
lines.push('|-------|-------------|');
|
|
267
|
+
lines.push('| `col-span-full` | Full width (all columns) |');
|
|
268
|
+
lines.push('| `laptop:col-start-2 laptop:col-span-10` | Centered with one-column margin each side (laptop+) |');
|
|
269
|
+
lines.push('| `laptop:col-start-2 laptop:col-span-4` | Left column (text side in two-column layout) |');
|
|
270
|
+
lines.push('| `laptop:col-start-7 laptop:col-span-5` | Right column (visual side in two-column layout) |');
|
|
271
|
+
lines.push('| `laptop:col-start-2 laptop:col-span-5` | Narrow left half |');
|
|
272
|
+
lines.push('| `laptop:col-start-7 laptop:col-span-6` | Wide right half |');
|
|
273
|
+
lines.push('');
|
|
274
|
+
lines.push('### Layout Notes');
|
|
275
|
+
lines.push('');
|
|
276
|
+
lines.push('- Wrap column children in a `content-cols-grid` parent to activate the column grid.');
|
|
277
|
+
lines.push('- On mobile, all columns are `col-span-full` by default.');
|
|
278
|
+
lines.push('- For edge-to-edge (full-bleed) content, set `fullWidth: true` on the HtmlComponent entry — the grid wrapper is removed.');
|
|
279
|
+
return lines.join('\n');
|
|
280
|
+
}
|
|
281
|
+
function buildSpacingSection() {
|
|
282
|
+
const lines = ['## Spacing Conventions', ''];
|
|
283
|
+
lines.push('Use Tailwind spacing utilities. Multiples of 4 (the Tailwind scale) are preferred.');
|
|
284
|
+
lines.push('');
|
|
285
|
+
lines.push('| Purpose | Classes |');
|
|
286
|
+
lines.push('|---------|---------|');
|
|
287
|
+
lines.push('| Section vertical padding (large) | `py-16 laptop:py-24` |');
|
|
288
|
+
lines.push('| Section vertical padding (medium) | `py-12 laptop:py-16` |');
|
|
289
|
+
lines.push('| Section vertical padding (small) | `py-8 laptop:py-12` |');
|
|
290
|
+
lines.push('| Between stacked elements | `space-y-4 laptop:space-y-8` |');
|
|
291
|
+
lines.push('| Flex/grid gap | `gap-4 laptop:gap-8` |');
|
|
292
|
+
lines.push('| Card padding | `p-6 laptop:p-10` |');
|
|
293
|
+
lines.push('');
|
|
294
|
+
lines.push('> **Note:** HtmlComponent renders inside the Section component which already provides top/bottom padding. Avoid adding extra outer padding that doubles the section gap.');
|
|
295
|
+
return lines.join('\n');
|
|
296
|
+
}
|
|
297
|
+
function buildUtilitiesSection(utilities) {
|
|
298
|
+
// Filter out internal/layout utilities unlikely to be useful in raw HTML
|
|
299
|
+
const skipList = new Set([
|
|
300
|
+
'unknown-component',
|
|
301
|
+
'button',
|
|
302
|
+
'outlined-button',
|
|
303
|
+
'visual-cols',
|
|
304
|
+
'visual-width',
|
|
305
|
+
'image-item-h',
|
|
306
|
+
'row-1-pageHalf',
|
|
307
|
+
'row-6-pageHalf',
|
|
308
|
+
]);
|
|
309
|
+
const useful = utilities.filter((u) => !skipList.has(u.name));
|
|
310
|
+
if (useful.length === 0) {
|
|
311
|
+
return '## Custom Tailwind Utilities\n\n*None defined in globals.css.*';
|
|
312
|
+
}
|
|
313
|
+
const lines = ['## Custom Tailwind Utilities', ''];
|
|
314
|
+
lines.push('These utilities are available in addition to the standard Tailwind library:');
|
|
315
|
+
lines.push('');
|
|
316
|
+
lines.push('| Class | Description |');
|
|
317
|
+
lines.push('|-------|-------------|');
|
|
318
|
+
const descriptions = {
|
|
319
|
+
'animate-ticker': 'Horizontal ticker/marquee scroll animation (20s loop)',
|
|
320
|
+
'animate-fade-in-grow': 'Fade in + scale up entrance animation (0.5s)',
|
|
321
|
+
'animate-shape-shift': 'Animated shape morphing (clip-path + rotation, 9s loop)',
|
|
322
|
+
'animate-card-rotate': 'Subtle 3D rotation on hover (0.4s)',
|
|
323
|
+
'animate-clip-reveal': 'Left-to-right clip-path reveal animation (0.6s)',
|
|
324
|
+
'film-grain': 'Adds a subtle animated film grain overlay (fixed, z-index 9998)',
|
|
325
|
+
'section-spacing': 'Standard section top/bottom padding',
|
|
326
|
+
};
|
|
327
|
+
for (const { name } of useful) {
|
|
328
|
+
const desc = descriptions[name] ?? 'Custom utility — see globals.css for details';
|
|
329
|
+
lines.push(`| \`${name}\` | ${desc} |`);
|
|
330
|
+
}
|
|
331
|
+
return lines.join('\n');
|
|
332
|
+
}
|
|
333
|
+
function buildRtfSection(rtfClasses) {
|
|
334
|
+
const lines = ['## Rich Text Classes', ''];
|
|
335
|
+
lines.push('Apply these classes to an element that contains HTML produced from rich text or Markdown:');
|
|
336
|
+
lines.push('');
|
|
337
|
+
const rtfDescriptions = {
|
|
338
|
+
'rtf-standard': 'Default rich text styling. Handles headings, paragraphs, lists, blockquotes, and links with standard spacing. Use for most body content.',
|
|
339
|
+
'rtf-article': 'Editorial / blog styling with wider paragraph spacing and emphasis on readability. Use for long-form articles.',
|
|
340
|
+
'rtf-article-right': 'Article styling with paragraphs pinned to the right column (laptop+). Use for editorial layouts with a wide left margin.',
|
|
341
|
+
'rtf-legal': 'Legal document styling with compact spacing. Headings map to smaller sizes (h1→h3, h2→h4, etc.). Use for terms, privacy, and compliance content.',
|
|
342
|
+
};
|
|
343
|
+
if (rtfClasses.length === 0) {
|
|
344
|
+
lines.push('*No `.rtf-*` classes found in globals.css.*');
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
lines.push('| Class | Use when… |');
|
|
348
|
+
lines.push('|-------|-----------|');
|
|
349
|
+
for (const cls of rtfClasses) {
|
|
350
|
+
const desc = rtfDescriptions[cls] ?? 'Custom rich text variant — see globals.css for details.';
|
|
351
|
+
lines.push(`| \`${cls}\` | ${desc} |`);
|
|
352
|
+
}
|
|
353
|
+
lines.push('');
|
|
354
|
+
lines.push('```html');
|
|
355
|
+
lines.push('<div class="rtf-standard">');
|
|
356
|
+
lines.push(' <h2>Heading</h2>');
|
|
357
|
+
lines.push(' <p>Paragraph with <strong>bold</strong> and <em>italic</em>.</p>');
|
|
358
|
+
lines.push(' <ul><li>List item</li></ul>');
|
|
359
|
+
lines.push('</div>');
|
|
360
|
+
lines.push('```');
|
|
361
|
+
}
|
|
362
|
+
return lines.join('\n');
|
|
363
|
+
}
|
|
364
|
+
function buildFontsSection(config) {
|
|
365
|
+
const fontTable = config.fontTable;
|
|
366
|
+
const baseFont = fontTable?.font;
|
|
367
|
+
const lines = ['## Fonts', ''];
|
|
368
|
+
if (baseFont) {
|
|
369
|
+
lines.push(`The primary font is **${baseFont}**, loaded via Next.js font optimisation.`);
|
|
370
|
+
lines.push('');
|
|
371
|
+
lines.push('| Tailwind property | CSS variable |');
|
|
372
|
+
lines.push('|-------------------|--------------|');
|
|
373
|
+
lines.push('| `font-sans` | `var(--font-sans)` — use for all body and heading text |');
|
|
374
|
+
lines.push('| `font-mono` | `var(--font-mono)` — use for code snippets |');
|
|
375
|
+
lines.push('');
|
|
376
|
+
lines.push('> **Do not** reference the font family by name in CSS. Use `font-sans` or rely on the typography classes which already apply the correct font.');
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
lines.push('Font information not available in tailwind.config.json.');
|
|
380
|
+
}
|
|
381
|
+
return lines.join('\n');
|
|
382
|
+
}
|
|
383
|
+
function buildPatternsSection(config) {
|
|
384
|
+
const colors = Object.keys(config.colorOptions ?? {});
|
|
385
|
+
const darkColor = colors.find((c) => c.toLowerCase() === 'dark') ?? colors[0] ?? 'dark';
|
|
386
|
+
const lightColor = colors.find((c) => c.toLowerCase() === 'light') ?? colors[1] ?? 'light';
|
|
387
|
+
const accentColor = colors.find((c) => !['dark', 'light', 'gray', 'grey'].includes(c.toLowerCase())) ??
|
|
388
|
+
colors[2] ??
|
|
389
|
+
'orange';
|
|
390
|
+
const dc = darkColor.toLowerCase();
|
|
391
|
+
const lc = lightColor.toLowerCase();
|
|
392
|
+
const ac = accentColor.toLowerCase();
|
|
393
|
+
const lines = ['## Common Layout Patterns', ''];
|
|
394
|
+
lines.push('Copy-paste these patterns into `rawHtml`. Replace placeholder text with real content.');
|
|
395
|
+
lines.push('');
|
|
396
|
+
lines.push('### Centered Text Block');
|
|
397
|
+
lines.push('');
|
|
398
|
+
lines.push('```html');
|
|
399
|
+
lines.push('<div class="content-cols-grid">');
|
|
400
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-10 space-y-6">');
|
|
401
|
+
lines.push(' <h2 class="h2">Section Heading</h2>');
|
|
402
|
+
lines.push(' <div class="rtf-standard">');
|
|
403
|
+
lines.push(' <p>Body copy goes here.</p>');
|
|
404
|
+
lines.push(' </div>');
|
|
405
|
+
lines.push(' </div>');
|
|
406
|
+
lines.push('</div>');
|
|
407
|
+
lines.push('```');
|
|
408
|
+
lines.push('');
|
|
409
|
+
lines.push('### Two-Column Layout (Text + Visual)');
|
|
410
|
+
lines.push('');
|
|
411
|
+
lines.push('```html');
|
|
412
|
+
lines.push('<div class="content-cols-grid gap-y-12">');
|
|
413
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-4 flex flex-col gap-6">');
|
|
414
|
+
lines.push(' <h2 class="h2">Heading</h2>');
|
|
415
|
+
lines.push(' <p class="p1">Descriptive text alongside the visual.</p>');
|
|
416
|
+
lines.push(' </div>');
|
|
417
|
+
lines.push(' <div class="col-span-full laptop:col-start-7 laptop:col-span-5">');
|
|
418
|
+
lines.push(' <img src="..." alt="..." class="w-full rounded-lg" />');
|
|
419
|
+
lines.push(' </div>');
|
|
420
|
+
lines.push('</div>');
|
|
421
|
+
lines.push('```');
|
|
422
|
+
lines.push('');
|
|
423
|
+
lines.push('### Coloured Card');
|
|
424
|
+
lines.push('');
|
|
425
|
+
lines.push('```html');
|
|
426
|
+
lines.push('<div class="content-cols-grid">');
|
|
427
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-10">');
|
|
428
|
+
lines.push(` <div class="bg-${ac} text-${dc} p-8 laptop:p-12 rounded-lg flex flex-col gap-4">`);
|
|
429
|
+
lines.push(' <h3 class="h3">Card Title</h3>');
|
|
430
|
+
lines.push(' <p class="p2">Supporting description text.</p>');
|
|
431
|
+
lines.push(' </div>');
|
|
432
|
+
lines.push(' </div>');
|
|
433
|
+
lines.push('</div>');
|
|
434
|
+
lines.push('```');
|
|
435
|
+
lines.push('');
|
|
436
|
+
lines.push('### Card Grid');
|
|
437
|
+
lines.push('');
|
|
438
|
+
lines.push('```html');
|
|
439
|
+
lines.push('<div class="content-cols-grid gap-y-8">');
|
|
440
|
+
lines.push(' <!-- Header row -->');
|
|
441
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-10">');
|
|
442
|
+
lines.push(' <h2 class="h2">Grid Title</h2>');
|
|
443
|
+
lines.push(' </div>');
|
|
444
|
+
lines.push(' <!-- Card grid -->');
|
|
445
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-10');
|
|
446
|
+
lines.push(' grid grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3 gap-6">');
|
|
447
|
+
lines.push(' <div class="flex flex-col gap-4 p-6 border border-gray rounded-lg">');
|
|
448
|
+
lines.push(' <h3 class="h3">Card 1</h3>');
|
|
449
|
+
lines.push(' <p class="p2">Description.</p>');
|
|
450
|
+
lines.push(' </div>');
|
|
451
|
+
lines.push(' <!-- repeat for more cards -->');
|
|
452
|
+
lines.push(' </div>');
|
|
453
|
+
lines.push('</div>');
|
|
454
|
+
lines.push('```');
|
|
455
|
+
lines.push('');
|
|
456
|
+
lines.push('### Hero with Dark Background');
|
|
457
|
+
lines.push('');
|
|
458
|
+
lines.push('```html');
|
|
459
|
+
lines.push('<!-- Set isHero: true on this HtmlComponent entry -->');
|
|
460
|
+
lines.push(`<div class="bg-${dc} text-${lc} content-cols-grid py-16 laptop:py-32">`);
|
|
461
|
+
lines.push(' <div class="col-span-full laptop:col-start-2 laptop:col-span-10 flex flex-col gap-8">');
|
|
462
|
+
lines.push(' <h1 class="h1">Hero Heading</h1>');
|
|
463
|
+
lines.push(' <p class="p1 laptop:col-span-6">Subtitle or intro text.</p>');
|
|
464
|
+
lines.push(' </div>');
|
|
465
|
+
lines.push('</div>');
|
|
466
|
+
lines.push('```');
|
|
467
|
+
return lines.join('\n');
|
|
468
|
+
}
|
|
469
|
+
function buildHtmlComponentRules() {
|
|
470
|
+
return `## HtmlComponent Field Reference
|
|
471
|
+
|
|
472
|
+
When authoring HTML for a \`HtmlComponent\` entry in Contentful, fill these fields:
|
|
473
|
+
|
|
474
|
+
| Field | Required | Notes |
|
|
475
|
+
|-------|----------|-------|
|
|
476
|
+
| \`rawHtml\` | ✓ | The HTML markup. Use Tailwind classes; avoid inline \`style=\` attributes for layout/colour/typography. |
|
|
477
|
+
| \`customCss\` | — | Scoped CSS only. Rules are automatically prefixed with \`[data-hc-id="<id>"]\` so they cannot leak. Use for complex interactions or pseudo-elements unavailable via Tailwind. |
|
|
478
|
+
| \`customJs\` | — | JavaScript loaded via Next.js \`<Script>\`. Always test the \`scriptStrategy\` setting. |
|
|
479
|
+
| \`markdownContent\` | — | Plain text summary of the component for site search indexing. Fill this to make the component searchable. |
|
|
480
|
+
| \`isHero\` | — | Set \`true\` if the HTML contains an \`<h1>\`. Ensures this block appears first in the page content flow. |
|
|
481
|
+
| \`fullWidth\` | — | Set \`true\` for edge-to-edge (full-bleed) layouts that break out of the column grid. |
|
|
482
|
+
| \`excludeFromSearch\` | — | Set \`true\` to exclude from search indexing even if \`markdownContent\` is filled. |
|
|
483
|
+
| \`scriptStrategy\` | — | \`afterInteractive\` (default, safe), \`lazyOnload\` (deferred), \`beforeInteractive\` (constrained). |
|
|
484
|
+
|
|
485
|
+
### Authoring Rules
|
|
486
|
+
|
|
487
|
+
1. **Classes, not inline styles.** Use Tailwind utility classes. Never write \`style="color: #FF5C00"\` — use \`class="text-orange"\` instead.
|
|
488
|
+
2. **Respect the grid.** Wrap content in \`content-cols-grid\` and use column classes to align with surrounding sections.
|
|
489
|
+
3. **Semantic HTML.** Use correct heading levels (\`<h1>\` only once per page, \`<h2>\` for section heads, \`<h3>\` for cards).
|
|
490
|
+
4. **Accessible images.** Always include \`alt\` attributes. Decorative images use \`alt=""\`.
|
|
491
|
+
5. **No custom font stacks.** Use \`font-sans\` or rely on typography classes. The project font is loaded by Next.js automatically.
|
|
492
|
+
6. **Fill \`markdownContent\`** so site search can index the component's textual content.`;
|
|
493
|
+
}
|
|
494
|
+
// ---------------------------------------------------------------------------
|
|
495
|
+
// Main
|
|
496
|
+
// ---------------------------------------------------------------------------
|
|
497
|
+
function main() {
|
|
498
|
+
const appRoot = parseAppDir();
|
|
499
|
+
const appName = basename(appRoot);
|
|
500
|
+
console.log(`Generating HTML style guide for: ${appRoot}`);
|
|
501
|
+
// Load tailwind config
|
|
502
|
+
const config = loadTailwindConfig(appRoot);
|
|
503
|
+
if (!config) {
|
|
504
|
+
console.error(`ERROR: Could not load tailwind.config.json from ${appRoot}`);
|
|
505
|
+
console.error(' Run from or pass --app-dir pointing to an app directory.');
|
|
506
|
+
process.exit(1);
|
|
507
|
+
}
|
|
508
|
+
// Load globals.css
|
|
509
|
+
const globalsCssPath = join(appRoot, 'src/app/globals.css');
|
|
510
|
+
let globalsCss = '';
|
|
511
|
+
if (existsSync(globalsCssPath)) {
|
|
512
|
+
globalsCss = readFileSync(globalsCssPath, 'utf8');
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
console.warn(` WARNING: globals.css not found at ${globalsCssPath} — skipping CSS parsing`);
|
|
516
|
+
}
|
|
517
|
+
const utilities = extractUtilities(globalsCss);
|
|
518
|
+
const rtfClasses = extractRtfClasses(globalsCss);
|
|
519
|
+
const rootVars = extractRootVars(globalsCss);
|
|
520
|
+
console.log(` Colours: ${Object.keys(config.colorOptions ?? {}).length}`);
|
|
521
|
+
console.log(` Typography styles: ${Object.keys(config.fontTable?.styles ?? {}).length}`);
|
|
522
|
+
console.log(` Utilities: ${utilities.length}`);
|
|
523
|
+
console.log(` RTF classes: ${rtfClasses.length}`);
|
|
524
|
+
console.log(` CSS variables: ${rootVars.length}`);
|
|
525
|
+
// Build sections
|
|
526
|
+
const now = new Date().toISOString().split('T')[0];
|
|
527
|
+
const sections = [
|
|
528
|
+
`# HTML Component Style Guide — ${appName}`,
|
|
529
|
+
'',
|
|
530
|
+
`> Auto-generated on ${now} from \`tailwind.config.json\` and \`src/app/globals.css\`.`,
|
|
531
|
+
'> Regenerate with: `pnpm cms-generate-html-style-guide`',
|
|
532
|
+
'',
|
|
533
|
+
'This guide defines every design token available for use in `HtmlComponent` `rawHtml` fields.',
|
|
534
|
+
'Read this before authoring any custom HTML for the site — it ensures visual consistency.',
|
|
535
|
+
'',
|
|
536
|
+
'---',
|
|
537
|
+
'',
|
|
538
|
+
buildHtmlComponentRules(),
|
|
539
|
+
'',
|
|
540
|
+
'---',
|
|
541
|
+
'',
|
|
542
|
+
buildBreakpointsSection(config),
|
|
543
|
+
'',
|
|
544
|
+
'---',
|
|
545
|
+
'',
|
|
546
|
+
buildColourSection(config),
|
|
547
|
+
'',
|
|
548
|
+
'---',
|
|
549
|
+
'',
|
|
550
|
+
buildTypographySection(config),
|
|
551
|
+
'',
|
|
552
|
+
'---',
|
|
553
|
+
'',
|
|
554
|
+
buildGridSection(config),
|
|
555
|
+
'',
|
|
556
|
+
'---',
|
|
557
|
+
'',
|
|
558
|
+
buildSpacingSection(),
|
|
559
|
+
'',
|
|
560
|
+
'---',
|
|
561
|
+
'',
|
|
562
|
+
buildFontsSection(config),
|
|
563
|
+
'',
|
|
564
|
+
'---',
|
|
565
|
+
'',
|
|
566
|
+
buildUtilitiesSection(utilities),
|
|
567
|
+
'',
|
|
568
|
+
'---',
|
|
569
|
+
'',
|
|
570
|
+
buildRtfSection(rtfClasses),
|
|
571
|
+
'',
|
|
572
|
+
'---',
|
|
573
|
+
'',
|
|
574
|
+
buildPatternsSection(config),
|
|
575
|
+
];
|
|
576
|
+
// Include CSS variables if any interesting ones found
|
|
577
|
+
const interestingVars = rootVars.filter((v) => !v.name.startsWith('--color-') && !v.name.startsWith('--animate-'));
|
|
578
|
+
if (interestingVars.length > 0) {
|
|
579
|
+
sections.push('', '---', '', '## CSS Custom Properties', '');
|
|
580
|
+
sections.push('These tokens are available via `var(--name)` in `customCss` fields:');
|
|
581
|
+
sections.push('');
|
|
582
|
+
sections.push('| Variable | Default value |');
|
|
583
|
+
sections.push('|----------|---------------|');
|
|
584
|
+
for (const { name, value } of interestingVars) {
|
|
585
|
+
sections.push(`| \`${name}\` | \`${value}\` |`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
const output = sections.join('\n') + '\n';
|
|
589
|
+
// Write output
|
|
590
|
+
const outputDir = join(appRoot, 'docs/cms-guidelines');
|
|
591
|
+
mkdirSync(outputDir, { recursive: true });
|
|
592
|
+
const outputPath = join(outputDir, 'html-component-style-guide.md');
|
|
593
|
+
writeFileSync(outputPath, output);
|
|
594
|
+
console.log(`\nWrote ${outputPath}`);
|
|
595
|
+
}
|
|
596
|
+
main();
|
|
597
|
+
//# sourceMappingURL=cms-generate-html-style-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms-generate-html-style-guide.js","sourceRoot":"","sources":["../src/cms-generate-html-style-guide.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* cms-merge-guidelines [--app-dir <path>] [--app-name <name>]
|
|
18
18
|
*/
|
|
19
19
|
import { execSync } from 'node:child_process';
|
|
20
|
-
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
20
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
21
21
|
import { basename, extname, join } from 'node:path';
|
|
22
22
|
// Parse CLI flags
|
|
23
23
|
function parseCli() {
|
|
@@ -88,8 +88,15 @@ function main() {
|
|
|
88
88
|
parts.push('');
|
|
89
89
|
parts.push(`> Generated: ${generatedDate} | Commit: ${commitId}`);
|
|
90
90
|
parts.push('');
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
// HTML Component Style Guide preamble (if generated)
|
|
92
|
+
const htmlGuideFile = join(GUIDELINES_DIR, 'html-component-style-guide.md');
|
|
93
|
+
if (existsSync(htmlGuideFile)) {
|
|
94
|
+
const htmlGuideContent = readFileSync(htmlGuideFile, 'utf8').trim();
|
|
95
|
+
parts.push(htmlGuideContent);
|
|
96
|
+
parts.push('');
|
|
97
|
+
parts.push('---');
|
|
98
|
+
parts.push('');
|
|
99
|
+
}
|
|
93
100
|
// Table of contents
|
|
94
101
|
parts.push('## Table of Contents');
|
|
95
102
|
parts.push('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-merge-guidelines.js","sourceRoot":"","sources":["../src/cms-merge-guidelines.ts"],"names":[],"mappings":";AAEA,uFAAuF;AAEvF;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cms-merge-guidelines.js","sourceRoot":"","sources":["../src/cms-merge-guidelines.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/project-build",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.119",
|
|
4
4
|
"description": "Build tools and management scripts for SE Studio projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"cms-merge-guidelines": "./dist/cms-merge-guidelines.js",
|
|
36
36
|
"cms-capture-screenshots": "./dist/cms-capture-screenshots.js",
|
|
37
37
|
"cms-update-colour-hints": "./dist/cms-update-colour-hints.js",
|
|
38
|
-
"cms-generate-collection-guidelines": "./dist/cms-generate-collection-guidelines.js"
|
|
38
|
+
"cms-generate-collection-guidelines": "./dist/cms-generate-collection-guidelines.js",
|
|
39
|
+
"cms-generate-html-style-guide": "./dist/cms-generate-html-style-guide.js"
|
|
39
40
|
},
|
|
40
41
|
"files": [
|
|
41
42
|
"dist",
|
|
@@ -60,12 +61,12 @@
|
|
|
60
61
|
"url": "https://github.com/Something-Else-Studio/se-core-product/issues"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"@biomejs/biome": "^2.4.
|
|
64
|
+
"@biomejs/biome": "^2.4.10",
|
|
64
65
|
"@biomejs/js-api": "^4.0.0",
|
|
65
|
-
"@biomejs/wasm-nodejs": "^2.4.
|
|
66
|
+
"@biomejs/wasm-nodejs": "^2.4.10",
|
|
66
67
|
"change-case": "^5.4.4",
|
|
67
68
|
"chroma-js": "^3.2.0",
|
|
68
|
-
"contentful-management": "^12.
|
|
69
|
+
"contentful-management": "^12.2.0",
|
|
69
70
|
"dotenv": "^17.3.1"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
@@ -75,13 +75,31 @@ cms-merge-guidelines --app-dir apps/example-om1
|
|
|
75
75
|
|
|
76
76
|
| CLI | Purpose |
|
|
77
77
|
|---|---|
|
|
78
|
+
| `cms-generate-html-style-guide` | Generate `html-component-style-guide.md` from `tailwind.config.json` + `globals.css` |
|
|
78
79
|
| `cms-generate-field-list` | Parse TypeScript types → `field-list.json` |
|
|
79
80
|
| `cms-capture-screenshots` | Capture component screenshots for variant evaluation |
|
|
80
81
|
| `cms-update-colour-hints` | Upsert a colour hint in `colour-hints.json` |
|
|
81
|
-
| `cms-generate-collection-guidelines` |
|
|
82
|
+
| `cms-generate-collection-guidelines` | Generate all collection/external `.md` files from a discovery URL |
|
|
82
83
|
| `cms-merge-guidelines` | Merge all fragments → `COMPONENT_GUIDELINES_FOR_LLM.md` |
|
|
83
84
|
|
|
84
|
-
All CLIs are provided by `@se-studio/
|
|
85
|
+
All CLIs are provided by `@se-studio/project-build`. Run `pnpm build` from the repo root to ensure they are built and linked.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## `cms-generate-html-style-guide`
|
|
90
|
+
|
|
91
|
+
Generates `docs/cms-guidelines/html-component-style-guide.md` — a design system reference for any LLM or developer authoring HTML in `HtmlComponent` CMS entries.
|
|
92
|
+
|
|
93
|
+
Does not require a running dev server. Reads only local files:
|
|
94
|
+
- `tailwind.config.json` → colour palette, typography classes, grid configuration
|
|
95
|
+
- `src/app/globals.css` → custom utilities, RTF class names, CSS custom properties
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# From the app directory:
|
|
99
|
+
pnpm cms-generate-html-style-guide
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The output file is a **static fragment** — not generated by the LLM component pipeline. It is automatically included as a preamble in `COMPONENT_GUIDELINES_FOR_LLM.md` when `cms-merge-guidelines` runs. Regenerate it whenever the design system changes.
|
|
85
103
|
|
|
86
104
|
---
|
|
87
105
|
|
|
@@ -128,10 +146,11 @@ Outputs:
|
|
|
128
146
|
```
|
|
129
147
|
<appDir>/
|
|
130
148
|
docs/cms-guidelines/
|
|
149
|
+
html-component-style-guide.md # design system reference (auto-generated; static fragment)
|
|
131
150
|
components/ # one .md per componentType
|
|
132
151
|
collections/ # one .md per collectionType
|
|
133
152
|
externals/ # one .md per externalComponentType
|
|
134
|
-
COMPONENT_GUIDELINES_FOR_LLM.md # merged document
|
|
153
|
+
COMPONENT_GUIDELINES_FOR_LLM.md # merged document (includes style guide as preamble)
|
|
135
154
|
generated/cms-discovery/
|
|
136
155
|
field-list.json
|
|
137
156
|
colour-hints.json
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: html-component-authoring
|
|
3
|
+
description: Guidelines for authoring HTML content in HtmlComponent CMS entries. Covers how to use the project style guide, what classes to use, field semantics, and common layout patterns.
|
|
4
|
+
license: Private
|
|
5
|
+
metadata:
|
|
6
|
+
author: se-core-product
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# HtmlComponent Authoring Guide
|
|
11
|
+
|
|
12
|
+
`HtmlComponent` is a CMS content type that renders developer-authored HTML directly into the page. It bypasses the standard component registration system and is intended for one-off or highly custom layouts that the structured component library cannot produce.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Before You Start
|
|
17
|
+
|
|
18
|
+
**Read the project style guide.** Every app has an auto-generated HTML Component Style Guide at:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
docs/cms-guidelines/html-component-style-guide.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This file contains the exact colour names, typography class names, grid configuration, and custom utilities available for that specific project. It is derived from `tailwind.config.json` and `globals.css` — always consult it before writing any HTML.
|
|
25
|
+
|
|
26
|
+
If the file does not exist, generate it first:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# From the app directory:
|
|
30
|
+
pnpm cms-generate-html-style-guide
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## HtmlComponent Fields
|
|
36
|
+
|
|
37
|
+
| Field | Required | Type | Purpose |
|
|
38
|
+
|-------|----------|------|---------|
|
|
39
|
+
| `rawHtml` | ✓ | Text | The HTML markup. Use Tailwind classes; never inline `style=` for colours/typography/layout. |
|
|
40
|
+
| `customCss` | — | Text | Scoped CSS. Rules are automatically prefixed with `[data-hc-id="<id>"]` — they cannot pollute other components. |
|
|
41
|
+
| `customJs` | — | Text | JavaScript loaded via Next.js `<Script>`. Use sparingly. |
|
|
42
|
+
| `markdownContent` | — | Text | Plain text for search indexing. **Always fill this** so the component appears in site search. |
|
|
43
|
+
| `isHero` | — | Boolean | `true` if the HTML contains an `<h1>`. Moves this block to the top of the page content flow. |
|
|
44
|
+
| `fullWidth` | — | Boolean | `true` for edge-to-edge (full-bleed) layouts that break out of the column grid. |
|
|
45
|
+
| `excludeFromSearch` | — | Boolean | `true` to exclude from search even if `markdownContent` is set. |
|
|
46
|
+
| `loadScriptOnce` | — | Boolean | `true` (default) to deduplicate the script tag when the same entry appears multiple times. |
|
|
47
|
+
| `scriptStrategy` | — | Enum | `afterInteractive` (default), `lazyOnload`, `beforeInteractive`. |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## The Four Non-Negotiable Rules
|
|
52
|
+
|
|
53
|
+
1. **Use Tailwind classes, not inline styles.**
|
|
54
|
+
- ❌ `style="color: #FF5C00; font-size: 48px;"`
|
|
55
|
+
- ✓ `class="text-orange h2"`
|
|
56
|
+
|
|
57
|
+
2. **Use named colour classes from the palette.**
|
|
58
|
+
- ❌ `class="bg-[#1F2E32]"` or `style="background: #1F2E32"`
|
|
59
|
+
- ✓ `class="bg-dark text-light"`
|
|
60
|
+
|
|
61
|
+
3. **Use typography classes, not raw font sizes.**
|
|
62
|
+
- ❌ `class="text-[48px] font-semibold"`
|
|
63
|
+
- ✓ `class="h2"`
|
|
64
|
+
|
|
65
|
+
4. **Respect the grid.** Wrap content in `content-cols-grid` and use `col-span-*` / `col-start-*` to align with other sections.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Colour Usage
|
|
70
|
+
|
|
71
|
+
All colour names are defined in the style guide. Use lowercase in Tailwind:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Dark → bg-dark / text-dark / border-dark
|
|
75
|
+
Light → bg-light / text-light / border-light
|
|
76
|
+
Orange → bg-orange / text-orange
|
|
77
|
+
Blue → bg-blue / text-blue
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For dark backgrounds, pair with the contrast colour (`bg-dark text-light`). Check the "Contrast pair" column in the style guide to know which pairings are approved.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Typography Usage
|
|
85
|
+
|
|
86
|
+
Pick from the named type styles in the style guide. Apply directly to the element:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<h1 class="h1">Large display heading (uppercase, 96–200px)</h1>
|
|
90
|
+
<h2 class="h2">Section heading (45–48px)</h2>
|
|
91
|
+
<h3 class="h3">Sub-heading (21–44px, uppercase)</h3>
|
|
92
|
+
<p class="p1">Large body (20–24px)</p>
|
|
93
|
+
<p class="p2">Standard body (16px)</p>
|
|
94
|
+
<p class="p3">Small body (13px)</p>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**For rich text blocks** (content rendered from Markdown or the CMS), wrap in an RTF class:
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<div class="rtf-standard">
|
|
101
|
+
<h2>Auto-styled heading</h2>
|
|
102
|
+
<p>Auto-styled paragraph with list and link support.</p>
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Available RTF classes: `rtf-standard`, `rtf-article`, `rtf-article-right`, `rtf-legal`.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Grid & Layout
|
|
111
|
+
|
|
112
|
+
HtmlComponent content lives inside the site's `Section` component, which provides the outer grid. To position content within the grid:
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<!-- Standard: wrap in content-cols-grid, span columns -->
|
|
116
|
+
<div class="content-cols-grid">
|
|
117
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10">
|
|
118
|
+
<!-- content -->
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Common column spans (all on a 12-column laptop grid):
|
|
124
|
+
|
|
125
|
+
| Use | Classes |
|
|
126
|
+
|-----|---------|
|
|
127
|
+
| Full width | `col-span-full` |
|
|
128
|
+
| Centered (one column margin) | `laptop:col-start-2 laptop:col-span-10` |
|
|
129
|
+
| Left half (text) | `laptop:col-start-2 laptop:col-span-4` |
|
|
130
|
+
| Right half (visual) | `laptop:col-start-7 laptop:col-span-5` |
|
|
131
|
+
|
|
132
|
+
For **full-bleed** content (background extends edge to edge), set `fullWidth: true` on the entry. The grid wrapper is removed and you control the full viewport width.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Breakpoints
|
|
137
|
+
|
|
138
|
+
All breakpoints are mobile-first. Use prefixes to override at larger sizes:
|
|
139
|
+
|
|
140
|
+
| Prefix | Min-width |
|
|
141
|
+
|--------|-----------|
|
|
142
|
+
| *(none)* | 0px (mobile default) |
|
|
143
|
+
| `tablet:` | 768px |
|
|
144
|
+
| `laptop:` | 1024px |
|
|
145
|
+
| `desktop:` | 1440px |
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<div class="flex flex-col laptop:flex-row gap-6">...</div>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Scoped CSS (`customCss`)
|
|
154
|
+
|
|
155
|
+
Use `customCss` only for styles impossible with Tailwind (complex `:hover`, `::before`/`::after`, third-party widget overrides).
|
|
156
|
+
|
|
157
|
+
Rules are automatically scoped to this entry's `data-hc-id` attribute — write selectors without the prefix:
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
/* In customCss — this gets scoped to [data-hc-id="<id>"] automatically */
|
|
161
|
+
.my-card:hover {
|
|
162
|
+
transform: translateY(-4px);
|
|
163
|
+
transition: transform 0.2s ease;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
::before {
|
|
167
|
+
content: '';
|
|
168
|
+
display: block;
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Never redeclare colours or typography in `customCss` — those already exist as Tailwind classes.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Common Patterns
|
|
177
|
+
|
|
178
|
+
### Centered text block
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<div class="content-cols-grid">
|
|
182
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10 space-y-6">
|
|
183
|
+
<h2 class="h2">Section Heading</h2>
|
|
184
|
+
<div class="rtf-standard">
|
|
185
|
+
<p>Body copy goes here.</p>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Two-column (text + image)
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<div class="content-cols-grid gap-y-12">
|
|
195
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-4 flex flex-col gap-6">
|
|
196
|
+
<h2 class="h2">Heading</h2>
|
|
197
|
+
<p class="p1">Supporting description.</p>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="col-span-full laptop:col-start-7 laptop:col-span-5">
|
|
200
|
+
<img src="..." alt="..." class="w-full rounded-lg" />
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Coloured card
|
|
206
|
+
|
|
207
|
+
```html
|
|
208
|
+
<div class="content-cols-grid">
|
|
209
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10">
|
|
210
|
+
<div class="bg-orange text-dark p-8 laptop:p-12 rounded-lg flex flex-col gap-4">
|
|
211
|
+
<h3 class="h3">Card Title</h3>
|
|
212
|
+
<p class="p2">Supporting text.</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Hero (set `isHero: true`)
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<!-- fullWidth: true → background goes edge-to-edge -->
|
|
222
|
+
<div class="bg-dark text-light">
|
|
223
|
+
<div class="content-cols-grid py-16 laptop:py-32">
|
|
224
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10 flex flex-col gap-8">
|
|
225
|
+
<h1 class="h1">Hero Heading</h1>
|
|
226
|
+
<p class="p1 laptop:col-span-6">Subtitle or intro text.</p>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Checklist Before Saving
|
|
235
|
+
|
|
236
|
+
- [ ] `rawHtml` uses only Tailwind classes — no inline `style=` for colours/typography/layout
|
|
237
|
+
- [ ] All colour references use named classes (`text-dark`, `bg-orange`), not hex values
|
|
238
|
+
- [ ] Typography uses named classes (`h2`, `p1`), not raw `text-[Npx]`
|
|
239
|
+
- [ ] Content is wrapped in `content-cols-grid` and positioned with `col-span-*` / `col-start-*`
|
|
240
|
+
- [ ] `markdownContent` is filled with the plain-text equivalent for search indexing
|
|
241
|
+
- [ ] `isHero: true` if the HTML contains an `<h1>`
|
|
242
|
+
- [ ] `fullWidth: true` if the design needs an edge-to-edge background
|
|
243
|
+
- [ ] Tested at mobile, tablet, and laptop breakpoints
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Generating and Updating the Style Guide
|
|
248
|
+
|
|
249
|
+
The style guide is auto-generated and should be regenerated whenever the design system changes:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# From the app directory:
|
|
253
|
+
pnpm cms-generate-html-style-guide
|
|
254
|
+
|
|
255
|
+
# Then re-merge to include it in COMPONENT_GUIDELINES_FOR_LLM.md:
|
|
256
|
+
pnpm cms-guidelines:merge
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The style guide is also regenerated automatically as part of the `update-cms-guidelines` workflow (Step 3 in `fresh` mode, or any time you run a merge step).
|
|
@@ -123,7 +123,20 @@ When complete, confirm:
|
|
|
123
123
|
|
|
124
124
|
Backfill any registered types missing from the LLM draft using `showcase-examples.json` (see curate skill), and add minimal `accepted-variants` JSON for types with no variant file so screenshot capture can run.
|
|
125
125
|
|
|
126
|
-
### Step 3 — Generate
|
|
126
|
+
### Step 3 — Generate HTML Component Style Guide
|
|
127
|
+
|
|
128
|
+
Generate the design system reference used when authoring `HtmlComponent` entries:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# From the app directory:
|
|
132
|
+
pnpm run cms-generate-html-style-guide
|
|
133
|
+
# or from repo root:
|
|
134
|
+
pnpm --filter <appName> exec cms-generate-html-style-guide --app-dir .
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Reads `tailwind.config.json` and `src/app/globals.css`; writes `docs/cms-guidelines/html-component-style-guide.md`. No dev server required. Safe to skip if the design system has not changed since the last run.
|
|
138
|
+
|
|
139
|
+
### Step 4 — Generate field list
|
|
127
140
|
|
|
128
141
|
```bash
|
|
129
142
|
# From the app directory:
|
|
@@ -134,12 +147,12 @@ pnpm --filter <appName> exec cms-generate-field-list --app-dir .
|
|
|
134
147
|
|
|
135
148
|
Produces `generated/cms-discovery/field-list.json` (discovery API reads from this path). Some apps use `src/generated/` for showcase artifacts; see app docs.
|
|
136
149
|
|
|
137
|
-
### Step
|
|
150
|
+
### Step 5 — Run generate-all-guidelines
|
|
138
151
|
|
|
139
152
|
Read and follow the **generate-all-guidelines** skill:
|
|
140
153
|
`.agents/skills/contentful-cms/generate-all-guidelines/SKILL.md`
|
|
141
154
|
|
|
142
|
-
Skip its prerequisite check (you already verified everything through Step
|
|
155
|
+
Skip its prerequisite check (you already verified everything through Step 4).
|
|
143
156
|
Run Phases 0–5 from that skill with **full regeneration rules**:
|
|
144
157
|
|
|
145
158
|
- **Phase 0** — Discover types; **do not** skip components that already had old fragments (there should be none after clean slate).
|