@svadmin/ui 0.34.10 → 0.35.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 (70) hide show
  1. package/dist/app.css +372 -0
  2. package/dist/component-registry.svelte.d.ts +1 -0
  3. package/dist/components/AdminApp.svelte +94 -15
  4. package/dist/components/AdminApp.svelte.d.ts +32 -2
  5. package/dist/components/ApiSettings.svelte +191 -0
  6. package/dist/components/ApiSettings.svelte.d.ts +3 -0
  7. package/dist/components/AutoForm.svelte +48 -43
  8. package/dist/components/AutoTable.svelte +27 -22
  9. package/dist/components/ErrorPage.svelte +58 -0
  10. package/dist/components/ErrorPage.svelte.d.ts +8 -0
  11. package/dist/components/FieldRenderer.svelte +2 -2
  12. package/dist/components/ForgotPasswordPage.svelte +111 -68
  13. package/dist/components/Header.svelte +6 -7
  14. package/dist/components/IntegrationsSettings.svelte +70 -0
  15. package/dist/components/IntegrationsSettings.svelte.d.ts +4 -0
  16. package/dist/components/Layout.svelte +8 -8
  17. package/dist/components/LoginPage.svelte +207 -105
  18. package/dist/components/LoginPage.svelte.d.ts +3 -15
  19. package/dist/components/NotificationsSettings.svelte +115 -0
  20. package/dist/components/NotificationsSettings.svelte.d.ts +3 -0
  21. package/dist/components/PageHeader.svelte +9 -7
  22. package/dist/components/RegisterPage.svelte +103 -65
  23. package/dist/components/ResourceOperationsPage.svelte +153 -0
  24. package/dist/components/ResourceOperationsPage.svelte.d.ts +37 -0
  25. package/dist/components/SecuritySettings.svelte +179 -0
  26. package/dist/components/SecuritySettings.svelte.d.ts +4 -0
  27. package/dist/components/SettingsPage.svelte +121 -54
  28. package/dist/components/SettingsPage.svelte.d.ts +25 -1
  29. package/dist/components/ShowPage.svelte +9 -9
  30. package/dist/components/Sidebar.svelte +96 -48
  31. package/dist/components/SidebarItem.svelte +37 -12
  32. package/dist/components/TwoFactorAuthPage.svelte +247 -0
  33. package/dist/components/TwoFactorAuthPage.svelte.d.ts +3 -0
  34. package/dist/components/UpdatePasswordPage.svelte +86 -48
  35. package/dist/components/account/CompanyProfilePage.svelte +99 -0
  36. package/dist/components/account/CompanyProfilePage.svelte.d.ts +3 -0
  37. package/dist/components/account/GetStartedPage.svelte +123 -0
  38. package/dist/components/account/GetStartedPage.svelte.d.ts +4 -0
  39. package/dist/components/account/ImportMembersPage.svelte +143 -0
  40. package/dist/components/account/ImportMembersPage.svelte.d.ts +3 -0
  41. package/dist/components/account/MembersStarterPage.svelte +104 -0
  42. package/dist/components/account/MembersStarterPage.svelte.d.ts +3 -0
  43. package/dist/components/account/SecurityLogPage.svelte +108 -0
  44. package/dist/components/account/SecurityLogPage.svelte.d.ts +3 -0
  45. package/dist/components/account/SettingsEnterprisePage.svelte +131 -0
  46. package/dist/components/account/SettingsEnterprisePage.svelte.d.ts +3 -0
  47. package/dist/components/account/SettingsPlainPage.svelte +81 -0
  48. package/dist/components/account/SettingsPlainPage.svelte.d.ts +3 -0
  49. package/dist/components/account/SettingsSidebarPage.svelte +98 -0
  50. package/dist/components/account/SettingsSidebarPage.svelte.d.ts +3 -0
  51. package/dist/components/account/TeamMembersPage.svelte +98 -0
  52. package/dist/components/account/TeamMembersPage.svelte.d.ts +3 -0
  53. package/dist/components/network/TeamCrewTablePage.svelte +122 -0
  54. package/dist/components/network/TeamCrewTablePage.svelte.d.ts +3 -0
  55. package/dist/components/network/UserCardsNFTPage.svelte +134 -0
  56. package/dist/components/network/UserCardsNFTPage.svelte.d.ts +3 -0
  57. package/dist/components/profile/ActivityTimeline.svelte +77 -0
  58. package/dist/components/profile/ActivityTimeline.svelte.d.ts +16 -0
  59. package/dist/components/profile/ProfileCard.svelte +216 -0
  60. package/dist/components/profile/ProfileCard.svelte.d.ts +27 -0
  61. package/dist/components/profile/ProjectsGrid.svelte +91 -0
  62. package/dist/components/profile/ProjectsGrid.svelte.d.ts +17 -0
  63. package/dist/components/profile/PublicProfilePage.svelte +179 -0
  64. package/dist/components/profile/PublicProfilePage.svelte.d.ts +10 -0
  65. package/dist/components/profile/TeamsShowcase.svelte +98 -0
  66. package/dist/components/profile/TeamsShowcase.svelte.d.ts +19 -0
  67. package/dist/index.d.ts +23 -0
  68. package/dist/index.js +27 -0
  69. package/dist/router-state.svelte.js +17 -0
  70. package/package.json +2 -2
@@ -5,9 +5,8 @@
5
5
  import { Button } from './ui/button/index.js';
6
6
  import { Input } from './ui/input/index.js';
7
7
  import { Label } from './ui/label/index.js';
8
- import * as Card from './ui/card/index.js';
9
8
  import * as Alert from './ui/alert/index.js';
10
- import { KeyRound, User, ArrowLeft, CheckCircle, Loader2, AlertCircle } from '@lucide/svelte';
9
+ import { User, ArrowLeft, CheckCircle, Loader2, AlertCircle, Shield } from '@lucide/svelte';
11
10
 
12
11
  let { title = 'Admin' } = $props<{
13
12
  title?: string;
@@ -34,79 +33,123 @@
34
33
  }
35
34
  </script>
36
35
 
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
- <Card.CardHeader class="text-center pb-2">
41
- <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
36
+ <div class="min-h-screen flex flex-col lg:flex-row">
37
+ <!-- Left brand panel -->
38
+ <div class="hidden lg:flex lg:w-[480px] xl:w-[520px] relative overflow-hidden bg-gradient-to-br from-primary/90 via-primary to-primary/80 shrink-0">
39
+ <div class="absolute inset-0">
40
+ <div class="absolute top-[12%] left-[8%] w-28 h-28 rounded-3xl border border-white/10 bg-white/5 rotate-12 backdrop-blur-sm"></div>
41
+ <div class="absolute top-[55%] left-[55%] w-40 h-40 rounded-full border border-white/10 bg-white/5 -rotate-6 backdrop-blur-sm"></div>
42
+ <div class="absolute bottom-[15%] left-[15%] w-24 h-24 rounded-2xl border border-white/10 bg-white/5 -rotate-12 backdrop-blur-sm"></div>
43
+ <div class="absolute top-[30%] right-[10%] w-16 h-16 rounded-xl border border-white/10 bg-white/5 rotate-45 backdrop-blur-sm"></div>
44
+ <div class="absolute inset-0 opacity-[0.03]" style="background-image: radial-gradient(circle, white 1px, transparent 1px); background-size: 24px 24px;"></div>
45
+ </div>
46
+
47
+ <div class="relative z-10 flex flex-col justify-between p-10 xl:p-12 w-full">
48
+ <div class="flex items-center gap-3">
49
+ <div class="flex h-9 w-9 items-center justify-center rounded-lg bg-white/15 backdrop-blur-sm">
50
+ <Shield class="h-5 w-5 text-white" />
51
+ </div>
52
+ <span class="text-lg font-semibold text-white tracking-tight">{title}</span>
53
+ </div>
54
+
55
+ <div class="space-y-4">
56
+ <h2 class="text-3xl xl:text-4xl font-bold text-white leading-tight">
57
+ {t('auth.forgotPassword')}
58
+ </h2>
59
+ <p class="text-base text-white/70 leading-relaxed max-w-[320px]">
60
+ {t('auth.forgotPasswordDescription')}
61
+ </p>
62
+ </div>
63
+
64
+ <div class="flex items-center gap-3">
65
+ <div class="h-1 w-8 rounded-full bg-white/30"></div>
66
+ <div class="h-1 w-4 rounded-full bg-white/15"></div>
67
+ <div class="h-1 w-2 rounded-full bg-white/10"></div>
68
+ </div>
69
+ </div>
70
+ </div>
71
+
72
+ <!-- Right form panel -->
73
+ <div class="flex-1 flex items-center justify-center bg-background p-6 sm:p-8 lg:p-12">
74
+ <div class="w-full max-w-[400px]">
75
+ <div class="flex items-center gap-3 mb-8 lg:hidden">
76
+ <div class="flex h-9 w-9 items-center justify-center rounded-lg bg-primary/10 text-primary">
77
+ <Shield class="h-5 w-5" />
78
+ </div>
79
+ <span class="text-lg font-semibold tracking-tight">{title}</span>
80
+ </div>
81
+
82
+ <div class="space-y-1 mb-8">
83
+ <h1 class="text-2xl font-semibold tracking-tight">
42
84
  {#if sent}
43
- <CheckCircle class="h-5 w-5" />
85
+ {t('auth.resetLinkSent')}
44
86
  {:else}
45
- <KeyRound class="h-5 w-5" />
87
+ {t('auth.forgotPassword')}
46
88
  {/if}
47
- </div>
48
- <Card.CardTitle class="text-xl">
49
- {sent ? t('auth.resetLinkSent') : t('auth.forgotPassword')}
50
- </Card.CardTitle>
51
- {#if !sent}
52
- <p class="text-sm text-muted-foreground">{t('auth.forgotPasswordDescription')}</p>
53
- {/if}
54
- </Card.CardHeader>
55
- <Card.CardContent>
56
- {#if sent}
57
- <div class="py-2">
58
- <p class="text-sm text-muted-foreground text-center mb-4">
59
- {t('auth.resetLinkSent')}
60
- </p>
61
- <Button variant="outline" class="w-full" onclick={() => navigate('/login')}>
62
- <ArrowLeft class="h-4 w-4 mr-2" />
63
- {t('auth.backToLogin')}
64
- </Button>
89
+ </h1>
90
+ <p class="text-sm text-muted-foreground">
91
+ {#if sent}
92
+ {t('auth.resetLinkSent')}
93
+ {:else}
94
+ {t('auth.forgotPasswordDescription')}
95
+ {/if}
96
+ </p>
97
+ </div>
98
+
99
+ {#if sent}
100
+ <div class="space-y-4">
101
+ <div class="flex items-center gap-3 rounded-lg border bg-muted/50 p-4">
102
+ <CheckCircle class="h-5 w-5 text-primary shrink-0" />
103
+ <p class="text-sm text-muted-foreground">{t('auth.resetLinkSent')}</p>
65
104
  </div>
66
- {:else}
67
- <form onsubmit={handleSubmit} class="space-y-4">
68
- {#if error}
69
- <Alert.Root variant="destructive">
70
- <AlertCircle class="h-4 w-4" />
71
- <Alert.Description>{error}</Alert.Description>
72
- </Alert.Root>
73
- {/if}
105
+ <Button variant="outline" class="w-full" onclick={() => navigate('/login')}>
106
+ <ArrowLeft class="h-4 w-4 mr-2" />
107
+ {t('auth.backToLogin')}
108
+ </Button>
109
+ </div>
110
+ {:else}
111
+ <form onsubmit={handleSubmit} class="space-y-5">
112
+ {#if error}
113
+ <Alert.Root variant="destructive">
114
+ <AlertCircle class="h-4 w-4" />
115
+ <Alert.Description>{error}</Alert.Description>
116
+ </Alert.Root>
117
+ {/if}
74
118
 
75
- <div class="space-y-2">
76
- <Label for="forgot-identifier">{t('auth.usernameOrEmail')}</Label>
77
- <div class="relative">
78
- <User class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none z-[1]" />
79
- <Input
80
- id="forgot-identifier"
81
- type="text"
82
- placeholder={t('auth.identifierPlaceholder')}
83
- bind:value={identifier}
84
- class="pl-9"
85
- autocomplete="username"
86
- />
87
- </div>
119
+ <div class="space-y-2">
120
+ <Label for="forgot-identifier">{t('auth.usernameOrEmail')}</Label>
121
+ <div class="relative">
122
+ <User class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none z-[1]" />
123
+ <Input
124
+ id="forgot-identifier"
125
+ type="text"
126
+ placeholder={t('auth.identifierPlaceholder')}
127
+ bind:value={identifier}
128
+ class="pl-9"
129
+ autocomplete="username"
130
+ />
88
131
  </div>
89
-
90
- <Button type="submit" class="w-full" disabled={forgot.isLoading}>
91
- {#if forgot.isLoading}
92
- <Loader2 class="h-4 w-4 animate-spin mr-2" />
93
- {/if}
94
- {t('auth.sendResetLink')}
95
- </Button>
96
- </form>
97
-
98
- <div class="flex items-center justify-center mt-5 pt-5 border-t">
99
- <Button variant="link" class="text-sm h-auto p-0 font-medium inline-flex items-center gap-1" onclick={() => navigate('/login')}>
100
- <ArrowLeft class="h-3 w-3" />
101
- {t('auth.backToLogin')}
102
- </Button>
103
132
  </div>
104
- {/if}
105
- </Card.CardContent>
106
- </Card.Card>
107
133
 
108
- <p class="text-xs text-muted-foreground mt-4 text-center opacity-60">
109
- Powered by {title}
110
- </p>
134
+ <Button type="submit" class="w-full h-10" disabled={forgot.isLoading}>
135
+ {#if forgot.isLoading}
136
+ <Loader2 class="h-4 w-4 animate-spin mr-2" />
137
+ {/if}
138
+ {t('auth.sendResetLink')}
139
+ </Button>
140
+ </form>
141
+
142
+ <div class="flex items-center justify-center mt-8 pt-6 border-t">
143
+ <Button variant="link" class="text-sm h-auto p-0 font-medium inline-flex items-center gap-1" onclick={() => navigate('/login')}>
144
+ <ArrowLeft class="h-3 w-3" />
145
+ {t('auth.backToLogin')}
146
+ </Button>
147
+ </div>
148
+ {/if}
149
+
150
+ <p class="text-xs text-muted-foreground/60 mt-8 text-center">
151
+ Powered by {title}
152
+ </p>
153
+ </div>
111
154
  </div>
112
155
  </div>
@@ -35,7 +35,7 @@
35
35
  const CustomNotificationPanel = registry.NotificationPanel;
36
36
  </script>
37
37
 
38
- <header class="sticky top-0 z-30 flex h-14 w-full shrink-0 items-center justify-between bg-card/60 backdrop-blur-md px-4 md:px-6">
38
+ <header class="sticky top-0 z-30 flex h-16 w-full shrink-0 items-center justify-between border-b border-border/70 bg-card/85 px-4 shadow-sm shadow-slate-900/[0.02] backdrop-blur-xl md:px-6">
39
39
  <div class="flex items-center gap-4">
40
40
  {#if children}
41
41
  {@render children()}
@@ -54,7 +54,7 @@
54
54
  {/if}
55
55
 
56
56
  {#if siteUrl}
57
- <TooltipButton tooltip={t('common.goToSite') || 'Site'} href={siteUrl} target="_blank" rel="noopener noreferrer" class="rounded-full flex items-center justify-center">
57
+ <TooltipButton tooltip={t('common.goToSite')} href={siteUrl} target="_blank" rel="noopener noreferrer" class="flex items-center justify-center rounded-xl border border-border/60 bg-background/80">
58
58
  <MonitorUp class="h-4 w-4 text-muted-foreground transition-colors hover:text-foreground" />
59
59
  </TooltipButton>
60
60
  {/if}
@@ -64,10 +64,10 @@
64
64
  {/if}
65
65
 
66
66
  {#if showSearch && onSearchClick}
67
- <Button variant="outline" size="sm" onclick={onSearchClick} class="gap-2 text-muted-foreground h-8 px-3">
67
+ <Button variant="outline" size="sm" onclick={onSearchClick} class="h-10 gap-2 rounded-xl border-border/70 bg-background/85 px-3 text-muted-foreground shadow-sm shadow-slate-900/[0.02] hover:bg-muted/45 sm:min-w-56 sm:justify-start">
68
68
  <Search class="h-3.5 w-3.5" />
69
- <span class="hidden sm:inline text-xs">Search...</span>
70
- <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 font-mono text-muted-foreground">
69
+ <span class="hidden text-xs sm:inline">{t('common.search')}</span>
70
+ <kbd class="ml-auto hidden items-center gap-0.5 rounded-md border bg-muted/60 px-1.5 py-0.5 font-mono text-[10px] font-medium text-muted-foreground sm:inline-flex">
71
71
  <span class="text-xs">⌘</span>K
72
72
  </kbd>
73
73
  </Button>
@@ -77,7 +77,7 @@
77
77
  {#if CustomThemeToggle}
78
78
  <CustomThemeToggle />
79
79
  {:else}
80
- <TooltipButton tooltip={t('common.toggleTheme')} onclick={() => toggleTheme()} class="rounded-full">
80
+ <TooltipButton tooltip={t('common.toggleTheme')} onclick={() => toggleTheme()} class="rounded-xl border border-border/60 bg-background/80">
81
81
  {#if getResolvedTheme() === 'dark'}
82
82
  <Moon class="h-4 w-4 transition-all" />
83
83
  {:else}
@@ -92,4 +92,3 @@
92
92
  {/if}
93
93
  </div>
94
94
  </header>
95
-
@@ -0,0 +1,70 @@
1
+ <script lang="ts">
2
+ import { t } from '@svadmin/core/i18n';
3
+ import { AlertCircle, Cloud, FolderGit, MessageCircle, Plug } from '@lucide/svelte';
4
+ import type { Component } from 'svelte';
5
+ import * as Card from './ui/card/index.js';
6
+ import { Switch } from './ui/switch/index.js';
7
+
8
+ interface Integration {
9
+ id: string;
10
+ name: string;
11
+ description: string;
12
+ connected: boolean;
13
+ Icon: Component;
14
+ tone: string;
15
+ }
16
+
17
+ let integrations = $state<Integration[]>([
18
+ { id: 'source-control', name: 'Source Control', description: 'Sync repository metadata, deployments, and commit activity.', connected: true, Icon: FolderGit, tone: 'bg-zinc-900 text-white' },
19
+ { id: 'chatops', name: 'ChatOps', description: 'Send operational alerts and audit summaries to workspace channels.', connected: false, Icon: MessageCircle, tone: 'bg-violet-700 text-white' },
20
+ { id: 'identity-cloud', name: 'Identity Cloud', description: 'Configure SSO and workspace identity handoff.', connected: true, Icon: Cloud, tone: 'bg-blue-600 text-white' },
21
+ { id: 'webhooks', name: 'Webhooks', description: 'Register outbound webhooks for internal tools and monitors.', connected: false, Icon: Plug, tone: 'bg-emerald-700 text-white' },
22
+ ]);
23
+
24
+ function toggleConnection(id: string, connected: boolean) {
25
+ integrations = integrations.map((item) => (item.id === id ? { ...item, connected } : item));
26
+ }
27
+ </script>
28
+
29
+ <div class="space-y-6">
30
+ <div>
31
+ <h2 class="text-xl font-semibold text-foreground">{t('settings.integrations')}</h2>
32
+ <p class="mt-1 text-sm text-muted-foreground">{t('settings.integrationsDescription')}</p>
33
+ </div>
34
+
35
+ <div class="grid gap-4">
36
+ {#each integrations as integration (integration.id)}
37
+ <Card.Card>
38
+ <Card.CardContent class="p-5">
39
+ <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
40
+ <div class="flex items-start gap-4">
41
+ <div class="shrink-0 rounded-lg p-3 {integration.tone}">
42
+ <integration.Icon class="h-5 w-5" />
43
+ </div>
44
+ <div class="space-y-1">
45
+ <div class="flex flex-wrap items-center gap-2">
46
+ <span class="font-semibold text-foreground">{integration.name}</span>
47
+ <span class="rounded-full px-2 py-0.5 text-[10px] font-semibold {integration.connected ? 'bg-green-500/10 text-green-600' : 'bg-muted text-muted-foreground'}">
48
+ {integration.connected ? t('integrations.statusConnected') : t('integrations.statusDisconnected')}
49
+ </span>
50
+ </div>
51
+ <p class="text-sm text-muted-foreground">{integration.description}</p>
52
+ </div>
53
+ </div>
54
+ <div class="flex items-center gap-3">
55
+ <span class="text-xs text-muted-foreground">{integration.connected ? t('integrations.enabled') : t('integrations.disabled')}</span>
56
+ <Switch checked={integration.connected} onCheckedChange={(checked) => toggleConnection(integration.id, checked)} />
57
+ </div>
58
+ </div>
59
+ </Card.CardContent>
60
+ </Card.Card>
61
+ {/each}
62
+ </div>
63
+
64
+ <Card.Card class="border-dashed bg-muted/20">
65
+ <Card.CardContent class="flex items-center gap-3 p-5 text-sm text-muted-foreground">
66
+ <AlertCircle class="h-4 w-4 shrink-0" />
67
+ <span>{t('integrations.addMoreHint')}</span>
68
+ </Card.CardContent>
69
+ </Card.Card>
70
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { Component } from 'svelte';
2
+ declare const IntegrationsSettings: Component<Record<string, never>, {}, "">;
3
+ type IntegrationsSettings = ReturnType<typeof IntegrationsSettings>;
4
+ export default IntegrationsSettings;
@@ -104,8 +104,8 @@
104
104
  ontouchend={handleTouchEnd}
105
105
  />
106
106
  {#if loading}
107
- <div class="flex h-screen" in:fade={{ duration: 150 }}>
108
- <div class="hidden md:block w-64 bg-sidebar/80 p-4 space-y-4">
107
+ <div class="flex h-screen bg-muted/30" in:fade={{ duration: 150 }}>
108
+ <div class="hidden w-64 space-y-4 border-r border-border/70 bg-card p-4 md:block">
109
109
  <Skeleton class="h-8 w-32" />
110
110
  <div class="space-y-2 mt-6">
111
111
  {#each Array(5) as _, _i (_i)}
@@ -113,7 +113,7 @@
113
113
  {/each}
114
114
  </div>
115
115
  </div>
116
- <div class="flex-1 p-8 space-y-6">
116
+ <div class="flex-1 space-y-6 p-8">
117
117
  <Skeleton class="h-8 w-48" />
118
118
  <div class="space-y-3">
119
119
  {#each Array(4) as _, _i (_i)}
@@ -123,7 +123,7 @@
123
123
  </div>
124
124
  </div>
125
125
  {:else}
126
- <div class="flex h-screen bg-background" in:fade={{ duration: 200, delay: 50 }}>
126
+ <div class="flex h-screen bg-[radial-gradient(circle_at_top_left,hsl(var(--primary)/0.08),transparent_32rem),linear-gradient(180deg,hsl(var(--muted)/0.48),hsl(var(--background))_42rem)]" in:fade={{ duration: 200, delay: 50 }}>
127
127
  <!-- Desktop sidebar -->
128
128
  <div class="hidden md:block">
129
129
  <Sidebar {collapsed} {identity} {title} {menu} {routeMode} onToggle={() => collapsed = !collapsed} onLogout={handleLogout} />
@@ -138,8 +138,8 @@
138
138
 
139
139
  <div
140
140
  class="flex-1 flex flex-col overflow-hidden transition-all duration-300"
141
- class:md:ml-64={!collapsed}
142
- class:md:ml-16={collapsed}
141
+ class:md:ml-72={!collapsed}
142
+ class:md:ml-20={collapsed}
143
143
  >
144
144
  <!-- Header with mobile hamburger -->
145
145
  <Header
@@ -163,9 +163,9 @@
163
163
  </Header>
164
164
 
165
165
  <!-- Content area -->
166
- <main class="flex-1 overflow-y-auto p-6 md:p-8">
166
+ <main class="flex-1 overflow-y-auto px-4 py-5 sm:px-6 md:px-8 md:py-7">
167
167
  {#key getPath()}
168
- <div in:fly={{ x: 20, duration: 150 }} out:fade={{ duration: 80 }}>
168
+ <div class="mx-auto w-full max-w-[1680px]" in:fly={{ x: 20, duration: 150 }} out:fade={{ duration: 80 }}>
169
169
  {@render children()}
170
170
  </div>
171
171
  {/key}