@bookklik/senangstart-css 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.agent/skills/add-utility/scripts/scaffold-utility.js +209 -0
  2. package/.agent/skills/compiler-development/SKILL.md +272 -0
  3. package/.agent/skills/jit-engine/SKILL.md +241 -0
  4. package/.agent/skills/jit-engine/examples/add-visual-utility.js +117 -0
  5. package/.agent/skills/jit-engine/examples/scale-based-utilities.js +130 -0
  6. package/.agent/skills/jit-engine/examples/state-responsive-handling.js +177 -0
  7. package/.agent/skills/senangstart-architecture/SKILL.md +163 -0
  8. package/.agent/skills/tailwind-conversion/SKILL.md +264 -0
  9. package/.agent/workflows/add-utility.md +155 -0
  10. package/.agent/workflows/build.md +97 -0
  11. package/.agent/workflows/dev.md +58 -0
  12. package/.agent/workflows/docs.md +113 -0
  13. package/.agent/workflows/test.md +103 -0
  14. package/dist/senangstart-css.js +99 -56
  15. package/dist/senangstart-css.min.js +36 -27
  16. package/dist/senangstart-tw.js +71 -2
  17. package/dist/senangstart-tw.min.js +1 -1
  18. package/docs/.vitepress/config.js +10 -2
  19. package/docs/guide/getting-started.md +6 -0
  20. package/docs/ms/guide/getting-started.md +6 -0
  21. package/docs/ms/reference/space/height.md +42 -7
  22. package/docs/ms/reference/space/width.md +40 -5
  23. package/docs/ms/reference/visual/divide-reverse.md +66 -0
  24. package/docs/ms/reference/visual/divide-style.md +80 -0
  25. package/docs/ms/reference/visual/divide-width.md +89 -0
  26. package/docs/ms/reference/visual/divide.md +115 -0
  27. package/docs/public/assets/senangstart-css.min.js +36 -27
  28. package/docs/public/llms.txt +40 -1
  29. package/docs/reference/space/height.md +42 -7
  30. package/docs/reference/space/width.md +40 -5
  31. package/docs/reference/visual/divide-reverse.md +66 -0
  32. package/docs/reference/visual/divide-style.md +80 -0
  33. package/docs/reference/visual/divide-width.md +89 -0
  34. package/docs/reference/visual/divide.md +115 -0
  35. package/docs/reference/visual.md +8 -2
  36. package/package.json +1 -1
  37. package/scripts/convert-tailwind.js +105 -2
  38. package/scripts/generate-llms-txt.js +2 -1
  39. package/src/cdn/senangstart-engine.js +128 -40
  40. package/src/cdn/tw-conversion-engine.js +92 -3
  41. package/src/compiler/generators/css.js +107 -3
  42. package/src/definitions/index.js +3 -0
  43. package/src/definitions/space.js +53 -17
  44. package/src/definitions/visual-divide.js +225 -0
  45. package/tests/unit/compiler/generators/css.test.js +75 -3
  46. package/tests/unit/convert-tailwind.test.js +71 -1
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Scaffold New Utility
5
+ *
6
+ * Helper script to generate boilerplate for a new SenangStart utility.
7
+ * Creates definition, adds stub to JIT engine, and generates test file.
8
+ *
9
+ * Usage: node .agent/skills/add-utility/scripts/scaffold-utility.js <name> <category>
10
+ *
11
+ * Example: node .agent/skills/add-utility/scripts/scaffold-utility.js glow visual
12
+ */
13
+
14
+ import fs from 'fs';
15
+ import path from 'path';
16
+ import { fileURLToPath } from 'url';
17
+
18
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
+ const rootDir = path.resolve(__dirname, '../../../../');
20
+
21
+ // Parse arguments
22
+ const args = process.argv.slice(2);
23
+ const utilityName = args[0];
24
+ const category = args[1] || 'visual';
25
+
26
+ if (!utilityName) {
27
+ console.log(`
28
+ šŸ“¦ SenangStart Utility Scaffold
29
+
30
+ Usage: node scaffold-utility.js <name> [category]
31
+
32
+ Arguments:
33
+ name Utility name (e.g., 'glow', 'outline-offset')
34
+ category Category: layout | space | visual (default: visual)
35
+
36
+ Example:
37
+ node scaffold-utility.js glow visual
38
+ node scaffold-utility.js gap-x space
39
+ node scaffold-utility.js grid-flow layout
40
+ `);
41
+ process.exit(0);
42
+ }
43
+
44
+ console.log(`\nšŸ”§ Scaffolding utility: ${utilityName} (${category})\n`);
45
+
46
+ // ============================================
47
+ // 1. Generate Definition Template
48
+ // ============================================
49
+
50
+ const definitionTemplate = `/**
51
+ * ${utilityName} - SenangStart CSS Utility Definition
52
+ * Category: ${category}
53
+ *
54
+ * TODO: Update values, descriptions, and examples
55
+ */
56
+
57
+ export const ${toCamelCase(utilityName)}Definition = {
58
+ name: '${utilityName}',
59
+ property: 'TODO-css-property',
60
+ category: '${category}',
61
+ attribute: '${category}',
62
+ description: 'TODO: English description',
63
+ descriptionMs: 'TODO: Malay description',
64
+ syntax: '${utilityName}:<value>',
65
+ values: [
66
+ { name: 'small', value: 'TODO', description: 'Small value' },
67
+ { name: 'medium', value: 'TODO', description: 'Medium value' },
68
+ { name: 'big', value: 'TODO', description: 'Big value' },
69
+ { name: 'none', value: 'none', description: 'Disable' }
70
+ ],
71
+ examples: [
72
+ { code: '${category}="${utilityName}:small"', description: 'Basic usage' },
73
+ { code: '${category}="hover:${utilityName}:medium"', description: 'On hover' }
74
+ ],
75
+ notes: 'TODO: Additional notes for documentation'
76
+ };
77
+
78
+ export default { ${toCamelCase(utilityName)}Definition };
79
+ `;
80
+
81
+ // ============================================
82
+ // 2. Generate Test Template
83
+ // ============================================
84
+
85
+ const testTemplate = `/**
86
+ * ${utilityName} Utility Tests
87
+ */
88
+
89
+ import { test, describe } from 'node:test';
90
+ import assert from 'node:assert';
91
+ // import { generateVisualRule } from '../../../../src/compiler/generators/css.js';
92
+
93
+ const mockConfig = {
94
+ theme: {
95
+ // TODO: Add required theme scales
96
+ }
97
+ };
98
+
99
+ describe('${utilityName} utility', () => {
100
+ test('generates correct CSS for small value', () => {
101
+ const token = {
102
+ property: '${utilityName}',
103
+ value: 'small',
104
+ attrType: '${category}'
105
+ };
106
+ // TODO: Uncomment and update when generator is implemented
107
+ // const result = generate${capitalize(category)}Rule(token, mockConfig);
108
+ // assert.strictEqual(result, 'TODO-expected-css');
109
+ assert.ok(true, 'TODO: Implement test');
110
+ });
111
+
112
+ test('generates correct CSS for none value', () => {
113
+ const token = {
114
+ property: '${utilityName}',
115
+ value: 'none',
116
+ attrType: '${category}'
117
+ };
118
+ // TODO: Implement
119
+ assert.ok(true, 'TODO: Implement test');
120
+ });
121
+
122
+ test('handles arbitrary values', () => {
123
+ const token = {
124
+ property: '${utilityName}',
125
+ value: '10px',
126
+ attrType: '${category}',
127
+ isArbitrary: true
128
+ };
129
+ // TODO: Implement
130
+ assert.ok(true, 'TODO: Implement test');
131
+ });
132
+ });
133
+ `;
134
+
135
+ // ============================================
136
+ // 3. Generate JIT Engine Stub
137
+ // ============================================
138
+
139
+ const jitStubTemplate = `
140
+ // ============================================
141
+ // ${utilityName.toUpperCase()} UTILITY
142
+ // Add this to generate${capitalize(category)}Rule() in src/cdn/senangstart-engine.js
143
+ // ============================================
144
+
145
+ /*
146
+ if (prop === '${utilityName}') {
147
+ if (value === 'none') {
148
+ return 'TODO-css-property: none';
149
+ }
150
+ // TODO: Add scale lookup
151
+ // const scaled = config.theme.TODO_SCALE?.[value];
152
+ // if (scaled) return \`TODO-css-property: \${scaled}\`;
153
+
154
+ // Arbitrary value support
155
+ if (value.startsWith('[') && value.endsWith(']')) {
156
+ return \`TODO-css-property: \${value.slice(1, -1)}\`;
157
+ }
158
+ }
159
+ */
160
+ `;
161
+
162
+ // ============================================
163
+ // Write Files
164
+ // ============================================
165
+
166
+ // Create output directory
167
+ const outputDir = path.join(rootDir, '.agent', 'skills', 'add-utility', 'generated');
168
+ fs.mkdirSync(outputDir, { recursive: true });
169
+
170
+ // Write definition
171
+ const defPath = path.join(outputDir, `${utilityName}-definition.js`);
172
+ fs.writeFileSync(defPath, definitionTemplate);
173
+ console.log(`āœ“ Created definition template: ${path.relative(rootDir, defPath)}`);
174
+
175
+ // Write test
176
+ const testPath = path.join(outputDir, `${utilityName}.test.js`);
177
+ fs.writeFileSync(testPath, testTemplate);
178
+ console.log(`āœ“ Created test template: ${path.relative(rootDir, testPath)}`);
179
+
180
+ // Write JIT stub
181
+ const jitPath = path.join(outputDir, `${utilityName}-jit-stub.js`);
182
+ fs.writeFileSync(jitPath, jitStubTemplate);
183
+ console.log(`āœ“ Created JIT stub: ${path.relative(rootDir, jitPath)}`);
184
+
185
+ console.log(`
186
+ šŸ“‹ Next Steps:
187
+
188
+ 1. Move definition to src/definitions/${category}.js or create new file
189
+ 2. Export from src/definitions/index.js
190
+ 3. Add handler to src/cdn/senangstart-engine.js (use stub as reference)
191
+ 4. Add handler to src/compiler/generators/css.js (same logic)
192
+ 5. Move test to tests/unit/compiler/generators/
193
+ 6. Run: npm run docs:generate
194
+ 7. Run: npm test
195
+
196
+ Generated files are in: .agent/skills/add-utility/generated/
197
+ `);
198
+
199
+ // ============================================
200
+ // Helper Functions
201
+ // ============================================
202
+
203
+ function toCamelCase(str) {
204
+ return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
205
+ }
206
+
207
+ function capitalize(str) {
208
+ return str.charAt(0).toUpperCase() + str.slice(1);
209
+ }
@@ -0,0 +1,272 @@
1
+ ---
2
+ name: Compiler Development
3
+ description: Understanding and extending the CLI compiler with parser, tokenizer, and CSS generators
4
+ ---
5
+
6
+ # Compiler Development
7
+
8
+ This skill covers the build-time compiler used by the CLI commands (`senangstart build` and `senangstart dev`).
9
+
10
+ ## Compiler Architecture
11
+
12
+ ```
13
+ src/compiler/
14
+ ā”œā”€ā”€ index.js # Main compiler entry point
15
+ ā”œā”€ā”€ parser.js # HTML/JSX attribute extraction
16
+ ā”œā”€ā”€ tokenizer.js # Re-exports from core tokenizer
17
+ └── generators/
18
+ ā”œā”€ā”€ css.js # Main CSS generator (~2200 lines)
19
+ ā”œā”€ā”€ preflight.js # Base reset styles
20
+ ā”œā”€ā”€ typescript.js # TypeScript definitions
21
+ └── ai-context.js # AI context generation
22
+ ```
23
+
24
+ ## Compilation Pipeline
25
+
26
+ ```mermaid
27
+ flowchart LR
28
+ A[Source Files] --> B[Parser]
29
+ B --> C[Tokenizer]
30
+ C --> D[Generator]
31
+ D --> E[CSS Output]
32
+ ```
33
+
34
+ 1. **Parser** extracts `layout`, `space`, `visual` attribute values from HTML/JSX
35
+ 2. **Tokenizer** parses raw strings into structured token objects
36
+ 3. **Generator** transforms tokens into CSS rules
37
+
38
+ ---
39
+
40
+ ## Parser (`src/compiler/parser.js`)
41
+
42
+ Extracts SenangStart attributes from source files using regex.
43
+
44
+ ### Key Functions
45
+
46
+ ```javascript
47
+ // Parse single file content
48
+ parseSource(content) → { layout: Set, space: Set, visual: Set }
49
+
50
+ // Parse multiple files
51
+ parseMultipleSources([{path, content}]) → combined results
52
+ ```
53
+
54
+ ### Regex Patterns
55
+
56
+ ```javascript
57
+ const ATTRIBUTE_PATTERNS = {
58
+ layout: /layout\s*=\s*["']([^"']*)\["']/g,
59
+ space: /space\s*=\s*["']([^"']*)\["']/g,
60
+ visual: /visual\s*=\s*["']([^"']*)\["']/g
61
+ };
62
+ ```
63
+
64
+ ### Security Features
65
+ - Value length limits (10,000 chars max)
66
+ - Token length limits (500 chars max)
67
+ - Fresh regex per parse to prevent state issues
68
+
69
+ ---
70
+
71
+ ## Tokenizer (`src/core/tokenizer-core.js`)
72
+
73
+ Transforms raw attribute strings into structured token objects.
74
+
75
+ ### Token Structure
76
+
77
+ ```javascript
78
+ {
79
+ raw: 'tab:hover:bg:blue-500', // Original string
80
+ breakpoint: 'tab', // null | mob | tab | lap | desk
81
+ state: 'hover', // null | hover | focus | active | ...
82
+ property: 'bg', // Utility name
83
+ value: 'blue-500', // Utility value
84
+ isArbitrary: false, // true if [bracketed]
85
+ attrType: 'visual' // layout | space | visual
86
+ }
87
+ ```
88
+
89
+ ### Key Functions
90
+
91
+ ```javascript
92
+ // Tokenize single attribute string
93
+ tokenize(raw, attrType) → token object
94
+
95
+ // Tokenize all parsed attributes
96
+ tokenizeAll(parsed) → token array
97
+
98
+ // Parse token without validation (internal)
99
+ parseToken(raw) → token object
100
+
101
+ // Validate token structure
102
+ isValidToken(token) → boolean
103
+
104
+ // Sanitize value (remove semicolons)
105
+ sanitizeValue(value) → string
106
+ ```
107
+
108
+ ### Parsing Logic
109
+
110
+ 1. Split by `:` separator
111
+ 2. Check first part for breakpoint prefix
112
+ 3. Check next part for state prefix
113
+ 4. Remaining parts are property and value
114
+ 5. Detect arbitrary values with `[brackets]`
115
+
116
+ ---
117
+
118
+ ## CSS Generator (`src/compiler/generators/css.js`)
119
+
120
+ The core generator transforms tokens into CSS rules.
121
+
122
+ ### Main Functions
123
+
124
+ ```javascript
125
+ // Generate complete CSS from tokens
126
+ generateCSS(tokens, config) → string
127
+
128
+ // Generate CSS variables from config
129
+ generateCSSVariables(config) → string
130
+
131
+ // Generate single rule from token
132
+ generateRule(token, config) → string
133
+
134
+ // Minify CSS output
135
+ minifyCSS(css) → string
136
+ ```
137
+
138
+ ### Generator Functions by Category
139
+
140
+ ```javascript
141
+ // Layout utilities (display, flex, grid, position)
142
+ generateLayoutRule(token, config) → string
143
+
144
+ // Space utilities (padding, margin, gap, width, height)
145
+ generateSpaceRule(token, config) → string
146
+
147
+ // Visual utilities (colors, borders, shadows, transforms, etc.)
148
+ generateVisualRule(token, config) → string
149
+ ```
150
+
151
+ ### Adding a New Generator Pattern
152
+
153
+ In the appropriate function (e.g., `generateVisualRule`):
154
+
155
+ ```javascript
156
+ // 1. Simple keyword mapping
157
+ if (prop === 'my-utility') {
158
+ if (value === 'on') return 'my-property: value-on';
159
+ if (value === 'off') return 'my-property: value-off';
160
+ }
161
+
162
+ // 2. Scale-based value
163
+ if (prop === 'my-scale-utility') {
164
+ const v = config.theme.myScale?.[value];
165
+ if (v) return `my-property: ${v}`;
166
+ }
167
+
168
+ // 3. Arbitrary value support
169
+ if (prop === 'my-arbitrary-utility') {
170
+ if (token.isArbitrary) {
171
+ return `my-property: ${sanitizeArbitraryValue(value)}`;
172
+ }
173
+ return `my-property: ${config.theme.myScale?.[value] || value}`;
174
+ }
175
+
176
+ // 4. Multi-property output
177
+ if (prop === 'inset') {
178
+ const v = config.theme.spacing[value] || value;
179
+ return `top: ${v}; right: ${v}; bottom: ${v}; left: ${v}`;
180
+ }
181
+ ```
182
+
183
+ ### CSS Selector Generation
184
+
185
+ Selectors use attribute selectors with proper escaping:
186
+
187
+ ```javascript
188
+ // Simple: [visual~="bg:blue-500"]
189
+ // With state: [visual~="hover:bg:blue-500"]:hover
190
+ // With breakpoint: @media (min-width: 768px) { [layout~="tab:flex"] }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Preflight Generator (`src/compiler/generators/preflight.js`)
196
+
197
+ Generates base reset styles similar to Tailwind's preflight.
198
+
199
+ ```javascript
200
+ generatePreflight() → string // Returns CSS reset
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Other Generators
206
+
207
+ ### TypeScript (`typescript.js`)
208
+ Generates TypeScript declarations for IntelliSense.
209
+
210
+ ### AI Context (`ai-context.js`)
211
+ Generates context files for AI assistants.
212
+
213
+ ---
214
+
215
+ ## Testing Generators
216
+
217
+ Unit tests in `tests/unit/compiler/generators/`:
218
+
219
+ ```javascript
220
+ import { test, describe } from 'node:test';
221
+ import { generateVisualRule } from '../../../src/compiler/generators/css.js';
222
+
223
+ describe('my-utility', () => {
224
+ test('generates correct CSS', () => {
225
+ const token = { property: 'my-utility', value: 'on', attrType: 'visual' };
226
+ const result = generateVisualRule(token, config);
227
+ assert.strictEqual(result, 'my-property: value-on');
228
+ });
229
+ });
230
+ ```
231
+
232
+ Run tests:
233
+ ```bash
234
+ npm run test:unit
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Common Patterns
240
+
241
+ ### State-Aware Generation
242
+
243
+ ```javascript
244
+ function generateRule(token, config) {
245
+ const css = generateVisualRule(token, config);
246
+
247
+ if (token.state) {
248
+ // Wrap with pseudo-selector
249
+ return `${selector}:${token.state} { ${css} }`;
250
+ }
251
+
252
+ return `${selector} { ${css} }`;
253
+ }
254
+ ```
255
+
256
+ ### Responsive Wrapping
257
+
258
+ ```javascript
259
+ if (token.breakpoint) {
260
+ const minWidth = config.theme.screens[token.breakpoint];
261
+ return `@media (min-width: ${minWidth}) { ${rule} }`;
262
+ }
263
+ ```
264
+
265
+ ### Dark Mode Handling
266
+
267
+ ```javascript
268
+ if (token.state === 'dark') {
269
+ const darkSelector = getDarkModeSelector(config);
270
+ return `${darkSelector} ${selector} { ${css} }`;
271
+ }
272
+ ```
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: JIT Engine Development
3
+ description: Developing and extending the browser-based JIT CSS engine
4
+ ---
5
+
6
+ # JIT Engine Development
7
+
8
+ This skill covers development of `src/cdn/senangstart-engine.js` - the browser-based Just-In-Time CSS compilation engine.
9
+
10
+ ## Engine Overview
11
+
12
+ The JIT engine is an IIFE (~83KB unminified) that runs in the browser with zero configuration. It:
13
+
14
+ 1. Observes DOM for elements with `layout`, `space`, or `visual` attributes
15
+ 2. Parses attribute values into utility tokens
16
+ 3. Generates CSS rules on-demand
17
+ 4. Injects styles via a `<style>` element
18
+ 5. Watches for DOM mutations to handle dynamic content
19
+
20
+ ## File Structure
21
+
22
+ ```javascript
23
+ // src/cdn/senangstart-engine.js
24
+
25
+ // Imports from core modules
26
+ import { BREAKPOINTS, STATES, LAYOUT_KEYWORDS } from '../core/constants.js';
27
+ import { tokenize, parseToken } from '../core/tokenizer-core.js';
28
+
29
+ (function() {
30
+ 'use strict';
31
+
32
+ // 1. Default Configuration
33
+ const defaultConfig = { theme: {...}, darkMode: 'media', preflight: true };
34
+
35
+ // 2. Config Loader
36
+ function validateConfig(config) {...}
37
+ function loadInlineConfig() {...}
38
+ function mergeConfig(user) {...}
39
+
40
+ // 3. CSS Variable Generator
41
+ function generateCSSVariables(config) {...}
42
+
43
+ // 4. Utility Generators
44
+ function generateLayoutRule(prop, value, config) {...}
45
+ function generateSpaceRule(prop, value, config) {...}
46
+ function generateVisualRule(prop, value, config) {...}
47
+
48
+ // 5. DOM Observer & Style Injection
49
+ function processElement(element) {...}
50
+ function observeDOM() {...}
51
+
52
+ // 6. Initialize
53
+ document.addEventListener('DOMContentLoaded', init);
54
+ })();
55
+ ```
56
+
57
+ ## Default Configuration
58
+
59
+ Located at the top of the engine, `defaultConfig` defines all theme scales:
60
+
61
+ ```javascript
62
+ const defaultConfig = {
63
+ theme: {
64
+ spacing: {
65
+ 'none': '0px',
66
+ 'thin': '1px',
67
+ // ... full scale
68
+ 'vast-10x': '384px'
69
+ },
70
+ radius: { 'none': '0px', 'small': '4px', ... },
71
+ shadow: { 'none': 'none', 'small': '...', ... },
72
+ fontSize: { 'tiny': '0.75rem', ... },
73
+ fontWeight: { 'normal': '400', 'medium': '500', 'bold': '700' },
74
+ screens: { 'mob': '480px', 'tab': '768px', ... },
75
+ colors: { 'white': '#FFFFFF', 'primary': '#3B82F6', ... },
76
+ zIndex: { 'base': '0', 'low': '10', ... },
77
+ ring: { 'none': '0px', 'thin': '1px', ... }
78
+ },
79
+ darkMode: 'media',
80
+ preflight: true
81
+ };
82
+ ```
83
+
84
+ ## Adding a New Utility Handler
85
+
86
+ ### Step 1: Identify the Category
87
+
88
+ - `generateLayoutRule()` - For layout utilities
89
+ - `generateSpaceRule()` - For spacing utilities
90
+ - `generateVisualRule()` - For visual utilities
91
+
92
+ ### Step 2: Add Pattern Matching
93
+
94
+ In the appropriate generator function:
95
+
96
+ ```javascript
97
+ function generateVisualRule(prop, value, config) {
98
+ // Existing handlers...
99
+
100
+ // ADD: New utility
101
+ if (prop === 'my-utility') {
102
+ // Option 1: Simple keyword mapping
103
+ if (value === 'on') return 'my-css-property: value-on';
104
+ if (value === 'off') return 'my-css-property: value-off';
105
+
106
+ // Option 2: Scale-based
107
+ const scaleValue = config.theme.myScale?.[value];
108
+ if (scaleValue) return `my-css-property: ${scaleValue}`;
109
+
110
+ // Option 3: Arbitrary value with [brackets]
111
+ if (value.startsWith('[') && value.endsWith(']')) {
112
+ return `my-css-property: ${value.slice(1, -1)}`;
113
+ }
114
+ }
115
+
116
+ // ... rest of handlers
117
+ }
118
+ ```
119
+
120
+ ### Step 3: Add Scale (if needed)
121
+
122
+ Add to `defaultConfig.theme`:
123
+
124
+ ```javascript
125
+ myScale: {
126
+ 'small': '4px',
127
+ 'medium': '8px',
128
+ 'big': '16px'
129
+ }
130
+ ```
131
+
132
+ And update `generateCSSVariables()` if CSS variables are needed:
133
+
134
+ ```javascript
135
+ // In generateCSSVariables():
136
+ Object.entries(config.theme.myScale).forEach(([name, value]) => {
137
+ vars += ` --ss-my-scale-${name}: ${value};\n`;
138
+ });
139
+ ```
140
+
141
+ ## State Handling
142
+
143
+ States (hover, focus, etc.) are handled automatically. The engine:
144
+
145
+ 1. Detects state prefix: `hover:bg:blue-500`
146
+ 2. Generates CSS with pseudo-selector: `.hover\:bg\:blue-500:hover { ... }`
147
+
148
+ State parsing occurs in the main processing loop before calling generators.
149
+
150
+ ## Responsive Handling
151
+
152
+ Breakpoints wrap rules in media queries:
153
+
154
+ 1. Detects breakpoint prefix: `mob:flex`
155
+ 2. Generates: `@media (min-width: 480px) { .mob\:flex { display: flex } }`
156
+
157
+ ## CSS Variable System
158
+
159
+ The engine generates CSS variables for all theme values:
160
+
161
+ ```css
162
+ :root {
163
+ --ss-spacing-none: 0px;
164
+ --ss-spacing-thin: 1px;
165
+ --ss-radius-small: 4px;
166
+ --ss-color-primary: #3B82F6;
167
+ /* ... */
168
+ }
169
+ ```
170
+
171
+ Utilities can reference variables:
172
+ ```javascript
173
+ return `border-radius: var(--ss-radius-${value})`;
174
+ ```
175
+
176
+ ## Testing Engine Changes
177
+
178
+ After modifying the engine:
179
+
180
+ 1. **Rebuild distribution:**
181
+ ```bash
182
+ npm run build:dist
183
+ ```
184
+
185
+ 2. **Test in playground:**
186
+ Open `playground/index.html` in browser
187
+
188
+ 3. **Run unit tests:**
189
+ ```bash
190
+ npm run test:unit
191
+ ```
192
+
193
+ 4. **Check sync tests:**
194
+ ```bash
195
+ npm run test:sync
196
+ ```
197
+
198
+ ## Common Patterns
199
+
200
+ ### Color Handler
201
+ ```javascript
202
+ if (prop === 'text') {
203
+ const color = config.theme.colors[value];
204
+ if (color) return `color: ${color}`;
205
+ // Support arbitrary colors
206
+ if (value.startsWith('[')) return `color: ${value.slice(1, -1)}`;
207
+ }
208
+ ```
209
+
210
+ ### Spacing Handler
211
+ ```javascript
212
+ if (prop === 'p') { // padding shorthand
213
+ const space = config.theme.spacing[value];
214
+ if (space) return `padding: ${space}`;
215
+ }
216
+ ```
217
+
218
+ ### Multi-Property Handler
219
+ ```javascript
220
+ if (prop === 'inset') {
221
+ const v = config.theme.spacing[value] || value;
222
+ return `top: ${v}; right: ${v}; bottom: ${v}; left: ${v}`;
223
+ }
224
+ ```
225
+
226
+ ### Transform Handler
227
+ ```javascript
228
+ if (prop === 'rotate') {
229
+ return `--ss-rotate: ${value}deg; transform: var(--ss-transform)`;
230
+ }
231
+ ```
232
+
233
+ ## Debugging
234
+
235
+ Enable debug logging by adding early in the IIFE:
236
+ ```javascript
237
+ const DEBUG = true;
238
+ function log(...args) { if (DEBUG) console.log('[SS]', ...args); }
239
+ ```
240
+
241
+ Then sprinkle `log()` calls in key functions.