@authrim/sveltekit 0.1.0 → 0.1.2

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 (34) hide show
  1. package/LICENSE +191 -191
  2. package/README.md +527 -531
  3. package/dist/components/AuthProvider.svelte +56 -56
  4. package/dist/components/ProtectedRoute.svelte +71 -71
  5. package/dist/components/SignInButton.svelte +93 -93
  6. package/dist/components/SignOutButton.svelte +72 -72
  7. package/dist/components/UserProfile.svelte +71 -71
  8. package/dist/ui/account/LinkAccountButton.svelte +133 -133
  9. package/dist/ui/account/LinkedAccountsList.svelte +233 -233
  10. package/dist/ui/account/UnlinkAccountButton.svelte +179 -179
  11. package/dist/ui/forms/EmailCodeForm.svelte +224 -224
  12. package/dist/ui/forms/PasskeyConditionalInput.svelte +173 -173
  13. package/dist/ui/forms/SocialLoginButtons.svelte +209 -209
  14. package/dist/ui/helpers/AuthError.svelte +124 -124
  15. package/dist/ui/helpers/AuthLoading.svelte +83 -83
  16. package/dist/ui/helpers/OTPInput.svelte +214 -214
  17. package/dist/ui/helpers/ResendCodeButton.svelte +140 -140
  18. package/dist/ui/passkey/PasskeyDeleteButton.svelte +177 -177
  19. package/dist/ui/passkey/PasskeyList.svelte +225 -225
  20. package/dist/ui/passkey/PasskeyRegisterButton.svelte +52 -52
  21. package/dist/ui/session/SessionExpiryIndicator.svelte +109 -109
  22. package/dist/ui/session/SessionList.svelte +231 -231
  23. package/dist/ui/session/SessionRevokeButton.svelte +72 -72
  24. package/dist/ui/shared/Badge.svelte +100 -100
  25. package/dist/ui/shared/Button.svelte +213 -213
  26. package/dist/ui/shared/Card.svelte +85 -85
  27. package/dist/ui/shared/Input.svelte +192 -192
  28. package/dist/ui/shared/Spinner.svelte +75 -75
  29. package/dist/ui/styles/base.css +168 -168
  30. package/dist/ui/styles/theme.css +279 -279
  31. package/dist/ui/templates/AccountSettingsTemplate.svelte +205 -205
  32. package/dist/ui/templates/LoginTemplate.svelte +234 -234
  33. package/dist/ui/templates/SignUpTemplate.svelte +345 -345
  34. package/package.json +112 -111
@@ -1,233 +1,233 @@
1
- <!--
2
- LinkedAccountsList Component
3
- Display and manage linked social accounts
4
- -->
5
- <script lang="ts">
6
- import { createEventDispatcher } from 'svelte';
7
- import type { LinkedAccountDisplay } from '../types.js';
8
- import type { SocialProvider } from '../../types.js';
9
- import Spinner from '../shared/Spinner.svelte';
10
- import UnlinkAccountButton from './UnlinkAccountButton.svelte';
11
-
12
- export let accounts: LinkedAccountDisplay[] = [];
13
- export let loading = false;
14
- export let unlinkingId: string | undefined = undefined;
15
- let className = '';
16
- export { className as class };
17
-
18
- const dispatch = createEventDispatcher<{
19
- unlink: { accountId: string; provider: SocialProvider };
20
- }>();
21
-
22
- const providerNames: Record<SocialProvider, string> = {
23
- google: 'Google',
24
- apple: 'Apple',
25
- microsoft: 'Microsoft',
26
- github: 'GitHub',
27
- facebook: 'Facebook',
28
- };
29
-
30
- function formatDate(date: Date | undefined): string {
31
- if (!date) return '';
32
- return new Intl.DateTimeFormat('en-US', {
33
- month: 'short',
34
- day: 'numeric',
35
- year: 'numeric',
36
- }).format(date);
37
- }
38
- </script>
39
-
40
- <div class="authrim-linked-accounts {className}" {...$$restProps}>
41
- {#if loading && accounts.length === 0}
42
- <div class="authrim-linked-accounts__loading">
43
- <Spinner size="md" />
44
- <span>Loading accounts...</span>
45
- </div>
46
- {:else if accounts.length === 0}
47
- <div class="authrim-linked-accounts__empty">
48
- <div class="authrim-linked-accounts__empty-icon">
49
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
50
- <path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"/>
51
- </svg>
52
- </div>
53
- <p class="authrim-linked-accounts__empty-title">No linked accounts</p>
54
- <p class="authrim-linked-accounts__empty-desc">
55
- Connect social accounts for easier sign-in
56
- </p>
57
- </div>
58
- {:else}
59
- <ul class="authrim-linked-accounts__items">
60
- {#each accounts as account, index (account.accountId)}
61
- <li
62
- class="authrim-linked-accounts__item"
63
- style="animation-delay: {index * 50}ms"
64
- >
65
- <div class="authrim-linked-accounts__icon authrim-linked-accounts__icon--{account.provider}">
66
- {#if account.provider === 'google'}
67
- <svg viewBox="0 0 24 24">
68
- <path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
69
- <path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
70
- <path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
71
- <path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
72
- </svg>
73
- {:else if account.provider === 'github'}
74
- <svg viewBox="0 0 24 24" fill="currentColor">
75
- <path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
76
- </svg>
77
- {:else if account.provider === 'apple'}
78
- <svg viewBox="0 0 24 24" fill="currentColor">
79
- <path d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"/>
80
- </svg>
81
- {:else}
82
- <svg viewBox="0 0 24 24" fill="currentColor">
83
- <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
84
- </svg>
85
- {/if}
86
- </div>
87
-
88
- <div class="authrim-linked-accounts__info">
89
- <span class="authrim-linked-accounts__provider">
90
- {providerNames[account.provider] || account.provider}
91
- </span>
92
- {#if account.email || account.name}
93
- <span class="authrim-linked-accounts__detail">
94
- {account.email || account.name}
95
- </span>
96
- {/if}
97
- {#if account.linkedAt}
98
- <span class="authrim-linked-accounts__date">
99
- Linked {formatDate(account.linkedAt)}
100
- </span>
101
- {/if}
102
- </div>
103
-
104
- <UnlinkAccountButton
105
- accountId={account.accountId}
106
- provider={account.provider}
107
- loading={unlinkingId === account.accountId}
108
- on:confirm={() => dispatch('unlink', { accountId: account.accountId, provider: account.provider })}
109
- />
110
- </li>
111
- {/each}
112
- </ul>
113
- {/if}
114
- </div>
115
-
116
- <style>
117
- .authrim-linked-accounts__loading {
118
- display: flex;
119
- flex-direction: column;
120
- align-items: center;
121
- gap: var(--authrim-space-3);
122
- padding: var(--authrim-space-8);
123
- color: var(--authrim-color-text-secondary);
124
- font-size: var(--authrim-text-sm);
125
- }
126
-
127
- .authrim-linked-accounts__empty {
128
- display: flex;
129
- flex-direction: column;
130
- align-items: center;
131
- padding: var(--authrim-space-8);
132
- text-align: center;
133
- }
134
-
135
- .authrim-linked-accounts__empty-icon {
136
- width: 48px;
137
- height: 48px;
138
- margin-bottom: var(--authrim-space-4);
139
- color: var(--authrim-color-text-muted);
140
- }
141
-
142
- .authrim-linked-accounts__empty-icon svg {
143
- width: 100%;
144
- height: 100%;
145
- }
146
-
147
- .authrim-linked-accounts__empty-title {
148
- margin: 0 0 var(--authrim-space-2);
149
- font-size: var(--authrim-text-base);
150
- font-weight: 600;
151
- color: var(--authrim-color-text);
152
- }
153
-
154
- .authrim-linked-accounts__empty-desc {
155
- margin: 0;
156
- font-size: var(--authrim-text-sm);
157
- color: var(--authrim-color-text-secondary);
158
- }
159
-
160
- .authrim-linked-accounts__items {
161
- list-style: none;
162
- margin: 0;
163
- padding: 0;
164
- }
165
-
166
- .authrim-linked-accounts__item {
167
- display: flex;
168
- align-items: center;
169
- gap: var(--authrim-space-4);
170
- padding: var(--authrim-space-4);
171
- border-bottom: 1px solid var(--authrim-color-border-subtle);
172
- animation: slide-in var(--authrim-duration-normal) var(--authrim-ease-out) both;
173
- }
174
-
175
- @keyframes slide-in {
176
- from {
177
- opacity: 0;
178
- transform: translateX(8px);
179
- }
180
- to {
181
- opacity: 1;
182
- transform: translateX(0);
183
- }
184
- }
185
-
186
- .authrim-linked-accounts__item:last-child {
187
- border-bottom: none;
188
- }
189
-
190
- .authrim-linked-accounts__icon {
191
- flex-shrink: 0;
192
- display: flex;
193
- align-items: center;
194
- justify-content: center;
195
- width: 40px;
196
- height: 40px;
197
- background: var(--authrim-color-bg-subtle);
198
- border-radius: var(--authrim-radius-md);
199
- }
200
-
201
- .authrim-linked-accounts__icon svg {
202
- width: 20px;
203
- height: 20px;
204
- }
205
-
206
- .authrim-linked-accounts__info {
207
- flex: 1;
208
- min-width: 0;
209
- display: flex;
210
- flex-direction: column;
211
- gap: var(--authrim-space-1);
212
- }
213
-
214
- .authrim-linked-accounts__provider {
215
- font-size: var(--authrim-text-sm);
216
- font-weight: 500;
217
- color: var(--authrim-color-text);
218
- letter-spacing: var(--authrim-tracking-tight);
219
- }
220
-
221
- .authrim-linked-accounts__detail {
222
- font-size: var(--authrim-text-xs);
223
- color: var(--authrim-color-text-secondary);
224
- overflow: hidden;
225
- text-overflow: ellipsis;
226
- white-space: nowrap;
227
- }
228
-
229
- .authrim-linked-accounts__date {
230
- font-size: var(--authrim-text-xs);
231
- color: var(--authrim-color-text-muted);
232
- }
233
- </style>
1
+ <!--
2
+ LinkedAccountsList Component
3
+ Display and manage linked social accounts
4
+ -->
5
+ <script lang="ts">
6
+ import { createEventDispatcher } from 'svelte';
7
+ import type { LinkedAccountDisplay } from '../types.js';
8
+ import type { SocialProvider } from '../../types.js';
9
+ import Spinner from '../shared/Spinner.svelte';
10
+ import UnlinkAccountButton from './UnlinkAccountButton.svelte';
11
+
12
+ export let accounts: LinkedAccountDisplay[] = [];
13
+ export let loading = false;
14
+ export let unlinkingId: string | undefined = undefined;
15
+ let className = '';
16
+ export { className as class };
17
+
18
+ const dispatch = createEventDispatcher<{
19
+ unlink: { accountId: string; provider: SocialProvider };
20
+ }>();
21
+
22
+ const providerNames: Record<SocialProvider, string> = {
23
+ google: 'Google',
24
+ apple: 'Apple',
25
+ microsoft: 'Microsoft',
26
+ github: 'GitHub',
27
+ facebook: 'Facebook',
28
+ };
29
+
30
+ function formatDate(date: Date | undefined): string {
31
+ if (!date) return '';
32
+ return new Intl.DateTimeFormat('en-US', {
33
+ month: 'short',
34
+ day: 'numeric',
35
+ year: 'numeric',
36
+ }).format(date);
37
+ }
38
+ </script>
39
+
40
+ <div class="authrim-linked-accounts {className}" {...$$restProps}>
41
+ {#if loading && accounts.length === 0}
42
+ <div class="authrim-linked-accounts__loading">
43
+ <Spinner size="md" />
44
+ <span>Loading accounts...</span>
45
+ </div>
46
+ {:else if accounts.length === 0}
47
+ <div class="authrim-linked-accounts__empty">
48
+ <div class="authrim-linked-accounts__empty-icon">
49
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
50
+ <path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"/>
51
+ </svg>
52
+ </div>
53
+ <p class="authrim-linked-accounts__empty-title">No linked accounts</p>
54
+ <p class="authrim-linked-accounts__empty-desc">
55
+ Connect social accounts for easier sign-in
56
+ </p>
57
+ </div>
58
+ {:else}
59
+ <ul class="authrim-linked-accounts__items">
60
+ {#each accounts as account, index (account.accountId)}
61
+ <li
62
+ class="authrim-linked-accounts__item"
63
+ style="animation-delay: {index * 50}ms"
64
+ >
65
+ <div class="authrim-linked-accounts__icon authrim-linked-accounts__icon--{account.provider}">
66
+ {#if account.provider === 'google'}
67
+ <svg viewBox="0 0 24 24">
68
+ <path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
69
+ <path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
70
+ <path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
71
+ <path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
72
+ </svg>
73
+ {:else if account.provider === 'github'}
74
+ <svg viewBox="0 0 24 24" fill="currentColor">
75
+ <path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
76
+ </svg>
77
+ {:else if account.provider === 'apple'}
78
+ <svg viewBox="0 0 24 24" fill="currentColor">
79
+ <path d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"/>
80
+ </svg>
81
+ {:else}
82
+ <svg viewBox="0 0 24 24" fill="currentColor">
83
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
84
+ </svg>
85
+ {/if}
86
+ </div>
87
+
88
+ <div class="authrim-linked-accounts__info">
89
+ <span class="authrim-linked-accounts__provider">
90
+ {providerNames[account.provider] || account.provider}
91
+ </span>
92
+ {#if account.email || account.name}
93
+ <span class="authrim-linked-accounts__detail">
94
+ {account.email || account.name}
95
+ </span>
96
+ {/if}
97
+ {#if account.linkedAt}
98
+ <span class="authrim-linked-accounts__date">
99
+ Linked {formatDate(account.linkedAt)}
100
+ </span>
101
+ {/if}
102
+ </div>
103
+
104
+ <UnlinkAccountButton
105
+ accountId={account.accountId}
106
+ provider={account.provider}
107
+ loading={unlinkingId === account.accountId}
108
+ on:confirm={() => dispatch('unlink', { accountId: account.accountId, provider: account.provider })}
109
+ />
110
+ </li>
111
+ {/each}
112
+ </ul>
113
+ {/if}
114
+ </div>
115
+
116
+ <style>
117
+ .authrim-linked-accounts__loading {
118
+ display: flex;
119
+ flex-direction: column;
120
+ align-items: center;
121
+ gap: var(--authrim-space-3);
122
+ padding: var(--authrim-space-8);
123
+ color: var(--authrim-color-text-secondary);
124
+ font-size: var(--authrim-text-sm);
125
+ }
126
+
127
+ .authrim-linked-accounts__empty {
128
+ display: flex;
129
+ flex-direction: column;
130
+ align-items: center;
131
+ padding: var(--authrim-space-8);
132
+ text-align: center;
133
+ }
134
+
135
+ .authrim-linked-accounts__empty-icon {
136
+ width: 48px;
137
+ height: 48px;
138
+ margin-bottom: var(--authrim-space-4);
139
+ color: var(--authrim-color-text-muted);
140
+ }
141
+
142
+ .authrim-linked-accounts__empty-icon svg {
143
+ width: 100%;
144
+ height: 100%;
145
+ }
146
+
147
+ .authrim-linked-accounts__empty-title {
148
+ margin: 0 0 var(--authrim-space-2);
149
+ font-size: var(--authrim-text-base);
150
+ font-weight: 600;
151
+ color: var(--authrim-color-text);
152
+ }
153
+
154
+ .authrim-linked-accounts__empty-desc {
155
+ margin: 0;
156
+ font-size: var(--authrim-text-sm);
157
+ color: var(--authrim-color-text-secondary);
158
+ }
159
+
160
+ .authrim-linked-accounts__items {
161
+ list-style: none;
162
+ margin: 0;
163
+ padding: 0;
164
+ }
165
+
166
+ .authrim-linked-accounts__item {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: var(--authrim-space-4);
170
+ padding: var(--authrim-space-4);
171
+ border-bottom: 1px solid var(--authrim-color-border-subtle);
172
+ animation: slide-in var(--authrim-duration-normal) var(--authrim-ease-out) both;
173
+ }
174
+
175
+ @keyframes slide-in {
176
+ from {
177
+ opacity: 0;
178
+ transform: translateX(8px);
179
+ }
180
+ to {
181
+ opacity: 1;
182
+ transform: translateX(0);
183
+ }
184
+ }
185
+
186
+ .authrim-linked-accounts__item:last-child {
187
+ border-bottom: none;
188
+ }
189
+
190
+ .authrim-linked-accounts__icon {
191
+ flex-shrink: 0;
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ width: 40px;
196
+ height: 40px;
197
+ background: var(--authrim-color-bg-subtle);
198
+ border-radius: var(--authrim-radius-md);
199
+ }
200
+
201
+ .authrim-linked-accounts__icon svg {
202
+ width: 20px;
203
+ height: 20px;
204
+ }
205
+
206
+ .authrim-linked-accounts__info {
207
+ flex: 1;
208
+ min-width: 0;
209
+ display: flex;
210
+ flex-direction: column;
211
+ gap: var(--authrim-space-1);
212
+ }
213
+
214
+ .authrim-linked-accounts__provider {
215
+ font-size: var(--authrim-text-sm);
216
+ font-weight: 500;
217
+ color: var(--authrim-color-text);
218
+ letter-spacing: var(--authrim-tracking-tight);
219
+ }
220
+
221
+ .authrim-linked-accounts__detail {
222
+ font-size: var(--authrim-text-xs);
223
+ color: var(--authrim-color-text-secondary);
224
+ overflow: hidden;
225
+ text-overflow: ellipsis;
226
+ white-space: nowrap;
227
+ }
228
+
229
+ .authrim-linked-accounts__date {
230
+ font-size: var(--authrim-text-xs);
231
+ color: var(--authrim-color-text-muted);
232
+ }
233
+ </style>