Our Personal Data Server from scratch! tranquil.farm
atproto pds rust postgresql fun oauth

refactor(frontend): extract auth and registration page styles + pages.css #64

merged opened by oyster.cafe targeting main from refactor/extract-scoped-styles
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:3fwecdnvtcscjnrx2p4n7alz/sh.tangled.repo.pull/3mhdc5fbv5z22
+1617 -848
Diff #0
+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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
··· 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
sign up or login to add to the discussion
oyster.cafe submitted #0
1 commit
expand
refactor(frontend): extract auth and registration page styles + pages.css
expand 0 comments
pull request successfully merged