@svadmin/ui 0.34.9 → 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 (123) hide show
  1. package/dist/app.css +372 -0
  2. package/dist/component-registry.svelte.d.ts +1 -0
  3. package/dist/component-registry.svelte.js +1 -0
  4. package/dist/components/AICommandBar.svelte +3 -3
  5. package/dist/components/AboutSettings.svelte +2 -2
  6. package/dist/components/AdminApp.svelte +96 -18
  7. package/dist/components/AdminApp.svelte.d.ts +32 -2
  8. package/dist/components/AnomalyBadge.svelte +1 -1
  9. package/dist/components/ApiSettings.svelte +191 -0
  10. package/dist/components/ApiSettings.svelte.d.ts +3 -0
  11. package/dist/components/AppearanceSettings.svelte +5 -6
  12. package/dist/components/AuditLogDrawer.svelte +1 -1
  13. package/dist/components/AuditLogViewer.svelte +1 -1
  14. package/dist/components/AutoForm.svelte +50 -44
  15. package/dist/components/AutoTable.svelte +44 -39
  16. package/dist/components/Breadcrumbs.svelte +1 -0
  17. package/dist/components/ChatDialog.svelte +5 -4
  18. package/dist/components/ComboboxField.svelte +3 -3
  19. package/dist/components/CommandPalette.svelte +3 -3
  20. package/dist/components/CopilotPanel.svelte +2 -2
  21. package/dist/components/CreatePage.svelte +0 -1
  22. package/dist/components/DevTools.svelte +4 -3
  23. package/dist/components/DraggableHeader.svelte +2 -1
  24. package/dist/components/EditPage.svelte +1 -1
  25. package/dist/components/EmptyState.svelte +1 -1
  26. package/dist/components/ErrorPage.svelte +58 -0
  27. package/dist/components/ErrorPage.svelte.d.ts +8 -0
  28. package/dist/components/FieldRenderer.svelte +9 -8
  29. package/dist/components/ForgotPasswordPage.svelte +111 -68
  30. package/dist/components/Header.svelte +7 -7
  31. package/dist/components/InferencerPanel.svelte +4 -3
  32. package/dist/components/InfiniteList.svelte +3 -4
  33. package/dist/components/IntegrationsSettings.svelte +70 -0
  34. package/dist/components/IntegrationsSettings.svelte.d.ts +4 -0
  35. package/dist/components/KeyboardShortcuts.svelte +3 -3
  36. package/dist/components/Layout.svelte +13 -13
  37. package/dist/components/LoginPage.svelte +207 -105
  38. package/dist/components/LoginPage.svelte.d.ts +3 -15
  39. package/dist/components/MarkdownRenderer.svelte +3 -5
  40. package/dist/components/ModalForm.svelte +1 -3
  41. package/dist/components/NotificationsSettings.svelte +115 -0
  42. package/dist/components/NotificationsSettings.svelte.d.ts +3 -0
  43. package/dist/components/PageHeader.svelte +9 -7
  44. package/dist/components/PageSkeleton.svelte +4 -4
  45. package/dist/components/PasswordInput.svelte +1 -2
  46. package/dist/components/PermissionMatrix.svelte +5 -5
  47. package/dist/components/ProfilePage.svelte +1 -1
  48. package/dist/components/RegisterPage.svelte +103 -65
  49. package/dist/components/ResourceOperationsPage.svelte +153 -0
  50. package/dist/components/ResourceOperationsPage.svelte.d.ts +37 -0
  51. package/dist/components/RolesSettings.svelte +1 -2
  52. package/dist/components/SecuritySettings.svelte +179 -0
  53. package/dist/components/SecuritySettings.svelte.d.ts +4 -0
  54. package/dist/components/SettingsPage.svelte +121 -55
  55. package/dist/components/SettingsPage.svelte.d.ts +25 -1
  56. package/dist/components/ShowPage.svelte +13 -15
  57. package/dist/components/Sidebar.svelte +107 -58
  58. package/dist/components/SidebarItem.svelte +38 -14
  59. package/dist/components/StepsForm.svelte +1 -1
  60. package/dist/components/TaskList.svelte +1 -1
  61. package/dist/components/TaskQueueDrawer.svelte +2 -1
  62. package/dist/components/TenantSwitcher.svelte +1 -2
  63. package/dist/components/Toast.svelte +1 -0
  64. package/dist/components/TooltipButton.svelte +1 -0
  65. package/dist/components/TwoFactorAuthPage.svelte +247 -0
  66. package/dist/components/TwoFactorAuthPage.svelte.d.ts +3 -0
  67. package/dist/components/UpdatePasswordPage.svelte +86 -48
  68. package/dist/components/VirtualTable.svelte +1 -1
  69. package/dist/components/VoiceInput.svelte +1 -0
  70. package/dist/components/account/CompanyProfilePage.svelte +99 -0
  71. package/dist/components/account/CompanyProfilePage.svelte.d.ts +3 -0
  72. package/dist/components/account/GetStartedPage.svelte +123 -0
  73. package/dist/components/account/GetStartedPage.svelte.d.ts +4 -0
  74. package/dist/components/account/ImportMembersPage.svelte +143 -0
  75. package/dist/components/account/ImportMembersPage.svelte.d.ts +3 -0
  76. package/dist/components/account/MembersStarterPage.svelte +104 -0
  77. package/dist/components/account/MembersStarterPage.svelte.d.ts +3 -0
  78. package/dist/components/account/SecurityLogPage.svelte +108 -0
  79. package/dist/components/account/SecurityLogPage.svelte.d.ts +3 -0
  80. package/dist/components/account/SettingsEnterprisePage.svelte +131 -0
  81. package/dist/components/account/SettingsEnterprisePage.svelte.d.ts +3 -0
  82. package/dist/components/account/SettingsPlainPage.svelte +81 -0
  83. package/dist/components/account/SettingsPlainPage.svelte.d.ts +3 -0
  84. package/dist/components/account/SettingsSidebarPage.svelte +98 -0
  85. package/dist/components/account/SettingsSidebarPage.svelte.d.ts +3 -0
  86. package/dist/components/account/TeamMembersPage.svelte +98 -0
  87. package/dist/components/account/TeamMembersPage.svelte.d.ts +3 -0
  88. package/dist/components/buttons/ImportButton.svelte +1 -1
  89. package/dist/components/buttons/ListButton.svelte +1 -1
  90. package/dist/components/charts/BarChart.svelte +1 -1
  91. package/dist/components/charts/LineChart.svelte +3 -3
  92. package/dist/components/charts/PieChart.svelte +2 -2
  93. package/dist/components/fieldComponentMap.js +2 -1
  94. package/dist/components/fields/ArrayField.svelte +1 -1
  95. package/dist/components/fields/MarkdownField.svelte +1 -0
  96. package/dist/components/fields/MultiSelectField.svelte +1 -1
  97. package/dist/components/fields/TagField.svelte +1 -1
  98. package/dist/components/network/TeamCrewTablePage.svelte +122 -0
  99. package/dist/components/network/TeamCrewTablePage.svelte.d.ts +3 -0
  100. package/dist/components/network/UserCardsNFTPage.svelte +134 -0
  101. package/dist/components/network/UserCardsNFTPage.svelte.d.ts +3 -0
  102. package/dist/components/profile/ActivityTimeline.svelte +77 -0
  103. package/dist/components/profile/ActivityTimeline.svelte.d.ts +16 -0
  104. package/dist/components/profile/ProfileCard.svelte +216 -0
  105. package/dist/components/profile/ProfileCard.svelte.d.ts +27 -0
  106. package/dist/components/profile/ProjectsGrid.svelte +91 -0
  107. package/dist/components/profile/ProjectsGrid.svelte.d.ts +17 -0
  108. package/dist/components/profile/PublicProfilePage.svelte +179 -0
  109. package/dist/components/profile/PublicProfilePage.svelte.d.ts +10 -0
  110. package/dist/components/profile/TeamsShowcase.svelte +98 -0
  111. package/dist/components/profile/TeamsShowcase.svelte.d.ts +19 -0
  112. package/dist/components/ui/alert/index.js +1 -0
  113. package/dist/components/ui/badge/index.js +1 -0
  114. package/dist/components/ui/button/button.svelte +1 -0
  115. package/dist/components/ui/button/index.js +1 -0
  116. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +1 -0
  117. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +1 -1
  118. package/dist/components/ui/sheet/sheet.svelte +1 -0
  119. package/dist/components/ui/tabs/tabs.svelte +1 -0
  120. package/dist/index.d.ts +23 -0
  121. package/dist/index.js +27 -0
  122. package/dist/router-state.svelte.js +17 -0
  123. package/package.json +13 -13
@@ -1,67 +1,123 @@
1
1
  <script lang="ts">
2
- import { t } from '@svadmin/core/i18n';
3
- import { navigate } from '@svadmin/core/router';
4
- import { currentPath } from '@svadmin/core/router';
5
- import { User, Palette, Info, Shield, FileSearch } from '@lucide/svelte';
6
- import ProfilePage from './ProfilePage.svelte';
7
- import AppearanceSettings from './AppearanceSettings.svelte';
8
- import AboutSettings from './AboutSettings.svelte';
9
- import RolesSettings from './RolesSettings.svelte';
10
- import AuditLogViewer from './AuditLogViewer.svelte';
11
- import { getAuthProvider } from '@svadmin/core';
2
+ import type { Component, Snippet } from "svelte";
3
+ import { t } from "@svadmin/core/i18n";
4
+ import { navigate } from "@svadmin/core/router";
5
+ import { User, Palette, Info, Shield, FileSearch, Lock, Puzzle, Bell, Key } from "@lucide/svelte";
6
+ import ProfilePage from "./ProfilePage.svelte";
7
+ import AppearanceSettings from "./AppearanceSettings.svelte";
8
+ import AboutSettings from "./AboutSettings.svelte";
9
+ import RolesSettings from "./RolesSettings.svelte";
10
+ import AuditLogViewer from "./AuditLogViewer.svelte";
11
+ import SecuritySettings from "./SecuritySettings.svelte";
12
+ import IntegrationsSettings from "./IntegrationsSettings.svelte";
13
+ import NotificationsSettings from "./NotificationsSettings.svelte";
14
+ import ApiSettings from "./ApiSettings.svelte";
15
+ import { getAuthProvider } from "@svadmin/core";
12
16
 
13
17
  const authProvider = getAuthProvider({ optional: true });
14
18
 
15
- const sections = [
19
+ interface SettingsItem {
20
+ key: string;
21
+ path: string;
22
+ icon: Component;
23
+ label: string;
24
+ }
25
+
26
+ interface SettingsSection {
27
+ group: string;
28
+ items: SettingsItem[];
29
+ }
30
+
31
+ interface Props {
32
+ customSections?: SettingsSection[];
33
+ profile?: Snippet;
34
+ appearance?: Snippet;
35
+ roles?: Snippet;
36
+ security?: Snippet;
37
+ integrations?: Snippet;
38
+ notifications?: Snippet;
39
+ api?: Snippet;
40
+ audit?: Snippet;
41
+ about?: Snippet;
42
+ content?: Snippet<[string]>;
43
+ }
44
+
45
+ let {
46
+ customSections,
47
+ profile,
48
+ appearance,
49
+ roles,
50
+ security,
51
+ integrations,
52
+ notifications,
53
+ api,
54
+ audit,
55
+ about,
56
+ content,
57
+ }: Props = $props();
58
+
59
+ const defaultSections = [
16
60
  {
17
- group: 'settings.general',
61
+ group: "settings.general",
18
62
  items: [
19
- { key: 'profile', path: '/settings/profile', icon: User, label: 'settings.profile' },
20
- { key: 'appearance', path: '/settings/appearance', icon: Palette, label: 'settings.appearance' },
63
+ { key: "profile", path: "/settings/profile", icon: User, label: "settings.profile" },
64
+ { key: "appearance", path: "/settings/appearance", icon: Palette, label: "settings.appearance" },
65
+ { key: "notifications", path: "/settings/notifications", icon: Bell, label: "settings.notifications" },
21
66
  ],
22
67
  },
23
68
  {
24
- group: 'settings.system',
69
+ group: "settings.workspace",
25
70
  items: [
71
+ { key: "security", path: "/settings/security", icon: Lock, label: "settings.security" },
26
72
  ...(authProvider ? [
27
- { key: 'roles', path: '/settings/roles', icon: Shield, label: 'settings.rolesAndPermissions' },
28
- { key: 'audit', path: '/settings/audit', icon: FileSearch, label: 'settings.auditLogs' },
73
+ { key: "roles", path: "/settings/roles", icon: Shield, label: "settings.rolesAndPermissions" },
29
74
  ] : []),
30
- { key: 'about', path: '/settings/about', icon: Info, label: 'settings.about' },
75
+ { key: "integrations", path: "/settings/integrations", icon: Puzzle, label: "settings.integrations" },
76
+ ],
77
+ },
78
+ {
79
+ group: "settings.developer",
80
+ items: [
81
+ { key: "api", path: "/settings/api", icon: Key, label: "settings.api" },
82
+ ...(authProvider ? [
83
+ { key: "audit", path: "/settings/audit", icon: FileSearch, label: "settings.auditLogs" },
84
+ ] : []),
85
+ { key: "about", path: "/settings/about", icon: Info, label: "settings.about" },
31
86
  ],
32
87
  },
33
88
  ];
34
89
 
35
- import { getParams, getRoute } from '../router-state.svelte.js';
90
+ const resolvedSections = $derived(customSections ?? defaultSections);
91
+ const sectionKeys = $derived(new Set(resolvedSections.flatMap((section) => section.items.map((item) => item.key))));
92
+
93
+ import { getParams, getRoute } from "../router-state.svelte.js";
36
94
 
37
95
  let activeKey = $derived.by(() => {
38
96
  const tab = getParams().tab;
39
- if (tab === 'appearance') return 'appearance';
40
- if (tab === 'roles') return 'roles';
41
- if (tab === 'audit') return 'audit';
42
- if (tab === 'about') return 'about';
43
- return 'profile';
97
+ if (!tab) return "profile";
98
+ if (sectionKeys.has(tab)) return tab;
99
+ return content ? tab : "profile";
44
100
  });
45
101
 
46
102
  // Default redirect to profile
47
103
  $effect(() => {
48
- if (getRoute() === '/settings') {
49
- navigate('/settings/profile');
104
+ if (getRoute() === "/settings") {
105
+ navigate("/settings/profile");
50
106
  }
51
107
  });
52
108
  </script>
53
109
 
54
- <div class="flex flex-col lg:flex-row gap-0 min-h-full">
110
+ <div class="flex min-h-full flex-col overflow-hidden rounded-3xl border border-border/70 bg-card/95 shadow-sm shadow-slate-900/[0.03] backdrop-blur lg:flex-row">
55
111
  <!-- Left sidebar navigation -->
56
- <nav class="w-full lg:w-56 shrink-0 bg-muted/10 shadow-[inset_0_-1px_0_rgba(0,0,0,0.05)] lg:shadow-[inset_-1px_0_0_rgba(0,0,0,0.05)] dark:shadow-[inset_-1px_0_0_rgba(255,255,255,0.05)]">
112
+ <nav class="w-full shrink-0 border-b border-border/70 bg-muted/20 lg:w-64 lg:border-b-0 lg:border-r">
57
113
  <!-- Mobile: horizontal scroll tabs -->
58
- <div class="flex lg:hidden overflow-x-auto px-4 py-2 gap-1">
59
- {#each sections as section}
60
- {#each section.items as item}
114
+ <div class="flex gap-2 overflow-x-auto px-4 py-3 lg:hidden">
115
+ {#each resolvedSections as section, _i (_i)}
116
+ {#each section.items as item, _j (_j)}
61
117
  {@const active = activeKey === item.key}
62
118
  <button
63
- class="flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md whitespace-nowrap transition-colors
64
- {active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground hover:bg-background/50'}"
119
+ class="flex items-center gap-2 whitespace-nowrap rounded-xl px-3 py-2 text-sm font-medium transition-colors
120
+ {active ? 'bg-primary/10 text-primary ring-1 ring-primary/15' : 'text-muted-foreground hover:bg-background/70 hover:text-foreground'}"
65
121
  onclick={() => navigate(item.path)}
66
122
  >
67
123
  <item.icon class="h-4 w-4" />
@@ -72,24 +128,24 @@
72
128
  </div>
73
129
 
74
130
  <!-- Desktop: vertical nav with groups -->
75
- <div class="hidden lg:block py-6 px-3 space-y-6">
76
- <div class="px-3">
77
- <h2 class="text-lg font-semibold text-foreground">{t('settings.title')}</h2>
78
- <p class="text-xs text-muted-foreground mt-1">{t('settings.settingsDescription')}</p>
131
+ <div class="hidden space-y-6 px-4 py-6 lg:block">
132
+ <div class="rounded-2xl border border-border/60 bg-background/70 p-4">
133
+ <h2 class="text-lg font-semibold tracking-tight text-foreground">{t("settings.title")}</h2>
134
+ <p class="text-xs text-muted-foreground mt-1">{t("settings.settingsDescription")}</p>
79
135
  </div>
80
- {#each sections as section}
136
+ {#each resolvedSections as section, _i (_i)}
81
137
  <div>
82
- <h3 class="px-3 mb-1 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">
138
+ <h3 class="mb-2 px-3 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/60">
83
139
  {t(section.group)}
84
140
  </h3>
85
- <div class="space-y-0.5">
86
- {#each section.items as item}
141
+ <div class="space-y-1">
142
+ {#each section.items as item, _j (_j)}
87
143
  {@const active = activeKey === item.key}
88
144
  <button
89
- class="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm transition-all
145
+ class="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-sm transition-all
90
146
  {active
91
- ? 'bg-primary/10 text-primary font-medium'
92
- : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'}"
147
+ ? 'bg-primary/10 text-primary font-medium ring-1 ring-primary/15 shadow-sm shadow-primary/10'
148
+ : 'text-muted-foreground hover:bg-background/75 hover:text-foreground'}"
93
149
  onclick={() => navigate(item.path)}
94
150
  >
95
151
  <item.icon class="h-4 w-4 shrink-0" />
@@ -103,17 +159,27 @@
103
159
  </nav>
104
160
 
105
161
  <!-- Right content area -->
106
- <div class="flex-1 p-6 lg:p-8 {activeKey === 'roles' || activeKey === 'audit' ? 'max-w-6xl' : 'max-w-3xl'}">
107
- {#if activeKey === 'profile'}
108
- <ProfilePage />
109
- {:else if activeKey === 'appearance'}
110
- <AppearanceSettings />
111
- {:else if activeKey === 'roles'}
112
- <RolesSettings />
113
- {:else if activeKey === 'audit'}
114
- <AuditLogViewer />
115
- {:else if activeKey === 'about'}
116
- <AboutSettings />
162
+ <div class="flex-1 bg-background/60 p-5 sm:p-6 lg:p-8 {activeKey === 'roles' || activeKey === 'audit' || activeKey === 'integrations' || activeKey === 'api' ? 'max-w-6xl' : 'max-w-3xl'}">
163
+ {#if activeKey === "profile"}
164
+ {#if profile}{@render profile()}{:else}<ProfilePage />{/if}
165
+ {:else if activeKey === "appearance"}
166
+ {#if appearance}{@render appearance()}{:else}<AppearanceSettings />{/if}
167
+ {:else if activeKey === "roles"}
168
+ {#if roles}{@render roles()}{:else}<RolesSettings />{/if}
169
+ {:else if activeKey === "security"}
170
+ {#if security}{@render security()}{:else}<SecuritySettings />{/if}
171
+ {:else if activeKey === "integrations"}
172
+ {#if integrations}{@render integrations()}{:else}<IntegrationsSettings />{/if}
173
+ {:else if activeKey === "notifications"}
174
+ {#if notifications}{@render notifications()}{:else}<NotificationsSettings />{/if}
175
+ {:else if activeKey === "api"}
176
+ {#if api}{@render api()}{:else}<ApiSettings />{/if}
177
+ {:else if activeKey === "audit"}
178
+ {#if audit}{@render audit()}{:else}<AuditLogViewer />{/if}
179
+ {:else if activeKey === "about"}
180
+ {#if about}{@render about()}{:else}<AboutSettings />{/if}
181
+ {:else if content}
182
+ {@render content(activeKey)}
117
183
  {/if}
118
184
  </div>
119
185
  </div>
@@ -1,3 +1,27 @@
1
- declare const SettingsPage: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import type { Component, Snippet } from "svelte";
2
+ interface SettingsItem {
3
+ key: string;
4
+ path: string;
5
+ icon: Component;
6
+ label: string;
7
+ }
8
+ interface SettingsSection {
9
+ group: string;
10
+ items: SettingsItem[];
11
+ }
12
+ interface Props {
13
+ customSections?: SettingsSection[];
14
+ profile?: Snippet;
15
+ appearance?: Snippet;
16
+ roles?: Snippet;
17
+ security?: Snippet;
18
+ integrations?: Snippet;
19
+ notifications?: Snippet;
20
+ api?: Snippet;
21
+ audit?: Snippet;
22
+ about?: Snippet;
23
+ content?: Snippet<[string]>;
24
+ }
25
+ declare const SettingsPage: Component<Props, {}, "">;
2
26
  type SettingsPage = ReturnType<typeof SettingsPage>;
3
27
  export default SettingsPage;
@@ -1,9 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { useShow, getResource } from '@svadmin/core';
3
- import type { FieldDefinition } from '@svadmin/core';
4
3
  import { navigate } from '@svadmin/core/router';
5
- import { t, getLocale } from '@svadmin/core/i18n';
6
- import { Button } from './ui/button/index.js';
4
+ import { t } from '@svadmin/core/i18n';
7
5
  import * as Card from './ui/card/index.js';
8
6
  import { Skeleton } from './ui/skeleton/index.js';
9
7
  import PageHeader from './PageHeader.svelte';
@@ -40,10 +38,10 @@
40
38
  </PageHeader>
41
39
 
42
40
  {#if query.isLoading}
43
- <Card.Root class="overflow-hidden border-border/40 shadow-sm">
44
- <Card.Content class="p-0">
45
- {#each showFields.slice(0, 6) as _, i}
46
- <div class="flex flex-col sm:flex-row px-4 sm:px-6 py-3 sm:py-4 {i % 2 === 1 ? 'bg-muted/20' : ''}">
41
+ <Card.Root class="overflow-hidden rounded-3xl border-border/70 bg-card/95 shadow-sm shadow-slate-900/[0.03]">
42
+ <Card.Content class="space-y-3 p-4 sm:p-5">
43
+ {#each showFields.slice(0, 6) as _, i (i)}
44
+ <div class="flex flex-col rounded-2xl border border-border/50 bg-muted/20 px-4 py-3 sm:flex-row sm:py-4">
47
45
  <Skeleton class="h-4 w-1/2 sm:w-1/4" />
48
46
  <Skeleton class="h-4 w-3/4 sm:w-2/5 mt-1 sm:mt-0 sm:ml-auto" />
49
47
  </div>
@@ -51,14 +49,14 @@
51
49
  </Card.Content>
52
50
  </Card.Root>
53
51
  {:else if query.data?.data}
54
- <Card.Root class="overflow-hidden border-border/40 shadow-sm">
55
- <Card.Content class="p-0">
56
- {#each showFields as field, i}
57
- {@const value = (query.data!.data as Record<string, unknown>)[field.key]}
52
+ <Card.Root class="overflow-hidden rounded-3xl border-border/70 bg-card/95 shadow-sm shadow-slate-900/[0.03]">
53
+ <Card.Content class="space-y-3 p-4 sm:p-5">
54
+ {#each showFields as field, i (i)}
55
+ {@const value = ((query.data as { data: Record<string, unknown> }).data as Record<string, unknown>)[field.key]}
58
56
  {@const DisplayComponent = getDisplayComponent(field.type)}
59
- <div class="flex flex-col sm:flex-row px-4 sm:px-6 py-3 sm:py-4 {i % 2 === 1 ? 'bg-muted/20' : ''}">
60
- <div class="sm:w-1/3 text-xs sm:text-sm font-medium text-muted-foreground mb-1 sm:mb-0">{field.label}</div>
61
- <div class="sm:w-2/3 text-sm text-foreground">
57
+ <div class="flex flex-col rounded-2xl border border-border/55 bg-background/70 px-4 py-3 transition-colors hover:bg-muted/20 sm:flex-row sm:items-start sm:py-4 {i % 2 === 1 ? 'bg-muted/15' : ''}">
58
+ <div class="mb-1 text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground sm:mb-0 sm:w-1/3">{field.label}</div>
59
+ <div class="text-sm text-foreground sm:w-2/3">
62
60
  {#if DisplayComponent && value != null}
63
61
  <DisplayComponent
64
62
  {value}
@@ -74,7 +72,7 @@
74
72
  </Card.Content>
75
73
  </Card.Root>
76
74
  {:else}
77
- <Card.Root class="overflow-hidden border-border/40 shadow-sm">
75
+ <Card.Root class="overflow-hidden rounded-3xl border-border/70 bg-card/95 shadow-sm shadow-slate-900/[0.03]">
78
76
  <Card.Content class="p-8 text-center">
79
77
  <p class="text-muted-foreground">{t('common.noData')}</p>
80
78
  {#if query.isError}