+1617
-848
Diff
round #0
+1
-51
frontend/src/routes/ActAs.svelte
+1
-51
frontend/src/routes/ActAs.svelte
···
139
139
{/if}
140
140
141
141
<div class="actions">
142
-
<button class="back-btn" onclick={goBack}>
142
+
<button class="secondary" onclick={goBack}>
143
143
{$_('actAs.backToControllers')}
144
144
</button>
145
145
</div>
···
148
148
{/snippet}
149
149
</AuthenticatedRoute>
150
150
151
-
<style>
152
-
.page {
153
-
max-width: var(--width-md);
154
-
margin: var(--space-9) auto;
155
-
padding: var(--space-7);
156
-
}
157
-
158
-
.loading {
159
-
display: flex;
160
-
align-items: center;
161
-
justify-content: center;
162
-
min-height: 200px;
163
-
color: var(--text-secondary);
164
-
}
165
-
166
-
header {
167
-
margin-bottom: var(--space-6);
168
-
}
169
-
170
-
h1 {
171
-
margin: 0;
172
-
}
173
-
174
-
.message.error {
175
-
padding: var(--space-3);
176
-
background: var(--error-bg);
177
-
border: 1px solid var(--error-border);
178
-
border-radius: var(--radius-md);
179
-
color: var(--error-text);
180
-
margin-bottom: var(--space-4);
181
-
}
182
-
183
-
.actions {
184
-
margin-top: var(--space-4);
185
-
}
186
-
187
-
.back-btn {
188
-
padding: var(--space-3) var(--space-5);
189
-
border: 1px solid var(--border-color);
190
-
border-radius: var(--radius-md);
191
-
background: transparent;
192
-
color: var(--text-primary);
193
-
cursor: pointer;
194
-
}
195
-
196
-
.back-btn:hover {
197
-
background: var(--bg-card);
198
-
border-color: var(--accent);
199
-
}
200
-
</style>
+2
-169
frontend/src/routes/Login.svelte
+2
-169
frontend/src/routes/Login.svelte
···
126
126
{/if}
127
127
128
128
<form onsubmit={(e) => { e.preventDefault(); handleVerification(e); }}>
129
-
<div class="field">
129
+
<div>
130
130
<label for="verification-code">{$_('verification.codeLabel')}</label>
131
131
<input
132
132
id="verification-code"
···
192
192
<p class="or-divider">{$_('login.signInToAnother')}</p>
193
193
{/if}
194
194
195
-
<button type="button" class="oauth-btn" onclick={handleOAuthLogin} disabled={submitting || loading}>
195
+
<button type="button" class="lg" style="width: 100%" onclick={handleOAuthLogin} disabled={submitting || loading}>
196
196
{submitting ? $_('login.redirecting') : $_('login.button')}
197
197
</button>
198
198
···
209
209
{/if}
210
210
</div>
211
211
212
-
<style>
213
-
.login-page {
214
-
max-width: var(--width-lg);
215
-
margin: var(--space-9) auto;
216
-
padding: var(--space-7);
217
-
}
218
-
219
-
.page-header {
220
-
margin-bottom: var(--space-6);
221
-
text-align: center;
222
-
}
223
-
224
-
h1 {
225
-
margin: 0 0 var(--space-3) 0;
226
-
}
227
-
228
-
.subtitle {
229
-
color: var(--text-secondary);
230
-
margin: 0;
231
-
}
232
-
233
-
.login-content {
234
-
max-width: var(--width-md);
235
-
margin: 0 auto;
236
-
}
237
-
238
-
form {
239
-
display: flex;
240
-
flex-direction: column;
241
-
gap: var(--space-4);
242
-
max-width: var(--width-sm);
243
-
margin: 0 auto;
244
-
}
245
-
246
-
.actions {
247
-
display: flex;
248
-
flex-direction: column;
249
-
gap: var(--space-3);
250
-
margin-top: var(--space-3);
251
-
}
252
-
253
-
@media (min-width: 600px) {
254
-
.actions {
255
-
flex-direction: row;
256
-
}
257
-
258
-
.actions button {
259
-
flex: 1;
260
-
}
261
-
}
262
-
263
-
.oauth-btn {
264
-
width: 100%;
265
-
padding: var(--space-5);
266
-
font-size: var(--text-lg);
267
-
}
268
-
269
-
.forgot-links {
270
-
margin-top: var(--space-4);
271
-
font-size: var(--text-sm);
272
-
color: var(--text-secondary);
273
-
text-align: center;
274
-
}
275
-
276
-
.forgot-links a {
277
-
color: var(--accent);
278
-
}
279
-
280
-
.separator {
281
-
margin: 0 var(--space-2);
282
-
}
283
-
284
-
.link-text {
285
-
margin-top: var(--space-6);
286
-
font-size: var(--text-sm);
287
-
color: var(--text-secondary);
288
-
text-align: center;
289
-
}
290
-
291
-
.link-text a {
292
-
color: var(--accent);
293
-
}
294
-
295
-
.saved-accounts {
296
-
display: flex;
297
-
flex-direction: column;
298
-
gap: var(--space-3);
299
-
margin-bottom: var(--space-5);
300
-
}
301
-
302
-
.saved-accounts.grid {
303
-
display: grid;
304
-
grid-template-columns: 1fr;
305
-
}
306
-
307
-
@media (min-width: 700px) {
308
-
.saved-accounts.grid {
309
-
grid-template-columns: repeat(2, 1fr);
310
-
}
311
-
}
312
-
313
-
.account-item {
314
-
display: flex;
315
-
align-items: center;
316
-
justify-content: space-between;
317
-
padding: var(--space-5);
318
-
background: var(--bg-card);
319
-
border: 1px solid var(--border-color);
320
-
border-radius: var(--radius-xl);
321
-
cursor: pointer;
322
-
transition: border-color var(--transition-normal), box-shadow var(--transition-normal);
323
-
}
324
-
325
-
.account-item:hover:not(.disabled) {
326
-
border-color: var(--accent);
327
-
box-shadow: var(--shadow-md);
328
-
}
329
-
330
-
.account-item.disabled {
331
-
opacity: 0.6;
332
-
cursor: not-allowed;
333
-
}
334
-
335
-
.account-info {
336
-
display: flex;
337
-
flex-direction: column;
338
-
gap: var(--space-1);
339
-
min-width: 0;
340
-
}
341
-
342
-
.account-handle {
343
-
font-weight: var(--font-medium);
344
-
color: var(--text-primary);
345
-
}
346
-
347
-
.account-did {
348
-
font-size: var(--text-xs);
349
-
color: var(--text-muted);
350
-
font-family: var(--font-mono);
351
-
overflow: hidden;
352
-
text-overflow: ellipsis;
353
-
}
354
-
355
-
.forget-btn {
356
-
flex-shrink: 0;
357
-
padding: var(--space-2) var(--space-3);
358
-
background: transparent;
359
-
border: none;
360
-
color: var(--text-muted);
361
-
cursor: pointer;
362
-
font-size: var(--text-xl);
363
-
line-height: 1;
364
-
border-radius: var(--radius-md);
365
-
}
366
-
367
-
.forget-btn:hover {
368
-
background: var(--error-bg);
369
-
color: var(--error-text);
370
-
}
371
-
372
-
.or-divider {
373
-
text-align: center;
374
-
color: var(--text-muted);
375
-
font-size: var(--text-sm);
376
-
margin: var(--space-5) 0;
377
-
}
378
-
</style>
+2
-68
frontend/src/routes/RecoverPasskey.svelte
+2
-68
frontend/src/routes/RecoverPasskey.svelte
···
97
97
{/if}
98
98
99
99
<form onsubmit={handleSubmit}>
100
-
<div class="field">
100
+
<div>
101
101
<label for="new-password">{$_('recoverPasskey.newPassword')}</label>
102
102
<input
103
103
id="new-password"
···
110
110
/>
111
111
</div>
112
112
113
-
<div class="field">
113
+
<div>
114
114
<label for="confirm-password">{$_('recoverPasskey.confirmPassword')}</label>
115
115
<input
116
116
id="confirm-password"
···
134
134
{/if}
135
135
</div>
136
136
137
-
<style>
138
-
.recover-page {
139
-
max-width: var(--width-sm);
140
-
margin: var(--space-9) auto;
141
-
padding: var(--space-7);
142
-
}
143
-
144
-
h1 {
145
-
margin: 0 0 var(--space-3) 0;
146
-
}
147
-
148
-
.subtitle {
149
-
color: var(--text-secondary);
150
-
margin: 0 0 var(--space-7) 0;
151
-
}
152
-
153
-
form {
154
-
display: flex;
155
-
flex-direction: column;
156
-
gap: var(--space-4);
157
-
}
158
-
159
-
.info-box {
160
-
background: var(--bg-secondary);
161
-
border: 1px solid var(--border-color);
162
-
border-radius: var(--radius-lg);
163
-
padding: var(--space-5);
164
-
font-size: var(--text-sm);
165
-
}
166
-
167
-
.info-box strong {
168
-
display: block;
169
-
margin-bottom: var(--space-3);
170
-
}
171
-
172
-
.info-box p {
173
-
margin: 0;
174
-
color: var(--text-secondary);
175
-
}
176
-
177
-
.error-message {
178
-
color: var(--text-secondary);
179
-
margin-bottom: var(--space-6);
180
-
}
181
-
182
-
.success-content {
183
-
text-align: center;
184
-
}
185
-
186
-
.success-icon {
187
-
font-size: var(--text-4xl);
188
-
color: var(--success-text);
189
-
margin-bottom: var(--space-4);
190
-
}
191
-
192
-
.success-message {
193
-
color: var(--text-secondary);
194
-
margin-bottom: var(--space-3);
195
-
}
196
-
197
-
.next-steps {
198
-
color: var(--text-muted);
199
-
font-size: var(--text-sm);
200
-
margin-bottom: var(--space-6);
201
-
}
202
-
</style>
+9
-116
frontend/src/routes/Register.svelte
+9
-116
frontend/src/routes/Register.svelte
···
329
329
330
330
<div class="page">
331
331
{#if loadingServerInfo}
332
-
<div class="loading">
333
-
<div class="spinner"></div>
334
-
<p>{$_('common.loading')}</p>
335
-
</div>
332
+
<div class="loading"></div>
336
333
{:else if flow}
337
334
<header class="page-header">
338
335
<h1>{$_('oauth.register.title')}</h1>
···
360
357
<AccountTypeSwitcher active="passkey" {ssoAvailable} oauthRequestUri={getRequestUriFromUrl()} />
361
358
362
359
<form class="register-form" onsubmit={handleInfoSubmit}>
363
-
<div class="field">
360
+
<div>
364
361
<label for="handle">{$_('register.handle')}</label>
365
362
<HandleInput
366
363
value={flow.info.handle}
···
384
381
{/if}
385
382
</div>
386
383
387
-
<div class="field">
384
+
<div>
388
385
<label for="verification-channel">{$_('register.verificationMethod')}</label>
389
386
<select id="verification-channel" bind:value={flow.info.verificationChannel} disabled={flow.state.submitting}>
390
387
<option value="email">{channelLabel('email')}</option>
···
401
398
</div>
402
399
403
400
{#if flow.info.verificationChannel === 'email'}
404
-
<div class="field">
401
+
<div>
405
402
<label for="email">{$_('register.emailAddress')}</label>
406
403
<input
407
404
id="email"
···
413
410
/>
414
411
</div>
415
412
{:else if flow.info.verificationChannel === 'discord'}
416
-
<div class="field">
413
+
<div>
417
414
<label for="discord-username">{$_('register.discordUsername')}</label>
418
415
<input
419
416
id="discord-username"
···
425
422
/>
426
423
</div>
427
424
{:else if flow.info.verificationChannel === 'telegram'}
428
-
<div class="field">
425
+
<div>
429
426
<label for="telegram-username">{$_('register.telegramUsername')}</label>
430
427
<input
431
428
id="telegram-username"
···
437
434
/>
438
435
</div>
439
436
{:else if flow.info.verificationChannel === 'signal'}
440
-
<div class="field">
437
+
<div>
441
438
<label for="signal-number">{$_('register.signalUsername')}</label>
442
439
<input
443
440
id="signal-number"
···
496
493
{/if}
497
494
498
495
{#if flow.info.didType === 'web-external'}
499
-
<div class="field">
496
+
<div>
500
497
<label for="external-did">{$_('registerPasskey.externalDid')}</label>
501
498
<input id="external-did" type="text" bind:value={flow.info.externalDid} placeholder={$_('registerPasskey.externalDidPlaceholder')} disabled={flow.state.submitting} required />
502
499
<p class="hint">{$_('registerPasskey.externalDidHint')} <code>https://{flow.info.externalDid ? flow.extractDomain(flow.info.externalDid) : 'yourdomain.com'}/.well-known/did.json</code></p>
···
504
501
{/if}
505
502
506
503
{#if serverInfo?.inviteCodeRequired}
507
-
<div class="field">
504
+
<div>
508
505
<label for="invite-code">{$_('register.inviteCode')}</label>
509
506
<input
510
507
id="invite-code"
···
535
532
536
533
{:else if flow.state.step === 'creating'}
537
534
<div class="loading">
538
-
<div class="spinner md"></div>
539
535
<p>{$_('registerPasskey.creatingAccount')}</p>
540
536
</div>
541
537
···
577
573
578
574
{:else if flow.state.step === 'activating'}
579
575
<div class="loading">
580
-
<div class="spinner md"></div>
581
576
<p>{$_('registerPasskey.activatingAccount')}</p>
582
577
</div>
583
578
{/if}
584
579
{/if}
585
580
</div>
586
-
587
-
<style>
588
-
.register-form {
589
-
display: flex;
590
-
flex-direction: column;
591
-
gap: var(--space-3);
592
-
max-width: 500px;
593
-
}
594
-
595
-
.identity-section {
596
-
border: 1px solid var(--border-color);
597
-
border-radius: var(--radius-md);
598
-
padding: var(--space-4);
599
-
margin: 0;
600
-
margin-top: var(--space-5);
601
-
}
602
-
603
-
.identity-section legend {
604
-
font-weight: var(--font-medium);
605
-
font-size: var(--text-sm);
606
-
padding: 0 var(--space-2);
607
-
}
608
-
609
-
.radio-group {
610
-
display: flex;
611
-
flex-direction: column;
612
-
gap: var(--space-3);
613
-
}
614
-
615
-
.radio-label {
616
-
display: flex;
617
-
align-items: flex-start;
618
-
gap: var(--space-2);
619
-
cursor: pointer;
620
-
}
621
-
622
-
.radio-label.disabled {
623
-
opacity: 0.5;
624
-
cursor: not-allowed;
625
-
}
626
-
627
-
.radio-label input {
628
-
margin-top: 2px;
629
-
}
630
-
631
-
.radio-content {
632
-
display: flex;
633
-
flex-direction: column;
634
-
gap: var(--space-1);
635
-
}
636
-
637
-
.radio-hint {
638
-
font-size: var(--text-sm);
639
-
color: var(--text-secondary);
640
-
}
641
-
642
-
.radio-hint.disabled-hint {
643
-
color: var(--text-muted);
644
-
}
645
-
646
-
.warning-box {
647
-
padding: var(--space-4);
648
-
background: var(--warning-bg);
649
-
border: 1px solid var(--warning-border);
650
-
border-radius: var(--radius-md);
651
-
}
652
-
653
-
.warning-box ul {
654
-
margin: var(--space-2) 0 0 0;
655
-
padding-left: var(--space-5);
656
-
}
657
-
658
-
.warning-box li {
659
-
margin-top: var(--space-2);
660
-
}
661
-
662
-
.form-actions {
663
-
display: flex;
664
-
gap: var(--space-4);
665
-
margin-top: var(--space-5);
666
-
}
667
-
668
-
.form-actions .primary {
669
-
flex: 1;
670
-
}
671
-
672
-
.passkey-step {
673
-
display: flex;
674
-
flex-direction: column;
675
-
gap: var(--space-4);
676
-
max-width: 500px;
677
-
}
678
-
679
-
.passkey-step h2 {
680
-
margin: 0;
681
-
}
682
-
683
-
.passkey-step p {
684
-
color: var(--text-secondary);
685
-
margin: 0;
686
-
}
687
-
</style>
-24
frontend/src/routes/RegisterPasskey.svelte
-24
frontend/src/routes/RegisterPasskey.svelte
···
21
21
<a href="/app/login">{$_('register.signIn')}</a>
22
22
{:else}
23
23
<div class="loading-content">
24
-
<div class="spinner"></div>
25
24
<p>{$_('common.loading')}</p>
26
25
</div>
27
26
{/if}
28
27
</div>
29
-
30
-
<style>
31
-
.register-redirect {
32
-
min-height: 100vh;
33
-
display: flex;
34
-
flex-direction: column;
35
-
align-items: center;
36
-
justify-content: center;
37
-
gap: var(--space-4);
38
-
}
39
-
40
-
.loading-content {
41
-
display: flex;
42
-
flex-direction: column;
43
-
align-items: center;
44
-
gap: var(--space-4);
45
-
}
46
-
47
-
.loading-content p {
48
-
margin: 0;
49
-
color: var(--text-secondary);
50
-
}
51
-
</style>
+11
-101
frontend/src/routes/RegisterPassword.svelte
+11
-101
frontend/src/routes/RegisterPassword.svelte
···
287
287
{/if}
288
288
289
289
{#if loadingServerInfo || !flow}
290
-
<div class="loading">
291
-
<div class="spinner md"></div>
292
-
</div>
290
+
<div class="loading"></div>
293
291
{:else if flow.state.step === 'info'}
294
292
<div class="migrate-callout">
295
293
<div class="migrate-icon">↗</div>
···
305
303
<AccountTypeSwitcher active="password" {ssoAvailable} oauthRequestUri={getRequestUriFromUrl()} />
306
304
307
305
<form class="register-form" onsubmit={handleInfoSubmit}>
308
-
<div class="field">
306
+
<div>
309
307
<label for="handle">{$_('register.handle')}</label>
310
308
<HandleInput
311
309
value={flow.info.handle}
···
329
327
{/if}
330
328
</div>
331
329
332
-
<div class="field">
330
+
<div>
333
331
<label for="password">{$_('register.password')}</label>
334
332
<input
335
333
id="password"
···
342
340
/>
343
341
</div>
344
342
345
-
<div class="field">
343
+
<div>
346
344
<label for="confirm-password">{$_('register.confirmPassword')}</label>
347
345
<input
348
346
id="confirm-password"
···
354
352
/>
355
353
</div>
356
354
357
-
<div class="field">
355
+
<div>
358
356
<label for="verification-channel">{$_('register.verificationMethod')}</label>
359
357
<select id="verification-channel" bind:value={flow.info.verificationChannel} disabled={flow.state.submitting}>
360
358
<option value="email">{$_('register.email')}</option>
···
371
369
</div>
372
370
373
371
{#if flow.info.verificationChannel === 'email'}
374
-
<div class="field">
372
+
<div>
375
373
<label for="email">{$_('register.emailAddress')}</label>
376
374
<input
377
375
id="email"
···
383
381
/>
384
382
</div>
385
383
{:else if flow.info.verificationChannel === 'discord'}
386
-
<div class="field">
384
+
<div>
387
385
<label for="discord-username">{$_('register.discordUsername')}</label>
388
386
<input
389
387
id="discord-username"
···
399
397
{/if}
400
398
</div>
401
399
{:else if flow.info.verificationChannel === 'telegram'}
402
-
<div class="field">
400
+
<div>
403
401
<label for="telegram-username">{$_('register.telegramUsername')}</label>
404
402
<input
405
403
id="telegram-username"
···
415
413
{/if}
416
414
</div>
417
415
{:else if flow.info.verificationChannel === 'signal'}
418
-
<div class="field">
416
+
<div>
419
417
<label for="signal-number">{$_('register.signalUsername')}</label>
420
418
<input
421
419
id="signal-number"
···
480
478
{/if}
481
479
482
480
{#if flow.info.didType === 'web-external'}
483
-
<div class="field">
481
+
<div>
484
482
<label for="external-did">{$_('register.externalDid')}</label>
485
483
<input
486
484
id="external-did"
···
495
493
{/if}
496
494
497
495
{#if serverInfo?.inviteCodeRequired}
498
-
<div class="field">
496
+
<div>
499
497
<label for="invite-code">{$_('register.inviteCode')}</label>
500
498
<input
501
499
id="invite-code"
···
531
529
532
530
{:else if flow.state.step === 'creating'}
533
531
<div class="loading">
534
-
<div class="spinner md"></div>
535
532
<p>{$_('common.creating')}</p>
536
533
</div>
537
534
···
547
544
548
545
{:else if flow.state.step === 'redirect-to-dashboard'}
549
546
<div class="loading">
550
-
<div class="spinner md"></div>
551
547
<p>{$_('register.redirecting')}</p>
552
548
</div>
553
549
{/if}
554
550
</div>
555
-
556
-
<style>
557
-
.register-form {
558
-
display: flex;
559
-
flex-direction: column;
560
-
gap: var(--space-3);
561
-
max-width: 500px;
562
-
}
563
-
564
-
.identity-section {
565
-
border: 1px solid var(--border-color);
566
-
border-radius: var(--radius-md);
567
-
padding: var(--space-4);
568
-
margin: 0;
569
-
margin-top: var(--space-5);
570
-
}
571
-
572
-
.identity-section legend {
573
-
font-weight: var(--font-medium);
574
-
font-size: var(--text-sm);
575
-
padding: 0 var(--space-2);
576
-
}
577
-
578
-
.radio-group {
579
-
display: flex;
580
-
flex-direction: column;
581
-
gap: var(--space-3);
582
-
}
583
-
584
-
.radio-label {
585
-
display: flex;
586
-
align-items: flex-start;
587
-
gap: var(--space-2);
588
-
cursor: pointer;
589
-
}
590
-
591
-
.radio-label.disabled {
592
-
opacity: 0.5;
593
-
cursor: not-allowed;
594
-
}
595
-
596
-
.radio-label input {
597
-
margin-top: 2px;
598
-
}
599
-
600
-
.radio-content {
601
-
display: flex;
602
-
flex-direction: column;
603
-
gap: var(--space-1);
604
-
}
605
-
606
-
.radio-hint {
607
-
font-size: var(--text-sm);
608
-
color: var(--text-secondary);
609
-
}
610
-
611
-
.radio-hint.disabled-hint {
612
-
color: var(--text-muted);
613
-
}
614
-
615
-
.warning-box {
616
-
padding: var(--space-4);
617
-
background: var(--warning-bg);
618
-
border: 1px solid var(--warning-border);
619
-
border-radius: var(--radius-md);
620
-
}
621
-
622
-
.warning-box ul {
623
-
margin: var(--space-2) 0 0 0;
624
-
padding-left: var(--space-5);
625
-
}
626
-
627
-
.warning-box li {
628
-
margin-top: var(--space-2);
629
-
}
630
-
631
-
.form-actions {
632
-
display: flex;
633
-
gap: var(--space-4);
634
-
margin-top: var(--space-5);
635
-
}
636
-
637
-
.form-actions .primary {
638
-
flex: 1;
639
-
}
640
-
</style>
+1
-63
frontend/src/routes/RegisterSso.svelte
+1
-63
frontend/src/routes/RegisterSso.svelte
···
148
148
<AccountTypeSwitcher active="sso" ssoAvailable={providers.length > 0} oauthRequestUri={getRequestUriFromUrl()} />
149
149
150
150
{#if loading}
151
-
<div class="loading">
152
-
<div class="spinner md"></div>
153
-
</div>
151
+
<div class="loading"></div>
154
152
{:else if providers.length === 0}
155
153
<div class="no-providers">
156
154
<p>{$_('register.noSsoProviders')}</p>
···
184
182
</button>
185
183
</div>
186
184
</div>
187
-
188
-
<style>
189
-
.no-providers {
190
-
text-align: center;
191
-
padding: var(--space-8);
192
-
color: var(--text-secondary);
193
-
}
194
-
195
-
.provider-list {
196
-
max-width: var(--width-md);
197
-
}
198
-
199
-
.provider-grid {
200
-
display: grid;
201
-
grid-template-columns: 1fr;
202
-
gap: var(--space-3);
203
-
}
204
-
205
-
@media (min-width: 500px) {
206
-
.provider-grid {
207
-
grid-template-columns: repeat(2, 1fr);
208
-
}
209
-
}
210
-
211
-
.provider-button {
212
-
display: flex;
213
-
align-items: center;
214
-
gap: var(--space-3);
215
-
padding: var(--space-4);
216
-
background: var(--bg-card);
217
-
border: 1px solid var(--border-dark);
218
-
border-radius: var(--radius-lg);
219
-
cursor: pointer;
220
-
transition: all var(--transition-normal);
221
-
font-size: var(--text-base);
222
-
font-weight: var(--font-medium);
223
-
color: var(--text-primary);
224
-
text-align: left;
225
-
width: 100%;
226
-
}
227
-
228
-
.provider-button:hover:not(:disabled) {
229
-
background: var(--bg-secondary);
230
-
border-color: var(--accent);
231
-
}
232
-
233
-
.provider-button:disabled {
234
-
opacity: 0.6;
235
-
cursor: not-allowed;
236
-
}
237
-
238
-
.provider-button .provider-name {
239
-
flex: 1;
240
-
}
241
-
242
-
.form-actions {
243
-
margin-top: var(--space-5);
244
-
max-width: var(--width-md);
245
-
}
246
-
</style>
+1
-60
frontend/src/routes/RequestPasskeyRecovery.svelte
+1
-60
frontend/src/routes/RequestPasskeyRecovery.svelte
···
48
48
{/if}
49
49
50
50
<form onsubmit={handleSubmit}>
51
-
<div class="field">
51
+
<div>
52
52
<label for="identifier">{$_('requestPasskeyRecovery.handleOrEmail')}</label>
53
53
<input
54
54
id="identifier"
···
76
76
</p>
77
77
</div>
78
78
79
-
<style>
80
-
.recovery-page {
81
-
max-width: var(--width-sm);
82
-
margin: var(--space-9) auto;
83
-
padding: var(--space-7);
84
-
}
85
-
86
-
h1 {
87
-
margin: 0 0 var(--space-3) 0;
88
-
}
89
-
90
-
.subtitle {
91
-
color: var(--text-secondary);
92
-
margin: 0 0 var(--space-7) 0;
93
-
}
94
-
95
-
form {
96
-
display: flex;
97
-
flex-direction: column;
98
-
gap: var(--space-4);
99
-
}
100
-
101
-
.info-box {
102
-
background: var(--bg-secondary);
103
-
border: 1px solid var(--border-color);
104
-
border-radius: var(--radius-lg);
105
-
padding: var(--space-5);
106
-
font-size: var(--text-sm);
107
-
}
108
-
109
-
.info-box strong {
110
-
display: block;
111
-
margin-bottom: var(--space-3);
112
-
}
113
-
114
-
.info-box p {
115
-
margin: 0;
116
-
color: var(--text-secondary);
117
-
}
118
-
119
-
.success-content {
120
-
text-align: center;
121
-
}
122
-
123
-
.info-text {
124
-
color: var(--text-secondary);
125
-
font-size: var(--text-sm);
126
-
margin-bottom: var(--space-6);
127
-
}
128
-
129
-
.link-text {
130
-
text-align: center;
131
-
margin-top: var(--space-7);
132
-
}
133
-
134
-
.link-text a {
135
-
color: var(--accent);
136
-
}
137
-
</style>
+4
-36
frontend/src/routes/ResetPassword.svelte
+4
-36
frontend/src/routes/ResetPassword.svelte
···
85
85
<p class="subtitle">{$_('resetPassword.subtitle')}</p>
86
86
87
87
<form onsubmit={handleReset}>
88
-
<div class="field">
88
+
<div>
89
89
<label for="token">{$_('resetPassword.code')}</label>
90
90
<input
91
91
id="token"
···
96
96
required
97
97
/>
98
98
</div>
99
-
<div class="field">
99
+
<div>
100
100
<label for="new-password">{$_('resetPassword.newPassword')}</label>
101
101
<input
102
102
id="new-password"
···
108
108
minlength="8"
109
109
/>
110
110
</div>
111
-
<div class="field">
111
+
<div>
112
112
<label for="confirm-password">{$_('resetPassword.confirmPassword')}</label>
113
113
<input
114
114
id="confirm-password"
···
131
131
<p class="subtitle">{$_('resetPassword.forgotSubtitle')}</p>
132
132
133
133
<form onsubmit={handleRequestReset}>
134
-
<div class="field">
134
+
<div>
135
135
<label for="email">{$_('resetPassword.handleOrEmail')}</label>
136
136
<input
137
137
id="email"
···
153
153
</p>
154
154
</div>
155
155
156
-
<style>
157
-
.reset-page {
158
-
max-width: var(--width-sm);
159
-
margin: var(--space-9) auto;
160
-
padding: var(--space-7);
161
-
}
162
-
163
-
h1 {
164
-
margin: 0 0 var(--space-3) 0;
165
-
}
166
-
167
-
.subtitle {
168
-
color: var(--text-secondary);
169
-
margin: 0 0 var(--space-7) 0;
170
-
}
171
-
172
-
form {
173
-
display: flex;
174
-
flex-direction: column;
175
-
gap: var(--space-4);
176
-
}
177
-
178
-
.link-text {
179
-
text-align: center;
180
-
margin-top: var(--space-6);
181
-
color: var(--text-secondary);
182
-
}
183
-
184
-
.link-text a {
185
-
color: var(--accent);
186
-
}
187
-
</style>
+3
-22
frontend/src/routes/SsoRegisterComplete.svelte
+3
-22
frontend/src/routes/SsoRegisterComplete.svelte
···
332
332
333
333
<div class="page">
334
334
{#if loading}
335
-
<div class="loading">
336
-
<div class="spinner md"></div>
337
-
<p>{$_('common.loading')}</p>
338
-
</div>
335
+
<div class="loading"></div>
339
336
{:else if error && !pending}
340
337
<div class="error-container">
341
338
<div class="error-icon">!</div>
···
397
394
<div class="split-layout sidebar-right">
398
395
<div class="form-section">
399
396
<form onsubmit={handleSubmit}>
400
-
<div class="field">
397
+
<div>
401
398
<label for="handle">{$_('sso_register.handle_label')}</label>
402
399
<HandleInput
403
400
value={handle}
···
551
548
</fieldset>
552
549
553
550
{#if serverInfo?.inviteCodeRequired}
554
-
<div class="field">
551
+
<div>
555
552
<label for="invite-code">{$_('register.inviteCode')} <span class="required">{$_('register.inviteCodeRequired')}</span></label>
556
553
<input
557
554
id="invite-code"
···
582
579
</div>
583
580
{/if}
584
581
</div>
585
-
586
-
<style>
587
-
form {
588
-
display: flex;
589
-
flex-direction: column;
590
-
gap: var(--space-5);
591
-
}
592
-
593
-
.provider-info {
594
-
margin-bottom: var(--space-6);
595
-
}
596
-
597
-
button[type="submit"] {
598
-
margin-top: var(--space-3);
599
-
}
600
-
</style>
+5
-138
frontend/src/routes/Verify.svelte
+5
-138
frontend/src/routes/Verify.svelte
···
343
343
{/if}
344
344
345
345
<form onsubmit={(e) => { e.preventDefault(); handleEmailUpdate(); }}>
346
-
<div class="field">
346
+
<div>
347
347
<label for="new-email">{$_('verify.newEmailLabel')}</label>
348
348
<input
349
349
id="new-email"
···
357
357
</div>
358
358
359
359
{#if !tokenFromUrl}
360
-
<div class="field">
360
+
<div>
361
361
<label for="verification-code">{$_('verify.codeLabel')}</label>
362
362
<input
363
363
id="verification-code"
···
395
395
{/if}
396
396
397
397
<form onsubmit={(e) => { e.preventDefault(); handleTokenVerification(); }}>
398
-
<div class="field">
398
+
<div>
399
399
<label for="identifier">{$_('verify.identifierLabel')}</label>
400
400
<input
401
401
id="identifier"
···
409
409
<p class="field-help">{$_('verify.identifierHelp')}</p>
410
410
</div>
411
411
412
-
<div class="field">
412
+
<div>
413
413
<label for="verification-code">{$_('verify.codeLabel')}</label>
414
414
<input
415
415
id="verification-code"
···
474
474
</div>
475
475
{:else}
476
476
<form onsubmit={(e) => { e.preventDefault(); handleSignupVerification(e); }}>
477
-
<div class="field">
477
+
<div>
478
478
<label for="verification-code">{$_('verify.codeLabel')}</label>
479
479
<input
480
480
id="verification-code"
···
515
515
{/if}
516
516
</div>
517
517
518
-
<style>
519
-
.verify-page {
520
-
max-width: var(--width-sm);
521
-
margin: var(--space-9) auto;
522
-
padding: var(--space-7);
523
-
}
524
-
525
-
h1 {
526
-
margin: 0 0 var(--space-3) 0;
527
-
}
528
-
529
-
.subtitle {
530
-
color: var(--text-secondary);
531
-
margin: 0 0 var(--space-4) 0;
532
-
}
533
-
534
-
.handle-info {
535
-
font-size: var(--text-sm);
536
-
color: var(--text-secondary);
537
-
margin: 0 0 var(--space-6) 0;
538
-
}
539
-
540
-
.info-text {
541
-
color: var(--text-secondary);
542
-
margin: var(--space-4) 0 var(--space-6) 0;
543
-
}
544
-
545
-
form {
546
-
display: flex;
547
-
flex-direction: column;
548
-
gap: var(--space-4);
549
-
}
550
-
551
-
.field-help {
552
-
font-size: var(--text-xs);
553
-
color: var(--text-secondary);
554
-
margin: var(--space-1) 0 0 0;
555
-
}
556
-
557
-
.token-input {
558
-
font-family: var(--font-mono);
559
-
letter-spacing: 0.05em;
560
-
}
561
-
562
-
.form-actions {
563
-
display: flex;
564
-
gap: var(--space-4);
565
-
margin-top: var(--space-4);
566
-
}
567
-
568
-
.link-text {
569
-
text-align: center;
570
-
margin-top: var(--space-6);
571
-
font-size: var(--text-sm);
572
-
}
573
-
574
-
.link-text a {
575
-
color: var(--text-secondary);
576
-
}
577
-
578
-
.actions {
579
-
display: flex;
580
-
gap: var(--space-4);
581
-
}
582
-
583
-
.btn {
584
-
flex: 1;
585
-
display: inline-block;
586
-
padding: var(--space-4);
587
-
background: var(--accent);
588
-
color: var(--text-inverse);
589
-
border: none;
590
-
border-radius: var(--radius-md);
591
-
font-size: var(--text-base);
592
-
font-weight: var(--font-medium);
593
-
cursor: pointer;
594
-
text-decoration: none;
595
-
text-align: center;
596
-
}
597
-
598
-
.btn:hover {
599
-
background: var(--accent-hover);
600
-
text-decoration: none;
601
-
}
602
-
603
-
.btn.secondary {
604
-
background: transparent;
605
-
color: var(--accent);
606
-
border: 1px solid var(--accent);
607
-
}
608
-
609
-
.btn.secondary:hover {
610
-
background: var(--accent);
611
-
color: var(--text-inverse);
612
-
}
613
-
614
-
.success-container,
615
-
.loading-container {
616
-
text-align: center;
617
-
}
618
-
619
-
.success-container .actions {
620
-
justify-content: center;
621
-
margin-top: var(--space-6);
622
-
}
623
-
624
-
.success-container .btn {
625
-
flex: none;
626
-
padding: var(--space-4) var(--space-8);
627
-
}
628
-
629
-
.bot-hint {
630
-
padding: var(--space-4);
631
-
background: var(--bg-secondary);
632
-
border-radius: var(--radius-md);
633
-
}
634
-
635
-
.bot-hint p {
636
-
margin: 0;
637
-
}
638
-
639
-
.bot-hint .manual-text {
640
-
font-size: var(--text-sm);
641
-
color: var(--text-secondary);
642
-
margin-top: var(--space-1);
643
-
}
644
-
645
-
.bot-hint .waiting-text {
646
-
font-size: var(--text-sm);
647
-
color: var(--text-secondary);
648
-
margin-top: var(--space-2);
649
-
}
650
-
</style>
+1578
frontend/src/styles/pages.css
+1578
frontend/src/styles/pages.css
···
1
+
.register-redirect {
2
+
min-height: 100vh;
3
+
display: flex;
4
+
flex-direction: column;
5
+
align-items: center;
6
+
justify-content: center;
7
+
gap: var(--space-4);
8
+
}
9
+
10
+
.loading-content {
11
+
display: flex;
12
+
flex-direction: column;
13
+
align-items: center;
14
+
gap: var(--space-4);
15
+
}
16
+
17
+
.loading-content p {
18
+
margin: 0;
19
+
color: var(--text-secondary);
20
+
}
21
+
22
+
.login-page,
23
+
.verify-page,
24
+
.reset-page,
25
+
.recover-page,
26
+
.recovery-page,
27
+
.oauth-accounts-container,
28
+
.oauth-2fa-container,
29
+
.oauth-totp-container,
30
+
.delegation-container,
31
+
.oauth-register-container,
32
+
.sso-register-container,
33
+
.migration-page {
34
+
margin: var(--space-9) auto;
35
+
padding: var(--space-7);
36
+
}
37
+
38
+
.act-as-page .loading,
39
+
.consent-container .loading,
40
+
.oauth-accounts-container .loading,
41
+
.delegation-container .loading {
42
+
display: flex;
43
+
align-items: center;
44
+
justify-content: center;
45
+
min-height: 200px;
46
+
color: var(--text-secondary);
47
+
}
48
+
49
+
.oauth-2fa-container .actions,
50
+
.oauth-totp-container .actions,
51
+
.delegation-container .actions {
52
+
display: flex;
53
+
gap: var(--space-4);
54
+
margin-top: var(--space-2);
55
+
}
56
+
57
+
.oauth-2fa-container .actions button,
58
+
.oauth-totp-container .actions button,
59
+
.delegation-container .actions button {
60
+
flex: 1;
61
+
padding: var(--space-3);
62
+
border: none;
63
+
font-size: var(--text-base);
64
+
cursor: pointer;
65
+
}
66
+
67
+
.login-page {
68
+
max-width: var(--width-lg);
69
+
}
70
+
71
+
.login-page .page-header {
72
+
margin-bottom: var(--space-6);
73
+
text-align: center;
74
+
}
75
+
76
+
.login-content {
77
+
max-width: var(--width-md);
78
+
margin: 0 auto;
79
+
}
80
+
81
+
.login-page .actions {
82
+
display: flex;
83
+
flex-direction: column;
84
+
gap: var(--space-3);
85
+
margin-top: var(--space-3);
86
+
}
87
+
88
+
@media (min-width: 600px) {
89
+
.login-page .actions {
90
+
flex-direction: row;
91
+
}
92
+
93
+
.login-page .actions button {
94
+
flex: 1;
95
+
}
96
+
}
97
+
98
+
.link-text {
99
+
margin-top: var(--space-6);
100
+
font-size: var(--text-sm);
101
+
color: var(--text-secondary);
102
+
text-align: center;
103
+
}
104
+
105
+
.link-text a {
106
+
color: var(--secondary);
107
+
}
108
+
109
+
.saved-accounts {
110
+
display: flex;
111
+
flex-direction: column;
112
+
gap: var(--space-3);
113
+
margin-bottom: var(--space-5);
114
+
}
115
+
116
+
.saved-accounts.grid {
117
+
display: grid;
118
+
grid-template-columns: 1fr;
119
+
}
120
+
121
+
@media (min-width: 700px) {
122
+
.saved-accounts.grid {
123
+
grid-template-columns: repeat(2, 1fr);
124
+
}
125
+
}
126
+
127
+
.account-item {
128
+
display: flex;
129
+
align-items: center;
130
+
justify-content: space-between;
131
+
padding: var(--space-5);
132
+
background: var(--bg-card);
133
+
cursor: pointer;
134
+
}
135
+
136
+
.account-item:hover:not(.disabled) {
137
+
border-color: var(--secondary);
138
+
box-shadow: var(--shadow-md);
139
+
}
140
+
141
+
.account-item.disabled {
142
+
opacity: 0.6;
143
+
cursor: not-allowed;
144
+
}
145
+
146
+
.account-info {
147
+
display: flex;
148
+
flex-direction: column;
149
+
gap: var(--space-1);
150
+
min-width: 0;
151
+
}
152
+
153
+
.account-handle {
154
+
font-weight: var(--font-medium);
155
+
color: var(--text-primary);
156
+
}
157
+
158
+
.account-did {
159
+
font-size: var(--text-xs);
160
+
color: var(--text-muted);
161
+
font-family: var(--font-mono);
162
+
overflow: hidden;
163
+
text-overflow: ellipsis;
164
+
}
165
+
166
+
.forget-btn {
167
+
flex-shrink: 0;
168
+
padding: var(--space-2) var(--space-3);
169
+
background: transparent;
170
+
border: none;
171
+
color: var(--text-muted);
172
+
cursor: pointer;
173
+
font-size: var(--text-xl);
174
+
line-height: 1;
175
+
}
176
+
177
+
button.forget-btn:hover {
178
+
background: var(--error-bg);
179
+
color: var(--error-text);
180
+
}
181
+
182
+
.verify-page {
183
+
max-width: var(--width-sm);
184
+
}
185
+
186
+
.handle-info {
187
+
font-size: var(--text-sm);
188
+
color: var(--text-secondary);
189
+
margin: 0 0 var(--space-6) 0;
190
+
}
191
+
192
+
.verify-page .info-text {
193
+
color: var(--text-secondary);
194
+
margin: var(--space-4) 0 var(--space-6) 0;
195
+
}
196
+
197
+
.field-help {
198
+
font-size: var(--text-xs);
199
+
color: var(--text-secondary);
200
+
margin: var(--space-1) 0 0 0;
201
+
}
202
+
203
+
.token-input {
204
+
font-family: var(--font-mono);
205
+
letter-spacing: 0.05em;
206
+
}
207
+
208
+
.verify-page .form-actions {
209
+
display: flex;
210
+
gap: var(--space-4);
211
+
margin-top: var(--space-4);
212
+
}
213
+
214
+
.verify-page .actions {
215
+
display: flex;
216
+
gap: var(--space-4);
217
+
}
218
+
219
+
.success-container,
220
+
.loading-container {
221
+
text-align: center;
222
+
}
223
+
224
+
.success-container .actions {
225
+
justify-content: center;
226
+
margin-top: var(--space-6);
227
+
}
228
+
229
+
.bot-hint {
230
+
padding: var(--space-4);
231
+
background: var(--bg-secondary);
232
+
}
233
+
234
+
.bot-hint p {
235
+
margin: 0;
236
+
}
237
+
238
+
.bot-hint .manual-text {
239
+
font-size: var(--text-sm);
240
+
color: var(--text-secondary);
241
+
margin-top: var(--space-1);
242
+
}
243
+
244
+
.bot-hint .waiting-text {
245
+
font-size: var(--text-sm);
246
+
color: var(--text-secondary);
247
+
margin-top: var(--space-2);
248
+
}
249
+
250
+
.reset-page {
251
+
max-width: var(--width-sm);
252
+
}
253
+
254
+
.reset-page .link-text {
255
+
text-align: center;
256
+
margin-top: var(--space-6);
257
+
color: var(--text-secondary);
258
+
}
259
+
260
+
.reset-page .link-text a {
261
+
color: var(--secondary);
262
+
}
263
+
264
+
.recover-page {
265
+
max-width: var(--width-sm);
266
+
}
267
+
268
+
.error-message {
269
+
color: var(--text-secondary);
270
+
margin-bottom: var(--space-6);
271
+
}
272
+
273
+
.success-content {
274
+
text-align: center;
275
+
}
276
+
277
+
.success-icon {
278
+
font-size: var(--text-4xl);
279
+
color: var(--success-text);
280
+
margin-bottom: var(--space-4);
281
+
}
282
+
283
+
.success-message {
284
+
color: var(--text-secondary);
285
+
margin-bottom: var(--space-3);
286
+
}
287
+
288
+
.next-steps {
289
+
color: var(--text-muted);
290
+
font-size: var(--text-sm);
291
+
margin-bottom: var(--space-6);
292
+
}
293
+
294
+
.recovery-page {
295
+
max-width: var(--width-sm);
296
+
}
297
+
298
+
.recovery-page .info-text {
299
+
color: var(--text-secondary);
300
+
font-size: var(--text-sm);
301
+
margin-bottom: var(--space-6);
302
+
}
303
+
304
+
.recovery-page .link-text {
305
+
text-align: center;
306
+
margin-top: var(--space-7);
307
+
}
308
+
309
+
.recovery-page .link-text a {
310
+
color: var(--secondary);
311
+
}
312
+
313
+
.act-as-page .page {
314
+
max-width: var(--width-md);
315
+
margin: var(--space-9) auto;
316
+
padding: var(--space-7);
317
+
}
318
+
319
+
.act-as-page header {
320
+
margin-bottom: var(--space-6);
321
+
}
322
+
323
+
.act-as-page .message.error {
324
+
padding: var(--space-3);
325
+
background: var(--error-bg);
326
+
color: var(--error-text);
327
+
margin-bottom: var(--space-4);
328
+
}
329
+
330
+
.act-as-page .actions {
331
+
margin-top: var(--space-4);
332
+
}
333
+
334
+
.migration-page {
335
+
max-width: var(--width-lg);
336
+
}
337
+
338
+
.migration-page .page-header {
339
+
text-align: center;
340
+
margin-bottom: var(--space-8);
341
+
}
342
+
343
+
.migration-page .subtitle {
344
+
color: var(--text-secondary);
345
+
margin: 0;
346
+
font-size: var(--text-lg);
347
+
}
348
+
349
+
.direction-cards {
350
+
display: grid;
351
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
352
+
gap: var(--space-6);
353
+
margin-bottom: var(--space-8);
354
+
}
355
+
356
+
.direction-card {
357
+
display: flex;
358
+
flex-direction: column;
359
+
align-items: stretch;
360
+
background: var(--bg-secondary);
361
+
padding: var(--space-6);
362
+
text-align: left;
363
+
cursor: pointer;
364
+
}
365
+
366
+
.direction-card:hover:not(:disabled) {
367
+
border-color: var(--secondary);
368
+
transform: translateY(-2px);
369
+
box-shadow: var(--shadow-lg);
370
+
}
371
+
372
+
.direction-card:disabled {
373
+
opacity: 0.6;
374
+
cursor: not-allowed;
375
+
}
376
+
377
+
.direction-card h2 {
378
+
margin: 0 0 var(--space-3) 0;
379
+
font-size: var(--text-xl);
380
+
color: var(--text-primary);
381
+
}
382
+
383
+
.direction-card p {
384
+
color: var(--text-secondary);
385
+
margin: 0 0 var(--space-4) 0;
386
+
font-size: var(--text-sm);
387
+
}
388
+
389
+
.features {
390
+
margin: 0;
391
+
padding-left: var(--space-5);
392
+
color: var(--text-secondary);
393
+
font-size: var(--text-sm);
394
+
}
395
+
396
+
.features li {
397
+
margin-bottom: var(--space-2);
398
+
}
399
+
400
+
.info-section {
401
+
background: var(--bg-secondary);
402
+
padding: var(--space-6);
403
+
}
404
+
405
+
.info-section h3 {
406
+
margin: 0 0 var(--space-3) 0;
407
+
font-size: var(--text-lg);
408
+
}
409
+
410
+
.info-section h3:not(:first-child) {
411
+
margin-top: var(--space-6);
412
+
}
413
+
414
+
.info-section p {
415
+
color: var(--text-secondary);
416
+
line-height: var(--leading-relaxed);
417
+
margin: 0;
418
+
}
419
+
420
+
.info-section ul {
421
+
color: var(--text-secondary);
422
+
padding-left: var(--space-5);
423
+
margin: var(--space-3) 0 0 0;
424
+
}
425
+
426
+
.info-section li {
427
+
margin-bottom: var(--space-2);
428
+
}
429
+
430
+
.migration-page .warning-box {
431
+
margin-top: var(--space-6);
432
+
padding: var(--space-5);
433
+
background: var(--warning-bg);
434
+
font-size: var(--text-sm);
435
+
}
436
+
437
+
.migration-page .warning-box strong {
438
+
color: var(--warning-text);
439
+
}
440
+
441
+
.migration-page .warning-box a {
442
+
display: inline;
443
+
margin-top: var(--space-2);
444
+
}
445
+
446
+
.modal-overlay {
447
+
position: fixed;
448
+
inset: 0;
449
+
background: var(--overlay-bg);
450
+
display: flex;
451
+
align-items: center;
452
+
justify-content: center;
453
+
z-index: var(--z-modal);
454
+
}
455
+
456
+
.migration-page .modal {
457
+
background: var(--bg-primary);
458
+
padding: var(--space-6);
459
+
max-width: var(--width-sm);
460
+
width: 90%;
461
+
}
462
+
463
+
.migration-page .modal h2 {
464
+
margin: 0 0 var(--space-4) 0;
465
+
}
466
+
467
+
.migration-page .modal p {
468
+
color: var(--text-secondary);
469
+
margin: 0 0 var(--space-4) 0;
470
+
}
471
+
472
+
.resume-details {
473
+
background: var(--bg-secondary);
474
+
padding: var(--space-4);
475
+
margin-bottom: var(--space-4);
476
+
}
477
+
478
+
.detail-row {
479
+
display: flex;
480
+
justify-content: space-between;
481
+
padding: var(--space-2) 0;
482
+
font-size: var(--text-sm);
483
+
}
484
+
485
+
.detail-row:not(:last-child) {
486
+
border-bottom: 1px solid var(--border-color);
487
+
}
488
+
489
+
.detail-row .label {
490
+
color: var(--text-secondary);
491
+
}
492
+
493
+
.detail-row .value {
494
+
font-weight: var(--font-medium);
495
+
}
496
+
497
+
.note {
498
+
font-size: var(--text-sm);
499
+
font-style: italic;
500
+
}
501
+
502
+
.migration-page .modal-actions {
503
+
display: flex;
504
+
gap: var(--space-3);
505
+
justify-content: flex-end;
506
+
}
507
+
508
+
.oauth-error {
509
+
max-width: 500px;
510
+
margin: 0 auto;
511
+
text-align: center;
512
+
padding: var(--space-8);
513
+
background: var(--error-bg);
514
+
}
515
+
516
+
.oauth-error h2 {
517
+
margin: 0 0 var(--space-4) 0;
518
+
color: var(--error-text);
519
+
}
520
+
521
+
.oauth-error p {
522
+
color: var(--text-secondary);
523
+
margin: 0 0 var(--space-5) 0;
524
+
}
525
+
526
+
.register-form {
527
+
display: flex;
528
+
flex-direction: column;
529
+
gap: var(--space-3);
530
+
max-width: 500px;
531
+
}
532
+
533
+
.identity-section {
534
+
border: 1px solid var(--border-color);
535
+
padding: var(--space-4);
536
+
margin: 0;
537
+
margin-top: var(--space-5);
538
+
}
539
+
540
+
.identity-section legend {
541
+
font-weight: var(--font-medium);
542
+
font-size: var(--text-sm);
543
+
padding: 0 var(--space-2);
544
+
}
545
+
546
+
.passkey-step {
547
+
display: flex;
548
+
flex-direction: column;
549
+
gap: var(--space-4);
550
+
max-width: 500px;
551
+
}
552
+
553
+
.passkey-step h2 {
554
+
margin: 0;
555
+
}
556
+
557
+
.passkey-step p {
558
+
color: var(--text-secondary);
559
+
margin: 0;
560
+
}
561
+
562
+
.no-providers {
563
+
text-align: center;
564
+
padding: var(--space-8);
565
+
color: var(--text-secondary);
566
+
}
567
+
568
+
.provider-list {
569
+
max-width: var(--width-md);
570
+
}
571
+
572
+
.provider-grid {
573
+
display: grid;
574
+
grid-template-columns: 1fr;
575
+
gap: var(--space-3);
576
+
}
577
+
578
+
@media (min-width: 500px) {
579
+
.provider-grid {
580
+
grid-template-columns: repeat(2, 1fr);
581
+
}
582
+
}
583
+
584
+
.provider-button {
585
+
display: flex;
586
+
align-items: center;
587
+
gap: var(--space-3);
588
+
padding: var(--space-4);
589
+
background: var(--bg-card);
590
+
border: 1px solid var(--border-dark);
591
+
cursor: pointer;
592
+
font-size: var(--text-base);
593
+
font-weight: var(--font-medium);
594
+
color: var(--text-primary);
595
+
text-align: left;
596
+
width: 100%;
597
+
}
598
+
599
+
.provider-button:hover:not(:disabled) {
600
+
background: var(--bg-secondary);
601
+
border-color: var(--secondary);
602
+
}
603
+
604
+
.provider-button:disabled {
605
+
opacity: 0.6;
606
+
cursor: not-allowed;
607
+
}
608
+
609
+
.provider-button .provider-name {
610
+
flex: 1;
611
+
}
612
+
613
+
.register-sso .form-actions {
614
+
margin-top: var(--space-5);
615
+
max-width: var(--width-md);
616
+
}
617
+
618
+
.sso-register-complete .provider-info {
619
+
margin-bottom: var(--space-6);
620
+
}
621
+
622
+
.sso-register-complete button[type="submit"] {
623
+
margin-top: var(--space-3);
624
+
}
625
+
626
+
.oauth-login .auth-methods {
627
+
display: grid;
628
+
grid-template-columns: 1fr;
629
+
gap: var(--space-5);
630
+
margin-top: var(--space-4);
631
+
}
632
+
633
+
@media (min-width: 600px) {
634
+
.oauth-login .auth-methods {
635
+
grid-template-columns: 1fr auto 1fr;
636
+
align-items: start;
637
+
}
638
+
}
639
+
640
+
.auth-methods {
641
+
display: grid;
642
+
grid-template-columns: 1fr;
643
+
gap: var(--space-5);
644
+
margin-top: var(--space-4);
645
+
}
646
+
647
+
@media (min-width: 600px) {
648
+
.auth-methods {
649
+
grid-template-columns: 1fr auto 1fr;
650
+
align-items: start;
651
+
}
652
+
}
653
+
654
+
.auth-methods.single-method {
655
+
grid-template-columns: 1fr;
656
+
}
657
+
658
+
@media (min-width: 600px) {
659
+
.auth-methods.single-method {
660
+
grid-template-columns: 1fr;
661
+
max-width: 400px;
662
+
margin: var(--space-4) auto 0;
663
+
}
664
+
}
665
+
666
+
.passkey-method,
667
+
.password-method {
668
+
display: flex;
669
+
flex-direction: column;
670
+
gap: var(--space-4);
671
+
padding: var(--space-5);
672
+
background: var(--bg-secondary);
673
+
}
674
+
675
+
.passkey-method h3,
676
+
.password-method h3 {
677
+
margin: 0;
678
+
font-size: var(--text-sm);
679
+
font-weight: var(--font-semibold);
680
+
color: var(--text-secondary);
681
+
text-transform: uppercase;
682
+
letter-spacing: 0.05em;
683
+
}
684
+
685
+
.method-divider {
686
+
display: flex;
687
+
align-items: center;
688
+
justify-content: center;
689
+
color: var(--text-muted);
690
+
font-size: var(--text-sm);
691
+
}
692
+
693
+
@media (min-width: 600px) {
694
+
.method-divider {
695
+
flex-direction: column;
696
+
padding: 0 var(--space-3);
697
+
}
698
+
699
+
.method-divider::before,
700
+
.method-divider::after {
701
+
content: '';
702
+
width: 1px;
703
+
height: var(--space-6);
704
+
background: var(--border-color);
705
+
}
706
+
707
+
.method-divider span {
708
+
writing-mode: vertical-rl;
709
+
text-orientation: mixed;
710
+
transform: rotate(180deg);
711
+
padding: var(--space-2) 0;
712
+
}
713
+
}
714
+
715
+
@media (max-width: 599px) {
716
+
.method-divider {
717
+
gap: var(--space-4);
718
+
}
719
+
720
+
.method-divider::before,
721
+
.method-divider::after {
722
+
content: '';
723
+
flex: 1;
724
+
height: 1px;
725
+
background: var(--border-color);
726
+
}
727
+
}
728
+
729
+
.remember-device {
730
+
display: flex;
731
+
align-items: center;
732
+
gap: var(--space-2);
733
+
cursor: pointer;
734
+
color: var(--text-secondary);
735
+
font-size: var(--text-sm);
736
+
}
737
+
738
+
.remember-device input {
739
+
width: 16px;
740
+
height: 16px;
741
+
}
742
+
743
+
.oauth-login .actions {
744
+
display: flex;
745
+
gap: var(--space-4);
746
+
margin-top: var(--space-2);
747
+
}
748
+
749
+
.oauth-login .actions button {
750
+
flex: 1;
751
+
}
752
+
753
+
.passkey-unavailable {
754
+
background: var(--bg-secondary);
755
+
color: var(--text-secondary);
756
+
border-color: var(--border-color);
757
+
}
758
+
759
+
.passkey-icon {
760
+
width: 20px;
761
+
height: 20px;
762
+
}
763
+
764
+
.passkey-text {
765
+
flex: 1;
766
+
text-align: left;
767
+
}
768
+
769
+
.sso-section {
770
+
margin-top: var(--space-6);
771
+
}
772
+
773
+
.sso-section-top {
774
+
margin-top: var(--space-4);
775
+
margin-bottom: 0;
776
+
}
777
+
778
+
.sso-section-top .sso-divider {
779
+
margin-top: var(--space-5);
780
+
margin-bottom: 0;
781
+
}
782
+
783
+
.sso-divider {
784
+
display: flex;
785
+
align-items: center;
786
+
gap: var(--space-4);
787
+
margin-bottom: var(--space-4);
788
+
color: var(--text-muted);
789
+
font-size: var(--text-sm);
790
+
}
791
+
792
+
.sso-divider::before,
793
+
.sso-divider::after {
794
+
content: '';
795
+
flex: 1;
796
+
height: 1px;
797
+
background: var(--border-color);
798
+
}
799
+
800
+
.sso-buttons {
801
+
display: flex;
802
+
flex-wrap: wrap;
803
+
gap: var(--space-3);
804
+
justify-content: center;
805
+
}
806
+
807
+
.sso-btn {
808
+
display: flex;
809
+
align-items: center;
810
+
gap: var(--space-2);
811
+
padding: var(--space-2) var(--space-4);
812
+
background: var(--bg-secondary);
813
+
color: var(--text-primary);
814
+
border: 1px solid var(--border-color);
815
+
font-size: var(--text-sm);
816
+
cursor: pointer;
817
+
}
818
+
819
+
.sso-btn-prominent {
820
+
padding: var(--space-3) var(--space-5);
821
+
font-size: var(--text-base);
822
+
font-weight: var(--font-medium);
823
+
}
824
+
825
+
.sso-btn:hover:not(:disabled) {
826
+
background: var(--bg-tertiary);
827
+
border-color: var(--secondary);
828
+
}
829
+
830
+
.sso-btn:disabled {
831
+
opacity: 0.6;
832
+
cursor: not-allowed;
833
+
}
834
+
835
+
.consent-container {
836
+
max-width: var(--width-lg);
837
+
margin: var(--space-7) auto;
838
+
padding: var(--space-7);
839
+
}
840
+
841
+
.client-panel {
842
+
display: flex;
843
+
flex-direction: column;
844
+
gap: var(--space-5);
845
+
}
846
+
847
+
.permissions-panel {
848
+
min-width: 0;
849
+
}
850
+
851
+
.client-info {
852
+
text-align: center;
853
+
padding: var(--space-6);
854
+
background: var(--bg-secondary);
855
+
}
856
+
857
+
@media (min-width: 800px) {
858
+
.client-info {
859
+
text-align: left;
860
+
}
861
+
}
862
+
863
+
.client-logo {
864
+
width: 64px;
865
+
height: 64px;
866
+
margin-bottom: var(--space-4);
867
+
}
868
+
869
+
.client-info h1 {
870
+
margin: 0 0 var(--space-1) 0;
871
+
font-size: var(--text-xl);
872
+
}
873
+
874
+
.client-link {
875
+
display: inline-block;
876
+
margin-top: var(--space-2);
877
+
font-size: var(--text-sm);
878
+
color: var(--secondary);
879
+
text-decoration: none;
880
+
}
881
+
882
+
.client-link:hover {
883
+
text-decoration: underline;
884
+
}
885
+
886
+
.consent-container .account-info {
887
+
display: flex;
888
+
flex-direction: column;
889
+
gap: var(--space-1);
890
+
padding: var(--space-4);
891
+
background: var(--bg-secondary);
892
+
margin-bottom: var(--space-6);
893
+
}
894
+
895
+
.consent-container .account-info .label {
896
+
font-size: var(--text-xs);
897
+
color: var(--text-muted);
898
+
text-transform: uppercase;
899
+
letter-spacing: 0.05em;
900
+
}
901
+
902
+
.consent-container .account-info .did {
903
+
font-family: var(--font-mono);
904
+
font-size: var(--text-sm);
905
+
color: var(--text-secondary);
906
+
word-break: break-all;
907
+
}
908
+
909
+
.consent-container .account-info .handle {
910
+
font-size: var(--text-base);
911
+
font-weight: var(--font-medium);
912
+
color: var(--text-primary);
913
+
}
914
+
915
+
.delegation-badge {
916
+
display: inline-block;
917
+
padding: var(--space-1) var(--space-2);
918
+
background: var(--accent);
919
+
color: var(--text-inverse);
920
+
font-size: var(--text-xs);
921
+
font-weight: var(--font-semibold);
922
+
text-transform: uppercase;
923
+
letter-spacing: 0.05em;
924
+
margin-bottom: var(--space-3);
925
+
}
926
+
927
+
.delegation-info {
928
+
display: flex;
929
+
flex-direction: column;
930
+
gap: var(--space-2);
931
+
}
932
+
933
+
.delegation-info .info-row {
934
+
display: flex;
935
+
flex-direction: column;
936
+
gap: 2px;
937
+
}
938
+
939
+
.delegation-info .handle {
940
+
font-weight: var(--font-medium);
941
+
color: var(--text-primary);
942
+
}
943
+
944
+
.level-badge {
945
+
display: inline-block;
946
+
padding: 2px var(--space-2);
947
+
background: var(--bg-tertiary);
948
+
color: var(--text-primary);
949
+
font-size: var(--text-sm);
950
+
font-weight: var(--font-medium);
951
+
}
952
+
953
+
.level-badge.level-owner {
954
+
background: var(--success-bg);
955
+
color: var(--success-text);
956
+
}
957
+
958
+
.level-badge.level-admin {
959
+
background: var(--accent);
960
+
color: var(--text-inverse);
961
+
}
962
+
963
+
.level-badge.level-editor {
964
+
background: var(--warning-bg);
965
+
color: var(--warning-text);
966
+
}
967
+
968
+
.level-badge.level-viewer {
969
+
background: var(--bg-tertiary);
970
+
color: var(--text-secondary);
971
+
}
972
+
973
+
.permissions-notice {
974
+
margin-top: var(--space-3);
975
+
padding: var(--space-3);
976
+
background: var(--warning-bg);
977
+
}
978
+
979
+
.notice-header {
980
+
display: flex;
981
+
align-items: center;
982
+
gap: var(--space-2);
983
+
font-weight: var(--font-semibold);
984
+
color: var(--warning-text);
985
+
margin-bottom: var(--space-2);
986
+
}
987
+
988
+
.notice-header svg {
989
+
flex-shrink: 0;
990
+
}
991
+
992
+
.notice-text {
993
+
margin: 0;
994
+
font-size: var(--text-sm);
995
+
color: var(--warning-text);
996
+
line-height: 1.5;
997
+
}
998
+
999
+
.scopes-section {
1000
+
margin-bottom: var(--space-6);
1001
+
}
1002
+
1003
+
.scopes-section h2 {
1004
+
font-size: var(--text-base);
1005
+
margin: 0 0 var(--space-4) 0;
1006
+
color: var(--text-secondary);
1007
+
}
1008
+
1009
+
.scope-group {
1010
+
margin-bottom: var(--space-4);
1011
+
}
1012
+
1013
+
.category-title {
1014
+
font-size: var(--text-sm);
1015
+
font-weight: var(--font-semibold);
1016
+
color: var(--text-primary);
1017
+
margin: 0 0 var(--space-2) 0;
1018
+
padding-bottom: var(--space-1);
1019
+
border-bottom: 1px solid var(--border-color);
1020
+
}
1021
+
1022
+
.scope-item {
1023
+
display: flex;
1024
+
gap: var(--space-3);
1025
+
padding: var(--space-3);
1026
+
background: var(--bg-card);
1027
+
margin-bottom: var(--space-2);
1028
+
cursor: pointer;
1029
+
overflow: hidden;
1030
+
}
1031
+
1032
+
.scope-item:hover:not(.required) {
1033
+
border-color: var(--secondary);
1034
+
}
1035
+
1036
+
.scope-item.required {
1037
+
background: var(--bg-secondary);
1038
+
}
1039
+
1040
+
.scope-item.read-only {
1041
+
background: var(--bg-secondary);
1042
+
border-style: dashed;
1043
+
}
1044
+
1045
+
.scope-item input[type="checkbox"] {
1046
+
flex-shrink: 0;
1047
+
width: 18px;
1048
+
height: 18px;
1049
+
margin-top: 2px;
1050
+
}
1051
+
1052
+
.scope-info {
1053
+
flex: 1;
1054
+
min-width: 0;
1055
+
display: flex;
1056
+
flex-direction: column;
1057
+
gap: 2px;
1058
+
overflow: hidden;
1059
+
}
1060
+
1061
+
.scope-name {
1062
+
font-weight: var(--font-medium);
1063
+
color: var(--text-primary);
1064
+
word-break: break-all;
1065
+
}
1066
+
1067
+
.scope-description {
1068
+
font-size: var(--text-sm);
1069
+
color: var(--text-secondary);
1070
+
word-break: break-all;
1071
+
}
1072
+
1073
+
.required-badge {
1074
+
display: inline-block;
1075
+
font-size: 0.625rem;
1076
+
padding: 2px var(--space-2);
1077
+
background: var(--warning-bg);
1078
+
color: var(--warning-text);
1079
+
text-transform: uppercase;
1080
+
letter-spacing: 0.05em;
1081
+
margin-top: var(--space-1);
1082
+
width: fit-content;
1083
+
}
1084
+
1085
+
.remember-choice {
1086
+
display: flex;
1087
+
align-items: center;
1088
+
gap: var(--space-2);
1089
+
margin-top: var(--space-5);
1090
+
cursor: pointer;
1091
+
color: var(--text-secondary);
1092
+
font-size: var(--text-sm);
1093
+
}
1094
+
1095
+
.remember-choice input {
1096
+
width: 16px;
1097
+
height: 16px;
1098
+
}
1099
+
1100
+
.consent-container .actions {
1101
+
display: flex;
1102
+
gap: var(--space-4);
1103
+
margin-top: var(--space-6);
1104
+
}
1105
+
1106
+
@media (min-width: 800px) {
1107
+
.consent-container .actions {
1108
+
max-width: 400px;
1109
+
margin-left: auto;
1110
+
}
1111
+
}
1112
+
1113
+
.consent-container .actions button {
1114
+
flex: 1;
1115
+
padding: var(--space-3);
1116
+
border: none;
1117
+
font-size: var(--text-base);
1118
+
font-weight: var(--font-medium);
1119
+
cursor: pointer;
1120
+
}
1121
+
1122
+
.oauth-accounts-container {
1123
+
max-width: var(--width-sm);
1124
+
}
1125
+
1126
+
.accounts-list {
1127
+
display: flex;
1128
+
flex-direction: column;
1129
+
gap: var(--space-2);
1130
+
margin-bottom: var(--space-4);
1131
+
}
1132
+
1133
+
.oauth-accounts-container .account-item {
1134
+
display: flex;
1135
+
align-items: center;
1136
+
padding: var(--space-4);
1137
+
background: var(--bg-secondary);
1138
+
cursor: pointer;
1139
+
text-align: left;
1140
+
width: 100%;
1141
+
}
1142
+
1143
+
.oauth-accounts-container .account-item:hover:not(.disabled) {
1144
+
border-color: var(--secondary);
1145
+
background: var(--bg-tertiary);
1146
+
}
1147
+
1148
+
.oauth-accounts-container .account-item.disabled {
1149
+
opacity: 0.6;
1150
+
cursor: not-allowed;
1151
+
}
1152
+
1153
+
.oauth-accounts-container .account-info {
1154
+
display: flex;
1155
+
flex-direction: column;
1156
+
gap: var(--space-1);
1157
+
}
1158
+
1159
+
.oauth-accounts-container .account-handle {
1160
+
font-weight: var(--font-medium);
1161
+
color: var(--text-primary);
1162
+
}
1163
+
1164
+
.account-email {
1165
+
font-size: var(--text-sm);
1166
+
color: var(--text-secondary);
1167
+
}
1168
+
1169
+
.different-account {
1170
+
margin-top: var(--space-4);
1171
+
width: 100%;
1172
+
}
1173
+
1174
+
.oauth-2fa-container {
1175
+
max-width: var(--width-sm);
1176
+
}
1177
+
1178
+
.oauth-2fa-container input {
1179
+
padding: var(--space-3);
1180
+
border: 1px solid var(--border-color);
1181
+
font-size: var(--text-xl);
1182
+
letter-spacing: 0.5em;
1183
+
text-align: center;
1184
+
background: var(--bg-input);
1185
+
color: var(--text-primary);
1186
+
}
1187
+
1188
+
.oauth-totp-container {
1189
+
max-width: var(--width-sm);
1190
+
}
1191
+
1192
+
.oauth-totp-container input {
1193
+
padding: var(--space-3);
1194
+
border: 1px solid var(--border-color);
1195
+
font-size: var(--text-xl);
1196
+
letter-spacing: 0.25em;
1197
+
text-align: center;
1198
+
background: var(--bg-input);
1199
+
color: var(--text-primary);
1200
+
text-transform: uppercase;
1201
+
}
1202
+
1203
+
.oauth-totp-container .hint {
1204
+
font-size: var(--text-xs);
1205
+
color: var(--text-muted);
1206
+
margin: var(--space-1) 0 0 0;
1207
+
text-align: center;
1208
+
}
1209
+
1210
+
.trust-device-label {
1211
+
display: flex;
1212
+
align-items: center;
1213
+
gap: var(--space-2);
1214
+
cursor: pointer;
1215
+
font-size: var(--text-sm);
1216
+
color: var(--text-secondary);
1217
+
margin-top: var(--space-2);
1218
+
}
1219
+
1220
+
.trust-device-label input[type="checkbox"] {
1221
+
width: auto;
1222
+
margin: 0;
1223
+
}
1224
+
1225
+
.oauth-passkey-container {
1226
+
max-width: 400px;
1227
+
margin: 4rem auto;
1228
+
padding: 2rem;
1229
+
text-align: center;
1230
+
}
1231
+
1232
+
.oauth-passkey-container h1 {
1233
+
margin: 0 0 1.5rem 0;
1234
+
}
1235
+
1236
+
.oauth-passkey-container .error {
1237
+
padding: 0.75rem;
1238
+
background: var(--error-bg);
1239
+
color: var(--error-text);
1240
+
margin-bottom: 1.5rem;
1241
+
text-align: left;
1242
+
}
1243
+
1244
+
.passkey-status {
1245
+
padding: 2rem;
1246
+
background: var(--bg-secondary);
1247
+
margin-bottom: 1.5rem;
1248
+
}
1249
+
1250
+
.oauth-passkey-container .loading-indicator {
1251
+
display: flex;
1252
+
flex-direction: column;
1253
+
align-items: center;
1254
+
gap: 1rem;
1255
+
}
1256
+
1257
+
.oauth-passkey-container .loading-indicator p {
1258
+
margin: 0;
1259
+
color: var(--text-secondary);
1260
+
}
1261
+
1262
+
.oauth-passkey-container .actions {
1263
+
display: flex;
1264
+
justify-content: center;
1265
+
margin-bottom: 1.5rem;
1266
+
}
1267
+
1268
+
.delegation-container {
1269
+
max-width: var(--width-md);
1270
+
}
1271
+
1272
+
.delegation-container .page-header {
1273
+
margin-bottom: var(--space-6);
1274
+
}
1275
+
1276
+
.delegation-container .subtitle {
1277
+
color: var(--text-secondary);
1278
+
margin: 0;
1279
+
line-height: 1.6;
1280
+
}
1281
+
1282
+
.oauth-error-page h1 {
1283
+
margin: 0 0 var(--space-6) 0;
1284
+
color: var(--error-text);
1285
+
}
1286
+
1287
+
.error-box {
1288
+
padding: var(--space-6);
1289
+
background: var(--error-bg);
1290
+
margin-bottom: var(--space-6);
1291
+
}
1292
+
1293
+
.error-code {
1294
+
font-family: var(--font-mono);
1295
+
font-size: var(--text-base);
1296
+
color: var(--error-text);
1297
+
margin-bottom: var(--space-2);
1298
+
}
1299
+
1300
+
.error-description {
1301
+
color: var(--text-secondary);
1302
+
font-size: var(--text-sm);
1303
+
}
1304
+
1305
+
.oauth-error-page .actions {
1306
+
display: flex;
1307
+
gap: var(--space-3);
1308
+
justify-content: center;
1309
+
}
1310
+
1311
+
.oauth-register-container {
1312
+
max-width: var(--width-lg);
1313
+
}
1314
+
1315
+
.oauth-register-container .loading,
1316
+
.oauth-register-container .creating {
1317
+
display: flex;
1318
+
flex-direction: column;
1319
+
align-items: center;
1320
+
gap: var(--space-4);
1321
+
padding: var(--space-8);
1322
+
}
1323
+
1324
+
.oauth-register-container .loading p,
1325
+
.oauth-register-container .creating p {
1326
+
color: var(--text-secondary);
1327
+
}
1328
+
1329
+
.oauth-register-container .page-header {
1330
+
margin-bottom: var(--space-6);
1331
+
}
1332
+
1333
+
.oauth-register-container .page-header h1 {
1334
+
margin: 0 0 var(--space-2) 0;
1335
+
}
1336
+
1337
+
.oauth-register-container form {
1338
+
display: flex;
1339
+
flex-direction: column;
1340
+
gap: var(--space-5);
1341
+
}
1342
+
1343
+
.oauth-register-container .actions {
1344
+
display: flex;
1345
+
gap: var(--space-4);
1346
+
margin-top: var(--space-2);
1347
+
}
1348
+
1349
+
.secondary-actions {
1350
+
display: flex;
1351
+
justify-content: center;
1352
+
gap: var(--space-4);
1353
+
margin-top: var(--space-4);
1354
+
}
1355
+
1356
+
.oauth-register-container fieldset {
1357
+
border: 1px solid var(--border-color);
1358
+
padding: var(--space-4);
1359
+
}
1360
+
1361
+
.oauth-register-container legend {
1362
+
padding: 0 var(--space-2);
1363
+
font-weight: var(--font-medium);
1364
+
}
1365
+
1366
+
.sso-register-container {
1367
+
max-width: var(--width-lg);
1368
+
}
1369
+
1370
+
.sso-register-container .loading {
1371
+
padding: var(--space-8);
1372
+
}
1373
+
1374
+
.sso-register-container .page-header {
1375
+
margin-bottom: var(--space-6);
1376
+
}
1377
+
1378
+
.sso-register-container .page-header h1 {
1379
+
margin: 0 0 var(--space-3) 0;
1380
+
}
1381
+
1382
+
.sso-register-container .form-section {
1383
+
min-width: 0;
1384
+
}
1385
+
1386
+
.sso-register-container form {
1387
+
display: flex;
1388
+
flex-direction: column;
1389
+
gap: var(--space-5);
1390
+
}
1391
+
1392
+
.sso-register-container .provider-info {
1393
+
margin-bottom: var(--space-6);
1394
+
}
1395
+
1396
+
.sso-register-container button[type="submit"] {
1397
+
margin-top: var(--space-3);
1398
+
}
1399
+
1400
+
.color-pair {
1401
+
display: flex;
1402
+
gap: var(--space-2);
1403
+
align-items: center;
1404
+
}
1405
+
1406
+
.color-pair input[type="color"] {
1407
+
width: 40px;
1408
+
height: 36px;
1409
+
padding: 2px;
1410
+
cursor: pointer;
1411
+
flex-shrink: 0;
1412
+
}
1413
+
1414
+
.color-pair input[type="text"] {
1415
+
flex: 1;
1416
+
}
1417
+
1418
+
.swatch {
1419
+
padding: var(--space-3) var(--space-4);
1420
+
margin-bottom: var(--space-2);
1421
+
font-size: var(--text-xs);
1422
+
}
1423
+
1424
+
.spacing-row {
1425
+
display: flex;
1426
+
flex-wrap: wrap;
1427
+
gap: var(--space-5);
1428
+
align-items: flex-end;
1429
+
}
1430
+
1431
+
.spacing-item {
1432
+
display: flex;
1433
+
flex-direction: column;
1434
+
align-items: center;
1435
+
gap: var(--space-2);
1436
+
}
1437
+
1438
+
.spacing-box {
1439
+
background: var(--accent);
1440
+
min-width: 2px;
1441
+
min-height: 2px;
1442
+
}
1443
+
1444
+
.key-choice-step {
1445
+
display: flex;
1446
+
flex-direction: column;
1447
+
gap: var(--space-4);
1448
+
}
1449
+
1450
+
.key-choice-options {
1451
+
display: flex;
1452
+
flex-direction: column;
1453
+
gap: var(--space-3);
1454
+
}
1455
+
1456
+
.key-choice-btn {
1457
+
display: flex;
1458
+
flex-direction: column;
1459
+
align-items: flex-start;
1460
+
gap: var(--space-2);
1461
+
padding: var(--space-5);
1462
+
background: var(--bg-card);
1463
+
text-align: left;
1464
+
cursor: pointer;
1465
+
}
1466
+
1467
+
.key-choice-btn:hover:not(:disabled) {
1468
+
border-color: var(--secondary);
1469
+
}
1470
+
1471
+
.key-choice-btn:disabled {
1472
+
opacity: 0.6;
1473
+
cursor: not-allowed;
1474
+
}
1475
+
1476
+
.key-choice-title {
1477
+
font-weight: var(--font-semibold);
1478
+
color: var(--text-primary);
1479
+
}
1480
+
1481
+
.key-choice-desc {
1482
+
font-size: var(--text-sm);
1483
+
color: var(--text-secondary);
1484
+
}
1485
+
1486
+
.key-choice-step .loading {
1487
+
text-align: center;
1488
+
color: var(--text-secondary);
1489
+
}
1490
+
1491
+
.did-doc-step {
1492
+
display: flex;
1493
+
flex-direction: column;
1494
+
gap: var(--space-4);
1495
+
}
1496
+
1497
+
.did-doc-step .warning-box {
1498
+
padding: var(--space-5);
1499
+
background: var(--warning-bg);
1500
+
font-size: var(--text-sm);
1501
+
}
1502
+
1503
+
.did-doc-step .warning-box strong {
1504
+
display: block;
1505
+
margin-bottom: var(--space-3);
1506
+
color: var(--warning-text);
1507
+
}
1508
+
1509
+
.did-doc-step .warning-box p {
1510
+
margin: 0;
1511
+
color: var(--warning-text);
1512
+
}
1513
+
1514
+
.did-url {
1515
+
display: block;
1516
+
margin-top: var(--space-3);
1517
+
padding: var(--space-3);
1518
+
background: var(--bg-input);
1519
+
font-size: var(--text-sm);
1520
+
word-break: break-all;
1521
+
}
1522
+
1523
+
.did-doc-display {
1524
+
background: var(--bg-card);
1525
+
overflow: hidden;
1526
+
}
1527
+
1528
+
.did-doc-code {
1529
+
margin: 0;
1530
+
padding: var(--space-4);
1531
+
background: var(--bg-input);
1532
+
font-size: var(--text-xs);
1533
+
overflow-x: auto;
1534
+
white-space: pre;
1535
+
max-height: 300px;
1536
+
overflow-y: auto;
1537
+
}
1538
+
1539
+
.did-doc-step .copy-btn {
1540
+
width: 100%;
1541
+
margin: 0;
1542
+
padding: var(--space-3) var(--space-5);
1543
+
font-size: var(--text-sm);
1544
+
}
1545
+
1546
+
.verification-step {
1547
+
display: flex;
1548
+
flex-direction: column;
1549
+
gap: var(--space-4);
1550
+
}
1551
+
1552
+
.verification-step .info-text {
1553
+
color: var(--text-secondary);
1554
+
margin: 0;
1555
+
}
1556
+
1557
+
.verification-step .info-text.waiting {
1558
+
font-size: var(--text-sm);
1559
+
}
1560
+
1561
+
.verification-step .info-text code {
1562
+
font-family: var(--font-mono, monospace);
1563
+
background: var(--bg-secondary);
1564
+
padding: 0.1em 0.3em;
1565
+
}
1566
+
1567
+
.code-input {
1568
+
font-family: var(--font-mono, monospace);
1569
+
font-size: var(--text-base);
1570
+
letter-spacing: 0.05em;
1571
+
}
1572
+
1573
+
.verification-step .hint {
1574
+
display: block;
1575
+
color: var(--text-secondary);
1576
+
font-size: var(--text-sm);
1577
+
margin-top: var(--space-1);
1578
+
}
History
1 round
0 comments
oyster.cafe
submitted
#0
1 commit
expand
collapse
refactor(frontend): extract auth and registration page styles + pages.css
expand 0 comments
pull request successfully merged