mui-atelier 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 (77) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE +32 -0
  4. package/README.md +282 -0
  5. package/dist/components/AddressFields.js +83 -0
  6. package/dist/components/AuthCard.js +94 -0
  7. package/dist/components/AuthSplash.js +88 -0
  8. package/dist/components/BrandHeader.js +81 -0
  9. package/dist/components/BrandLink.js +22 -0
  10. package/dist/components/BrandMark.js +69 -0
  11. package/dist/components/BrandProvider.js +14 -0
  12. package/dist/components/Breadcrumbs.js +62 -0
  13. package/dist/components/CardHead.js +46 -0
  14. package/dist/components/ConfirmProvider.js +77 -0
  15. package/dist/components/DashboardLayout.js +645 -0
  16. package/dist/components/DataTable.js +546 -0
  17. package/dist/components/DetailRows.js +42 -0
  18. package/dist/components/EmptyNote.js +28 -0
  19. package/dist/components/Eyebrow.js +21 -0
  20. package/dist/components/HeadingHelp.js +38 -0
  21. package/dist/components/HeadingLevel.js +18 -0
  22. package/dist/components/IconTile.js +42 -0
  23. package/dist/components/ImagePreviewDialog.js +86 -0
  24. package/dist/components/LabeledField.js +156 -0
  25. package/dist/components/LanguageSwitcher.js +43 -0
  26. package/dist/components/ListRow.js +59 -0
  27. package/dist/components/ModeToggle.js +35 -0
  28. package/dist/components/PageHeader.js +65 -0
  29. package/dist/components/PasswordField.js +43 -0
  30. package/dist/components/PublicLayout.js +27 -0
  31. package/dist/components/PublicNav.js +17 -0
  32. package/dist/components/RouteMessage.js +31 -0
  33. package/dist/components/RowList.js +10 -0
  34. package/dist/components/SafeHtml.js +57 -0
  35. package/dist/components/SaveState.js +13 -0
  36. package/dist/components/SectionPanel.js +48 -0
  37. package/dist/components/SectionTabs.js +139 -0
  38. package/dist/components/SiteNav.js +130 -0
  39. package/dist/components/Skeletons.js +63 -0
  40. package/dist/components/Sortable.js +81 -0
  41. package/dist/components/StatTile.js +66 -0
  42. package/dist/components/StatusChip.js +17 -0
  43. package/dist/components/StatusDot.js +42 -0
  44. package/dist/components/SubCard.js +30 -0
  45. package/dist/components/TabbedCard.js +20 -0
  46. package/dist/components/TableFilters.js +247 -0
  47. package/dist/components/ToastProvider.js +65 -0
  48. package/dist/eslint/chipRules.mjs +65 -0
  49. package/dist/hooks/useDocumentTitle.js +19 -0
  50. package/dist/hooks/useOverflowTabs.js +53 -0
  51. package/dist/hooks/useUnsavedChanges.js +46 -0
  52. package/dist/i18n/loadMessages.js +15 -0
  53. package/dist/i18n/mergeMessages.js +13 -0
  54. package/dist/i18n/messages/en.json +103 -0
  55. package/dist/i18n/messages/es.json +103 -0
  56. package/dist/i18n/messages/zh.json +103 -0
  57. package/dist/lib/authCard.js +4 -0
  58. package/dist/lib/chipTone.js +46 -0
  59. package/dist/lib/countryRegionData.js +29 -0
  60. package/dist/lib/countryRegionData.json +1 -0
  61. package/dist/lib/navLock.js +22 -0
  62. package/dist/lib/navTabSx.js +78 -0
  63. package/dist/lib/orgTime.js +243 -0
  64. package/dist/lib/pageHtml.js +139 -0
  65. package/dist/lib/safeNext.js +13 -0
  66. package/dist/lib/sanitizeHtml.js +36 -0
  67. package/dist/lib/slugify.js +7 -0
  68. package/dist/lib/tableFilter.js +147 -0
  69. package/dist/lib/tableStyle.js +87 -0
  70. package/dist/test/jsdomShims.js +53 -0
  71. package/dist/test/themeContract.js +178 -0
  72. package/dist/theme/OrgThemeRegistry.js +71 -0
  73. package/dist/theme/ThemeRegistry.js +17 -0
  74. package/dist/theme/berryNavRow.js +21 -0
  75. package/dist/theme/createSiteTheme.js +974 -0
  76. package/dist/theme/themes.js +438 -0
  77. package/package.json +118 -0
@@ -0,0 +1,438 @@
1
+ const SANS_STACK = 'system-ui, -apple-system, "Segoe UI", Roboto, sans-serif';
2
+ const SERIF_STACK = '"Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif';
3
+ const SANS = `var(--font-inter, ${SANS_STACK})`;
4
+ const SERIF = `var(--font-editorial, ${SERIF_STACK})`;
5
+ const PUBLIC_SANS = `var(--font-public-sans, ${SANS_STACK})`;
6
+ const SORA = `var(--font-sora, ${SANS_STACK})`;
7
+ const GROTESK = `var(--font-grotesk, ${SANS_STACK})`;
8
+ const MANROPE = `var(--font-manrope, ${SANS_STACK})`;
9
+ const CHAKRA = `var(--font-chakra, ${SANS_STACK})`;
10
+ const JETBRAINS = `var(--font-jetbrains, ui-monospace, "SF Mono", Menlo, Consolas, monospace)`;
11
+ const SPECTRAL = `var(--font-spectral, ${SERIF_STACK})`;
12
+ const ROBOTO = `var(--font-roboto, Roboto, ${SANS_STACK})`;
13
+ const DEFAULT_DEF = {
14
+ accent: {
15
+ light: "#AC5C1E",
16
+ dark: "#F2A365",
17
+ contrastLight: "#FFFFFF",
18
+ contrastDark: "#231A10",
19
+ gradient: { light: ["#F0A15C", "#E8894A"], dark: ["#F2A365", "#E8894A"] }
20
+ },
21
+ palette: {
22
+ light: { textPrimary: "#2C2925", textSecondary: "#6B6357", divider: "#E0D4C2", bgDefault: "#FBF7F1", bgPaper: "#FFFFFF", secondary: "#6B6357", data: "#1E59AC", success: "#2E7D54", warning: "#A8630A", error: "#C4442E" },
23
+ dark: { textPrimary: "#EDE7DC", textSecondary: "#A79E90", divider: "rgba(255,244,224,0.11)", bgDefault: "#17140F", bgPaper: "#211D16", secondary: "#B4AC9E", data: "#67A0F0", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
24
+ },
25
+ radii: { base: 10, card: 20, button: 12, buttonLarge: 14, chip: 999, input: 12, dialog: 20, menu: 16 },
26
+ shadow: "warm",
27
+ bodyFont: SANS,
28
+ ui: { button: "gradient", input: "filled", surface: "soft", pillChips: true, dense: false, tableHead: "band" }
29
+ };
30
+ const LUXE_DEF = {
31
+ accent: {
32
+ light: "#5860E6",
33
+ dark: "#8F96FF",
34
+ contrastLight: "#FFFFFF",
35
+ contrastDark: "#0A0B0F",
36
+ gradient: { light: ["#6366F1", "#4F46E5"], dark: ["#6EE7FF", "#7C83FF"] }
37
+ },
38
+ palette: {
39
+ light: { textPrimary: "#1A1C22", textSecondary: "#464C59", divider: "rgba(18,20,30,0.16)", bgDefault: "#F4F5FA", bgPaper: "#FFFFFF", secondary: "#464C59", data: "#BE1FCC", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
40
+ dark: { textPrimary: "#E7E9EE", textSecondary: "#8B90A0", divider: "rgba(255,255,255,0.09)", bgDefault: "#0A0B0F", bgPaper: "#16171D", secondary: "#8B90A0", data: "#ED99F5", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
41
+ },
42
+ radii: { base: 10, card: 14, button: 10, buttonLarge: 12, chip: 999, input: 10, dialog: 16, menu: 12 },
43
+ shadow: "glow",
44
+ bodyFont: SANS,
45
+ ui: { button: "gradient", glow: true, input: "glass", surface: "glass", pillChips: true, dense: false, tableHead: "band" }
46
+ };
47
+ const EDITORIAL_DEF = {
48
+ accent: {
49
+ light: "#4F46E5",
50
+ dark: "#818CF8",
51
+ contrastLight: "#FFFFFF",
52
+ contrastDark: "#14151A",
53
+ gradient: { light: ["#4F46E5", "#4338CA"], dark: ["#818CF8", "#6366F1"] }
54
+ },
55
+ palette: {
56
+ light: { textPrimary: "#1A1C22", textSecondary: "#3A404B", divider: "rgba(0,0,0,0.16)", bgDefault: "#F5F5F4", bgPaper: "#FFFFFF", secondary: "#3A404B", data: "#137D86", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
57
+ dark: { textPrimary: "#ECEEF3", textSecondary: "#9AA0AC", divider: "rgba(255,255,255,0.12)", bgDefault: "#14151A", bgPaper: "#1B1D24", secondary: "#9AA0AC", data: "#E186F3", success: "#34D399", warning: "#F2B347", error: "#F0876F" }
58
+ },
59
+ radii: { base: 3, card: 4, button: 3, buttonLarge: 4, chip: 3, input: 3, dialog: 6, menu: 4 },
60
+ shadow: "none",
61
+ headingFont: SERIF,
62
+ // artifact: serif headlines over a sans body (not serif throughout)
63
+ bodyFont: SANS,
64
+ ui: { button: "solid", underlineLinks: true, input: "minimal", surface: "flat", pillChips: false, dense: false, tableHead: "band" }
65
+ };
66
+ const PRO_DEF = {
67
+ accent: {
68
+ light: "#4338CA",
69
+ dark: "#818CF8",
70
+ contrastLight: "#FFFFFF",
71
+ contrastDark: "#0F1117",
72
+ gradient: { light: ["#4338CA", "#4F46E5"], dark: ["#818CF8", "#6366F1"] }
73
+ },
74
+ palette: {
75
+ light: { textPrimary: "#1C2027", textSecondary: "#4B5563", divider: "#D2D7DE", bgDefault: "#F7F8FA", bgPaper: "#FFFFFF", secondary: "#4B5563", data: "#248189", success: "#15803D", warning: "#92600A", error: "#B4442E" },
76
+ dark: { textPrimary: "#E5E7EB", textSecondary: "#9AA0AC", divider: "rgba(255,255,255,0.10)", bgDefault: "#0F1117", bgPaper: "#171A21", secondary: "#9AA0AC", data: "#E186F3", success: "#22C55E", warning: "#F2B347", error: "#F0876F" }
77
+ },
78
+ radii: { base: 6, card: 8, button: 6, buttonLarge: 6, chip: 5, input: 6, dialog: 8, menu: 6 },
79
+ shadow: "neutral",
80
+ bodyFont: SANS,
81
+ ui: { button: "solid", input: "crisp", surface: "flat", pillChips: false, dense: true, tableHead: "band" }
82
+ };
83
+ const MINIMAL_DEF = {
84
+ accent: {
85
+ light: "#008057",
86
+ dark: "#5BE49B",
87
+ contrastLight: "#FFFFFF",
88
+ contrastDark: "#004B50",
89
+ gradient: { light: ["#5BE49B", "#00A76F"], dark: ["#5BE49B", "#00A76F"] }
90
+ },
91
+ palette: {
92
+ light: { textPrimary: "#1C252E", textSecondary: "#4A5560", divider: "rgba(145,158,171,0.34)", bgDefault: "#F4F6F8", bgPaper: "#FFFFFF", secondary: "#4A5560", data: "#0E388B", success: "#11833F", warning: "#9A6600", error: "#D13B1F" },
93
+ dark: { textPrimary: "#FFFFFF", textSecondary: "#919EAB", divider: "rgba(145,158,171,0.2)", bgDefault: "#141A21", bgPaper: "#1C252E", secondary: "#919EAB", data: "#5B94E4", success: "#11833F", warning: "#9A6600", error: "#D13B1F" }
94
+ },
95
+ radii: { base: 8, card: 16, button: 8, buttonLarge: 8, chip: 8, input: 8, dialog: 16, menu: 10 },
96
+ shadow: "neutral",
97
+ bodyFont: PUBLIC_SANS,
98
+ // the Minimal kit's typeface — everything, headings included
99
+ // Design, not just colour: borderless cards on a soft grey shadow (surface:'minimal'),
100
+ // bold accent-shadowed CTAs (solidShadow), ring-less rounded inputs (input:'minimal').
101
+ ui: { button: "solid", solidShadow: true, input: "minimal", surface: "minimal", pillChips: false, labelChips: true, dense: false, tableHead: "band" }
102
+ };
103
+ const COBALT_DEF = {
104
+ accent: {
105
+ light: "#0063F2",
106
+ dark: "#5B9BFF",
107
+ contrastLight: "#FFFFFF",
108
+ contrastDark: "#071022",
109
+ gradient: { light: ["#0068FF", "#6E3AFF"], dark: ["#3E7BFF", "#8B5CF6"] }
110
+ },
111
+ palette: {
112
+ light: { textPrimary: "#101828", textSecondary: "#475467", divider: "#D5DEEF", bgDefault: "#ECF1F9", bgPaper: "#FFFFFF", secondary: "#475467", data: "#8515D5", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
113
+ dark: { textPrimary: "#E6EBF5", textSecondary: "#8E9AB3", divider: "rgba(148,170,220,0.16)", bgDefault: "#060B18", bgPaper: "#131E36", secondary: "#8E9AB3", data: "#B86AF0", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
114
+ },
115
+ radii: { base: 12, card: 18, button: 12, buttonLarge: 14, chip: 999, input: 12, dialog: 20, menu: 14 },
116
+ shadow: "glow",
117
+ headingFont: SORA,
118
+ bodyFont: SANS,
119
+ // nav:'inverse' — the deep-navy sidebar over light content is cobalt's
120
+ // signature move, straight from the reference.
121
+ ui: { button: "gradient", glow: true, input: "filled", surface: "soft", pillChips: true, dense: false, nav: "inverse", cardEdge: "gradient", tableHead: "band", stat: "gradient" }
122
+ };
123
+ const NOIR_DEF = {
124
+ accent: {
125
+ light: "#111111",
126
+ dark: "#F5F5F5",
127
+ contrastLight: "#FFFFFF",
128
+ contrastDark: "#0C0C0D",
129
+ gradient: { light: ["#2A2A2E", "#111111"], dark: ["#FFFFFF", "#D9D9DE"] }
130
+ },
131
+ palette: {
132
+ light: { textPrimary: "#141414", textSecondary: "#5C5C61", divider: "rgba(0,0,0,0.13)", bgDefault: "#E9E9EC", bgPaper: "#FFFFFF", secondary: "#5C5C61", data: "#1A5FD0", success: "#1F7A4D", warning: "#A16207", error: "#B42318" },
133
+ dark: { textPrimary: "#F2F2F2", textSecondary: "#9C9CA3", divider: "rgba(255,255,255,0.11)", bgDefault: "#09090A", bgPaper: "#161618", secondary: "#9C9CA3", data: "#7FB2FF", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
134
+ },
135
+ radii: { base: 4, card: 8, button: 6, buttonLarge: 6, chip: 4, input: 4, dialog: 10, menu: 6 },
136
+ shadow: "none",
137
+ headingFont: GROTESK,
138
+ bodyFont: SANS,
139
+ // nav:'quiet' — the compact ink edge-bar sidebar; selection is weight and a
140
+ // hairline, never a tinted pill.
141
+ ui: { button: "solid", input: "crisp", surface: "flat", pillChips: false, labelChips: true, dense: false, nav: "quiet", cardEdge: "ink", tableHead: "band" }
142
+ };
143
+ const AZURE_DEF = {
144
+ accent: {
145
+ light: "#D71C45",
146
+ dark: "#FB7185",
147
+ contrastLight: "#FFFFFF",
148
+ contrastDark: "#1F0A10",
149
+ gradient: { light: ["#F43F5E", "#E11D48"], dark: ["#FB7185", "#F43F5E"] }
150
+ },
151
+ palette: {
152
+ light: { textPrimary: "#232B36", textSecondary: "#5A6572", divider: "#E3E7ED", bgDefault: "#F1F3F6", bgPaper: "#FFFFFF", secondary: "#5A6572", data: "#1B66D0", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
153
+ dark: { textPrimary: "#E8ECF2", textSecondary: "#96A1AD", divider: "rgba(255,255,255,0.10)", bgDefault: "#0B1017", bgPaper: "#1A2230", secondary: "#96A1AD", data: "#7AACF2", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
154
+ },
155
+ radii: { base: 8, card: 10, button: 8, buttonLarge: 10, chip: 6, input: 8, dialog: 12, menu: 8 },
156
+ shadow: "neutral",
157
+ bodyFont: MANROPE,
158
+ // Manrope everywhere, headings included — azure's whole voice
159
+ // nav:'accent' — selection wears a soft tint and the rounded accent side-bar.
160
+ ui: { button: "solid", input: "minimal", surface: "flat", pillChips: false, dense: false, nav: "accent", cardEdge: "accent", tableHead: "band" }
161
+ };
162
+ const PURPLEHAZE_DEF = {
163
+ accent: {
164
+ light: "#7C3AED",
165
+ dark: "#A78BFA",
166
+ contrastLight: "#FFFFFF",
167
+ contrastDark: "#150D2B",
168
+ gradient: { light: ["#8B5CF6", "#D946EF"], dark: ["#A78BFA", "#E879F9"] }
169
+ },
170
+ palette: {
171
+ light: { textPrimary: "#1B1730", textSecondary: "#585175", divider: "#DFD9F0", bgDefault: "#EFECF8", bgPaper: "#FFFFFF", secondary: "#585175", data: "#137AC3", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
172
+ dark: { textPrimary: "#EBE6FA", textSecondary: "#9F97BE", divider: "rgba(167,139,250,0.16)", bgDefault: "#0B0716", bgPaper: "#171130", secondary: "#9F97BE", data: "#91D3F4", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
173
+ },
174
+ radii: { base: 10, card: 14, button: 10, buttonLarge: 12, chip: 6, input: 10, dialog: 16, menu: 12 },
175
+ shadow: "glow",
176
+ headingFont: CHAKRA,
177
+ bodyFont: SANS,
178
+ // Glass under a gradient edge, inside a permanently dark violet rail — the
179
+ // whole chrome glows. Shares luxe's surface machinery, none of its palette.
180
+ ui: { button: "gradient", glow: true, input: "glass", surface: "glass", pillChips: false, dense: false, nav: "inverse", cardEdge: "gradient", tableHead: "band" }
181
+ };
182
+ const VERDIGRIS_DEF = {
183
+ accent: {
184
+ light: "#0C776F",
185
+ dark: "#34C4B4",
186
+ contrastLight: "#FFFFFF",
187
+ contrastDark: "#04302C",
188
+ gradient: { light: ["#12A096", "#0E8A80"], dark: ["#34C4B4", "#12A096"] }
189
+ },
190
+ // Read by createSiteTheme's MuiDrawer override and by DashboardLayout's
191
+ // `rail` branch. Literals, not vars: the rail must not flip with the scheme.
192
+ rail: { bg: "#0B5E58", fg: "#EAF4F2" },
193
+ palette: {
194
+ light: { textPrimary: "#16211F", textSecondary: "#5A6B68", divider: "#DEE2DE", bgDefault: "#E8EDE8", bgPaper: "#FFFFFF", secondary: "#5A6B68", data: "#0E188B", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
195
+ dark: { textPrimary: "#E6EFED", textSecondary: "#93A5A2", divider: "rgba(230,239,237,0.12)", bgDefault: "#0C1413", bgPaper: "#14201E", secondary: "#93A5A2", data: "#6E80D9", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
196
+ },
197
+ // input matches `card` — a raised field IS a small card on this theme, so a
198
+ // tighter corner than the panels it sits between reads as a different family.
199
+ radii: { base: 10, card: 16, button: 12, buttonLarge: 12, chip: 999, input: 16, dialog: 16, menu: 12 },
200
+ shadow: "neutral",
201
+ bodyFont: PUBLIC_SANS,
202
+ /*
203
+ * `input: 'raised'`. Two things were wrong before it: 'minimal' is
204
+ * TRANSPARENT, so every field took the soft green ground and read as a grey
205
+ * slab; 'crisp' fixed the fill but kept a hard border on a theme where
206
+ * nothing else has one. Raised gives a field the same paper-and-soft-lift
207
+ * treatment the cards and buttons have, so every surface on the page is the
208
+ * same kind of thing.
209
+ *
210
+ * `tableHead: 'band'` for the same reason at the other end: without it a
211
+ * header row is the same size and weight as its data, and on a soft rounded
212
+ * card the ink rule 'rule' draws would be far too heavy.
213
+ */
214
+ ui: { button: "solid", solidShadow: true, input: "raised", surface: "soft", pillChips: true, dense: false, nav: "rail", tableHead: "band" }
215
+ };
216
+ const CONSOLE_DEF = {
217
+ accent: {
218
+ light: "#3F7A15",
219
+ dark: "#7CD44B",
220
+ contrastLight: "#FFFFFF",
221
+ contrastDark: "#0E1112",
222
+ gradient: { light: ["#5CA32B", "#3F7A15"], dark: ["#9BE86F", "#7CD44B"] }
223
+ },
224
+ palette: {
225
+ light: { textPrimary: "#14181A", textSecondary: "#5A6468", divider: "#D3D8DA", bgDefault: "#F2F3F2", bgPaper: "#FFFFFF", secondary: "#5A6468", data: "#164383", success: "#0B855A", warning: "#B45309", error: "#C4442E" },
226
+ dark: { textPrimary: "#DFE5E4", textSecondary: "#8A9694", divider: "rgba(223,229,228,0.14)", bgDefault: "#0E1112", bgPaper: "#15191A", secondary: "#8A9694", data: "#6394DA", success: "#7CD44B", warning: "#F2B347", error: "#F0876F" }
227
+ },
228
+ radii: { base: 2, card: 2, button: 2, buttonLarge: 2, chip: 2, input: 2, dialog: 4, menu: 2 },
229
+ shadow: "none",
230
+ bodyFont: JETBRAINS,
231
+ // everything, headings included — the whole voice
232
+ ui: { button: "solid", input: "crisp", surface: "flat", pillChips: false, labelChips: true, dense: true, nav: "bar", tableRules: "columns", tableHead: "rule", microLabels: true }
233
+ };
234
+ const LEDGER_DEF = {
235
+ accent: {
236
+ light: "#8C2F22",
237
+ dark: "#E08472",
238
+ contrastLight: "#FDFAF3",
239
+ contrastDark: "#2B1611",
240
+ gradient: { light: ["#A63A2A", "#8C2F22"], dark: ["#E08472", "#C2604D"] }
241
+ },
242
+ palette: {
243
+ light: { textPrimary: "#2B2621", textSecondary: "#6B6155", divider: "#C9BFA9", bgDefault: "#F5EFE3", bgPaper: "#FDFAF3", secondary: "#6B6155", data: "#224E8C", success: "#3F6B3A", warning: "#8E6210", error: "#8C2F22" },
244
+ dark: { textPrimary: "#F1E9DB", textSecondary: "#B0A390", divider: "rgba(241,233,219,0.16)", bgDefault: "#221D18", bgPaper: "#2C251E", secondary: "#B0A390", data: "#72A0E0", success: "#8FBE86", warning: "#E0B063", error: "#E08472" }
245
+ },
246
+ radii: { base: 0, card: 0, button: 0, buttonLarge: 0, chip: 0, input: 0, dialog: 4, menu: 2 },
247
+ shadow: "none",
248
+ headingFont: SPECTRAL,
249
+ bodyFont: SPECTRAL,
250
+ ui: { button: "solid", underlineLinks: true, input: "ruled", surface: "flat", pillChips: false, labelChips: true, dense: false, nav: "ruled", tableRules: "columns", tableHead: "rule", tableZebra: true, microLabels: true }
251
+ };
252
+ const DAMSON_DEF = {
253
+ accent: {
254
+ light: "#7A3B69",
255
+ dark: "#C68BB6",
256
+ contrastLight: "#FFFFFF",
257
+ contrastDark: "#1D1620",
258
+ gradient: { light: ["#8E4A7B", "#7A3B69"], dark: ["#C68BB6", "#8E4A7B"] }
259
+ },
260
+ accent2: { light: "#5F7A2E", dark: "#A8C46A" },
261
+ rail: { bg: "#4E2646", fg: "#F6EFF4" },
262
+ palette: {
263
+ light: { textPrimary: "#1D1620", textSecondary: "#6A5C66", divider: "#E3DCE2", bgDefault: "#EDE8EC", bgPaper: "#FFFFFF", secondary: "#6A5C66", data: "#325483", success: "#4A7A2E", warning: "#A8630A", error: "#C4442E" },
264
+ dark: { textPrimary: "#EFE6EE", textSecondary: "#A697A4", divider: "rgba(239,230,238,0.12)", bgDefault: "#160F16", bgPaper: "#1F1620", secondary: "#A697A4", data: "#82A2CF", success: "#A8C46A", warning: "#F2B347", error: "#F0876F" }
265
+ },
266
+ radii: { base: 10, card: 16, button: 12, buttonLarge: 12, chip: 999, input: 12, dialog: 16, menu: 12 },
267
+ shadow: "neutral",
268
+ bodyFont: PUBLIC_SANS,
269
+ // solidChips, and the reason is measurable: a low-alpha tint of a muted plum
270
+ // lands on top of the neutral chip — `admin` and `member` came out about
271
+ // 10/255 apart, which is not a distinction in a data table.
272
+ // `input: 'crisp'` and `tableHead: 'band'` for the same reason as verdigris,
273
+ // which this theme is built the same way as: a transparent field on the soft
274
+ // mauve ground (#EDE8EC against white paper) reads as a grey slab rather than
275
+ // a card, and an untreated header row is indistinguishable from its data.
276
+ ui: { button: "solid", solidShadow: true, input: "raised", surface: "soft", pillChips: true, solidChips: true, dense: false, nav: "rail", tableHead: "band" }
277
+ };
278
+ const DAMSONLIGHT_DEF = {
279
+ accent: {
280
+ light: "#7A3B69",
281
+ dark: "#C68BB6",
282
+ contrastLight: "#FFFFFF",
283
+ contrastDark: "#1D1620",
284
+ gradient: { light: ["#8E4A7B", "#7A3B69"], dark: ["#C68BB6", "#8E4A7B"] }
285
+ },
286
+ accent2: { light: "#5F7A2E", dark: "#A8C46A" },
287
+ palette: {
288
+ light: { textPrimary: "#1D1620", textSecondary: "#6A5C66", divider: "#ECE4EA", bgDefault: "#F3F0F3", bgPaper: "#FFFFFF", secondary: "#6A5C66", data: "#325483", success: "#4A7A2E", warning: "#A8630A", error: "#C4442E" },
289
+ dark: { textPrimary: "#EFE6EE", textSecondary: "#A697A4", divider: "rgba(239,230,238,0.12)", bgDefault: "#171017", bgPaper: "#211823", secondary: "#A697A4", data: "#82A2CF", success: "#A8C46A", warning: "#F2B347", error: "#F0876F" }
290
+ },
291
+ radii: { base: 8, card: 12, button: 10, buttonLarge: 10, chip: 999, input: 10, dialog: 12, menu: 10 },
292
+ shadow: "neutral",
293
+ bodyFont: PUBLIC_SANS,
294
+ ui: { button: "solid", input: "minimal", surface: "flat", pillChips: true, solidChips: true, dense: false, nav: "bar", tableHead: "band" }
295
+ };
296
+ const SEAFOAM_DEF = {
297
+ accent: {
298
+ light: "#0E5F4E",
299
+ dark: "#8ECFBC",
300
+ contrastLight: "#FFFFFF",
301
+ contrastDark: "#0C3B31",
302
+ gradient: { light: ["#0E5F4E", "#12836B"], dark: ["#8ECFBC", "#A6D9C8"] }
303
+ },
304
+ palette: {
305
+ light: { textPrimary: "#1D2422", textSecondary: "#5C6461", divider: "#DCE9E3", bgDefault: "#EFF6F2", bgPaper: "#FFFFFF", secondary: "#5C6461", data: "#143085", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
306
+ dark: { textPrimary: "#E9F1ED", textSecondary: "#93A39C", divider: "rgba(180,220,205,0.14)", bgDefault: "#0C1210", bgPaper: "#161D1A", secondary: "#93A39C", data: "#8AA2D3", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
307
+ },
308
+ radii: { base: 14, card: 18, button: 12, buttonLarge: 14, chip: 999, input: 12, dialog: 20, menu: 16 },
309
+ shadow: "neutral",
310
+ bodyFont: MANROPE,
311
+ // Soft & airy: a floating rail with the gentle ringed-tint selection (not the
312
+ // bold pill periwinkle wears) and gradient stat tiles.
313
+ ui: { button: "solid", input: "filled", surface: "soft", pillChips: true, dense: false, tableHead: "band", stat: "gradient", navFloat: true, nav: "accent" }
314
+ };
315
+ const PERIWINKLE_DEF = {
316
+ accent: {
317
+ light: "#3A44BE",
318
+ dark: "#AAB4EE",
319
+ contrastLight: "#FFFFFF",
320
+ contrastDark: "#1D2455",
321
+ gradient: { light: ["#4048C8", "#6A4FD6"], dark: ["#AAB4EE", "#C3C0F5"] }
322
+ },
323
+ palette: {
324
+ light: { textPrimary: "#1D1F2A", textSecondary: "#5E6274", divider: "#E2E4F3", bgDefault: "#EFF0FB", bgPaper: "#FFFFFF", secondary: "#5E6274", data: "#A937B4", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
325
+ dark: { textPrimary: "#E9EAF5", textSecondary: "#989DB6", divider: "rgba(200,205,245,0.14)", bgDefault: "#0C0D15", bgPaper: "#171826", secondary: "#989DB6", data: "#E3AAEE", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
326
+ },
327
+ radii: { base: 14, card: 18, button: 12, buttonLarge: 14, chip: 999, input: 12, dialog: 20, menu: 16 },
328
+ shadow: "glow",
329
+ headingFont: SORA,
330
+ bodyFont: SANS,
331
+ ui: { button: "gradient", glow: true, input: "filled", surface: "soft", pillChips: true, dense: false, tableHead: "band", stat: "gradient", navFloat: true, nav: "pill", navCollapsible: true, barFloat: true, pillHeading: true }
332
+ };
333
+ const VERDINKLE_SQUARE_DEF = {
334
+ accent: {
335
+ light: "#0E5F4E",
336
+ dark: "#8ECFBC",
337
+ contrastLight: "#FFFFFF",
338
+ contrastDark: "#0C3B31",
339
+ gradient: { light: ["#0E5F4E", "#12836B"], dark: ["#8ECFBC", "#A6D9C8"] }
340
+ },
341
+ palette: {
342
+ light: { textPrimary: "#1D2422", textSecondary: "#5C6461", divider: "#DCE9E3", bgDefault: "#EFF6F2", bgPaper: "#FFFFFF", secondary: "#5C6461", data: "#143085", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
343
+ dark: { textPrimary: "#E9F1ED", textSecondary: "#93A39C", divider: "rgba(180,220,205,0.14)", bgDefault: "#0C1210", bgPaper: "#161D1A", secondary: "#93A39C", data: "#8AA2D3", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
344
+ },
345
+ radii: { base: 0, card: 0, button: 0, buttonLarge: 0, chip: 0, input: 0, dialog: 0, menu: 0 },
346
+ shadow: "glow",
347
+ bodyFont: MANROPE,
348
+ ui: { button: "gradient", glow: true, input: "filled", surface: "soft", pillChips: false, dense: false, tableHead: "band", stat: "gradient", navFloat: true, nav: "pill", navCollapsible: true, barFloat: true, pillHeading: true }
349
+ };
350
+ const AZURINKLE_ROUNDED_DEF = {
351
+ accent: {
352
+ light: "#173A8C",
353
+ dark: "#8FB4FF",
354
+ contrastLight: "#FFFFFF",
355
+ contrastDark: "#0A1B44",
356
+ gradient: { light: ["#173A8C", "#2457C4"], dark: ["#8FB4FF", "#AECBFF"] }
357
+ },
358
+ palette: {
359
+ light: { textPrimary: "#141A2B", textSecondary: "#565F73", divider: "#D8E0F0", bgDefault: "#E9EEFA", bgPaper: "#FFFFFF", secondary: "#565F73", data: "#65178C", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
360
+ dark: { textPrimary: "#E8EDF9", textSecondary: "#95A1BC", divider: "rgba(150,180,245,0.14)", bgDefault: "#080B16", bgPaper: "#121828", secondary: "#95A1BC", data: "#D699F5", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
361
+ },
362
+ radii: { base: 6, card: 8, button: 6, buttonLarge: 8, chip: 8, input: 6, dialog: 10, menu: 8, nav: 8 },
363
+ shadow: "glow",
364
+ bodyFont: MANROPE,
365
+ ui: { button: "gradient", glow: true, input: "filled", surface: "soft", pillChips: false, dense: false, tableHead: "band", stat: "gradient", navFloat: true, nav: "pill", navCollapsible: true, barFloat: true, pillHeading: true }
366
+ };
367
+ const BUTTER_DEF = {
368
+ accent: {
369
+ light: "#6A4E0C",
370
+ dark: "#EBCF8B",
371
+ contrastLight: "#FFFFFF",
372
+ contrastDark: "#4A3609",
373
+ gradient: { light: ["#6A4E0C", "#8A6614"], dark: ["#EBCF8B", "#F0DBA2"] }
374
+ },
375
+ palette: {
376
+ light: { textPrimary: "#241F16", textSecondary: "#645C4B", divider: "#EAE2CE", bgDefault: "#F8F2E4", bgPaper: "#FFFFFF", secondary: "#645C4B", data: "#104289", success: "#0B855A", warning: "#A8630A", error: "#C4442E" },
377
+ dark: { textPrimary: "#F1EBDD", textSecondary: "#A79E8A", divider: "rgba(235,207,139,0.14)", bgDefault: "#121009", bgPaper: "#1E1A12", secondary: "#A79E8A", data: "#8BB3EB", success: "#5FCB92", warning: "#F2B347", error: "#F0876F" }
378
+ },
379
+ radii: { base: 14, card: 18, button: 12, buttonLarge: 14, chip: 999, input: 12, dialog: 20, menu: 16 },
380
+ shadow: "warm",
381
+ headingFont: SPECTRAL,
382
+ bodyFont: MANROPE,
383
+ // Warm & editorial: a floating rail with the accent left-edge bar selection
384
+ // and gradient stat tiles for the dashboard.
385
+ ui: { button: "solid", input: "filled", surface: "soft", pillChips: true, dense: false, tableHead: "band", stat: "gradient", nav: "bar", navFloat: true }
386
+ };
387
+ const FONTS = { SANS_STACK, SERIF_STACK, SANS, SERIF, PUBLIC_SANS, SORA, GROTESK, MANROPE, CHAKRA, JETBRAINS, SPECTRAL, ROBOTO };
388
+ const ORG_THEMES = [
389
+ { id: "default", label: "Warm & rounded", def: DEFAULT_DEF },
390
+ { id: "luxe", label: "Dark luxe", def: LUXE_DEF },
391
+ { id: "editorial", label: "Editorial", def: EDITORIAL_DEF },
392
+ { id: "pro", label: "Data-dense pro", def: PRO_DEF },
393
+ { id: "minimal", label: "Minimal", def: MINIMAL_DEF },
394
+ { id: "cobalt", label: "Electric cobalt", def: COBALT_DEF },
395
+ { id: "noir", label: "Noir", def: NOIR_DEF },
396
+ { id: "azure", label: "Azure", def: AZURE_DEF },
397
+ { id: "purplehaze", label: "Purple haze", def: PURPLEHAZE_DEF },
398
+ { id: "verdigris", label: "Verdigris", def: VERDIGRIS_DEF },
399
+ { id: "console", label: "Console", def: CONSOLE_DEF },
400
+ { id: "ledger", label: "Ledger", def: LEDGER_DEF },
401
+ { id: "damson", label: "Damson", def: DAMSON_DEF },
402
+ { id: "damsonlight", label: "Damson Light", def: DAMSONLIGHT_DEF },
403
+ { id: "seafoam", label: "Seafoam", def: SEAFOAM_DEF },
404
+ { id: "periwinkle", label: "Periwinkle", def: PERIWINKLE_DEF },
405
+ { id: "verdinklesquare", label: "Verdinkle Square", def: VERDINKLE_SQUARE_DEF },
406
+ { id: "azurinklerounded", label: "Azurinkle Rounded", def: AZURINKLE_ROUNDED_DEF },
407
+ { id: "butter", label: "Butter", def: BUTTER_DEF }
408
+ ];
409
+ const DEFAULT_THEME_ID = "default";
410
+ function createThemeCatalog({ themes, chrome = {}, defaultId = DEFAULT_THEME_ID, chromeDefaultId = null }) {
411
+ const byId = /* @__PURE__ */ new Map();
412
+ for (const theme of themes) {
413
+ if (byId.has(theme.id)) throw new Error(`Duplicate theme id "${theme.id}"`);
414
+ byId.set(theme.id, theme);
415
+ }
416
+ if (!byId.has(defaultId)) throw new Error(`Default theme "${defaultId}" is not in the catalogue`);
417
+ const resolveThemeId2 = (id) => byId.has(id) ? id : defaultId;
418
+ const getOrgTheme2 = (id) => byId.get(resolveThemeId2(id)).def;
419
+ const getChromeTheme2 = (id) => chrome[id] ?? byId.get(id)?.def ?? chrome[chromeDefaultId] ?? getOrgTheme2(defaultId);
420
+ return { themes, defaultId, resolveThemeId: resolveThemeId2, getOrgTheme: getOrgTheme2, getChromeTheme: getChromeTheme2 };
421
+ }
422
+ const { resolveThemeId, getOrgTheme, getChromeTheme } = createThemeCatalog({ themes: ORG_THEMES });
423
+ function appRootTheme(accent) {
424
+ return {
425
+ ...DEFAULT_DEF,
426
+ accent: { contrastLight: "#FFFFFF", contrastDark: "#231A10", ...accent }
427
+ };
428
+ }
429
+ export {
430
+ DEFAULT_THEME_ID,
431
+ FONTS,
432
+ ORG_THEMES,
433
+ appRootTheme,
434
+ createThemeCatalog,
435
+ getChromeTheme,
436
+ getOrgTheme,
437
+ resolveThemeId
438
+ };
package/package.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "name": "mui-atelier",
3
+ "version": "0.1.0",
4
+ "description": "Twenty-odd complete MUI themes with a theme factory, per-organisation theme scoping, and the Next.js components built on them.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/vladslobodkin/mui-atelier.git"
10
+ },
11
+ "homepage": "https://github.com/vladslobodkin/mui-atelier#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/vladslobodkin/mui-atelier/issues"
14
+ },
15
+ "keywords": [
16
+ "mui",
17
+ "material-ui",
18
+ "theme",
19
+ "themes",
20
+ "nextjs",
21
+ "react",
22
+ "design-system",
23
+ "components"
24
+ ],
25
+ "files": [
26
+ "dist",
27
+ "NOTICE",
28
+ "CHANGELOG.md"
29
+ ],
30
+ "sideEffects": [
31
+ "./dist/test/jsdomShims.js"
32
+ ],
33
+ "exports": {
34
+ "./components/*": "./dist/components/*.js",
35
+ "./hooks/*": "./dist/hooks/*.js",
36
+ "./lib/*": "./dist/lib/*.js",
37
+ "./theme/*": "./dist/theme/*.js",
38
+ "./i18n/mergeMessages": "./dist/i18n/mergeMessages.js",
39
+ "./i18n/loadMessages": "./dist/i18n/loadMessages.js",
40
+ "./i18n/messages/*": "./dist/i18n/messages/*",
41
+ "./eslint": "./dist/eslint/chipRules.mjs",
42
+ "./test/*": "./dist/test/*.js",
43
+ "./package.json": "./package.json"
44
+ },
45
+ "engines": {
46
+ "node": ">=20.9"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public",
50
+ "provenance": true
51
+ },
52
+ "scripts": {
53
+ "build": "node scripts/build.mjs",
54
+ "prepack": "npm run build",
55
+ "lint": "eslint",
56
+ "test": "vitest run"
57
+ },
58
+ "peerDependencies": {
59
+ "@dnd-kit/core": "^6",
60
+ "@dnd-kit/sortable": "^10",
61
+ "@dnd-kit/utilities": "^3",
62
+ "@emotion/react": "^11",
63
+ "@emotion/styled": "^11",
64
+ "@mui/icons-material": "^9",
65
+ "@mui/material": "^9",
66
+ "@tanstack/react-table": "^8",
67
+ "dompurify": "^3",
68
+ "next": ">=15",
69
+ "next-intl": "^4",
70
+ "react": "^19",
71
+ "react-dom": "^19",
72
+ "vitest": "^3"
73
+ },
74
+ "peerDependenciesMeta": {
75
+ "@dnd-kit/core": {
76
+ "optional": true
77
+ },
78
+ "@dnd-kit/sortable": {
79
+ "optional": true
80
+ },
81
+ "@dnd-kit/utilities": {
82
+ "optional": true
83
+ },
84
+ "@tanstack/react-table": {
85
+ "optional": true
86
+ },
87
+ "dompurify": {
88
+ "optional": true
89
+ },
90
+ "vitest": {
91
+ "optional": true
92
+ }
93
+ },
94
+ "devDependencies": {
95
+ "@dnd-kit/core": "^6.3.1",
96
+ "@dnd-kit/sortable": "^10.0.0",
97
+ "@dnd-kit/utilities": "^3.2.2",
98
+ "@emotion/react": "^11.14.0",
99
+ "@emotion/styled": "^11.14.1",
100
+ "@mui/icons-material": "^9.4.0",
101
+ "@mui/material": "^9.4.0",
102
+ "@tanstack/react-table": "^8.21.3",
103
+ "@testing-library/jest-dom": "^7.0.1",
104
+ "@testing-library/react": "^16.3.3",
105
+ "dompurify": "^3.4.16",
106
+ "esbuild": "^0.28.2",
107
+ "eslint": "^9.39.5",
108
+ "eslint-config-next": "^16.2.10",
109
+ "intl-messageformat": "^12.1.2",
110
+ "jsdom": "^27.4.0",
111
+ "next": "^16.2.10",
112
+ "next-intl": "^4.14.7",
113
+ "react": "^19.2.4",
114
+ "react-dom": "^19.2.4",
115
+ "sanitize-html": "^2.17.7",
116
+ "vitest": "^3.2.7"
117
+ }
118
+ }