@phcdevworks/spectre-ui 1.1.0 → 1.1.2

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.
@@ -1,25 +1,27 @@
1
1
  'use strict';
2
2
 
3
3
  // src/tailwind/theme.ts
4
+ var asTokenTree = (value) => value && typeof value === "object" ? value : {};
4
5
  function createSpectreTailwindTheme(options) {
5
6
  const mergedTokens = {
6
7
  ...options.tokens ?? {},
7
8
  ...options.overrides ?? {}
8
9
  };
9
- const t = mergedTokens;
10
+ const t = asTokenTree(mergedTokens);
11
+ const typography = asTokenTree(t.typography);
10
12
  const colors = {
11
- ...t.colors ?? t.color ?? t.palette ?? {},
12
- surface: t.surface ?? {},
13
- text: t.text ?? {},
14
- buttons: t.buttons ?? {},
15
- forms: t.forms ?? {},
16
- component: t.component ?? {}
13
+ ...asTokenTree(t.colors ?? t.color ?? t.palette),
14
+ surface: asTokenTree(t.surface),
15
+ text: asTokenTree(t.text),
16
+ buttons: asTokenTree(t.buttons),
17
+ forms: asTokenTree(t.forms),
18
+ component: asTokenTree(t.component)
17
19
  };
18
- const spacing = t.spacing ?? t.space ?? {};
19
- const borderRadius = t.radii ?? t.radius ?? {};
20
- const boxShadow = t.shadows ?? t.shadow ?? {};
21
- const fontFamily = t.typography?.families ?? t.fonts ?? {};
22
- const fontSize = t.typography?.scale ?? t.fontSize ?? {};
20
+ const spacing = asTokenTree(t.spacing ?? t.space);
21
+ const borderRadius = asTokenTree(t.radii ?? t.radius);
22
+ const boxShadow = asTokenTree(t.shadows ?? t.shadow);
23
+ const fontFamily = asTokenTree(typography.families ?? t.fonts);
24
+ const fontSize = asTokenTree(typography.scale ?? t.fontSize);
23
25
  const theme = {
24
26
  colors,
25
27
  spacing,
@@ -35,7 +37,9 @@ function createSpectreTailwindTheme(options) {
35
37
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
36
38
  var deepMerge = (base, overrides) => {
37
39
  if (!overrides) return base;
38
- const result = { ...base };
40
+ const result = {
41
+ ...base
42
+ };
39
43
  for (const [key, overrideValue] of Object.entries(overrides)) {
40
44
  const baseValue = result[key];
41
45
  if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
@@ -54,19 +58,12 @@ var createSpectreTailwindPreset = (options) => {
54
58
  }
55
59
  const { tokens } = options;
56
60
  const { theme } = createSpectreTailwindTheme({ tokens });
57
- const mergedTheme = deepMerge(
58
- theme,
59
- options.themeOverrides
60
- );
61
+ const mergedTheme = deepMerge(theme, options.themeOverrides);
61
62
  const basePreset = {
62
63
  content: [],
63
64
  theme: mergedTheme
64
- // theme is guaranteed non-undefined now
65
65
  };
66
- return deepMerge(
67
- basePreset,
68
- options.presetOverrides
69
- );
66
+ return deepMerge(basePreset, options.presetOverrides);
70
67
  };
71
68
 
72
69
  exports.createSpectreTailwindPreset = createSpectreTailwindPreset;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":";;;AAkBO,SAAS,2BACd,OAAA,EACsB;AACtB,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,GAAI,OAAA,CAAQ,MAAA,IAAW,EAAC;AAAA,IACxB,GAAI,OAAA,CAAQ,SAAA,IAAa;AAAC,GAC5B;AAIA,EAAA,MAAM,CAAA,GAAS,YAAA;AAEf,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,GAAK,CAAA,CAAE,MAAA,IAAU,EAAE,KAAA,IAAS,CAAA,CAAE,WAAW,EAAC;AAAA,IAC1C,OAAA,EAAS,CAAA,CAAE,OAAA,IAAW,EAAC;AAAA,IACvB,IAAA,EAAM,CAAA,CAAE,IAAA,IAAQ,EAAC;AAAA,IACjB,OAAA,EAAS,CAAA,CAAE,OAAA,IAAW,EAAC;AAAA,IACvB,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,EAAC;AAAA,IACnB,SAAA,EAAW,CAAA,CAAE,SAAA,IAAa;AAAC,GAC7B;AACA,EAAA,MAAM,OAAA,GAAW,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,SAAS,EAAC;AAC1C,EAAA,MAAM,YAAA,GAAgB,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,UAAU,EAAC;AAC9C,EAAA,MAAM,SAAA,GAAa,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,UAAU,EAAC;AAC7C,EAAA,MAAM,aAAc,CAAA,CAAE,UAAA,EAAY,QAAA,IAAY,CAAA,CAAE,SAAS,EAAC;AAC1D,EAAA,MAAM,WAAY,CAAA,CAAE,UAAA,EAAY,KAAA,IAAS,CAAA,CAAE,YAAY,EAAC;AAExD,EAAA,MAAM,KAAA,GAAuB;AAAA,IAC3B,MAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;;;AC1CA,IAAM,aAAA,GAAgB,CAAC,KAAA,KACrB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAGrE,IAAM,SAAA,GAAY,CAChB,IAAA,EACA,SAAA,KACM;AACN,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,MAAM,MAAA,GAAkC,EAAE,GAAG,IAAA,EAAK;AAElD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,aAAa,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5D,IAAA,MAAM,SAAA,GAAY,OAAO,GAAG,CAAA;AAC5B,IAAA,IAAI,aAAA,CAAc,SAAS,CAAA,IAAK,aAAA,CAAc,aAAa,CAAA,EAAG;AAC5D,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA,CAAU,SAAA,EAAW,aAAa,CAAA;AAAA,IAClD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,aAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,IAAM,2BAAA,GAA8B,CACzC,OAAA,KACmB;AACnB,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,OAAA;AACnB,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,0BAAA,CAA2B,EAAE,QAAQ,CAAA;AACvD,EAAA,MAAM,WAAA,GAAc,SAAA;AAAA,IAClB,KAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,MAAM,UAAA,GAA6B;AAAA,IACjC,SAAS,EAAC;AAAA,IACV,KAAA,EAAO;AAAA;AAAA,GACT;AAEA,EAAA,OAAO,SAAA;AAAA,IACL,UAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AACF","file":"index.cjs","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = {\n ...((t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>),\n surface: t.surface ?? {},\n text: t.text ?? {},\n buttons: t.buttons ?? {},\n forms: t.forms ?? {},\n component: t.component ?? {},\n };\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\n};\n"]}
1
+ {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\ntype TokenTree = Record<string, unknown>;\n\nconst asTokenTree = (value: unknown): TokenTree =>\n value && typeof value === \"object\" ? (value as TokenTree) : {};\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t = asTokenTree(mergedTokens);\n const typography = asTokenTree(t.typography);\n\n const colors = {\n ...asTokenTree(t.colors ?? t.color ?? t.palette),\n surface: asTokenTree(t.surface),\n text: asTokenTree(t.text),\n buttons: asTokenTree(t.buttons),\n forms: asTokenTree(t.forms),\n component: asTokenTree(t.component),\n };\n const spacing = asTokenTree(t.spacing ?? t.space);\n const borderRadius = asTokenTree(t.radii ?? t.radius);\n const boxShadow = asTokenTree(t.shadows ?? t.shadow);\n const fontFamily = asTokenTree(typography.families ?? t.fonts);\n const fontSize = asTokenTree(typography.scale ?? t.fontSize);\n\n const theme: TailwindTheme = {\n colors: colors as TailwindTheme[\"colors\"],\n spacing: spacing as TailwindTheme[\"spacing\"],\n borderRadius: borderRadius as TailwindTheme[\"borderRadius\"],\n boxShadow: boxShadow as TailwindTheme[\"boxShadow\"],\n fontFamily: fontFamily as TailwindTheme[\"fontFamily\"],\n fontSize: fontSize as TailwindTheme[\"fontSize\"],\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends object>(\n base: T,\n overrides?: Partial<T>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = {\n ...(base as Record<string, unknown>),\n };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(theme, options.themeOverrides);\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme,\n };\n\n return deepMerge(basePreset, options.presetOverrides);\n};\n"]}
@@ -1,23 +1,25 @@
1
1
  // src/tailwind/theme.ts
2
+ var asTokenTree = (value) => value && typeof value === "object" ? value : {};
2
3
  function createSpectreTailwindTheme(options) {
3
4
  const mergedTokens = {
4
5
  ...options.tokens ?? {},
5
6
  ...options.overrides ?? {}
6
7
  };
7
- const t = mergedTokens;
8
+ const t = asTokenTree(mergedTokens);
9
+ const typography = asTokenTree(t.typography);
8
10
  const colors = {
9
- ...t.colors ?? t.color ?? t.palette ?? {},
10
- surface: t.surface ?? {},
11
- text: t.text ?? {},
12
- buttons: t.buttons ?? {},
13
- forms: t.forms ?? {},
14
- component: t.component ?? {}
11
+ ...asTokenTree(t.colors ?? t.color ?? t.palette),
12
+ surface: asTokenTree(t.surface),
13
+ text: asTokenTree(t.text),
14
+ buttons: asTokenTree(t.buttons),
15
+ forms: asTokenTree(t.forms),
16
+ component: asTokenTree(t.component)
15
17
  };
16
- const spacing = t.spacing ?? t.space ?? {};
17
- const borderRadius = t.radii ?? t.radius ?? {};
18
- const boxShadow = t.shadows ?? t.shadow ?? {};
19
- const fontFamily = t.typography?.families ?? t.fonts ?? {};
20
- const fontSize = t.typography?.scale ?? t.fontSize ?? {};
18
+ const spacing = asTokenTree(t.spacing ?? t.space);
19
+ const borderRadius = asTokenTree(t.radii ?? t.radius);
20
+ const boxShadow = asTokenTree(t.shadows ?? t.shadow);
21
+ const fontFamily = asTokenTree(typography.families ?? t.fonts);
22
+ const fontSize = asTokenTree(typography.scale ?? t.fontSize);
21
23
  const theme = {
22
24
  colors,
23
25
  spacing,
@@ -33,7 +35,9 @@ function createSpectreTailwindTheme(options) {
33
35
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
34
36
  var deepMerge = (base, overrides) => {
35
37
  if (!overrides) return base;
36
- const result = { ...base };
38
+ const result = {
39
+ ...base
40
+ };
37
41
  for (const [key, overrideValue] of Object.entries(overrides)) {
38
42
  const baseValue = result[key];
39
43
  if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
@@ -52,19 +56,12 @@ var createSpectreTailwindPreset = (options) => {
52
56
  }
53
57
  const { tokens } = options;
54
58
  const { theme } = createSpectreTailwindTheme({ tokens });
55
- const mergedTheme = deepMerge(
56
- theme,
57
- options.themeOverrides
58
- );
59
+ const mergedTheme = deepMerge(theme, options.themeOverrides);
59
60
  const basePreset = {
60
61
  content: [],
61
62
  theme: mergedTheme
62
- // theme is guaranteed non-undefined now
63
63
  };
64
- return deepMerge(
65
- basePreset,
66
- options.presetOverrides
67
- );
64
+ return deepMerge(basePreset, options.presetOverrides);
68
65
  };
69
66
 
70
67
  export { createSpectreTailwindPreset, createSpectreTailwindTheme };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = {\n ...((t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>),\n surface: t.surface ?? {},\n text: t.text ?? {},\n buttons: t.buttons ?? {},\n forms: t.forms ?? {},\n component: t.component ?? {},\n };\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\n};\n"]}
1
+ {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\ntype TokenTree = Record<string, unknown>;\n\nconst asTokenTree = (value: unknown): TokenTree =>\n value && typeof value === \"object\" ? (value as TokenTree) : {};\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t = asTokenTree(mergedTokens);\n const typography = asTokenTree(t.typography);\n\n const colors = {\n ...asTokenTree(t.colors ?? t.color ?? t.palette),\n surface: asTokenTree(t.surface),\n text: asTokenTree(t.text),\n buttons: asTokenTree(t.buttons),\n forms: asTokenTree(t.forms),\n component: asTokenTree(t.component),\n };\n const spacing = asTokenTree(t.spacing ?? t.space);\n const borderRadius = asTokenTree(t.radii ?? t.radius);\n const boxShadow = asTokenTree(t.shadows ?? t.shadow);\n const fontFamily = asTokenTree(typography.families ?? t.fonts);\n const fontSize = asTokenTree(typography.scale ?? t.fontSize);\n\n const theme: TailwindTheme = {\n colors: colors as TailwindTheme[\"colors\"],\n spacing: spacing as TailwindTheme[\"spacing\"],\n borderRadius: borderRadius as TailwindTheme[\"borderRadius\"],\n boxShadow: boxShadow as TailwindTheme[\"boxShadow\"],\n fontFamily: fontFamily as TailwindTheme[\"fontFamily\"],\n fontSize: fontSize as TailwindTheme[\"fontSize\"],\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends object>(\n base: T,\n overrides?: Partial<T>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = {\n ...(base as Record<string, unknown>),\n };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(theme, options.themeOverrides);\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme,\n };\n\n return deepMerge(basePreset, options.presetOverrides);\n};\n"]}
@@ -1,3 +1,378 @@
1
+ :root {
2
+ --sp-surface-page: #f7f8fb;
3
+ --sp-surface-card: #ffffff;
4
+ --sp-surface-input: #ffffff;
5
+ --sp-surface-overlay: rgba(20, 27, 36, 0.6);
6
+ --sp-surface-hero: linear-gradient(135deg, #5b6ee1 0%, #6f3fd7 100%);
7
+ --sp-text-on-page-default: #141b24;
8
+ --sp-text-on-page-muted: #4b576a;
9
+ --sp-text-on-page-subtle: #657287;
10
+ --sp-text-on-page-meta: #657287;
11
+ --sp-text-on-surface-default: #141b24;
12
+ --sp-text-on-surface-muted: #4b576a;
13
+ --sp-text-on-surface-subtle: #657287;
14
+ --sp-text-on-surface-meta: #657287;
15
+ --sp-component-card-text: #141b24;
16
+ --sp-component-card-text-muted: #657287;
17
+ --sp-component-input-text: #141b24;
18
+ --sp-component-input-placeholder: #657287;
19
+ --sp-button-text-default: #141b24;
20
+ --sp-button-text-on-primary: #ffffff;
21
+ --sp-badge-neutral-bg: #eef1f6;
22
+ --sp-badge-neutral-text: #374253;
23
+ --sp-badge-info-bg: #e0f2fe;
24
+ --sp-badge-info-text: #075985;
25
+ --sp-badge-success-bg: #dcfce7;
26
+ --sp-badge-success-text: #15803d;
27
+ --sp-badge-warning-bg: #fff1c2;
28
+ --sp-badge-warning-text: #8f5200;
29
+ --sp-badge-danger-bg: #fee2e2;
30
+ --sp-badge-danger-text: #b91c1c;
31
+ --sp-icon-box-bg: #ffffff;
32
+ --sp-icon-box-border: #d9dfeb;
33
+ --sp-icon-box-icon-default: #0369a1;
34
+ --sp-icon-box-icon-success: #16a34a;
35
+ --sp-icon-box-icon-warning: #d48806;
36
+ --sp-icon-box-icon-danger: #dc2626;
37
+ --sp-color-brand-50: #eef4ff;
38
+ --sp-color-brand-100: #d9e7ff;
39
+ --sp-color-brand-200: #b9d2ff;
40
+ --sp-color-brand-300: #8ab6ff;
41
+ --sp-color-brand-400: #5a92ff;
42
+ --sp-color-brand-500: #336df4;
43
+ --sp-color-brand-600: #1f57db;
44
+ --sp-color-brand-700: #1946b4;
45
+ --sp-color-brand-800: #173b8f;
46
+ --sp-color-brand-900: #16336f;
47
+ --sp-color-neutral-50: #f7f8fb;
48
+ --sp-color-neutral-100: #eef1f6;
49
+ --sp-color-neutral-200: #d9dfeb;
50
+ --sp-color-neutral-300: #b7c1d4;
51
+ --sp-color-neutral-400: #8a96ad;
52
+ --sp-color-neutral-500: #657287;
53
+ --sp-color-neutral-600: #4b576a;
54
+ --sp-color-neutral-700: #374253;
55
+ --sp-color-neutral-800: #222b38;
56
+ --sp-color-neutral-900: #141b24;
57
+ --sp-color-accent-50: #f6f2ff;
58
+ --sp-color-accent-100: #eee5ff;
59
+ --sp-color-accent-200: #ddccff;
60
+ --sp-color-accent-300: #c3a7ff;
61
+ --sp-color-accent-400: #a279ff;
62
+ --sp-color-accent-500: #854ff7;
63
+ --sp-color-accent-600: #7135dd;
64
+ --sp-color-accent-700: #5d28b8;
65
+ --sp-color-accent-800: #4d2393;
66
+ --sp-color-accent-900: #401f75;
67
+ --sp-color-success-50: #f0fdf4;
68
+ --sp-color-success-100: #dcfce7;
69
+ --sp-color-success-200: #bbf7d0;
70
+ --sp-color-success-300: #86efac;
71
+ --sp-color-success-400: #4ade80;
72
+ --sp-color-success-500: #22c55e;
73
+ --sp-color-success-600: #16a34a;
74
+ --sp-color-success-700: #15803d;
75
+ --sp-color-success-800: #166534;
76
+ --sp-color-success-900: #14532d;
77
+ --sp-color-warning-50: #fffbea;
78
+ --sp-color-warning-100: #fff1c2;
79
+ --sp-color-warning-200: #ffe08a;
80
+ --sp-color-warning-300: #ffd24d;
81
+ --sp-color-warning-400: #ffc21a;
82
+ --sp-color-warning-500: #f5ad00;
83
+ --sp-color-warning-600: #d48806;
84
+ --sp-color-warning-700: #ad6800;
85
+ --sp-color-warning-800: #8f5200;
86
+ --sp-color-warning-900: #734000;
87
+ --sp-color-error-50: #fef2f2;
88
+ --sp-color-error-100: #fee2e2;
89
+ --sp-color-error-200: #fecaca;
90
+ --sp-color-error-300: #fca5a5;
91
+ --sp-color-error-400: #f87171;
92
+ --sp-color-error-500: #ef4444;
93
+ --sp-color-error-600: #dc2626;
94
+ --sp-color-error-700: #b91c1c;
95
+ --sp-color-error-800: #991b1b;
96
+ --sp-color-error-900: #7f1d1d;
97
+ --sp-color-info-50: #f0f9ff;
98
+ --sp-color-info-100: #e0f2fe;
99
+ --sp-color-info-200: #bae6fd;
100
+ --sp-color-info-300: #7dd3fc;
101
+ --sp-color-info-400: #38bdf8;
102
+ --sp-color-info-500: #0ea5e9;
103
+ --sp-color-info-600: #0369a1;
104
+ --sp-color-info-700: #075985;
105
+ --sp-color-info-800: #0c4a6e;
106
+ --sp-color-info-900: #082f49;
107
+ --sp-color-indigo-500: #5b6ee1;
108
+ --sp-color-indigo-600: #4d61db;
109
+ --sp-color-violet-600: #6f3fd7;
110
+ --sp-color-focus-primary: #336df4;
111
+ --sp-color-focus-error: #ef4444;
112
+ --sp-color-focus-info: #0369a1;
113
+ --sp-color-white-0: #;
114
+ --sp-color-white-1: f;
115
+ --sp-color-white-2: f;
116
+ --sp-color-white-3: f;
117
+ --sp-color-white-4: f;
118
+ --sp-color-white-5: f;
119
+ --sp-color-white-6: f;
120
+ --sp-color-black-0: #;
121
+ --sp-color-black-1: 0;
122
+ --sp-color-black-2: 0;
123
+ --sp-color-black-3: 0;
124
+ --sp-color-black-4: 0;
125
+ --sp-color-black-5: 0;
126
+ --sp-color-black-6: 0;
127
+ --sp-space-0: 0rem;
128
+ --sp-space-4: 0.25rem;
129
+ --sp-space-8: 0.5rem;
130
+ --sp-space-12: 0.75rem;
131
+ --sp-space-16: 1rem;
132
+ --sp-space-20: 1.25rem;
133
+ --sp-space-24: 1.5rem;
134
+ --sp-space-32: 2rem;
135
+ --sp-space-40: 2.5rem;
136
+ --sp-space-48: 3rem;
137
+ --sp-space-56: 3.5rem;
138
+ --sp-space-64: 4rem;
139
+ --sp-space-80: 5rem;
140
+ --sp-space-96: 6rem;
141
+ --sp-layout-section-padding-sm: 1.5rem;
142
+ --sp-layout-section-padding-md: 2rem;
143
+ --sp-layout-section-padding-lg: 3rem;
144
+ --sp-layout-section-gap-sm: 1rem;
145
+ --sp-layout-section-gap-md: 1.5rem;
146
+ --sp-layout-section-gap-lg: 2rem;
147
+ --sp-layout-stack-gap-sm: 0.5rem;
148
+ --sp-layout-stack-gap-md: 0.75rem;
149
+ --sp-layout-stack-gap-lg: 1rem;
150
+ --sp-layout-container-padding-inline-sm: 1rem;
151
+ --sp-layout-container-padding-inline-md: 1.5rem;
152
+ --sp-layout-container-padding-inline-lg: 2rem;
153
+ --sp-layout-container-max-width: 72rem;
154
+ --sp-border-width-base: 1px;
155
+ --sp-border-width-thick: 2px;
156
+ --sp-radius-none: 0;
157
+ --sp-radius-sm: 2px;
158
+ --sp-radius-md: 4px;
159
+ --sp-radius-lg: 8px;
160
+ --sp-radius-pill: 999px;
161
+ --sp-font-family-sans: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
162
+ --sp-font-family-serif: 'Times New Roman', Times, serif;
163
+ --sp-font-family-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
164
+ --sp-font-xs-size: 0.75rem;
165
+ --sp-font-xs-line-height: 1.25rem;
166
+ --sp-font-xs-weight: 400;
167
+ --sp-font-sm-size: 0.875rem;
168
+ --sp-font-sm-line-height: 1.5rem;
169
+ --sp-font-sm-weight: 400;
170
+ --sp-font-md-size: 1rem;
171
+ --sp-font-md-line-height: 1.75rem;
172
+ --sp-font-md-weight: 500;
173
+ --sp-font-lg-size: 1.25rem;
174
+ --sp-font-lg-line-height: 2rem;
175
+ --sp-font-lg-weight: 500;
176
+ --sp-font-xl-size: 1.5rem;
177
+ --sp-font-xl-line-height: 2.125rem;
178
+ --sp-font-xl-weight: 600;
179
+ --sp-font-2xl-size: 1.875rem;
180
+ --sp-font-2xl-line-height: 2.5rem;
181
+ --sp-font-2xl-weight: 600;
182
+ --sp-font-xs-letter-spacing: 0.02em;
183
+ --sp-text-on-page-default: #141b24;
184
+ --sp-text-on-page-muted: #4b576a;
185
+ --sp-text-on-page-subtle: #657287;
186
+ --sp-text-on-page-meta: #657287;
187
+ --sp-text-on-surface-default: #141b24;
188
+ --sp-text-on-surface-muted: #4b576a;
189
+ --sp-text-on-surface-subtle: #657287;
190
+ --sp-text-on-surface-meta: #657287;
191
+ --sp-badge-neutral-bg: #eef1f6;
192
+ --sp-badge-neutral-text: #374253;
193
+ --sp-badge-info-bg: #e0f2fe;
194
+ --sp-badge-info-text: #075985;
195
+ --sp-badge-success-bg: #dcfce7;
196
+ --sp-badge-success-text: #166534;
197
+ --sp-badge-warning-bg: #fff1c2;
198
+ --sp-badge-warning-text: #8f5200;
199
+ --sp-badge-danger-bg: #fee2e2;
200
+ --sp-badge-danger-text: #991b1b;
201
+ --sp-icon-box-bg: #ffffff;
202
+ --sp-icon-box-border: #d9dfeb;
203
+ --sp-icon-box-icon-default: #0369a1;
204
+ --sp-icon-box-icon-success: #16a34a;
205
+ --sp-icon-box-icon-warning: #d48806;
206
+ --sp-icon-box-icon-danger: #dc2626;
207
+ --sp-shadow-none: none;
208
+ --sp-shadow-sm: 0 1px 2px 0 rgba(34, 43, 56, 0.06);
209
+ --sp-shadow-md: 0 2px 6px -1px rgba(34, 43, 56, 0.08);
210
+ --sp-shadow-lg: 0 6px 16px -4px rgba(34, 43, 56, 0.12);
211
+ --sp-breakpoint-sm: 640px;
212
+ --sp-breakpoint-md: 768px;
213
+ --sp-breakpoint-lg: 1024px;
214
+ --sp-breakpoint-xl: 1280px;
215
+ --sp-breakpoint-2xl: 1536px;
216
+ --sp-z-index-base: 0;
217
+ --sp-z-index-dropdown: 1000;
218
+ --sp-z-index-sticky: 1100;
219
+ --sp-z-index-fixed: 1200;
220
+ --sp-z-index-overlay: 1300;
221
+ --sp-z-index-modal: 1400;
222
+ --sp-z-index-popover: 1500;
223
+ --sp-z-index-tooltip: 1600;
224
+ --sp-duration-instant: 75ms;
225
+ --sp-duration-fast: 150ms;
226
+ --sp-duration-base: 200ms;
227
+ --sp-duration-moderate: 300ms;
228
+ --sp-duration-slow: 500ms;
229
+ --sp-duration-slower: 700ms;
230
+ --sp-easing-linear: linear;
231
+ --sp-easing-in: cubic-bezier(0.4, 0, 1, 1);
232
+ --sp-easing-out: cubic-bezier(0, 0, 0.2, 1);
233
+ --sp-easing-inout: cubic-bezier(0.4, 0, 0.2, 1);
234
+ --sp-easing-spring: cubic-bezier(0.4, 0, 0.2, 1);
235
+ --sp-opacity-disabled: 0.38;
236
+ --sp-opacity-hover: 0.92;
237
+ --sp-opacity-active: 0.84;
238
+ --sp-opacity-focus: 1;
239
+ --sp-opacity-overlay: 0.5;
240
+ --sp-opacity-tooltip: 0.95;
241
+ --sp-focus-ring-width: 2px;
242
+ --sp-focus-ring-offset: 2px;
243
+ --sp-focus-ring-style: solid;
244
+ --sp-min-touch-target: 44px;
245
+ --sp-min-text-size: 16px;
246
+ --sp-button-primary-bg: #0369a1;
247
+ --sp-button-primary-bghover: #075985;
248
+ --sp-button-primary-bgactive: #0c4a6e;
249
+ --sp-button-primary-bgdisabled: #d9dfeb;
250
+ --sp-button-primary-text: #ffffff;
251
+ --sp-button-primary-textdisabled: #8a96ad;
252
+ --sp-button-primary-focusring: rgba(14, 165, 233, 0.4);
253
+ --sp-button-secondary-bg: #ffffff;
254
+ --sp-button-secondary-bghover: #f7f8fb;
255
+ --sp-button-secondary-bgactive: #eef1f6;
256
+ --sp-button-secondary-bgdisabled: #f7f8fb;
257
+ --sp-button-secondary-text: #075985;
258
+ --sp-button-secondary-textdisabled: #8a96ad;
259
+ --sp-button-secondary-border: #075985;
260
+ --sp-button-secondary-borderdisabled: #d9dfeb;
261
+ --sp-button-secondary-focusring: rgba(14, 165, 233, 0.4);
262
+ --sp-button-ghost-bg: transparent;
263
+ --sp-button-ghost-bghover: #f0f9ff;
264
+ --sp-button-ghost-bgactive: #e0f2fe;
265
+ --sp-button-ghost-bgdisabled: transparent;
266
+ --sp-button-ghost-text: #075985;
267
+ --sp-button-ghost-textdisabled: #8a96ad;
268
+ --sp-button-ghost-focusring: rgba(14, 165, 233, 0.4);
269
+ --sp-button-danger-bg: #dc2626;
270
+ --sp-button-danger-bghover: #b91c1c;
271
+ --sp-button-danger-bgactive: #991b1b;
272
+ --sp-button-danger-bgdisabled: #fecaca;
273
+ --sp-button-danger-text: #ffffff;
274
+ --sp-button-danger-textdisabled: #8a96ad;
275
+ --sp-button-danger-focusring: rgba(239, 68, 68, 0.4);
276
+ --sp-button-success-bg: #15803d;
277
+ --sp-button-success-bghover: #166534;
278
+ --sp-button-success-bgactive: #14532d;
279
+ --sp-button-success-bgdisabled: #bbf7d0;
280
+ --sp-button-success-text: #ffffff;
281
+ --sp-button-success-textdisabled: #8a96ad;
282
+ --sp-button-success-focusring: rgba(34, 197, 94, 0.4);
283
+ --sp-button-cta-bg: #1f57db;
284
+ --sp-button-cta-bghover: #1946b4;
285
+ --sp-button-cta-bgactive: #173b8f;
286
+ --sp-button-cta-bgdisabled: #b9d2ff;
287
+ --sp-button-cta-text: #ffffff;
288
+ --sp-button-cta-textdisabled: #8a96ad;
289
+ --sp-button-cta-shadow: 0 4px 14px 0 rgba(51, 109, 244, 0.39);
290
+ --sp-button-cta-focusring: rgba(51, 109, 244, 0.4);
291
+ --sp-button-accent-bg: #7135dd;
292
+ --sp-button-accent-bghover: #5d28b8;
293
+ --sp-button-accent-bgactive: #4d2393;
294
+ --sp-button-accent-bgdisabled: #ddccff;
295
+ --sp-button-accent-text: #ffffff;
296
+ --sp-button-accent-textdisabled: #8a96ad;
297
+ --sp-button-accent-focusring: rgba(133, 79, 247, 0.4);
298
+ --sp-form-default-bg: #ffffff;
299
+ --sp-form-default-border: #b7c1d4;
300
+ --sp-form-default-text: #141b24;
301
+ --sp-form-default-placeholder: #657287;
302
+ --sp-form-hover-border: #0ea5e9;
303
+ --sp-form-focus-border: #0ea5e9;
304
+ --sp-form-focus-ring: #0ea5e9;
305
+ --sp-form-valid-border: #22c55e;
306
+ --sp-form-valid-bg: #f0fdf4;
307
+ --sp-form-valid-text: #15803d;
308
+ --sp-form-invalid-border: #ef4444;
309
+ --sp-form-invalid-bg: #fef2f2;
310
+ --sp-form-invalid-text: #b91c1c;
311
+ --sp-form-disabled-bg: #f7f8fb;
312
+ --sp-form-disabled-border: #d9dfeb;
313
+ --sp-form-disabled-text: #8a96ad;
314
+ --sp-animation-fadein-duration: 200ms;
315
+ --sp-animation-fadein-easing: cubic-bezier(0, 0, 0.2, 1);
316
+ --sp-animation-fadein-keyframes: fade-in;
317
+ --sp-animation-fadeout-duration: 150ms;
318
+ --sp-animation-fadeout-easing: cubic-bezier(0.4, 0, 1, 1);
319
+ --sp-animation-fadeout-keyframes: fade-out;
320
+ --sp-animation-slideup-duration: 300ms;
321
+ --sp-animation-slideup-easing: cubic-bezier(0, 0, 0.2, 1);
322
+ --sp-animation-slideup-keyframes: slide-up;
323
+ --sp-animation-slidedown-duration: 300ms;
324
+ --sp-animation-slidedown-easing: cubic-bezier(0, 0, 0.2, 1);
325
+ --sp-animation-slidedown-keyframes: slide-down;
326
+ --sp-animation-scalein-duration: 200ms;
327
+ --sp-animation-scalein-easing: cubic-bezier(0.34, 1.56, 0.64, 1);
328
+ --sp-animation-scalein-keyframes: scale-in;
329
+ --sp-animation-bounce-duration: 300ms;
330
+ --sp-animation-bounce-easing: cubic-bezier(0.4, 0, 0.2, 1);
331
+ --sp-animation-bounce-keyframes: bounce;
332
+ --sp-animation-shake-duration: 250ms;
333
+ --sp-animation-shake-easing: cubic-bezier(0.4, 0, 0.2, 1);
334
+ --sp-animation-shake-keyframes: shake;
335
+ --sp-animation-pulse-duration: 1200ms;
336
+ --sp-animation-pulse-easing: cubic-bezier(0.4, 0, 0.2, 1);
337
+ --sp-animation-pulse-keyframes: pulse;
338
+ }
339
+ :root[data-spectre-theme="dark"] {
340
+ --sp-surface-page: #141b24;
341
+ --sp-surface-card: #222b38;
342
+ --sp-surface-input: #374253;
343
+ --sp-surface-overlay: #222b38;
344
+ --sp-surface-hero: linear-gradient(135deg, #401f75 0%, #5d28b8 100%);
345
+ --sp-text-on-page-default: #f7f8fb;
346
+ --sp-text-on-page-muted: #b7c1d4;
347
+ --sp-text-on-page-subtle: #8a96ad;
348
+ --sp-text-on-page-meta: #8a96ad;
349
+ --sp-text-on-surface-default: #eef1f6;
350
+ --sp-text-on-surface-muted: #b7c1d4;
351
+ --sp-text-on-surface-subtle: #8a96ad;
352
+ --sp-text-on-surface-meta: #8a96ad;
353
+ --sp-component-card-text: #eef1f6;
354
+ --sp-component-card-text-muted: #b7c1d4;
355
+ --sp-component-input-text: #eef1f6;
356
+ --sp-component-input-placeholder: #b7c1d4;
357
+ --sp-button-text-default: #eef1f6;
358
+ --sp-button-text-on-primary: #ffffff;
359
+ --sp-badge-neutral-bg: #374253;
360
+ --sp-badge-neutral-text: #eef1f6;
361
+ --sp-badge-info-bg: #0c4a6e;
362
+ --sp-badge-info-text: #e0f2fe;
363
+ --sp-badge-success-bg: #166534;
364
+ --sp-badge-success-text: #dcfce7;
365
+ --sp-badge-warning-bg: #8f5200;
366
+ --sp-badge-warning-text: #fff1c2;
367
+ --sp-badge-danger-bg: #991b1b;
368
+ --sp-badge-danger-text: #fee2e2;
369
+ --sp-icon-box-bg: #222b38;
370
+ --sp-icon-box-border: #374253;
371
+ --sp-icon-box-icon-default: #7dd3fc;
372
+ --sp-icon-box-icon-success: #4ade80;
373
+ --sp-icon-box-icon-warning: #ffc21a;
374
+ --sp-icon-box-icon-danger: #f87171;
375
+ }
1
376
  @layer utilities {
2
377
  .sp-stack {
3
378
  display: flex;