@ankhorage/color-theory 0.0.1

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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/contrast.d.ts +7 -0
  4. package/dist/contrast.d.ts.map +1 -0
  5. package/dist/contrast.js +13 -0
  6. package/dist/contrast.js.map +1 -0
  7. package/dist/culori-fn.d.ts +2 -0
  8. package/dist/culori-fn.d.ts.map +1 -0
  9. package/dist/culori-fn.js +2 -0
  10. package/dist/culori-fn.js.map +1 -0
  11. package/dist/culori.d.ts +2 -0
  12. package/dist/culori.d.ts.map +1 -0
  13. package/dist/culori.js +2 -0
  14. package/dist/culori.js.map +1 -0
  15. package/dist/harmony.d.ts +20 -0
  16. package/dist/harmony.d.ts.map +1 -0
  17. package/dist/harmony.js +60 -0
  18. package/dist/harmony.js.map +1 -0
  19. package/dist/hex.d.ts +10 -0
  20. package/dist/hex.d.ts.map +1 -0
  21. package/dist/hex.js +24 -0
  22. package/dist/hex.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/internal-culori.d.ts +25 -0
  28. package/dist/internal-culori.d.ts.map +1 -0
  29. package/dist/internal-culori.js +62 -0
  30. package/dist/internal-culori.js.map +1 -0
  31. package/dist/neutral.d.ts +15 -0
  32. package/dist/neutral.d.ts.map +1 -0
  33. package/dist/neutral.js +41 -0
  34. package/dist/neutral.js.map +1 -0
  35. package/dist/semantics.d.ts +13 -0
  36. package/dist/semantics.d.ts.map +1 -0
  37. package/dist/semantics.js +31 -0
  38. package/dist/semantics.js.map +1 -0
  39. package/dist/swatches.d.ts +27 -0
  40. package/dist/swatches.d.ts.map +1 -0
  41. package/dist/swatches.js +109 -0
  42. package/dist/swatches.js.map +1 -0
  43. package/dist/theme-colors.d.ts +31 -0
  44. package/dist/theme-colors.d.ts.map +1 -0
  45. package/dist/theme-colors.js +44 -0
  46. package/dist/theme-colors.js.map +1 -0
  47. package/package.json +86 -0
  48. package/src/color-theory.test.ts +91 -0
  49. package/src/contrast.ts +22 -0
  50. package/src/culori-fn.ts +1 -0
  51. package/src/culori.ts +1 -0
  52. package/src/harmony.ts +92 -0
  53. package/src/hex.ts +29 -0
  54. package/src/index.ts +7 -0
  55. package/src/internal-culori.ts +100 -0
  56. package/src/neutral.ts +68 -0
  57. package/src/semantics.ts +60 -0
  58. package/src/swatches.ts +151 -0
  59. package/src/theme-colors.ts +77 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ankhorage
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @ankhorage/color-theory
@@ -0,0 +1,7 @@
1
+ import type { HexColor } from './hex';
2
+ export interface ReadableForegroundResult {
3
+ foreground: HexColor;
4
+ contrast: number;
5
+ }
6
+ export declare function getReadableForeground(background: HexColor): ReadableForegroundResult;
7
+ //# sourceMappingURL=contrast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contrast.d.ts","sourceRoot":"","sources":["../src/contrast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAItC,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,QAAQ,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,QAAQ,GAAG,wBAAwB,CASpF"}
@@ -0,0 +1,13 @@
1
+ import { parseHexColorOrThrow } from './hex';
2
+ import { contrastRatio } from './internal-culori';
3
+ const BLACK = parseHexColorOrThrow('#000000');
4
+ const WHITE = parseHexColorOrThrow('#FFFFFF');
5
+ export function getReadableForeground(background) {
6
+ const contrastOnBlack = contrastRatio(background, BLACK);
7
+ const contrastOnWhite = contrastRatio(background, WHITE);
8
+ if (contrastOnBlack >= contrastOnWhite) {
9
+ return { foreground: BLACK, contrast: contrastOnBlack };
10
+ }
11
+ return { foreground: WHITE, contrast: contrastOnWhite };
12
+ }
13
+ //# sourceMappingURL=contrast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contrast.js","sourceRoot":"","sources":["../src/contrast.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAOlD,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;AAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;AAE9C,MAAM,UAAU,qBAAqB,CAAC,UAAoB;IACxD,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACzD,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAEzD,IAAI,eAAe,IAAI,eAAe,EAAE,CAAC;QACvC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;AAC1D,CAAC","sourcesContent":["import type { HexColor } from './hex';\nimport { parseHexColorOrThrow } from './hex';\nimport { contrastRatio } from './internal-culori';\n\nexport interface ReadableForegroundResult {\n foreground: HexColor;\n contrast: number;\n}\n\nconst BLACK = parseHexColorOrThrow('#000000');\nconst WHITE = parseHexColorOrThrow('#FFFFFF');\n\nexport function getReadableForeground(background: HexColor): ReadableForegroundResult {\n const contrastOnBlack = contrastRatio(background, BLACK);\n const contrastOnWhite = contrastRatio(background, WHITE);\n\n if (contrastOnBlack >= contrastOnWhite) {\n return { foreground: BLACK, contrast: contrastOnBlack };\n }\n\n return { foreground: WHITE, contrast: contrastOnWhite };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from 'culori/fn';
2
+ //# sourceMappingURL=culori-fn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"culori-fn.d.ts","sourceRoot":"","sources":["../src/culori-fn.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from 'culori/fn';
2
+ //# sourceMappingURL=culori-fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"culori-fn.js","sourceRoot":"","sources":["../src/culori-fn.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC","sourcesContent":["export * from 'culori/fn';\n"]}
@@ -0,0 +1,2 @@
1
+ export * from 'culori';
2
+ //# sourceMappingURL=culori.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"culori.d.ts","sourceRoot":"","sources":["../src/culori.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
package/dist/culori.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from 'culori';
2
+ //# sourceMappingURL=culori.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"culori.js","sourceRoot":"","sources":["../src/culori.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC","sourcesContent":["export * from 'culori';\n"]}
@@ -0,0 +1,20 @@
1
+ import type { HexColor } from './hex';
2
+ export declare const COLOR_HARMONIES: readonly ["monochromatic", "analogous", "complementary", "triadic", "tetradic", "splitComplementary"];
3
+ export type ColorHarmony = (typeof COLOR_HARMONIES)[number];
4
+ export type GeneratedColorRole = 'primary' | 'secondary' | 'tertiary' | 'quaternary';
5
+ export interface GeneratedHarmonyRoleColor {
6
+ role: GeneratedColorRole;
7
+ hex: HexColor;
8
+ hueDegrees: number;
9
+ source: 'selected' | 'generated';
10
+ }
11
+ export interface GeneratedHarmonyRoleColors {
12
+ harmony: ColorHarmony;
13
+ colors: readonly GeneratedHarmonyRoleColor[];
14
+ primary: GeneratedHarmonyRoleColor;
15
+ secondary?: GeneratedHarmonyRoleColor;
16
+ tertiary?: GeneratedHarmonyRoleColor;
17
+ quaternary?: GeneratedHarmonyRoleColor;
18
+ }
19
+ export declare function generateHarmonyRoleColors(primaryColor: HexColor, harmony: ColorHarmony): GeneratedHarmonyRoleColors;
20
+ //# sourceMappingURL=harmony.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harmony.d.ts","sourceRoot":"","sources":["../src/harmony.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtC,eAAO,MAAM,eAAe,uGAOlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,kBAAkB,CAAC;IACzB,GAAG,EAAE,QAAQ,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC7C,OAAO,EAAE,yBAAyB,CAAC;IACnC,SAAS,CAAC,EAAE,yBAAyB,CAAC;IACtC,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,UAAU,CAAC,EAAE,yBAAyB,CAAC;CACxC;AAoBD,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,QAAQ,EACtB,OAAO,EAAE,YAAY,GACpB,0BAA0B,CAsC5B"}
@@ -0,0 +1,60 @@
1
+ import { normalizeHueDegrees, oklchToHex, parseHexToOklch } from './internal-culori';
2
+ export const COLOR_HARMONIES = [
3
+ 'monochromatic',
4
+ 'analogous',
5
+ 'complementary',
6
+ 'triadic',
7
+ 'tetradic',
8
+ 'splitComplementary',
9
+ ];
10
+ const ROLE_ORDER_BY_HARMONY = {
11
+ monochromatic: ['primary'],
12
+ complementary: ['primary', 'secondary'],
13
+ analogous: ['primary', 'secondary', 'tertiary'],
14
+ splitComplementary: ['primary', 'secondary', 'tertiary'],
15
+ triadic: ['primary', 'secondary', 'tertiary'],
16
+ tetradic: ['primary', 'secondary', 'tertiary', 'quaternary'],
17
+ };
18
+ const OFFSETS_BY_HARMONY = {
19
+ monochromatic: [0],
20
+ analogous: [0, -30, 30],
21
+ complementary: [0, 180],
22
+ splitComplementary: [0, 150, 210],
23
+ triadic: [0, 120, 240],
24
+ tetradic: [0, 90, 180, 270],
25
+ };
26
+ export function generateHarmonyRoleColors(primaryColor, harmony) {
27
+ const base = parseHexToOklch(primaryColor);
28
+ const roles = ROLE_ORDER_BY_HARMONY[harmony];
29
+ const offsets = OFFSETS_BY_HARMONY[harmony];
30
+ const baseHue = normalizeHueDegrees(base.h);
31
+ const colors = [];
32
+ for (let index = 0; index < roles.length; index++) {
33
+ const role = roles[index];
34
+ if (!role)
35
+ continue;
36
+ const hueDegrees = normalizeHueDegrees(baseHue + (offsets[index] ?? 0));
37
+ colors.push({
38
+ role,
39
+ hex: role === 'primary' ? primaryColor : oklchToHex({ ...base, h: hueDegrees }),
40
+ hueDegrees,
41
+ source: role === 'primary' ? 'selected' : 'generated',
42
+ });
43
+ }
44
+ const primary = colors.find((color) => color.role === 'primary');
45
+ if (!primary) {
46
+ throw new Error('[color-theory] Expected generated harmony role colors to include primary.');
47
+ }
48
+ const secondary = colors.find((color) => color.role === 'secondary');
49
+ const tertiary = colors.find((color) => color.role === 'tertiary');
50
+ const quaternary = colors.find((color) => color.role === 'quaternary');
51
+ return {
52
+ harmony,
53
+ colors,
54
+ primary,
55
+ ...(secondary ? { secondary } : {}),
56
+ ...(tertiary ? { tertiary } : {}),
57
+ ...(quaternary ? { quaternary } : {}),
58
+ };
59
+ }
60
+ //# sourceMappingURL=harmony.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harmony.js","sourceRoot":"","sources":["../src/harmony.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HexColor } from './hex';\nimport { normalizeHueDegrees, oklchToHex, parseHexToOklch } from './internal-culori';\n\nexport const COLOR_HARMONIES = [\n 'monochromatic',\n 'analogous',\n 'complementary',\n 'triadic',\n 'tetradic',\n 'splitComplementary',\n] as const;\n\nexport type ColorHarmony = (typeof COLOR_HARMONIES)[number];\n\nexport type GeneratedColorRole = 'primary' | 'secondary' | 'tertiary' | 'quaternary';\n\nexport interface GeneratedHarmonyRoleColor {\n role: GeneratedColorRole;\n hex: HexColor;\n hueDegrees: number;\n source: 'selected' | 'generated';\n}\n\nexport interface GeneratedHarmonyRoleColors {\n harmony: ColorHarmony;\n colors: readonly GeneratedHarmonyRoleColor[];\n primary: GeneratedHarmonyRoleColor;\n secondary?: GeneratedHarmonyRoleColor;\n tertiary?: GeneratedHarmonyRoleColor;\n quaternary?: GeneratedHarmonyRoleColor;\n}\n\nconst ROLE_ORDER_BY_HARMONY: Record<ColorHarmony, readonly GeneratedColorRole[]> = {\n monochromatic: ['primary'],\n complementary: ['primary', 'secondary'],\n analogous: ['primary', 'secondary', 'tertiary'],\n splitComplementary: ['primary', 'secondary', 'tertiary'],\n triadic: ['primary', 'secondary', 'tertiary'],\n tetradic: ['primary', 'secondary', 'tertiary', 'quaternary'],\n};\n\nconst OFFSETS_BY_HARMONY: Record<ColorHarmony, readonly number[]> = {\n monochromatic: [0],\n analogous: [0, -30, 30],\n complementary: [0, 180],\n splitComplementary: [0, 150, 210],\n triadic: [0, 120, 240],\n tetradic: [0, 90, 180, 270],\n};\n\nexport function generateHarmonyRoleColors(\n primaryColor: HexColor,\n harmony: ColorHarmony,\n): GeneratedHarmonyRoleColors {\n const base = parseHexToOklch(primaryColor);\n const roles = ROLE_ORDER_BY_HARMONY[harmony];\n const offsets = OFFSETS_BY_HARMONY[harmony];\n const baseHue = normalizeHueDegrees(base.h);\n\n const colors: GeneratedHarmonyRoleColor[] = [];\n\n for (let index = 0; index < roles.length; index++) {\n const role = roles[index];\n if (!role) continue;\n\n const hueDegrees = normalizeHueDegrees(baseHue + (offsets[index] ?? 0));\n colors.push({\n role,\n hex: role === 'primary' ? primaryColor : oklchToHex({ ...base, h: hueDegrees }),\n hueDegrees,\n source: role === 'primary' ? 'selected' : 'generated',\n });\n }\n\n const primary = colors.find((color) => color.role === 'primary');\n if (!primary) {\n throw new Error('[color-theory] Expected generated harmony role colors to include primary.');\n }\n\n const secondary = colors.find((color) => color.role === 'secondary');\n const tertiary = colors.find((color) => color.role === 'tertiary');\n const quaternary = colors.find((color) => color.role === 'quaternary');\n\n return {\n harmony,\n colors,\n primary,\n ...(secondary ? { secondary } : {}),\n ...(tertiary ? { tertiary } : {}),\n ...(quaternary ? { quaternary } : {}),\n };\n}\n"]}
package/dist/hex.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export type HexColor = string & {
2
+ readonly __hexColorBrand: unique symbol;
3
+ };
4
+ export declare function isHexColor(value: string): value is HexColor;
5
+ export declare function parseHexColor(value: string): HexColor | null;
6
+ export declare function parseHexColorOrThrow(value: string): HexColor;
7
+ export declare const normalizeHexColor: typeof parseHexColor;
8
+ export declare const normalizeHexColorOrThrow: typeof parseHexColorOrThrow;
9
+ export declare function assertHexColor(value: string): asserts value is HexColor;
10
+ //# sourceMappingURL=hex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../src/hex.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,eAAe,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAI5E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAE3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAG5D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAM5D;AAED,eAAO,MAAM,iBAAiB,sBAAgB,CAAC;AAC/C,eAAO,MAAM,wBAAwB,6BAAuB,CAAC;AAE7D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAIvE"}
package/dist/hex.js ADDED
@@ -0,0 +1,24 @@
1
+ const HEX6_CASE_INSENSITIVE_REGEX = /^#[0-9a-fA-F]{6}$/;
2
+ export function isHexColor(value) {
3
+ return HEX6_CASE_INSENSITIVE_REGEX.test(value);
4
+ }
5
+ export function parseHexColor(value) {
6
+ if (!HEX6_CASE_INSENSITIVE_REGEX.test(value))
7
+ return null;
8
+ return value;
9
+ }
10
+ export function parseHexColorOrThrow(value) {
11
+ const parsed = parseHexColor(value);
12
+ if (!parsed) {
13
+ throw new Error(`Invalid hex color (expected #RRGGBB or #rrggbb): ${JSON.stringify(value)}`);
14
+ }
15
+ return parsed;
16
+ }
17
+ export const normalizeHexColor = parseHexColor;
18
+ export const normalizeHexColorOrThrow = parseHexColorOrThrow;
19
+ export function assertHexColor(value) {
20
+ if (!isHexColor(value)) {
21
+ throw new Error(`Invalid hex color (expected #RRGGBB or #rrggbb): ${JSON.stringify(value)}`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=hex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hex.js","sourceRoot":"","sources":["../src/hex.ts"],"names":[],"mappings":"AAEA,MAAM,2BAA2B,GAAG,mBAAmB,CAAC;AAExD,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,KAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAC/C,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAE7D,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC","sourcesContent":["export type HexColor = string & { readonly __hexColorBrand: unique symbol };\n\nconst HEX6_CASE_INSENSITIVE_REGEX = /^#[0-9a-fA-F]{6}$/;\n\nexport function isHexColor(value: string): value is HexColor {\n return HEX6_CASE_INSENSITIVE_REGEX.test(value);\n}\n\nexport function parseHexColor(value: string): HexColor | null {\n if (!HEX6_CASE_INSENSITIVE_REGEX.test(value)) return null;\n return value as HexColor;\n}\n\nexport function parseHexColorOrThrow(value: string): HexColor {\n const parsed = parseHexColor(value);\n if (!parsed) {\n throw new Error(`Invalid hex color (expected #RRGGBB or #rrggbb): ${JSON.stringify(value)}`);\n }\n return parsed;\n}\n\nexport const normalizeHexColor = parseHexColor;\nexport const normalizeHexColorOrThrow = parseHexColorOrThrow;\n\nexport function assertHexColor(value: string): asserts value is HexColor {\n if (!isHexColor(value)) {\n throw new Error(`Invalid hex color (expected #RRGGBB or #rrggbb): ${JSON.stringify(value)}`);\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export * from './contrast';
2
+ export * from './harmony';
3
+ export * from './hex';
4
+ export * from './neutral';
5
+ export * from './semantics';
6
+ export * from './swatches';
7
+ export * from './theme-colors';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './contrast';
2
+ export * from './harmony';
3
+ export * from './hex';
4
+ export * from './neutral';
5
+ export * from './semantics';
6
+ export * from './swatches';
7
+ export * from './theme-colors';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './contrast';\nexport * from './harmony';\nexport * from './hex';\nexport * from './neutral';\nexport * from './semantics';\nexport * from './swatches';\nexport * from './theme-colors';\n"]}
@@ -0,0 +1,25 @@
1
+ import type { HexColor } from './hex';
2
+ export interface OklchColor {
3
+ mode: 'oklch';
4
+ l: number;
5
+ c: number;
6
+ h: number;
7
+ alpha?: number;
8
+ }
9
+ export interface RgbColor {
10
+ mode: 'rgb';
11
+ r: number;
12
+ g: number;
13
+ b: number;
14
+ alpha?: number;
15
+ }
16
+ export declare function normalizeHueDegrees(hueDegrees: number): number;
17
+ export declare function parseHexToOklch(hex: HexColor): OklchColor;
18
+ export declare function oklchToHex(oklch: OklchColor): HexColor;
19
+ export declare function toOklchColor(input: string | object): OklchColor;
20
+ export declare function toHexColor(input: string | object): HexColor;
21
+ export declare function deltaEoklch(a: OklchColor, b: OklchColor): number;
22
+ export declare function contrastRatio(colorA: string | object, colorB: string | object): number;
23
+ export declare function relativeLuminance(color: string | object): number;
24
+ export declare function rgbFrom(input: string | object): RgbColor;
25
+ //# sourceMappingURL=internal-culori.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-culori.d.ts","sourceRoot":"","sources":["../src/internal-culori.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,UAAU,CAWzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAItD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAW/D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAI3D;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAEhE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEtF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAMxD"}
@@ -0,0 +1,62 @@
1
+ import { converter, differenceEuclidean, formatHex, toGamut, wcagContrast, wcagLuminance, } from 'culori';
2
+ import { parseHexColorOrThrow } from './hex';
3
+ const toOklch = converter('oklch');
4
+ const toRgb = converter('rgb');
5
+ const toRgbGamut = toGamut('rgb', 'oklch');
6
+ const deltaE = differenceEuclidean('oklch');
7
+ function clampNumber(value, min, max) {
8
+ if (!Number.isFinite(value))
9
+ return min;
10
+ return Math.min(max, Math.max(min, value));
11
+ }
12
+ export function normalizeHueDegrees(hueDegrees) {
13
+ const hue = ((hueDegrees % 360) + 360) % 360;
14
+ return hue === 360 ? 0 : hue;
15
+ }
16
+ export function parseHexToOklch(hex) {
17
+ const color = toOklch(hex);
18
+ if (color?.mode !== 'oklch') {
19
+ throw new Error(`Failed to convert hex to OKLCH: ${hex}`);
20
+ }
21
+ const l = clampNumber(color.l, 0, 1);
22
+ const c = clampNumber(color.c, 0, 0.4);
23
+ const h = normalizeHueDegrees(Number.isFinite(color.h) ? color.h : 0);
24
+ return { mode: 'oklch', l, c, h, alpha: color.alpha };
25
+ }
26
+ export function oklchToHex(oklch) {
27
+ const gamutRgb = toRgbGamut(oklch);
28
+ const hex = formatHex(gamutRgb ?? oklch);
29
+ return parseHexColorOrThrow(hex);
30
+ }
31
+ export function toOklchColor(input) {
32
+ const color = toOklch(input);
33
+ if (color?.mode !== 'oklch') {
34
+ throw new Error(`Failed to parse/convert to OKLCH: ${JSON.stringify(input)}`);
35
+ }
36
+ const l = clampNumber(color.l, 0, 1);
37
+ const c = clampNumber(color.c, 0, 0.4);
38
+ const h = normalizeHueDegrees(Number.isFinite(color.h) ? color.h : 0);
39
+ return { mode: 'oklch', l, c, h, alpha: color.alpha };
40
+ }
41
+ export function toHexColor(input) {
42
+ const gamutRgb = toRgbGamut(input);
43
+ const hex = formatHex(gamutRgb ?? input);
44
+ return parseHexColorOrThrow(hex);
45
+ }
46
+ export function deltaEoklch(a, b) {
47
+ return deltaE(a, b);
48
+ }
49
+ export function contrastRatio(colorA, colorB) {
50
+ return wcagContrast(colorA, colorB);
51
+ }
52
+ export function relativeLuminance(color) {
53
+ return wcagLuminance(color);
54
+ }
55
+ export function rgbFrom(input) {
56
+ const rgb = toRgb(input);
57
+ if (rgb?.mode !== 'rgb') {
58
+ throw new Error(`Failed to convert to rgb: ${JSON.stringify(input)}`);
59
+ }
60
+ return rgb;
61
+ }
62
+ //# sourceMappingURL=internal-culori.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-culori.js","sourceRoot":"","sources":["../src/internal-culori.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n converter,\n differenceEuclidean,\n formatHex,\n toGamut,\n wcagContrast,\n wcagLuminance,\n} from 'culori';\n\nimport type { HexColor } from './hex';\nimport { parseHexColorOrThrow } from './hex';\n\nexport interface OklchColor {\n mode: 'oklch';\n l: number;\n c: number;\n h: number;\n alpha?: number;\n}\n\nexport interface RgbColor {\n mode: 'rgb';\n r: number;\n g: number;\n b: number;\n alpha?: number;\n}\n\nconst toOklch = converter('oklch');\nconst toRgb = converter('rgb');\nconst toRgbGamut = toGamut('rgb', 'oklch');\nconst deltaE = differenceEuclidean('oklch');\n\nfunction clampNumber(value: number, min: number, max: number): number {\n if (!Number.isFinite(value)) return min;\n return Math.min(max, Math.max(min, value));\n}\n\nexport function normalizeHueDegrees(hueDegrees: number): number {\n const hue = ((hueDegrees % 360) + 360) % 360;\n return hue === 360 ? 0 : hue;\n}\n\nexport function parseHexToOklch(hex: HexColor): OklchColor {\n const color = toOklch(hex) as unknown as OklchColor | undefined;\n if (color?.mode !== 'oklch') {\n throw new Error(`Failed to convert hex to OKLCH: ${hex}`);\n }\n\n const l = clampNumber(color.l, 0, 1);\n const c = clampNumber(color.c, 0, 0.4);\n const h = normalizeHueDegrees(Number.isFinite(color.h) ? color.h : 0);\n\n return { mode: 'oklch', l, c, h, alpha: color.alpha };\n}\n\nexport function oklchToHex(oklch: OklchColor): HexColor {\n const gamutRgb = toRgbGamut(oklch) as unknown as RgbColor | undefined;\n const hex = formatHex(gamutRgb ?? oklch);\n return parseHexColorOrThrow(hex);\n}\n\nexport function toOklchColor(input: string | object): OklchColor {\n const color = toOklch(input as never) as unknown as OklchColor | undefined;\n if (color?.mode !== 'oklch') {\n throw new Error(`Failed to parse/convert to OKLCH: ${JSON.stringify(input)}`);\n }\n\n const l = clampNumber(color.l, 0, 1);\n const c = clampNumber(color.c, 0, 0.4);\n const h = normalizeHueDegrees(Number.isFinite(color.h) ? color.h : 0);\n\n return { mode: 'oklch', l, c, h, alpha: color.alpha };\n}\n\nexport function toHexColor(input: string | object): HexColor {\n const gamutRgb = toRgbGamut(input as never) as unknown as RgbColor | undefined;\n const hex = formatHex(gamutRgb ?? (input as never));\n return parseHexColorOrThrow(hex);\n}\n\nexport function deltaEoklch(a: OklchColor, b: OklchColor): number {\n return deltaE(a, b);\n}\n\nexport function contrastRatio(colorA: string | object, colorB: string | object): number {\n return wcagContrast(colorA as never, colorB as never);\n}\n\nexport function relativeLuminance(color: string | object): number {\n return wcagLuminance(color as never);\n}\n\nexport function rgbFrom(input: string | object): RgbColor {\n const rgb = toRgb(input as never) as unknown as RgbColor | undefined;\n if (rgb?.mode !== 'rgb') {\n throw new Error(`Failed to convert to rgb: ${JSON.stringify(input)}`);\n }\n return rgb;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { GeneratedHarmonyRoleColors } from './harmony';
2
+ import type { HexColor } from './hex';
3
+ import { type ColorSwatch, type ColorSwatchDiagnostics } from './swatches';
4
+ export declare const MIN_HUEFUL_CHROMA = 0.015;
5
+ export interface NeutralSwatchResult {
6
+ neutralKeyColor: HexColor;
7
+ neutral: ColorSwatch;
8
+ diagnostics: ColorSwatchDiagnostics;
9
+ }
10
+ export interface GeneratedNeutralMetadata {
11
+ neutralKeyColor: HexColor;
12
+ diagnostics: ColorSwatchDiagnostics;
13
+ }
14
+ export declare function generateNeutralSwatch(roleColors: GeneratedHarmonyRoleColors): NeutralSwatchResult;
15
+ //# sourceMappingURL=neutral.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neutral.d.ts","sourceRoot":"","sources":["../src/neutral.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,sBAAsB,EAAuB,MAAM,YAAY,CAAC;AAEhG,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,QAAQ,CAAC;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,QAAQ,CAAC;IAC1B,WAAW,EAAE,sBAAsB,CAAC;CACrC;AA4BD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,0BAA0B,GAAG,mBAAmB,CAuBjG"}
@@ -0,0 +1,41 @@
1
+ import { normalizeHueDegrees, oklchToHex, parseHexToOklch } from './internal-culori';
2
+ import { generateColorSwatch } from './swatches';
3
+ export const MIN_HUEFUL_CHROMA = 0.015;
4
+ function pickTintSourceHex(roleColors, harmony) {
5
+ const byMapping = {
6
+ monochromatic: roleColors.primary.hex,
7
+ complementary: roleColors.secondary?.hex,
8
+ analogous: roleColors.tertiary?.hex,
9
+ splitComplementary: roleColors.tertiary?.hex,
10
+ triadic: roleColors.tertiary?.hex,
11
+ tetradic: roleColors.tertiary?.hex,
12
+ };
13
+ return (byMapping[harmony] ??
14
+ roleColors.tertiary?.hex ??
15
+ roleColors.secondary?.hex ??
16
+ roleColors.primary.hex);
17
+ }
18
+ function clampNumber(value, min, max) {
19
+ if (!Number.isFinite(value))
20
+ return min;
21
+ return Math.min(max, Math.max(min, value));
22
+ }
23
+ export function generateNeutralSwatch(roleColors) {
24
+ const tintSourceHex = pickTintSourceHex(roleColors, roleColors.harmony);
25
+ const tintSource = parseHexToOklch(tintSourceHex);
26
+ const primary = parseHexToOklch(roleColors.primary.hex);
27
+ const preferGray = tintSource.c < MIN_HUEFUL_CHROMA;
28
+ const hue = roleColors.harmony === 'monochromatic' ? primary.h : tintSource.h;
29
+ const sourceChroma = roleColors.harmony === 'monochromatic' ? primary.c : tintSource.c;
30
+ const neutralHue = preferGray ? 0 : normalizeHueDegrees(hue);
31
+ const neutralChroma = preferGray ? 0 : clampNumber(sourceChroma * 0.06, 0.004, 0.012);
32
+ const neutralKeyColor = oklchToHex({
33
+ mode: 'oklch',
34
+ l: 0.6,
35
+ c: neutralChroma,
36
+ h: neutralHue,
37
+ });
38
+ const { swatch, diagnostics } = generateColorSwatch(neutralKeyColor);
39
+ return { neutralKeyColor, neutral: swatch, diagnostics };
40
+ }
41
+ //# sourceMappingURL=neutral.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neutral.js","sourceRoot":"","sources":["../src/neutral.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAiD,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhG,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAavC,SAAS,iBAAiB,CACxB,UAAsC,EACtC,OAAqB;IAErB,MAAM,SAAS,GAAwD;QACrE,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG;QACrC,aAAa,EAAE,UAAU,CAAC,SAAS,EAAE,GAAG;QACxC,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG;QACnC,kBAAkB,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG;QAC5C,OAAO,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG;QACjC,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,GAAG;KACnC,CAAC;IAEF,OAAO,CACL,SAAS,CAAC,OAAO,CAAC;QAClB,UAAU,CAAC,QAAQ,EAAE,GAAG;QACxB,UAAU,CAAC,SAAS,EAAE,GAAG;QACzB,UAAU,CAAC,OAAO,CAAC,GAAG,CACvB,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAsC;IAC1E,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAElD,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAExD,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,GAAG,iBAAiB,CAAC;IAEpD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACvF,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEtF,MAAM,eAAe,GAAG,UAAU,CAAC;QACjC,IAAI,EAAE,OAAO;QACb,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,aAAa;QAChB,CAAC,EAAE,UAAU;KACd,CAAC,CAAC;IAEH,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IAErE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC3D,CAAC","sourcesContent":["import type { ColorHarmony, GeneratedHarmonyRoleColors } from './harmony';\nimport type { HexColor } from './hex';\nimport { normalizeHueDegrees, oklchToHex, parseHexToOklch } from './internal-culori';\nimport { type ColorSwatch, type ColorSwatchDiagnostics, generateColorSwatch } from './swatches';\n\nexport const MIN_HUEFUL_CHROMA = 0.015;\n\nexport interface NeutralSwatchResult {\n neutralKeyColor: HexColor;\n neutral: ColorSwatch;\n diagnostics: ColorSwatchDiagnostics;\n}\n\nexport interface GeneratedNeutralMetadata {\n neutralKeyColor: HexColor;\n diagnostics: ColorSwatchDiagnostics;\n}\n\nfunction pickTintSourceHex(\n roleColors: GeneratedHarmonyRoleColors,\n harmony: ColorHarmony,\n): HexColor {\n const byMapping: Partial<Record<ColorHarmony, HexColor | undefined>> = {\n monochromatic: roleColors.primary.hex,\n complementary: roleColors.secondary?.hex,\n analogous: roleColors.tertiary?.hex,\n splitComplementary: roleColors.tertiary?.hex,\n triadic: roleColors.tertiary?.hex,\n tetradic: roleColors.tertiary?.hex,\n };\n\n return (\n byMapping[harmony] ??\n roleColors.tertiary?.hex ??\n roleColors.secondary?.hex ??\n roleColors.primary.hex\n );\n}\n\nfunction clampNumber(value: number, min: number, max: number): number {\n if (!Number.isFinite(value)) return min;\n return Math.min(max, Math.max(min, value));\n}\n\nexport function generateNeutralSwatch(roleColors: GeneratedHarmonyRoleColors): NeutralSwatchResult {\n const tintSourceHex = pickTintSourceHex(roleColors, roleColors.harmony);\n const tintSource = parseHexToOklch(tintSourceHex);\n\n const primary = parseHexToOklch(roleColors.primary.hex);\n\n const preferGray = tintSource.c < MIN_HUEFUL_CHROMA;\n\n const hue = roleColors.harmony === 'monochromatic' ? primary.h : tintSource.h;\n const sourceChroma = roleColors.harmony === 'monochromatic' ? primary.c : tintSource.c;\n const neutralHue = preferGray ? 0 : normalizeHueDegrees(hue);\n const neutralChroma = preferGray ? 0 : clampNumber(sourceChroma * 0.06, 0.004, 0.012);\n\n const neutralKeyColor = oklchToHex({\n mode: 'oklch',\n l: 0.6,\n c: neutralChroma,\n h: neutralHue,\n });\n\n const { swatch, diagnostics } = generateColorSwatch(neutralKeyColor);\n\n return { neutralKeyColor, neutral: swatch, diagnostics };\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { GeneratedColorRole } from './harmony';
2
+ import type { ColorSwatchStep } from './swatches';
3
+ export type ThemeColorMode = 'light' | 'dark';
4
+ export type SemanticColorToken = 'background' | 'surface' | 'surfaceRaised' | 'border' | 'divider' | 'text' | 'textMuted' | 'disabledBg' | 'disabledText' | 'brand' | 'brandEmphasis' | 'action' | 'actionEmphasis';
5
+ export type SemanticColorRole = 'neutral' | GeneratedColorRole;
6
+ export interface SemanticColorReference {
7
+ role: SemanticColorRole;
8
+ step: ColorSwatchStep;
9
+ }
10
+ export type SemanticColorReferenceMap = Record<SemanticColorToken, SemanticColorReference>;
11
+ export declare const LIGHT_SEMANTIC_COLOR_REFERENCES: SemanticColorReferenceMap;
12
+ export declare const DARK_SEMANTIC_COLOR_REFERENCES: SemanticColorReferenceMap;
13
+ //# sourceMappingURL=semantics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAC1B,YAAY,GACZ,SAAS,GACT,eAAe,GACf,QAAQ,GACR,SAAS,GACT,MAAM,GACN,WAAW,GACX,YAAY,GACZ,cAAc,GACd,OAAO,GACP,eAAe,GACf,QAAQ,GACR,gBAAgB,CAAC;AAErB,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,kBAAkB,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AAE3F,eAAO,MAAM,+BAA+B,EAAE,yBAc7C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,yBAc5C,CAAC"}
@@ -0,0 +1,31 @@
1
+ export const LIGHT_SEMANTIC_COLOR_REFERENCES = {
2
+ background: { role: 'neutral', step: 50 },
3
+ surface: { role: 'neutral', step: 100 },
4
+ surfaceRaised: { role: 'neutral', step: 50 },
5
+ border: { role: 'neutral', step: 200 },
6
+ divider: { role: 'neutral', step: 200 },
7
+ text: { role: 'neutral', step: 900 },
8
+ textMuted: { role: 'neutral', step: 700 },
9
+ disabledBg: { role: 'neutral', step: 200 },
10
+ disabledText: { role: 'neutral', step: 500 },
11
+ brand: { role: 'primary', step: 600 },
12
+ brandEmphasis: { role: 'primary', step: 700 },
13
+ action: { role: 'primary', step: 600 },
14
+ actionEmphasis: { role: 'primary', step: 700 },
15
+ };
16
+ export const DARK_SEMANTIC_COLOR_REFERENCES = {
17
+ background: { role: 'neutral', step: 950 },
18
+ surface: { role: 'neutral', step: 900 },
19
+ surfaceRaised: { role: 'neutral', step: 900 },
20
+ border: { role: 'neutral', step: 800 },
21
+ divider: { role: 'neutral', step: 800 },
22
+ text: { role: 'neutral', step: 50 },
23
+ textMuted: { role: 'neutral', step: 200 },
24
+ disabledBg: { role: 'neutral', step: 800 },
25
+ disabledText: { role: 'neutral', step: 500 },
26
+ brand: { role: 'primary', step: 400 },
27
+ brandEmphasis: { role: 'primary', step: 300 },
28
+ action: { role: 'primary', step: 400 },
29
+ actionEmphasis: { role: 'primary', step: 300 },
30
+ };
31
+ //# sourceMappingURL=semantics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantics.js","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AA6BA,MAAM,CAAC,MAAM,+BAA+B,GAA8B;IACxE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACvC,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;IAC5C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACtC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACvC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACpC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACzC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC1C,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACrC,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC7C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACtC,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;CAC/C,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAA8B;IACvE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC1C,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACvC,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC7C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACtC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACvC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;IACnC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACzC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC1C,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACrC,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IAC7C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;IACtC,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE;CAC/C,CAAC","sourcesContent":["import type { GeneratedColorRole } from './harmony';\nimport type { ColorSwatchStep } from './swatches';\n\nexport type ThemeColorMode = 'light' | 'dark';\n\nexport type SemanticColorToken =\n | 'background'\n | 'surface'\n | 'surfaceRaised'\n | 'border'\n | 'divider'\n | 'text'\n | 'textMuted'\n | 'disabledBg'\n | 'disabledText'\n | 'brand'\n | 'brandEmphasis'\n | 'action'\n | 'actionEmphasis';\n\nexport type SemanticColorRole = 'neutral' | GeneratedColorRole;\n\nexport interface SemanticColorReference {\n role: SemanticColorRole;\n step: ColorSwatchStep;\n}\n\nexport type SemanticColorReferenceMap = Record<SemanticColorToken, SemanticColorReference>;\n\nexport const LIGHT_SEMANTIC_COLOR_REFERENCES: SemanticColorReferenceMap = {\n background: { role: 'neutral', step: 50 },\n surface: { role: 'neutral', step: 100 },\n surfaceRaised: { role: 'neutral', step: 50 },\n border: { role: 'neutral', step: 200 },\n divider: { role: 'neutral', step: 200 },\n text: { role: 'neutral', step: 900 },\n textMuted: { role: 'neutral', step: 700 },\n disabledBg: { role: 'neutral', step: 200 },\n disabledText: { role: 'neutral', step: 500 },\n brand: { role: 'primary', step: 600 },\n brandEmphasis: { role: 'primary', step: 700 },\n action: { role: 'primary', step: 600 },\n actionEmphasis: { role: 'primary', step: 700 },\n};\n\nexport const DARK_SEMANTIC_COLOR_REFERENCES: SemanticColorReferenceMap = {\n background: { role: 'neutral', step: 950 },\n surface: { role: 'neutral', step: 900 },\n surfaceRaised: { role: 'neutral', step: 900 },\n border: { role: 'neutral', step: 800 },\n divider: { role: 'neutral', step: 800 },\n text: { role: 'neutral', step: 50 },\n textMuted: { role: 'neutral', step: 200 },\n disabledBg: { role: 'neutral', step: 800 },\n disabledText: { role: 'neutral', step: 500 },\n brand: { role: 'primary', step: 400 },\n brandEmphasis: { role: 'primary', step: 300 },\n action: { role: 'primary', step: 400 },\n actionEmphasis: { role: 'primary', step: 300 },\n};\n"]}
@@ -0,0 +1,27 @@
1
+ import type { HexColor } from './hex';
2
+ export declare const COLOR_SWATCH_STEPS: readonly [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
3
+ export type ColorSwatchStep = (typeof COLOR_SWATCH_STEPS)[number];
4
+ export declare const COLOR_SWATCH_BASE_STEP: 500;
5
+ export type ColorSwatch = Record<ColorSwatchStep, HexColor>;
6
+ export type ColorSwatchWarningCode = 'weak_step' | 'weak_adjacent_delta' | 'limited_lightness_range';
7
+ export interface ColorSwatchWarning {
8
+ code: ColorSwatchWarningCode;
9
+ step?: ColorSwatchStep;
10
+ message: string;
11
+ deltaEFromBase?: number;
12
+ }
13
+ export interface ColorSwatchDiagnostics {
14
+ isUsable: boolean;
15
+ warnings: readonly ColorSwatchWarning[];
16
+ minAdjacentDelta: number;
17
+ maxAdjacentDelta: number;
18
+ lightnessRange: {
19
+ min: number;
20
+ max: number;
21
+ };
22
+ }
23
+ export declare function generateColorSwatch(baseColor: HexColor): {
24
+ swatch: ColorSwatch;
25
+ diagnostics: ColorSwatchDiagnostics;
26
+ };
27
+ //# sourceMappingURL=swatches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swatches.d.ts","sourceRoot":"","sources":["../src/swatches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGtC,eAAO,MAAM,kBAAkB,iEAAkE,CAAC;AAClG,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,eAAO,MAAM,sBAAsB,EAAG,GAAY,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAE5D,MAAM,MAAM,sBAAsB,GAC9B,WAAW,GACX,qBAAqB,GACrB,yBAAyB,CAAC;AAE9B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAgCD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,QAAQ,GAAG;IACxD,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,sBAAsB,CAAC;CACrC,CAoFA"}