zabi-components 5.0.18 → 5.0.20

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 (54) hide show
  1. package/dist/atoms/Button.svelte +6 -3
  2. package/dist/atoms/Button.svelte.d.ts +1 -0
  3. package/dist/atoms/Card.svelte +23 -47
  4. package/dist/atoms/CardContent.svelte +12 -5
  5. package/dist/atoms/CardContent.svelte.d.ts +2 -0
  6. package/dist/atoms/CardHeader.svelte +22 -5
  7. package/dist/atoms/CardHeader.svelte.d.ts +3 -0
  8. package/dist/atoms/ColorPicker.svelte +271 -7
  9. package/dist/atoms/Input.svelte +7 -6
  10. package/dist/atoms/Input.svelte.d.ts +3 -1
  11. package/dist/atoms/Progress.svelte +1 -3
  12. package/dist/atoms/Select.svelte +17 -22
  13. package/dist/atoms/Skeleton.svelte +12 -2
  14. package/dist/atoms/Skeleton.svelte.d.ts +1 -0
  15. package/dist/atoms/Tooltip.svelte +15 -17
  16. package/dist/atoms/index.d.ts +0 -2
  17. package/dist/atoms/index.js +0 -2
  18. package/dist/components/atoms/index.d.ts +0 -2
  19. package/dist/components/atoms/index.d.ts.map +1 -1
  20. package/dist/components/molecules/index.d.ts +7 -0
  21. package/dist/components/molecules/index.d.ts.map +1 -1
  22. package/dist/molecules/Dropdown.svelte +101 -14
  23. package/dist/molecules/Dropdown.svelte.d.ts +7 -0
  24. package/dist/molecules/ImageUpload.svelte +4 -4
  25. package/dist/molecules/Modal.svelte +43 -27
  26. package/dist/molecules/Modal.svelte.d.ts +1 -0
  27. package/dist/molecules/NavigationMenu.svelte +158 -0
  28. package/dist/molecules/NavigationMenu.svelte.d.ts +25 -0
  29. package/dist/molecules/NavigationMenuContent.svelte +83 -0
  30. package/dist/molecules/NavigationMenuContent.svelte.d.ts +9 -0
  31. package/dist/molecules/NavigationMenuItem.svelte +36 -0
  32. package/dist/molecules/NavigationMenuItem.svelte.d.ts +9 -0
  33. package/dist/molecules/NavigationMenuLink.svelte +53 -0
  34. package/dist/molecules/NavigationMenuLink.svelte.d.ts +10 -0
  35. package/dist/molecules/NavigationMenuList.svelte +31 -0
  36. package/dist/molecules/NavigationMenuList.svelte.d.ts +8 -0
  37. package/dist/molecules/NavigationMenuTrigger.svelte +81 -0
  38. package/dist/molecules/NavigationMenuTrigger.svelte.d.ts +9 -0
  39. package/dist/molecules/Sidebar.svelte +324 -0
  40. package/dist/molecules/Sidebar.svelte.d.ts +30 -0
  41. package/dist/molecules/SlideUp.svelte +2 -2
  42. package/dist/molecules/index.d.ts +7 -0
  43. package/dist/molecules/index.js +7 -0
  44. package/dist/routes/lib/focus-utils.d.ts +23 -0
  45. package/dist/routes/lib/focus-utils.ts +112 -0
  46. package/dist/zabi-components-colors.css +2 -2
  47. package/dist/zabi-components-theme-only.css +2 -2
  48. package/dist/zabi-components-theme.css +2 -2
  49. package/dist/zabi-components.css +192 -27
  50. package/package.json +4 -3
  51. package/dist/atoms/CardDescription.svelte +0 -24
  52. package/dist/atoms/CardDescription.svelte.d.ts +0 -8
  53. package/dist/atoms/CardTitle.svelte +0 -33
  54. package/dist/atoms/CardTitle.svelte.d.ts +0 -9
@@ -0,0 +1,324 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import { onMount, onDestroy } from "svelte";
4
+
5
+ interface SidebarItem {
6
+ id: string;
7
+ label: string;
8
+ description?: string;
9
+ icon?: any;
10
+ onClick?: () => void;
11
+ }
12
+
13
+ interface SidebarSection {
14
+ title?: string;
15
+ items: SidebarItem[];
16
+ }
17
+
18
+ interface Props {
19
+ title?: string;
20
+ sections?: SidebarSection[];
21
+ items?: SidebarItem[];
22
+ selectedItemId?: string;
23
+ selectedSectionId?: string;
24
+ onItemClick?: (item: SidebarItem) => void;
25
+ onSectionClick?: (sectionId: string) => void;
26
+ className?: string;
27
+ header?: Snippet;
28
+ footer?: Snippet;
29
+ isOpen?: boolean;
30
+ onClose?: () => void;
31
+ mobileResponsive?: boolean;
32
+ }
33
+
34
+ let {
35
+ title = "",
36
+ sections = [],
37
+ items = [],
38
+ selectedItemId = "",
39
+ selectedSectionId = "",
40
+ onItemClick,
41
+ onSectionClick,
42
+ className = "",
43
+ header,
44
+ footer,
45
+ isOpen = true,
46
+ onClose,
47
+ mobileResponsive = true,
48
+ ...restProps
49
+ }: Props = $props();
50
+
51
+ let isMobile = $state(false);
52
+ let sidebarElement = $state<HTMLElement | null>(null);
53
+
54
+ function checkMobile() {
55
+ if (mobileResponsive) {
56
+ isMobile = window.innerWidth < 768;
57
+ } else {
58
+ isMobile = false;
59
+ }
60
+ }
61
+
62
+ function handleItemClick(item: SidebarItem) {
63
+ if (item.onClick) {
64
+ item.onClick();
65
+ }
66
+ if (onItemClick) {
67
+ onItemClick(item);
68
+ }
69
+ // Close sidebar on mobile when item is clicked
70
+ if (isMobile && onClose) {
71
+ onClose();
72
+ }
73
+ }
74
+
75
+ function handleSectionClick(sectionId: string) {
76
+ if (onSectionClick) {
77
+ onSectionClick(sectionId);
78
+ }
79
+ }
80
+
81
+ function handleBackdropClick(event: MouseEvent) {
82
+ if (event.target === event.currentTarget && onClose) {
83
+ onClose();
84
+ }
85
+ }
86
+
87
+ function handleKeydown(event: KeyboardEvent) {
88
+ if (event.key === "Escape" && isOpen && isMobile && onClose) {
89
+ onClose();
90
+ }
91
+ }
92
+
93
+ onMount(() => {
94
+ checkMobile();
95
+ if (mobileResponsive) {
96
+ window.addEventListener("resize", checkMobile);
97
+ return () => window.removeEventListener("resize", checkMobile);
98
+ }
99
+ });
100
+
101
+ const hasSections = $derived(sections.length > 0);
102
+ const hasItems = $derived(items.length > 0);
103
+ </script>
104
+
105
+ {#if isMobile && mobileResponsive}
106
+ <!-- Mobile: Overlay and Drawer -->
107
+ {#if isOpen}
108
+ <div
109
+ class="fixed inset-0 bg-overlay z-modal md:hidden"
110
+ onclick={handleBackdropClick}
111
+ onkeydown={handleKeydown}
112
+ role="dialog"
113
+ aria-modal="true"
114
+ aria-label="Sidebar navigation"
115
+ tabindex="-1"
116
+ >
117
+ <aside
118
+ bind:this={sidebarElement}
119
+ class="fixed left-0 top-0 bottom-0 w-64 bg-base-100 border-r border-border p-6 h-full overflow-y-auto transform transition-transform duration-300 ease-in-out {isOpen ? 'translate-x-0' : '-translate-x-full'} {className}"
120
+ role="complementary"
121
+ aria-label="Sidebar navigation"
122
+ onclick={(e) => e.stopPropagation()}
123
+ {...restProps}
124
+ >
125
+ <div class="flex items-center justify-between mb-4 md:hidden">
126
+ {#if title}
127
+ <h2 class="text-lg font-semibold text-headline">{title}</h2>
128
+ {/if}
129
+ {#if onClose}
130
+ <button
131
+ type="button"
132
+ onclick={onClose}
133
+ class="text-description hover:text-headline text-2xl cursor-pointer transition-colors w-8 h-8 flex items-center justify-center rounded-full hover:bg-base-50"
134
+ aria-label="Close sidebar"
135
+ >
136
+ ×
137
+ </button>
138
+ {/if}
139
+ </div>
140
+
141
+ {#if header}
142
+ <div class="mb-6">
143
+ {@render header()}
144
+ </div>
145
+ {:else if title && !isMobile}
146
+ <h2 class="text-lg font-semibold text-headline mb-4">{title}</h2>
147
+ {/if}
148
+
149
+ {#if hasSections}
150
+ {#each sections as section}
151
+ {#if section.title}
152
+ <div class="mb-4">
153
+ <h3 class="text-sm font-medium text-headline mb-2 uppercase tracking-wide">
154
+ {section.title}
155
+ </h3>
156
+ </div>
157
+ {/if}
158
+
159
+ <nav class="space-y-2 mb-8">
160
+ {#each section.items as item}
161
+ <button
162
+ type="button"
163
+ onclick={() => handleItemClick(item)}
164
+ class="w-full text-left px-3 py-2 rounded-md transition-colors duration-200 {selectedItemId ===
165
+ item.id
166
+ ? 'bg-action-primary-subtle text-headline border-l-2 border-action-primary'
167
+ : 'text-secondary hover:text-headline hover:bg-base-50'}"
168
+ aria-current={selectedItemId === item.id ? "page" : undefined}
169
+ >
170
+ <div class="flex items-center gap-2">
171
+ {#if item.icon}
172
+ <div class="shrink-0">
173
+ <svelte:component this={item.icon} class="h-4 w-4" />
174
+ </div>
175
+ {/if}
176
+ <div class="flex-1">
177
+ <div class="font-medium">{item.label}</div>
178
+ {#if item.description}
179
+ <div class="text-xs text-description">
180
+ {item.description}
181
+ </div>
182
+ {/if}
183
+ </div>
184
+ </div>
185
+ </button>
186
+ {/each}
187
+ </nav>
188
+ {/each}
189
+ {:else if hasItems}
190
+ <nav class="space-y-1">
191
+ {#each items as item}
192
+ <button
193
+ type="button"
194
+ onclick={() => handleItemClick(item)}
195
+ class="w-full text-left px-3 py-2 rounded-md transition-colors duration-200 {selectedItemId ===
196
+ item.id
197
+ ? 'bg-action-primary-subtle text-headline border-l-2 border-action-primary'
198
+ : 'text-secondary hover:text-headline hover:bg-base-50'}"
199
+ aria-current={selectedItemId === item.id ? "page" : undefined}
200
+ >
201
+ <div class="flex items-center gap-2">
202
+ {#if item.icon}
203
+ <div class="shrink-0">
204
+ <svelte:component this={item.icon} class="h-4 w-4" />
205
+ </div>
206
+ {/if}
207
+ <div class="flex-1">
208
+ <div class="font-medium">{item.label}</div>
209
+ {#if item.description}
210
+ <div class="text-xs text-description">
211
+ {item.description}
212
+ </div>
213
+ {/if}
214
+ </div>
215
+ </div>
216
+ </button>
217
+ {/each}
218
+ </nav>
219
+ {/if}
220
+
221
+ {#if footer}
222
+ <div class="mt-auto pt-6 border-t border-border">
223
+ {@render footer()}
224
+ </div>
225
+ {/if}
226
+ </aside>
227
+ </div>
228
+ {/if}
229
+ {:else}
230
+ <!-- Desktop: Always visible sidebar -->
231
+ <aside
232
+ bind:this={sidebarElement}
233
+ class="w-64 bg-base-100 border-r border-border p-6 h-full overflow-y-auto {className}"
234
+ role="complementary"
235
+ aria-label="Sidebar navigation"
236
+ {...restProps}
237
+ >
238
+ {#if header}
239
+ <div class="mb-6">
240
+ {@render header()}
241
+ </div>
242
+ {:else if title}
243
+ <h2 class="text-lg font-semibold text-headline mb-4">{title}</h2>
244
+ {/if}
245
+
246
+ {#if hasSections}
247
+ {#each sections as section}
248
+ {#if section.title}
249
+ <div class="mb-4">
250
+ <h3 class="text-sm font-medium text-headline mb-2 uppercase tracking-wide">
251
+ {section.title}
252
+ </h3>
253
+ </div>
254
+ {/if}
255
+
256
+ <nav class="space-y-2 mb-8">
257
+ {#each section.items as item}
258
+ <button
259
+ type="button"
260
+ onclick={() => handleItemClick(item)}
261
+ class="w-full text-left px-3 py-2 rounded-md transition-colors duration-200 {selectedItemId ===
262
+ item.id
263
+ ? 'bg-action-primary-subtle text-headline border-l-2 border-action-primary'
264
+ : 'text-secondary hover:text-headline hover:bg-base-50'}"
265
+ aria-current={selectedItemId === item.id ? "page" : undefined}
266
+ >
267
+ <div class="flex items-center gap-2">
268
+ {#if item.icon}
269
+ <div class="shrink-0">
270
+ <svelte:component this={item.icon} class="h-4 w-4" />
271
+ </div>
272
+ {/if}
273
+ <div class="flex-1">
274
+ <div class="font-medium">{item.label}</div>
275
+ {#if item.description}
276
+ <div class="text-xs text-description">
277
+ {item.description}
278
+ </div>
279
+ {/if}
280
+ </div>
281
+ </div>
282
+ </button>
283
+ {/each}
284
+ </nav>
285
+ {/each}
286
+ {:else if hasItems}
287
+ <nav class="space-y-1">
288
+ {#each items as item}
289
+ <button
290
+ type="button"
291
+ onclick={() => handleItemClick(item)}
292
+ class="w-full text-left px-3 py-2 rounded-md transition-colors duration-200 {selectedItemId ===
293
+ item.id
294
+ ? 'bg-action-primary-subtle text-headline border-l-2 border-action-primary'
295
+ : 'text-secondary hover:text-headline hover:bg-base-50'}"
296
+ aria-current={selectedItemId === item.id ? "page" : undefined}
297
+ >
298
+ <div class="flex items-center gap-2">
299
+ {#if item.icon}
300
+ <div class="shrink-0">
301
+ <svelte:component this={item.icon} class="h-4 w-4" />
302
+ </div>
303
+ {/if}
304
+ <div class="flex-1">
305
+ <div class="font-medium">{item.label}</div>
306
+ {#if item.description}
307
+ <div class="text-xs text-description">
308
+ {item.description}
309
+ </div>
310
+ {/if}
311
+ </div>
312
+ </div>
313
+ </button>
314
+ {/each}
315
+ </nav>
316
+ {/if}
317
+
318
+ {#if footer}
319
+ <div class="mt-auto pt-6 border-t border-border">
320
+ {@render footer()}
321
+ </div>
322
+ {/if}
323
+ </aside>
324
+ {/if}
@@ -0,0 +1,30 @@
1
+ import type { Snippet } from "svelte";
2
+ interface SidebarItem {
3
+ id: string;
4
+ label: string;
5
+ description?: string;
6
+ icon?: any;
7
+ onClick?: () => void;
8
+ }
9
+ interface SidebarSection {
10
+ title?: string;
11
+ items: SidebarItem[];
12
+ }
13
+ interface Props {
14
+ title?: string;
15
+ sections?: SidebarSection[];
16
+ items?: SidebarItem[];
17
+ selectedItemId?: string;
18
+ selectedSectionId?: string;
19
+ onItemClick?: (item: SidebarItem) => void;
20
+ onSectionClick?: (sectionId: string) => void;
21
+ className?: string;
22
+ header?: Snippet;
23
+ footer?: Snippet;
24
+ isOpen?: boolean;
25
+ onClose?: () => void;
26
+ mobileResponsive?: boolean;
27
+ }
28
+ declare const Sidebar: import("svelte").Component<Props, {}, "">;
29
+ type Sidebar = ReturnType<typeof Sidebar>;
30
+ export default Sidebar;
@@ -39,7 +39,7 @@
39
39
 
40
40
  {#if isOpen}
41
41
  <div
42
- class="fixed inset-0 bg-black/50 dark:bg-black/70 z-modal"
42
+ class="fixed inset-0 bg-overlay z-modal"
43
43
  onclick={handleBackdropClick}
44
44
  onkeydown={handleKeydown}
45
45
  role="dialog"
@@ -48,7 +48,7 @@
48
48
  tabindex="-1"
49
49
  >
50
50
  <div
51
- class="fixed bottom-0 left-0 right-0 bg-base-50 rounded-t-3xl shadow-xl z-modal max-h-[90vh] overflow-y-auto animate-[slideUp_0.3s_ease-out] flex flex-col"
51
+ class="fixed bottom-0 left-0 right-0 bg-card rounded-t-3xl shadow-xl z-modal max-h-[90vh] overflow-y-auto animate-[slideUp_0.3s_ease-out] flex flex-col"
52
52
  >
53
53
  {#if title}
54
54
  <div class="flex items-center justify-between px-6 pt-6 pb-4">
@@ -5,5 +5,12 @@ export { default as Dropdown } from './Dropdown.svelte';
5
5
  export { default as Form } from './Form.svelte';
6
6
  export { default as ImageUpload } from './ImageUpload.svelte';
7
7
  export { default as Modal } from './Modal.svelte';
8
+ export { default as NavigationMenu } from './NavigationMenu.svelte';
9
+ export { default as NavigationMenuList } from './NavigationMenuList.svelte';
10
+ export { default as NavigationMenuItem } from './NavigationMenuItem.svelte';
11
+ export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.svelte';
12
+ export { default as NavigationMenuContent } from './NavigationMenuContent.svelte';
13
+ export { default as NavigationMenuLink } from './NavigationMenuLink.svelte';
14
+ export { default as Sidebar } from './Sidebar.svelte';
8
15
  export { default as SlideUp } from './SlideUp.svelte';
9
16
  export { default as Tabs } from './Tabs.svelte';
@@ -5,5 +5,12 @@ export { default as Dropdown } from './Dropdown.svelte';
5
5
  export { default as Form } from './Form.svelte';
6
6
  export { default as ImageUpload } from './ImageUpload.svelte';
7
7
  export { default as Modal } from './Modal.svelte';
8
+ export { default as NavigationMenu } from './NavigationMenu.svelte';
9
+ export { default as NavigationMenuList } from './NavigationMenuList.svelte';
10
+ export { default as NavigationMenuItem } from './NavigationMenuItem.svelte';
11
+ export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.svelte';
12
+ export { default as NavigationMenuContent } from './NavigationMenuContent.svelte';
13
+ export { default as NavigationMenuLink } from './NavigationMenuLink.svelte';
14
+ export { default as Sidebar } from './Sidebar.svelte';
8
15
  export { default as SlideUp } from './SlideUp.svelte';
9
16
  export { default as Tabs } from './Tabs.svelte';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Focus management utilities for accessibility
3
+ */
4
+ /**
5
+ * Get all focusable elements within a container
6
+ */
7
+ export declare function getFocusableElements(container: HTMLElement): HTMLElement[];
8
+ /**
9
+ * Trap focus within a container element
10
+ */
11
+ export declare function trapFocus(container: HTMLElement): () => void;
12
+ /**
13
+ * Save the currently focused element
14
+ */
15
+ export declare function saveFocus(): void;
16
+ /**
17
+ * Return focus to the previously focused element
18
+ */
19
+ export declare function returnFocus(): void;
20
+ /**
21
+ * Focus the first focusable element in a container
22
+ */
23
+ export declare function focusFirstElement(container: HTMLElement): void;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Focus management utilities for accessibility
3
+ */
4
+
5
+ /**
6
+ * Get all focusable elements within a container
7
+ */
8
+ export function getFocusableElements(container: HTMLElement): HTMLElement[] {
9
+ const selector = [
10
+ 'button:not([disabled])',
11
+ '[href]',
12
+ 'input:not([disabled])',
13
+ 'select:not([disabled])',
14
+ 'textarea:not([disabled])',
15
+ '[tabindex]:not([tabindex="-1"])',
16
+ ].join(', ');
17
+
18
+ return Array.from(container.querySelectorAll<HTMLElement>(selector)).filter(
19
+ (el) => {
20
+ // Filter out elements that are not visible
21
+ const style = window.getComputedStyle(el);
22
+ return style.display !== 'none' && style.visibility !== 'hidden';
23
+ }
24
+ );
25
+ }
26
+
27
+ /**
28
+ * Trap focus within a container element
29
+ */
30
+ export function trapFocus(container: HTMLElement): () => void {
31
+ const focusableElements = getFocusableElements(container);
32
+
33
+ if (focusableElements.length === 0) {
34
+ return () => {}; // No-op cleanup
35
+ }
36
+
37
+ const firstElement = focusableElements[0];
38
+ const lastElement = focusableElements[focusableElements.length - 1];
39
+
40
+ // Focus first element
41
+ firstElement.focus();
42
+
43
+ function handleKeydown(event: KeyboardEvent) {
44
+ if (event.key !== 'Tab') {
45
+ return;
46
+ }
47
+
48
+ const currentFocus = document.activeElement as HTMLElement;
49
+
50
+ if (!focusableElements.includes(currentFocus)) {
51
+ event.preventDefault();
52
+ firstElement.focus();
53
+ return;
54
+ }
55
+
56
+ if (event.shiftKey) {
57
+ // Shift + Tab
58
+ if (currentFocus === firstElement) {
59
+ event.preventDefault();
60
+ lastElement.focus();
61
+ }
62
+ } else {
63
+ // Tab
64
+ if (currentFocus === lastElement) {
65
+ event.preventDefault();
66
+ firstElement.focus();
67
+ }
68
+ }
69
+ }
70
+
71
+ container.addEventListener('keydown', handleKeydown);
72
+
73
+ // Return cleanup function
74
+ return () => {
75
+ container.removeEventListener('keydown', handleKeydown);
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Store the element that had focus before opening a modal/dialog
81
+ */
82
+ let previousFocus: HTMLElement | null = null;
83
+
84
+ /**
85
+ * Save the currently focused element
86
+ */
87
+ export function saveFocus(): void {
88
+ if (typeof document !== 'undefined') {
89
+ previousFocus = document.activeElement as HTMLElement;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Return focus to the previously focused element
95
+ */
96
+ export function returnFocus(): void {
97
+ if (previousFocus && typeof document !== 'undefined') {
98
+ previousFocus.focus();
99
+ previousFocus = null;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Focus the first focusable element in a container
105
+ */
106
+ export function focusFirstElement(container: HTMLElement): void {
107
+ const focusableElements = getFocusableElements(container);
108
+ if (focusableElements.length > 0) {
109
+ focusableElements[0].focus();
110
+ }
111
+ }
112
+
@@ -194,8 +194,8 @@
194
194
  --color-action-primary-text: var(--color-brand-50);
195
195
 
196
196
  /* Secondary Actions - Used by bg-action-secondary utility class */
197
- --color-action-secondary: var(--color-brand-200);
198
- --color-action-secondary-hover: var(--color-brand-100);
197
+ --color-action-secondary: color-mix(in srgb, var(--color-brand-800) 10%, transparent);
198
+ --color-action-secondary-hover: color-mix(in srgb, var(--color-brand-800) 20%, transparent);
199
199
  --color-action-secondary-active: var(--color-brand-400);
200
200
  --color-action-secondary-disabled: var(--color-brand-500);
201
201
  --color-action-secondary-subtle: var(--color-brand-600);
@@ -186,8 +186,8 @@
186
186
  --color-action-primary-text: var(--color-brand-50);
187
187
 
188
188
  /* Secondary Actions - Used by bg-action-secondary utility class */
189
- --color-action-secondary: var(--color-brand-200);
190
- --color-action-secondary-hover: var(--color-brand-100);
189
+ --color-action-secondary: color-mix(in srgb, var(--color-brand-800) 10%, transparent);
190
+ --color-action-secondary-hover: color-mix(in srgb, var(--color-brand-800) 20%, transparent);
191
191
  --color-action-secondary-active: var(--color-brand-400);
192
192
  --color-action-secondary-disabled: var(--color-brand-500);
193
193
  --color-action-secondary-subtle: var(--color-brand-600);
@@ -188,8 +188,8 @@
188
188
  --color-action-primary-text: var(--color-brand-50);
189
189
 
190
190
  /* Secondary Actions - Used by bg-action-secondary utility class */
191
- --color-action-secondary: var(--color-brand-200);
192
- --color-action-secondary-hover: var(--color-brand-100);
191
+ --color-action-secondary: color-mix(in srgb, var(--color-brand-800) 10%, transparent);
192
+ --color-action-secondary-hover: color-mix(in srgb, var(--color-brand-800) 20%, transparent);
193
193
  --color-action-secondary-active: var(--color-brand-400);
194
194
  --color-action-secondary-disabled: var(--color-brand-500);
195
195
  --color-action-secondary-subtle: var(--color-brand-600);