@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.
- package/LICENSE +191 -191
- package/README.md +527 -531
- package/dist/components/AuthProvider.svelte +56 -56
- package/dist/components/ProtectedRoute.svelte +71 -71
- package/dist/components/SignInButton.svelte +93 -93
- package/dist/components/SignOutButton.svelte +72 -72
- package/dist/components/UserProfile.svelte +71 -71
- package/dist/ui/account/LinkAccountButton.svelte +133 -133
- package/dist/ui/account/LinkedAccountsList.svelte +233 -233
- package/dist/ui/account/UnlinkAccountButton.svelte +179 -179
- package/dist/ui/forms/EmailCodeForm.svelte +224 -224
- package/dist/ui/forms/PasskeyConditionalInput.svelte +173 -173
- package/dist/ui/forms/SocialLoginButtons.svelte +209 -209
- package/dist/ui/helpers/AuthError.svelte +124 -124
- package/dist/ui/helpers/AuthLoading.svelte +83 -83
- package/dist/ui/helpers/OTPInput.svelte +214 -214
- package/dist/ui/helpers/ResendCodeButton.svelte +140 -140
- package/dist/ui/passkey/PasskeyDeleteButton.svelte +177 -177
- package/dist/ui/passkey/PasskeyList.svelte +225 -225
- package/dist/ui/passkey/PasskeyRegisterButton.svelte +52 -52
- package/dist/ui/session/SessionExpiryIndicator.svelte +109 -109
- package/dist/ui/session/SessionList.svelte +231 -231
- package/dist/ui/session/SessionRevokeButton.svelte +72 -72
- package/dist/ui/shared/Badge.svelte +100 -100
- package/dist/ui/shared/Button.svelte +213 -213
- package/dist/ui/shared/Card.svelte +85 -85
- package/dist/ui/shared/Input.svelte +192 -192
- package/dist/ui/shared/Spinner.svelte +75 -75
- package/dist/ui/styles/base.css +168 -168
- package/dist/ui/styles/theme.css +279 -279
- package/dist/ui/templates/AccountSettingsTemplate.svelte +205 -205
- package/dist/ui/templates/LoginTemplate.svelte +234 -234
- package/dist/ui/templates/SignUpTemplate.svelte +345 -345
- package/package.json +112 -111
|
@@ -1,234 +1,234 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
LoginTemplate Component
|
|
3
|
-
|
|
4
|
-
Reference implementation for login screens.
|
|
5
|
-
Copy and customize for production use.
|
|
6
|
-
|
|
7
|
-
@example
|
|
8
|
-
<LoginTemplate
|
|
9
|
-
availableProviders={['google', 'github']}
|
|
10
|
-
enablePasskey={true}
|
|
11
|
-
enableEmailCode={true}
|
|
12
|
-
on:passkey-login={handlePasskeyLogin}
|
|
13
|
-
on:social-login={handleSocialLogin}
|
|
14
|
-
on:email-submit={handleEmailSubmit}
|
|
15
|
-
on:code-submit={handleCodeSubmit}
|
|
16
|
-
/>
|
|
17
|
-
-->
|
|
18
|
-
<script lang="ts">
|
|
19
|
-
import { createEventDispatcher } from 'svelte';
|
|
20
|
-
import type { SocialProvider } from '../../types.js';
|
|
21
|
-
import type { EmailCodeStep } from '../types.js';
|
|
22
|
-
import Card from '../shared/Card.svelte';
|
|
23
|
-
import Button from '../shared/Button.svelte';
|
|
24
|
-
import AuthError from '../helpers/AuthError.svelte';
|
|
25
|
-
import EmailCodeForm from '../forms/EmailCodeForm.svelte';
|
|
26
|
-
import SocialLoginButtons from '../forms/SocialLoginButtons.svelte';
|
|
27
|
-
import PasskeyConditionalInput from '../forms/PasskeyConditionalInput.svelte';
|
|
28
|
-
|
|
29
|
-
export let availableProviders: SocialProvider[] = [];
|
|
30
|
-
export let enablePasskey = true;
|
|
31
|
-
export let enableEmailCode = true;
|
|
32
|
-
export let loading = false;
|
|
33
|
-
export let loadingProvider: SocialProvider | undefined = undefined;
|
|
34
|
-
export let error = '';
|
|
35
|
-
export let title = 'Welcome back';
|
|
36
|
-
export let subtitle = 'Sign in to your account';
|
|
37
|
-
let className = '';
|
|
38
|
-
export { className as class };
|
|
39
|
-
|
|
40
|
-
const dispatch = createEventDispatcher<{
|
|
41
|
-
'passkey-login': void;
|
|
42
|
-
'social-login': { provider: SocialProvider };
|
|
43
|
-
'email-submit': { email: string };
|
|
44
|
-
'code-submit': { code: string };
|
|
45
|
-
'code-resend': void;
|
|
46
|
-
'dismiss-error': void;
|
|
47
|
-
}>();
|
|
48
|
-
|
|
49
|
-
let emailStep: EmailCodeStep = 'email';
|
|
50
|
-
let email = '';
|
|
51
|
-
|
|
52
|
-
function handlePasskeySubmit() {
|
|
53
|
-
dispatch('passkey-login');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function handleSocialClick(e: CustomEvent<{ provider: SocialProvider }>) {
|
|
57
|
-
dispatch('social-login', e.detail);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function handleEmailSubmit(e: CustomEvent<{ email: string }>) {
|
|
61
|
-
email = e.detail.email;
|
|
62
|
-
dispatch('email-submit', e.detail);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function handleCodeSubmit(e: CustomEvent<{ code: string }>) {
|
|
66
|
-
dispatch('code-submit', e.detail);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function handleBack() {
|
|
70
|
-
emailStep = 'email';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function setEmailStep(step: EmailCodeStep) {
|
|
74
|
-
emailStep = step;
|
|
75
|
-
}
|
|
76
|
-
</script>
|
|
77
|
-
|
|
78
|
-
<div class="authrim-login-template {className}">
|
|
79
|
-
<Card padding="lg" shadow="lg" class="authrim-login-template__card">
|
|
80
|
-
<div class="authrim-login-template__header">
|
|
81
|
-
<h1 class="authrim-login-template__title">{title}</h1>
|
|
82
|
-
<p class="authrim-login-template__subtitle">{subtitle}</p>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
85
|
-
{#if error}
|
|
86
|
-
<AuthError message={error} on:dismiss={() => dispatch('dismiss-error')} />
|
|
87
|
-
{/if}
|
|
88
|
-
|
|
89
|
-
<div class="authrim-login-template__content">
|
|
90
|
-
{#if enablePasskey && emailStep === 'email'}
|
|
91
|
-
<div class="authrim-login-template__passkey">
|
|
92
|
-
<PasskeyConditionalInput
|
|
93
|
-
placeholder="Email or username"
|
|
94
|
-
disabled={loading}
|
|
95
|
-
/>
|
|
96
|
-
<Button
|
|
97
|
-
fullWidth
|
|
98
|
-
size="lg"
|
|
99
|
-
{loading}
|
|
100
|
-
on:click={handlePasskeySubmit}
|
|
101
|
-
>
|
|
102
|
-
Continue with Passkey
|
|
103
|
-
</Button>
|
|
104
|
-
</div>
|
|
105
|
-
{/if}
|
|
106
|
-
|
|
107
|
-
{#if enableEmailCode}
|
|
108
|
-
{#if enablePasskey && emailStep === 'email'}
|
|
109
|
-
<div class="authrim-login-template__divider">
|
|
110
|
-
<span>or continue with email</span>
|
|
111
|
-
</div>
|
|
112
|
-
{/if}
|
|
113
|
-
|
|
114
|
-
<EmailCodeForm
|
|
115
|
-
step={emailStep}
|
|
116
|
-
{email}
|
|
117
|
-
{loading}
|
|
118
|
-
on:submit-email={handleEmailSubmit}
|
|
119
|
-
on:submit-code={handleCodeSubmit}
|
|
120
|
-
on:back={handleBack}
|
|
121
|
-
on:resend={() => dispatch('code-resend')}
|
|
122
|
-
/>
|
|
123
|
-
{/if}
|
|
124
|
-
|
|
125
|
-
{#if availableProviders.length > 0 && emailStep === 'email'}
|
|
126
|
-
<div class="authrim-login-template__divider">
|
|
127
|
-
<span>or</span>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<SocialLoginButtons
|
|
131
|
-
providers={availableProviders}
|
|
132
|
-
{loading}
|
|
133
|
-
{loadingProvider}
|
|
134
|
-
on:click={handleSocialClick}
|
|
135
|
-
/>
|
|
136
|
-
{/if}
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<div slot="footer" class="authrim-login-template__footer">
|
|
140
|
-
<slot name="footer">
|
|
141
|
-
<p>
|
|
142
|
-
Don't have an account?
|
|
143
|
-
<a href="/signup" class="authrim-login-template__link">Sign up</a>
|
|
144
|
-
</p>
|
|
145
|
-
</slot>
|
|
146
|
-
</div>
|
|
147
|
-
</Card>
|
|
148
|
-
</div>
|
|
149
|
-
|
|
150
|
-
<style>
|
|
151
|
-
.authrim-login-template {
|
|
152
|
-
display: flex;
|
|
153
|
-
justify-content: center;
|
|
154
|
-
align-items: center;
|
|
155
|
-
min-height: 100vh;
|
|
156
|
-
padding: var(--authrim-space-4);
|
|
157
|
-
background:
|
|
158
|
-
linear-gradient(135deg, var(--authrim-color-bg-subtle) 0%, var(--authrim-color-bg) 100%);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
:global(.authrim-login-template__card) {
|
|
162
|
-
width: 100%;
|
|
163
|
-
max-width: 420px;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.authrim-login-template__header {
|
|
167
|
-
text-align: center;
|
|
168
|
-
margin-bottom: var(--authrim-space-6);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.authrim-login-template__title {
|
|
172
|
-
margin: 0 0 var(--authrim-space-2);
|
|
173
|
-
font-size: var(--authrim-text-2xl);
|
|
174
|
-
font-weight: 700;
|
|
175
|
-
color: var(--authrim-color-text);
|
|
176
|
-
letter-spacing: var(--authrim-tracking-tight);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.authrim-login-template__subtitle {
|
|
180
|
-
margin: 0;
|
|
181
|
-
font-size: var(--authrim-text-sm);
|
|
182
|
-
color: var(--authrim-color-text-secondary);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.authrim-login-template__content {
|
|
186
|
-
display: flex;
|
|
187
|
-
flex-direction: column;
|
|
188
|
-
gap: var(--authrim-space-5);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.authrim-login-template__passkey {
|
|
192
|
-
display: flex;
|
|
193
|
-
flex-direction: column;
|
|
194
|
-
gap: var(--authrim-space-4);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.authrim-login-template__divider {
|
|
198
|
-
display: flex;
|
|
199
|
-
align-items: center;
|
|
200
|
-
gap: var(--authrim-space-3);
|
|
201
|
-
color: var(--authrim-color-text-muted);
|
|
202
|
-
font-size: var(--authrim-text-sm);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.authrim-login-template__divider::before,
|
|
206
|
-
.authrim-login-template__divider::after {
|
|
207
|
-
content: '';
|
|
208
|
-
flex: 1;
|
|
209
|
-
height: 1px;
|
|
210
|
-
background: var(--authrim-color-border);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.authrim-login-template__footer {
|
|
214
|
-
text-align: center;
|
|
215
|
-
font-size: var(--authrim-text-sm);
|
|
216
|
-
color: var(--authrim-color-text-secondary);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.authrim-login-template__footer p {
|
|
220
|
-
margin: 0;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
.authrim-login-template__link {
|
|
224
|
-
color: var(--authrim-color-primary);
|
|
225
|
-
font-weight: 500;
|
|
226
|
-
text-decoration: none;
|
|
227
|
-
transition: color var(--authrim-duration-fast) var(--authrim-ease-default);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.authrim-login-template__link:hover {
|
|
231
|
-
color: var(--authrim-color-primary-hover);
|
|
232
|
-
text-decoration: underline;
|
|
233
|
-
}
|
|
234
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
LoginTemplate Component
|
|
3
|
+
|
|
4
|
+
Reference implementation for login screens.
|
|
5
|
+
Copy and customize for production use.
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
<LoginTemplate
|
|
9
|
+
availableProviders={['google', 'github']}
|
|
10
|
+
enablePasskey={true}
|
|
11
|
+
enableEmailCode={true}
|
|
12
|
+
on:passkey-login={handlePasskeyLogin}
|
|
13
|
+
on:social-login={handleSocialLogin}
|
|
14
|
+
on:email-submit={handleEmailSubmit}
|
|
15
|
+
on:code-submit={handleCodeSubmit}
|
|
16
|
+
/>
|
|
17
|
+
-->
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import { createEventDispatcher } from 'svelte';
|
|
20
|
+
import type { SocialProvider } from '../../types.js';
|
|
21
|
+
import type { EmailCodeStep } from '../types.js';
|
|
22
|
+
import Card from '../shared/Card.svelte';
|
|
23
|
+
import Button from '../shared/Button.svelte';
|
|
24
|
+
import AuthError from '../helpers/AuthError.svelte';
|
|
25
|
+
import EmailCodeForm from '../forms/EmailCodeForm.svelte';
|
|
26
|
+
import SocialLoginButtons from '../forms/SocialLoginButtons.svelte';
|
|
27
|
+
import PasskeyConditionalInput from '../forms/PasskeyConditionalInput.svelte';
|
|
28
|
+
|
|
29
|
+
export let availableProviders: SocialProvider[] = [];
|
|
30
|
+
export let enablePasskey = true;
|
|
31
|
+
export let enableEmailCode = true;
|
|
32
|
+
export let loading = false;
|
|
33
|
+
export let loadingProvider: SocialProvider | undefined = undefined;
|
|
34
|
+
export let error = '';
|
|
35
|
+
export let title = 'Welcome back';
|
|
36
|
+
export let subtitle = 'Sign in to your account';
|
|
37
|
+
let className = '';
|
|
38
|
+
export { className as class };
|
|
39
|
+
|
|
40
|
+
const dispatch = createEventDispatcher<{
|
|
41
|
+
'passkey-login': void;
|
|
42
|
+
'social-login': { provider: SocialProvider };
|
|
43
|
+
'email-submit': { email: string };
|
|
44
|
+
'code-submit': { code: string };
|
|
45
|
+
'code-resend': void;
|
|
46
|
+
'dismiss-error': void;
|
|
47
|
+
}>();
|
|
48
|
+
|
|
49
|
+
let emailStep: EmailCodeStep = 'email';
|
|
50
|
+
let email = '';
|
|
51
|
+
|
|
52
|
+
function handlePasskeySubmit() {
|
|
53
|
+
dispatch('passkey-login');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function handleSocialClick(e: CustomEvent<{ provider: SocialProvider }>) {
|
|
57
|
+
dispatch('social-login', e.detail);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function handleEmailSubmit(e: CustomEvent<{ email: string }>) {
|
|
61
|
+
email = e.detail.email;
|
|
62
|
+
dispatch('email-submit', e.detail);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function handleCodeSubmit(e: CustomEvent<{ code: string }>) {
|
|
66
|
+
dispatch('code-submit', e.detail);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function handleBack() {
|
|
70
|
+
emailStep = 'email';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function setEmailStep(step: EmailCodeStep) {
|
|
74
|
+
emailStep = step;
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<div class="authrim-login-template {className}">
|
|
79
|
+
<Card padding="lg" shadow="lg" class="authrim-login-template__card">
|
|
80
|
+
<div class="authrim-login-template__header">
|
|
81
|
+
<h1 class="authrim-login-template__title">{title}</h1>
|
|
82
|
+
<p class="authrim-login-template__subtitle">{subtitle}</p>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
{#if error}
|
|
86
|
+
<AuthError message={error} on:dismiss={() => dispatch('dismiss-error')} />
|
|
87
|
+
{/if}
|
|
88
|
+
|
|
89
|
+
<div class="authrim-login-template__content">
|
|
90
|
+
{#if enablePasskey && emailStep === 'email'}
|
|
91
|
+
<div class="authrim-login-template__passkey">
|
|
92
|
+
<PasskeyConditionalInput
|
|
93
|
+
placeholder="Email or username"
|
|
94
|
+
disabled={loading}
|
|
95
|
+
/>
|
|
96
|
+
<Button
|
|
97
|
+
fullWidth
|
|
98
|
+
size="lg"
|
|
99
|
+
{loading}
|
|
100
|
+
on:click={handlePasskeySubmit}
|
|
101
|
+
>
|
|
102
|
+
Continue with Passkey
|
|
103
|
+
</Button>
|
|
104
|
+
</div>
|
|
105
|
+
{/if}
|
|
106
|
+
|
|
107
|
+
{#if enableEmailCode}
|
|
108
|
+
{#if enablePasskey && emailStep === 'email'}
|
|
109
|
+
<div class="authrim-login-template__divider">
|
|
110
|
+
<span>or continue with email</span>
|
|
111
|
+
</div>
|
|
112
|
+
{/if}
|
|
113
|
+
|
|
114
|
+
<EmailCodeForm
|
|
115
|
+
step={emailStep}
|
|
116
|
+
{email}
|
|
117
|
+
{loading}
|
|
118
|
+
on:submit-email={handleEmailSubmit}
|
|
119
|
+
on:submit-code={handleCodeSubmit}
|
|
120
|
+
on:back={handleBack}
|
|
121
|
+
on:resend={() => dispatch('code-resend')}
|
|
122
|
+
/>
|
|
123
|
+
{/if}
|
|
124
|
+
|
|
125
|
+
{#if availableProviders.length > 0 && emailStep === 'email'}
|
|
126
|
+
<div class="authrim-login-template__divider">
|
|
127
|
+
<span>or</span>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<SocialLoginButtons
|
|
131
|
+
providers={availableProviders}
|
|
132
|
+
{loading}
|
|
133
|
+
{loadingProvider}
|
|
134
|
+
on:click={handleSocialClick}
|
|
135
|
+
/>
|
|
136
|
+
{/if}
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div slot="footer" class="authrim-login-template__footer">
|
|
140
|
+
<slot name="footer">
|
|
141
|
+
<p>
|
|
142
|
+
Don't have an account?
|
|
143
|
+
<a href="/signup" class="authrim-login-template__link">Sign up</a>
|
|
144
|
+
</p>
|
|
145
|
+
</slot>
|
|
146
|
+
</div>
|
|
147
|
+
</Card>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<style>
|
|
151
|
+
.authrim-login-template {
|
|
152
|
+
display: flex;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
align-items: center;
|
|
155
|
+
min-height: 100vh;
|
|
156
|
+
padding: var(--authrim-space-4);
|
|
157
|
+
background:
|
|
158
|
+
linear-gradient(135deg, var(--authrim-color-bg-subtle) 0%, var(--authrim-color-bg) 100%);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
:global(.authrim-login-template__card) {
|
|
162
|
+
width: 100%;
|
|
163
|
+
max-width: 420px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.authrim-login-template__header {
|
|
167
|
+
text-align: center;
|
|
168
|
+
margin-bottom: var(--authrim-space-6);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.authrim-login-template__title {
|
|
172
|
+
margin: 0 0 var(--authrim-space-2);
|
|
173
|
+
font-size: var(--authrim-text-2xl);
|
|
174
|
+
font-weight: 700;
|
|
175
|
+
color: var(--authrim-color-text);
|
|
176
|
+
letter-spacing: var(--authrim-tracking-tight);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.authrim-login-template__subtitle {
|
|
180
|
+
margin: 0;
|
|
181
|
+
font-size: var(--authrim-text-sm);
|
|
182
|
+
color: var(--authrim-color-text-secondary);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.authrim-login-template__content {
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-direction: column;
|
|
188
|
+
gap: var(--authrim-space-5);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.authrim-login-template__passkey {
|
|
192
|
+
display: flex;
|
|
193
|
+
flex-direction: column;
|
|
194
|
+
gap: var(--authrim-space-4);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.authrim-login-template__divider {
|
|
198
|
+
display: flex;
|
|
199
|
+
align-items: center;
|
|
200
|
+
gap: var(--authrim-space-3);
|
|
201
|
+
color: var(--authrim-color-text-muted);
|
|
202
|
+
font-size: var(--authrim-text-sm);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.authrim-login-template__divider::before,
|
|
206
|
+
.authrim-login-template__divider::after {
|
|
207
|
+
content: '';
|
|
208
|
+
flex: 1;
|
|
209
|
+
height: 1px;
|
|
210
|
+
background: var(--authrim-color-border);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.authrim-login-template__footer {
|
|
214
|
+
text-align: center;
|
|
215
|
+
font-size: var(--authrim-text-sm);
|
|
216
|
+
color: var(--authrim-color-text-secondary);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.authrim-login-template__footer p {
|
|
220
|
+
margin: 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.authrim-login-template__link {
|
|
224
|
+
color: var(--authrim-color-primary);
|
|
225
|
+
font-weight: 500;
|
|
226
|
+
text-decoration: none;
|
|
227
|
+
transition: color var(--authrim-duration-fast) var(--authrim-ease-default);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.authrim-login-template__link:hover {
|
|
231
|
+
color: var(--authrim-color-primary-hover);
|
|
232
|
+
text-decoration: underline;
|
|
233
|
+
}
|
|
234
|
+
</style>
|