@ankhorage/surface 0.1.11 โ†’ 0.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ankhorage/surface
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d9c21be: Updates theme configuration to use `colorTone` / `ColorTone` from `@ankhorage/contracts` and aligns internal color-engine naming.
8
+
9
+ ## 0.1.12
10
+
11
+ ### Patch Changes
12
+
13
+ - 173d938: Export @types/culori as a regular dependency
14
+
3
15
  ## 0.1.11
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -3,33 +3,39 @@
3
3
  A minimal design foundation for React Native and React Native Web.
4
4
 
5
5
  ## ๐ŸŽฏ What you get
6
+
6
7
  - Predictable layout system
7
8
  - Theme-driven styling
8
9
  - Cross-platform consistency
9
10
 
10
11
  ## โœจ Features
12
+
11
13
  - Token-based theming
12
14
  - Layout primitives
13
15
  - Responsive utilities
14
16
 
15
17
  ## ๐Ÿš€ Installation
18
+
16
19
  ```bash
17
20
  bun add @ankhorage/surface
18
21
  ```
19
22
 
20
23
  ## ๐Ÿ“ฆ Usage
24
+
21
25
  ```tsx
22
- import { Box, Text } from '@ankhorage/surface'
26
+ import { Box, Text } from '@ankhorage/surface';
23
27
 
24
28
  <Box padding="lg" gap="md">
25
29
  <Text variant="title">Title</Text>
26
30
  <Text>Content</Text>
27
- </Box>
31
+ </Box>;
28
32
  ```
29
33
 
30
34
  ## ๐Ÿงช Use Cases
35
+
31
36
  - Design system foundations
32
37
  - Cross-platform layout abstraction
33
38
 
34
39
  ## ๐Ÿง  Why this exists
40
+
35
41
  Bridges the gap between raw primitives and full UI frameworks.
@@ -6,12 +6,12 @@ const docsThemeConfig = {
6
6
  light: {
7
7
  harmony: 'monochromatic',
8
8
  primaryColor: '#2563eb',
9
- systemTone: 'neutral',
9
+ colorTone: 'neutral',
10
10
  },
11
11
  dark: {
12
12
  harmony: 'monochromatic',
13
13
  primaryColor: '#2563eb',
14
- systemTone: 'neutral',
14
+ colorTone: 'neutral',
15
15
  },
16
16
  };
17
17
  export function ProviderExample() {
@@ -1 +1 @@
1
- {"version":3,"file":"DocsExamples.js","sourceRoot":"","sources":["../../src/examples/DocsExamples.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport {\n Badge,\n Box,\n Button,\n Checkbox,\n Drawer,\n Field,\n HelperText,\n Label,\n Menu,\n Modal,\n Radio,\n Stack,\n Switch,\n Tab,\n TabList,\n TabPanel,\n Tabs,\n Text,\n Textarea,\n TextInput,\n ThemeProvider,\n} from '../index';\n\nconst docsThemeConfig = {\n id: 'docs-example',\n name: 'Docs Example',\n light: {\n harmony: 'monochromatic' as const,\n primaryColor: '#2563eb',\n systemTone: 'neutral' as const,\n },\n dark: {\n harmony: 'monochromatic' as const,\n primaryColor: '#2563eb',\n systemTone: 'neutral' as const,\n },\n};\n\nexport function ProviderExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Text variant=\"body\">Surface starter</Text>\n <Badge content=\"Foundation\" tone=\"success\" />\n <Button tone=\"warning\" variant=\"soft\">\n Continue\n </Button>\n </Stack>\n </ThemeProvider>\n );\n}\n\nexport function FormAndOverlayExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Field helperText=\"We only use this for sign-in.\" label=\"Email\">\n <TextInput placeholder=\"name@example.com\" />\n </Field>\n <Field errorText=\"Bio is required.\" invalid label=\"Bio\">\n <Textarea placeholder=\"Tell us a little about yourself\" />\n </Field>\n <Stack gap=\"s\">\n <Label required>Preferences</Label>\n <Checkbox defaultChecked>Weekly updates</Checkbox>\n <Radio>Product announcements</Radio>\n <Switch readOnly>Read-only setting</Switch>\n <HelperText tone=\"danger\">Invalid fields should reuse the same danger tone.</HelperText>\n </Stack>\n <Modal visible={false}>\n <Text>Modal content</Text>\n </Modal>\n <Drawer visible={false}>\n <Text>Drawer content</Text>\n </Drawer>\n </Stack>\n </ThemeProvider>\n );\n}\n\nexport function NavigationExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Tabs defaultValue=\"account\">\n <TabList>\n <Tab value=\"account\">Account</Tab>\n <Tab disabled value=\"security\">\n Security\n </Tab>\n <Tab value=\"billing\">Billing</Tab>\n </TabList>\n <TabPanel value=\"account\">\n <Text>Account settings</Text>\n </TabPanel>\n <TabPanel value=\"billing\">\n <Text>Billing settings</Text>\n </TabPanel>\n </Tabs>\n <Menu\n items={[\n { id: 'edit', label: 'Edit' },\n { disabled: true, id: 'archive', label: 'Archive' },\n ]}\n trigger={<Text>Open menu</Text>}\n />\n <Box>\n <Text tone=\"success\">Theme overrides can stay semantic.</Text>\n </Box>\n </Stack>\n </ThemeProvider>\n );\n}\n"]}
1
+ {"version":3,"file":"DocsExamples.js","sourceRoot":"","sources":["../../src/examples/DocsExamples.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport {\n Badge,\n Box,\n Button,\n Checkbox,\n Drawer,\n Field,\n HelperText,\n Label,\n Menu,\n Modal,\n Radio,\n Stack,\n Switch,\n Tab,\n TabList,\n TabPanel,\n Tabs,\n Text,\n Textarea,\n TextInput,\n ThemeProvider,\n} from '../index';\n\nconst docsThemeConfig = {\n id: 'docs-example',\n name: 'Docs Example',\n light: {\n harmony: 'monochromatic' as const,\n primaryColor: '#2563eb',\n colorTone: 'neutral' as const,\n },\n dark: {\n harmony: 'monochromatic' as const,\n primaryColor: '#2563eb',\n colorTone: 'neutral' as const,\n },\n};\n\nexport function ProviderExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Text variant=\"body\">Surface starter</Text>\n <Badge content=\"Foundation\" tone=\"success\" />\n <Button tone=\"warning\" variant=\"soft\">\n Continue\n </Button>\n </Stack>\n </ThemeProvider>\n );\n}\n\nexport function FormAndOverlayExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Field helperText=\"We only use this for sign-in.\" label=\"Email\">\n <TextInput placeholder=\"name@example.com\" />\n </Field>\n <Field errorText=\"Bio is required.\" invalid label=\"Bio\">\n <Textarea placeholder=\"Tell us a little about yourself\" />\n </Field>\n <Stack gap=\"s\">\n <Label required>Preferences</Label>\n <Checkbox defaultChecked>Weekly updates</Checkbox>\n <Radio>Product announcements</Radio>\n <Switch readOnly>Read-only setting</Switch>\n <HelperText tone=\"danger\">Invalid fields should reuse the same danger tone.</HelperText>\n </Stack>\n <Modal visible={false}>\n <Text>Modal content</Text>\n </Modal>\n <Drawer visible={false}>\n <Text>Drawer content</Text>\n </Drawer>\n </Stack>\n </ThemeProvider>\n );\n}\n\nexport function NavigationExample() {\n return (\n <ThemeProvider initialConfig={docsThemeConfig}>\n <Stack gap=\"m\" p=\"l\">\n <Tabs defaultValue=\"account\">\n <TabList>\n <Tab value=\"account\">Account</Tab>\n <Tab disabled value=\"security\">\n Security\n </Tab>\n <Tab value=\"billing\">Billing</Tab>\n </TabList>\n <TabPanel value=\"account\">\n <Text>Account settings</Text>\n </TabPanel>\n <TabPanel value=\"billing\">\n <Text>Billing settings</Text>\n </TabPanel>\n </Tabs>\n <Menu\n items={[\n { id: 'edit', label: 'Edit' },\n { disabled: true, id: 'archive', label: 'Archive' },\n ]}\n trigger={<Text>Open menu</Text>}\n />\n <Box>\n <Text tone=\"success\">Theme overrides can stay semantic.</Text>\n </Box>\n </Stack>\n </ThemeProvider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"colorEngine.d.ts","sourceRoot":"","sources":["../../src/theme/colorEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,UAAU,EAOV,WAAW,EACX,cAAc,EACf,MAAM,SAAS,CAAC;AAIjB,UAAU,UAAU;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,WAAW,iEAAkE,CAAC;AA0F3F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU,CAqBrF;AAqGD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC/B;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,SAAS,EAAE,cAAc,CAAC;CAC3B,CA0OA"}
1
+ {"version":3,"file":"colorEngine.d.ts","sourceRoot":"","sources":["../../src/theme/colorEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,UAAU,EAMV,WAAW,EACX,cAAc,EACf,MAAM,SAAS,CAAC;AAIjB,UAAU,UAAU;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,WAAW,iEAAkE,CAAC;AAmH3F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU,CAqBrF;AAwJD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,OAAO,GAAG,MAAgB,GAC/B;IACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,SAAS,EAAE,cAAc,CAAC;CAC3B,CA0OA"}
@@ -9,14 +9,20 @@ const LIGHTNESS_CURVES = {
9
9
  dark: [0.12, 0.16, 0.2, 0.26, 0.34, 0.62, 0.7, 0.78, 0.86, 0.92, 0.96],
10
10
  };
11
11
  /**
12
- * Lightness anchors per tone
12
+ * Lightness anchors per internal palette kind
13
13
  */
14
- const TONE_LIGHTNESS_ANCHORS = {
14
+ const ROLE_PALETTE_LIGHTNESS_ANCHORS = {
15
15
  grayscale: 0.62,
16
- earth: 0.55,
16
+ neutral: 0.62,
17
17
  pastel: 0.7,
18
+ earth: 0.55,
19
+ mineral: 0.58,
20
+ muted: 0.6,
18
21
  jewel: 0.62,
19
22
  fluorescent: 0.65,
23
+ obsidian: 0.12,
24
+ vaporwave: 0.7,
25
+ monochromeAccent: 0.62,
20
26
  };
21
27
  /**
22
28
  * Chroma curve per step to prevent "tinted whites" and "glow"
@@ -26,12 +32,18 @@ const CHROMA_BY_STEP = [0.1, 0.18, 0.3, 0.45, 0.7, 1.0, 0.92, 0.8, 0.6, 0.4, 0.2
26
32
  /**
27
33
  * Deterministic Chroma Anchors (OKLCH C)
28
34
  */
29
- const CHROMA_ANCHORS = {
35
+ const ROLE_PALETTE_CHROMA_ANCHORS = {
30
36
  grayscale: 0,
31
- earth: 0.05,
37
+ neutral: 0.02,
32
38
  pastel: 0.08,
39
+ earth: 0.05,
40
+ mineral: 0.07,
41
+ muted: 0.04,
33
42
  jewel: 0.16,
34
43
  fluorescent: 0.26,
44
+ obsidian: 0.01,
45
+ vaporwave: 0.2,
46
+ monochromeAccent: 0.02,
35
47
  };
36
48
  /**
37
49
  * Chroma Hierarchy Rule
@@ -124,11 +136,8 @@ function getHarmonyHues(baseHue, mode) {
124
136
  return [h];
125
137
  }
126
138
  }
127
- /**
128
- * System Tone Assignment Logic
129
- */
130
- function getSystemToneMapping(system) {
131
- switch (system) {
139
+ function getColorToneRolePalette(colorTone) {
140
+ switch (colorTone) {
132
141
  case 'pastel':
133
142
  return {
134
143
  bg: 'pastel',
@@ -147,6 +156,24 @@ function getSystemToneMapping(system) {
147
156
  accent: 'jewel',
148
157
  highlight: 'jewel',
149
158
  };
159
+ case 'mineral':
160
+ return {
161
+ bg: 'mineral',
162
+ surface: 'mineral',
163
+ primary: 'jewel',
164
+ secondary: 'mineral',
165
+ accent: 'jewel',
166
+ highlight: 'fluorescent',
167
+ };
168
+ case 'muted':
169
+ return {
170
+ bg: 'muted',
171
+ surface: 'muted',
172
+ primary: 'jewel',
173
+ secondary: 'muted',
174
+ accent: 'jewel',
175
+ highlight: 'fluorescent',
176
+ };
150
177
  case 'jewel':
151
178
  return {
152
179
  bg: 'grayscale',
@@ -165,6 +192,33 @@ function getSystemToneMapping(system) {
165
192
  accent: 'fluorescent',
166
193
  highlight: 'fluorescent',
167
194
  };
195
+ case 'obsidian':
196
+ return {
197
+ bg: 'obsidian',
198
+ surface: 'obsidian',
199
+ primary: 'fluorescent',
200
+ secondary: 'jewel',
201
+ accent: 'fluorescent',
202
+ highlight: 'fluorescent',
203
+ };
204
+ case 'vaporwave':
205
+ return {
206
+ bg: 'pastel',
207
+ surface: 'pastel',
208
+ primary: 'fluorescent',
209
+ secondary: 'jewel',
210
+ accent: 'fluorescent',
211
+ highlight: 'fluorescent',
212
+ };
213
+ case 'monochromeAccent':
214
+ return {
215
+ bg: 'grayscale',
216
+ surface: 'grayscale',
217
+ primary: 'jewel',
218
+ secondary: 'grayscale',
219
+ accent: 'jewel',
220
+ highlight: 'fluorescent',
221
+ };
168
222
  default: // neutral
169
223
  return {
170
224
  bg: 'grayscale',
@@ -191,7 +245,7 @@ function getBestContrast(solidHex, neutral50, neutral950) {
191
245
  }
192
246
  export function generatePalette(config, mode = 'light') {
193
247
  const modeConfig = mode === 'dark' ? config.dark : config.light;
194
- const { primaryColor, harmony, systemTone } = modeConfig;
248
+ const { primaryColor, harmony, colorTone } = modeConfig;
195
249
  let base = oklch(primaryColor);
196
250
  if (!base) {
197
251
  console.warn(`[colorEngine] Invalid primary color: "${primaryColor}". Falling back to default blue.`);
@@ -199,15 +253,15 @@ export function generatePalette(config, mode = 'light') {
199
253
  }
200
254
  const baseHue = base?.h ?? 0;
201
255
  const hues = getHarmonyHues(baseHue, harmony);
202
- const toneMap = getSystemToneMapping(systemTone);
256
+ const rolePalette = getColorToneRolePalette(colorTone);
203
257
  // 1. Resolve Chromas
204
- const getC = (t) => CHROMA_ANCHORS[t];
258
+ const getC = (t) => ROLE_PALETTE_CHROMA_ANCHORS[t];
205
259
  const getHue = (index, fallback) => hues[index] ?? fallback;
206
- const primaryChroma = getC(toneMap.primary);
207
- const secondaryChroma = getC(toneMap.secondary) * CHROMA_HIERARCHY.secondary;
208
- const tertiaryChroma = getC(toneMap.accent) * CHROMA_HIERARCHY.accent;
209
- const highlightChroma = getC(toneMap.highlight);
210
- const surfaceChroma = Math.min(0.02, getC(toneMap.bg) * CHROMA_HIERARCHY.surface);
260
+ const primaryChroma = getC(rolePalette.primary);
261
+ const secondaryChroma = getC(rolePalette.secondary) * CHROMA_HIERARCHY.secondary;
262
+ const tertiaryChroma = getC(rolePalette.accent) * CHROMA_HIERARCHY.accent;
263
+ const highlightChroma = getC(rolePalette.highlight);
264
+ const surfaceChroma = Math.min(0.02, getC(rolePalette.bg) * CHROMA_HIERARCHY.surface);
211
265
  // 2. Stable Role Assignment
212
266
  let pHue = getHue(0, baseHue);
213
267
  let sHue = getHue(0, baseHue);
@@ -238,28 +292,28 @@ export function generatePalette(config, mode = 'light') {
238
292
  break;
239
293
  }
240
294
  // 3. Build Bases with tuned lightness
241
- const getL = (t) => TONE_LIGHTNESS_ANCHORS[t];
295
+ const getL = (t) => ROLE_PALETTE_LIGHTNESS_ANCHORS[t];
242
296
  const primaryBase = {
243
297
  mode: 'oklch',
244
- l: getL(toneMap.primary),
298
+ l: getL(rolePalette.primary),
245
299
  c: primaryChroma,
246
300
  h: pHue,
247
301
  };
248
302
  const secondaryBase = {
249
303
  mode: 'oklch',
250
- l: getL(toneMap.secondary),
304
+ l: getL(rolePalette.secondary),
251
305
  c: secondaryChroma,
252
306
  h: sHue,
253
307
  };
254
308
  const accentBase = {
255
309
  mode: 'oklch',
256
- l: getL(toneMap.accent),
310
+ l: getL(rolePalette.accent),
257
311
  c: tertiaryChroma,
258
312
  h: aHue,
259
313
  };
260
314
  const highlightBase = {
261
315
  mode: 'oklch',
262
- l: getL(toneMap.highlight),
316
+ l: getL(rolePalette.highlight),
263
317
  c: highlightChroma,
264
318
  h: hHue,
265
319
  };
@@ -1 +1 @@
1
- {"version":3,"file":"colorEngine.js","sourceRoot":"","sources":["../../src/theme/colorEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatHex, modeOklch, oklch, useMode } from 'culori';\n\nimport type {\n ActionSemantics,\n BorderSemantics,\n ColorHarmony,\n ColorScale,\n ColorTone,\n ContentSemantics,\n NeutralSemantics,\n RoleSemantics,\n SurfaceSemantics,\n SystemTone,\n ThemeConfig,\n ThemeSemantics,\n} from './types';\n\nuseMode(modeOklch);\n\ninterface OklchColor {\n mode: 'oklch';\n l: number;\n c: number;\n h?: number;\n}\n\nexport const SCALE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\n\n/**\n * Deterministic Lightness Curves (OKLCH L)\n */\nconst LIGHTNESS_CURVES = {\n light: [0.98, 0.95, 0.9, 0.82, 0.72, 0.62, 0.52, 0.42, 0.32, 0.22, 0.15],\n dark: [0.12, 0.16, 0.2, 0.26, 0.34, 0.62, 0.7, 0.78, 0.86, 0.92, 0.96],\n} as const;\n\n/**\n * Lightness anchors per tone\n */\nconst TONE_LIGHTNESS_ANCHORS: Record<ColorTone, number> = {\n grayscale: 0.62,\n earth: 0.55,\n pastel: 0.7,\n jewel: 0.62,\n fluorescent: 0.65,\n};\n\n/**\n * Chroma curve per step to prevent \"tinted whites\" and \"glow\"\n * Peak energy at 500, falloff at extremes.\n */\nconst CHROMA_BY_STEP = [0.1, 0.18, 0.3, 0.45, 0.7, 1.0, 0.92, 0.8, 0.6, 0.4, 0.25] as const;\n\n/**\n * Deterministic Chroma Anchors (OKLCH C)\n */\nconst CHROMA_ANCHORS: Record<ColorTone, number> = {\n grayscale: 0,\n earth: 0.05,\n pastel: 0.08,\n jewel: 0.16,\n fluorescent: 0.26,\n};\n\n/**\n * Chroma Hierarchy Rule\n */\nconst CHROMA_HIERARCHY = {\n primary: 1.0,\n secondary: 0.7,\n accent: 0.4,\n surface: 0.1,\n} as const;\n\n/**\n * Semantic Step Mapping\n */\nconst SEMANTIC_STEPS = {\n light: {\n bg: 0, // 50\n bgSubtle: 1, // 100\n surface: 1, // 100\n surfaceHover: 2, // 200\n surfaceActive: 3, // 300\n border: 3, // 300\n borderStrong: 4, // 400\n divider: 2, // 200\n text: 9, // 900\n textMuted: 7, // 700\n textSubtle: 6, // 600\n solid: 5, // 500\n softBg: 1, // 100\n softHover: 2, // 200\n softActive: 3, // 300\n outline: 4, // 400\n },\n dark: {\n bg: 0, // 50\n bgSubtle: 1, // 100\n surface: 1, // 100\n surfaceHover: 2, // 200\n surfaceActive: 3, // 300\n border: 3, // 300\n borderStrong: 4, // 400\n divider: 2, // 200\n text: 10, // 950\n textMuted: 8, // 800\n textSubtle: 7, // 700\n solid: 5, // 500\n softBg: 1, // 100\n softHover: 2, // 200\n softActive: 3, // 300\n outline: 4, // 400\n },\n} as const;\n\nexport function generateColorScale(baseColor: OklchColor, isDark: boolean): ColorScale {\n const scale: Partial<ColorScale> = {};\n const curve = isDark ? LIGHTNESS_CURVES.dark : LIGHTNESS_CURVES.light;\n\n // Dark-mode chroma rule: reduce chroma by 25%\n const chromaMultiplier = isDark ? 0.75 : 1.0;\n const targetChroma = baseColor.c * chromaMultiplier;\n\n SCALE_STEPS.forEach((step, index) => {\n const lightness = curve[index];\n const chromaByStep = CHROMA_BY_STEP[index];\n if (lightness === undefined || chromaByStep === undefined) {\n return;\n }\n // Apply chroma falloff curve per step\n const stepChroma = targetChroma * chromaByStep;\n const stepColor = { ...baseColor, l: lightness, c: stepChroma };\n scale[step as keyof ColorScale] = formatHex(stepColor);\n });\n\n return scale as ColorScale;\n}\n\n/**\n * Deterministic Harmony Hues\n */\nfunction getHarmonyHues(baseHue: number, mode: ColorHarmony): number[] {\n const h = (baseHue + 360) % 360;\n switch (mode) {\n case 'monochromatic':\n return [h];\n case 'analogous':\n return [h, (h - 30 + 360) % 360, (h + 30) % 360];\n case 'complementary':\n return [h, (h + 180) % 360];\n case 'splitComplementary':\n return [h, (h + 150) % 360, (h + 210) % 360];\n case 'triadic':\n return [h, (h + 120) % 360, (h + 240) % 360];\n case 'tetradic':\n return [h, (h + 90) % 360, (h + 180) % 360, (h + 270) % 360];\n default:\n return [h];\n }\n}\n\n/**\n * System Tone Assignment Logic\n */\nfunction getSystemToneMapping(system: SystemTone): {\n bg: ColorTone;\n surface: ColorTone;\n primary: ColorTone;\n secondary: ColorTone;\n accent: ColorTone;\n highlight: ColorTone;\n} {\n switch (system) {\n case 'pastel':\n return {\n bg: 'pastel',\n surface: 'pastel',\n primary: 'pastel',\n secondary: 'pastel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n case 'earth':\n return {\n bg: 'earth',\n surface: 'earth',\n primary: 'earth',\n secondary: 'earth',\n accent: 'jewel',\n highlight: 'jewel',\n };\n case 'jewel':\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'jewel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n case 'fluorescent':\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'jewel',\n accent: 'fluorescent',\n highlight: 'fluorescent',\n };\n default: // neutral\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'pastel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n }\n}\n\n/**\n * Simple OKLCH L-based contrast check\n */\nfunction getBestContrast(solidHex: string, neutral50: string, neutral950: string): string {\n const solid = oklch(solidHex);\n const n50 = oklch(neutral50);\n const n950 = oklch(neutral950);\n\n if (!solid || !n50 || !n950) return neutral50;\n\n const diff50 = Math.abs(solid.l - n50.l);\n const diff950 = Math.abs(solid.l - n950.l);\n\n return diff50 >= diff950 ? neutral50 : neutral950;\n}\n\nexport function generatePalette(\n config: ThemeConfig,\n mode: 'light' | 'dark' = 'light',\n): {\n colors: Record<string, string>;\n scales: Record<string, ColorScale>;\n semantics: ThemeSemantics;\n} {\n const modeConfig = mode === 'dark' ? config.dark : config.light;\n const { primaryColor, harmony, systemTone } = modeConfig;\n\n let base = oklch(primaryColor);\n if (!base) {\n console.warn(\n `[colorEngine] Invalid primary color: \"${primaryColor}\". Falling back to default blue.`,\n );\n base = oklch('#3B82F6');\n }\n\n const baseHue = base?.h ?? 0;\n const hues = getHarmonyHues(baseHue, harmony);\n const toneMap = getSystemToneMapping(systemTone);\n\n // 1. Resolve Chromas\n const getC = (t: ColorTone) => CHROMA_ANCHORS[t];\n const getHue = (index: number, fallback: number) => hues[index] ?? fallback;\n\n const primaryChroma = getC(toneMap.primary);\n const secondaryChroma = getC(toneMap.secondary) * CHROMA_HIERARCHY.secondary;\n const tertiaryChroma = getC(toneMap.accent) * CHROMA_HIERARCHY.accent;\n const highlightChroma = getC(toneMap.highlight);\n const surfaceChroma = Math.min(0.02, getC(toneMap.bg) * CHROMA_HIERARCHY.surface);\n\n // 2. Stable Role Assignment\n let pHue = getHue(0, baseHue);\n let sHue = getHue(0, baseHue);\n let aHue = getHue(0, baseHue);\n let hHue =\n harmony === 'tetradic' ? getHue(3, getHue(0, baseHue)) : (getHue(0, baseHue) + 60) % 360; // Yellow-ish offset if no tetradic\n\n switch (harmony) {\n case 'complementary':\n pHue = getHue(0, pHue);\n aHue = getHue(1, pHue);\n sHue = (getHue(0, pHue) + 30) % 360;\n break;\n case 'splitComplementary':\n case 'triadic':\n pHue = getHue(0, pHue);\n sHue = getHue(1, pHue);\n aHue = getHue(2, sHue);\n break;\n case 'tetradic':\n pHue = getHue(0, pHue);\n sHue = getHue(1, pHue);\n aHue = getHue(2, sHue);\n hHue = getHue(3, aHue);\n break;\n case 'analogous':\n pHue = getHue(1, pHue);\n sHue = getHue(0, pHue);\n aHue = getHue(2, sHue);\n break;\n }\n\n // 3. Build Bases with tuned lightness\n const getL = (t: ColorTone) => TONE_LIGHTNESS_ANCHORS[t];\n\n const primaryBase: OklchColor = {\n mode: 'oklch',\n l: getL(toneMap.primary),\n c: primaryChroma,\n h: pHue,\n };\n const secondaryBase: OklchColor = {\n mode: 'oklch',\n l: getL(toneMap.secondary),\n c: secondaryChroma,\n h: sHue,\n };\n const accentBase: OklchColor = {\n mode: 'oklch',\n l: getL(toneMap.accent),\n c: tertiaryChroma,\n h: aHue,\n };\n const highlightBase: OklchColor = {\n mode: 'oklch',\n l: getL(toneMap.highlight),\n c: highlightChroma,\n h: hHue,\n };\n const dangerBase: OklchColor = {\n mode: 'oklch',\n l: 0.6,\n c: 0.2,\n h: 25,\n };\n const successBase: OklchColor = {\n mode: 'oklch',\n l: 0.6,\n c: 0.2,\n h: 145,\n };\n const warningBase: OklchColor = {\n mode: 'oklch',\n l: 0.75,\n c: 0.15,\n h: 85,\n };\n\n const neutralBase: OklchColor =\n surfaceChroma === 0\n ? { mode: 'oklch', l: 0.62, c: 0 }\n : { mode: 'oklch', l: 0.62, c: surfaceChroma, h: 260 };\n\n // 4. Generate Scales\n const isDark = mode === 'dark';\n const scales = {\n primary: generateColorScale(primaryBase, isDark),\n secondary: generateColorScale(secondaryBase, isDark),\n accent: generateColorScale(accentBase, isDark),\n highlight: generateColorScale(highlightBase, isDark),\n neutral: generateColorScale(neutralBase, isDark),\n danger: generateColorScale(dangerBase, isDark),\n success: generateColorScale(successBase, isDark),\n warning: generateColorScale(warningBase, isDark),\n };\n\n // 5. Mappings\n const steps = isDark ? SEMANTIC_STEPS.dark : SEMANTIC_STEPS.light;\n const getStep = (s: ColorScale, idx: number) => {\n const key = SCALE_STEPS[idx] ?? SCALE_STEPS[SCALE_STEPS.length - 1] ?? 950;\n return s[key];\n };\n\n const getNeutralMapping = (scale: ColorScale): NeutralSemantics => ({\n bg: getStep(scale, steps.bg),\n bgSubtle: getStep(scale, steps.bgSubtle),\n surface: getStep(scale, steps.surface),\n surfaceHover: getStep(scale, steps.surfaceHover),\n surfaceActive: getStep(scale, steps.surfaceActive),\n border: getStep(scale, steps.border),\n borderStrong: getStep(scale, steps.borderStrong),\n divider: getStep(scale, steps.divider),\n text: getStep(scale, steps.text),\n textMuted: getStep(scale, steps.textMuted),\n textSubtle: getStep(scale, steps.textSubtle),\n });\n\n const getColorMapping = (scale: ColorScale, neutralScale: ColorScale): RoleSemantics => {\n const solid = getStep(scale, steps.solid);\n const softChromaLimit = 0.08;\n\n // Chroma capping for soft tokens\n const getSoftStep = (idx: number) => {\n const hex = getStep(scale, idx);\n const color = oklch(hex);\n if (color && color.c > softChromaLimit) {\n return formatHex({ ...color, c: softChromaLimit });\n }\n return hex;\n };\n\n return {\n base: solid,\n hover: getStep(scale, 6), // 600\n strong: getStep(scale, 7), // 700\n softBg: getSoftStep(steps.softBg),\n softHover: getSoftStep(steps.softHover),\n softActive: getSoftStep(steps.softActive),\n outline: getStep(scale, steps.outline),\n onSolidText: getBestContrast(solid, getStep(neutralScale, 0), getStep(neutralScale, 10)),\n };\n };\n\n const neutral = getNeutralMapping(scales.neutral);\n const brand = getColorMapping(scales.primary, scales.neutral);\n const neutralAction = getColorMapping(scales.neutral, scales.neutral);\n const danger = getColorMapping(scales.danger, scales.neutral);\n const success = getColorMapping(scales.success, scales.neutral);\n const warning = getColorMapping(scales.warning, scales.neutral);\n\n const colors: Record<string, string> = {\n primary: getStep(scales.primary, steps.solid),\n secondary: getStep(scales.secondary, steps.solid),\n accent: getStep(scales.accent, steps.solid),\n highlight: getStep(scales.highlight, steps.solid),\n background: neutral.bg,\n surface: neutral.surface,\n text: neutral.text,\n textSecondary: neutral.textMuted,\n border: neutral.border,\n error: getStep(scales.danger, steps.solid),\n success: getStep(scales.success, steps.solid),\n warning: getStep(scales.warning, steps.solid),\n };\n\n const surface: SurfaceSemantics = {\n default: neutral.surface,\n subtle: neutral.bgSubtle,\n raised: neutral.surface,\n };\n\n const content: ContentSemantics = {\n default: neutral.text,\n muted: neutral.textMuted,\n subtle: neutral.textSubtle,\n inverse: brand.onSolidText,\n };\n\n const border: BorderSemantics = {\n default: neutral.border,\n strong: neutral.borderStrong,\n focus: brand.outline,\n };\n\n const action: ActionSemantics = {\n primary: brand,\n neutral: neutralAction,\n danger,\n };\n\n return {\n colors,\n scales,\n semantics: {\n neutral,\n brand,\n secondary: getColorMapping(scales.secondary, scales.neutral),\n accent: getColorMapping(scales.accent, scales.neutral),\n highlight: getColorMapping(scales.highlight, scales.neutral),\n danger,\n success,\n warning,\n surface,\n content,\n border,\n action,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"colorEngine.js","sourceRoot":"","sources":["../../src/theme/colorEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatHex, modeOklch, oklch, useMode } from 'culori';\n\nimport type {\n ActionSemantics,\n BorderSemantics,\n ColorHarmony,\n ColorScale,\n ColorTone,\n ContentSemantics,\n NeutralSemantics,\n RoleSemantics,\n SurfaceSemantics,\n ThemeConfig,\n ThemeSemantics,\n} from './types';\n\nuseMode(modeOklch);\n\ninterface OklchColor {\n mode: 'oklch';\n l: number;\n c: number;\n h?: number;\n}\n\nexport const SCALE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\n\ntype RolePaletteKind =\n | 'grayscale'\n | 'neutral'\n | 'pastel'\n | 'earth'\n | 'mineral'\n | 'muted'\n | 'jewel'\n | 'fluorescent'\n | 'obsidian'\n | 'vaporwave'\n | 'monochromeAccent';\n\n/**\n * Deterministic Lightness Curves (OKLCH L)\n */\nconst LIGHTNESS_CURVES = {\n light: [0.98, 0.95, 0.9, 0.82, 0.72, 0.62, 0.52, 0.42, 0.32, 0.22, 0.15],\n dark: [0.12, 0.16, 0.2, 0.26, 0.34, 0.62, 0.7, 0.78, 0.86, 0.92, 0.96],\n} as const;\n\n/**\n * Lightness anchors per internal palette kind\n */\nconst ROLE_PALETTE_LIGHTNESS_ANCHORS: Record<RolePaletteKind, number> = {\n grayscale: 0.62,\n neutral: 0.62,\n pastel: 0.7,\n earth: 0.55,\n mineral: 0.58,\n muted: 0.6,\n jewel: 0.62,\n fluorescent: 0.65,\n obsidian: 0.12,\n vaporwave: 0.7,\n monochromeAccent: 0.62,\n};\n\n/**\n * Chroma curve per step to prevent \"tinted whites\" and \"glow\"\n * Peak energy at 500, falloff at extremes.\n */\nconst CHROMA_BY_STEP = [0.1, 0.18, 0.3, 0.45, 0.7, 1.0, 0.92, 0.8, 0.6, 0.4, 0.25] as const;\n\n/**\n * Deterministic Chroma Anchors (OKLCH C)\n */\nconst ROLE_PALETTE_CHROMA_ANCHORS: Record<RolePaletteKind, number> = {\n grayscale: 0,\n neutral: 0.02,\n pastel: 0.08,\n earth: 0.05,\n mineral: 0.07,\n muted: 0.04,\n jewel: 0.16,\n fluorescent: 0.26,\n obsidian: 0.01,\n vaporwave: 0.2,\n monochromeAccent: 0.02,\n};\n\n/**\n * Chroma Hierarchy Rule\n */\nconst CHROMA_HIERARCHY = {\n primary: 1.0,\n secondary: 0.7,\n accent: 0.4,\n surface: 0.1,\n} as const;\n\n/**\n * Semantic Step Mapping\n */\nconst SEMANTIC_STEPS = {\n light: {\n bg: 0, // 50\n bgSubtle: 1, // 100\n surface: 1, // 100\n surfaceHover: 2, // 200\n surfaceActive: 3, // 300\n border: 3, // 300\n borderStrong: 4, // 400\n divider: 2, // 200\n text: 9, // 900\n textMuted: 7, // 700\n textSubtle: 6, // 600\n solid: 5, // 500\n softBg: 1, // 100\n softHover: 2, // 200\n softActive: 3, // 300\n outline: 4, // 400\n },\n dark: {\n bg: 0, // 50\n bgSubtle: 1, // 100\n surface: 1, // 100\n surfaceHover: 2, // 200\n surfaceActive: 3, // 300\n border: 3, // 300\n borderStrong: 4, // 400\n divider: 2, // 200\n text: 10, // 950\n textMuted: 8, // 800\n textSubtle: 7, // 700\n solid: 5, // 500\n softBg: 1, // 100\n softHover: 2, // 200\n softActive: 3, // 300\n outline: 4, // 400\n },\n} as const;\n\nexport function generateColorScale(baseColor: OklchColor, isDark: boolean): ColorScale {\n const scale: Partial<ColorScale> = {};\n const curve = isDark ? LIGHTNESS_CURVES.dark : LIGHTNESS_CURVES.light;\n\n // Dark-mode chroma rule: reduce chroma by 25%\n const chromaMultiplier = isDark ? 0.75 : 1.0;\n const targetChroma = baseColor.c * chromaMultiplier;\n\n SCALE_STEPS.forEach((step, index) => {\n const lightness = curve[index];\n const chromaByStep = CHROMA_BY_STEP[index];\n if (lightness === undefined || chromaByStep === undefined) {\n return;\n }\n // Apply chroma falloff curve per step\n const stepChroma = targetChroma * chromaByStep;\n const stepColor = { ...baseColor, l: lightness, c: stepChroma };\n scale[step as keyof ColorScale] = formatHex(stepColor);\n });\n\n return scale as ColorScale;\n}\n\n/**\n * Deterministic Harmony Hues\n */\nfunction getHarmonyHues(baseHue: number, mode: ColorHarmony): number[] {\n const h = (baseHue + 360) % 360;\n switch (mode) {\n case 'monochromatic':\n return [h];\n case 'analogous':\n return [h, (h - 30 + 360) % 360, (h + 30) % 360];\n case 'complementary':\n return [h, (h + 180) % 360];\n case 'splitComplementary':\n return [h, (h + 150) % 360, (h + 210) % 360];\n case 'triadic':\n return [h, (h + 120) % 360, (h + 240) % 360];\n case 'tetradic':\n return [h, (h + 90) % 360, (h + 180) % 360, (h + 270) % 360];\n default:\n return [h];\n }\n}\n\nfunction getColorToneRolePalette(colorTone: ColorTone): {\n bg: RolePaletteKind;\n surface: RolePaletteKind;\n primary: RolePaletteKind;\n secondary: RolePaletteKind;\n accent: RolePaletteKind;\n highlight: RolePaletteKind;\n} {\n switch (colorTone) {\n case 'pastel':\n return {\n bg: 'pastel',\n surface: 'pastel',\n primary: 'pastel',\n secondary: 'pastel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n\n case 'earth':\n return {\n bg: 'earth',\n surface: 'earth',\n primary: 'earth',\n secondary: 'earth',\n accent: 'jewel',\n highlight: 'jewel',\n };\n\n case 'mineral':\n return {\n bg: 'mineral',\n surface: 'mineral',\n primary: 'jewel',\n secondary: 'mineral',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n\n case 'muted':\n return {\n bg: 'muted',\n surface: 'muted',\n primary: 'jewel',\n secondary: 'muted',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n\n case 'jewel':\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'jewel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n\n case 'fluorescent':\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'jewel',\n accent: 'fluorescent',\n highlight: 'fluorescent',\n };\n\n case 'obsidian':\n return {\n bg: 'obsidian',\n surface: 'obsidian',\n primary: 'fluorescent',\n secondary: 'jewel',\n accent: 'fluorescent',\n highlight: 'fluorescent',\n };\n\n case 'vaporwave':\n return {\n bg: 'pastel',\n surface: 'pastel',\n primary: 'fluorescent',\n secondary: 'jewel',\n accent: 'fluorescent',\n highlight: 'fluorescent',\n };\n\n case 'monochromeAccent':\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'grayscale',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n\n default: // neutral\n return {\n bg: 'grayscale',\n surface: 'grayscale',\n primary: 'jewel',\n secondary: 'pastel',\n accent: 'jewel',\n highlight: 'fluorescent',\n };\n }\n}\n\n/**\n * Simple OKLCH L-based contrast check\n */\nfunction getBestContrast(solidHex: string, neutral50: string, neutral950: string): string {\n const solid = oklch(solidHex);\n const n50 = oklch(neutral50);\n const n950 = oklch(neutral950);\n\n if (!solid || !n50 || !n950) return neutral50;\n\n const diff50 = Math.abs(solid.l - n50.l);\n const diff950 = Math.abs(solid.l - n950.l);\n\n return diff50 >= diff950 ? neutral50 : neutral950;\n}\n\nexport function generatePalette(\n config: ThemeConfig,\n mode: 'light' | 'dark' = 'light',\n): {\n colors: Record<string, string>;\n scales: Record<string, ColorScale>;\n semantics: ThemeSemantics;\n} {\n const modeConfig = mode === 'dark' ? config.dark : config.light;\n const { primaryColor, harmony, colorTone } = modeConfig;\n\n let base = oklch(primaryColor);\n if (!base) {\n console.warn(\n `[colorEngine] Invalid primary color: \"${primaryColor}\". Falling back to default blue.`,\n );\n base = oklch('#3B82F6');\n }\n\n const baseHue = base?.h ?? 0;\n const hues = getHarmonyHues(baseHue, harmony);\n const rolePalette = getColorToneRolePalette(colorTone);\n\n // 1. Resolve Chromas\n const getC = (t: RolePaletteKind) => ROLE_PALETTE_CHROMA_ANCHORS[t];\n const getHue = (index: number, fallback: number) => hues[index] ?? fallback;\n\n const primaryChroma = getC(rolePalette.primary);\n const secondaryChroma = getC(rolePalette.secondary) * CHROMA_HIERARCHY.secondary;\n const tertiaryChroma = getC(rolePalette.accent) * CHROMA_HIERARCHY.accent;\n const highlightChroma = getC(rolePalette.highlight);\n const surfaceChroma = Math.min(0.02, getC(rolePalette.bg) * CHROMA_HIERARCHY.surface);\n\n // 2. Stable Role Assignment\n let pHue = getHue(0, baseHue);\n let sHue = getHue(0, baseHue);\n let aHue = getHue(0, baseHue);\n let hHue =\n harmony === 'tetradic' ? getHue(3, getHue(0, baseHue)) : (getHue(0, baseHue) + 60) % 360; // Yellow-ish offset if no tetradic\n\n switch (harmony) {\n case 'complementary':\n pHue = getHue(0, pHue);\n aHue = getHue(1, pHue);\n sHue = (getHue(0, pHue) + 30) % 360;\n break;\n case 'splitComplementary':\n case 'triadic':\n pHue = getHue(0, pHue);\n sHue = getHue(1, pHue);\n aHue = getHue(2, sHue);\n break;\n case 'tetradic':\n pHue = getHue(0, pHue);\n sHue = getHue(1, pHue);\n aHue = getHue(2, sHue);\n hHue = getHue(3, aHue);\n break;\n case 'analogous':\n pHue = getHue(1, pHue);\n sHue = getHue(0, pHue);\n aHue = getHue(2, sHue);\n break;\n }\n\n // 3. Build Bases with tuned lightness\n const getL = (t: RolePaletteKind) => ROLE_PALETTE_LIGHTNESS_ANCHORS[t];\n\n const primaryBase: OklchColor = {\n mode: 'oklch',\n l: getL(rolePalette.primary),\n c: primaryChroma,\n h: pHue,\n };\n const secondaryBase: OklchColor = {\n mode: 'oklch',\n l: getL(rolePalette.secondary),\n c: secondaryChroma,\n h: sHue,\n };\n const accentBase: OklchColor = {\n mode: 'oklch',\n l: getL(rolePalette.accent),\n c: tertiaryChroma,\n h: aHue,\n };\n const highlightBase: OklchColor = {\n mode: 'oklch',\n l: getL(rolePalette.highlight),\n c: highlightChroma,\n h: hHue,\n };\n const dangerBase: OklchColor = {\n mode: 'oklch',\n l: 0.6,\n c: 0.2,\n h: 25,\n };\n const successBase: OklchColor = {\n mode: 'oklch',\n l: 0.6,\n c: 0.2,\n h: 145,\n };\n const warningBase: OklchColor = {\n mode: 'oklch',\n l: 0.75,\n c: 0.15,\n h: 85,\n };\n\n const neutralBase: OklchColor =\n surfaceChroma === 0\n ? { mode: 'oklch', l: 0.62, c: 0 }\n : { mode: 'oklch', l: 0.62, c: surfaceChroma, h: 260 };\n\n // 4. Generate Scales\n const isDark = mode === 'dark';\n const scales = {\n primary: generateColorScale(primaryBase, isDark),\n secondary: generateColorScale(secondaryBase, isDark),\n accent: generateColorScale(accentBase, isDark),\n highlight: generateColorScale(highlightBase, isDark),\n neutral: generateColorScale(neutralBase, isDark),\n danger: generateColorScale(dangerBase, isDark),\n success: generateColorScale(successBase, isDark),\n warning: generateColorScale(warningBase, isDark),\n };\n\n // 5. Mappings\n const steps = isDark ? SEMANTIC_STEPS.dark : SEMANTIC_STEPS.light;\n const getStep = (s: ColorScale, idx: number) => {\n const key = SCALE_STEPS[idx] ?? SCALE_STEPS[SCALE_STEPS.length - 1] ?? 950;\n return s[key];\n };\n\n const getNeutralMapping = (scale: ColorScale): NeutralSemantics => ({\n bg: getStep(scale, steps.bg),\n bgSubtle: getStep(scale, steps.bgSubtle),\n surface: getStep(scale, steps.surface),\n surfaceHover: getStep(scale, steps.surfaceHover),\n surfaceActive: getStep(scale, steps.surfaceActive),\n border: getStep(scale, steps.border),\n borderStrong: getStep(scale, steps.borderStrong),\n divider: getStep(scale, steps.divider),\n text: getStep(scale, steps.text),\n textMuted: getStep(scale, steps.textMuted),\n textSubtle: getStep(scale, steps.textSubtle),\n });\n\n const getColorMapping = (scale: ColorScale, neutralScale: ColorScale): RoleSemantics => {\n const solid = getStep(scale, steps.solid);\n const softChromaLimit = 0.08;\n\n // Chroma capping for soft tokens\n const getSoftStep = (idx: number) => {\n const hex = getStep(scale, idx);\n const color = oklch(hex);\n if (color && color.c > softChromaLimit) {\n return formatHex({ ...color, c: softChromaLimit });\n }\n return hex;\n };\n\n return {\n base: solid,\n hover: getStep(scale, 6), // 600\n strong: getStep(scale, 7), // 700\n softBg: getSoftStep(steps.softBg),\n softHover: getSoftStep(steps.softHover),\n softActive: getSoftStep(steps.softActive),\n outline: getStep(scale, steps.outline),\n onSolidText: getBestContrast(solid, getStep(neutralScale, 0), getStep(neutralScale, 10)),\n };\n };\n\n const neutral = getNeutralMapping(scales.neutral);\n const brand = getColorMapping(scales.primary, scales.neutral);\n const neutralAction = getColorMapping(scales.neutral, scales.neutral);\n const danger = getColorMapping(scales.danger, scales.neutral);\n const success = getColorMapping(scales.success, scales.neutral);\n const warning = getColorMapping(scales.warning, scales.neutral);\n\n const colors: Record<string, string> = {\n primary: getStep(scales.primary, steps.solid),\n secondary: getStep(scales.secondary, steps.solid),\n accent: getStep(scales.accent, steps.solid),\n highlight: getStep(scales.highlight, steps.solid),\n background: neutral.bg,\n surface: neutral.surface,\n text: neutral.text,\n textSecondary: neutral.textMuted,\n border: neutral.border,\n error: getStep(scales.danger, steps.solid),\n success: getStep(scales.success, steps.solid),\n warning: getStep(scales.warning, steps.solid),\n };\n\n const surface: SurfaceSemantics = {\n default: neutral.surface,\n subtle: neutral.bgSubtle,\n raised: neutral.surface,\n };\n\n const content: ContentSemantics = {\n default: neutral.text,\n muted: neutral.textMuted,\n subtle: neutral.textSubtle,\n inverse: brand.onSolidText,\n };\n\n const border: BorderSemantics = {\n default: neutral.border,\n strong: neutral.borderStrong,\n focus: brand.outline,\n };\n\n const action: ActionSemantics = {\n primary: brand,\n neutral: neutralAction,\n danger,\n };\n\n return {\n colors,\n scales,\n semantics: {\n neutral,\n brand,\n secondary: getColorMapping(scales.secondary, scales.neutral),\n accent: getColorMapping(scales.accent, scales.neutral),\n highlight: getColorMapping(scales.highlight, scales.neutral),\n danger,\n success,\n warning,\n surface,\n content,\n border,\n action,\n },\n };\n}\n"]}
@@ -68,12 +68,12 @@ export const DEFAULT_CONFIG = {
68
68
  light: {
69
69
  primaryColor: '#3B82F6',
70
70
  harmony: 'monochromatic',
71
- systemTone: 'neutral',
71
+ colorTone: 'neutral',
72
72
  },
73
73
  dark: {
74
74
  primaryColor: '#3B82F6',
75
75
  harmony: 'monochromatic',
76
- systemTone: 'neutral',
76
+ colorTone: 'neutral',
77
77
  },
78
78
  };
79
79
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"createTheme.js","sourceRoot":"","sources":["../../src/theme/createTheme.ts"],"names":[],"mappings":"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","sourcesContent":["import { generatePalette } from './colorEngine';\nimport type { AnkhTheme, FontWeight, ThemeConfig, ThemeTokens } from './types';\n\nexport const DEFAULT_TOKENS: Omit<ThemeTokens, 'colors' | 'scales' | 'semantics'> = {\n spacing: {\n none: 0,\n xs: 4,\n s: 8,\n m: 16,\n l: 24,\n xl: 32,\n xxl: 48,\n },\n radii: {\n none: 0,\n s: 4,\n m: 8,\n l: 16,\n full: 9999,\n },\n typography: {\n headings: {\n 1: { size: 32, lineHeight: 40, weight: 'bold' },\n 2: { size: 24, lineHeight: 32, weight: 'bold' },\n 3: { size: 20, lineHeight: 28, weight: 'bold' },\n 4: { size: 18, lineHeight: 24, weight: 'semiBold' },\n 5: { size: 16, lineHeight: 22, weight: 'semiBold' },\n 6: { size: 14, lineHeight: 20, weight: 'semiBold' },\n },\n sizes: {\n xs: 12,\n s: 14,\n m: 16,\n l: 18,\n xl: 20,\n xxl: 24,\n '3xl': 30,\n h1: 32,\n h2: 24,\n h3: 20,\n h4: 18,\n h5: 16,\n h6: 14,\n },\n weights: {\n thin: '100',\n extraLight: '200',\n light: '300',\n regular: '400',\n medium: '500',\n semiBold: '600',\n bold: '700',\n extraBold: '800',\n black: '900',\n },\n fonts: {\n normal: {} as Record<FontWeight, string | undefined>,\n italic: {} as Record<FontWeight, string | undefined>,\n },\n },\n shadows: {\n soft: 2,\n medium: 4,\n hard: 8,\n },\n};\n\nexport const DEFAULT_CONFIG: ThemeConfig = {\n id: 'default',\n name: 'Default',\n light: {\n primaryColor: '#3B82F6',\n harmony: 'monochromatic',\n systemTone: 'neutral',\n },\n dark: {\n primaryColor: '#3B82F6',\n harmony: 'monochromatic',\n systemTone: 'neutral',\n },\n};\n\n/**\n * Normalizes font family name to PascalCase for consistent key generation\n * matches GoogleFontsPlugin logic.\n */\nfunction toPascalCase(str: string) {\n return str\n .split(/[- ]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\nexport function createTheme(\n config: ThemeConfig = DEFAULT_CONFIG,\n mode: 'light' | 'dark' = 'light',\n activeFontId?: string | null,\n): AnkhTheme {\n const { colors, scales, semantics } = generatePalette(config, mode);\n\n const theme = {\n ...DEFAULT_TOKENS,\n colors: colors as AnkhTheme['colors'],\n scales,\n semantics,\n config,\n };\n\n if (activeFontId) {\n const familyName = toPascalCase(activeFontId);\n const weights: FontWeight[] = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\n weights.forEach((w) => {\n // Convention from GoogleFonts plugin: Family_WeightRegular\n theme.typography.fonts.normal[w] = `${familyName}_${w}Regular`;\n theme.typography.fonts.italic[w] = `${familyName}_${w}Italic`;\n });\n }\n\n return theme;\n}\n"]}
1
+ {"version":3,"file":"createTheme.js","sourceRoot":"","sources":["../../src/theme/createTheme.ts"],"names":[],"mappings":"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","sourcesContent":["import { generatePalette } from './colorEngine';\nimport type { AnkhTheme, FontWeight, ThemeConfig, ThemeTokens } from './types';\n\nexport const DEFAULT_TOKENS: Omit<ThemeTokens, 'colors' | 'scales' | 'semantics'> = {\n spacing: {\n none: 0,\n xs: 4,\n s: 8,\n m: 16,\n l: 24,\n xl: 32,\n xxl: 48,\n },\n radii: {\n none: 0,\n s: 4,\n m: 8,\n l: 16,\n full: 9999,\n },\n typography: {\n headings: {\n 1: { size: 32, lineHeight: 40, weight: 'bold' },\n 2: { size: 24, lineHeight: 32, weight: 'bold' },\n 3: { size: 20, lineHeight: 28, weight: 'bold' },\n 4: { size: 18, lineHeight: 24, weight: 'semiBold' },\n 5: { size: 16, lineHeight: 22, weight: 'semiBold' },\n 6: { size: 14, lineHeight: 20, weight: 'semiBold' },\n },\n sizes: {\n xs: 12,\n s: 14,\n m: 16,\n l: 18,\n xl: 20,\n xxl: 24,\n '3xl': 30,\n h1: 32,\n h2: 24,\n h3: 20,\n h4: 18,\n h5: 16,\n h6: 14,\n },\n weights: {\n thin: '100',\n extraLight: '200',\n light: '300',\n regular: '400',\n medium: '500',\n semiBold: '600',\n bold: '700',\n extraBold: '800',\n black: '900',\n },\n fonts: {\n normal: {} as Record<FontWeight, string | undefined>,\n italic: {} as Record<FontWeight, string | undefined>,\n },\n },\n shadows: {\n soft: 2,\n medium: 4,\n hard: 8,\n },\n};\n\nexport const DEFAULT_CONFIG: ThemeConfig = {\n id: 'default',\n name: 'Default',\n light: {\n primaryColor: '#3B82F6',\n harmony: 'monochromatic',\n colorTone: 'neutral',\n },\n dark: {\n primaryColor: '#3B82F6',\n harmony: 'monochromatic',\n colorTone: 'neutral',\n },\n};\n\n/**\n * Normalizes font family name to PascalCase for consistent key generation\n * matches GoogleFontsPlugin logic.\n */\nfunction toPascalCase(str: string) {\n return str\n .split(/[- ]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\nexport function createTheme(\n config: ThemeConfig = DEFAULT_CONFIG,\n mode: 'light' | 'dark' = 'light',\n activeFontId?: string | null,\n): AnkhTheme {\n const { colors, scales, semantics } = generatePalette(config, mode);\n\n const theme = {\n ...DEFAULT_TOKENS,\n colors: colors as AnkhTheme['colors'],\n scales,\n semantics,\n config,\n };\n\n if (activeFontId) {\n const familyName = toPascalCase(activeFontId);\n const weights: FontWeight[] = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];\n\n weights.forEach((w) => {\n // Convention from GoogleFonts plugin: Family_WeightRegular\n theme.typography.fonts.normal[w] = `${familyName}_${w}Regular`;\n theme.typography.fonts.italic[w] = `${familyName}_${w}Italic`;\n });\n }\n\n return theme;\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';
2
- export type { ColorHarmony, SystemTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';
3
- export type ColorTone = 'jewel' | 'earth' | 'fluorescent' | 'grayscale' | 'pastel';
2
+ export type { ColorHarmony, ColorTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';
4
3
  export interface ColorScale {
5
4
  [key: number]: string;
6
5
  50: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';\n\nexport type { ColorHarmony, SystemTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';\n\nexport type ColorTone = 'jewel' | 'earth' | 'fluorescent' | 'grayscale' | 'pastel';\n\nexport interface ColorScale {\n [key: number]: string;\n 50: string;\n 100: string;\n 200: string;\n 300: string;\n 400: string;\n 500: string;\n 600: string;\n 700: string;\n 800: string;\n 900: string;\n 950: string;\n}\n\nexport interface NeutralSemantics {\n bg: string;\n bgSubtle: string;\n surface: string;\n surfaceHover: string;\n surfaceActive: string;\n border: string;\n borderStrong: string;\n divider: string;\n text: string;\n textMuted: string;\n textSubtle: string;\n}\n\nexport interface RoleSemantics {\n base: string;\n hover: string;\n strong: string;\n softBg: string;\n softHover: string;\n softActive: string;\n outline: string;\n onSolidText: string;\n}\n\nexport interface SurfaceSemantics {\n default: string;\n subtle: string;\n raised: string;\n}\n\nexport interface ContentSemantics {\n default: string;\n muted: string;\n subtle: string;\n inverse: string;\n}\n\nexport interface BorderSemantics {\n default: string;\n strong: string;\n focus: string;\n}\n\nexport interface ActionSemantics {\n primary: RoleSemantics;\n neutral: RoleSemantics;\n danger: RoleSemantics;\n}\n\nexport interface ThemeSemantics {\n neutral: NeutralSemantics;\n brand: RoleSemantics;\n secondary: RoleSemantics;\n accent: RoleSemantics;\n highlight: RoleSemantics;\n danger: RoleSemantics;\n success: RoleSemantics;\n warning: RoleSemantics;\n surface: SurfaceSemantics;\n content: ContentSemantics;\n border: BorderSemantics;\n action: ActionSemantics;\n}\n\nexport type FontWeight =\n | '100'\n | '200'\n | '300'\n | '400'\n | '500'\n | '600'\n | '700'\n | '800'\n | '900'\n | 'bold'\n | 'normal';\n\nexport interface ThemeTokens {\n colors: {\n primary: string;\n secondary: string;\n accent: string;\n highlight: string;\n background: string;\n surface: string;\n text: string;\n textSecondary: string;\n border: string;\n error: string;\n success: string;\n warning: string;\n [key: string]: string;\n };\n scales: Record<string, ColorScale>;\n semantics: ThemeSemantics;\n spacing: {\n none: 0;\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n [key: string]: number;\n };\n radii: {\n none: 0;\n s: number;\n m: number;\n l: number;\n full: number;\n };\n typography: {\n headings: Record<\n 1 | 2 | 3 | 4 | 5 | 6,\n {\n size: number;\n lineHeight: number;\n weight: 'regular' | 'medium' | 'semiBold' | 'bold';\n }\n >;\n sizes: {\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n '3xl': number;\n h1: number;\n h2: number;\n h3: number;\n h4: number;\n h5: number;\n h6: number;\n [key: string]: number;\n };\n weights: {\n thin: FontWeight;\n extraLight: FontWeight;\n light: FontWeight;\n regular: FontWeight;\n medium: FontWeight;\n semiBold: FontWeight;\n bold: FontWeight;\n extraBold: FontWeight;\n black: FontWeight;\n };\n fonts: {\n /** Map of weight -> fontFamily name for normal style */\n normal: Record<FontWeight, string | undefined>;\n /** Map of weight -> fontFamily name for italic style */\n italic: Record<FontWeight, string | undefined>;\n };\n };\n shadows: {\n soft: number;\n medium: number;\n hard: number;\n [key: string]: number;\n };\n}\n\nexport interface AnkhTheme extends ThemeTokens {\n config: ContractsThemeConfig;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';\n\nexport type { ColorHarmony, ColorTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';\n\nexport interface ColorScale {\n [key: number]: string;\n 50: string;\n 100: string;\n 200: string;\n 300: string;\n 400: string;\n 500: string;\n 600: string;\n 700: string;\n 800: string;\n 900: string;\n 950: string;\n}\n\nexport interface NeutralSemantics {\n bg: string;\n bgSubtle: string;\n surface: string;\n surfaceHover: string;\n surfaceActive: string;\n border: string;\n borderStrong: string;\n divider: string;\n text: string;\n textMuted: string;\n textSubtle: string;\n}\n\nexport interface RoleSemantics {\n base: string;\n hover: string;\n strong: string;\n softBg: string;\n softHover: string;\n softActive: string;\n outline: string;\n onSolidText: string;\n}\n\nexport interface SurfaceSemantics {\n default: string;\n subtle: string;\n raised: string;\n}\n\nexport interface ContentSemantics {\n default: string;\n muted: string;\n subtle: string;\n inverse: string;\n}\n\nexport interface BorderSemantics {\n default: string;\n strong: string;\n focus: string;\n}\n\nexport interface ActionSemantics {\n primary: RoleSemantics;\n neutral: RoleSemantics;\n danger: RoleSemantics;\n}\n\nexport interface ThemeSemantics {\n neutral: NeutralSemantics;\n brand: RoleSemantics;\n secondary: RoleSemantics;\n accent: RoleSemantics;\n highlight: RoleSemantics;\n danger: RoleSemantics;\n success: RoleSemantics;\n warning: RoleSemantics;\n surface: SurfaceSemantics;\n content: ContentSemantics;\n border: BorderSemantics;\n action: ActionSemantics;\n}\n\nexport type FontWeight =\n | '100'\n | '200'\n | '300'\n | '400'\n | '500'\n | '600'\n | '700'\n | '800'\n | '900'\n | 'bold'\n | 'normal';\n\nexport interface ThemeTokens {\n colors: {\n primary: string;\n secondary: string;\n accent: string;\n highlight: string;\n background: string;\n surface: string;\n text: string;\n textSecondary: string;\n border: string;\n error: string;\n success: string;\n warning: string;\n [key: string]: string;\n };\n scales: Record<string, ColorScale>;\n semantics: ThemeSemantics;\n spacing: {\n none: 0;\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n [key: string]: number;\n };\n radii: {\n none: 0;\n s: number;\n m: number;\n l: number;\n full: number;\n };\n typography: {\n headings: Record<\n 1 | 2 | 3 | 4 | 5 | 6,\n {\n size: number;\n lineHeight: number;\n weight: 'regular' | 'medium' | 'semiBold' | 'bold';\n }\n >;\n sizes: {\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n '3xl': number;\n h1: number;\n h2: number;\n h3: number;\n h4: number;\n h5: number;\n h6: number;\n [key: string]: number;\n };\n weights: {\n thin: FontWeight;\n extraLight: FontWeight;\n light: FontWeight;\n regular: FontWeight;\n medium: FontWeight;\n semiBold: FontWeight;\n bold: FontWeight;\n extraBold: FontWeight;\n black: FontWeight;\n };\n fonts: {\n /** Map of weight -> fontFamily name for normal style */\n normal: Record<FontWeight, string | undefined>;\n /** Map of weight -> fontFamily name for italic style */\n italic: Record<FontWeight, string | undefined>;\n };\n };\n shadows: {\n soft: number;\n medium: number;\n hard: number;\n [key: string]: number;\n };\n}\n\nexport interface AnkhTheme extends ThemeTokens {\n config: ContractsThemeConfig;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/surface",
3
3
  "type": "module",
4
- "version": "0.1.11",
4
+ "version": "0.2.0",
5
5
  "description": "Stable UI foundation for React Native and React Native Web.",
6
6
  "homepage": "https://github.com/ankhorage/surface#readme",
7
7
  "bugs": {
@@ -41,7 +41,8 @@
41
41
  }
42
42
  },
43
43
  "dependencies": {
44
- "@ankhorage/contracts": "^0.1.3",
44
+ "@ankhorage/contracts": "^0.2.0",
45
+ "@types/culori": "^4.0.1",
45
46
  "culori": "^4.0.2"
46
47
  },
47
48
  "files": [
@@ -80,7 +81,6 @@
80
81
  "@changesets/cli": "^2.31.0",
81
82
  "@expo/vector-icons": "^15.1.1",
82
83
  "@types/bun": "^1.3.13",
83
- "@types/culori": "^4.0.1",
84
84
  "@types/node": "^25.6.0",
85
85
  "@types/react": "^19.2.14",
86
86
  "react": "19.1.0",
@@ -30,12 +30,12 @@ const docsThemeConfig = {
30
30
  light: {
31
31
  harmony: 'monochromatic' as const,
32
32
  primaryColor: '#2563eb',
33
- systemTone: 'neutral' as const,
33
+ colorTone: 'neutral' as const,
34
34
  },
35
35
  dark: {
36
36
  harmony: 'monochromatic' as const,
37
37
  primaryColor: '#2563eb',
38
- systemTone: 'neutral' as const,
38
+ colorTone: 'neutral' as const,
39
39
  },
40
40
  };
41
41
 
@@ -10,12 +10,12 @@ const mockConfig: ThemeConfig = {
10
10
  light: {
11
11
  primaryColor: '#3B82F6',
12
12
  harmony: 'triadic',
13
- systemTone: 'neutral',
13
+ colorTone: 'neutral',
14
14
  },
15
15
  dark: {
16
16
  primaryColor: '#3B82F6',
17
17
  harmony: 'triadic',
18
- systemTone: 'neutral',
18
+ colorTone: 'neutral',
19
19
  },
20
20
  };
21
21
 
@@ -10,7 +10,6 @@ import type {
10
10
  NeutralSemantics,
11
11
  RoleSemantics,
12
12
  SurfaceSemantics,
13
- SystemTone,
14
13
  ThemeConfig,
15
14
  ThemeSemantics,
16
15
  } from './types';
@@ -26,6 +25,19 @@ interface OklchColor {
26
25
 
27
26
  export const SCALE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;
28
27
 
28
+ type RolePaletteKind =
29
+ | 'grayscale'
30
+ | 'neutral'
31
+ | 'pastel'
32
+ | 'earth'
33
+ | 'mineral'
34
+ | 'muted'
35
+ | 'jewel'
36
+ | 'fluorescent'
37
+ | 'obsidian'
38
+ | 'vaporwave'
39
+ | 'monochromeAccent';
40
+
29
41
  /**
30
42
  * Deterministic Lightness Curves (OKLCH L)
31
43
  */
@@ -35,14 +47,20 @@ const LIGHTNESS_CURVES = {
35
47
  } as const;
36
48
 
37
49
  /**
38
- * Lightness anchors per tone
50
+ * Lightness anchors per internal palette kind
39
51
  */
40
- const TONE_LIGHTNESS_ANCHORS: Record<ColorTone, number> = {
52
+ const ROLE_PALETTE_LIGHTNESS_ANCHORS: Record<RolePaletteKind, number> = {
41
53
  grayscale: 0.62,
42
- earth: 0.55,
54
+ neutral: 0.62,
43
55
  pastel: 0.7,
56
+ earth: 0.55,
57
+ mineral: 0.58,
58
+ muted: 0.6,
44
59
  jewel: 0.62,
45
60
  fluorescent: 0.65,
61
+ obsidian: 0.12,
62
+ vaporwave: 0.7,
63
+ monochromeAccent: 0.62,
46
64
  };
47
65
 
48
66
  /**
@@ -54,12 +72,18 @@ const CHROMA_BY_STEP = [0.1, 0.18, 0.3, 0.45, 0.7, 1.0, 0.92, 0.8, 0.6, 0.4, 0.2
54
72
  /**
55
73
  * Deterministic Chroma Anchors (OKLCH C)
56
74
  */
57
- const CHROMA_ANCHORS: Record<ColorTone, number> = {
75
+ const ROLE_PALETTE_CHROMA_ANCHORS: Record<RolePaletteKind, number> = {
58
76
  grayscale: 0,
59
- earth: 0.05,
77
+ neutral: 0.02,
60
78
  pastel: 0.08,
79
+ earth: 0.05,
80
+ mineral: 0.07,
81
+ muted: 0.04,
61
82
  jewel: 0.16,
62
83
  fluorescent: 0.26,
84
+ obsidian: 0.01,
85
+ vaporwave: 0.2,
86
+ monochromeAccent: 0.02,
63
87
  };
64
88
 
65
89
  /**
@@ -160,18 +184,15 @@ function getHarmonyHues(baseHue: number, mode: ColorHarmony): number[] {
160
184
  }
161
185
  }
162
186
 
163
- /**
164
- * System Tone Assignment Logic
165
- */
166
- function getSystemToneMapping(system: SystemTone): {
167
- bg: ColorTone;
168
- surface: ColorTone;
169
- primary: ColorTone;
170
- secondary: ColorTone;
171
- accent: ColorTone;
172
- highlight: ColorTone;
187
+ function getColorToneRolePalette(colorTone: ColorTone): {
188
+ bg: RolePaletteKind;
189
+ surface: RolePaletteKind;
190
+ primary: RolePaletteKind;
191
+ secondary: RolePaletteKind;
192
+ accent: RolePaletteKind;
193
+ highlight: RolePaletteKind;
173
194
  } {
174
- switch (system) {
195
+ switch (colorTone) {
175
196
  case 'pastel':
176
197
  return {
177
198
  bg: 'pastel',
@@ -181,6 +202,7 @@ function getSystemToneMapping(system: SystemTone): {
181
202
  accent: 'jewel',
182
203
  highlight: 'fluorescent',
183
204
  };
205
+
184
206
  case 'earth':
185
207
  return {
186
208
  bg: 'earth',
@@ -190,6 +212,27 @@ function getSystemToneMapping(system: SystemTone): {
190
212
  accent: 'jewel',
191
213
  highlight: 'jewel',
192
214
  };
215
+
216
+ case 'mineral':
217
+ return {
218
+ bg: 'mineral',
219
+ surface: 'mineral',
220
+ primary: 'jewel',
221
+ secondary: 'mineral',
222
+ accent: 'jewel',
223
+ highlight: 'fluorescent',
224
+ };
225
+
226
+ case 'muted':
227
+ return {
228
+ bg: 'muted',
229
+ surface: 'muted',
230
+ primary: 'jewel',
231
+ secondary: 'muted',
232
+ accent: 'jewel',
233
+ highlight: 'fluorescent',
234
+ };
235
+
193
236
  case 'jewel':
194
237
  return {
195
238
  bg: 'grayscale',
@@ -199,6 +242,7 @@ function getSystemToneMapping(system: SystemTone): {
199
242
  accent: 'jewel',
200
243
  highlight: 'fluorescent',
201
244
  };
245
+
202
246
  case 'fluorescent':
203
247
  return {
204
248
  bg: 'grayscale',
@@ -208,6 +252,37 @@ function getSystemToneMapping(system: SystemTone): {
208
252
  accent: 'fluorescent',
209
253
  highlight: 'fluorescent',
210
254
  };
255
+
256
+ case 'obsidian':
257
+ return {
258
+ bg: 'obsidian',
259
+ surface: 'obsidian',
260
+ primary: 'fluorescent',
261
+ secondary: 'jewel',
262
+ accent: 'fluorescent',
263
+ highlight: 'fluorescent',
264
+ };
265
+
266
+ case 'vaporwave':
267
+ return {
268
+ bg: 'pastel',
269
+ surface: 'pastel',
270
+ primary: 'fluorescent',
271
+ secondary: 'jewel',
272
+ accent: 'fluorescent',
273
+ highlight: 'fluorescent',
274
+ };
275
+
276
+ case 'monochromeAccent':
277
+ return {
278
+ bg: 'grayscale',
279
+ surface: 'grayscale',
280
+ primary: 'jewel',
281
+ secondary: 'grayscale',
282
+ accent: 'jewel',
283
+ highlight: 'fluorescent',
284
+ };
285
+
211
286
  default: // neutral
212
287
  return {
213
288
  bg: 'grayscale',
@@ -245,7 +320,7 @@ export function generatePalette(
245
320
  semantics: ThemeSemantics;
246
321
  } {
247
322
  const modeConfig = mode === 'dark' ? config.dark : config.light;
248
- const { primaryColor, harmony, systemTone } = modeConfig;
323
+ const { primaryColor, harmony, colorTone } = modeConfig;
249
324
 
250
325
  let base = oklch(primaryColor);
251
326
  if (!base) {
@@ -257,17 +332,17 @@ export function generatePalette(
257
332
 
258
333
  const baseHue = base?.h ?? 0;
259
334
  const hues = getHarmonyHues(baseHue, harmony);
260
- const toneMap = getSystemToneMapping(systemTone);
335
+ const rolePalette = getColorToneRolePalette(colorTone);
261
336
 
262
337
  // 1. Resolve Chromas
263
- const getC = (t: ColorTone) => CHROMA_ANCHORS[t];
338
+ const getC = (t: RolePaletteKind) => ROLE_PALETTE_CHROMA_ANCHORS[t];
264
339
  const getHue = (index: number, fallback: number) => hues[index] ?? fallback;
265
340
 
266
- const primaryChroma = getC(toneMap.primary);
267
- const secondaryChroma = getC(toneMap.secondary) * CHROMA_HIERARCHY.secondary;
268
- const tertiaryChroma = getC(toneMap.accent) * CHROMA_HIERARCHY.accent;
269
- const highlightChroma = getC(toneMap.highlight);
270
- const surfaceChroma = Math.min(0.02, getC(toneMap.bg) * CHROMA_HIERARCHY.surface);
341
+ const primaryChroma = getC(rolePalette.primary);
342
+ const secondaryChroma = getC(rolePalette.secondary) * CHROMA_HIERARCHY.secondary;
343
+ const tertiaryChroma = getC(rolePalette.accent) * CHROMA_HIERARCHY.accent;
344
+ const highlightChroma = getC(rolePalette.highlight);
345
+ const surfaceChroma = Math.min(0.02, getC(rolePalette.bg) * CHROMA_HIERARCHY.surface);
271
346
 
272
347
  // 2. Stable Role Assignment
273
348
  let pHue = getHue(0, baseHue);
@@ -302,29 +377,29 @@ export function generatePalette(
302
377
  }
303
378
 
304
379
  // 3. Build Bases with tuned lightness
305
- const getL = (t: ColorTone) => TONE_LIGHTNESS_ANCHORS[t];
380
+ const getL = (t: RolePaletteKind) => ROLE_PALETTE_LIGHTNESS_ANCHORS[t];
306
381
 
307
382
  const primaryBase: OklchColor = {
308
383
  mode: 'oklch',
309
- l: getL(toneMap.primary),
384
+ l: getL(rolePalette.primary),
310
385
  c: primaryChroma,
311
386
  h: pHue,
312
387
  };
313
388
  const secondaryBase: OklchColor = {
314
389
  mode: 'oklch',
315
- l: getL(toneMap.secondary),
390
+ l: getL(rolePalette.secondary),
316
391
  c: secondaryChroma,
317
392
  h: sHue,
318
393
  };
319
394
  const accentBase: OklchColor = {
320
395
  mode: 'oklch',
321
- l: getL(toneMap.accent),
396
+ l: getL(rolePalette.accent),
322
397
  c: tertiaryChroma,
323
398
  h: aHue,
324
399
  };
325
400
  const highlightBase: OklchColor = {
326
401
  mode: 'oklch',
327
- l: getL(toneMap.highlight),
402
+ l: getL(rolePalette.highlight),
328
403
  c: highlightChroma,
329
404
  h: hHue,
330
405
  };
@@ -71,12 +71,12 @@ export const DEFAULT_CONFIG: ThemeConfig = {
71
71
  light: {
72
72
  primaryColor: '#3B82F6',
73
73
  harmony: 'monochromatic',
74
- systemTone: 'neutral',
74
+ colorTone: 'neutral',
75
75
  },
76
76
  dark: {
77
77
  primaryColor: '#3B82F6',
78
78
  harmony: 'monochromatic',
79
- systemTone: 'neutral',
79
+ colorTone: 'neutral',
80
80
  },
81
81
  };
82
82
 
@@ -1,8 +1,6 @@
1
1
  import type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';
2
2
 
3
- export type { ColorHarmony, SystemTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';
4
-
5
- export type ColorTone = 'jewel' | 'earth' | 'fluorescent' | 'grayscale' | 'pastel';
3
+ export type { ColorHarmony, ColorTone, ThemeConfig, ThemeModeConfig } from '@ankhorage/contracts';
6
4
 
7
5
  export interface ColorScale {
8
6
  [key: number]: string;
@@ -85,12 +85,12 @@ describe('deepMerge', () => {
85
85
  light: {
86
86
  primaryColor: 'blue',
87
87
  harmony: 'monochromatic',
88
- systemTone: 'neutral',
88
+ colorTone: 'neutral',
89
89
  },
90
90
  dark: {
91
91
  primaryColor: 'blue',
92
92
  harmony: 'monochromatic',
93
- systemTone: 'neutral',
93
+ colorTone: 'neutral',
94
94
  },
95
95
  };
96
96
  const source: UnknownObject = {
@@ -105,12 +105,12 @@ describe('deepMerge', () => {
105
105
  light: {
106
106
  primaryColor: 'red',
107
107
  harmony: 'monochromatic',
108
- systemTone: 'neutral',
108
+ colorTone: 'neutral',
109
109
  },
110
110
  dark: {
111
111
  primaryColor: 'blue',
112
112
  harmony: 'monochromatic',
113
- systemTone: 'neutral',
113
+ colorTone: 'neutral',
114
114
  },
115
115
  });
116
116
  });