@abumble/design-system 0.0.37 → 0.0.39

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 (70) hide show
  1. package/dist/components/BackLink/BackLink.d.ts.map +1 -1
  2. package/dist/components/Banner/Banner.d.ts +7 -5
  3. package/dist/components/Banner/Banner.d.ts.map +1 -1
  4. package/dist/components/Banner.js +15 -5
  5. package/dist/components/Banner.js.map +1 -1
  6. package/dist/components/BannerHeader.js +1 -1
  7. package/dist/components/Carousel/Carousel.d.ts.map +1 -1
  8. package/dist/components/Carousel.js +36 -36
  9. package/dist/components/Carousel.js.map +1 -1
  10. package/dist/components/Dialog.js +1 -1
  11. package/dist/components/PageHeader.js +1 -1
  12. package/dist/components/Select.js +2 -22
  13. package/dist/components/Select.js.map +1 -1
  14. package/dist/components/Sheet.js +1 -1
  15. package/dist/components/Sidebar.js +2 -2
  16. package/dist/components/ThemeSelector/ThemeSelector.d.ts +2 -0
  17. package/dist/components/ThemeSelector/ThemeSelector.d.ts.map +1 -0
  18. package/dist/components/ThemeSelector/index.d.ts +2 -0
  19. package/dist/components/ThemeSelector/index.d.ts.map +1 -0
  20. package/dist/components/ThemeSelector.js +24 -0
  21. package/dist/components/ThemeSelector.js.map +1 -0
  22. package/dist/components/ThemeToggle/ThemeToggle.d.ts +2 -0
  23. package/dist/components/ThemeToggle/ThemeToggle.d.ts.map +1 -0
  24. package/dist/components/ThemeToggle/index.d.ts +2 -0
  25. package/dist/components/ThemeToggle/index.d.ts.map +1 -0
  26. package/dist/components/ThemeToggle.js +24 -0
  27. package/dist/components/ThemeToggle.js.map +1 -0
  28. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  29. package/dist/components/Tooltip.js +1 -1
  30. package/dist/components/UnderConstruction.js +1 -1
  31. package/dist/hooks/use-mobile.d.ts.map +1 -1
  32. package/dist/index.css +1 -0
  33. package/dist/shared/BackLink.js +25 -19
  34. package/dist/shared/BackLink.js.map +1 -1
  35. package/dist/shared/Dialog.js +2 -2
  36. package/dist/shared/Empty.js +1 -1
  37. package/dist/shared/Empty.js.map +1 -1
  38. package/dist/shared/PageHeader.js +2 -2
  39. package/dist/shared/Select.js +25 -0
  40. package/dist/shared/Select.js.map +1 -0
  41. package/dist/shared/Sheet.js +11 -11
  42. package/dist/shared/Sheet.js.map +1 -1
  43. package/dist/shared/Skeleton.js +7 -7
  44. package/dist/shared/Skeleton.js.map +1 -1
  45. package/dist/shared/Tooltip.js +12 -12
  46. package/dist/shared/Tooltip.js.map +1 -1
  47. package/dist/shared/use-mobile.js +6 -4
  48. package/dist/shared/use-mobile.js.map +1 -1
  49. package/dist/shared/useTheme.js +12 -0
  50. package/dist/shared/useTheme.js.map +1 -0
  51. package/dist/themes/ThemeContext.d.ts +10 -0
  52. package/dist/themes/ThemeContext.d.ts.map +1 -0
  53. package/dist/themes/ThemeProvider.d.ts +9 -0
  54. package/dist/themes/ThemeProvider.d.ts.map +1 -0
  55. package/dist/themes/index.d.ts +3 -0
  56. package/dist/themes/index.d.ts.map +1 -0
  57. package/dist/themes/theme.d.ts +2 -0
  58. package/dist/themes/theme.d.ts.map +1 -0
  59. package/dist/themes/useTheme.d.ts +2 -0
  60. package/dist/themes/useTheme.d.ts.map +1 -0
  61. package/dist/themes.js +50 -0
  62. package/dist/themes.js.map +1 -0
  63. package/package.json +16 -144
  64. package/src/themes/ThemeContext.ts +12 -0
  65. package/src/themes/ThemeProvider.tsx +86 -0
  66. package/src/themes/index.ts +2 -0
  67. package/src/themes/linen.css +131 -0
  68. package/src/themes/steel.css +131 -0
  69. package/src/themes/theme.tsx +3 -0
  70. package/src/themes/useTheme.ts +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abumble/design-system",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
4
4
  "files": [
5
5
  "dist",
6
6
  "src/styles.css",
@@ -11,141 +11,9 @@
11
11
  "import": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts"
13
13
  },
14
- "./components/Banner": {
15
- "import": "./dist/components/Banner.js",
16
- "types": "./dist/components/Banner/Banner.d.ts"
17
- },
18
- "./components/Breadcrumb": {
19
- "import": "./dist/components/Breadcrumb.js",
20
- "types": "./dist/components/Breadcrumb/Breadcrumb.d.ts"
21
- },
22
- "./components/Button": {
23
- "import": "./dist/components/Button.js",
24
- "types": "./dist/components/Button/Button.d.ts"
25
- },
26
- "./components/Card": {
27
- "import": "./dist/components/Card.js",
28
- "types": "./dist/components/Card/Card.d.ts"
29
- },
30
- "./components/Carousel": {
31
- "import": "./dist/components/Carousel.js",
32
- "types": "./dist/components/Carousel/Carousel.d.ts"
33
- },
34
- "./components/CodeDisplay": {
35
- "import": "./dist/components/CodeDisplay.js",
36
- "types": "./dist/components/CodeDisplay/CodeDisplay.d.ts"
37
- },
38
- "./components/Collapsible": {
39
- "import": "./dist/components/Collapsible.js",
40
- "types": "./dist/components/Collapsible/Collapsible.d.ts"
41
- },
42
- "./components/ContextMenu": {
43
- "import": "./dist/components/ContextMenu.js",
44
- "types": "./dist/components/ContextMenu/ContextMenu.d.ts"
45
- },
46
- "./components/Empty": {
47
- "import": "./dist/components/Empty.js",
48
- "types": "./dist/components/Empty/Empty.d.ts"
49
- },
50
- "./components/Input": {
51
- "import": "./dist/components/Input.js",
52
- "types": "./dist/components/Input/Input.d.ts"
53
- },
54
- "./components/List": {
55
- "import": "./dist/components/List.js",
56
- "types": "./dist/components/List/List.d.ts"
57
- },
58
- "./components/NotFound": {
59
- "import": "./dist/components/NotFound.js",
60
- "types": "./dist/components/NotFound/NotFound.d.ts"
61
- },
62
- "./components/Popover": {
63
- "import": "./dist/components/Popover.js",
64
- "types": "./dist/components/Popover/Popover.d.ts"
65
- },
66
- "./components/Separator": {
67
- "import": "./dist/components/Separator.js",
68
- "types": "./dist/components/Separator/Separator.d.ts"
69
- },
70
- "./components/Sheet": {
71
- "import": "./dist/components/Sheet.js",
72
- "types": "./dist/components/Sheet/Sheet.d.ts"
73
- },
74
- "./components/Sidebar": {
75
- "import": "./dist/components/Sidebar.js",
76
- "types": "./dist/components/Sidebar/Sidebar.d.ts"
77
- },
78
- "./components/Skeleton": {
79
- "import": "./dist/components/Skeleton.js",
80
- "types": "./dist/components/Skeleton/Skeleton.d.ts"
81
- },
82
- "./components/Tooltip": {
83
- "import": "./dist/components/Tooltip.js",
84
- "types": "./dist/components/Tooltip/Tooltip.d.ts"
85
- },
86
- "./components/UnderConstruction": {
87
- "import": "./dist/components/UnderConstruction.js",
88
- "types": "./dist/components/UnderConstruction/UnderConstruction.d.ts"
89
- },
90
- "./components/Badge": {
91
- "import": "./dist/components/Badge.js",
92
- "types": "./dist/components/Badge/Badge.d.ts"
93
- },
94
- "./components/Label": {
95
- "import": "./dist/components/Label.js",
96
- "types": "./dist/components/Label/Label.d.ts"
97
- },
98
- "./components/Checkbox": {
99
- "import": "./dist/components/Checkbox.js",
100
- "types": "./dist/components/Checkbox/Checkbox.d.ts"
101
- },
102
- "./components/Select": {
103
- "import": "./dist/components/Select.js",
104
- "types": "./dist/components/Select/Select.d.ts"
105
- },
106
- "./components/Textarea": {
107
- "import": "./dist/components/Textarea.js",
108
- "types": "./dist/components/Textarea/Textarea.d.ts"
109
- },
110
- "./components/Table": {
111
- "import": "./dist/components/Table.js",
112
- "types": "./dist/components/Table/Table.d.ts"
113
- },
114
- "./components/PageHeader": {
115
- "import": "./dist/components/PageHeader.js",
116
- "types": "./dist/components/PageHeader/PageHeader.d.ts"
117
- },
118
- "./components/Dialog": {
119
- "import": "./dist/components/Dialog.js",
120
- "types": "./dist/components/Dialog/Dialog.d.ts"
121
- },
122
- "./components/FieldsTable": {
123
- "import": "./dist/components/FieldsTable.js",
124
- "types": "./dist/components/FieldsTable/FieldsTable.d.ts"
125
- },
126
- "./components/ConfirmDeleteDialog": {
127
- "import": "./dist/components/ConfirmDeleteDialog.js",
128
- "types": "./dist/components/ConfirmDeleteDialog/ConfirmDeleteDialog.d.ts"
129
- },
130
- "./components/ActionsPopover": {
131
- "import": "./dist/components/ActionsPopover.js",
132
- "types": "./dist/components/ActionsPopover/ActionsPopover.d.ts"
133
- },
134
- "./components/BackLink": {
135
- "import": "./dist/components/BackLink.js",
136
- "types": "./dist/components/BackLink/BackLink.d.ts"
137
- },
138
- "./components/BannerHeader": {
139
- "import": "./dist/components/BannerHeader.js",
140
- "types": "./dist/components/BannerHeader/BannerHeader.d.ts"
141
- },
142
- "./components/DelayedLoadingFallback": {
143
- "import": "./dist/components/DelayedLoadingFallback.js",
144
- "types": "./dist/components/DelayedLoadingFallback/DelayedLoadingFallback.d.ts"
145
- },
146
- "./components/Toaster": {
147
- "import": "./dist/components/Toaster.js",
148
- "types": "./dist/components/Toaster/Toaster.d.ts"
14
+ "./components/*": {
15
+ "import": "./dist/components/*.js",
16
+ "types": "./dist/components/*/index.d.ts"
149
17
  },
150
18
  "./hooks/use-delayed-loading": {
151
19
  "import": "./dist/use-delayed-loading.js",
@@ -168,6 +36,10 @@
168
36
  "types": "./dist/hooks/use-mobile.d.ts"
169
37
  },
170
38
  "./styles.css": "./src/styles.css",
39
+ "./themes": {
40
+ "import": "./dist/themes.js",
41
+ "types": "./dist/themes/index.d.ts"
42
+ },
171
43
  "./themes/linen.css": "./src/themes/linen.css",
172
44
  "./themes/steel.css": "./src/themes/steel.css"
173
45
  },
@@ -187,7 +59,7 @@
187
59
  "tw-animate-css": "^1.3.6"
188
60
  },
189
61
  "devDependencies": {
190
- "@chromatic-com/storybook": "^4.1.2",
62
+ "@chromatic-com/storybook": "^5.0.1",
191
63
  "@eslint/js": "^9.39.1",
192
64
  "@radix-ui/react-collapsible": "^1.1.12",
193
65
  "@radix-ui/react-context-menu": "^2.2.16",
@@ -196,11 +68,11 @@
196
68
  "@radix-ui/react-separator": "^1.1.7",
197
69
  "@radix-ui/react-slot": "^1.2.3",
198
70
  "@radix-ui/react-tooltip": "^1.2.8",
199
- "@storybook/addon-a11y": "10.2.8",
200
- "@storybook/addon-docs": "10.2.8",
201
- "@storybook/addon-onboarding": "10.2.8",
202
- "@storybook/addon-vitest": "10.2.8",
203
- "@storybook/react-vite": "10.2.8",
71
+ "@storybook/addon-a11y": "10.2.17",
72
+ "@storybook/addon-docs": "10.2.17",
73
+ "@storybook/addon-onboarding": "10.2.17",
74
+ "@storybook/addon-vitest": "10.2.17",
75
+ "@storybook/react-vite": "10.2.17",
204
76
  "@tailwindcss/vite": "^4.0.6",
205
77
  "@types/node": "^24.10.0",
206
78
  "@types/react": "^19.2.2",
@@ -216,7 +88,7 @@
216
88
  "eslint": "^9.39.1",
217
89
  "eslint-plugin-react-hooks": "^7.0.1",
218
90
  "eslint-plugin-react-refresh": "^0.4.24",
219
- "eslint-plugin-storybook": "10.2.8",
91
+ "eslint-plugin-storybook": "10.2.17",
220
92
  "globals": "^16.5.0",
221
93
  "lucide-react": "^0.544.0",
222
94
  "playwright": "^1.56.1",
@@ -225,7 +97,7 @@
225
97
  "react": "^19.2.0",
226
98
  "react-dom": "^19.2.0",
227
99
  "rimraf": "^6.1.2",
228
- "storybook": "10.2.8",
100
+ "storybook": "10.2.17",
229
101
  "tailwind-merge": "^3.0.2",
230
102
  "tailwindcss": "^4.1.17",
231
103
  "typescript": "~5.9.3",
@@ -0,0 +1,12 @@
1
+ import { createContext } from 'react'
2
+ import type { ColorTheme, Theme } from './ThemeProvider'
3
+
4
+ export interface ThemeContextValue {
5
+ theme: Theme
6
+ setTheme: (theme: Theme) => void
7
+ effectiveTheme: 'light' | 'dark'
8
+ colorTheme: ColorTheme
9
+ setColorTheme: (colorTheme: ColorTheme) => void
10
+ }
11
+
12
+ export const ThemeContext = createContext<ThemeContextValue | null>(null)
@@ -0,0 +1,86 @@
1
+ import type { ReactNode } from 'react'
2
+ import { useCallback, useEffect, useMemo, useState } from 'react'
3
+ import { ThemeContext } from './ThemeContext'
4
+ import './linen.css'
5
+ import './steel.css'
6
+
7
+ export type Theme = 'light' | 'dark' | 'system'
8
+ export type ColorTheme = 'linen' | 'steel'
9
+
10
+ const STORAGE_KEY = 'theme'
11
+ const COLOR_THEME_STORAGE_KEY = 'color-theme'
12
+
13
+ function getStoredTheme(): Theme {
14
+ if (typeof window === 'undefined') return 'system'
15
+ const stored = localStorage.getItem(STORAGE_KEY)
16
+ if (stored === 'light' || stored === 'dark' || stored === 'system')
17
+ return stored
18
+ return 'dark'
19
+ }
20
+
21
+ function getStoredColorTheme(): ColorTheme {
22
+ if (typeof window === 'undefined') return 'linen'
23
+ const stored = localStorage.getItem(COLOR_THEME_STORAGE_KEY)
24
+ if (stored === 'linen' || stored === 'steel') return stored
25
+ return 'linen'
26
+ }
27
+
28
+ function applyTheme(effective: 'light' | 'dark') {
29
+ const root = document.documentElement
30
+ if (effective === 'dark') {
31
+ root.classList.add('dark')
32
+ } else {
33
+ root.classList.remove('dark')
34
+ }
35
+ }
36
+
37
+ function applyColorTheme(colorTheme: ColorTheme) {
38
+ document.documentElement.setAttribute('data-theme', colorTheme)
39
+ }
40
+
41
+ export function ThemeProvider({ children }: { children: ReactNode }) {
42
+ const [theme, setThemeState] = useState<Theme>(getStoredTheme)
43
+ const [colorTheme, setColorThemeState] =
44
+ useState<ColorTheme>(getStoredColorTheme)
45
+ const [systemDark, setSystemDark] = useState(
46
+ () => window.matchMedia('(prefers-color-scheme: dark)').matches,
47
+ )
48
+
49
+ const effectiveTheme: 'light' | 'dark' =
50
+ theme === 'system' ? (systemDark ? 'dark' : 'light') : theme
51
+
52
+ useEffect(() => {
53
+ applyTheme(effectiveTheme)
54
+ }, [effectiveTheme])
55
+
56
+ useEffect(() => {
57
+ applyColorTheme(colorTheme)
58
+ }, [colorTheme])
59
+
60
+ useEffect(() => {
61
+ if (theme !== 'system') return
62
+ const media = window.matchMedia('(prefers-color-scheme: dark)')
63
+ const handler = () => setSystemDark(media.matches)
64
+ media.addEventListener('change', handler)
65
+ return () => media.removeEventListener('change', handler)
66
+ }, [theme])
67
+
68
+ const setTheme = useCallback((next: Theme) => {
69
+ setThemeState(next)
70
+ localStorage.setItem(STORAGE_KEY, next)
71
+ }, [])
72
+
73
+ const setColorTheme = useCallback((next: ColorTheme) => {
74
+ setColorThemeState(next)
75
+ localStorage.setItem(COLOR_THEME_STORAGE_KEY, next)
76
+ }, [])
77
+
78
+ const value = useMemo(
79
+ () => ({ theme, setTheme, effectiveTheme, colorTheme, setColorTheme }),
80
+ [theme, setTheme, effectiveTheme, colorTheme, setColorTheme],
81
+ )
82
+
83
+ return (
84
+ <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
85
+ )
86
+ }
@@ -0,0 +1,2 @@
1
+ export { ThemeProvider, type Theme, type ColorTheme } from './ThemeProvider'
2
+ export { useTheme } from './useTheme'
@@ -65,6 +65,73 @@
65
65
  --checkbox-unchecked-border: oklch(0.88 0.01 60);
66
66
  }
67
67
 
68
+ [data-theme="linen"] {
69
+ /* --- Light Theme (Linen & Slate - Minimal Warmth) --- */
70
+ --background: oklch(0.992 0.003 85);
71
+ --foreground: oklch(0.2 0.01 85);
72
+
73
+ /* Surfaces (Tables, Cards, Buttons) - Frosted White */
74
+ --card: oklch(1 0 0 / 0.75);
75
+ --card-foreground: oklch(0.2 0.01 85);
76
+
77
+ --popover: oklch(1 0 0);
78
+ --popover-foreground: oklch(0.2 0.01 85);
79
+
80
+ /* Primary: Deep Warm Charcoal (Neutral & High Contrast) */
81
+ --primary: oklch(0.18 0.01 85);
82
+ --primary-foreground: oklch(1 0 0);
83
+
84
+ /* Button/Surface Colors: Pure White */
85
+ --secondary: oklch(1 0 0);
86
+ --secondary-foreground: oklch(0.18 0.01 85);
87
+
88
+ --muted: oklch(1 0 0);
89
+ --muted-foreground: oklch(0.5 0.01 85);
90
+
91
+ --accent: oklch(1 0 0);
92
+ --accent-foreground: oklch(0.18 0.01 85);
93
+
94
+ --destructive: oklch(0.55 0.15 25);
95
+ --destructive-foreground: oklch(1 0 0);
96
+
97
+ --border: oklch(0.94 0.005 85);
98
+ --input: oklch(0.94 0.005 85);
99
+ --ring: oklch(0.18 0.01 85 / 0.1);
100
+
101
+ --radius: 0.6rem;
102
+
103
+ /* Sidebar (Soft White) */
104
+ --sidebar: oklch(0.995 0.002 85);
105
+ --sidebar-foreground: oklch(0.2 0.01 85);
106
+ --sidebar-primary: oklch(0.18 0.01 85);
107
+ --sidebar-primary-foreground: oklch(1 0 0);
108
+ --sidebar-accent: oklch(0.97 0.01 85);
109
+ --sidebar-accent-foreground: oklch(0.18 0.01 85);
110
+ --sidebar-border: oklch(0.95 0.005 85);
111
+
112
+ /* Banners */
113
+ --banner-info: oklch(0.94 0.02 240);
114
+ --banner-info-foreground: oklch(0.4 0.1 240);
115
+ --banner-info-border: oklch(0.85 0.05 240);
116
+ --banner-note: oklch(0.94 0.02 160);
117
+ --banner-note-foreground: oklch(0.35 0.1 160);
118
+ --banner-note-border: oklch(0.85 0.05 160);
119
+ --banner-warning: oklch(0.95 0.03 80);
120
+ --banner-warning-foreground: oklch(0.45 0.1 60);
121
+ --banner-warning-border: oklch(0.88 0.05 70);
122
+ --banner-alert: oklch(0.95 0.03 25);
123
+ --banner-alert-foreground: oklch(0.45 0.12 25);
124
+ --banner-alert-border: oklch(0.88 0.08 25);
125
+
126
+ /* Interactive Elements */
127
+ --badge-success: oklch(0.4 0.1 160);
128
+ --badge-success-foreground: oklch(1 0 0);
129
+ --checkbox-checked: oklch(0.15 0.01 60);
130
+ --checkbox-checked-foreground: oklch(1 0 0);
131
+ --checkbox-unchecked-bg: oklch(1 0 0);
132
+ --checkbox-unchecked-border: oklch(0.88 0.01 60);
133
+ }
134
+
68
135
  .dark {
69
136
  /* --- Dark Theme (Warm Charcoal - Candlelit) --- */
70
137
  --background: oklch(0.14 0.01 80);
@@ -128,3 +195,67 @@
128
195
  --checkbox-unchecked-bg: oklch(0.22 0.01 80);
129
196
  --checkbox-unchecked-border: oklch(0.35 0.01 80);
130
197
  }
198
+
199
+ [data-theme="linen"].dark {
200
+ /* --- Dark Theme (Warm Charcoal - Candlelit) --- */
201
+ --background: oklch(0.14 0.01 80);
202
+ --foreground: oklch(0.93 0.01 85);
203
+
204
+ /* Card Elevation: Warm lifted surface */
205
+ --card: oklch(0.19 0.012 80 / 0.75);
206
+ --card-foreground: oklch(0.93 0.01 85);
207
+
208
+ --popover: oklch(0.17 0.01 80);
209
+ --popover-foreground: oklch(0.93 0.01 85);
210
+
211
+ /* Primary: Warm Sand/Cream */
212
+ --primary: oklch(0.86 0.05 85);
213
+ --primary-foreground: oklch(0.14 0.01 80);
214
+
215
+ --secondary: oklch(0.24 0.01 80);
216
+ --secondary-foreground: oklch(0.86 0.05 85);
217
+
218
+ --muted: oklch(0.24 0.01 80);
219
+ --muted-foreground: oklch(0.60 0.01 85);
220
+
221
+ --accent: oklch(0.24 0.01 80);
222
+ --accent-foreground: oklch(0.86 0.05 85);
223
+
224
+ --destructive: oklch(0.48 0.15 25);
225
+ --destructive-foreground: oklch(0.93 0.01 85);
226
+
227
+ --border: oklch(0.28 0.01 80);
228
+ --input: oklch(0.28 0.01 80);
229
+ --ring: oklch(0.86 0.05 85 / 0.3);
230
+
231
+ /* Sidebar (Warm Dark) */
232
+ --sidebar: oklch(0.17 0.01 80);
233
+ --sidebar-foreground: oklch(0.93 0.01 85);
234
+ --sidebar-primary: oklch(0.86 0.05 85);
235
+ --sidebar-primary-foreground: oklch(0.14 0.01 80);
236
+ --sidebar-accent: oklch(0.23 0.01 80);
237
+ --sidebar-accent-foreground: oklch(0.93 0.01 85);
238
+ --sidebar-border: oklch(0.28 0.01 80);
239
+
240
+ /* Banners (Warm Dark) */
241
+ --banner-info: oklch(0.22 0.04 230);
242
+ --banner-info-foreground: oklch(0.88 0.05 230);
243
+ --banner-info-border: oklch(0.48 0.16 235);
244
+ --banner-note: oklch(0.22 0.04 155);
245
+ --banner-note-foreground: oklch(0.88 0.06 155);
246
+ --banner-note-border: oklch(0.44 0.1 155);
247
+ --banner-warning: oklch(0.26 0.06 70);
248
+ --banner-warning-foreground: oklch(0.92 0.1 80);
249
+ --banner-warning-border: oklch(0.65 0.2 75);
250
+ --banner-alert: oklch(0.23 0.05 25);
251
+ --banner-alert-foreground: oklch(0.9 0.06 25);
252
+ --banner-alert-border: oklch(0.44 0.14 25);
253
+
254
+ /* Interactive Elements (Warm Dark) */
255
+ --badge-success: oklch(0.44 0.12 150);
256
+ --badge-success-foreground: oklch(0.93 0.01 85);
257
+ --checkbox-checked: oklch(0.86 0.05 85);
258
+ --checkbox-checked-foreground: oklch(0.14 0.01 80);
259
+ --checkbox-unchecked-bg: oklch(0.22 0.01 80);
260
+ --checkbox-unchecked-border: oklch(0.35 0.01 80);
261
+ }
@@ -65,6 +65,73 @@
65
65
  --checkbox-unchecked-border: oklch(0.85 0.01 250);
66
66
  }
67
67
 
68
+ [data-theme="steel"] {
69
+ /* --- Light Theme (Metallic & Industrial - Brushed Steel) --- */
70
+ --background: oklch(0.95 0.005 250);
71
+ --foreground: oklch(0.2 0.02 250);
72
+
73
+ /* Surfaces - Aluminum Finish */
74
+ --card: oklch(0.98 0.005 250 / 0.85);
75
+ --card-foreground: oklch(0.2 0.02 250);
76
+
77
+ --popover: oklch(1 0 0);
78
+ --popover-foreground: oklch(0.2 0.02 250);
79
+
80
+ /* Primary: Industrial Blue */
81
+ --primary: oklch(0.3 0.05 250);
82
+ --primary-foreground: oklch(0.98 0.005 250);
83
+
84
+ /* Button/Surface Colors: Silver */
85
+ --secondary: oklch(0.97 0.005 250);
86
+ --secondary-foreground: oklch(0.3 0.05 250);
87
+
88
+ --muted: oklch(0.93 0.005 250);
89
+ --muted-foreground: oklch(0.5 0.02 250);
90
+
91
+ --accent: oklch(0.91 0.008 250);
92
+ --accent-foreground: oklch(0.3 0.05 250);
93
+
94
+ --destructive: oklch(0.55 0.15 25);
95
+ --destructive-foreground: oklch(1 0 0);
96
+
97
+ --border: oklch(0.88 0.005 250);
98
+ --input: oklch(0.88 0.005 250);
99
+ --ring: oklch(0.3 0.05 250 / 0.15);
100
+
101
+ --radius: 0.25rem; /* Sharper for robotic feel */
102
+
103
+ /* Sidebar (Cold Slate) */
104
+ --sidebar: oklch(0.97 0.005 250);
105
+ --sidebar-foreground: oklch(0.25 0.02 250);
106
+ --sidebar-primary: oklch(0.3 0.05 250);
107
+ --sidebar-primary-foreground: oklch(0.98 0.005 250);
108
+ --sidebar-accent: oklch(0.93 0.008 250);
109
+ --sidebar-accent-foreground: oklch(0.25 0.02 250);
110
+ --sidebar-border: oklch(0.9 0.005 250);
111
+
112
+ /* Banners (Metallic & Industrial) */
113
+ --banner-info: oklch(0.94 0.02 245);
114
+ --banner-info-foreground: oklch(0.24 0.09 245);
115
+ --banner-info-border: oklch(0.52 0.18 245);
116
+ --banner-note: oklch(0.94 0.02 162);
117
+ --banner-note-foreground: oklch(0.24 0.1 162);
118
+ --banner-note-border: oklch(0.48 0.16 162);
119
+ --banner-warning: oklch(0.95 0.04 78);
120
+ --banner-warning-foreground: oklch(0.34 0.13 62);
121
+ --banner-warning-border: oklch(0.62 0.18 72);
122
+ --banner-alert: oklch(0.95 0.03 22);
123
+ --banner-alert-foreground: oklch(0.34 0.14 22);
124
+ --banner-alert-border: oklch(0.52 0.2 22);
125
+
126
+ /* Interactive Elements */
127
+ --badge-success: oklch(0.35 0.1 160);
128
+ --badge-success-foreground: oklch(0.98 0.01 160);
129
+ --checkbox-checked: oklch(0.3 0.05 250);
130
+ --checkbox-checked-foreground: oklch(1 0 0);
131
+ --checkbox-unchecked-bg: oklch(1 0 0);
132
+ --checkbox-unchecked-border: oklch(0.85 0.01 250);
133
+ }
134
+
68
135
  .dark {
69
136
  /* --- Dark Theme (Modern Slate & Glow) --- */
70
137
  --background: oklch(0.18 0.015 260);
@@ -128,3 +195,67 @@
128
195
  --checkbox-unchecked-bg: oklch(0.25 0.01 260);
129
196
  --checkbox-unchecked-border: oklch(0.4 0.01 260);
130
197
  }
198
+
199
+ [data-theme="steel"].dark {
200
+ /* --- Dark Theme (Modern Slate & Glow) --- */
201
+ --background: oklch(0.18 0.015 260);
202
+ --foreground: oklch(0.985 0 0);
203
+
204
+ /* Card Elevation: Brighter than background */
205
+ --card: oklch(0.23 0.02 260 / 0.75);
206
+ --card-foreground: oklch(0.985 0 0);
207
+
208
+ --popover: oklch(0.21 0.015 260);
209
+ --popover-foreground: oklch(0.985 0 0);
210
+
211
+ /* Primary: Electric Cyan Glow */
212
+ --primary: oklch(0.9 0.1 220);
213
+ --primary-foreground: oklch(0.18 0.015 260);
214
+
215
+ --secondary: oklch(0.28 0.02 260);
216
+ --secondary-foreground: oklch(0.9 0.1 220);
217
+
218
+ --muted: oklch(0.28 0.02 260);
219
+ --muted-foreground: oklch(0.705 0.015 260);
220
+
221
+ --accent: oklch(0.28 0.02 260);
222
+ --accent-foreground: oklch(0.9 0.1 220);
223
+
224
+ --destructive: oklch(0.45 0.15 25);
225
+ --destructive-foreground: oklch(0.985 0 0);
226
+
227
+ --border: oklch(0.32 0.02 260);
228
+ --input: oklch(0.32 0.02 260);
229
+ --ring: oklch(0.9 0.1 220 / 0.3);
230
+
231
+ /* Sidebar (Dark) */
232
+ --sidebar: oklch(0.21 0.015 260);
233
+ --sidebar-foreground: oklch(0.985 0 0);
234
+ --sidebar-primary: oklch(0.9 0.1 220);
235
+ --sidebar-primary-foreground: oklch(0.18 0.015 260);
236
+ --sidebar-accent: oklch(0.28 0.02 260);
237
+ --sidebar-accent-foreground: oklch(0.985 0 0);
238
+ --sidebar-border: oklch(0.32 0.02 260);
239
+
240
+ /* Banners (Dark - Desaturated) */
241
+ --banner-info: oklch(0.274 0.079 260);
242
+ --banner-info-foreground: oklch(0.925 0.033 260);
243
+ --banner-info-border: oklch(0.488 0.2 260);
244
+ --banner-note: oklch(0.266 0.065 152);
245
+ --banner-note-foreground: oklch(0.962 0.044 156);
246
+ --banner-note-border: oklch(0.45 0.1 152);
247
+ --banner-warning: oklch(0.55 0.22 100);
248
+ --banner-warning-foreground: oklch(0.99 0.15 102);
249
+ --banner-warning-border: oklch(0.75 0.25 100);
250
+ --banner-alert: oklch(0.293 0.084 27);
251
+ --banner-alert-foreground: oklch(0.969 0.071 27);
252
+ --banner-alert-border: oklch(0.45 0.12 27);
253
+
254
+ /* Interactive Elements (Dark) */
255
+ --badge-success: oklch(0.48 0.15 150);
256
+ --badge-success-foreground: oklch(1 0 0);
257
+ --checkbox-checked: oklch(0.9 0.1 220);
258
+ --checkbox-checked-foreground: oklch(0.18 0.015 260);
259
+ --checkbox-unchecked-bg: oklch(0.25 0.01 260);
260
+ --checkbox-unchecked-border: oklch(0.4 0.01 260);
261
+ }
@@ -0,0 +1,3 @@
1
+ // This file has been reorganized.
2
+ // ThemeProvider, useTheme, Theme → ./ThemeProvider (exported via @abumble/design-system/themes)
3
+ // ThemeToggle → src/components/ThemeToggle (exported via @abumble/design-system/components/ThemeToggle)
@@ -0,0 +1,8 @@
1
+ import { useContext } from 'react'
2
+ import { ThemeContext } from './ThemeContext'
3
+
4
+ export function useTheme() {
5
+ const ctx = useContext(ThemeContext)
6
+ if (!ctx) throw new Error('useTheme must be used within ThemeProvider')
7
+ return ctx
8
+ }