@aws505/sheetsite 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/README.md +105 -0
- package/dist/components/index.js +1696 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +1630 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.js +1840 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +1793 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/data/index.js +1296 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/index.mjs +1220 -0
- package/dist/data/index.mjs.map +1 -0
- package/dist/index.js +5433 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5285 -0
- package/dist/index.mjs.map +1 -0
- package/dist/seo/index.js +187 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/index.mjs +155 -0
- package/dist/seo/index.mjs.map +1 -0
- package/dist/theme/index.js +552 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/index.mjs +526 -0
- package/dist/theme/index.mjs.map +1 -0
- package/package.json +96 -0
- package/src/components/index.ts +41 -0
- package/src/components/layout/Footer.tsx +234 -0
- package/src/components/layout/Header.tsx +134 -0
- package/src/components/sections/FAQ.tsx +178 -0
- package/src/components/sections/Gallery.tsx +107 -0
- package/src/components/sections/Hero.tsx +202 -0
- package/src/components/sections/Hours.tsx +225 -0
- package/src/components/sections/Services.tsx +216 -0
- package/src/components/sections/Testimonials.tsx +184 -0
- package/src/components/ui/Button.tsx +158 -0
- package/src/components/ui/Card.tsx +162 -0
- package/src/components/ui/Icons.tsx +508 -0
- package/src/config/index.ts +207 -0
- package/src/config/presets/generic.ts +153 -0
- package/src/config/presets/home-kitchen.ts +154 -0
- package/src/config/presets/index.ts +708 -0
- package/src/config/presets/professional.ts +165 -0
- package/src/config/presets/repair.ts +160 -0
- package/src/config/presets/restaurant.ts +162 -0
- package/src/config/presets/salon.ts +178 -0
- package/src/config/presets/tailor.ts +159 -0
- package/src/config/types.ts +314 -0
- package/src/data/csv-parser.ts +154 -0
- package/src/data/defaults.ts +202 -0
- package/src/data/google-drive.ts +148 -0
- package/src/data/index.ts +535 -0
- package/src/data/sheets.ts +709 -0
- package/src/data/types.ts +379 -0
- package/src/seo/index.ts +272 -0
- package/src/theme/colors.ts +351 -0
- package/src/theme/index.ts +249 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Color Palettes
|
|
3
|
+
*
|
|
4
|
+
* Pre-defined color palettes for different business types and styles.
|
|
5
|
+
* Each palette follows Tailwind's color scale (50-950).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ColorPalette, ThemePreset } from '../config/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Warm Brown - Tailoring, leather, traditional crafts
|
|
12
|
+
*/
|
|
13
|
+
export const warmBrown: ColorPalette = {
|
|
14
|
+
primary: {
|
|
15
|
+
50: '#faf8f6',
|
|
16
|
+
100: '#f2ede8',
|
|
17
|
+
200: '#e4d9ce',
|
|
18
|
+
300: '#d3c0ad',
|
|
19
|
+
400: '#bfa38a',
|
|
20
|
+
500: '#a68a6d',
|
|
21
|
+
600: '#8b7058',
|
|
22
|
+
700: '#735c49',
|
|
23
|
+
800: '#604d3f',
|
|
24
|
+
900: '#514237',
|
|
25
|
+
950: '#2b221c',
|
|
26
|
+
},
|
|
27
|
+
accent: {
|
|
28
|
+
50: '#fef3f2',
|
|
29
|
+
100: '#fee4e2',
|
|
30
|
+
200: '#fecdca',
|
|
31
|
+
300: '#fcaca5',
|
|
32
|
+
400: '#f87d71',
|
|
33
|
+
500: '#ef5544',
|
|
34
|
+
600: '#dc3626',
|
|
35
|
+
700: '#b92a1c',
|
|
36
|
+
800: '#99261b',
|
|
37
|
+
900: '#7f261d',
|
|
38
|
+
950: '#450f0a',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Cool Blue - Professional services, tech, trust
|
|
44
|
+
*/
|
|
45
|
+
export const coolBlue: ColorPalette = {
|
|
46
|
+
primary: {
|
|
47
|
+
50: '#f0f7ff',
|
|
48
|
+
100: '#e0effe',
|
|
49
|
+
200: '#b9dffd',
|
|
50
|
+
300: '#7cc5fc',
|
|
51
|
+
400: '#36a8f8',
|
|
52
|
+
500: '#0c8de9',
|
|
53
|
+
600: '#006fc7',
|
|
54
|
+
700: '#0159a1',
|
|
55
|
+
800: '#064c85',
|
|
56
|
+
900: '#0b406e',
|
|
57
|
+
950: '#072849',
|
|
58
|
+
},
|
|
59
|
+
accent: {
|
|
60
|
+
50: '#f0fdf4',
|
|
61
|
+
100: '#dcfce7',
|
|
62
|
+
200: '#bbf7d0',
|
|
63
|
+
300: '#86efac',
|
|
64
|
+
400: '#4ade80',
|
|
65
|
+
500: '#22c55e',
|
|
66
|
+
600: '#16a34a',
|
|
67
|
+
700: '#15803d',
|
|
68
|
+
800: '#166534',
|
|
69
|
+
900: '#14532d',
|
|
70
|
+
950: '#052e16',
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Earth Green - Natural, organic, outdoor
|
|
76
|
+
*/
|
|
77
|
+
export const earthGreen: ColorPalette = {
|
|
78
|
+
primary: {
|
|
79
|
+
50: '#f4f9f4',
|
|
80
|
+
100: '#e5f2e7',
|
|
81
|
+
200: '#cce5d0',
|
|
82
|
+
300: '#a3d0ac',
|
|
83
|
+
400: '#72b381',
|
|
84
|
+
500: '#4f9760',
|
|
85
|
+
600: '#3d7a4c',
|
|
86
|
+
700: '#33613f',
|
|
87
|
+
800: '#2c4e35',
|
|
88
|
+
900: '#26412e',
|
|
89
|
+
950: '#112317',
|
|
90
|
+
},
|
|
91
|
+
accent: {
|
|
92
|
+
50: '#fefce8',
|
|
93
|
+
100: '#fef9c3',
|
|
94
|
+
200: '#fef08a',
|
|
95
|
+
300: '#fde047',
|
|
96
|
+
400: '#facc15',
|
|
97
|
+
500: '#eab308',
|
|
98
|
+
600: '#ca8a04',
|
|
99
|
+
700: '#a16207',
|
|
100
|
+
800: '#854d0e',
|
|
101
|
+
900: '#713f12',
|
|
102
|
+
950: '#422006',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Warm Amber - Food, hospitality, warmth
|
|
108
|
+
*/
|
|
109
|
+
export const warmAmber: ColorPalette = {
|
|
110
|
+
primary: {
|
|
111
|
+
50: '#fffbeb',
|
|
112
|
+
100: '#fef3c7',
|
|
113
|
+
200: '#fde68a',
|
|
114
|
+
300: '#fcd34d',
|
|
115
|
+
400: '#fbbf24',
|
|
116
|
+
500: '#f59e0b',
|
|
117
|
+
600: '#d97706',
|
|
118
|
+
700: '#b45309',
|
|
119
|
+
800: '#92400e',
|
|
120
|
+
900: '#78350f',
|
|
121
|
+
950: '#451a03',
|
|
122
|
+
},
|
|
123
|
+
accent: {
|
|
124
|
+
50: '#fef2f2',
|
|
125
|
+
100: '#fee2e2',
|
|
126
|
+
200: '#fecaca',
|
|
127
|
+
300: '#fca5a5',
|
|
128
|
+
400: '#f87171',
|
|
129
|
+
500: '#ef4444',
|
|
130
|
+
600: '#dc2626',
|
|
131
|
+
700: '#b91c1c',
|
|
132
|
+
800: '#991b1b',
|
|
133
|
+
900: '#7f1d1d',
|
|
134
|
+
950: '#450a0a',
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Elegant Gold - Luxury, formal, upscale
|
|
140
|
+
*/
|
|
141
|
+
export const elegantGold: ColorPalette = {
|
|
142
|
+
primary: {
|
|
143
|
+
50: '#fdfcf7',
|
|
144
|
+
100: '#f9f5e7',
|
|
145
|
+
200: '#f2e9cb',
|
|
146
|
+
300: '#e8d7a5',
|
|
147
|
+
400: '#dcc07a',
|
|
148
|
+
500: '#cfaa58',
|
|
149
|
+
600: '#c09548',
|
|
150
|
+
700: '#a0783d',
|
|
151
|
+
800: '#826037',
|
|
152
|
+
900: '#6b4f31',
|
|
153
|
+
950: '#3b2a19',
|
|
154
|
+
},
|
|
155
|
+
accent: {
|
|
156
|
+
50: '#f8fafc',
|
|
157
|
+
100: '#f1f5f9',
|
|
158
|
+
200: '#e2e8f0',
|
|
159
|
+
300: '#cbd5e1',
|
|
160
|
+
400: '#94a3b8',
|
|
161
|
+
500: '#64748b',
|
|
162
|
+
600: '#475569',
|
|
163
|
+
700: '#334155',
|
|
164
|
+
800: '#1e293b',
|
|
165
|
+
900: '#0f172a',
|
|
166
|
+
950: '#020617',
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Fresh Teal - Modern, creative, spa
|
|
172
|
+
*/
|
|
173
|
+
export const freshTeal: ColorPalette = {
|
|
174
|
+
primary: {
|
|
175
|
+
50: '#f0fdfa',
|
|
176
|
+
100: '#ccfbf1',
|
|
177
|
+
200: '#99f6e4',
|
|
178
|
+
300: '#5eead4',
|
|
179
|
+
400: '#2dd4bf',
|
|
180
|
+
500: '#14b8a6',
|
|
181
|
+
600: '#0d9488',
|
|
182
|
+
700: '#0f766e',
|
|
183
|
+
800: '#115e59',
|
|
184
|
+
900: '#134e4a',
|
|
185
|
+
950: '#042f2e',
|
|
186
|
+
},
|
|
187
|
+
accent: {
|
|
188
|
+
50: '#fdf4ff',
|
|
189
|
+
100: '#fae8ff',
|
|
190
|
+
200: '#f5d0fe',
|
|
191
|
+
300: '#f0abfc',
|
|
192
|
+
400: '#e879f9',
|
|
193
|
+
500: '#d946ef',
|
|
194
|
+
600: '#c026d3',
|
|
195
|
+
700: '#a21caf',
|
|
196
|
+
800: '#86198f',
|
|
197
|
+
900: '#701a75',
|
|
198
|
+
950: '#4a044e',
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Bold Red - Auto, sports, energy
|
|
204
|
+
*/
|
|
205
|
+
export const boldRed: ColorPalette = {
|
|
206
|
+
primary: {
|
|
207
|
+
50: '#fef2f2',
|
|
208
|
+
100: '#fee2e2',
|
|
209
|
+
200: '#fecaca',
|
|
210
|
+
300: '#fca5a5',
|
|
211
|
+
400: '#f87171',
|
|
212
|
+
500: '#ef4444',
|
|
213
|
+
600: '#dc2626',
|
|
214
|
+
700: '#b91c1c',
|
|
215
|
+
800: '#991b1b',
|
|
216
|
+
900: '#7f1d1d',
|
|
217
|
+
950: '#450a0a',
|
|
218
|
+
},
|
|
219
|
+
accent: {
|
|
220
|
+
50: '#f8fafc',
|
|
221
|
+
100: '#f1f5f9',
|
|
222
|
+
200: '#e2e8f0',
|
|
223
|
+
300: '#cbd5e1',
|
|
224
|
+
400: '#94a3b8',
|
|
225
|
+
500: '#64748b',
|
|
226
|
+
600: '#475569',
|
|
227
|
+
700: '#334155',
|
|
228
|
+
800: '#1e293b',
|
|
229
|
+
900: '#0f172a',
|
|
230
|
+
950: '#020617',
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Soft Pink - Beauty, feminine, delicate
|
|
236
|
+
*/
|
|
237
|
+
export const softPink: ColorPalette = {
|
|
238
|
+
primary: {
|
|
239
|
+
50: '#fdf2f8',
|
|
240
|
+
100: '#fce7f3',
|
|
241
|
+
200: '#fbcfe8',
|
|
242
|
+
300: '#f9a8d4',
|
|
243
|
+
400: '#f472b6',
|
|
244
|
+
500: '#ec4899',
|
|
245
|
+
600: '#db2777',
|
|
246
|
+
700: '#be185d',
|
|
247
|
+
800: '#9d174d',
|
|
248
|
+
900: '#831843',
|
|
249
|
+
950: '#500724',
|
|
250
|
+
},
|
|
251
|
+
accent: {
|
|
252
|
+
50: '#faf5ff',
|
|
253
|
+
100: '#f3e8ff',
|
|
254
|
+
200: '#e9d5ff',
|
|
255
|
+
300: '#d8b4fe',
|
|
256
|
+
400: '#c084fc',
|
|
257
|
+
500: '#a855f7',
|
|
258
|
+
600: '#9333ea',
|
|
259
|
+
700: '#7e22ce',
|
|
260
|
+
800: '#6b21a8',
|
|
261
|
+
900: '#581c87',
|
|
262
|
+
950: '#3b0764',
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Slate Gray - Minimalist, industrial
|
|
268
|
+
*/
|
|
269
|
+
export const slateGray: ColorPalette = {
|
|
270
|
+
primary: {
|
|
271
|
+
50: '#f8fafc',
|
|
272
|
+
100: '#f1f5f9',
|
|
273
|
+
200: '#e2e8f0',
|
|
274
|
+
300: '#cbd5e1',
|
|
275
|
+
400: '#94a3b8',
|
|
276
|
+
500: '#64748b',
|
|
277
|
+
600: '#475569',
|
|
278
|
+
700: '#334155',
|
|
279
|
+
800: '#1e293b',
|
|
280
|
+
900: '#0f172a',
|
|
281
|
+
950: '#020617',
|
|
282
|
+
},
|
|
283
|
+
accent: {
|
|
284
|
+
50: '#ecfeff',
|
|
285
|
+
100: '#cffafe',
|
|
286
|
+
200: '#a5f3fc',
|
|
287
|
+
300: '#67e8f9',
|
|
288
|
+
400: '#22d3ee',
|
|
289
|
+
500: '#06b6d4',
|
|
290
|
+
600: '#0891b2',
|
|
291
|
+
700: '#0e7490',
|
|
292
|
+
800: '#155e75',
|
|
293
|
+
900: '#164e63',
|
|
294
|
+
950: '#083344',
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Forest Green - Deep nature, sustainability
|
|
300
|
+
*/
|
|
301
|
+
export const forestGreen: ColorPalette = {
|
|
302
|
+
primary: {
|
|
303
|
+
50: '#f0fdf4',
|
|
304
|
+
100: '#dcfce7',
|
|
305
|
+
200: '#bbf7d0',
|
|
306
|
+
300: '#86efac',
|
|
307
|
+
400: '#4ade80',
|
|
308
|
+
500: '#22c55e',
|
|
309
|
+
600: '#16a34a',
|
|
310
|
+
700: '#15803d',
|
|
311
|
+
800: '#166534',
|
|
312
|
+
900: '#14532d',
|
|
313
|
+
950: '#052e16',
|
|
314
|
+
},
|
|
315
|
+
accent: {
|
|
316
|
+
50: '#fffbeb',
|
|
317
|
+
100: '#fef3c7',
|
|
318
|
+
200: '#fde68a',
|
|
319
|
+
300: '#fcd34d',
|
|
320
|
+
400: '#fbbf24',
|
|
321
|
+
500: '#f59e0b',
|
|
322
|
+
600: '#d97706',
|
|
323
|
+
700: '#b45309',
|
|
324
|
+
800: '#92400e',
|
|
325
|
+
900: '#78350f',
|
|
326
|
+
950: '#451a03',
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Map of theme presets to color palettes.
|
|
332
|
+
*/
|
|
333
|
+
export const themePalettes: Record<ThemePreset, ColorPalette> = {
|
|
334
|
+
'warm-brown': warmBrown,
|
|
335
|
+
'cool-blue': coolBlue,
|
|
336
|
+
'earth-green': earthGreen,
|
|
337
|
+
'warm-amber': warmAmber,
|
|
338
|
+
'elegant-gold': elegantGold,
|
|
339
|
+
'fresh-teal': freshTeal,
|
|
340
|
+
'bold-red': boldRed,
|
|
341
|
+
'soft-pink': softPink,
|
|
342
|
+
'slate-gray': slateGray,
|
|
343
|
+
'forest-green': forestGreen,
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Get a color palette by theme preset name.
|
|
348
|
+
*/
|
|
349
|
+
export function getColorPalette(preset: ThemePreset): ColorPalette {
|
|
350
|
+
return themePalettes[preset] || themePalettes['cool-blue'];
|
|
351
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SheetSite Theme Module
|
|
3
|
+
*
|
|
4
|
+
* Provides theming utilities, color palettes, and Tailwind CSS configuration helpers.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ThemeConfig, ThemePreset, ColorPalette, FontConfig } from '../config/types';
|
|
8
|
+
export { getColorPalette, themePalettes } from './colors';
|
|
9
|
+
export * from './colors';
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// FONT CONFIGURATIONS
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Recommended font pairings.
|
|
17
|
+
*/
|
|
18
|
+
export const fontPairings: Record<string, FontConfig> = {
|
|
19
|
+
classic: {
|
|
20
|
+
heading: 'Playfair Display',
|
|
21
|
+
body: 'Inter',
|
|
22
|
+
},
|
|
23
|
+
modern: {
|
|
24
|
+
heading: 'Inter',
|
|
25
|
+
body: 'Inter',
|
|
26
|
+
},
|
|
27
|
+
elegant: {
|
|
28
|
+
heading: 'Cormorant Garamond',
|
|
29
|
+
body: 'Lato',
|
|
30
|
+
},
|
|
31
|
+
friendly: {
|
|
32
|
+
heading: 'Nunito',
|
|
33
|
+
body: 'Open Sans',
|
|
34
|
+
},
|
|
35
|
+
professional: {
|
|
36
|
+
heading: 'Merriweather',
|
|
37
|
+
body: 'Source Sans Pro',
|
|
38
|
+
},
|
|
39
|
+
bold: {
|
|
40
|
+
heading: 'Montserrat',
|
|
41
|
+
body: 'Roboto',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// =============================================================================
|
|
46
|
+
// TAILWIND CONFIGURATION GENERATOR
|
|
47
|
+
// =============================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generate Tailwind CSS theme extension from a theme configuration.
|
|
51
|
+
*/
|
|
52
|
+
export function generateTailwindTheme(config: ThemeConfig): object {
|
|
53
|
+
const { getColorPalette } = require('./colors');
|
|
54
|
+
const palette = config.preset ? getColorPalette(config.preset) : null;
|
|
55
|
+
|
|
56
|
+
// Merge custom colors with preset
|
|
57
|
+
const colors = {
|
|
58
|
+
primary: {
|
|
59
|
+
...(palette?.primary || {}),
|
|
60
|
+
...(config.colors?.primary || {}),
|
|
61
|
+
},
|
|
62
|
+
accent: {
|
|
63
|
+
...(palette?.accent || {}),
|
|
64
|
+
...(config.colors?.accent || {}),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
colors,
|
|
70
|
+
fontFamily: config.fonts
|
|
71
|
+
? {
|
|
72
|
+
heading: [config.fonts.heading, 'serif'],
|
|
73
|
+
body: [config.fonts.body, 'sans-serif'],
|
|
74
|
+
...(config.fonts.accent ? { accent: [config.fonts.accent, 'sans-serif'] } : {}),
|
|
75
|
+
}
|
|
76
|
+
: undefined,
|
|
77
|
+
borderRadius: config.borderRadius
|
|
78
|
+
? {
|
|
79
|
+
DEFAULT: getBorderRadiusValue(config.borderRadius),
|
|
80
|
+
}
|
|
81
|
+
: undefined,
|
|
82
|
+
boxShadow: config.shadows
|
|
83
|
+
? {
|
|
84
|
+
DEFAULT: getShadowValue(config.shadows),
|
|
85
|
+
}
|
|
86
|
+
: undefined,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Generate a complete Tailwind config object.
|
|
92
|
+
*/
|
|
93
|
+
export function generateTailwindConfig(config: ThemeConfig): object {
|
|
94
|
+
const themeExtend = generateTailwindTheme(config);
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
theme: {
|
|
98
|
+
extend: themeExtend,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Generate CSS custom properties from a theme configuration.
|
|
105
|
+
* Useful for CSS-in-JS or custom styling.
|
|
106
|
+
*/
|
|
107
|
+
export function generateCSSVariables(config: ThemeConfig): Record<string, string> {
|
|
108
|
+
const { getColorPalette } = require('./colors');
|
|
109
|
+
const palette = config.preset ? getColorPalette(config.preset) : null;
|
|
110
|
+
const variables: Record<string, string> = {};
|
|
111
|
+
|
|
112
|
+
// Add color variables
|
|
113
|
+
if (palette) {
|
|
114
|
+
for (const [shade, color] of Object.entries(palette.primary)) {
|
|
115
|
+
variables[`--color-primary-${shade}`] = color as string;
|
|
116
|
+
}
|
|
117
|
+
for (const [shade, color] of Object.entries(palette.accent)) {
|
|
118
|
+
variables[`--color-accent-${shade}`] = color as string;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Add custom colors
|
|
123
|
+
if (config.colors?.primary) {
|
|
124
|
+
for (const [shade, color] of Object.entries(config.colors.primary)) {
|
|
125
|
+
variables[`--color-primary-${shade}`] = color;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (config.colors?.accent) {
|
|
129
|
+
for (const [shade, color] of Object.entries(config.colors.accent)) {
|
|
130
|
+
variables[`--color-accent-${shade}`] = color;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Add font variables
|
|
135
|
+
if (config.fonts) {
|
|
136
|
+
if (config.fonts.heading) {
|
|
137
|
+
variables['--font-heading'] = config.fonts.heading;
|
|
138
|
+
}
|
|
139
|
+
if (config.fonts.body) {
|
|
140
|
+
variables['--font-body'] = config.fonts.body;
|
|
141
|
+
}
|
|
142
|
+
if (config.fonts.accent) {
|
|
143
|
+
variables['--font-accent'] = config.fonts.accent;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return variables;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Generate the CSS string for custom properties.
|
|
152
|
+
*/
|
|
153
|
+
export function generateCSSVariablesString(config: ThemeConfig): string {
|
|
154
|
+
const variables = generateCSSVariables(config);
|
|
155
|
+
const lines = Object.entries(variables).map(([key, value]) => ` ${key}: ${value};`);
|
|
156
|
+
return `:root {\n${lines.join('\n')}\n}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// =============================================================================
|
|
160
|
+
// HELPERS
|
|
161
|
+
// =============================================================================
|
|
162
|
+
|
|
163
|
+
function getBorderRadiusValue(size: ThemeConfig['borderRadius']): string {
|
|
164
|
+
const values: Record<NonNullable<ThemeConfig['borderRadius']>, string> = {
|
|
165
|
+
none: '0',
|
|
166
|
+
sm: '0.125rem',
|
|
167
|
+
md: '0.375rem',
|
|
168
|
+
lg: '0.5rem',
|
|
169
|
+
xl: '0.75rem',
|
|
170
|
+
full: '9999px',
|
|
171
|
+
};
|
|
172
|
+
return values[size || 'md'];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function getShadowValue(size: ThemeConfig['shadows']): string {
|
|
176
|
+
const values: Record<NonNullable<ThemeConfig['shadows']>, string> = {
|
|
177
|
+
none: 'none',
|
|
178
|
+
sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
|
179
|
+
md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
|
|
180
|
+
lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
|
|
181
|
+
};
|
|
182
|
+
return values[size || 'md'];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// =============================================================================
|
|
186
|
+
// THEME UTILITIES
|
|
187
|
+
// =============================================================================
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get the primary color for a given shade.
|
|
191
|
+
*/
|
|
192
|
+
export function getPrimaryColor(config: ThemeConfig, shade: keyof ColorPalette['primary'] = 600): string {
|
|
193
|
+
const { getColorPalette } = require('./colors');
|
|
194
|
+
|
|
195
|
+
// Check custom colors first
|
|
196
|
+
if (config.colors?.primary?.[shade]) {
|
|
197
|
+
return config.colors.primary[shade];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Fall back to preset
|
|
201
|
+
if (config.preset) {
|
|
202
|
+
const palette = getColorPalette(config.preset);
|
|
203
|
+
return palette.primary[shade];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Default
|
|
207
|
+
return '#0c8de9'; // cool-blue 500
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get the accent color for a given shade.
|
|
212
|
+
*/
|
|
213
|
+
export function getAccentColor(config: ThemeConfig, shade: keyof ColorPalette['accent'] = 600): string {
|
|
214
|
+
const { getColorPalette } = require('./colors');
|
|
215
|
+
|
|
216
|
+
// Check custom colors first
|
|
217
|
+
if (config.colors?.accent?.[shade]) {
|
|
218
|
+
return config.colors.accent[shade];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Fall back to preset
|
|
222
|
+
if (config.preset) {
|
|
223
|
+
const palette = getColorPalette(config.preset);
|
|
224
|
+
return palette.accent[shade];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Default
|
|
228
|
+
return '#16a34a'; // green 600
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Recommend a font pairing for a business type.
|
|
233
|
+
*/
|
|
234
|
+
export function recommendFontPairing(businessType: string): FontConfig {
|
|
235
|
+
const recommendations: Record<string, string> = {
|
|
236
|
+
tailor: 'classic',
|
|
237
|
+
restaurant: 'elegant',
|
|
238
|
+
'home-kitchen': 'friendly',
|
|
239
|
+
salon: 'modern',
|
|
240
|
+
accountant: 'professional',
|
|
241
|
+
lawyer: 'professional',
|
|
242
|
+
'auto-repair': 'bold',
|
|
243
|
+
'shoe-repair': 'classic',
|
|
244
|
+
generic: 'modern',
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const pairingName = recommendations[businessType] || 'modern';
|
|
248
|
+
return fontPairings[pairingName];
|
|
249
|
+
}
|