@svadmin/ui 0.5.13 → 0.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/ui",
3
- "version": "0.5.13",
3
+ "version": "0.5.14",
4
4
  "description": "Pre-built admin UI components — AdminApp, AutoTable, AutoForm, Sidebar, Layout",
5
5
  "type": "module",
6
6
  "sideEffects": [
package/src/app.css CHANGED
@@ -1,110 +1,100 @@
1
- /* Typography — Inter font should be imported in index.html for New York style */
1
+ /* Typography — Inter font for clean, modern look */
2
2
 
3
- /* @svadmin/ui — Design Tokens (Shadcn New York style)
3
+ /* @svadmin/ui — Design Tokens (Elygate-inspired)
4
4
  * Auto-imported by AdminApp. Can be overridden by consumer's CSS.
5
5
  *
6
- * Based on shadcn/ui "New York" theme with oklch() color space.
7
- * Differences from "Default" style:
8
- * - Smaller border-radius (0.5rem vs 0.625rem)
9
- * - Refined color palette with deeper contrast
10
- * - Chart color tokens included
11
- * - More polished dark mode
6
+ * Based on Elygate dashboard style: Indigo primary, light glassmorphism,
7
+ * professional admin aesthetic with subtle depth.
12
8
  */
13
9
 
14
- /* Auto-register svadmin source files for Tailwind 4 content scanning.
15
- * This ensures all utility classes used in @svadmin/ui and @svadmin/core
16
- * components are generated without manual @source in consumer projects. */
17
- @source "@svadmin/ui/src/**/*.{svelte,ts,js}";
18
- @source "@svadmin/core/src/**/*.{svelte,ts,js}";
19
-
20
10
  @layer base {
21
11
  :root {
22
12
  --radius: 0.5rem;
23
- --background: oklch(1 0 0);
24
- --foreground: oklch(0.145 0 0);
13
+ --background: oklch(0.98 0.002 264);
14
+ --foreground: oklch(0.13 0.02 265);
25
15
  --card: oklch(1 0 0);
26
- --card-foreground: oklch(0.145 0 0);
16
+ --card-foreground: oklch(0.13 0.02 265);
27
17
  --popover: oklch(1 0 0);
28
- --popover-foreground: oklch(0.145 0 0);
29
- --primary: oklch(0.205 0 0);
18
+ --popover-foreground: oklch(0.13 0.02 265);
19
+ --primary: oklch(0.488 0.243 264.376);
30
20
  --primary-foreground: oklch(0.985 0 0);
31
- --secondary: oklch(0.965 0 0);
32
- --secondary-foreground: oklch(0.205 0 0);
33
- --muted: oklch(0.965 0 0);
34
- --muted-foreground: oklch(0.45 0 0);
35
- --accent: oklch(0.965 0 0);
36
- --accent-foreground: oklch(0.205 0 0);
21
+ --secondary: oklch(0.955 0.008 264);
22
+ --secondary-foreground: oklch(0.2 0.04 265);
23
+ --muted: oklch(0.955 0.005 264);
24
+ --muted-foreground: oklch(0.45 0.03 260);
25
+ --accent: oklch(0.955 0.008 264);
26
+ --accent-foreground: oklch(0.2 0.04 265);
37
27
  --destructive: oklch(0.577 0.245 27.325);
38
28
  --destructive-foreground: oklch(0.985 0 0);
39
- --border: oklch(0.922 0 0);
40
- --input: oklch(0.922 0 0);
41
- --ring: oklch(0.708 0 0);
42
- --chart-1: oklch(0.646 0.222 41.116);
29
+ --border: oklch(0.912 0.008 264);
30
+ --input: oklch(0.912 0.008 264);
31
+ --ring: oklch(0.488 0.243 264.376);
32
+ --chart-1: oklch(0.488 0.243 264.376);
43
33
  --chart-2: oklch(0.6 0.118 184.704);
44
34
  --chart-3: oklch(0.398 0.07 227.392);
45
35
  --chart-4: oklch(0.828 0.189 84.429);
46
36
  --chart-5: oklch(0.769 0.188 70.08);
47
- --sidebar: oklch(0.985 0 0);
48
- --sidebar-foreground: oklch(0.145 0 0);
49
- --sidebar-primary: oklch(0.205 0 0);
37
+ --sidebar: oklch(1 0 0 / 80%);
38
+ --sidebar-foreground: oklch(0.13 0.02 265);
39
+ --sidebar-primary: oklch(0.488 0.243 264.376);
50
40
  --sidebar-primary-foreground: oklch(0.985 0 0);
51
- --sidebar-accent: oklch(0.965 0 0);
52
- --sidebar-accent-foreground: oklch(0.205 0 0);
53
- --sidebar-border: oklch(0.922 0 0);
54
- --sidebar-ring: oklch(0.708 0 0);
41
+ --sidebar-accent: oklch(0.94 0.025 264);
42
+ --sidebar-accent-foreground: oklch(0.33 0.17 264);
43
+ --sidebar-border: oklch(0.912 0.008 264);
44
+ --sidebar-ring: oklch(0.488 0.243 264.376);
55
45
  }
56
46
 
57
47
  .dark {
58
- --background: oklch(0.145 0 0);
48
+ --background: oklch(0.13 0.015 265);
59
49
  --foreground: oklch(0.985 0 0);
60
- --card: oklch(0.178 0 0);
50
+ --card: oklch(0.16 0.015 265);
61
51
  --card-foreground: oklch(0.985 0 0);
62
- --popover: oklch(0.178 0 0);
52
+ --popover: oklch(0.16 0.015 265);
63
53
  --popover-foreground: oklch(0.985 0 0);
64
- --primary: oklch(0.985 0 0);
65
- --primary-foreground: oklch(0.205 0 0);
66
- --secondary: oklch(0.269 0 0);
54
+ --primary: oklch(0.585 0.233 264);
55
+ --primary-foreground: oklch(0.15 0.04 265);
56
+ --secondary: oklch(0.23 0.025 265);
67
57
  --secondary-foreground: oklch(0.985 0 0);
68
- --muted: oklch(0.269 0 0);
69
- --muted-foreground: oklch(0.708 0 0);
70
- --accent: oklch(0.269 0 0);
58
+ --muted: oklch(0.23 0.025 265);
59
+ --muted-foreground: oklch(0.7 0.02 260);
60
+ --accent: oklch(0.23 0.025 265);
71
61
  --accent-foreground: oklch(0.985 0 0);
72
62
  --destructive: oklch(0.704 0.191 22.216);
73
63
  --destructive-foreground: oklch(0.985 0 0);
74
- --border: oklch(1 0 0 / 10%);
75
- --input: oklch(1 0 0 / 15%);
76
- --ring: oklch(0.556 0 0);
77
- --chart-1: oklch(0.488 0.243 264.376);
64
+ --border: oklch(0.23 0.025 265);
65
+ --input: oklch(0.23 0.025 265);
66
+ --ring: oklch(0.55 0.18 264);
67
+ --chart-1: oklch(0.585 0.233 264);
78
68
  --chart-2: oklch(0.696 0.17 162.48);
79
69
  --chart-3: oklch(0.769 0.188 70.08);
80
70
  --chart-4: oklch(0.627 0.265 303.9);
81
71
  --chart-5: oklch(0.645 0.246 16.439);
82
- --sidebar: oklch(0.178 0 0);
72
+ --sidebar: oklch(0.16 0.015 265 / 80%);
83
73
  --sidebar-foreground: oklch(0.985 0 0);
84
- --sidebar-primary: oklch(0.488 0.243 264.376);
74
+ --sidebar-primary: oklch(0.585 0.233 264);
85
75
  --sidebar-primary-foreground: oklch(0.985 0 0);
86
- --sidebar-accent: oklch(0.269 0 0);
87
- --sidebar-accent-foreground: oklch(0.985 0 0);
88
- --sidebar-border: oklch(1 0 0 / 10%);
89
- --sidebar-ring: oklch(0.556 0 0);
76
+ --sidebar-accent: oklch(0.488 0.243 264.376 / 10%);
77
+ --sidebar-accent-foreground: oklch(0.7 0.15 264);
78
+ --sidebar-border: oklch(0.23 0.025 265);
79
+ --sidebar-ring: oklch(0.55 0.18 264);
90
80
  }
91
81
 
92
- /* Emulate new-york style shadows on inputs and buttons */
82
+ /* Elygate-style shadows — subtle depth without heaviness */
93
83
  [data-slot="button"],
94
84
  [data-slot="input"],
95
85
  [data-slot="select-trigger"],
96
86
  [data-slot="select"],
97
87
  [data-slot="textarea"] {
98
- @apply shadow-sm;
88
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
99
89
  }
100
90
 
101
91
  [data-slot="card"] {
102
- @apply shadow-sm;
92
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.06), 0 1px 2px -1px rgb(0 0 0 / 0.06);
103
93
  }
104
94
 
105
95
  [data-slot="dialog-content"],
106
96
  [data-slot="sheet-content"] {
107
- @apply shadow-lg;
97
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
108
98
  }
109
99
  }
110
100
 
@@ -122,10 +112,7 @@ body {
122
112
  .dark ::-webkit-scrollbar-thumb { background: oklch(0.35 0 0); }
123
113
  .dark ::-webkit-scrollbar-thumb:hover { background: oklch(0.45 0 0); }
124
114
 
125
- /* Tailwind CSS v4 — Map design tokens to utility classes
126
- * This enables bg-primary, text-muted-foreground, border-input, etc.
127
- * Without this, Tailwind 4 utility classes referencing these tokens are no-ops.
128
- */
115
+ /* Tailwind CSS v4 — Map design tokens to utility classes */
129
116
  @theme {
130
117
  --color-background: var(--background);
131
118
  --color-foreground: var(--foreground);
@@ -119,7 +119,7 @@
119
119
  {@render dashboard()}
120
120
  {:else}
121
121
  <div class="space-y-4">
122
- <h1 class="text-2xl font-bold text-foreground">{t('common.welcome', { title })}</h1>
122
+ <h1 class="text-xl font-semibold text-foreground">{t('common.welcome', { title })}</h1>
123
123
  <p class="text-muted-foreground">{t('common.dashboardHint')}</p>
124
124
  </div>
125
125
  {/if}
@@ -222,7 +222,7 @@
222
222
  >
223
223
  <ArrowLeft class="h-5 w-5" />
224
224
  </TooltipButton>
225
- <h1 class="text-2xl font-bold text-foreground">{pageTitle}</h1>
225
+ <h1 class="text-xl font-semibold text-foreground">{pageTitle}</h1>
226
226
  {#if isDirty}
227
227
  <Badge variant="outline" class="border-amber-200 bg-amber-50 text-amber-700">{t('common.unsaved')}</Badge>
228
228
  {/if}
@@ -230,7 +230,7 @@
230
230
 
231
231
  {#if isLoading}
232
232
  <div class="max-w-3xl space-y-6">
233
- <div class="rounded-xl border p-6 space-y-5">
233
+ <div class="rounded-lg border p-6 space-y-5">
234
234
  {#each Array(4) as _}
235
235
  <div class="space-y-2">
236
236
  <Skeleton class="h-4 w-24" />
@@ -311,7 +311,7 @@
311
311
  <div class="space-y-4">
312
312
  <!-- Header -->
313
313
  <div class="flex items-center justify-between">
314
- <h1 class="text-2xl font-bold text-foreground">{resource.label}</h1>
314
+ <h1 class="text-xl font-semibold text-foreground">{resource.label}</h1>
315
315
  <div class="flex items-center gap-2">
316
316
  {#if canExport}
317
317
  <Button variant="outline" size="sm" onclick={exportCSV}>
@@ -414,7 +414,7 @@
414
414
  {/if}
415
415
 
416
416
  <!-- Table (TanStack-powered) -->
417
- <div class="rounded-xl border border-border/60 bg-card shadow-md overflow-hidden">
417
+ <div class="rounded-lg border border-border bg-card shadow-sm overflow-hidden">
418
418
  {#if query.isLoading}
419
419
  <div class="p-4 space-y-3">
420
420
  <div class="flex gap-4 mb-2">
@@ -48,14 +48,14 @@
48
48
  }
49
49
  </script>
50
50
 
51
- <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-destructive/[0.05] via-background to-destructive/[0.03] p-4">
51
+ <div class="min-h-screen flex items-center justify-center bg-background p-4">
52
52
  <div class="w-full max-w-[480px]">
53
- <Card.Card class="backdrop-blur-xl border-border/50 shadow-[0_8px_32px_hsl(var(--destructive)/0.08),0_2px_8px_hsl(0_0%_0%/0.06)]">
53
+ <Card.Card>
54
54
  <Card.CardHeader class="text-center pb-2">
55
- <div class="inline-flex items-center justify-center w-14 h-14 rounded-[14px] bg-destructive/10 text-destructive mx-auto mb-3">
56
- <AlertTriangle class="h-7 w-7" />
55
+ <div class="inline-flex items-center justify-center w-12 h-12 rounded-lg bg-destructive/10 text-destructive mx-auto mb-3">
56
+ <AlertTriangle class="h-6 w-6" />
57
57
  </div>
58
- <Card.CardTitle class="text-xl font-bold">{displayTitle}</Card.CardTitle>
58
+ <Card.CardTitle class="text-xl">{displayTitle}</Card.CardTitle>
59
59
  <p class="text-sm text-muted-foreground">
60
60
  {t('config.missingEnvDescription')}
61
61
  </p>
@@ -34,18 +34,18 @@
34
34
  }
35
35
  </script>
36
36
 
37
- <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary/[0.08] via-background to-primary/[0.04] p-4">
38
- <div class="w-full max-w-[420px]">
39
- <Card.Card class="backdrop-blur-xl border-border/50 shadow-[0_8px_32px_hsl(var(--primary)/0.08),0_2px_8px_hsl(0_0%_0%/0.06)]">
37
+ <div class="min-h-screen flex items-center justify-center bg-background p-4">
38
+ <div class="w-full max-w-[380px]">
39
+ <Card.Card>
40
40
  <Card.CardHeader class="text-center pb-2">
41
- <div class="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mx-auto mb-3">
41
+ <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
42
42
  {#if sent}
43
- <CheckCircle class="h-6 w-6" />
43
+ <CheckCircle class="h-5 w-5" />
44
44
  {:else}
45
- <KeyRound class="h-6 w-6" />
45
+ <KeyRound class="h-5 w-5" />
46
46
  {/if}
47
47
  </div>
48
- <Card.CardTitle class="text-2xl font-bold">
48
+ <Card.CardTitle class="text-xl">
49
49
  {sent ? t('auth.resetLinkSent') : t('auth.forgotPassword')}
50
50
  </Card.CardTitle>
51
51
  {#if !sent}
@@ -7,7 +7,7 @@
7
7
  import { t } from '@svadmin/core/i18n';
8
8
 
9
9
  let {
10
- showThemeToggle = true,
10
+ showThemeToggle = false,
11
11
  showBreadcrumbs = true,
12
12
  showSearch = true,
13
13
  onSearchClick,
@@ -21,20 +21,19 @@
21
21
  }>();
22
22
  </script>
23
23
 
24
- <header class="sticky top-0 z-30 flex h-16 w-full shrink-0 items-center justify-between border-b bg-background/95 px-4 backdrop-blur supports-[backdrop-filter]:bg-background/60 md:px-6">
24
+ <header class="sticky top-0 z-30 flex h-14 w-full shrink-0 items-center justify-between border-b border-slate-200/60 dark:border-slate-800/60 bg-white/60 dark:bg-slate-900/60 backdrop-blur-md px-4 md:px-6">
25
25
  <div class="flex items-center gap-4">
26
+ {#if children}
27
+ {@render children()}
28
+ {/if}
26
29
  {#if showBreadcrumbs}
27
30
  <Breadcrumbs />
28
31
  {/if}
29
32
  </div>
30
33
  <div class="ml-auto flex items-center gap-2">
31
- {#if children}
32
- {@render children()}
33
- {/if}
34
-
35
34
  {#if showSearch && onSearchClick}
36
- <Button variant="outline" size="sm" onclick={onSearchClick} class="gap-2 text-muted-foreground">
37
- <Search class="h-4 w-4" />
35
+ <Button variant="outline" size="sm" onclick={onSearchClick} class="gap-2 text-muted-foreground h-8 px-3">
36
+ <Search class="h-3.5 w-3.5" />
38
37
  <span class="hidden sm:inline text-xs">Search...</span>
39
38
  <kbd class="hidden sm:inline-flex items-center gap-0.5 rounded border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
40
39
  <span class="text-xs">⌘</span>K
@@ -45,9 +44,9 @@
45
44
  {#if showThemeToggle}
46
45
  <TooltipButton tooltip={t('common.toggleTheme')} onclick={() => toggleTheme()} class="rounded-full">
47
46
  {#if getResolvedTheme() === 'dark'}
48
- <Moon class="h-5 w-5 transition-all" />
47
+ <Moon class="h-4 w-4 transition-all" />
49
48
  {:else}
50
- <Sun class="h-5 w-5 transition-all" />
49
+ <Sun class="h-4 w-4 transition-all" />
51
50
  {/if}
52
51
  </TooltipButton>
53
52
  {/if}
@@ -82,7 +82,7 @@
82
82
  </div>
83
83
  </div>
84
84
  {:else}
85
- <div class="flex h-screen bg-gradient-to-br from-background via-background to-muted/30" in:fade={{ duration: 200, delay: 50 }}>
85
+ <div class="flex h-screen bg-slate-50 dark:bg-slate-950" in:fade={{ duration: 200, delay: 50 }}>
86
86
  <!-- Desktop sidebar -->
87
87
  <div class="hidden md:block">
88
88
  <Sidebar {collapsed} {identity} {title} onToggle={() => collapsed = !collapsed} onLogout={handleLogout} />
@@ -61,14 +61,14 @@
61
61
  }
62
62
  </script>
63
63
 
64
- <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary/[0.08] via-background to-primary/[0.04] p-4">
65
- <div class="w-full max-w-[420px]">
66
- <Card.Card class="backdrop-blur-xl border-border/50 shadow-[0_8px_32px_hsl(var(--primary)/0.08),0_2px_8px_hsl(0_0%_0%/0.06)]">
64
+ <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-100 via-blue-50/30 to-indigo-50/40 dark:from-slate-950 dark:via-slate-900 dark:to-indigo-950/20 p-4">
65
+ <div class="w-full max-w-[380px]">
66
+ <Card.Card>
67
67
  <Card.CardHeader class="text-center pb-2">
68
- <div class="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mx-auto mb-3">
69
- <LogIn class="h-6 w-6" />
68
+ <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
69
+ <LogIn class="h-5 w-5" />
70
70
  </div>
71
- <Card.CardTitle class="text-2xl font-bold">{t('auth.welcomeBack')}</Card.CardTitle>
71
+ <Card.CardTitle class="text-xl">{t('auth.welcomeBack')}</Card.CardTitle>
72
72
  <p class="text-sm text-muted-foreground">{t('auth.welcomeMessage')}</p>
73
73
  </Card.CardHeader>
74
74
  <Card.CardContent>
@@ -155,8 +155,9 @@
155
155
  </Card.CardContent>
156
156
  </Card.Card>
157
157
 
158
- <p class="text-xs text-muted-foreground mt-4 text-center opacity-60">
158
+ <p class="text-xs text-muted-foreground mt-4 text-center">
159
159
  Powered by {title}
160
160
  </p>
161
161
  </div>
162
162
  </div>
163
+
@@ -25,7 +25,7 @@
25
25
  {/if}
26
26
  <div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
27
27
  <div>
28
- <h1 class="text-2xl font-bold tracking-tight text-foreground">{title}</h1>
28
+ <h1 class="text-xl font-semibold tracking-tight text-foreground">{title}</h1>
29
29
  {#if description}
30
30
  <p class="text-sm text-muted-foreground">{description}</p>
31
31
  {/if}
@@ -72,10 +72,10 @@
72
72
  <img
73
73
  src={identity.data.avatar}
74
74
  alt={identity.data.name ?? ''}
75
- class="h-20 w-20 rounded-xl object-cover ring-2 ring-primary/20"
75
+ class="h-20 w-20 rounded-lg object-cover ring-2 ring-primary/20"
76
76
  />
77
77
  {:else}
78
- <div class="h-20 w-20 rounded-xl bg-primary/10 text-primary flex items-center justify-center text-2xl font-bold">
78
+ <div class="h-20 w-20 rounded-lg bg-primary/10 text-primary flex items-center justify-center text-2xl font-bold">
79
79
  {initials}
80
80
  </div>
81
81
  {/if}
@@ -39,14 +39,14 @@
39
39
  }
40
40
  </script>
41
41
 
42
- <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary/[0.08] via-background to-primary/[0.04] p-4">
43
- <div class="w-full max-w-[420px]">
44
- <Card.Card class="backdrop-blur-xl border-border/50 shadow-[0_8px_32px_hsl(var(--primary)/0.08),0_2px_8px_hsl(0_0%_0%/0.06)]">
42
+ <div class="min-h-screen flex items-center justify-center bg-background p-4">
43
+ <div class="w-full max-w-[380px]">
44
+ <Card.Card>
45
45
  <Card.CardHeader class="text-center pb-2">
46
- <div class="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mx-auto mb-3">
47
- <UserPlus class="h-6 w-6" />
46
+ <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
47
+ <UserPlus class="h-5 w-5" />
48
48
  </div>
49
- <Card.CardTitle class="text-2xl font-bold">{t('auth.createAccount')}</Card.CardTitle>
49
+ <Card.CardTitle class="text-xl">{t('auth.createAccount')}</Card.CardTitle>
50
50
  <p class="text-sm text-muted-foreground">{t('auth.createAccountMessage')}</p>
51
51
  </Card.CardHeader>
52
52
  <Card.CardContent>
@@ -1,20 +1,19 @@
1
1
  <script lang="ts">
2
2
  import { getResources } from '@svadmin/core';
3
3
  import type { Identity } from '@svadmin/core';
4
- import { currentPath, navigate } from '@svadmin/core/router';
4
+ import { currentPath } from '@svadmin/core/router';
5
5
  import { t, getLocale, setLocale, getAvailableLocales } from '@svadmin/core/i18n';
6
6
  import { toggleTheme, getResolvedTheme, colorThemes, getColorTheme, setColorTheme, canAccessAsync } from '@svadmin/core';
7
7
  import { Button } from './ui/button/index.js';
8
8
  import TooltipButton from './TooltipButton.svelte';
9
9
  import * as Tooltip from './ui/tooltip/index.js';
10
- import * as DropdownMenu from './ui/dropdown-menu/index.js';
11
- import { Separator } from './ui/separator/index.js';
10
+
12
11
  import { ScrollArea } from './ui/scroll-area/index.js';
13
12
  import * as Collapsible from './ui/collapsible/index.js';
14
13
  import { Avatar } from './ui/avatar/index.js';
15
14
  import {
16
15
  LayoutDashboard, FileText, Users, Settings, Home,
17
- ChevronLeft, ChevronRight, ChevronDown, LogOut, Sun, Moon, Languages, Palette
16
+ ChevronLeft, ChevronDown, LogOut, Sun, Moon, Palette
18
17
  } from 'lucide-svelte';
19
18
 
20
19
  let { collapsed, identity, title, onToggle, onLogout } = $props<{
@@ -118,34 +117,57 @@
118
117
 
119
118
  // Track which groups are open
120
119
  let openGroups = $state<Set<string>>(new Set());
120
+ let colorPickerOpen = $state(false);
121
+ let colorPickerRef = $state<HTMLDivElement | null>(null);
122
+ let colorPickerOpenedAt = 0;
123
+
124
+ // Click-outside to close color picker
125
+ $effect(() => {
126
+ if (!colorPickerOpen) return;
127
+ function handleMouseDown(e: MouseEvent) {
128
+ // Ignore if opened within last 200ms (same interaction)
129
+ if (Date.now() - colorPickerOpenedAt < 200) return;
130
+ if (colorPickerRef && !colorPickerRef.contains(e.target as Node)) {
131
+ colorPickerOpen = false;
132
+ }
133
+ }
134
+ document.addEventListener('mousedown', handleMouseDown, true);
135
+ return () => {
136
+ document.removeEventListener('mousedown', handleMouseDown, true);
137
+ };
138
+ });
121
139
  </script>
122
140
 
123
141
  <svelte:window onhashchange={onHashChange} />
124
142
 
125
143
  <aside
126
144
  aria-label="Sidebar navigation"
127
- class="fixed inset-y-0 left-0 z-30 flex flex-col bg-sidebar/80 backdrop-blur-xl border-r border-sidebar-border/50 shadow-xl transition-all duration-300"
145
+ class="fixed inset-y-0 left-0 z-30 flex flex-col backdrop-blur-xl border-r border-sidebar-border transition-all duration-300"
146
+ style="background-color: var(--sidebar);"
128
147
  class:w-64={!collapsed}
129
148
  class:w-16={collapsed}
130
149
  >
131
150
  <!-- Logo -->
132
151
  <div class="flex h-16 items-center justify-between border-b border-sidebar-border px-4">
133
152
  {#if !collapsed}
134
- <span class="text-lg font-bold text-sidebar-primary">{title}</span>
153
+ <div class="flex items-center gap-3">
154
+ <div class="w-8 h-8 rounded-lg bg-gradient-to-tr from-primary to-purple-500 shrink-0" style="box-shadow: 0 4px 12px oklch(0.488 0.243 264.376 / 20%);"></div>
155
+ <span class="font-semibold text-lg tracking-tight text-sidebar-foreground">{title}</span>
156
+ </div>
135
157
  {:else}
136
- <span class="text-lg font-bold text-sidebar-primary">{title.charAt(0)}</span>
158
+ <div class="w-8 h-8 rounded-lg bg-gradient-to-tr from-primary to-purple-500 shrink-0 mx-auto" style="box-shadow: 0 4px 12px oklch(0.488 0.243 264.376 / 20%);"></div>
137
159
  {/if}
138
- <TooltipButton tooltip={t('common.toggleSidebar')} variant="ghost" size="icon-sm" onclick={onToggle}>
139
- {#if collapsed}
140
- <ChevronRight class="h-4 w-4" />
141
- {:else}
160
+ {#if !collapsed}
161
+ <TooltipButton tooltip={t('common.toggleSidebar')} variant="ghost" size="icon-sm" onclick={onToggle}>
142
162
  <ChevronLeft class="h-4 w-4" />
143
- {/if}
144
- </TooltipButton>
163
+ </TooltipButton>
164
+ {:else}
165
+ <div></div>
166
+ {/if}
145
167
  </div>
146
168
 
147
169
  <ScrollArea class="flex-1">
148
- <nav aria-label="Main menu" class="py-4 px-2 space-y-1">
170
+ <nav aria-label="Main menu" class="py-4 px-3 space-y-4">
149
171
  {#each navGroups as group}
150
172
  {#if group.name && !collapsed}
151
173
  <!-- Grouped section with Collapsible -->
@@ -155,24 +177,24 @@
155
177
  openGroups = next;
156
178
  }}>
157
179
  <Collapsible.Trigger
158
- class="flex w-full items-center justify-between rounded-lg px-3 py-2 text-xs font-semibold uppercase tracking-wider text-sidebar-foreground/60 hover:bg-sidebar-accent/50 transition-colors"
180
+ class="flex w-full items-center justify-between px-3 py-1.5 text-[10px] font-bold uppercase tracking-wider text-sidebar-foreground/40 hover:text-sidebar-foreground/60 transition-colors"
159
181
  >
160
182
  <span>{group.name}</span>
161
183
  <ChevronDown class="h-3 w-3 transition-transform {openGroups.has(group.name) ? 'rotate-180' : ''}" />
162
184
  </Collapsible.Trigger>
163
185
  <Collapsible.Content>
164
- <div class="mt-1 space-y-0.5 pl-1">
186
+ <div class="mt-1 space-y-1">
165
187
  {#each group.items as item}
166
188
  {@const active = isActive(item.path)}
167
189
  <a
168
190
  href={`#${item.path}`}
169
- class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors"
170
- class:bg-sidebar-accent={active}
171
- class:text-sidebar-accent-foreground={active}
172
- class:text-sidebar-foreground={!active}
173
- class:hover:bg-sidebar-accent={!active}
191
+ class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200
192
+ {active
193
+ ? 'bg-sidebar-accent text-sidebar-accent-foreground'
194
+ : 'text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground'}"
195
+ style={active ? 'box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);' : ''}
174
196
  >
175
- <item.Icon class="h-5 w-5 flex-shrink-0" />
197
+ <item.Icon class="h-4 w-4 flex-shrink-0" />
176
198
  <span>{item.label}</span>
177
199
  </a>
178
200
  {/each}
@@ -190,13 +212,12 @@
190
212
  <a
191
213
  {...props}
192
214
  href={`#${item.path}`}
193
- class="flex items-center justify-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors"
194
- class:bg-sidebar-accent={active}
195
- class:text-sidebar-accent-foreground={active}
196
- class:text-sidebar-foreground={!active}
197
- class:hover:bg-sidebar-accent={!active}
215
+ class="flex items-center justify-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200
216
+ {active
217
+ ? 'bg-sidebar-accent text-sidebar-accent-foreground'
218
+ : 'text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground'}"
198
219
  >
199
- <item.Icon class="h-5 w-5 flex-shrink-0" />
220
+ <item.Icon class="h-4 w-4 flex-shrink-0" />
200
221
  </a>
201
222
  {/snippet}
202
223
  </Tooltip.Trigger>
@@ -207,13 +228,13 @@
207
228
  {:else}
208
229
  <a
209
230
  href={`#${item.path}`}
210
- class="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors"
211
- class:bg-sidebar-accent={active}
212
- class:text-sidebar-accent-foreground={active}
213
- class:text-sidebar-foreground={!active}
214
- class:hover:bg-sidebar-accent={!active}
231
+ class="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200
232
+ {active
233
+ ? 'bg-sidebar-accent text-sidebar-accent-foreground'
234
+ : 'text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground'}"
235
+ style={active ? 'box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);' : ''}
215
236
  >
216
- <item.Icon class="h-5 w-5 flex-shrink-0" />
237
+ <item.Icon class="h-4 w-4 flex-shrink-0" />
217
238
  <span>{item.label}</span>
218
239
  </a>
219
240
  {/if}
@@ -224,111 +245,121 @@
224
245
  </ScrollArea>
225
246
 
226
247
  <!-- Footer -->
227
- <Separator class="bg-sidebar-border" />
228
- <div class="p-3 space-y-2">
229
- <!-- Color theme picker via DropdownMenu -->
248
+ <div class="border-t border-sidebar-border">
249
+ <!-- Color theme picker -->
230
250
  {#if !collapsed}
231
- <DropdownMenu.Root>
232
- <DropdownMenu.Trigger>
233
- {#snippet child({ props })}
234
- <Button
235
- {...props}
236
- variant="ghost"
237
- class="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-sidebar-foreground hover:bg-sidebar-accent transition-colors h-auto justify-start"
238
- >
239
- <Palette class="h-4 w-4" />
240
- <span class="flex-1 text-left text-xs">{t('common.toggleTheme')}</span>
241
- <span
242
- class="h-4 w-4 rounded-full ring-1 ring-offset-1 ring-offset-sidebar"
243
- style="background-color: {colorThemes.find(c => c.id === getColorTheme())?.color ?? '#3b82f6'}; --tw-ring-color: {colorThemes.find(c => c.id === getColorTheme())?.color ?? '#3b82f6'}"
244
- ></span>
245
- </Button>
246
- {/snippet}
247
- </DropdownMenu.Trigger>
248
- <DropdownMenu.Content align="end" class="w-40">
249
- {#each colorThemes as ct}
250
- <DropdownMenu.Item onclick={() => setColorTheme(ct.id)} class="gap-2">
251
- <span
252
- class="h-4 w-4 rounded-full {getColorTheme() === ct.id ? 'ring-2 ring-offset-2 scale-110' : 'opacity-70'}"
253
- style="background-color: {ct.color}; {getColorTheme() === ct.id ? `--tw-ring-color: ${ct.color}` : ''}"
254
- ></span>
255
- {ct.label}
256
- </DropdownMenu.Item>
257
- {/each}
258
- </DropdownMenu.Content>
259
- </DropdownMenu.Root>
251
+ <div class="px-3 pt-3 pb-1">
252
+ <div class="relative" bind:this={colorPickerRef}>
253
+ <Button
254
+ variant="ghost"
255
+ class="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground transition-colors h-auto justify-start"
256
+ onclick={() => { if (!colorPickerOpen) colorPickerOpenedAt = Date.now(); colorPickerOpen = !colorPickerOpen; }}
257
+ >
258
+ <Palette class="h-4 w-4" />
259
+ <span class="flex-1 text-left text-xs">{t('common.toggleTheme')}</span>
260
+ <span
261
+ class="h-3.5 w-3.5 rounded-full ring-1 ring-offset-1 ring-offset-sidebar"
262
+ style="background-color: {colorThemes.find(c => c.id === getColorTheme())?.color ?? '#6366f1'}; --tw-ring-color: {colorThemes.find(c => c.id === getColorTheme())?.color ?? '#6366f1'}"
263
+ ></span>
264
+ </Button>
265
+ {#if colorPickerOpen}
266
+ <div class="absolute bottom-full left-0 mb-1 z-50 w-40 rounded-lg border bg-popover p-1 text-popover-foreground shadow-lg animate-in fade-in-0 zoom-in-95">
267
+ {#each colorThemes as ct}
268
+ <button
269
+ class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground transition-colors"
270
+ onclick={() => { setColorTheme(ct.id); colorPickerOpen = false; }}
271
+ >
272
+ <span
273
+ class="h-3.5 w-3.5 rounded-full {getColorTheme() === ct.id ? 'ring-2 ring-offset-1 scale-110' : 'opacity-70'}"
274
+ style="background-color: {ct.color}; {getColorTheme() === ct.id ? `--tw-ring-color: ${ct.color}` : ''}"
275
+ ></span>
276
+ <span class="text-xs">{ct.label}</span>
277
+ </button>
278
+ {/each}
279
+ </div>
280
+ {/if}
281
+ </div>
282
+ </div>
260
283
  {/if}
261
284
 
285
+ <!-- User info -->
262
286
  {#if !collapsed && identity}
263
- <div class="flex items-center gap-3 rounded-lg px-2 py-2">
264
- <Avatar
265
- src={(identity as Record<string, unknown>).avatar as string | undefined}
266
- alt={identity.name ?? 'User'}
267
- fallback={identity.name?.charAt(0).toUpperCase() ?? 'U'}
268
- size="sm"
269
- />
270
- <div class="flex-1 min-w-0">
271
- <p class="truncate text-sm font-medium text-sidebar-foreground">{identity.name}</p>
287
+ <div class="px-3 pb-3 pt-1">
288
+ <div class="flex items-center gap-3 rounded-lg p-2 hover:bg-sidebar-accent/50 transition-colors">
289
+ <Avatar
290
+ src={(identity as Record<string, unknown>).avatar as string | undefined}
291
+ alt={identity.name ?? 'User'}
292
+ fallback={identity.name?.charAt(0).toUpperCase() ?? 'U'}
293
+ size="sm"
294
+ />
295
+ <div class="flex-1 min-w-0">
296
+ <p class="truncate text-sm font-medium text-sidebar-foreground">{identity.name}</p>
297
+ <p class="truncate text-[10px] text-sidebar-foreground/50">Administrator</p>
298
+ </div>
299
+ </div>
300
+ <div class="flex items-center justify-between px-1 mt-1">
301
+ <TooltipButton tooltip={t('common.switchLanguage')} variant="ghost" size="icon-sm" onclick={toggleLocale} class="text-sidebar-foreground/60 hover:text-sidebar-foreground">
302
+ <span class="text-xs font-bold">{localeLabel}</span>
303
+ </TooltipButton>
304
+ <TooltipButton tooltip={t('common.toggleTheme')} variant="ghost" size="icon-sm" onclick={toggleTheme} class="text-sidebar-foreground/60 hover:text-sidebar-foreground">
305
+ {#if getResolvedTheme() === 'dark'}
306
+ <Sun class="h-4 w-4" />
307
+ {:else}
308
+ <Moon class="h-4 w-4" />
309
+ {/if}
310
+ </TooltipButton>
311
+ <TooltipButton tooltip={t('common.logout')} variant="ghost" size="icon-sm" onclick={onLogout} class="text-sidebar-foreground/60 hover:text-destructive">
312
+ <LogOut class="h-4 w-4" />
313
+ </TooltipButton>
272
314
  </div>
273
- <TooltipButton tooltip={t('common.switchLanguage')} variant="ghost" size="icon-sm" onclick={toggleLocale} class="text-sidebar-foreground">
274
- <span class="text-xs font-bold">{localeLabel}</span>
275
- </TooltipButton>
276
- <TooltipButton tooltip={t('common.toggleTheme')} variant="ghost" size="icon-sm" onclick={toggleTheme} class="text-sidebar-foreground">
277
- {#if getResolvedTheme() === 'dark'}
278
- <Sun class="h-4 w-4" />
279
- {:else}
280
- <Moon class="h-4 w-4" />
281
- {/if}
282
- </TooltipButton>
283
- <TooltipButton tooltip={t('common.logout')} variant="ghost" size="icon-sm" onclick={onLogout} class="text-sidebar-foreground hover:text-destructive">
284
- <LogOut class="h-4 w-4" />
285
- </TooltipButton>
286
315
  </div>
287
316
  {:else if collapsed}
288
- <Tooltip.Root>
289
- <Tooltip.Trigger>
290
- {#snippet child({ props })}
291
- <Button {...props} variant="ghost" size="icon" onclick={toggleLocale} class="w-full text-sidebar-foreground">
292
- <span class="text-xs font-bold">{localeLabel}</span>
293
- </Button>
294
- {/snippet}
295
- </Tooltip.Trigger>
296
- <Tooltip.Content side="right">{t('common.switchLanguage')}</Tooltip.Content>
297
- </Tooltip.Root>
298
- <Tooltip.Root>
299
- <Tooltip.Trigger>
300
- {#snippet child({ props })}
301
- <Button {...props} variant="ghost" size="icon" onclick={toggleTheme} class="w-full text-sidebar-foreground">
302
- {#if getResolvedTheme() === 'dark'}
303
- <Sun class="h-5 w-5" />
304
- {:else}
305
- <Moon class="h-5 w-5" />
306
- {/if}
307
- </Button>
308
- {/snippet}
309
- </Tooltip.Trigger>
310
- <Tooltip.Content side="right">{t('common.toggleTheme')}</Tooltip.Content>
311
- </Tooltip.Root>
312
- <Tooltip.Root>
313
- <Tooltip.Trigger>
314
- {#snippet child({ props })}
315
- <Button {...props} variant="ghost" size="icon" onclick={onLogout} class="w-full text-sidebar-foreground hover:text-destructive">
316
- <LogOut class="h-5 w-5" />
317
- </Button>
318
- {/snippet}
319
- </Tooltip.Trigger>
320
- <Tooltip.Content side="right">{t('common.logout')}</Tooltip.Content>
321
- </Tooltip.Root>
317
+ <div class="px-1 py-3 space-y-1">
318
+ <Tooltip.Root>
319
+ <Tooltip.Trigger>
320
+ {#snippet child({ props })}
321
+ <Button {...props} variant="ghost" size="icon" onclick={toggleLocale} class="w-full text-sidebar-foreground/60 hover:text-sidebar-foreground">
322
+ <span class="text-xs font-bold">{localeLabel}</span>
323
+ </Button>
324
+ {/snippet}
325
+ </Tooltip.Trigger>
326
+ <Tooltip.Content side="right">{t('common.switchLanguage')}</Tooltip.Content>
327
+ </Tooltip.Root>
328
+ <Tooltip.Root>
329
+ <Tooltip.Trigger>
330
+ {#snippet child({ props })}
331
+ <Button {...props} variant="ghost" size="icon" onclick={toggleTheme} class="w-full text-sidebar-foreground/60 hover:text-sidebar-foreground">
332
+ {#if getResolvedTheme() === 'dark'}
333
+ <Sun class="h-4 w-4" />
334
+ {:else}
335
+ <Moon class="h-4 w-4" />
336
+ {/if}
337
+ </Button>
338
+ {/snippet}
339
+ </Tooltip.Trigger>
340
+ <Tooltip.Content side="right">{t('common.toggleTheme')}</Tooltip.Content>
341
+ </Tooltip.Root>
342
+ <Tooltip.Root>
343
+ <Tooltip.Trigger>
344
+ {#snippet child({ props })}
345
+ <Button {...props} variant="ghost" size="icon" onclick={onLogout} class="w-full text-sidebar-foreground/60 hover:text-destructive">
346
+ <LogOut class="h-4 w-4" />
347
+ </Button>
348
+ {/snippet}
349
+ </Tooltip.Trigger>
350
+ <Tooltip.Content side="right">{t('common.logout')}</Tooltip.Content>
351
+ </Tooltip.Root>
352
+ </div>
322
353
  {:else}
323
- <div class="flex gap-1">
324
- <TooltipButton tooltip={t('common.switchLanguage')} variant="ghost" size="icon" onclick={toggleLocale} class="flex-1 text-sidebar-foreground">
354
+ <div class="flex gap-1 p-3">
355
+ <TooltipButton tooltip={t('common.switchLanguage')} variant="ghost" size="icon" onclick={toggleLocale} class="flex-1 text-sidebar-foreground/60 hover:text-sidebar-foreground">
325
356
  <span class="text-xs font-bold">{localeLabel}</span>
326
357
  </TooltipButton>
327
- <TooltipButton tooltip={t('common.toggleTheme')} variant="ghost" size="icon" onclick={toggleTheme} class="flex-1 text-sidebar-foreground">
358
+ <TooltipButton tooltip={t('common.toggleTheme')} variant="ghost" size="icon" onclick={toggleTheme} class="flex-1 text-sidebar-foreground/60 hover:text-sidebar-foreground">
328
359
  {#if getResolvedTheme() === 'dark'}
329
- <Sun class="h-5 w-5" />
360
+ <Sun class="h-4 w-4" />
330
361
  {:else}
331
- <Moon class="h-5 w-5" />
362
+ <Moon class="h-4 w-4" />
332
363
  {/if}
333
364
  </TooltipButton>
334
365
  </div>
@@ -45,9 +45,9 @@
45
45
  }: Props = $props();
46
46
  </script>
47
47
 
48
- <div class="flex items-center gap-4 rounded-xl p-5 {variantMap[variant]} {className}">
48
+ <div class="flex items-center gap-4 rounded-lg p-5 {variantMap[variant]} {className}">
49
49
  {#if Icon}
50
- <div class="flex h-12 w-12 items-center justify-center rounded-xl {colorMap[color]}">
50
+ <div class="flex h-12 w-12 items-center justify-center rounded-lg {colorMap[color]}">
51
51
  <Icon class="h-6 w-6" />
52
52
  </div>
53
53
  {/if}
@@ -57,7 +57,7 @@
57
57
  <Skeleton class="mt-1 h-7 w-20" />
58
58
  {:else}
59
59
  <div class="flex items-baseline gap-2">
60
- <p class="text-2xl font-bold text-foreground">{value}</p>
60
+ <p class="text-xl font-semibold text-foreground">{value}</p>
61
61
  {#if trend}
62
62
  <span
63
63
  class="text-xs font-medium {trend.value >= 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-red-600 dark:text-red-400'}"
@@ -49,7 +49,7 @@
49
49
 
50
50
  {#if !dismissed}
51
51
  <div
52
- class="fixed bottom-6 left-1/2 -translate-x-1/2 z-[100] min-w-80 max-w-lg rounded-xl border bg-card shadow-2xl overflow-hidden"
52
+ class="fixed bottom-6 left-1/2 -translate-x-1/2 z-[100] min-w-80 max-w-lg rounded-lg border bg-card shadow-lg overflow-hidden"
53
53
  transition:slide={{ duration: 250 }}
54
54
  >
55
55
  <div class="flex items-center justify-between px-4 py-3 gap-3">
@@ -32,14 +32,14 @@
32
32
  }
33
33
  </script>
34
34
 
35
- <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary/[0.08] via-background to-primary/[0.04] p-4">
36
- <div class="w-full max-w-[420px]">
37
- <Card.Card class="backdrop-blur-xl border-border/50 shadow-[0_8px_32px_hsl(var(--primary)/0.08),0_2px_8px_hsl(0_0%_0%/0.06)]">
35
+ <div class="min-h-screen flex items-center justify-center bg-background p-4">
36
+ <div class="w-full max-w-[380px]">
37
+ <Card.Card>
38
38
  <Card.CardHeader class="text-center pb-2">
39
- <div class="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-primary/10 text-primary mx-auto mb-3">
40
- <ShieldCheck class="h-6 w-6" />
39
+ <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
40
+ <ShieldCheck class="h-5 w-5" />
41
41
  </div>
42
- <Card.CardTitle class="text-2xl font-bold">{t('auth.resetPassword')}</Card.CardTitle>
42
+ <Card.CardTitle class="text-xl">{t('auth.resetPassword')}</Card.CardTitle>
43
43
  <p class="text-sm text-muted-foreground">{t('auth.resetPasswordDescription')}</p>
44
44
  </Card.CardHeader>
45
45
  <Card.CardContent>
@@ -15,7 +15,7 @@
15
15
  bind:this={ref}
16
16
  data-slot="card"
17
17
  data-size={size}
18
- class={cn("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)}
18
+ class={cn("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col", className)}
19
19
  {...restProps}
20
20
  >
21
21
  {@render children?.()}
@@ -28,7 +28,7 @@
28
28
  bind:ref
29
29
  data-slot="dialog-content"
30
30
  class={cn(
31
- "bg-background data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-4 rounded-xl p-6 text-sm ring-1 duration-100 sm:max-w-lg fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none",
31
+ "bg-background data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-4 rounded-lg p-6 text-sm ring-1 duration-100 sm:max-w-lg fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none",
32
32
  className
33
33
  )}
34
34
  {...restProps}