also looking at this
fix(ui): align component theme and login step visibility
#39
4 files
+163
-77
| @@ -37,74 +37,78 @@ const signedIn = session.user !== null | ||
| 37 | 37 | {{-- A real form, so a password manager recognises it and the enter key |
| 38 | 38 | submits. The script intercepts it; without the script it still |
| 39 | 39 | posts somewhere sensible rather than nowhere. --}} |
| 40 | <form id="signin" method="post" action="/api/auth/login" class="grid gap-4"> | |
| 41 | <label class="block"> | |
| 42 | <span class="block mb-1 text-muted text-sm">Email</span> | |
| 43 | <input | |
| 44 | id="email" | |
| 45 | name="email" | |
| 46 | type="email" | |
| 47 | autocomplete="username" | |
| 48 | required | |
| 49 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error" | |
| 50 | /> | |
| 51 | </label> | |
| 52 | ||
| 53 | <label class="block"> | |
| 54 | <span class="block mb-1 text-muted text-sm">Password</span> | |
| 55 | <input | |
| 56 | id="password" | |
| 57 | name="password" | |
| 58 | type="password" | |
| 59 | autocomplete="current-password" | |
| 60 | required | |
| 61 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error" | |
| 62 | /> | |
| 63 | </label> | |
| 64 | ||
| 65 | {{-- Off by default: a shared machine should not opt into a month-long | |
| 66 | session by accident. Checked lengthens the session to 30 days; | |
| 67 | unchecked is the one-week baseline. --}} | |
| 68 | <label class="flex gap-2 items-center text-muted text-sm cursor-pointer select-none"> | |
| 69 | <input id="remember" name="remember" type="checkbox" class="h-4 w-4 accent-accent" /> | |
| 70 | <span>Keep me signed in for 30 days</span> | |
| 71 | </label> | |
| 72 | ||
| 73 | <p id="error" class="text-sm text-warn" role="alert" hidden></p> | |
| 74 | ||
| 75 | <button | |
| 76 | id="submit" | |
| 77 | type="submit" | |
| 78 | class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60" | |
| 79 | >Sign in</button> | |
| 40 | <form id="signin" method="post" action="/api/auth/login"> | |
| 41 | <div class="grid gap-4"> | |
| 42 | <label class="block"> | |
| 43 | <span class="block mb-1 text-muted text-sm">Email</span> | |
| 44 | <input | |
| 45 | id="email" | |
| 46 | name="email" | |
| 47 | type="email" | |
| 48 | autocomplete="username" | |
| 49 | required | |
| 50 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error" | |
| 51 | /> | |
| 52 | </label> | |
| 53 | ||
| 54 | <label class="block"> | |
| 55 | <span class="block mb-1 text-muted text-sm">Password</span> | |
| 56 | <input | |
| 57 | id="password" | |
| 58 | name="password" | |
| 59 | type="password" | |
| 60 | autocomplete="current-password" | |
| 61 | required | |
| 62 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" aria-describedby="error" | |
| 63 | /> | |
| 64 | </label> | |
| 65 | ||
| 66 | {{-- Off by default: a shared machine should not opt into a month-long | |
| 67 | session by accident. Checked lengthens the session to 30 days; | |
| 68 | unchecked is the one-week baseline. --}} | |
| 69 | <label class="flex gap-2 items-center text-muted text-sm cursor-pointer select-none"> | |
| 70 | <input id="remember" name="remember" type="checkbox" class="h-4 w-4 accent-accent" /> | |
| 71 | <span>Keep me signed in for 30 days</span> | |
| 72 | </label> | |
| 73 | ||
| 74 | <p id="error" class="text-sm text-warn" role="alert" hidden></p> | |
| 75 | ||
| 76 | <button | |
| 77 | id="submit" | |
| 78 | type="submit" | |
| 79 | class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60" | |
| 80 | >Sign in</button> | |
| 81 | </div> | |
| 80 | 82 | </form> |
| 81 | 83 | |
| 82 | 84 | {{-- Second step, revealed only when the account has 2FA enabled. Dormant |
| 83 | 85 | until an enrollment surface ships, but present so a 2FA account can |
| 84 | 86 | never sign in halfway and stall. --}} |
| 85 | <form id="twofa" method="post" action="/api/auth/verify-two-factor-login" class="grid gap-4" hidden> | |
| 86 | <h2 class="font-semibold text-lg tracking-tight">Two-factor code</h2> | |
| 87 | <p class="-mt-2 text-muted text-sm">Enter the 6-digit code from your authenticator app.</p> | |
| 88 | <label class="block"> | |
| 89 | <span class="block mb-1 text-muted text-sm">Authentication code</span> | |
| 90 | <input | |
| 91 | id="code" | |
| 92 | name="code" | |
| 93 | type="text" | |
| 94 | inputmode="numeric" | |
| 95 | autocomplete="one-time-code" | |
| 96 | maxlength="6" | |
| 97 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" | |
| 98 | /> | |
| 99 | </label> | |
| 100 | ||
| 101 | <p id="twofa-error" class="text-sm text-warn" role="alert" hidden></p> | |
| 102 | ||
| 103 | <button | |
| 104 | id="twofa-submit" | |
| 105 | type="submit" | |
| 106 | class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60" | |
| 107 | >Verify and sign in</button> | |
| 87 | <form id="twofa" method="post" action="/api/auth/verify-two-factor-login" hidden> | |
| 88 | <div class="grid gap-4"> | |
| 89 | <h2 class="font-semibold text-lg tracking-tight">Two-factor code</h2> | |
| 90 | <p class="-mt-2 text-muted text-sm">Enter the 6-digit code from your authenticator app.</p> | |
| 91 | <label class="block"> | |
| 92 | <span class="block mb-1 text-muted text-sm">Authentication code</span> | |
| 93 | <input | |
| 94 | id="code" | |
| 95 | name="code" | |
| 96 | type="text" | |
| 97 | inputmode="numeric" | |
| 98 | autocomplete="one-time-code" | |
| 99 | maxlength="6" | |
| 100 | class="px-3 py-2 w-full text-ink text-sm bg-panel border border-line rounded-lg" | |
| 101 | /> | |
| 102 | </label> | |
| 103 | ||
| 104 | <p id="twofa-error" class="text-sm text-warn" role="alert" hidden></p> | |
| 105 | ||
| 106 | <button | |
| 107 | id="twofa-submit" | |
| 108 | type="submit" | |
| 109 | class="px-4 py-2.5 font-medium text-accent-ink text-sm bg-accent rounded-lg disabled:opacity-60" | |
| 110 | >Verify and sign in</button> | |
| 111 | </div> | |
| 108 | 112 | </form> |
| 109 | 113 | |
| 110 | 114 | <p class="mt-6 text-muted text-sm"> |