@hewnui/themes 0.0.0-stage → 0.1.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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -2
  3. package/dist/authoring/css-vars.d.ts +10 -0
  4. package/dist/authoring/css-vars.js +83 -0
  5. package/dist/authoring/derive.d.ts +9 -0
  6. package/dist/authoring/derive.js +79 -0
  7. package/dist/authoring/export-css.d.ts +8 -0
  8. package/dist/authoring/export-css.js +60 -0
  9. package/dist/authoring/export-design-md.d.ts +5 -0
  10. package/dist/authoring/export-design-md.js +113 -0
  11. package/dist/authoring/export-dtcg.d.ts +6 -0
  12. package/dist/authoring/export-dtcg.js +85 -0
  13. package/dist/authoring/export-figma.d.ts +27 -0
  14. package/dist/authoring/export-figma.js +76 -0
  15. package/dist/authoring/export-formats.d.ts +27 -0
  16. package/dist/authoring/export-formats.js +62 -0
  17. package/dist/authoring/export-skill.d.ts +5 -0
  18. package/dist/authoring/export-skill.js +75 -0
  19. package/dist/authoring/export-sticker.d.ts +6 -0
  20. package/dist/authoring/export-sticker.js +54 -0
  21. package/dist/authoring/export-style-dictionary.d.ts +3 -0
  22. package/dist/authoring/export-style-dictionary.js +52 -0
  23. package/dist/authoring/figma-kit.d.ts +16 -0
  24. package/dist/authoring/figma-kit.js +41 -0
  25. package/dist/authoring/index.d.ts +21 -0
  26. package/dist/authoring/index.js +18 -0
  27. package/dist/authoring/oklch.d.ts +11 -0
  28. package/dist/authoring/oklch.js +116 -0
  29. package/dist/authoring/override-map.d.ts +9 -0
  30. package/dist/authoring/override-map.js +150 -0
  31. package/dist/authoring/pack-def.d.ts +7 -0
  32. package/dist/authoring/pack-def.js +3 -0
  33. package/dist/authoring/pack-meta.d.ts +10 -0
  34. package/dist/authoring/pack-meta.js +58 -0
  35. package/dist/authoring/packs-dual.d.ts +129 -0
  36. package/dist/authoring/packs-dual.js +130 -0
  37. package/dist/authoring/packs-single.d.ts +87 -0
  38. package/dist/authoring/packs-single.js +88 -0
  39. package/dist/authoring/packs.d.ts +8 -0
  40. package/dist/authoring/packs.js +26 -0
  41. package/dist/authoring/pro-apply.d.ts +8 -0
  42. package/dist/authoring/pro-apply.js +107 -0
  43. package/dist/authoring/propose.d.ts +21 -0
  44. package/dist/authoring/propose.js +162 -0
  45. package/dist/authoring/ramps.d.ts +13 -0
  46. package/dist/authoring/ramps.js +40 -0
  47. package/dist/authoring/status-ramps.d.ts +13 -0
  48. package/dist/authoring/status-ramps.js +76 -0
  49. package/dist/authoring/token-entries.d.ts +10 -0
  50. package/dist/authoring/token-entries.js +52 -0
  51. package/dist/authoring/types.d.ts +110 -0
  52. package/dist/authoring/types.js +11 -0
  53. package/exports/clay/DESIGN.md +138 -0
  54. package/exports/clay/SKILL.md +94 -0
  55. package/exports/clay/theme.css +37 -0
  56. package/exports/clay/tokens.dtcg.json +200 -0
  57. package/exports/dune/DESIGN.md +138 -0
  58. package/exports/dune/SKILL.md +94 -0
  59. package/exports/dune/theme.css +37 -0
  60. package/exports/dune/tokens.dtcg.json +200 -0
  61. package/exports/ember/DESIGN.md +138 -0
  62. package/exports/ember/SKILL.md +94 -0
  63. package/exports/ember/theme.css +37 -0
  64. package/exports/ember/tokens.dtcg.json +200 -0
  65. package/exports/forest/DESIGN.md +138 -0
  66. package/exports/forest/SKILL.md +94 -0
  67. package/exports/forest/theme.css +67 -0
  68. package/exports/forest/tokens.dtcg.json +348 -0
  69. package/exports/graphite/DESIGN.md +138 -0
  70. package/exports/graphite/SKILL.md +94 -0
  71. package/exports/graphite/theme.css +67 -0
  72. package/exports/graphite/tokens.dtcg.json +348 -0
  73. package/exports/index.json +45 -0
  74. package/exports/tide/DESIGN.md +138 -0
  75. package/exports/tide/SKILL.md +94 -0
  76. package/exports/tide/theme.css +67 -0
  77. package/exports/tide/tokens.dtcg.json +348 -0
  78. package/figma/README.md +16 -0
  79. package/figma/hewn.tokens.json +1308 -0
  80. package/figma/sticker-sheet.svg +93 -0
  81. package/package.json +98 -4
  82. package/src/authoring/css-vars.ts +92 -0
  83. package/src/authoring/derive.ts +106 -0
  84. package/src/authoring/export-css.ts +86 -0
  85. package/src/authoring/export-design-md.ts +134 -0
  86. package/src/authoring/export-dtcg.ts +116 -0
  87. package/src/authoring/export-figma.ts +109 -0
  88. package/src/authoring/export-formats.ts +101 -0
  89. package/src/authoring/export-skill.ts +93 -0
  90. package/src/authoring/export-sticker.ts +60 -0
  91. package/src/authoring/export-style-dictionary.ts +67 -0
  92. package/src/authoring/figma-kit.ts +60 -0
  93. package/src/authoring/index.ts +61 -0
  94. package/src/authoring/oklch.ts +137 -0
  95. package/src/authoring/override-map.ts +191 -0
  96. package/src/authoring/pack-def.ts +11 -0
  97. package/src/authoring/pack-meta.ts +66 -0
  98. package/src/authoring/packs-dual.ts +131 -0
  99. package/src/authoring/packs-single.ts +89 -0
  100. package/src/authoring/packs.ts +43 -0
  101. package/src/authoring/pro-apply.ts +156 -0
  102. package/src/authoring/propose.ts +181 -0
  103. package/src/authoring/ramps.ts +62 -0
  104. package/src/authoring/status-ramps.ts +98 -0
  105. package/src/authoring/token-entries.ts +59 -0
  106. package/src/authoring/types.ts +133 -0
  107. package/src/glass-buttons.css +46 -0
  108. package/src/glass.css +266 -0
  109. package/src/motion.css +60 -0
  110. package/src/packs/clay.css +45 -0
  111. package/src/packs/dune.css +45 -0
  112. package/src/packs/ember.css +45 -0
  113. package/src/packs/forest.css +80 -0
  114. package/src/packs/graphite.css +79 -0
  115. package/src/packs/tide.css +79 -0
  116. package/src/radius.css +25 -0
  117. package/src/tokens.css +104 -0
@@ -0,0 +1,3 @@
1
+ export function o(l, c, h, alpha) {
2
+ return alpha === undefined ? { l, c, h } : { l, c, h, alpha };
3
+ }
@@ -0,0 +1,10 @@
1
+ import type { BasePackId } from "./types";
2
+ /** Curated pack identity copy — mirrors docs/design-hewn-v2.md. */
3
+ export declare const PACK_IDENTITY: Record<BasePackId, {
4
+ label: string;
5
+ summary: string;
6
+ }>;
7
+ export declare const COLOR_ROLES: Record<string, string>;
8
+ /** Shared design rules for DESIGN.md and agent skills. */
9
+ export declare const DESIGN_DO: readonly ["Use semantic OKLCH tokens (`--kp-*` / `--color-*`); never hard-code theme hues.", "Typography: IBM Plex Sans (UI), IBM Plex Mono (code/labels), Space Grotesk only for marketing hero H1 and brand wordmark ≥18px.", "Icons: Phosphor. Interactive hit targets ≥40×40px; press feedback `scale(0.96)`.", "Motion: animate transform, opacity, and filter; reduced motion always wins.", "Radius: concentric scale; panels use `--kp-radius-panel` (never full-pill menus/dialogs).", "Glass is a global material — tint, blur, saturation, refraction edge, opaque fallback."];
10
+ export declare const DESIGN_DONT: readonly ["No purple/lila defaults, neon glow, pure black, Inter, emoji, or generic centered heroes.", "Never `transition: all` — list exact properties.", "Never `h-screen` for full-height sections — use `min-h-[100dvh]`.", "No per-component `glass` prop; material is global.", "Do not invent unsupported light/dark combinations for a pack.", "Do not put Space Grotesk in UI chrome, forms, or dense product copy."];
@@ -0,0 +1,58 @@
1
+ /** Curated pack identity copy — mirrors docs/design-hewn-v2.md. */
2
+ export const PACK_IDENTITY = {
3
+ forest: {
4
+ label: "Forest",
5
+ summary: "Moss and emerald; grounded organic product UI.",
6
+ },
7
+ tide: {
8
+ label: "Tide",
9
+ summary: "Mineral neutrals and desaturated teal.",
10
+ },
11
+ graphite: {
12
+ label: "Graphite",
13
+ summary: "Technical neutral and restrained steel-blue.",
14
+ },
15
+ dune: {
16
+ label: "Dune",
17
+ summary: "Sand, ochre, soft paper surfaces.",
18
+ },
19
+ clay: {
20
+ label: "Clay",
21
+ summary: "Warm stone and terracotta.",
22
+ },
23
+ ember: {
24
+ label: "Ember",
25
+ summary: "Charcoal and burnt orange.",
26
+ },
27
+ };
28
+ export const COLOR_ROLES = {
29
+ background: "Page and app canvas",
30
+ foreground: "Primary text and icons",
31
+ surface: "Cards, panels, and elevated chrome",
32
+ "surface-raised": "Overlays and nested elevation",
33
+ muted: "Subtle fills and disabled wells",
34
+ "muted-foreground": "Secondary text and captions",
35
+ accent: "Primary actions and focus accents",
36
+ "accent-foreground": "Text/icons on accent",
37
+ border: "Separators and control outlines",
38
+ ring: "Focus ring",
39
+ danger: "Destructive and error states",
40
+ "glass-tint": "Tinted frosted glass material",
41
+ };
42
+ /** Shared design rules for DESIGN.md and agent skills. */
43
+ export const DESIGN_DO = [
44
+ "Use semantic OKLCH tokens (`--kp-*` / `--color-*`); never hard-code theme hues.",
45
+ "Typography: IBM Plex Sans (UI), IBM Plex Mono (code/labels), Space Grotesk only for marketing hero H1 and brand wordmark ≥18px.",
46
+ "Icons: Phosphor. Interactive hit targets ≥40×40px; press feedback `scale(0.96)`.",
47
+ "Motion: animate transform, opacity, and filter; reduced motion always wins.",
48
+ "Radius: concentric scale; panels use `--kp-radius-panel` (never full-pill menus/dialogs).",
49
+ "Glass is a global material — tint, blur, saturation, refraction edge, opaque fallback.",
50
+ ];
51
+ export const DESIGN_DONT = [
52
+ "No purple/lila defaults, neon glow, pure black, Inter, emoji, or generic centered heroes.",
53
+ "Never `transition: all` — list exact properties.",
54
+ "Never `h-screen` for full-height sections — use `min-h-[100dvh]`.",
55
+ "No per-component `glass` prop; material is global.",
56
+ "Do not invent unsupported light/dark combinations for a pack.",
57
+ "Do not put Space Grotesk in UI chrome, forms, or dense product copy.",
58
+ ];
@@ -0,0 +1,129 @@
1
+ /** Dual-mode curated packs. Keep in sync with src/packs/*.css. */
2
+ export declare const DUAL_PACKS: {
3
+ readonly forest: {
4
+ readonly structural: {
5
+ readonly radiusSm: "0.5rem";
6
+ readonly radiusMd: "0.75rem";
7
+ readonly radiusLg: "1rem";
8
+ readonly radiusPanel: "1rem";
9
+ readonly density: 1;
10
+ readonly motionDuration: "260ms";
11
+ readonly motionStiffness: 360;
12
+ readonly motionDamping: 28;
13
+ };
14
+ readonly modes: {
15
+ readonly light: {
16
+ readonly background: import("./types").Oklch;
17
+ readonly foreground: import("./types").Oklch;
18
+ readonly surface: import("./types").Oklch;
19
+ readonly surfaceRaised: import("./types").Oklch;
20
+ readonly muted: import("./types").Oklch;
21
+ readonly mutedForeground: import("./types").Oklch;
22
+ readonly accent: import("./types").Oklch;
23
+ readonly accentForeground: import("./types").Oklch;
24
+ readonly border: import("./types").Oklch;
25
+ readonly ring: import("./types").Oklch;
26
+ readonly danger: import("./types").Oklch;
27
+ readonly glassTint: import("./types").Oklch;
28
+ };
29
+ readonly dark: {
30
+ readonly background: import("./types").Oklch;
31
+ readonly foreground: import("./types").Oklch;
32
+ readonly surface: import("./types").Oklch;
33
+ readonly surfaceRaised: import("./types").Oklch;
34
+ readonly muted: import("./types").Oklch;
35
+ readonly mutedForeground: import("./types").Oklch;
36
+ readonly accent: import("./types").Oklch;
37
+ readonly accentForeground: import("./types").Oklch;
38
+ readonly border: import("./types").Oklch;
39
+ readonly ring: import("./types").Oklch;
40
+ readonly danger: import("./types").Oklch;
41
+ readonly glassTint: import("./types").Oklch;
42
+ };
43
+ };
44
+ };
45
+ readonly tide: {
46
+ readonly structural: {
47
+ readonly radiusSm: "0.45rem";
48
+ readonly radiusMd: "0.7rem";
49
+ readonly radiusLg: "0.95rem";
50
+ readonly radiusPanel: "0.95rem";
51
+ readonly density: 1;
52
+ readonly motionDuration: "240ms";
53
+ readonly motionStiffness: 380;
54
+ readonly motionDamping: 30;
55
+ };
56
+ readonly modes: {
57
+ readonly light: {
58
+ readonly background: import("./types").Oklch;
59
+ readonly foreground: import("./types").Oklch;
60
+ readonly surface: import("./types").Oklch;
61
+ readonly surfaceRaised: import("./types").Oklch;
62
+ readonly muted: import("./types").Oklch;
63
+ readonly mutedForeground: import("./types").Oklch;
64
+ readonly accent: import("./types").Oklch;
65
+ readonly accentForeground: import("./types").Oklch;
66
+ readonly border: import("./types").Oklch;
67
+ readonly ring: import("./types").Oklch;
68
+ readonly danger: import("./types").Oklch;
69
+ readonly glassTint: import("./types").Oklch;
70
+ };
71
+ readonly dark: {
72
+ readonly background: import("./types").Oklch;
73
+ readonly foreground: import("./types").Oklch;
74
+ readonly surface: import("./types").Oklch;
75
+ readonly surfaceRaised: import("./types").Oklch;
76
+ readonly muted: import("./types").Oklch;
77
+ readonly mutedForeground: import("./types").Oklch;
78
+ readonly accent: import("./types").Oklch;
79
+ readonly accentForeground: import("./types").Oklch;
80
+ readonly border: import("./types").Oklch;
81
+ readonly ring: import("./types").Oklch;
82
+ readonly danger: import("./types").Oklch;
83
+ readonly glassTint: import("./types").Oklch;
84
+ };
85
+ };
86
+ };
87
+ readonly graphite: {
88
+ readonly structural: {
89
+ readonly radiusSm: "0.4rem";
90
+ readonly radiusMd: "0.6rem";
91
+ readonly radiusLg: "0.85rem";
92
+ readonly radiusPanel: "0.85rem";
93
+ readonly density: 1.05;
94
+ readonly motionDuration: "220ms";
95
+ readonly motionStiffness: 420;
96
+ readonly motionDamping: 32;
97
+ };
98
+ readonly modes: {
99
+ readonly light: {
100
+ readonly background: import("./types").Oklch;
101
+ readonly foreground: import("./types").Oklch;
102
+ readonly surface: import("./types").Oklch;
103
+ readonly surfaceRaised: import("./types").Oklch;
104
+ readonly muted: import("./types").Oklch;
105
+ readonly mutedForeground: import("./types").Oklch;
106
+ readonly accent: import("./types").Oklch;
107
+ readonly accentForeground: import("./types").Oklch;
108
+ readonly border: import("./types").Oklch;
109
+ readonly ring: import("./types").Oklch;
110
+ readonly danger: import("./types").Oklch;
111
+ readonly glassTint: import("./types").Oklch;
112
+ };
113
+ readonly dark: {
114
+ readonly background: import("./types").Oklch;
115
+ readonly foreground: import("./types").Oklch;
116
+ readonly surface: import("./types").Oklch;
117
+ readonly surfaceRaised: import("./types").Oklch;
118
+ readonly muted: import("./types").Oklch;
119
+ readonly mutedForeground: import("./types").Oklch;
120
+ readonly accent: import("./types").Oklch;
121
+ readonly accentForeground: import("./types").Oklch;
122
+ readonly border: import("./types").Oklch;
123
+ readonly ring: import("./types").Oklch;
124
+ readonly danger: import("./types").Oklch;
125
+ readonly glassTint: import("./types").Oklch;
126
+ };
127
+ };
128
+ };
129
+ };
@@ -0,0 +1,130 @@
1
+ import { o } from "./pack-def.js";
2
+ /** Dual-mode curated packs. Keep in sync with src/packs/*.css. */
3
+ export const DUAL_PACKS = {
4
+ forest: {
5
+ structural: {
6
+ radiusSm: "0.5rem",
7
+ radiusMd: "0.75rem",
8
+ radiusLg: "1rem",
9
+ radiusPanel: "1rem",
10
+ density: 1,
11
+ motionDuration: "260ms",
12
+ motionStiffness: 360,
13
+ motionDamping: 28,
14
+ },
15
+ modes: {
16
+ light: {
17
+ background: o(0.972, 0.012, 145),
18
+ foreground: o(0.225, 0.028, 145),
19
+ surface: o(0.995, 0.004, 145),
20
+ surfaceRaised: o(1, 0, 0),
21
+ muted: o(0.925, 0.022, 145),
22
+ mutedForeground: o(0.49, 0.035, 145),
23
+ accent: o(0.49, 0.105, 148),
24
+ accentForeground: o(0.985, 0.008, 145),
25
+ border: o(0.36, 0.035, 145, 0.14),
26
+ ring: o(0.55, 0.12, 148),
27
+ danger: o(0.56, 0.17, 27),
28
+ glassTint: o(0.72, 0.12, 148, 0.28),
29
+ },
30
+ dark: {
31
+ background: o(0.185, 0.018, 145),
32
+ foreground: o(0.93, 0.018, 145),
33
+ surface: o(0.225, 0.024, 145),
34
+ surfaceRaised: o(0.265, 0.028, 145),
35
+ muted: o(0.285, 0.026, 145),
36
+ mutedForeground: o(0.715, 0.03, 145),
37
+ accent: o(0.71, 0.12, 148),
38
+ accentForeground: o(0.985, 0.01, 145),
39
+ border: o(0.86, 0.025, 145, 0.13),
40
+ ring: o(0.71, 0.12, 148),
41
+ danger: o(0.68, 0.16, 27),
42
+ glassTint: o(0.63, 0.13, 148, 0.24),
43
+ },
44
+ },
45
+ },
46
+ tide: {
47
+ structural: {
48
+ radiusSm: "0.45rem",
49
+ radiusMd: "0.7rem",
50
+ radiusLg: "0.95rem",
51
+ radiusPanel: "0.95rem",
52
+ density: 1,
53
+ motionDuration: "240ms",
54
+ motionStiffness: 380,
55
+ motionDamping: 30,
56
+ },
57
+ modes: {
58
+ light: {
59
+ background: o(0.97, 0.01, 220),
60
+ foreground: o(0.24, 0.03, 230),
61
+ surface: o(0.995, 0.004, 220),
62
+ surfaceRaised: o(1, 0, 0),
63
+ muted: o(0.93, 0.015, 220),
64
+ mutedForeground: o(0.48, 0.03, 230),
65
+ accent: o(0.52, 0.07, 210),
66
+ accentForeground: o(0.98, 0.01, 210),
67
+ border: o(0.35, 0.03, 230, 0.14),
68
+ ring: o(0.58, 0.08, 210),
69
+ danger: o(0.56, 0.17, 27),
70
+ glassTint: o(0.72, 0.08, 210, 0.28),
71
+ },
72
+ dark: {
73
+ background: o(0.18, 0.02, 230),
74
+ foreground: o(0.92, 0.015, 220),
75
+ surface: o(0.22, 0.025, 230),
76
+ surfaceRaised: o(0.26, 0.028, 230),
77
+ muted: o(0.28, 0.025, 230),
78
+ mutedForeground: o(0.72, 0.025, 220),
79
+ accent: o(0.72, 0.08, 205),
80
+ accentForeground: o(0.985, 0.01, 220),
81
+ border: o(0.86, 0.02, 220, 0.13),
82
+ ring: o(0.72, 0.08, 205),
83
+ danger: o(0.68, 0.16, 27),
84
+ glassTint: o(0.6, 0.09, 205, 0.24),
85
+ },
86
+ },
87
+ },
88
+ graphite: {
89
+ structural: {
90
+ radiusSm: "0.4rem",
91
+ radiusMd: "0.6rem",
92
+ radiusLg: "0.85rem",
93
+ radiusPanel: "0.85rem",
94
+ density: 1.05,
95
+ motionDuration: "220ms",
96
+ motionStiffness: 420,
97
+ motionDamping: 32,
98
+ },
99
+ modes: {
100
+ light: {
101
+ background: o(0.965, 0.005, 255),
102
+ foreground: o(0.23, 0.02, 255),
103
+ surface: o(0.99, 0.003, 255),
104
+ surfaceRaised: o(1, 0, 0),
105
+ muted: o(0.925, 0.008, 255),
106
+ mutedForeground: o(0.47, 0.02, 255),
107
+ accent: o(0.48, 0.06, 250),
108
+ accentForeground: o(0.98, 0.01, 250),
109
+ border: o(0.34, 0.02, 255, 0.14),
110
+ ring: o(0.55, 0.07, 250),
111
+ danger: o(0.55, 0.17, 27),
112
+ glassTint: o(0.7, 0.06, 250, 0.26),
113
+ },
114
+ dark: {
115
+ background: o(0.17, 0.012, 255),
116
+ foreground: o(0.93, 0.01, 255),
117
+ surface: o(0.21, 0.015, 255),
118
+ surfaceRaised: o(0.25, 0.018, 255),
119
+ muted: o(0.27, 0.016, 255),
120
+ mutedForeground: o(0.715, 0.015, 255),
121
+ accent: o(0.7, 0.07, 245),
122
+ accentForeground: o(0.985, 0.008, 255),
123
+ border: o(0.85, 0.012, 255, 0.12),
124
+ ring: o(0.7, 0.07, 245),
125
+ danger: o(0.68, 0.16, 27),
126
+ glassTint: o(0.58, 0.07, 245, 0.22),
127
+ },
128
+ },
129
+ },
130
+ };
@@ -0,0 +1,87 @@
1
+ /** Single-mode curated packs. Keep in sync with src/packs/*.css. */
2
+ export declare const SINGLE_PACKS: {
3
+ readonly dune: {
4
+ readonly structural: {
5
+ readonly radiusSm: "0.55rem";
6
+ readonly radiusMd: "0.85rem";
7
+ readonly radiusLg: "1.15rem";
8
+ readonly radiusPanel: "1.15rem";
9
+ readonly density: 0.95;
10
+ readonly motionDuration: "280ms";
11
+ readonly motionStiffness: 300;
12
+ readonly motionDamping: 26;
13
+ };
14
+ readonly modes: {
15
+ readonly light: {
16
+ readonly background: import("./types").Oklch;
17
+ readonly foreground: import("./types").Oklch;
18
+ readonly surface: import("./types").Oklch;
19
+ readonly surfaceRaised: import("./types").Oklch;
20
+ readonly muted: import("./types").Oklch;
21
+ readonly mutedForeground: import("./types").Oklch;
22
+ readonly accent: import("./types").Oklch;
23
+ readonly accentForeground: import("./types").Oklch;
24
+ readonly border: import("./types").Oklch;
25
+ readonly ring: import("./types").Oklch;
26
+ readonly danger: import("./types").Oklch;
27
+ readonly glassTint: import("./types").Oklch;
28
+ };
29
+ };
30
+ };
31
+ readonly clay: {
32
+ readonly structural: {
33
+ readonly radiusSm: "0.5rem";
34
+ readonly radiusMd: "0.8rem";
35
+ readonly radiusLg: "1.05rem";
36
+ readonly radiusPanel: "1.05rem";
37
+ readonly density: 1;
38
+ readonly motionDuration: "270ms";
39
+ readonly motionStiffness: 320;
40
+ readonly motionDamping: 27;
41
+ };
42
+ readonly modes: {
43
+ readonly light: {
44
+ readonly background: import("./types").Oklch;
45
+ readonly foreground: import("./types").Oklch;
46
+ readonly surface: import("./types").Oklch;
47
+ readonly surfaceRaised: import("./types").Oklch;
48
+ readonly muted: import("./types").Oklch;
49
+ readonly mutedForeground: import("./types").Oklch;
50
+ readonly accent: import("./types").Oklch;
51
+ readonly accentForeground: import("./types").Oklch;
52
+ readonly border: import("./types").Oklch;
53
+ readonly ring: import("./types").Oklch;
54
+ readonly danger: import("./types").Oklch;
55
+ readonly glassTint: import("./types").Oklch;
56
+ };
57
+ };
58
+ };
59
+ readonly ember: {
60
+ readonly structural: {
61
+ readonly radiusSm: "0.45rem";
62
+ readonly radiusMd: "0.7rem";
63
+ readonly radiusLg: "0.95rem";
64
+ readonly radiusPanel: "0.95rem";
65
+ readonly density: 1.05;
66
+ readonly motionDuration: "230ms";
67
+ readonly motionStiffness: 400;
68
+ readonly motionDamping: 28;
69
+ };
70
+ readonly modes: {
71
+ readonly dark: {
72
+ readonly background: import("./types").Oklch;
73
+ readonly foreground: import("./types").Oklch;
74
+ readonly surface: import("./types").Oklch;
75
+ readonly surfaceRaised: import("./types").Oklch;
76
+ readonly muted: import("./types").Oklch;
77
+ readonly mutedForeground: import("./types").Oklch;
78
+ readonly accent: import("./types").Oklch;
79
+ readonly accentForeground: import("./types").Oklch;
80
+ readonly border: import("./types").Oklch;
81
+ readonly ring: import("./types").Oklch;
82
+ readonly danger: import("./types").Oklch;
83
+ readonly glassTint: import("./types").Oklch;
84
+ };
85
+ };
86
+ };
87
+ };
@@ -0,0 +1,88 @@
1
+ import { o } from "./pack-def.js";
2
+ /** Single-mode curated packs. Keep in sync with src/packs/*.css. */
3
+ export const SINGLE_PACKS = {
4
+ dune: {
5
+ structural: {
6
+ radiusSm: "0.55rem",
7
+ radiusMd: "0.85rem",
8
+ radiusLg: "1.15rem",
9
+ radiusPanel: "1.15rem",
10
+ density: 0.95,
11
+ motionDuration: "280ms",
12
+ motionStiffness: 300,
13
+ motionDamping: 26,
14
+ },
15
+ modes: {
16
+ light: {
17
+ background: o(0.96, 0.02, 85),
18
+ foreground: o(0.28, 0.04, 65),
19
+ surface: o(0.985, 0.012, 90),
20
+ surfaceRaised: o(0.995, 0.006, 95),
21
+ muted: o(0.92, 0.025, 85),
22
+ mutedForeground: o(0.5, 0.04, 70),
23
+ accent: o(0.58, 0.11, 70),
24
+ accentForeground: o(0.98, 0.01, 90),
25
+ border: o(0.4, 0.04, 70, 0.16),
26
+ ring: o(0.62, 0.12, 70),
27
+ danger: o(0.55, 0.16, 30),
28
+ glassTint: o(0.78, 0.09, 80, 0.3),
29
+ },
30
+ },
31
+ },
32
+ clay: {
33
+ structural: {
34
+ radiusSm: "0.5rem",
35
+ radiusMd: "0.8rem",
36
+ radiusLg: "1.05rem",
37
+ radiusPanel: "1.05rem",
38
+ density: 1,
39
+ motionDuration: "270ms",
40
+ motionStiffness: 320,
41
+ motionDamping: 27,
42
+ },
43
+ modes: {
44
+ light: {
45
+ background: o(0.955, 0.02, 55),
46
+ foreground: o(0.27, 0.045, 40),
47
+ surface: o(0.98, 0.012, 50),
48
+ surfaceRaised: o(0.995, 0.006, 45),
49
+ muted: o(0.915, 0.025, 50),
50
+ mutedForeground: o(0.5, 0.045, 40),
51
+ accent: o(0.55, 0.12, 40),
52
+ accentForeground: o(0.98, 0.01, 50),
53
+ border: o(0.4, 0.05, 40, 0.16),
54
+ ring: o(0.6, 0.13, 40),
55
+ danger: o(0.54, 0.17, 28),
56
+ glassTint: o(0.74, 0.1, 45, 0.28),
57
+ },
58
+ },
59
+ },
60
+ ember: {
61
+ structural: {
62
+ radiusSm: "0.45rem",
63
+ radiusMd: "0.7rem",
64
+ radiusLg: "0.95rem",
65
+ radiusPanel: "0.95rem",
66
+ density: 1.05,
67
+ motionDuration: "230ms",
68
+ motionStiffness: 400,
69
+ motionDamping: 28,
70
+ },
71
+ modes: {
72
+ dark: {
73
+ background: o(0.17, 0.02, 40),
74
+ foreground: o(0.93, 0.02, 70),
75
+ surface: o(0.21, 0.025, 40),
76
+ surfaceRaised: o(0.255, 0.03, 42),
77
+ muted: o(0.275, 0.028, 40),
78
+ mutedForeground: o(0.72, 0.03, 60),
79
+ accent: o(0.7, 0.15, 50),
80
+ accentForeground: o(0.985, 0.015, 50),
81
+ border: o(0.84, 0.03, 60, 0.14),
82
+ ring: o(0.7, 0.15, 50),
83
+ danger: o(0.66, 0.17, 28),
84
+ glassTint: o(0.58, 0.15, 50, 0.28),
85
+ },
86
+ },
87
+ },
88
+ };
@@ -0,0 +1,8 @@
1
+ import type { BasePackId, ModeColorTokens, StructuralTokens, ThemeMode } from "./types";
2
+ export type ResolvedPackDef = {
3
+ modes: Partial<Record<ThemeMode, ModeColorTokens>>;
4
+ structural: StructuralTokens;
5
+ };
6
+ /** Curated pack color bases (mirrors CSS packs), including status families. */
7
+ export declare const BASE_PACKS: Record<BasePackId, ResolvedPackDef>;
8
+ export declare function supportedModes(packId: BasePackId): ThemeMode[];
@@ -0,0 +1,26 @@
1
+ import { DUAL_PACKS } from "./packs-dual.js";
2
+ import { SINGLE_PACKS } from "./packs-single.js";
3
+ import { PACK_STATUS_HUES, statusColors } from "./status-ramps.js";
4
+ function withStatus(id, def) {
5
+ const hues = PACK_STATUS_HUES[id];
6
+ const modes = {};
7
+ for (const [mode, colors] of Object.entries(def.modes)) {
8
+ modes[mode] = {
9
+ ...colors,
10
+ ...statusColors(mode, colors.danger, hues),
11
+ };
12
+ }
13
+ return { structural: def.structural, modes };
14
+ }
15
+ /** Curated pack color bases (mirrors CSS packs), including status families. */
16
+ export const BASE_PACKS = {
17
+ forest: withStatus("forest", DUAL_PACKS.forest),
18
+ tide: withStatus("tide", DUAL_PACKS.tide),
19
+ graphite: withStatus("graphite", DUAL_PACKS.graphite),
20
+ dune: withStatus("dune", SINGLE_PACKS.dune),
21
+ clay: withStatus("clay", SINGLE_PACKS.clay),
22
+ ember: withStatus("ember", SINGLE_PACKS.ember),
23
+ };
24
+ export function supportedModes(packId) {
25
+ return Object.keys(BASE_PACKS[packId].modes);
26
+ }
@@ -0,0 +1,8 @@
1
+ import type { GlassOverrides, ModeColorTokens, NeutralOverrides, OverrideMap, SemanticOverrides, ShapeOverrides, StructuralTokens, ThemeMode } from "./types";
2
+ export declare function applyNeutrals(colors: ModeColorTokens, neutrals: NeutralOverrides | undefined, mode: ThemeMode, adjustments: string[]): ModeColorTokens;
3
+ export declare function applySemantic(colors: ModeColorTokens, semantic: SemanticOverrides | undefined, mode: ThemeMode, adjustments: string[]): ModeColorTokens | {
4
+ error: string;
5
+ };
6
+ export declare function applyGlass(colors: ModeColorTokens, glass: GlassOverrides | undefined): ModeColorTokens;
7
+ export declare function applyShape(structural: StructuralTokens, shape: ShapeOverrides | undefined): StructuralTokens;
8
+ export declare function applyMotion(structural: StructuralTokens, motion: OverrideMap["motion"]): StructuralTokens;
@@ -0,0 +1,107 @@
1
+ import { contrastForeground, parseColor } from "./oklch.js";
2
+ import { statusColors } from "./status-ramps.js";
3
+ const DENSITY = {
4
+ compact: 0.85,
5
+ default: 1,
6
+ comfortable: 1.15,
7
+ };
8
+ const MOTION = {
9
+ snappy: {
10
+ motionDuration: "180ms",
11
+ motionStiffness: 480,
12
+ motionDamping: 32,
13
+ },
14
+ soft: {
15
+ motionDuration: "340ms",
16
+ motionStiffness: 220,
17
+ motionDamping: 26,
18
+ },
19
+ };
20
+ function clampL(color, delta) {
21
+ return { ...color, l: Math.min(0.99, Math.max(0.05, color.l + delta)) };
22
+ }
23
+ function scaleC(color, scale) {
24
+ return { ...color, c: Math.max(0, color.c * scale) };
25
+ }
26
+ function biasNeutral(color, n) {
27
+ let next = color;
28
+ if (n.surfaceShift !== undefined)
29
+ next = clampL(next, n.surfaceShift);
30
+ if (n.chromaScale !== undefined)
31
+ next = scaleC(next, n.chromaScale);
32
+ return next;
33
+ }
34
+ export function applyNeutrals(colors, neutrals, mode, adjustments) {
35
+ if (!neutrals)
36
+ return colors;
37
+ if (neutrals.surfaceShift === undefined &&
38
+ neutrals.chromaScale === undefined) {
39
+ return colors;
40
+ }
41
+ const next = {
42
+ ...colors,
43
+ background: biasNeutral(colors.background, neutrals),
44
+ surface: biasNeutral(colors.surface, neutrals),
45
+ surfaceRaised: biasNeutral(colors.surfaceRaised, neutrals),
46
+ muted: biasNeutral(colors.muted, neutrals),
47
+ border: biasNeutral(colors.border, neutrals),
48
+ };
49
+ const fg = contrastForeground(next.background, colors.foreground);
50
+ if (fg.adjusted) {
51
+ next.foreground = fg.color;
52
+ adjustments.push(`${mode} foreground adjusted after neutral bias to meet WCAG AA`);
53
+ }
54
+ else {
55
+ next.foreground = colors.foreground;
56
+ }
57
+ const mutedFg = contrastForeground(next.muted, colors.mutedForeground, 3);
58
+ next.mutedForeground = mutedFg.color;
59
+ return next;
60
+ }
61
+ export function applySemantic(colors, semantic, mode, adjustments) {
62
+ if (!semantic?.dangerSeed)
63
+ return colors;
64
+ const seed = parseColor(semantic.dangerSeed);
65
+ if (!seed)
66
+ return { error: `invalid danger seed: "${semantic.dangerSeed}"` };
67
+ const danger = mode === "dark"
68
+ ? { ...seed, l: Math.min(0.78, Math.max(0.58, seed.l + 0.08)) }
69
+ : { ...seed, l: Math.min(0.62, Math.max(0.48, seed.l)) };
70
+ if (danger.l !== seed.l) {
71
+ adjustments.push(`${mode} danger lightness clamped to ${danger.l.toFixed(2)}`);
72
+ }
73
+ const status = statusColors(mode, danger, {
74
+ success: colors.success.h,
75
+ warning: colors.warning.h,
76
+ info: colors.info.h,
77
+ });
78
+ return {
79
+ ...colors,
80
+ danger,
81
+ dangerForeground: status.dangerForeground,
82
+ dangerSubtle: status.dangerSubtle,
83
+ dangerBorder: status.dangerBorder,
84
+ };
85
+ }
86
+ export function applyGlass(colors, glass) {
87
+ if (!glass?.tintStrength || glass.tintStrength === 1)
88
+ return colors;
89
+ const base = colors.glassTint.alpha ?? 1;
90
+ return {
91
+ ...colors,
92
+ glassTint: {
93
+ ...colors.glassTint,
94
+ alpha: Math.min(0.55, Math.max(0.08, base * glass.tintStrength)),
95
+ },
96
+ };
97
+ }
98
+ export function applyShape(structural, shape) {
99
+ if (!shape?.density || shape.density === "default")
100
+ return structural;
101
+ return { ...structural, density: DENSITY[shape.density] };
102
+ }
103
+ export function applyMotion(structural, motion) {
104
+ if (!motion || motion === "balanced")
105
+ return structural;
106
+ return { ...structural, ...MOTION[motion] };
107
+ }