@umituz/web-design-system 6.11.0 → 6.13.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,167 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { render, screen, act } from '@testing-library/react';
3
+ import {
4
+ DesignSystemProvider,
5
+ useDesignSystem,
6
+ } from '../presentation/providers/DesignSystemProvider';
7
+ import {
8
+ getTheme,
9
+ registerTheme,
10
+ applyTheme,
11
+ themeToCssVariables,
12
+ createTheme,
13
+ midnightTheme,
14
+ editorialTheme,
15
+ oceanTheme,
16
+ defaultTheme,
17
+ } from '../infrastructure/themes';
18
+ import type { ThemeConfig } from '../domain/types';
19
+
20
+ describe('Theme System and Provider', () => {
21
+ beforeEach(() => {
22
+ localStorage.clear();
23
+ document.documentElement.className = '';
24
+ document.documentElement.removeAttribute('data-theme');
25
+ const existing = document.getElementById('umituz-theme-vars');
26
+ if (existing) existing.remove();
27
+ });
28
+
29
+ it('retrieves default and built-in themes by generic archetype name', () => {
30
+ expect(getTheme('midnight').name).toBe('midnight');
31
+ expect(getTheme('editorial').name).toBe('editorial');
32
+ expect(getTheme('ocean').name).toBe('ocean');
33
+ expect(getTheme('default').name).toBe('default');
34
+ expect(getTheme('non-existent').name).toBe('default');
35
+ });
36
+
37
+ it('allows createTheme to customize an existing preset or define from scratch', () => {
38
+ const customized = createTheme('midnight', {
39
+ name: 'midnight-custom',
40
+ colors: { primary: '#10b981' },
41
+ });
42
+
43
+ expect(customized.name).toBe('midnight-custom');
44
+ expect(customized.colors.primary).toBe('#10b981');
45
+ expect(customized.colors.background).toBe(midnightTheme.colors.background);
46
+
47
+ const fromScratch = createTheme({
48
+ name: 'standalone',
49
+ colors: {
50
+ background: '#000',
51
+ foreground: '#fff',
52
+ card: '#111',
53
+ cardForeground: '#fff',
54
+ popover: '#111',
55
+ popoverForeground: '#fff',
56
+ primary: '#f00',
57
+ primaryForeground: '#fff',
58
+ secondary: '#222',
59
+ secondaryForeground: '#fff',
60
+ muted: '#222',
61
+ mutedForeground: '#888',
62
+ accent: '#333',
63
+ accentForeground: '#fff',
64
+ border: '#444',
65
+ input: '#444',
66
+ destructive: '#f00',
67
+ destructiveForeground: '#fff',
68
+ },
69
+ });
70
+ expect(fromScratch.name).toBe('standalone');
71
+ });
72
+
73
+ it('registers and retrieves custom themes', () => {
74
+ const custom: ThemeConfig = {
75
+ name: 'custom-corp',
76
+ colors: {
77
+ background: '#111111',
78
+ foreground: '#eeeeee',
79
+ card: '#222222',
80
+ cardForeground: '#eeeeee',
81
+ popover: '#222222',
82
+ popoverForeground: '#eeeeee',
83
+ primary: '#ff0055',
84
+ primaryForeground: '#ffffff',
85
+ secondary: '#333333',
86
+ secondaryForeground: '#ffffff',
87
+ muted: '#333333',
88
+ mutedForeground: '#888888',
89
+ accent: '#444444',
90
+ accentForeground: '#ffffff',
91
+ border: '#555555',
92
+ input: '#555555',
93
+ destructive: '#ff0000',
94
+ destructiveForeground: '#ffffff',
95
+ },
96
+ };
97
+
98
+ registerTheme(custom);
99
+ expect(getTheme('custom-corp').colors.primary).toBe('#ff0055');
100
+ });
101
+
102
+ it('converts theme config to CSS variables string', () => {
103
+ const css = themeToCssVariables(midnightTheme);
104
+ expect(css).toContain('--color-primary: #4e8cff;');
105
+ expect(css).toContain('--app-primary: #4e8cff;');
106
+ expect(css).toContain('--color-background: #060a12;');
107
+ expect(css).toContain('--font-sans:');
108
+
109
+ const editorialCss = themeToCssVariables(editorialTheme);
110
+ expect(editorialCss).toContain('--color-primary: #33406b;');
111
+
112
+ const oceanCss = themeToCssVariables(oceanTheme);
113
+ expect(oceanCss).toContain('--color-primary: #0284c7;');
114
+
115
+ const defaultCss = themeToCssVariables(defaultTheme);
116
+ expect(defaultCss).toContain('--color-primary: #2563eb;');
117
+ });
118
+
119
+ it('applies theme variables to document head', () => {
120
+ applyTheme(midnightTheme);
121
+ const styleEl = document.getElementById('umituz-theme-vars');
122
+ expect(styleEl).toBeTruthy();
123
+ expect(styleEl?.textContent).toContain('--color-primary: #4e8cff;');
124
+ });
125
+
126
+ it('DesignSystemProvider provides theme and allows mode toggle', () => {
127
+ function Consumer() {
128
+ const { theme, mode, toggleMode, setMode } = useDesignSystem();
129
+ return (
130
+ <div>
131
+ <span data-testid="theme-name">{theme.name}</span>
132
+ <span data-testid="theme-mode">{mode}</span>
133
+ <button data-testid="toggle-btn" onClick={toggleMode}>
134
+ Toggle
135
+ </button>
136
+ <button data-testid="set-dark" onClick={() => setMode('dark')}>
137
+ Dark
138
+ </button>
139
+ </div>
140
+ );
141
+ }
142
+
143
+ render(
144
+ <DesignSystemProvider theme="midnight" mode="dark">
145
+ <Consumer />
146
+ </DesignSystemProvider>
147
+ );
148
+
149
+ expect(screen.getByTestId('theme-name').textContent).toBe('midnight');
150
+ expect(screen.getByTestId('theme-mode').textContent).toBe('dark');
151
+ expect(document.documentElement.classList.contains('dark')).toBe(true);
152
+
153
+ act(() => {
154
+ screen.getByTestId('toggle-btn').click();
155
+ });
156
+
157
+ expect(screen.getByTestId('theme-mode').textContent).toBe('light');
158
+ expect(document.documentElement.classList.contains('dark')).toBe(false);
159
+
160
+ act(() => {
161
+ screen.getByTestId('set-dark').click();
162
+ });
163
+
164
+ expect(screen.getByTestId('theme-mode').textContent).toBe('dark');
165
+ expect(document.documentElement.classList.contains('dark')).toBe(true);
166
+ });
167
+ });
@@ -18,3 +18,12 @@ export type {
18
18
  BreakpointState,
19
19
  UseBreakpointReturn,
20
20
  } from './breakpoint.types';
21
+
22
+ export type {
23
+ ThemeMode,
24
+ ThemeColors,
25
+ ThemeTypography,
26
+ ThemeRadii,
27
+ ThemeConfig,
28
+ } from './theme.types';
29
+
@@ -0,0 +1,56 @@
1
+ export type ThemeMode = 'light' | 'dark' | 'system';
2
+
3
+ export interface ThemeColors {
4
+ background: string;
5
+ foreground: string;
6
+ card: string;
7
+ cardForeground: string;
8
+ popover: string;
9
+ popoverForeground: string;
10
+ primary: string;
11
+ primaryForeground: string;
12
+ secondary: string;
13
+ secondaryForeground: string;
14
+ muted: string;
15
+ mutedForeground: string;
16
+ accent: string;
17
+ accentForeground: string;
18
+ border: string;
19
+ input: string;
20
+ destructive: string;
21
+ destructiveForeground: string;
22
+ ring?: string;
23
+ success?: string;
24
+ successForeground?: string;
25
+ warning?: string;
26
+ warningForeground?: string;
27
+ info?: string;
28
+ infoForeground?: string;
29
+ violet?: string;
30
+ violetForeground?: string;
31
+ primarySoft?: string;
32
+ }
33
+
34
+ export interface ThemeTypography {
35
+ fontSans?: string;
36
+ fontMono?: string;
37
+ fontDisplay?: string;
38
+ }
39
+
40
+ export interface ThemeRadii {
41
+ xs?: string;
42
+ sm?: string;
43
+ md?: string;
44
+ lg?: string;
45
+ xl?: string;
46
+ }
47
+
48
+ export interface ThemeConfig {
49
+ name: string;
50
+ mode?: 'light' | 'dark';
51
+ colors: ThemeColors;
52
+ darkColors?: Partial<ThemeColors>;
53
+ typography?: ThemeTypography;
54
+ radii?: ThemeRadii;
55
+ customVars?: Record<string, string>;
56
+ }
package/src/index.ts CHANGED
@@ -1,19 +1,23 @@
1
- // Core Tokens, Types, Constants, Hooks & Utils
2
1
  export * from './domain/tokens';
3
2
  export * from './domain/types';
4
3
  export * from './infrastructure/utils';
5
4
  export * from './infrastructure/constants';
5
+ export * from './infrastructure/themes';
6
6
  export * from './presentation/hooks';
7
-
8
- // Templates
9
7
  export * from './presentation/templates';
10
-
11
- // Organisms
12
8
  export * from './presentation/organisms';
9
+ export * from './presentation/providers';
10
+
13
11
 
14
- // Atoms
15
12
  export type { ButtonProps } from './presentation/atoms/Button';
16
13
  export { Button, buttonVariants } from './presentation/atoms/Button';
14
+ export type { StackProps, StackGap, StackAlign, StackJustify } from './presentation/atoms/Stack';
15
+ export { Stack } from './presentation/atoms/Stack';
16
+ export type { RowProps, RowGap, RowAlign, RowJustify } from './presentation/atoms/Row';
17
+ export { Row } from './presentation/atoms/Row';
18
+ export type { GridProps, GridCols, GridColsNumber, ResponsiveGridCols, GridGap } from './presentation/atoms/Grid';
19
+ export { Grid } from './presentation/atoms/Grid';
20
+
17
21
  export type { BadgeProps, BadgeVariant } from './presentation/atoms/Badge';
18
22
  export { Badge } from './presentation/atoms/Badge';
19
23
  export type { InputProps } from './presentation/atoms/Input';
@@ -74,7 +78,6 @@ export type { CopyButtonProps } from './presentation/atoms/CopyButton';
74
78
  export { StatusDot } from './presentation/atoms/StatusDot';
75
79
  export type { StatusDotProps, StatusType } from './presentation/atoms/StatusDot';
76
80
 
77
- // Molecules
78
81
  export type { FormFieldProps } from './presentation/molecules/FormField';
79
82
  export { FormField } from './presentation/molecules/FormField';
80
83
  export type { SearchBoxProps } from './presentation/molecules/SearchBox';
@@ -0,0 +1,149 @@
1
+ import type { ThemeConfig, ThemeColors } from '../../domain/types';
2
+ import { getTheme } from './registry';
3
+
4
+ function colorPropsToCss(colors: ThemeColors): string {
5
+ const lines: string[] = [];
6
+ const entries: [keyof ThemeColors, string][] = [
7
+ ['background', '--color-background'],
8
+ ['foreground', '--color-foreground'],
9
+ ['card', '--color-card'],
10
+ ['cardForeground', '--color-card-foreground'],
11
+ ['popover', '--color-popover'],
12
+ ['popoverForeground', '--color-popover-foreground'],
13
+ ['primary', '--color-primary'],
14
+ ['primaryForeground', '--color-primary-foreground'],
15
+ ['secondary', '--color-secondary'],
16
+ ['secondaryForeground', '--color-secondary-foreground'],
17
+ ['muted', '--color-muted'],
18
+ ['mutedForeground', '--color-muted-foreground'],
19
+ ['accent', '--color-accent'],
20
+ ['accentForeground', '--color-accent-foreground'],
21
+ ['border', '--color-border'],
22
+ ['input', '--color-input'],
23
+ ['destructive', '--color-destructive'],
24
+ ['destructiveForeground', '--color-destructive-foreground'],
25
+ ];
26
+
27
+ for (const [key, cssVar] of entries) {
28
+ const val = colors[key];
29
+ if (val) {
30
+ lines.push(`${cssVar}: ${val};`);
31
+ const appVar = cssVar.replace('--color-', '--app-');
32
+ lines.push(`${appVar}: ${val};`);
33
+ }
34
+ }
35
+
36
+ if (colors.ring) {
37
+ lines.push(`--color-ring: ${colors.ring};`);
38
+ lines.push(`--app-ring: ${colors.ring};`);
39
+ }
40
+ if (colors.success) {
41
+ lines.push(`--color-success: ${colors.success};`);
42
+ lines.push(`--app-success: ${colors.success};`);
43
+ }
44
+ if (colors.successForeground) {
45
+ lines.push(`--color-success-foreground: ${colors.successForeground};`);
46
+ lines.push(`--app-success-foreground: ${colors.successForeground};`);
47
+ }
48
+ if (colors.warning) {
49
+ lines.push(`--color-warning: ${colors.warning};`);
50
+ lines.push(`--app-warning: ${colors.warning};`);
51
+ }
52
+ if (colors.warningForeground) {
53
+ lines.push(`--color-warning-foreground: ${colors.warningForeground};`);
54
+ lines.push(`--app-warning-foreground: ${colors.warningForeground};`);
55
+ }
56
+ if (colors.info) {
57
+ lines.push(`--color-info: ${colors.info};`);
58
+ lines.push(`--app-info: ${colors.info};`);
59
+ }
60
+ if (colors.infoForeground) {
61
+ lines.push(`--color-info-foreground: ${colors.infoForeground};`);
62
+ lines.push(`--app-info-foreground: ${colors.infoForeground};`);
63
+ }
64
+ if (colors.violet) {
65
+ lines.push(`--color-violet: ${colors.violet};`);
66
+ lines.push(`--app-violet: ${colors.violet};`);
67
+ }
68
+ if (colors.violetForeground) {
69
+ lines.push(`--color-violet-foreground: ${colors.violetForeground};`);
70
+ lines.push(`--app-violet-foreground: ${colors.violetForeground};`);
71
+ }
72
+ if (colors.primarySoft) {
73
+ lines.push(`--color-primary-soft: ${colors.primarySoft};`);
74
+ lines.push(`--app-primary-soft: ${colors.primarySoft};`);
75
+ }
76
+
77
+ return lines.join('\n ');
78
+ }
79
+
80
+ export function themeToCssVariables(theme: ThemeConfig): string {
81
+ const rootLines: string[] = [colorPropsToCss(theme.colors)];
82
+
83
+ if (theme.typography?.fontSans) {
84
+ rootLines.push(`--font-sans: ${theme.typography.fontSans};`);
85
+ rootLines.push(`--app-font-sans: ${theme.typography.fontSans};`);
86
+ }
87
+ if (theme.typography?.fontMono) {
88
+ rootLines.push(`--font-mono: ${theme.typography.fontMono};`);
89
+ rootLines.push(`--app-font-mono: ${theme.typography.fontMono};`);
90
+ }
91
+ if (theme.typography?.fontDisplay) {
92
+ rootLines.push(`--font-display: ${theme.typography.fontDisplay};`);
93
+ }
94
+
95
+ if (theme.radii) {
96
+ if (theme.radii.xs) rootLines.push(`--radius-xs: ${theme.radii.xs};`);
97
+ if (theme.radii.sm) rootLines.push(`--radius-sm: ${theme.radii.sm};`);
98
+ if (theme.radii.md) rootLines.push(`--radius-md: ${theme.radii.md};`);
99
+ if (theme.radii.lg) rootLines.push(`--radius-lg: ${theme.radii.lg};`);
100
+ if (theme.radii.xl) rootLines.push(`--radius-xl: ${theme.radii.xl};`);
101
+ }
102
+
103
+ if (theme.customVars) {
104
+ for (const [k, v] of Object.entries(theme.customVars)) {
105
+ rootLines.push(`--${k}: ${v};`);
106
+ }
107
+ }
108
+
109
+ let css = `:root {\n ${rootLines.join('\n ')}\n}\n`;
110
+
111
+ if (theme.darkColors && Object.keys(theme.darkColors).length > 0) {
112
+ const darkMerged: ThemeColors = {
113
+ ...theme.colors,
114
+ ...theme.darkColors,
115
+ };
116
+ css += `\n.dark, [data-theme="dark"] {\n ${colorPropsToCss(darkMerged)}\n}\n`;
117
+ }
118
+
119
+ return css;
120
+ }
121
+
122
+ export function applyTheme(
123
+ themeOrName: string | ThemeConfig,
124
+ targetDoc?: Document
125
+ ): ThemeConfig {
126
+ const theme = typeof themeOrName === 'string' ? getTheme(themeOrName) : themeOrName;
127
+ const doc = targetDoc ?? (typeof document !== 'undefined' ? document : undefined);
128
+ if (!doc) return theme;
129
+
130
+ const styleId = 'umituz-theme-vars';
131
+ let styleEl = doc.getElementById(styleId) as HTMLStyleElement | null;
132
+ if (!styleEl) {
133
+ styleEl = doc.createElement('style');
134
+ styleEl.id = styleId;
135
+ doc.head.appendChild(styleEl);
136
+ }
137
+
138
+ styleEl.textContent = themeToCssVariables(theme);
139
+
140
+ if (theme.mode === 'dark') {
141
+ doc.documentElement.classList.add('dark');
142
+ doc.documentElement.setAttribute('data-theme', 'dark');
143
+ } else if (theme.mode === 'light') {
144
+ doc.documentElement.classList.remove('dark');
145
+ doc.documentElement.setAttribute('data-theme', 'light');
146
+ }
147
+
148
+ return theme;
149
+ }
@@ -0,0 +1,49 @@
1
+ import type { ThemeConfig, ThemeColors, ThemeTypography, ThemeRadii } from '../../domain/types';
2
+ import { getTheme } from './registry';
3
+
4
+ export interface ThemeOverrides {
5
+ name?: string;
6
+ mode?: 'light' | 'dark';
7
+ colors?: Partial<ThemeColors>;
8
+ darkColors?: Partial<ThemeColors>;
9
+ typography?: Partial<ThemeTypography>;
10
+ radii?: Partial<ThemeRadii>;
11
+ customVars?: Record<string, string>;
12
+ }
13
+
14
+ export function createTheme(
15
+ baseOrConfig: string | ThemeConfig,
16
+ overrides?: ThemeOverrides
17
+ ): ThemeConfig {
18
+ if (typeof baseOrConfig === 'object' && !overrides) {
19
+ return baseOrConfig;
20
+ }
21
+
22
+ const base = typeof baseOrConfig === 'string' ? getTheme(baseOrConfig) : baseOrConfig;
23
+ if (!overrides) return base;
24
+
25
+ return {
26
+ name: overrides.name ?? base.name,
27
+ mode: overrides.mode ?? base.mode,
28
+ colors: {
29
+ ...base.colors,
30
+ ...(overrides.colors ?? {}),
31
+ },
32
+ darkColors: {
33
+ ...(base.darkColors ?? {}),
34
+ ...(overrides.darkColors ?? {}),
35
+ },
36
+ typography: {
37
+ ...(base.typography ?? {}),
38
+ ...(overrides.typography ?? {}),
39
+ },
40
+ radii: {
41
+ ...(base.radii ?? {}),
42
+ ...(overrides.radii ?? {}),
43
+ },
44
+ customVars: {
45
+ ...(base.customVars ?? {}),
46
+ ...(overrides.customVars ?? {}),
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,73 @@
1
+ import type { ThemeConfig } from '../../domain/types';
2
+
3
+ export const defaultTheme: ThemeConfig = {
4
+ name: 'default',
5
+ mode: 'light',
6
+ colors: {
7
+ background: '#f8fafc',
8
+ foreground: '#0f172a',
9
+ card: '#ffffff',
10
+ cardForeground: '#0f172a',
11
+ popover: '#ffffff',
12
+ popoverForeground: '#0f172a',
13
+ primary: '#2563eb',
14
+ primaryForeground: '#ffffff',
15
+ primarySoft: 'rgba(37, 99, 235, 0.1)',
16
+ secondary: '#8b5cf6',
17
+ secondaryForeground: '#ffffff',
18
+ muted: '#f1f5f9',
19
+ mutedForeground: '#64748b',
20
+ accent: '#f1f5f9',
21
+ accentForeground: '#0f172a',
22
+ border: '#e2e8f0',
23
+ input: '#e2e8f0',
24
+ destructive: '#dc2626',
25
+ destructiveForeground: '#ffffff',
26
+ ring: 'rgba(37, 99, 235, 0.45)',
27
+ success: '#16a34a',
28
+ successForeground: '#ffffff',
29
+ warning: '#d97706',
30
+ warningForeground: '#ffffff',
31
+ info: '#2563eb',
32
+ infoForeground: '#ffffff',
33
+ violet: '#7c3aed',
34
+ violetForeground: '#ffffff',
35
+ },
36
+ darkColors: {
37
+ background: '#0b1120',
38
+ foreground: '#f1f5f9',
39
+ card: '#111827',
40
+ cardForeground: '#f1f5f9',
41
+ popover: '#111827',
42
+ popoverForeground: '#f1f5f9',
43
+ primary: '#3b82f6',
44
+ primaryForeground: '#ffffff',
45
+ secondary: '#a78bfa',
46
+ secondaryForeground: '#ffffff',
47
+ muted: '#1e293b',
48
+ mutedForeground: '#94a3b8',
49
+ accent: '#1e293b',
50
+ accentForeground: '#f1f5f9',
51
+ border: '#1f2a3c',
52
+ input: '#1f2a3c',
53
+ destructive: '#ef4444',
54
+ destructiveForeground: '#ffffff',
55
+ ring: 'rgba(59, 130, 246, 0.5)',
56
+ success: '#22c55e',
57
+ successForeground: '#ffffff',
58
+ warning: '#f59e0b',
59
+ warningForeground: '#ffffff',
60
+ info: '#3b82f6',
61
+ infoForeground: '#ffffff',
62
+ },
63
+ typography: {
64
+ fontSans: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
65
+ fontMono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
66
+ },
67
+ radii: {
68
+ sm: '6px',
69
+ md: '8px',
70
+ lg: '12px',
71
+ xl: '16px',
72
+ },
73
+ };
@@ -0,0 +1,65 @@
1
+ import type { ThemeConfig } from '../../domain/types';
2
+
3
+ export const editorialTheme: ThemeConfig = {
4
+ name: 'editorial',
5
+ mode: 'light',
6
+ colors: {
7
+ background: '#f4f1e9',
8
+ foreground: '#23252b',
9
+ card: '#fdfcf8',
10
+ cardForeground: '#23252b',
11
+ popover: '#fdfcf8',
12
+ popoverForeground: '#23252b',
13
+ primary: '#33406b',
14
+ primaryForeground: '#ffffff',
15
+ primarySoft: 'rgba(51, 64, 107, 0.12)',
16
+ secondary: '#efeadc',
17
+ secondaryForeground: '#5a5d66',
18
+ muted: '#efeadc',
19
+ mutedForeground: '#5a5d66',
20
+ accent: '#efeadc',
21
+ accentForeground: '#23252b',
22
+ border: '#e5e1d4',
23
+ input: '#d4cfbf',
24
+ destructive: '#a6483f',
25
+ destructiveForeground: '#ffffff',
26
+ ring: 'rgba(51, 64, 107, 0.4)',
27
+ success: '#3b7a5e',
28
+ successForeground: '#ffffff',
29
+ warning: '#a26b2f',
30
+ warningForeground: '#ffffff',
31
+ info: '#46618f',
32
+ infoForeground: '#ffffff',
33
+ },
34
+ darkColors: {
35
+ background: '#14161f',
36
+ foreground: '#eceadf',
37
+ card: '#1b1e2a',
38
+ cardForeground: '#eceadf',
39
+ popover: '#1b1e2a',
40
+ popoverForeground: '#eceadf',
41
+ primary: '#7f92cc',
42
+ primaryForeground: '#14161f',
43
+ secondary: '#212533',
44
+ secondaryForeground: '#a8abba',
45
+ muted: '#212533',
46
+ mutedForeground: '#a8abba',
47
+ accent: '#212533',
48
+ accentForeground: '#eceadf',
49
+ border: '#2e3344',
50
+ input: '#3d4358',
51
+ destructive: '#c2665c',
52
+ destructiveForeground: '#2a1210',
53
+ ring: 'rgba(143, 160, 214, 0.4)',
54
+ success: '#5ea184',
55
+ successForeground: '#0e1f17',
56
+ warning: '#c98f4a',
57
+ warningForeground: '#221607',
58
+ info: '#7f92cc',
59
+ infoForeground: '#0e1424',
60
+ },
61
+ typography: {
62
+ fontSans: '"Hanken Grotesk", "Noto Sans", -apple-system, "Segoe UI", sans-serif',
63
+ fontDisplay: '"Newsreader", "Iowan Old Style", Georgia, serif',
64
+ },
65
+ };
@@ -0,0 +1,8 @@
1
+ export { defaultTheme } from './default.theme';
2
+ export { oceanTheme } from './ocean.theme';
3
+ export { midnightTheme } from './midnight.theme';
4
+ export { editorialTheme } from './editorial.theme';
5
+ export { createTheme } from './create-theme';
6
+ export type { ThemeOverrides } from './create-theme';
7
+ export { registerTheme, getTheme, hasTheme, listThemes } from './registry';
8
+ export { themeToCssVariables, applyTheme } from './apply-theme';