@uniweb/build 0.7.6 → 0.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/build",
3
- "version": "0.7.6",
3
+ "version": "0.8.0",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -16,64 +16,82 @@ import { generatePalettes, formatOklch } from './shade-generator.js'
16
16
  // These map abstract concepts to specific palette values
17
17
  const DEFAULT_CONTEXT_TOKENS = {
18
18
  light: {
19
- 'bg': 'var(--neutral-50)',
20
- 'bg-subtle': 'var(--neutral-100)',
21
- 'bg-muted': 'var(--neutral-200)',
22
- 'text': 'var(--neutral-950)',
23
- 'text-muted': 'var(--neutral-600)',
24
- 'text-subtle': 'var(--neutral-500)',
19
+ 'section': 'var(--neutral-50)',
20
+ 'card': 'var(--neutral-100)',
21
+ 'muted': 'var(--neutral-200)',
22
+ 'body': 'var(--neutral-950)',
25
23
  'heading': 'var(--neutral-900)',
26
- 'link': 'var(--primary-600)',
27
- 'link-hover': 'var(--primary-700)',
24
+ 'subtle': 'var(--neutral-600)',
28
25
  'border': 'var(--neutral-200)',
29
- 'border-muted': 'var(--neutral-100)',
30
26
  'ring': 'var(--primary-500)',
31
- 'btn-primary-bg': 'var(--primary-600)',
32
- 'btn-primary-text': 'white',
33
- 'btn-primary-hover': 'var(--primary-700)',
34
- 'btn-secondary-bg': 'var(--neutral-100)',
35
- 'btn-secondary-text': 'var(--neutral-900)',
36
- 'btn-secondary-hover': 'var(--neutral-200)',
27
+ 'link': 'var(--primary-600)',
28
+ 'link-hover': 'var(--primary-700)',
29
+ 'primary': 'var(--primary-600)',
30
+ 'primary-foreground': 'white',
31
+ 'primary-hover': 'var(--primary-700)',
32
+ 'secondary': 'var(--neutral-100)',
33
+ 'secondary-foreground': 'var(--neutral-900)',
34
+ 'secondary-hover': 'var(--neutral-200)',
35
+ 'success': '#16a34a',
36
+ 'success-subtle': '#f0fdf4',
37
+ 'warning': '#d97706',
38
+ 'warning-subtle': '#fffbeb',
39
+ 'error': '#dc2626',
40
+ 'error-subtle': '#fef2f2',
41
+ 'info': '#2563eb',
42
+ 'info-subtle': '#eff6ff',
37
43
  },
38
44
  medium: {
39
- 'bg': 'var(--neutral-100)',
40
- 'bg-subtle': 'var(--neutral-200)',
41
- 'bg-muted': 'var(--neutral-300)',
42
- 'text': 'var(--neutral-950)',
43
- 'text-muted': 'var(--neutral-700)',
44
- 'text-subtle': 'var(--neutral-600)',
45
+ 'section': 'var(--neutral-100)',
46
+ 'card': 'var(--neutral-200)',
47
+ 'muted': 'var(--neutral-300)',
48
+ 'body': 'var(--neutral-950)',
45
49
  'heading': 'var(--neutral-900)',
46
- 'link': 'var(--primary-600)',
47
- 'link-hover': 'var(--primary-700)',
50
+ 'subtle': 'var(--neutral-700)',
48
51
  'border': 'var(--neutral-300)',
49
- 'border-muted': 'var(--neutral-200)',
50
52
  'ring': 'var(--primary-500)',
51
- 'btn-primary-bg': 'var(--primary-600)',
52
- 'btn-primary-text': 'white',
53
- 'btn-primary-hover': 'var(--primary-700)',
54
- 'btn-secondary-bg': 'var(--neutral-200)',
55
- 'btn-secondary-text': 'var(--neutral-900)',
56
- 'btn-secondary-hover': 'var(--neutral-300)',
53
+ 'link': 'var(--primary-600)',
54
+ 'link-hover': 'var(--primary-700)',
55
+ 'primary': 'var(--primary-600)',
56
+ 'primary-foreground': 'white',
57
+ 'primary-hover': 'var(--primary-700)',
58
+ 'secondary': 'var(--neutral-200)',
59
+ 'secondary-foreground': 'var(--neutral-900)',
60
+ 'secondary-hover': 'var(--neutral-300)',
61
+ 'success': '#16a34a',
62
+ 'success-subtle': '#f0fdf4',
63
+ 'warning': '#d97706',
64
+ 'warning-subtle': '#fffbeb',
65
+ 'error': '#dc2626',
66
+ 'error-subtle': '#fef2f2',
67
+ 'info': '#2563eb',
68
+ 'info-subtle': '#eff6ff',
57
69
  },
58
70
  dark: {
59
- 'bg': 'var(--neutral-900)',
60
- 'bg-subtle': 'var(--neutral-800)',
61
- 'bg-muted': 'var(--neutral-700)',
62
- 'text': 'var(--neutral-50)',
63
- 'text-muted': 'var(--neutral-300)',
64
- 'text-subtle': 'var(--neutral-400)',
71
+ 'section': 'var(--neutral-900)',
72
+ 'card': 'var(--neutral-800)',
73
+ 'muted': 'var(--neutral-700)',
74
+ 'body': 'var(--neutral-50)',
65
75
  'heading': 'white',
66
- 'link': 'var(--primary-400)',
67
- 'link-hover': 'var(--primary-300)',
76
+ 'subtle': 'var(--neutral-400)',
68
77
  'border': 'var(--neutral-700)',
69
- 'border-muted': 'var(--neutral-800)',
70
78
  'ring': 'var(--primary-500)',
71
- 'btn-primary-bg': 'var(--primary-500)',
72
- 'btn-primary-text': 'white',
73
- 'btn-primary-hover': 'var(--primary-400)',
74
- 'btn-secondary-bg': 'var(--neutral-800)',
75
- 'btn-secondary-text': 'var(--neutral-100)',
76
- 'btn-secondary-hover': 'var(--neutral-700)',
79
+ 'link': 'var(--primary-400)',
80
+ 'link-hover': 'var(--primary-300)',
81
+ 'primary': 'var(--primary-500)',
82
+ 'primary-foreground': 'white',
83
+ 'primary-hover': 'var(--primary-400)',
84
+ 'secondary': 'var(--neutral-800)',
85
+ 'secondary-foreground': 'var(--neutral-100)',
86
+ 'secondary-hover': 'var(--neutral-700)',
87
+ 'success': '#4ade80',
88
+ 'success-subtle': '#052e16',
89
+ 'warning': '#fbbf24',
90
+ 'warning-subtle': '#451a03',
91
+ 'error': '#f87171',
92
+ 'error-subtle': '#450a0a',
93
+ 'info': '#60a5fa',
94
+ 'info-subtle': '#172554',
77
95
  },
78
96
  }
79
97
 
@@ -82,7 +100,7 @@ const DEFAULT_COLORS = {
82
100
  primary: '#3b82f6', // Blue
83
101
  secondary: '#64748b', // Slate
84
102
  accent: '#8b5cf6', // Purple
85
- neutral: '#71717a', // Zinc
103
+ neutral: '#78716c', // Stone
86
104
  }
87
105
 
88
106
  // Shade levels for CSS variable generation
@@ -134,7 +152,7 @@ function generateContextCSS(context, tokens = {}) {
134
152
 
135
153
  const vars = generateVarDeclarations(mergedTokens)
136
154
 
137
- return `.context-${context} {\n${vars}\n background-color: var(--bg);\n}`
155
+ return `.context-${context} {\n${vars}\n background-color: var(--section);\n}`
138
156
  }
139
157
 
140
158
  /**
@@ -148,17 +166,30 @@ function generateDarkSchemeCSS(config = {}) {
148
166
 
149
167
  // Dark scheme tokens - similar to dark context but at root level
150
168
  const darkTokens = {
151
- 'bg': 'var(--neutral-950)',
152
- 'bg-subtle': 'var(--neutral-900)',
153
- 'bg-muted': 'var(--neutral-800)',
154
- 'text': 'var(--neutral-50)',
155
- 'text-muted': 'var(--neutral-300)',
156
- 'text-subtle': 'var(--neutral-400)',
169
+ 'section': 'var(--neutral-950)',
170
+ 'card': 'var(--neutral-900)',
171
+ 'muted': 'var(--neutral-800)',
172
+ 'body': 'var(--neutral-50)',
157
173
  'heading': 'white',
174
+ 'subtle': 'var(--neutral-400)',
175
+ 'border': 'var(--neutral-800)',
176
+ 'ring': 'var(--primary-500)',
158
177
  'link': 'var(--primary-400)',
159
178
  'link-hover': 'var(--primary-300)',
160
- 'border': 'var(--neutral-800)',
161
- 'border-muted': 'var(--neutral-900)',
179
+ 'primary': 'var(--primary-500)',
180
+ 'primary-foreground': 'white',
181
+ 'primary-hover': 'var(--primary-400)',
182
+ 'secondary': 'var(--neutral-800)',
183
+ 'secondary-foreground': 'var(--neutral-100)',
184
+ 'secondary-hover': 'var(--neutral-700)',
185
+ 'success': '#4ade80',
186
+ 'success-subtle': '#052e16',
187
+ 'warning': '#fbbf24',
188
+ 'warning-subtle': '#451a03',
189
+ 'error': '#f87171',
190
+ 'error-subtle': '#450a0a',
191
+ 'info': '#60a5fa',
192
+ 'info-subtle': '#172554',
162
193
  }
163
194
 
164
195
  const vars = generateVarDeclarations(darkTokens)
@@ -11,6 +11,31 @@
11
11
  import { isValidColor, generatePalettes } from './shade-generator.js'
12
12
  import { getDefaultColors, getDefaultContextTokens } from './css-generator.js'
13
13
 
14
+ /**
15
+ * Named neutral presets mapping to Tailwind gray families
16
+ */
17
+ const NEUTRAL_PRESETS = {
18
+ stone: '#78716c',
19
+ zinc: '#71717a',
20
+ gray: '#6b7280',
21
+ slate: '#64748b',
22
+ neutral: '#737373',
23
+ }
24
+
25
+ /**
26
+ * Default inline text styles (content-author markdown: [text]{emphasis})
27
+ * These reference semantic tokens so they adapt to context automatically
28
+ */
29
+ const DEFAULT_INLINE = {
30
+ emphasis: {
31
+ color: 'var(--link)',
32
+ 'font-weight': '600',
33
+ },
34
+ muted: {
35
+ color: 'var(--subtle)',
36
+ },
37
+ }
38
+
14
39
  /**
15
40
  * Default appearance configuration
16
41
  */
@@ -84,6 +109,11 @@ function validateColors(colors) {
84
109
  continue
85
110
  }
86
111
 
112
+ // Accept neutral preset names (stone, zinc, gray, slate, neutral)
113
+ if (name === 'neutral' && NEUTRAL_PRESETS[value]) {
114
+ continue
115
+ }
116
+
87
117
  if (!isValidColor(value)) {
88
118
  errors.push(`Color "${name}" has invalid value: ${value}`)
89
119
  }
@@ -357,7 +387,12 @@ export function processTheme(rawConfig = {}, options = {}) {
357
387
 
358
388
  // Process colors
359
389
  const defaultColors = getDefaultColors()
360
- const rawColors = rawConfig.colors || {}
390
+ const rawColors = { ...(rawConfig.colors || {}) }
391
+
392
+ // Resolve named neutral presets to hex values
393
+ if (typeof rawColors.neutral === 'string' && NEUTRAL_PRESETS[rawColors.neutral]) {
394
+ rawColors.neutral = NEUTRAL_PRESETS[rawColors.neutral]
395
+ }
361
396
 
362
397
  // Filter to only valid colors (skip invalid ones in non-strict mode)
363
398
  const validColors = {}
@@ -382,7 +417,7 @@ export function processTheme(rawConfig = {}, options = {}) {
382
417
  warnings.push('No primary color specified, using default blue (#3b82f6)')
383
418
  }
384
419
  if (!rawConfig.colors?.neutral) {
385
- warnings.push('No neutral color specified, using default zinc (#71717a)')
420
+ warnings.push('No neutral color specified, using default stone (#78716c)')
386
421
  }
387
422
 
388
423
  // Process contexts
@@ -426,7 +461,8 @@ export function processTheme(rawConfig = {}, options = {}) {
426
461
  const background = rawConfig.background || null
427
462
 
428
463
  // Inline text styles (semantic names → CSS declarations)
429
- const inline = rawConfig.inline || null
464
+ // Merge framework defaults with user overrides (user values win)
465
+ const inline = { ...DEFAULT_INLINE, ...(rawConfig.inline || {}) }
430
466
 
431
467
  const config = {
432
468
  colors, // Raw colors for CSS generator