@deneb-ui/core 2.0.68 → 2.0.70

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/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from './engine/domPatcher';
7
7
  export * from './engine/tokenResolver';
8
8
  export * from './engine/deepMerge';
9
9
  export * from './validation/styleSchemaValidator';
10
+ export * from './theme';
package/dist/index.js CHANGED
@@ -23,3 +23,4 @@ __exportStar(require("./engine/domPatcher"), exports);
23
23
  __exportStar(require("./engine/tokenResolver"), exports);
24
24
  __exportStar(require("./engine/deepMerge"), exports);
25
25
  __exportStar(require("./validation/styleSchemaValidator"), exports);
26
+ __exportStar(require("./theme"), exports);
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Determines whether a color is considered "dark" based on perceived relative luminance.
3
+ * Uses standard ITU-R BT.601 formula (r*299 + g*587 + b*114) / 1000 < 130.
4
+ * Supports 3-digit and 6-digit hex values.
5
+ */
6
+ export declare function isDarkColor(color?: unknown): boolean;
7
+ /**
8
+ * Returns an auto-contrasting text color (default white for dark backgrounds, dark slate for light backgrounds).
9
+ */
10
+ export declare function getAutoContrastTextColor(backgroundColor?: string, lightText?: string, darkText?: string): string;
11
+ /**
12
+ * Normalizes a 3-digit or 6-digit hex color to canonical 6-digit lowercase hex.
13
+ * Returns fallback if invalid.
14
+ */
15
+ export declare function toHexColor(color: string | undefined, fallback: string): string;
16
+ /**
17
+ * Parses and returns a valid 6-char hex string, or null if invalid.
18
+ */
19
+ export declare function normalizeHexColor(color: string | undefined): string | null;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDarkColor = isDarkColor;
4
+ exports.getAutoContrastTextColor = getAutoContrastTextColor;
5
+ exports.toHexColor = toHexColor;
6
+ exports.normalizeHexColor = normalizeHexColor;
7
+ /**
8
+ * Determines whether a color is considered "dark" based on perceived relative luminance.
9
+ * Uses standard ITU-R BT.601 formula (r*299 + g*587 + b*114) / 1000 < 130.
10
+ * Supports 3-digit and 6-digit hex values.
11
+ */
12
+ function isDarkColor(color) {
13
+ if (typeof color !== 'string' || !color)
14
+ return false;
15
+ const hex = color.trim().toLowerCase();
16
+ if (!/^#[0-9a-f]{3,6}$/i.test(hex))
17
+ return false;
18
+ const fullHex = hex.length === 4
19
+ ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`
20
+ : hex;
21
+ const r = Number.parseInt(fullHex.slice(1, 3), 16);
22
+ const g = Number.parseInt(fullHex.slice(3, 5), 16);
23
+ const b = Number.parseInt(fullHex.slice(5, 7), 16);
24
+ return (r * 299 + g * 587 + b * 114) / 1000 < 130;
25
+ }
26
+ /**
27
+ * Returns an auto-contrasting text color (default white for dark backgrounds, dark slate for light backgrounds).
28
+ */
29
+ function getAutoContrastTextColor(backgroundColor, lightText = '#ffffff', darkText = '#0f172a') {
30
+ return isDarkColor(backgroundColor) ? lightText : darkText;
31
+ }
32
+ /**
33
+ * Normalizes a 3-digit or 6-digit hex color to canonical 6-digit lowercase hex.
34
+ * Returns fallback if invalid.
35
+ */
36
+ function toHexColor(color, fallback) {
37
+ if (!color)
38
+ return fallback;
39
+ const trimmed = color.trim();
40
+ if (/^#[0-9a-f]{6}$/i.test(trimmed))
41
+ return trimmed.toLowerCase();
42
+ if (/^#[0-9a-f]{3}$/i.test(trimmed)) {
43
+ return `#${trimmed[1]}${trimmed[1]}${trimmed[2]}${trimmed[2]}${trimmed[3]}${trimmed[3]}`.toLowerCase();
44
+ }
45
+ return fallback;
46
+ }
47
+ /**
48
+ * Parses and returns a valid 6-char hex string, or null if invalid.
49
+ */
50
+ function normalizeHexColor(color) {
51
+ if (!color)
52
+ return null;
53
+ const trimmed = color.trim();
54
+ if (/^#[0-9a-f]{6}$/i.test(trimmed))
55
+ return trimmed.toLowerCase();
56
+ if (/^#[0-9a-f]{3}$/i.test(trimmed)) {
57
+ return `#${trimmed[1]}${trimmed[1]}${trimmed[2]}${trimmed[2]}${trimmed[3]}${trimmed[3]}`.toLowerCase();
58
+ }
59
+ return null;
60
+ }
@@ -0,0 +1,6 @@
1
+ import { TemplateThemeShape } from './types';
2
+ /**
3
+ * Computes all canonical CSS variables for a theme, automatically resolving
4
+ * dark/light mode contrasts, button states, card surfaces, and input tokens.
5
+ */
6
+ export declare function generateThemeVariables(theme?: TemplateThemeShape | null): Record<string, string>;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateThemeVariables = generateThemeVariables;
4
+ const contrast_1 = require("./contrast");
5
+ /**
6
+ * Computes all canonical CSS variables for a theme, automatically resolving
7
+ * dark/light mode contrasts, button states, card surfaces, and input tokens.
8
+ */
9
+ function generateThemeVariables(theme) {
10
+ const customVars = {};
11
+ if (theme) {
12
+ for (const [key, val] of Object.entries(theme)) {
13
+ if (typeof val === 'string' || typeof val === 'number') {
14
+ const cssVarName = `--${key.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()}`;
15
+ customVars[cssVarName] = String(val);
16
+ }
17
+ }
18
+ }
19
+ const isDark = (0, contrast_1.isDarkColor)(theme?.backgroundColor);
20
+ const bgColor = theme?.backgroundColor || (isDark ? '#0f172a' : '#ffffff');
21
+ const textColor = theme?.textColor || (isDark ? '#f8fafc' : '#0f172a');
22
+ const mutedColor = theme?.mutedTextColor ||
23
+ (isDark ? 'rgba(248, 250, 252, 0.7)' : '#64748b');
24
+ const borderColor = theme?.borderColor ||
25
+ (isDark ? 'rgba(255, 255, 255, 0.1)' : '#e2e8f0');
26
+ const cardBg = theme?.cardBackgroundColor ||
27
+ theme?.surfaceColor ||
28
+ (isDark ? '#111a2e' : '#ffffff');
29
+ const cardBorder = isDark ? 'rgba(255, 255, 255, 0.09)' : borderColor;
30
+ const primaryColor = theme?.primaryColor || '#2563eb';
31
+ const secondaryColor = theme?.secondaryColor || (isDark ? '#1e293b' : '#0f172a');
32
+ const accentColor = theme?.accentColor || '#14b8a6';
33
+ const buttonBg = theme?.buttonBackgroundColor || primaryColor;
34
+ const autoButtonText = (0, contrast_1.getAutoContrastTextColor)(buttonBg);
35
+ const buttonText = theme?.buttonTextColor || autoButtonText;
36
+ const buttonSecondaryBg = isDark
37
+ ? 'rgba(255, 255, 255, 0.08)'
38
+ : secondaryColor && !(0, contrast_1.isDarkColor)(secondaryColor)
39
+ ? secondaryColor
40
+ : '#f1f5f9';
41
+ const buttonSecondaryText = isDark ? '#f8fafc' : '#0f172a';
42
+ return {
43
+ '--brand-color': primaryColor,
44
+ '--brand-primary': primaryColor,
45
+ '--primary-color': primaryColor,
46
+ '--color-primary': primaryColor,
47
+ '--brand-secondary': secondaryColor,
48
+ '--secondary-color': secondaryColor,
49
+ '--brand-accent': accentColor,
50
+ '--accent-color': accentColor,
51
+ '--page-background': bgColor,
52
+ '--page-bg': bgColor,
53
+ '--background': bgColor,
54
+ '--page-text': textColor,
55
+ '--heading-color': theme?.headingColor || (isDark ? '#ffffff' : secondaryColor),
56
+ '--color-heading': theme?.headingColor || (isDark ? '#ffffff' : secondaryColor),
57
+ '--muted-text': mutedColor,
58
+ '--text-muted': mutedColor,
59
+ '--color-text': textColor,
60
+ '--color-text-muted': mutedColor,
61
+ '--link-color': theme?.linkColor || primaryColor,
62
+ '--border-primary': borderColor,
63
+ '--border': borderColor,
64
+ '--color-border': borderColor,
65
+ '--color-surface': isDark ? 'rgba(255,255,255,0.05)' : '#ffffff',
66
+ '--card-bg': cardBg,
67
+ '--card-border': cardBorder,
68
+ '--product-card-bg': cardBg,
69
+ '--product-card-border': cardBorder,
70
+ '--tag-bg': isDark
71
+ ? 'rgba(255, 255, 255, 0.08)'
72
+ : 'rgba(241, 245, 249, 0.9)',
73
+ '--tag-color': mutedColor,
74
+ '--card-shadow': isDark
75
+ ? '0 10px 25px -5px rgba(0, 0, 0, 0.4)'
76
+ : '0 10px 25px -5px rgba(0, 0, 0, 0.05)',
77
+ '--header-bg': theme?.headerBackgroundColor || (isDark ? 'rgba(15, 23, 42, 0.85)' : 'rgba(255, 255, 255, 0.82)'),
78
+ '--input-bg': isDark ? '#1e293b' : '#ffffff',
79
+ '--input-border': isDark ? 'rgba(255, 255, 255, 0.15)' : '#cbd5e1',
80
+ '--input-color': textColor,
81
+ // Dedicated Button Design Tokens
82
+ '--button-bg': buttonBg,
83
+ '--button-text': buttonText,
84
+ '--button-primary-bg': buttonBg,
85
+ '--button-primary-text': buttonText,
86
+ '--button-secondary-bg': buttonSecondaryBg,
87
+ '--button-secondary-text': buttonSecondaryText,
88
+ '--button-outline-border': isDark ? 'rgba(255, 255, 255, 0.22)' : 'currentColor',
89
+ '--button-outline-text': isDark ? '#f8fafc' : textColor,
90
+ '--button-ghost-text': isDark ? '#f8fafc' : textColor,
91
+ '--hero-min-height': theme?.heroMinHeight || '72vh',
92
+ '--section-padding': theme?.sectionPadding || '5rem',
93
+ '--base-size': theme?.baseSize || '16px',
94
+ '--heading-font': theme?.headingFont || 'Inter, sans-serif',
95
+ '--body-font': theme?.bodyFont || 'Inter, sans-serif',
96
+ '--border-radius': theme?.borderRadius || '8px',
97
+ '--content-align': theme?.align || 'left',
98
+ ...customVars,
99
+ };
100
+ }
@@ -0,0 +1,4 @@
1
+ import { FontPairing } from './types';
2
+ export declare const GLOBAL_FONT_OPTIONS: readonly ["Inter", "Playfair Display", "DM Sans", "Poppins", "Montserrat", "Plus Jakarta Sans", "Georgia", "Editorial Serif"];
3
+ export type GlobalFontOption = (typeof GLOBAL_FONT_OPTIONS)[number];
4
+ export declare const FONT_PAIRINGS: FontPairing[];
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FONT_PAIRINGS = exports.GLOBAL_FONT_OPTIONS = void 0;
4
+ exports.GLOBAL_FONT_OPTIONS = [
5
+ 'Inter',
6
+ 'Playfair Display',
7
+ 'DM Sans',
8
+ 'Poppins',
9
+ 'Montserrat',
10
+ 'Plus Jakarta Sans',
11
+ 'Georgia',
12
+ 'Editorial Serif',
13
+ ];
14
+ exports.FONT_PAIRINGS = [
15
+ {
16
+ id: 'modern-clean',
17
+ name: 'Modern & Clean',
18
+ headingFont: 'Plus Jakarta Sans',
19
+ bodyFont: 'Inter',
20
+ description: 'Crisp, contemporary tech and SaaS feel with high readability',
21
+ },
22
+ {
23
+ id: 'editorial-luxury',
24
+ name: 'Editorial Luxury',
25
+ headingFont: 'Playfair Display',
26
+ bodyFont: 'Inter',
27
+ description: 'Elegant serif headline paired with neutral modern body text',
28
+ },
29
+ {
30
+ id: 'tech-forward',
31
+ name: 'Tech Forward',
32
+ headingFont: 'Inter',
33
+ bodyFont: 'Inter',
34
+ description: 'Minimalist, uniform sans-serif design system',
35
+ },
36
+ {
37
+ id: 'vibrant-lifestyle',
38
+ name: 'Vibrant Lifestyle',
39
+ headingFont: 'Poppins',
40
+ bodyFont: 'DM Sans',
41
+ description: 'Warm, geometric sans pairing suited for retail and wellness',
42
+ },
43
+ {
44
+ id: 'classic-prestige',
45
+ name: 'Classic Prestige',
46
+ headingFont: 'Montserrat',
47
+ bodyFont: 'Inter',
48
+ description: 'Authoritative, balanced typography for premium brands',
49
+ },
50
+ ];
@@ -0,0 +1,6 @@
1
+ export * from './types';
2
+ export * from './contrast';
3
+ export * from './palettes';
4
+ export * from './fonts';
5
+ export * from './parser';
6
+ export * from './cssGenerator';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./contrast"), exports);
19
+ __exportStar(require("./palettes"), exports);
20
+ __exportStar(require("./fonts"), exports);
21
+ __exportStar(require("./parser"), exports);
22
+ __exportStar(require("./cssGenerator"), exports);
@@ -0,0 +1,2 @@
1
+ import { ThemePalette } from './types';
2
+ export declare const THEME_PALETTES: ThemePalette[];
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.THEME_PALETTES = void 0;
4
+ exports.THEME_PALETTES = [
5
+ // --- Light Themes ---
6
+ {
7
+ id: 'classic-luxe',
8
+ name: 'Classic Luxe',
9
+ badge: 'Light • Warm Luxe',
10
+ mode: 'light',
11
+ primary: '#1e293b',
12
+ secondary: '#d97706',
13
+ accent: '#f59e0b',
14
+ background: '#fdfbf7',
15
+ card: '#ffffff',
16
+ text: '#1e293b',
17
+ muted: '#64748b',
18
+ buttonBg: '#1e293b',
19
+ buttonText: '#ffffff',
20
+ },
21
+ {
22
+ id: 'ocean-modern',
23
+ name: 'Ocean Modern',
24
+ badge: 'Light • Crisp Ocean',
25
+ mode: 'light',
26
+ primary: '#0284c7',
27
+ secondary: '#0369a1',
28
+ accent: '#38bdf8',
29
+ background: '#f8fafc',
30
+ card: '#ffffff',
31
+ text: '#0f172a',
32
+ muted: '#64748b',
33
+ buttonBg: '#0284c7',
34
+ buttonText: '#ffffff',
35
+ },
36
+ {
37
+ id: 'forest-emerald',
38
+ name: 'Forest Emerald',
39
+ badge: 'Light • Organic Green',
40
+ mode: 'light',
41
+ primary: '#065f46',
42
+ secondary: '#047857',
43
+ accent: '#10b981',
44
+ background: '#f0fdf4',
45
+ card: '#ffffff',
46
+ text: '#064e3b',
47
+ muted: '#475569',
48
+ buttonBg: '#065f46',
49
+ buttonText: '#ffffff',
50
+ },
51
+ {
52
+ id: 'warm-terracotta',
53
+ name: 'Warm Terracotta',
54
+ badge: 'Light • Artisanal',
55
+ mode: 'light',
56
+ primary: '#c2410c',
57
+ secondary: '#ea580c',
58
+ accent: '#f97316',
59
+ background: '#fffaf5',
60
+ card: '#ffffff',
61
+ text: '#431407',
62
+ muted: '#78350f',
63
+ buttonBg: '#c2410c',
64
+ buttonText: '#ffffff',
65
+ },
66
+ {
67
+ id: 'velvet-berry',
68
+ name: 'Velvet Berry',
69
+ badge: 'Light • Vibrant Chic',
70
+ mode: 'light',
71
+ primary: '#9f1239',
72
+ secondary: '#be123c',
73
+ accent: '#f43f5e',
74
+ background: '#fff5f7',
75
+ card: '#ffffff',
76
+ text: '#4c0519',
77
+ muted: '#881337',
78
+ buttonBg: '#9f1239',
79
+ buttonText: '#ffffff',
80
+ },
81
+ // --- Dark Themes ---
82
+ {
83
+ id: 'sleek-obsidian',
84
+ name: 'Sleek Obsidian',
85
+ badge: 'Dark • Obsidian',
86
+ mode: 'dark',
87
+ primary: '#60a5fa',
88
+ secondary: '#38bdf8',
89
+ accent: '#93c5fd',
90
+ background: '#090d16',
91
+ card: '#131b2e',
92
+ text: '#f8fafc',
93
+ muted: '#94a3b8',
94
+ buttonBg: '#60a5fa',
95
+ buttonText: '#090d16',
96
+ },
97
+ {
98
+ id: 'midnight-cyber',
99
+ name: 'Midnight Cyber',
100
+ badge: 'Dark • Neon Cyber',
101
+ mode: 'dark',
102
+ primary: '#818cf8',
103
+ secondary: '#6366f1',
104
+ accent: '#22d3ee',
105
+ background: '#09090b',
106
+ card: '#18181b',
107
+ text: '#f4f4f5',
108
+ muted: '#a1a1aa',
109
+ buttonBg: '#818cf8',
110
+ buttonText: '#09090b',
111
+ },
112
+ {
113
+ id: 'royal-gold-dark',
114
+ name: 'Royal Gold & Dark',
115
+ badge: 'Dark • Imperial Gold',
116
+ mode: 'dark',
117
+ primary: '#f59e0b',
118
+ secondary: '#d97706',
119
+ accent: '#fbbf24',
120
+ background: '#0c0a09',
121
+ card: '#1c1917',
122
+ text: '#f5f5f4',
123
+ muted: '#a8a29e',
124
+ buttonBg: '#f59e0b',
125
+ buttonText: '#0c0a09',
126
+ },
127
+ {
128
+ id: 'emerald-nocturne',
129
+ name: 'Emerald Nocturne',
130
+ badge: 'Dark • Deep Emerald',
131
+ mode: 'dark',
132
+ primary: '#34d399',
133
+ secondary: '#10b981',
134
+ accent: '#6ee7b7',
135
+ background: '#022c22',
136
+ card: '#064e3b',
137
+ text: '#ecfdf5',
138
+ muted: '#a7f3d0',
139
+ buttonBg: '#34d399',
140
+ buttonText: '#022c22',
141
+ },
142
+ ];
@@ -0,0 +1,4 @@
1
+ import { VisualCustomization, TemplateThemeShape } from './types';
2
+ export declare function parseVisualCustomization(value: unknown): VisualCustomization;
3
+ export declare function customizationToTheme(customization: VisualCustomization): TemplateThemeShape;
4
+ export declare function mergeVisualCustomizationIntoTheme(baseTheme: TemplateThemeShape | null | undefined, customization: unknown): TemplateThemeShape | null;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseVisualCustomization = parseVisualCustomization;
4
+ exports.customizationToTheme = customizationToTheme;
5
+ exports.mergeVisualCustomizationIntoTheme = mergeVisualCustomizationIntoTheme;
6
+ function isPlainRecord(value) {
7
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
8
+ }
9
+ function parseVisualCustomization(value) {
10
+ if (!isPlainRecord(value))
11
+ return { version: 1 };
12
+ return {
13
+ version: 1,
14
+ colors: isPlainRecord(value.colors)
15
+ ? value.colors
16
+ : undefined,
17
+ colorReplacements: isPlainRecord(value.colorReplacements)
18
+ ? value.colorReplacements
19
+ : undefined,
20
+ typography: isPlainRecord(value.typography)
21
+ ? value.typography
22
+ : undefined,
23
+ spacing: isPlainRecord(value.spacing)
24
+ ? value.spacing
25
+ : undefined,
26
+ layout: isPlainRecord(value.layout)
27
+ ? value.layout
28
+ : undefined,
29
+ components: isPlainRecord(value.components)
30
+ ? value.components
31
+ : undefined,
32
+ sections: isPlainRecord(value.sections)
33
+ ? value.sections
34
+ : undefined,
35
+ elementStyles: isPlainRecord(value.elementStyles)
36
+ ? value.elementStyles
37
+ : undefined,
38
+ };
39
+ }
40
+ function customizationToTheme(customization) {
41
+ const colors = customization.colors ?? {};
42
+ return {
43
+ designCustomizationVersion: 1,
44
+ colorReplacements: customization.colorReplacements,
45
+ primaryColor: colors.primary,
46
+ secondaryColor: colors.secondary,
47
+ accentColor: colors.accent,
48
+ backgroundColor: colors.background,
49
+ textColor: colors.text,
50
+ surfaceColor: colors.surface ?? colors.cardBackground,
51
+ surfaceAltColor: colors.surfaceAlt,
52
+ headingColor: colors.heading ?? colors.text,
53
+ mutedTextColor: colors.mutedText,
54
+ borderColor: colors.border,
55
+ headerBackgroundColor: colors.headerBackground,
56
+ footerBackgroundColor: colors.footerBackground,
57
+ cardBackgroundColor: colors.cardBackground ?? colors.surface,
58
+ buttonBackgroundColor: colors.buttonBackground,
59
+ buttonTextColor: colors.buttonText,
60
+ ...customization.typography,
61
+ ...customization.spacing,
62
+ ...customization.layout,
63
+ ...customization.components,
64
+ sections: customization.sections,
65
+ elementStyles: customization.elementStyles,
66
+ };
67
+ }
68
+ function mergeVisualCustomizationIntoTheme(baseTheme, customization) {
69
+ const parsed = parseVisualCustomization(customization);
70
+ const hasOverrides = [
71
+ parsed.colors,
72
+ parsed.colorReplacements,
73
+ parsed.typography,
74
+ parsed.spacing,
75
+ parsed.layout,
76
+ parsed.components,
77
+ parsed.sections,
78
+ parsed.elementStyles,
79
+ ].some((group) => Boolean(group &&
80
+ Object.values(group).some((value) => value !== undefined && value !== '')));
81
+ if (!hasOverrides)
82
+ return baseTheme ?? null;
83
+ return Object.fromEntries(Object.entries({
84
+ ...(baseTheme ?? {}),
85
+ ...customizationToTheme(parsed),
86
+ }).filter(([, value]) => value !== undefined));
87
+ }
@@ -0,0 +1,197 @@
1
+ export interface VisualCustomizationColors {
2
+ primary?: string;
3
+ secondary?: string;
4
+ accent?: string;
5
+ background?: string;
6
+ text?: string;
7
+ surface?: string;
8
+ surfaceAlt?: string;
9
+ heading?: string;
10
+ mutedText?: string;
11
+ border?: string;
12
+ headerBackground?: string;
13
+ footerBackground?: string;
14
+ cardBackground?: string;
15
+ buttonBackground?: string;
16
+ buttonText?: string;
17
+ }
18
+ export interface VisualCustomizationTypography {
19
+ headingFont?: string;
20
+ bodyFont?: string;
21
+ baseSize?: string;
22
+ headingScale?: string;
23
+ bodyLineHeight?: string;
24
+ headingLineHeight?: string;
25
+ headingWeight?: string;
26
+ bodyWeight?: string;
27
+ letterSpacing?: string;
28
+ }
29
+ export interface VisualCustomizationSpacing {
30
+ heroMinHeight?: string;
31
+ sectionPadding?: string;
32
+ contentMaxWidth?: string;
33
+ containerPadding?: string;
34
+ sectionGap?: string;
35
+ elementGap?: string;
36
+ gridGap?: string;
37
+ }
38
+ export interface VisualCustomizationLayout {
39
+ textAlign?: string;
40
+ contentAlign?: string;
41
+ heroTextAlign?: string;
42
+ cardTextAlign?: string;
43
+ gridColumns?: string;
44
+ }
45
+ export interface VisualCustomizationComponents {
46
+ cardWidth?: string;
47
+ cardMinHeight?: string;
48
+ cardPadding?: string;
49
+ cardRadius?: string;
50
+ cardBorderWidth?: string;
51
+ cardShadow?: string;
52
+ buttonPadding?: string;
53
+ buttonRadius?: string;
54
+ buttonShadow?: string;
55
+ imageRadius?: string;
56
+ headerHeight?: string;
57
+ }
58
+ export interface VisualCustomizationSectionOverride {
59
+ backgroundColor?: string;
60
+ textColor?: string;
61
+ headingColor?: string;
62
+ minHeight?: string;
63
+ padding?: string;
64
+ contentMaxWidth?: string;
65
+ gap?: string;
66
+ textAlign?: string;
67
+ contentAlign?: string;
68
+ cardBackgroundColor?: string;
69
+ cardWidth?: string;
70
+ cardMinHeight?: string;
71
+ cardRadius?: string;
72
+ gridColumns?: string;
73
+ visible?: boolean;
74
+ }
75
+ export interface VisualCustomizationElementStyle {
76
+ fontFamily?: string;
77
+ fontSize?: string;
78
+ lineHeight?: string;
79
+ fontWeight?: string;
80
+ letterSpacing?: string;
81
+ color?: string;
82
+ backgroundColor?: string;
83
+ textAlign?: string;
84
+ width?: string;
85
+ height?: string;
86
+ minWidth?: string;
87
+ minHeight?: string;
88
+ maxWidth?: string;
89
+ maxHeight?: string;
90
+ marginTop?: string;
91
+ marginRight?: string;
92
+ marginBottom?: string;
93
+ marginLeft?: string;
94
+ paddingTop?: string;
95
+ paddingRight?: string;
96
+ paddingBottom?: string;
97
+ paddingLeft?: string;
98
+ borderWidth?: string;
99
+ borderStyle?: string;
100
+ borderColor?: string;
101
+ borderRadius?: string;
102
+ boxShadow?: string;
103
+ opacity?: string;
104
+ display?: string;
105
+ flexDirection?: string;
106
+ justifyContent?: string;
107
+ alignItems?: string;
108
+ gap?: string;
109
+ }
110
+ export interface VisualCustomization {
111
+ version: 1;
112
+ colors?: VisualCustomizationColors;
113
+ colorReplacements?: Record<string, string>;
114
+ typography?: VisualCustomizationTypography;
115
+ spacing?: VisualCustomizationSpacing;
116
+ layout?: VisualCustomizationLayout;
117
+ components?: VisualCustomizationComponents;
118
+ sections?: Record<string, VisualCustomizationSectionOverride>;
119
+ elementStyles?: Record<string, VisualCustomizationElementStyle>;
120
+ }
121
+ export interface TemplateThemeShape {
122
+ primaryColor?: string;
123
+ secondaryColor?: string;
124
+ accentColor?: string;
125
+ backgroundColor?: string;
126
+ textColor?: string;
127
+ surfaceColor?: string;
128
+ surfaceAltColor?: string;
129
+ headingColor?: string;
130
+ mutedTextColor?: string;
131
+ borderColor?: string;
132
+ headerBackgroundColor?: string;
133
+ footerBackgroundColor?: string;
134
+ cardBackgroundColor?: string;
135
+ buttonBackgroundColor?: string;
136
+ buttonTextColor?: string;
137
+ headingFont?: string;
138
+ bodyFont?: string;
139
+ baseSize?: string;
140
+ headingScale?: string;
141
+ bodyLineHeight?: string;
142
+ headingLineHeight?: string;
143
+ headingWeight?: string;
144
+ bodyWeight?: string;
145
+ letterSpacing?: string;
146
+ heroMinHeight?: string;
147
+ sectionPadding?: string;
148
+ contentMaxWidth?: string;
149
+ containerPadding?: string;
150
+ sectionGap?: string;
151
+ elementGap?: string;
152
+ gridGap?: string;
153
+ textAlign?: string;
154
+ contentAlign?: string;
155
+ heroTextAlign?: string;
156
+ cardTextAlign?: string;
157
+ gridColumns?: string;
158
+ cardWidth?: string;
159
+ cardMinHeight?: string;
160
+ cardPadding?: string;
161
+ cardRadius?: string;
162
+ cardBorderWidth?: string;
163
+ cardShadow?: string;
164
+ buttonPadding?: string;
165
+ buttonRadius?: string;
166
+ buttonShadow?: string;
167
+ imageRadius?: string;
168
+ headerHeight?: string;
169
+ style?: string;
170
+ designCustomizationVersion?: number;
171
+ colorReplacements?: Record<string, string>;
172
+ sections?: Record<string, VisualCustomizationSectionOverride>;
173
+ elementStyles?: Record<string, VisualCustomizationElementStyle>;
174
+ [key: string]: unknown;
175
+ }
176
+ export interface ThemePalette {
177
+ id: string;
178
+ name: string;
179
+ badge: string;
180
+ mode: 'light' | 'dark';
181
+ primary: string;
182
+ secondary: string;
183
+ accent: string;
184
+ background: string;
185
+ card: string;
186
+ text: string;
187
+ muted: string;
188
+ buttonBg?: string;
189
+ buttonText?: string;
190
+ }
191
+ export interface FontPairing {
192
+ id: string;
193
+ name: string;
194
+ headingFont: string;
195
+ bodyFont: string;
196
+ description: string;
197
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/core",
3
- "version": "2.0.68",
3
+ "version": "2.0.70",
4
4
  "description": "Headless style engine for real-time Fivora visual editing — CSS variables, DOM patcher, and preview protocol.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,6 +12,10 @@
12
12
  "./install-fonts": {
13
13
  "types": "./dist/fonts/installProject.d.ts",
14
14
  "default": "./dist/fonts/installProject.js"
15
+ },
16
+ "./theme": {
17
+ "types": "./dist/theme/index.d.ts",
18
+ "default": "./dist/theme/index.js"
15
19
  }
16
20
  },
17
21
  "publishConfig": {
@@ -32,7 +36,7 @@
32
36
  ],
33
37
  "scripts": {
34
38
  "build": "tsc",
35
- "test": "npm run build && node --test src/fonts/__tests__/fonts.test.cjs",
39
+ "test": "npm run build && node --test src/fonts/__tests__/fonts.test.cjs src/theme/__tests__/theme.test.cjs",
36
40
  "prepublishOnly": "npm run build"
37
41
  },
38
42
  "keywords": [