@convertex/skill 1.0.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/cli.mjs ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cpSync, existsSync, rmSync, readdirSync } from 'fs';
4
+ import { resolve, dirname, join } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+
9
+ // ANSI colors
10
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
11
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
12
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
13
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
14
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
15
+
16
+ const SKILL_NAME = 'convertex';
17
+ const SOURCE = resolve(__dirname, 'skills', SKILL_NAME);
18
+ const TARGET_DIR = resolve(process.cwd(), '.claude', 'skills');
19
+ const TARGET = resolve(TARGET_DIR, SKILL_NAME);
20
+
21
+ const command = process.argv[2] || 'install';
22
+
23
+ function countFiles(dir) {
24
+ let count = 0;
25
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
26
+ if (entry.name.startsWith('.')) continue;
27
+ if (entry.isDirectory()) count += countFiles(join(dir, entry.name));
28
+ else count++;
29
+ }
30
+ return count;
31
+ }
32
+
33
+ function install() {
34
+ const isUpdate = existsSync(TARGET);
35
+
36
+ cpSync(SOURCE, TARGET, { recursive: true });
37
+
38
+ const fileCount = countFiles(TARGET);
39
+ const action = isUpdate ? 'updated' : 'installed';
40
+
41
+ console.log('');
42
+ console.log(` ${green('✓')} Convertex skill ${bold(action)} successfully`);
43
+ console.log(` ${dim(`${fileCount} files → .claude/skills/${SKILL_NAME}/`)}`);
44
+ console.log('');
45
+
46
+ if (!isUpdate) {
47
+ console.log(` ${cyan('→')} Run ${bold('claude')} in your terminal to start using the skill.`);
48
+ console.log(` Claude will automatically detect and use it for Webflow code generation.`);
49
+ console.log('');
50
+ }
51
+ }
52
+
53
+ function uninstall() {
54
+ if (!existsSync(TARGET)) {
55
+ console.log('');
56
+ console.log(` ${dim('Convertex skill is not installed.')}`);
57
+ console.log('');
58
+ return;
59
+ }
60
+
61
+ rmSync(TARGET, { recursive: true });
62
+
63
+ console.log('');
64
+ console.log(` ${green('✓')} Convertex skill ${bold('uninstalled')} successfully`);
65
+ console.log(` ${dim(`Removed .claude/skills/${SKILL_NAME}/`)}`);
66
+ console.log('');
67
+ }
68
+
69
+ function help() {
70
+ console.log('');
71
+ console.log(` ${bold('@convertex/skill')} — Install Convertex skills for Claude Code`);
72
+ console.log('');
73
+ console.log(` ${bold('Usage:')}`);
74
+ console.log(` npx @convertex/skill install Install the skill ${dim('(default)')}`);
75
+ console.log(` npx @convertex/skill update Update to the latest version`);
76
+ console.log(` npx @convertex/skill uninstall Remove the skill`);
77
+ console.log(` npx @convertex/skill help Show this help`);
78
+ console.log('');
79
+ console.log(` ${dim('Skills are installed into .claude/skills/convertex/ in your project root.')}`);
80
+ console.log(` ${dim('Learn more at https://convertex.ai')}`);
81
+ console.log('');
82
+ }
83
+
84
+ switch (command) {
85
+ case 'install':
86
+ case 'update':
87
+ install();
88
+ break;
89
+ case 'uninstall':
90
+ case 'remove':
91
+ uninstall();
92
+ break;
93
+ case 'help':
94
+ case '--help':
95
+ case '-h':
96
+ help();
97
+ break;
98
+ default:
99
+ console.log('');
100
+ console.log(` ${red('✗')} Unknown command: ${bold(command)}`);
101
+ help();
102
+ process.exit(1);
103
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@convertex/skill",
3
+ "version": "1.0.0",
4
+ "description": "Install Convertex skills for Claude Code — Webflow-compatible HTML/CSS generation with Client-First methodology",
5
+ "bin": {
6
+ "convertex-skill": "./cli.mjs"
7
+ },
8
+ "files": [
9
+ "cli.mjs",
10
+ "skills/"
11
+ ],
12
+ "keywords": [
13
+ "claude",
14
+ "claude-code",
15
+ "webflow",
16
+ "convertex",
17
+ "skill",
18
+ "mcp",
19
+ "client-first",
20
+ "html-to-webflow"
21
+ ],
22
+ "author": "Convertex",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/convertex/skill"
27
+ },
28
+ "homepage": "https://convertex.ai"
29
+ }
@@ -0,0 +1,330 @@
1
+ ---
2
+ name: convertex
3
+ description: "Generate Webflow-compatible HTML and CSS for Convertex. Triggers on: Convertex Capture, Webflow conversion, HTML to Webflow, recreate section, reproduce page, Client-First, Finsweet, w- classes."
4
+ ---
5
+
6
+ # Convertex — Webflow HTML & CSS Generation
7
+
8
+ Generate HTML and CSS compatible with Webflow's native element system. Output two separate blocks: one for HTML (body only), one for CSS.
9
+
10
+ ## Pre-Flight — Ask Before Generating
11
+
12
+ Ask these 3 questions in ONE message, then WAIT for the answer:
13
+
14
+ 1. **Client-First or free naming?** — Client-First = apply the [Client-First rules](#client-first) below.
15
+ 2. **rem or px?** — rem: `1rem = 16px`. px: pixel values.
16
+ 3. **Content language?** — Adapt placeholder text, ARIA labels, and field names.
17
+
18
+ Skip ONLY if the user already answered all 3 in their current message.
19
+
20
+ ## Output Format
21
+
22
+ - **HTML block**: Body content only. No `<html>`, `<head>`, `<body>`, or `<style>` tags. Start with the first element.
23
+ - **CSS block**: Separate from HTML. Flat selectors, concrete values, desktop-first with responsive overrides.
24
+ - **JS block**: Separate from HTML. Never place `<script>` tags or inline JavaScript inside the HTML. All JavaScript must be pushed as a separate JS block via the `js` field of `create_page` / `update_page` / `patch_page`. Do NOT wrap JS in `<div class="w-embed">` or any HTML embed — the Convertex editor has a dedicated JS panel.
25
+ - **Push, don't display**: If the Convertex MCP is connected, push code via `notify_sync_start()` then `create_page` / `update_page` / `patch_page`. Do NOT paste large code blocks in chat.
26
+
27
+ ---
28
+
29
+ ## 10 Golden Rules
30
+
31
+ ### 1. Flat CSS selectors only
32
+
33
+ `.class` or `.class1.class2` (combo). **NEVER** use:
34
+ - Descendant: `.parent .child` — use `.parent_child` instead
35
+ - Child: `.parent > .child` — use `.parent_child` instead
36
+ - Sibling: `.a + .b` — use separate classes
37
+ - Tag-qualified: `div.container` — use `.container`
38
+
39
+ ### 2. Concrete values only — no CSS variables
40
+
41
+ Write actual values: `color: #2563eb`, never `color: var(--primary)`. Webflow does not support CSS custom properties natively.
42
+
43
+ ### 3. Combo class pattern
44
+
45
+ First class = base, additional classes = combos. `class="button is-primary"` means `.button` is the base, `.is-primary` is a combo. In CSS: `.button.is-primary { ... }`.
46
+
47
+ ### 4. Semantic HTML tags
48
+
49
+ Use `<section>`, `<header>`, `<footer>`, `<nav>`, `<main>`, `<article>`, `<aside>` for their semantic purpose. These render as Block elements in Webflow with their HTML tag preserved.
50
+
51
+ ### 5. No hidden states in CSS
52
+
53
+ **NEVER** set `display: none`, `opacity: 0`, `visibility: hidden`, or `height: 0` in base CSS. Elements must be visible in Webflow Designer for editing. Set initial hidden states via JavaScript on `DOMContentLoaded`. CSS only defines the active/visible state via combo classes: `.modal.is-open { opacity: 1; }`.
54
+
55
+ ### 6. CSS transitions for simple animations
56
+
57
+ Use `transition` for hover effects and state changes. Only use JavaScript animation libraries (GSAP) for scroll-triggered, staggered, or complex timeline animations.
58
+
59
+ ### 7. Inline SVGs must be wrapped
60
+
61
+ Raw `<svg>` elements **must** be inside `<div class="w-embed">`. Without the wrapper, SVGs render incorrectly in Webflow.
62
+
63
+ ### 8. Never use `<em>`
64
+
65
+ `<em>` becomes a block-level element in Webflow. Use `<span>` with a class that sets `font-style: italic` instead.
66
+
67
+ ### 9. Never use inline `style` attributes
68
+
69
+ All styling must go through CSS classes. The `style` attribute is not supported.
70
+
71
+ ### 10. Webflow components need exact `w-` structures
72
+
73
+ Navbars, forms, sliders, tabs, dropdowns, lightboxes, and background videos require specific HTML structures with `w-` classes and data attributes. **Read the pattern file** before generating any of these. See [Component Patterns](#component-patterns).
74
+
75
+ ---
76
+
77
+ ## Responsive Breakpoints
78
+
79
+ | Breakpoint | Media Query | Direction |
80
+ |---|---|---|
81
+ | XXL | `min-width: 1920px` | Upward override |
82
+ | XL | `min-width: 1440px` | Upward override |
83
+ | Large | `min-width: 1280px` | Upward override |
84
+ | **Desktop** | _(no media query)_ | **Base styles** |
85
+ | Tablet | `max-width: 991px` | Downward override |
86
+ | Mobile Landscape | `max-width: 767px` | Downward override |
87
+ | Mobile Portrait | `max-width: 479px` | Downward override |
88
+
89
+ **Rules:**
90
+ - Desktop-first: base styles have no media query
91
+ - Override downward with `max-width`, upward (rare) with `min-width`
92
+ - Only include properties that actually change — never repeat base values
93
+ - Use **only** these exact breakpoint values
94
+
95
+ ---
96
+
97
+ ## Selector Reference
98
+
99
+ ### Allowed
100
+ ```css
101
+ .hero_heading { } /* Single class */
102
+ .button.is-secondary { } /* Combo class */
103
+ .button:hover { } /* Pseudo on class */
104
+ .nav_link.is-active:hover { } /* Combo + pseudo */
105
+ ```
106
+
107
+ ### Forbidden — will break conversion
108
+ ```css
109
+ .hero .heading { } /* Descendant → use .hero_heading */
110
+ .card > .title { } /* Child → use .card_title */
111
+ .input + .error { } /* Sibling → use .input_error */
112
+ div.container { } /* Tag-qualified → use .container */
113
+ a.nav-link { } /* Tag-qualified → use .nav-link */
114
+ .list_item:nth-child(odd) { } /* Complex pseudo → needs ghost block */
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Pseudo-Classes
120
+
121
+ **Supported natively** (write in CSS): `:hover`, `:active`, `:focus`, `:visited`, `:focus-visible`, `:focus-within`, `::placeholder`
122
+
123
+ **FORBIDDEN — never use, even in ghost blocks:**
124
+ `::before`, `::after` — poorly supported by Webflow, not manageable in the Designer. Always use a real HTML element instead (e.g. a `<div>` with a class for decorative elements, icons, or separators).
125
+
126
+ **Not supported natively** (may use a [ghost block](patterns/ghost-blocks.md) if necessary):
127
+ `:nth-child()`, `:first-child`, `:last-child`, `:not()`, `@keyframes`
128
+
129
+ ```html
130
+ <div class="w-embed"><style>
131
+ .card:first-child { border-top: none; }
132
+ </style></div>
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Contextual Styling
138
+
139
+ Webflow has no descendant selectors. When a parent state must affect children, **propagate the combo class** to every affected child:
140
+
141
+ ```html
142
+ <div class="pricing_card is-featured">
143
+ <h3 class="pricing_title is-featured">Pro</h3>
144
+ <p class="pricing_price is-featured">$99/mo</p>
145
+ </div>
146
+ ```
147
+ ```css
148
+ .pricing_card.is-featured { background-color: #0f172a; }
149
+ .pricing_title.is-featured { color: #ffffff; }
150
+ .pricing_price.is-featured { color: #60a5fa; }
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Element Rules
156
+
157
+ ### Spans
158
+ `<span>` is valid only inside text elements (`<p>`, `<h1>`–`<h6>`) or alongside text siblings. In all other cases, use `<div>`.
159
+
160
+ ### Links & Buttons
161
+ **`<button>` is atomic in Webflow — it CANNOT have children.** It only holds plain text. If you need an icon or nested elements, use `<a>` (Link Block) instead.
162
+
163
+ Inside `<a>` Link Blocks, **always use `<div>`** for child elements (text wrappers, icon containers). Never use `<span>` — it creates Text Spans in Webflow instead of Block elements, breaking layout control.
164
+
165
+ **Link with icon — correct structure:**
166
+ ```html
167
+ <a href="/page" class="button is-primary">
168
+ <div class="button_text">Get started</div>
169
+ <div class="w-embed">
170
+ <svg class="button_icon" width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true">
171
+ <path d="M1 5h8M5 1l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
172
+ </svg>
173
+ </div>
174
+ </a>
175
+ ```
176
+
177
+ **Simple button — text only:**
178
+ ```html
179
+ <button class="button">Get started</button>
180
+ ```
181
+
182
+ **NEVER do this:**
183
+ ```html
184
+ <!-- WRONG: children inside <button> -->
185
+ <button class="button">
186
+ <div class="button_text">Get started</div>
187
+ <div class="w-embed"><svg>...</svg></div>
188
+ </button>
189
+
190
+ <!-- WRONG: text directly alongside w-embed -->
191
+ <a href="/page" class="button">
192
+ Get started
193
+ <div class="w-embed"><svg>...</svg></div>
194
+ </a>
195
+
196
+ <!-- WRONG: span inside a link -->
197
+ <a href="/page" class="button">
198
+ <span class="button_text">Get started</span>
199
+ </a>
200
+ ```
201
+
202
+ ### Lists
203
+ ```html
204
+ <ul class="features_list">
205
+ <li class="features_list-item">First feature</li>
206
+ <li class="features_list-item">Second feature</li>
207
+ </ul>
208
+ ```
209
+ Both `<ul>` and `<ol>` are supported. Style via classes on the list and list items.
210
+
211
+ ### Blockquote
212
+ ```html
213
+ <blockquote class="testimonial_quote">Customer feedback here.</blockquote>
214
+ ```
215
+
216
+ ### Horizontal Rule
217
+ ```html
218
+ <hr class="divider" />
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Inline Components
224
+
225
+ | Component | HTML | Notes |
226
+ |---|---|---|
227
+ | **Grid** | `<div class="w-layout-grid my-grid">` | Must have `display: grid` in CSS |
228
+ | **Container** | `<div class="w-layout-blockcontainer my-container">` | Centered max-width block |
229
+ | **Rich Text** | `<div class="w-richtext">` | CMS-style formatted content |
230
+ | **HTML Embed** | `<div class="w-embed">` | Raw HTML, SVG, or `<style>` blocks |
231
+
232
+ **Note:** `w-container` (used inside navbars) is different from `w-layout-blockcontainer` (general layout container). Don't mix them.
233
+
234
+ ---
235
+
236
+ ## Custom Attributes
237
+
238
+ - **Standard**: `id`, `href`, `src`, `alt`, `loading`, `target` — set directly on the element
239
+ - **Custom**: `data-*`, `aria-*`, `role`, `tabindex` — supported as custom attributes
240
+ - **`style`** — **never use**
241
+
242
+ ---
243
+
244
+ ## Component Patterns
245
+
246
+ These components require specific `w-` HTML structures. **Read the pattern file before generating any of them:**
247
+
248
+ - [Navbar](elements/navbar.md) — `w-nav` with brand, menu, burger button
249
+ - [Forms](elements/forms.md) — `w-form` wrapper with `w-form-done` / `w-form-fail` states
250
+ - [Dropdown](elements/dropdown.md) — `w-dropdown` with toggle and list
251
+ - [Slider](elements/slider.md) — `w-slider` with mask, slides, arrows, dot nav
252
+ - [Tabs](elements/tabs.md) — `w-tabs` with `data-w-tab` matching between links and panes
253
+ - [Lightbox](elements/lightbox.md) — `w-lightbox` with `w-json` config
254
+ - [Background Video](elements/background-video.md) — `w-background-video` with data attributes
255
+ - [Images](elements/images.md) — `<img>`, responsive `srcset`, SVG handling, `object-fit`
256
+ - [Links & Buttons](elements/links-buttons.md) — `<button>` vs `<a>` detection, Link Block vs Text Link
257
+
258
+ ---
259
+
260
+ ## Advanced Reference
261
+
262
+ - [Ghost Blocks & Dynamic States](patterns/ghost-blocks.md) — hidden states with JS, `::before`/`::after`, `@keyframes`, unsupported CSS via embed blocks
263
+ - [CSS Property Reference](css/best-practices.md) — detailed writing guide for spacing, borders, gradients, transitions, grid, flexbox, typography, filters, effects
264
+
265
+ ---
266
+
267
+ ## Accessibility Checklist
268
+
269
+ - Every `<img>` must have `alt` (empty `alt=""` for decorative images)
270
+ - Form inputs must have `<label>` with matching `for`/`id`
271
+ - Interactive elements must be keyboard-focusable with visible focus styles
272
+ - Icon-only buttons/links need `aria-label`
273
+ - Color contrast: WCAG AA minimum (4.5:1 normal text, 3:1 large text)
274
+ - Don't rely on color alone to convey information
275
+ - Use semantic tags (`<nav>`, `<main>`, `<section>`, `<article>`)
276
+
277
+ ---
278
+
279
+ ## Client-First
280
+
281
+ **Only apply this section if the user chose Client-First.** Otherwise skip entirely.
282
+
283
+ ### 5 Rules
284
+
285
+ 1. **Page skeleton is mandatory** — `page-wrapper > main-wrapper > section_[id] > padding-global padding-section-[size] > container-[size] > content`
286
+ 2. **Underscore = custom, hyphen = utility** — `hero_heading` (custom), `text-size-large` (utility), `is-primary` (combo)
287
+ 3. **All units in rem** — Never px. Only exception: `border-width` can use px.
288
+ 4. **Max 2 utility classes per element** — 3+ utilities = create a custom class instead. Exception: `padding-global padding-section-large`.
289
+ 5. **Flat CSS selectors only** — Same as Webflow Rule #1.
290
+
291
+ ### 3 Class Types
292
+
293
+ **Custom** — `[folder]_[element]`: specific to one component.
294
+ `hero_heading`, `footer_link`, `pricing_card`
295
+
296
+ **Utility** — `[category]-[property]-[value]`: reusable site-wide.
297
+ `text-size-large`, `margin-bottom margin-medium`, `hide-tablet`
298
+
299
+ **Combo** — `is-[variant]`: modifier on a base class. Never used alone.
300
+ `is-secondary`, `is-featured`, `is-active`
301
+
302
+ ### Page Skeleton
303
+
304
+ ```html
305
+ <div class="page-wrapper">
306
+ <main class="main-wrapper">
307
+ <section class="section_hero">
308
+ <div class="padding-global padding-section-large">
309
+ <div class="container-large">
310
+ <!-- content -->
311
+ </div>
312
+ </div>
313
+ </section>
314
+ </main>
315
+ </div>
316
+ ```
317
+
318
+ Nav and footer go **outside** `main-wrapper`, **inside** `page-wrapper`. `padding-global` and `padding-section-[size]` go on the **SAME div**.
319
+
320
+ ### Detailed Client-First Reference
321
+
322
+ Read these files for complete patterns and values:
323
+
324
+ - [Naming Conventions](client-first/naming/conventions.md) — full rules for custom, utility, and combo classes
325
+ - [Page Skeleton](client-first/structure/page-skeleton.md) — 5-layer structure, container sizes, padding values, complete page example
326
+ - [CSS Rules](client-first/css/rules.md) — rem values, core structure CSS, mandatory responsive overrides, typography base styles
327
+ - [Typography Utilities](client-first/utilities/typography.md) — `heading-style-*`, `text-size-*`, `text-weight-*`, `text-color-*`, `text-align-*`
328
+ - [Spacing Utilities](client-first/utilities/spacing.md) — margin/padding two-class system, spacer blocks, all size values
329
+ - [Layout Utilities](client-first/utilities/layout.md) — `max-width-*`, `hide-*`, `background-color-*`, icons, positioning, aspect ratios
330
+ - [Button Utilities](client-first/utilities/buttons.md) — `.button` base, `is-secondary`/`is-text`/`is-small`/`is-large` variants
@@ -0,0 +1,102 @@
1
+ # CSS Rules for Client-First
2
+
3
+ ## Units: rem Only
4
+
5
+ All sizes in rem (`1rem = 16px`). Use these standard values:
6
+
7
+ | rem | px | | rem | px |
8
+ |---|---|---|---|---|
9
+ | `0.25` | 4 | | `2.5` | 40 |
10
+ | `0.5` | 8 | | `3` | 48 |
11
+ | `0.75` | 12 | | `4` | 64 |
12
+ | `1` | 16 | | `5` | 80 |
13
+ | `1.25` | 20 | | `6` | 96 |
14
+ | `1.5` | 24 | | `8` | 128 |
15
+ | `2` | 32 | | `12` | 192 |
16
+
17
+ **Exception:** `border-width` values can use `px` (e.g., `border-width: 1px`).
18
+
19
+ ## Core Structure CSS
20
+
21
+ Only include classes that appear in the HTML:
22
+
23
+ ```css
24
+ /* Horizontal padding */
25
+ .padding-global { padding-left: 2.5rem; padding-right: 2.5rem; }
26
+
27
+ /* Containers */
28
+ .container-large { max-width: 80rem; margin-left: auto; margin-right: auto; width: 100%; }
29
+ .container-medium { max-width: 64rem; margin-left: auto; margin-right: auto; width: 100%; }
30
+ .container-small { max-width: 48rem; margin-left: auto; margin-right: auto; width: 100%; }
31
+
32
+ /* Section padding */
33
+ .padding-section-large { padding-top: 8rem; padding-bottom: 8rem; }
34
+ .padding-section-medium { padding-top: 5rem; padding-bottom: 5rem; }
35
+ .padding-section-small { padding-top: 3rem; padding-bottom: 3rem; }
36
+ ```
37
+
38
+ ## Mandatory Responsive Overrides
39
+
40
+ These must always be included when using the corresponding structure classes:
41
+
42
+ ```css
43
+ @media (max-width: 991px) {
44
+ .padding-global { padding-left: 1.5rem; padding-right: 1.5rem; }
45
+ .padding-section-large { padding-top: 6rem; padding-bottom: 6rem; }
46
+ .padding-section-medium { padding-top: 4rem; padding-bottom: 4rem; }
47
+ .padding-section-small { padding-top: 2rem; padding-bottom: 2rem; }
48
+ }
49
+
50
+ @media (max-width: 479px) {
51
+ .padding-global { padding-left: 1.25rem; padding-right: 1.25rem; }
52
+ .padding-section-large { padding-top: 4rem; padding-bottom: 4rem; }
53
+ .padding-section-medium { padding-top: 3rem; padding-bottom: 3rem; }
54
+ .padding-section-small { padding-top: 1.5rem; padding-bottom: 1.5rem; }
55
+ }
56
+ ```
57
+
58
+ ## CSS Organization Order
59
+
60
+ Structure your CSS in this order for consistency:
61
+
62
+ 1. **Core structure** — `padding-global`, containers, `padding-section-*`
63
+ 2. **Typography utilities** — `text-size-*`, `text-weight-*`, `heading-style-*`
64
+ 3. **Button utilities** — `button`, `.button.is-*` variants
65
+ 4. **Spacing utilities** — `margin-*`, `padding-*`, `spacer-*`
66
+ 5. **Layout utilities** — `max-width-*`, `hide-*`, `overflow-*`
67
+ 6. **Custom classes** — grouped by section (`hero_*`, `features_*`, `footer_*`)
68
+ 7. **Responsive overrides** — tablet (991px) → mobile landscape (767px) → mobile portrait (479px)
69
+
70
+ ## Typography Base Styles
71
+
72
+ Define tag-level styles for consistent typography across the site:
73
+
74
+ ```css
75
+ /* Heading tag styles */
76
+ h1 { font-size: 3.5rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }
77
+ h2 { font-size: 2.5rem; font-weight: 700; line-height: 1.2; letter-spacing: -0.02em; }
78
+ h3 { font-size: 2rem; font-weight: 600; line-height: 1.3; }
79
+ h4 { font-size: 1.5rem; font-weight: 600; line-height: 1.4; }
80
+ h5 { font-size: 1.25rem; font-weight: 600; line-height: 1.4; }
81
+ h6 { font-size: 1rem; font-weight: 600; line-height: 1.5; }
82
+
83
+ /* Body text */
84
+ p { font-size: 1rem; line-height: 1.6; color: #374151; }
85
+ a { color: #2563eb; text-decoration: none; }
86
+ a:hover { text-decoration: underline; }
87
+
88
+ /* Responsive typography */
89
+ @media (max-width: 991px) {
90
+ h1 { font-size: 2.75rem; }
91
+ h2 { font-size: 2rem; }
92
+ h3 { font-size: 1.75rem; }
93
+ }
94
+
95
+ @media (max-width: 479px) {
96
+ h1 { font-size: 2.25rem; }
97
+ h2 { font-size: 1.75rem; }
98
+ h3 { font-size: 1.5rem; }
99
+ }
100
+ ```
101
+
102
+ **Note:** These are starting values. Adapt sizes, weights, and colors to the project's design system.
@@ -0,0 +1,92 @@
1
+ # Client-First Naming Conventions
2
+
3
+ ## 3 Class Types
4
+
5
+ ### 1. Custom Classes — `[folder]_[element-name]`
6
+
7
+ Underscore separates the component (folder) from the element: `hero_heading`, `footer_link`, `team-list_headshot-image`.
8
+
9
+ Rules:
10
+ - **One underscore only** — folder + element
11
+ - **Hyphens for multi-word names** — `team-list_headshot-wrapper`
12
+ - **Descriptive, not abbreviated** — `hero_description` not `hero_desc`
13
+ - **Lowercase always** — never camelCase
14
+
15
+ ```html
16
+ <section class="section_hero">
17
+ <div class="hero_content">
18
+ <h1 class="hero_heading">Welcome</h1>
19
+ <p class="hero_description">Build something great</p>
20
+ <div class="hero_button-wrapper">
21
+ <a href="/start" class="button">Get started</a>
22
+ </div>
23
+ </div>
24
+ <div class="hero_image-wrapper">
25
+ <img src="hero.jpg" alt="Hero" class="hero_image" />
26
+ </div>
27
+ </section>
28
+ ```
29
+
30
+ ### 2. Utility Classes — `[category]-[property]-[value]`
31
+
32
+ No underscore, hyphens only. Reusable across the entire site.
33
+
34
+ ```html
35
+ <p class="text-size-large">Large text paragraph</p>
36
+ <div class="margin-bottom margin-medium">Spaced element</div>
37
+ <div class="hide-mobile-portrait">Hidden on small screens</div>
38
+ ```
39
+
40
+ General → specific reading order: `text-size-large` reads as "text → size → large".
41
+
42
+ ### 3. Combo Classes — `is-[variant]`
43
+
44
+ Applied ON TOP of a base class to create variants. **Never used alone.**
45
+
46
+ ```html
47
+ <a class="button is-secondary">Learn more</a>
48
+ <div class="card is-featured">Featured card</div>
49
+ <a class="nav_link is-active">Current page</a>
50
+ ```
51
+
52
+ ```css
53
+ .button.is-secondary { background-color: transparent; border-width: 1px; border-style: solid; }
54
+ .card.is-featured { border-color: #2563eb; }
55
+ .nav_link.is-active { color: #2563eb; font-weight: 700; }
56
+ ```
57
+
58
+ ## Decision Guide
59
+
60
+ | Situation | Use | Example |
61
+ |---|---|---|
62
+ | Specific to one component | Custom | `hero_heading` |
63
+ | Reused across multiple components | Utility | `text-size-large` |
64
+ | Variant of a base style | Combo | `is-highlighted` |
65
+ | 3+ utilities would stack | Custom class instead | `hero_stats` (not `text-size-large text-weight-bold text-color-primary`) |
66
+
67
+ ## No Deep Stacking
68
+
69
+ Max 2 utility classes per element.
70
+
71
+ **Exception:** `padding-global padding-section-large` (Layer 4 structure) — this specific combo is always allowed.
72
+
73
+ **Wrong:**
74
+ ```html
75
+ <p class="text-size-large text-weight-bold text-color-primary">Too many utilities</p>
76
+ ```
77
+
78
+ **Right:**
79
+ ```html
80
+ <p class="hero_stat-value">Clean custom class</p>
81
+ ```
82
+
83
+ ## Common Naming Patterns
84
+
85
+ | Component | Custom classes |
86
+ |---|---|
87
+ | Hero section | `hero_content`, `hero_heading`, `hero_description`, `hero_button-wrapper`, `hero_image` |
88
+ | Feature card | `feature_card`, `feature_icon`, `feature_title`, `feature_description` |
89
+ | Testimonial | `testimonial_card`, `testimonial_quote`, `testimonial_author`, `testimonial_avatar` |
90
+ | Pricing | `pricing_card`, `pricing_title`, `pricing_price`, `pricing_features`, `pricing_cta` |
91
+ | Footer | `footer_component`, `footer_top`, `footer_bottom`, `footer_link`, `footer_social` |
92
+ | CTA section | `cta_content`, `cta_heading`, `cta_description`, `cta_button-wrapper` |