apexcss-cli 0.1.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.
@@ -0,0 +1,963 @@
1
+ /**
2
+ * Configuration loader utility
3
+ * Loads and validates user configuration files
4
+ */
5
+
6
+ import { readFileSync, existsSync } from 'node:fs';
7
+ import { resolve } from 'node:path';
8
+ import { pathToFileURL } from 'node:url';
9
+ import { createRequire } from 'node:module';
10
+ import { logger } from './logger.js';
11
+
12
+ /**
13
+ * Default configuration
14
+ */
15
+ export const defaultConfig = {
16
+ features: {
17
+ // Core Layout
18
+ display: true,
19
+ flexbox: true,
20
+ grid: true,
21
+ positioning: true,
22
+ visibility: true,
23
+
24
+ // Core Spacing
25
+ spacing: true,
26
+ sizing: true,
27
+
28
+ // Core Typography
29
+ typography: true,
30
+
31
+ // Core Visual
32
+ colors: true,
33
+ backgrounds: true,
34
+ borders: true,
35
+ shadows: true,
36
+ opacity: true,
37
+ overflow: true,
38
+ objectFit: true,
39
+
40
+ // Core Interaction
41
+ cursor: true,
42
+ transitions: true,
43
+
44
+ // Extended features default to true
45
+ flexExtended: true,
46
+ gridExtended: true,
47
+ typographyExtended: true,
48
+ animations: true,
49
+ transforms: true,
50
+ transforms3d: true,
51
+ filters: true,
52
+ darkMode: true,
53
+ rtl: true,
54
+ accessibility: true
55
+ },
56
+
57
+ breakpoints: {
58
+ sm: '320px',
59
+ md: '768px',
60
+ lg: '1024px',
61
+ xl: '1280px',
62
+ xxl: '2560px',
63
+ xxxl: '3840px',
64
+ ultra: '7680px'
65
+ },
66
+
67
+ spacing: {
68
+ 0: '0',
69
+ px: '1px',
70
+ 0.5: '0.125rem',
71
+ 1: '0.25rem',
72
+ 2: '0.5rem',
73
+ 3: '0.75rem',
74
+ 4: '1rem',
75
+ 5: '1.25rem',
76
+ 6: '1.5rem',
77
+ 8: '2rem',
78
+ 10: '2.5rem',
79
+ 12: '3rem',
80
+ 16: '4rem',
81
+ 20: '5rem',
82
+ 24: '6rem',
83
+ 32: '8rem',
84
+ 40: '10rem',
85
+ 48: '12rem',
86
+ 64: '16rem',
87
+ 80: '20rem',
88
+ 96: '24rem'
89
+ },
90
+
91
+ colors: {
92
+ primary: {
93
+ hue: 250,
94
+ chroma: 0.18,
95
+ lightnessScale: {
96
+ 50: 95, 100: 90, 200: 85, 300: 78, 400: 70,
97
+ 500: 62, 600: 55, 700: 45, 800: 35, 900: 25, 950: 20
98
+ }
99
+ },
100
+ gray: {
101
+ hue: 250,
102
+ chroma: 0.02,
103
+ lightnessScale: {
104
+ 50: 96, 100: 90, 200: 85, 300: 78, 400: 70,
105
+ 500: 65, 600: 55, 700: 45, 800: 35, 900: 25, 950: 18
106
+ }
107
+ },
108
+ success: {
109
+ hue: 145,
110
+ chroma: 0.2,
111
+ lightnessScale: {
112
+ 50: 95, 100: 90, 200: 85, 300: 78, 400: 70,
113
+ 500: 62, 600: 55, 700: 45, 800: 35, 900: 25, 950: 20
114
+ }
115
+ },
116
+ warning: {
117
+ hue: 80,
118
+ chroma: 0.16,
119
+ lightnessScale: {
120
+ 50: 95, 100: 90, 200: 85, 300: 78, 400: 70,
121
+ 500: 72, 600: 60, 700: 50, 800: 40, 900: 30, 950: 25
122
+ }
123
+ },
124
+ danger: {
125
+ hue: 25,
126
+ chroma: 0.22,
127
+ lightnessScale: {
128
+ 50: 95, 100: 90, 200: 85, 300: 78, 400: 70,
129
+ 500: 62, 600: 55, 700: 45, 800: 35, 900: 25, 950: 20
130
+ }
131
+ },
132
+ info: {
133
+ hue: 220,
134
+ chroma: 0.14,
135
+ lightnessScale: {
136
+ 50: 95, 100: 90, 200: 85, 300: 78, 400: 70,
137
+ 500: 62, 600: 55, 700: 45, 800: 35, 900: 25, 950: 20
138
+ }
139
+ }
140
+ },
141
+
142
+ typography: {
143
+ fontFamily: {
144
+ sans: ['ui-sans-serif', 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'],
145
+ serif: ['ui-serif', 'Georgia', 'Cambria', 'Times New Roman', 'Times', 'serif'],
146
+ mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', 'monospace']
147
+ },
148
+ fontSize: {
149
+ xs: ['0.75rem', { lineHeight: '1rem' }],
150
+ sm: ['0.875rem', { lineHeight: '1.25rem' }],
151
+ base: ['1rem', { lineHeight: '1.5rem' }],
152
+ lg: ['1.125rem', { lineHeight: '1.75rem' }],
153
+ xl: ['1.25rem', { lineHeight: '1.75rem' }],
154
+ '2xl': ['1.5rem', { lineHeight: '2rem' }],
155
+ '3xl': ['1.875rem', { lineHeight: '2.25rem' }],
156
+ '4xl': ['2.25rem', { lineHeight: '2.5rem' }],
157
+ '5xl': ['3rem', { lineHeight: '1' }],
158
+ '6xl': ['3.75rem', { lineHeight: '1' }],
159
+ '7xl': ['4.5rem', { lineHeight: '1' }],
160
+ '8xl': ['6rem', { lineHeight: '1' }],
161
+ '9xl': ['8rem', { lineHeight: '1' }]
162
+ },
163
+ fontWeight: {
164
+ thin: '100',
165
+ extralight: '200',
166
+ light: '300',
167
+ normal: '400',
168
+ medium: '500',
169
+ semibold: '600',
170
+ bold: '700',
171
+ extrabold: '800',
172
+ black: '900'
173
+ },
174
+ letterSpacing: {
175
+ tighter: '-0.05em',
176
+ tight: '-0.025em',
177
+ normal: '0em',
178
+ wide: '0.025em',
179
+ wider: '0.05em',
180
+ widest: '0.1em'
181
+ },
182
+ lineHeight: {
183
+ none: '1',
184
+ tight: '1.25',
185
+ snug: '1.375',
186
+ normal: '1.5',
187
+ relaxed: '1.625',
188
+ loose: '2'
189
+ }
190
+ },
191
+
192
+ borderRadius: {
193
+ none: '0',
194
+ sm: '0.125rem',
195
+ default: '0.25rem',
196
+ md: '0.375rem',
197
+ lg: '0.5rem',
198
+ xl: '0.75rem',
199
+ '2xl': '1rem',
200
+ '3xl': '1.5rem',
201
+ full: '9999px'
202
+ },
203
+
204
+ shadows: {
205
+ sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
206
+ default: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
207
+ md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
208
+ lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
209
+ xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
210
+ '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
211
+ inner: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
212
+ none: 'none'
213
+ },
214
+
215
+ transition: {
216
+ duration: {
217
+ 75: '75ms',
218
+ 100: '100ms',
219
+ 150: '150ms',
220
+ 200: '200ms',
221
+ 300: '300ms',
222
+ 500: '500ms',
223
+ 700: '700ms',
224
+ 1000: '1000ms'
225
+ },
226
+ timing: {
227
+ linear: 'linear',
228
+ default: 'cubic-bezier(0.4, 0, 0.2, 1)',
229
+ in: 'cubic-bezier(0.4, 0, 1, 1)',
230
+ out: 'cubic-bezier(0, 0, 0.2, 1)',
231
+ 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)'
232
+ }
233
+ },
234
+
235
+ zIndex: {
236
+ auto: 'auto',
237
+ 0: '0',
238
+ 10: '10',
239
+ 20: '20',
240
+ 30: '30',
241
+ 40: '40',
242
+ 50: '50'
243
+ },
244
+
245
+ opacity: {
246
+ 0: '0',
247
+ 5: '0.05',
248
+ 10: '0.1',
249
+ 20: '0.2',
250
+ 25: '0.25',
251
+ 30: '0.3',
252
+ 40: '0.4',
253
+ 50: '0.5',
254
+ 60: '0.6',
255
+ 70: '0.7',
256
+ 75: '0.75',
257
+ 80: '0.8',
258
+ 90: '0.9',
259
+ 95: '0.95',
260
+ 100: '1'
261
+ }
262
+ };
263
+
264
+ /**
265
+ * Load configuration from file
266
+ * @param {string} configPath - Path to config file
267
+ * @returns {object} Merged configuration
268
+ */
269
+ export function loadConfig(configPath) {
270
+ const fullPath = resolve(process.cwd(), configPath);
271
+
272
+ if (!existsSync(fullPath)) {
273
+ logger.warn(`Config file not found at ${configPath}, using defaults`);
274
+ return { ...defaultConfig };
275
+ }
276
+
277
+ try {
278
+ // Support both .js and .json config files
279
+ let userConfig = {};
280
+
281
+ if (configPath.endsWith('.json')) {
282
+ // JSON config
283
+ const content = readFileSync(fullPath, 'utf-8');
284
+ userConfig = JSON.parse(content);
285
+ } else {
286
+ // JS config - use require for synchronous loading
287
+ const require = createRequire(pathToFileURL(fullPath));
288
+ delete require.cache[require.resolve(fullPath)];
289
+ const loadedModule = require(fullPath);
290
+ userConfig = loadedModule.default || loadedModule;
291
+ }
292
+
293
+ // Validate and merge
294
+ const merged = mergeConfig(defaultConfig, userConfig);
295
+
296
+ // Validate the merged config
297
+ const validation = validateConfig(merged);
298
+ if (!validation.valid) {
299
+ const errorMessages = validation.errors.map(e => ` - ${e}`).join('\n');
300
+ throw new Error(`Configuration validation failed:\n${errorMessages}`);
301
+ }
302
+
303
+ return merged;
304
+ } catch (error) {
305
+ if (error.code === 'ENOENT') {
306
+ logger.warn(`Config file not found at ${configPath}, using defaults`);
307
+ return { ...defaultConfig };
308
+ }
309
+ throw new Error(`Failed to load config: ${error.message}`);
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Deep merge configuration objects
315
+ * @param {object} target - Base configuration
316
+ * @param {object} source - User configuration
317
+ * @returns {object} - Merged configuration
318
+ */
319
+ export function mergeConfig(target, source) {
320
+ const output = { ...target };
321
+
322
+ for (const key in source) {
323
+ if (Object.hasOwn(source, key)) {
324
+ if (isObject(source[key]) && isObject(target[key])) {
325
+ output[key] = mergeConfig(target[key], source[key]);
326
+ } else {
327
+ output[key] = source[key];
328
+ }
329
+ }
330
+ }
331
+
332
+ return output;
333
+ }
334
+
335
+ /**
336
+ * Check if value is a plain object
337
+ * @param {*} item - Value to check
338
+ * @returns {boolean}
339
+ */
340
+ /**
341
+ * Check if value is a plain object
342
+ * @param {*} item - Value to check
343
+ * @returns {boolean}
344
+ */
345
+ export function isObject(item) {
346
+ return Boolean(item && typeof item === 'object' && !Array.isArray(item));
347
+ }
348
+
349
+ /**
350
+ * Validates that all feature values are booleans
351
+ * @param {object} features - Features configuration
352
+ * @param {Array} errors - Error collection
353
+ */
354
+ export function validateFeatures(features, errors) {
355
+ for (const [key, value] of Object.entries(features)) {
356
+ if (typeof value !== 'boolean') {
357
+ errors.push(`features.${key} must be a boolean`);
358
+ }
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Validates that all breakpoints are valid CSS lengths
364
+ * @param {object} breakpoints - Breakpoints configuration
365
+ * @param {Array} errors - Error collection
366
+ */
367
+ /**
368
+ * Validates that all breakpoints are valid CSS lengths
369
+ * @param {object} breakpoints - Breakpoints configuration
370
+ * @param {Array} errors - Error collection
371
+ */
372
+ export function validateBreakpoints(breakpoints, errors) {
373
+ const cssLengthPattern = /^\d+(px|rem|em|%)?$/;
374
+ for (const [key, value] of Object.entries(breakpoints)) {
375
+ if (typeof value !== 'string' || !cssLengthPattern.test(value)) {
376
+ errors.push(`breakpoints.${key} must be a valid CSS length`);
377
+ }
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Validates that all color configurations are valid
383
+ * @param {object} colors - Colors configuration
384
+ * @param {Array} errors - Error collection
385
+ */
386
+ export function validateColors(colors, errors) {
387
+ for (const [colorName, colorConfig] of Object.entries(colors)) {
388
+ validateColorHue(colorConfig, colorName, errors);
389
+ validateColorChroma(colorConfig, colorName, errors);
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Validates a color's hue value
395
+ * @param {object} colorConfig - Color configuration
396
+ * @param {string} colorName - Name of the color
397
+ * @param {Array} errors - Error collection
398
+ */
399
+ export function validateColorHue(colorConfig, colorName, errors) {
400
+ if (colorConfig.hue === undefined) {
401
+ return;
402
+ }
403
+ if (typeof colorConfig.hue !== 'number' || colorConfig.hue < 0 || colorConfig.hue > 360) {
404
+ errors.push(`colors.${colorName}.hue must be between 0 and 360`);
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Validates a color's chroma value
410
+ * @param {object} colorConfig - Color configuration
411
+ * @param {string} colorName - Name of the color
412
+ * @param {Array} errors - Error collection
413
+ */
414
+ export function validateColorChroma(colorConfig, colorName, errors) {
415
+ if (colorConfig.chroma === undefined) {
416
+ return;
417
+ }
418
+ if (typeof colorConfig.chroma !== 'number' || colorConfig.chroma < 0 || colorConfig.chroma > 0.4) {
419
+ errors.push(`colors.${colorName}.chroma must be between 0 and 0.4`);
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Validate configuration
425
+ * @param {object} config - Configuration to validate
426
+ * @returns {object} - Validation result
427
+ */
428
+ export function validateConfig(config) {
429
+ const errors = [];
430
+ const warnings = [];
431
+
432
+ if (config.features) {
433
+ validateFeatures(config.features, errors);
434
+ }
435
+
436
+ if (config.breakpoints) {
437
+ validateBreakpoints(config.breakpoints, errors);
438
+ }
439
+
440
+ if (config.colors) {
441
+ validateColors(config.colors, errors);
442
+ }
443
+
444
+ return {
445
+ valid: errors.length === 0,
446
+ errors,
447
+ warnings
448
+ };
449
+ }
450
+
451
+ /**
452
+ * Generate a sample configuration file content
453
+ * @returns {string} - Configuration file content
454
+ */
455
+ export function generateSampleConfig() {
456
+ return `/**
457
+ * ApexCSS Configuration File
458
+ *
459
+ * This is your configuration file for customizing ApexCSS.
460
+ * All features are enabled by default. Set any feature to false to disable it
461
+ * and reduce your bundle size.
462
+ *
463
+ * Usage:
464
+ * 1. Modify the values below to customize the framework
465
+ * 2. Run: npx apexcss build
466
+ * 3. The CSS will be regenerated with your customizations
467
+ *
468
+ * For full documentation, visit: https://docs.apex-css.com
469
+ */
470
+
471
+ export default {
472
+ // ============================================================================
473
+ // Feature Toggles - Enable/disable utility categories
474
+ // Set to false to exclude specific utilities from the build
475
+ // ============================================================================
476
+ features: {
477
+ // Core Layout
478
+ display: true,
479
+ flexbox: true,
480
+ grid: true,
481
+ positioning: true,
482
+ visibility: true,
483
+
484
+ // Core Spacing
485
+ spacing: true,
486
+ sizing: true,
487
+
488
+ // Core Typography
489
+ typography: true,
490
+
491
+ // Core Visual
492
+ colors: true,
493
+ backgrounds: true,
494
+ borders: true,
495
+ shadows: true,
496
+ opacity: true,
497
+ overflow: true,
498
+ objectFit: true,
499
+
500
+ // Core Interaction
501
+ cursor: true,
502
+ transitions: true,
503
+
504
+ // Extended Layout
505
+ flexExtended: true,
506
+ gridExtended: true,
507
+ float: true,
508
+ containerQueries: true,
509
+ isolation: true,
510
+ placeItems: true,
511
+ justifyItems: true,
512
+ spaceBetween: true,
513
+ columns: true,
514
+ columnsExtended: true,
515
+
516
+ // Extended Typography
517
+ typographyExtended: true,
518
+ fontExtended: true,
519
+ letterSpacing: true,
520
+ lineHeight: true,
521
+ textAlignLast: true,
522
+ textDecorationExtended: true,
523
+ textJustify: true,
524
+ textIndent: true,
525
+ textShadow: true,
526
+ textEmphasis: true,
527
+ textOrientation: true,
528
+ textUnderline: true,
529
+ hangingPunctuation: true,
530
+ hyphenate: true,
531
+ initialLetter: true,
532
+ tabSize: true,
533
+ wordBreak: true,
534
+ wordWrap: true,
535
+ writingMode: true,
536
+ unicodeBidi: true,
537
+
538
+ // Extended Visual
539
+ backgroundExtended: true,
540
+ colorModifiers: false,
541
+ blendModes: true,
542
+ masks: true,
543
+ borderRadiusLogical: true,
544
+ ring: true,
545
+ outline: true,
546
+ appearance: true,
547
+ accentColor: true,
548
+ colorScheme: true,
549
+
550
+ // Extended Interaction
551
+ interaction: true,
552
+ userSelect: true,
553
+ willChange: true,
554
+ all: true,
555
+ caret: true,
556
+ scroll: true,
557
+ overscrollBehavior: true,
558
+ overscrollBehaviorExtended: true,
559
+ overflowExtended: true,
560
+
561
+ // Effects
562
+ animations: true,
563
+ transforms: true,
564
+ transforms3d: true,
565
+ filters: true,
566
+ aspectRatio: true,
567
+ imageRendering: true,
568
+ transitionBehavior: true,
569
+
570
+ // Content
571
+ list: true,
572
+ listStyleExtended: true,
573
+ table: true,
574
+ counter: true,
575
+ caption: true,
576
+ quotes: true,
577
+ orphans: true,
578
+ widows: true,
579
+ pageBreak: true,
580
+ break: true,
581
+ verticalAlign: true,
582
+
583
+ // Advanced
584
+ arbitrary: false,
585
+ logicalProperties: true,
586
+ sizingLogical: true,
587
+ offset: true,
588
+ shapeOutside: true,
589
+ markerExtended: true,
590
+ zoom: true,
591
+ fieldSizing: true,
592
+ svg: true,
593
+ box: true,
594
+ divide: true,
595
+
596
+ // State Variants
597
+ states: true,
598
+ hover: true,
599
+ focus: true,
600
+ active: true,
601
+ disabled: true,
602
+
603
+ // Theme Support
604
+ darkMode: true,
605
+ rtl: true,
606
+ accessibility: true,
607
+ zIndex: true
608
+ },
609
+
610
+ // ============================================================================
611
+ // Breakpoints - Customize responsive breakpoints
612
+ // ============================================================================
613
+ breakpoints: {
614
+ sm: '320px',
615
+ md: '768px',
616
+ lg: '1024px',
617
+ xl: '1280px',
618
+ xxl: '2560px', // 2K / QHD
619
+ xxxl: '3840px', // 4K / UHD
620
+ ultra: '7680px' // 8K
621
+ },
622
+
623
+ // ============================================================================
624
+ // Spacing Scale - Customize margin/padding values
625
+ // ============================================================================
626
+ spacing: {
627
+ 0: '0',
628
+ px: '1px',
629
+ 0.5: '0.125rem',
630
+ 1: '0.25rem',
631
+ 1.5: '0.375rem',
632
+ 2: '0.5rem',
633
+ 2.5: '0.625rem',
634
+ 3: '0.75rem',
635
+ 3.5: '0.875rem',
636
+ 4: '1rem',
637
+ 5: '1.25rem',
638
+ 6: '1.5rem',
639
+ 7: '1.75rem',
640
+ 8: '2rem',
641
+ 9: '2.25rem',
642
+ 10: '2.5rem',
643
+ 11: '2.75rem',
644
+ 12: '3rem',
645
+ 14: '3.5rem',
646
+ 16: '4rem',
647
+ 20: '5rem',
648
+ 24: '6rem',
649
+ 28: '7rem',
650
+ 32: '8rem',
651
+ 36: '9rem',
652
+ 40: '10rem',
653
+ 44: '11rem',
654
+ 48: '12rem',
655
+ 52: '13rem',
656
+ 56: '14rem',
657
+ 60: '15rem',
658
+ 64: '16rem',
659
+ 72: '18rem',
660
+ 80: '20rem',
661
+ 96: '24rem'
662
+ },
663
+
664
+ // ============================================================================
665
+ // Colors - Customize your color palette (OKLCH format)
666
+ // ============================================================================
667
+ // Define colors with OKLCH format: { hue, chroma, lightnessScale }
668
+ // - hue: 0-360 (color wheel angle)
669
+ // - chroma: 0-0.4 (color intensity)
670
+ // - lightnessScale: { 50: 95, 100: 90, ... 950: 20 } (perceptual lightness values)
671
+ //
672
+ // Example: Change primary from blue (250) to purple (300):
673
+ // primary: { hue: 300, chroma: 0.18, lightnessScale: { ... } }
674
+ // ============================================================================
675
+ colors: {
676
+ // Primary Blue
677
+ primary: {
678
+ hue: 250,
679
+ chroma: 0.18,
680
+ lightnessScale: {
681
+ 50: 95,
682
+ 100: 90,
683
+ 200: 85,
684
+ 300: 78,
685
+ 400: 70,
686
+ 500: 62,
687
+ 600: 55,
688
+ 700: 45,
689
+ 800: 35,
690
+ 900: 25,
691
+ 950: 20
692
+ }
693
+ },
694
+ // Gray (neutral, low chroma)
695
+ gray: {
696
+ hue: 250,
697
+ chroma: 0.02,
698
+ lightnessScale: {
699
+ 50: 96,
700
+ 100: 90,
701
+ 200: 85,
702
+ 300: 78,
703
+ 400: 70,
704
+ 500: 65,
705
+ 600: 55,
706
+ 700: 45,
707
+ 800: 35,
708
+ 900: 25,
709
+ 950: 18
710
+ }
711
+ },
712
+ // Success Green
713
+ success: {
714
+ hue: 145,
715
+ chroma: 0.2,
716
+ lightnessScale: {
717
+ 50: 95,
718
+ 100: 90,
719
+ 200: 85,
720
+ 300: 78,
721
+ 400: 70,
722
+ 500: 62,
723
+ 600: 55,
724
+ 700: 45,
725
+ 800: 35,
726
+ 900: 25,
727
+ 950: 20
728
+ }
729
+ },
730
+ // Warning Amber
731
+ warning: {
732
+ hue: 80,
733
+ chroma: 0.16,
734
+ lightnessScale: {
735
+ 50: 95,
736
+ 100: 90,
737
+ 200: 85,
738
+ 300: 78,
739
+ 400: 70,
740
+ 500: 72,
741
+ 600: 60,
742
+ 700: 50,
743
+ 800: 40,
744
+ 900: 30,
745
+ 950: 25
746
+ }
747
+ },
748
+ // Danger Red
749
+ danger: {
750
+ hue: 25,
751
+ chroma: 0.22,
752
+ lightnessScale: {
753
+ 50: 95,
754
+ 100: 90,
755
+ 200: 85,
756
+ 300: 78,
757
+ 400: 70,
758
+ 500: 62,
759
+ 600: 55,
760
+ 700: 45,
761
+ 800: 35,
762
+ 900: 25,
763
+ 950: 20
764
+ }
765
+ },
766
+ // Info Sky
767
+ info: {
768
+ hue: 220,
769
+ chroma: 0.14,
770
+ lightnessScale: {
771
+ 50: 95,
772
+ 100: 90,
773
+ 200: 85,
774
+ 300: 78,
775
+ 400: 70,
776
+ 500: 62,
777
+ 600: 55,
778
+ 700: 45,
779
+ 800: 35,
780
+ 900: 25,
781
+ 950: 20
782
+ }
783
+ },
784
+ // Extended palette
785
+ extended: {
786
+ blue: { hue: 250, chroma: 0.18 },
787
+ green: { hue: 145, chroma: 0.2 },
788
+ red: { hue: 25, chroma: 0.22 },
789
+ yellow: { hue: 90, chroma: 0.18 },
790
+ purple: { hue: 300, chroma: 0.22 },
791
+ orange: { hue: 55, chroma: 0.18 },
792
+ teal: { hue: 180, chroma: 0.16 },
793
+ pink: { hue: 340, chroma: 0.18 }
794
+ }
795
+ },
796
+
797
+ // ============================================================================
798
+ // Typography - Font families, sizes, weights, spacing
799
+ // ============================================================================
800
+ typography: {
801
+ fontFamily: {
802
+ sans: [
803
+ 'ui-sans-serif',
804
+ 'system-ui',
805
+ '-apple-system',
806
+ 'BlinkMacSystemFont',
807
+ 'Segoe UI',
808
+ 'Roboto',
809
+ 'Helvetica Neue',
810
+ 'Arial',
811
+ 'sans-serif'
812
+ ],
813
+ serif: [
814
+ 'ui-serif',
815
+ 'Georgia',
816
+ 'Cambria',
817
+ 'Times New Roman',
818
+ 'Times',
819
+ 'serif'
820
+ ],
821
+ mono: [
822
+ 'ui-monospace',
823
+ 'SFMono-Regular',
824
+ 'Menlo',
825
+ 'Monaco',
826
+ 'Consolas',
827
+ 'Liberation Mono',
828
+ 'Courier New',
829
+ 'monospace'
830
+ ],
831
+ },
832
+ fontSize: {
833
+ xs: ['0.75rem', { lineHeight: '1rem' }],
834
+ sm: ['0.875rem', { lineHeight: '1.25rem' }],
835
+ base: ['1rem', { lineHeight: '1.5rem' }],
836
+ lg: ['1.125rem', { lineHeight: '1.75rem' }],
837
+ xl: ['1.25rem', { lineHeight: '1.75rem' }],
838
+ '2xl': ['1.5rem', { lineHeight: '2rem' }],
839
+ '3xl': ['1.875rem', { lineHeight: '2.25rem' }],
840
+ '4xl': ['2.25rem', { lineHeight: '2.5rem' }],
841
+ '5xl': ['3rem', { lineHeight: '1' }],
842
+ '6xl': ['3.75rem', { lineHeight: '1' }],
843
+ '7xl': ['4.5rem', { lineHeight: '1' }],
844
+ '8xl': ['6rem', { lineHeight: '1' }],
845
+ '9xl': ['8rem', { lineHeight: '1' }]
846
+ },
847
+ fontWeight: {
848
+ thin: '100',
849
+ extralight: '200',
850
+ light: '300',
851
+ normal: '400',
852
+ medium: '500',
853
+ semibold: '600',
854
+ bold: '700',
855
+ extrabold: '800',
856
+ black: '900'
857
+ },
858
+ letterSpacing: {
859
+ tighter: '-0.05em',
860
+ tight: '-0.025em',
861
+ normal: '0em',
862
+ wide: '0.025em',
863
+ wider: '0.05em',
864
+ widest: '0.1em'
865
+ },
866
+ lineHeight: {
867
+ none: '1',
868
+ tight: '1.25',
869
+ snug: '1.375',
870
+ normal: '1.5',
871
+ relaxed: '1.625',
872
+ loose: '2'
873
+ }
874
+ },
875
+
876
+ // ============================================================================
877
+ // Border Radius - Corner roundness values
878
+ // ============================================================================
879
+ borderRadius: {
880
+ none: '0',
881
+ sm: '0.125rem',
882
+ default: '0.25rem',
883
+ md: '0.375rem',
884
+ lg: '0.5rem',
885
+ xl: '0.75rem',
886
+ '2xl': '1rem',
887
+ '3xl': '1.5rem',
888
+ full: '9999px'
889
+ },
890
+
891
+ // ============================================================================
892
+ // Shadows - Box shadow values
893
+ // ============================================================================
894
+ shadows: {
895
+ sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
896
+ default: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
897
+ md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
898
+ lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
899
+ xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
900
+ '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
901
+ inner: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
902
+ none: 'none'
903
+ },
904
+
905
+ // ============================================================================
906
+ // Transitions - Animation timing
907
+ // ============================================================================
908
+ transition: {
909
+ duration: {
910
+ 75: '75ms',
911
+ 100: '100ms',
912
+ 150: '150ms',
913
+ 200: '200ms',
914
+ 300: '300ms',
915
+ 500: '500ms',
916
+ 700: '700ms',
917
+ 1000: '1000ms',
918
+ },
919
+ timing: {
920
+ linear: 'linear',
921
+ default: 'cubic-bezier(0.4, 0, 0.2, 1)',
922
+ in: 'cubic-bezier(0.4, 0, 1, 1)',
923
+ out: 'cubic-bezier(0, 0, 0.2, 1)',
924
+ 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)'
925
+ }
926
+ },
927
+
928
+ // ============================================================================
929
+ // Z-Index - Stacking order values
930
+ // ============================================================================
931
+ zIndex: {
932
+ auto: 'auto',
933
+ 0: '0',
934
+ 10: '10',
935
+ 20: '20',
936
+ 30: '30',
937
+ 40: '40',
938
+ 50: '50'
939
+ },
940
+
941
+ // ============================================================================
942
+ // Opacity - Transparency values
943
+ // ============================================================================
944
+ opacity: {
945
+ 0: '0',
946
+ 5: '0.05',
947
+ 10: '0.1',
948
+ 20: '0.2',
949
+ 25: '0.25',
950
+ 30: '0.3',
951
+ 40: '0.4',
952
+ 50: '0.5',
953
+ 60: '0.6',
954
+ 70: '0.7',
955
+ 75: '0.75',
956
+ 80: '0.8',
957
+ 90: '0.9',
958
+ 95: '0.95',
959
+ 100: '1'
960
+ },
961
+ };
962
+ `;
963
+ }