Registry testing - part 4

This commit is contained in:
mdecimus
2026-03-14 20:39:25 +01:00
parent 65a5900e7b
commit 4b5688fd57
28 changed files with 1448 additions and 922 deletions

View File

@@ -0,0 +1,283 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Sign in</title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0
}
:root {
--bg: #f5f5f4;
--card: #fff;
--border: #e5e5e3;
--text: #1a1a18;
--muted: #6b6b67;
--accent: #1a1a18;
--accent-fg: #fff;
--info: #185fa5;
--radius: 10px;
--input-bg: #fafaf9;
}
@media(prefers-color-scheme:dark) {
:root {
--bg: #18181b;
--card: #1f1f23;
--border: #2e2e33;
--text: #f4f4f2;
--muted: #9b9b95;
--accent: #f4f4f2;
--accent-fg: #18181b;
--info: #5faee3;
--input-bg: #2a2a2e;
}
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0.5rem 2.25rem 2rem;
width: 100%;
max-width: 384px;
}
.logo {
display: block;
width: calc(100% + 1rem);
height: auto;
margin: -0.25rem auto 0.1rem;
max-width: 320px
}
.logo .wordmark {
fill: var(--text)
}
.logo .symbol {
fill: #db2d54
}
h1 {
font-size: 1.125rem;
font-weight: 600;
letter-spacing: -.015em;
margin-bottom: .25rem
}
.sub {
font-size: .8125rem;
color: var(--muted);
margin-bottom: 1.75rem
}
.alert {
display: flex;
align-items: flex-start;
gap: .625rem;
padding: .625rem .75rem;
background: color-mix(in srgb, #db2d54 10%, transparent);
border: 1px solid color-mix(in srgb, #db2d54 30%, transparent);
border-radius: 8px;
font-size: .8125rem;
color: #a0192f;
margin-bottom: .25rem;
}
@media(prefers-color-scheme:dark) {
.alert {
color: #f4839a
}
}
.alert svg {
flex-shrink: 0;
margin-top: 1px
}
.fields {
display: flex;
flex-direction: column;
gap: .875rem
}
.field label {
font-size: .75rem;
font-weight: 500;
color: var(--muted);
letter-spacing: .03em;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: .3125rem;
}
.field label a {
font-weight: 400;
color: var(--info);
text-decoration: none
}
.field label a:hover {
text-decoration: underline
}
input[type=text],
input[type=password],
input[type=email] {
width: 100%;
padding: .5625rem .75rem;
font-size: .9375rem;
font-family: inherit;
background: var(--input-bg);
border: 1px solid var(--border);
border-radius: 8px;
color: var(--text);
outline: none;
transition: border-color .15s;
-webkit-appearance: none;
}
input[type=text]:focus,
input[type=password]:focus,
input[type=email]:focus {
border-color: color-mix(in srgb, var(--info) 60%, transparent);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--info) 12%, transparent);
}
input[type=text]::placeholder,
input[type=password]::placeholder,
input[type=email]::placeholder {
color: var(--muted);
opacity: .7
}
#otp {
letter-spacing: .2em;
font-size: 1.0625rem;
text-align: center;
font-variant-numeric: tabular-nums
}
.remember {
display: flex;
align-items: center;
gap: .5rem;
padding: .125rem 0
}
.remember input[type=checkbox] {
width: 1rem;
height: 1rem;
flex-shrink: 0;
cursor: pointer;
accent-color: var(--accent);
}
.remember label {
font-size: .8125rem;
color: var(--muted);
cursor: pointer;
user-select: none
}
.btn {
width: 100%;
margin-top: .375rem;
padding: .625rem 0;
font-size: .9375rem;
font-weight: 500;
font-family: inherit;
background: var(--accent);
color: var(--accent-fg);
border: none;
border-radius: 8px;
cursor: pointer;
letter-spacing: -.01em;
transition: opacity .15s;
}
.btn:hover {
opacity: .88
}
.btn:active {
opacity: .75;
transform: scale(.99)
}
</style>
</head>
<body>
<div class="card">
<svg class="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 680.5 252.1" aria-label="Logo">
<path class="wordmark"
d="M227.8 143.6c.3 4.2 2.1 7.6 5.1 10.1 3.1 2.5 7.1 3.8 12.1 3.8 4.3 0 7.9-.9 10.5-2.8 2.7-1.9 4-4.5 4-7.8 0-2.4-.7-4.3-2.2-5.7-1.5-1.4-3.4-2.5-6-3.2-2.5-.7-6-1.5-10.6-2.3-4.6-.8-8.6-1.9-11.9-3.2-3.3-1.3-6-3.3-8.1-6.1-2.1-2.7-3.1-6.3-3.1-10.7 0-4.1 1.1-7.7 3.2-10.9s5.1-5.7 9-7.4c3.8-1.8 8.2-2.6 13.2-2.6 5.1 0 9.6 1 13.7 2.9 4 1.9 7.2 4.5 9.5 7.8s3.6 7.1 3.8 11.4h-11.5c-.4-3.7-2-6.6-4.8-8.9-2.8-2.2-6.3-3.4-10.6-3.4-4.1 0-7.5.9-9.9 2.7-2.5 1.8-3.7 4.3-3.7 7.6 0 2.3.7 4.1 2.2 5.5 1.5 1.4 3.4 2.4 5.9 3.1 2.4.7 5.9 1.4 10.5 2.2 4.6.8 8.6 1.9 11.9 3.3 3.3 1.4 6 3.4 8.2 6 2.1 2.6 3.2 6.1 3.2 10.5 0 4.2-1.1 8-3.4 11.3-2.2 3.3-5.4 5.9-9.4 7.8-4 1.9-8.6 2.8-13.7 2.8-5.6 0-10.6-1-14.9-3.1-4.3-2-7.6-4.9-10-8.5-2.4-3.6-3.7-7.8-3.7-12.5l11.5.3zM278.5 102.1l11-2.1v14.6h12.6v9.7h-12.6v27.2c0 2 .4 3.5 1.2 4.3.8.9 2.2 1.3 4.2 1.3h8.4v9.7h-10.6c-5 0-8.6-1.2-10.8-3.5-2.2-2.3-3.4-5.9-3.4-10.7v-50.5zM356.8 114.6v52.2h-9.7l-1.2-7.9c-1.8 2.6-4.2 4.7-7 6.2-2.9 1.6-6.2 2.3-10 2.3-4.8 0-9-1.1-12.7-3.2-3.7-2.1-6.7-5.2-8.8-9.3-2.1-4-3.2-8.8-3.2-14.2 0-5.3 1.1-10 3.2-14s5.1-7.2 8.8-9.4c3.7-2.2 7.9-3.3 12.6-3.3 3.9 0 7.2.7 10.1 2.2 2.9 1.5 5.2 3.5 6.9 6.1l1.3-7.6h9.7zm-15.1 38.7c2.8-3.2 4.2-7.3 4.2-12.4 0-5.2-1.4-9.4-4.2-12.6-2.8-3.3-6.5-4.9-11-4.9-4.6 0-8.2 1.6-11 4.8-2.8 3.2-4.2 7.4-4.2 12.5 0 5.2 1.4 9.4 4.2 12.6 2.8 3.2 6.5 4.8 11 4.8s8.2-1.6 11-4.8zM365.5 97.5l11-2.1v71.3h-11V97.5zM380.3 114.6h11.6l11.9 39.9 11.9-39.9h10.1l11.4 39.9 12.3-39.9h11.2l-17.3 52.2h-11.8l-11-35.5-11.4 35.5-11.9.1-17-52.3zM513.7 114.6v52.2H504l-1.2-7.9c-1.8 2.6-4.2 4.7-7 6.2-2.9 1.6-6.2 2.3-10 2.3-4.8 0-9-1.1-12.7-3.2-3.7-2.1-6.7-5.2-8.8-9.3-2.1-4-3.2-8.8-3.2-14.2 0-5.3 1.1-10 3.2-14s5.1-7.2 8.8-9.4c3.7-2.2 7.9-3.3 12.6-3.3 3.9 0 7.2.7 10.1 2.2 2.9 1.5 5.2 3.5 6.9 6.1l1.3-7.6h9.7zm-15.1 38.7c2.8-3.2 4.2-7.3 4.2-12.4 0-5.2-1.4-9.4-4.2-12.6-2.8-3.3-6.5-4.9-11-4.9-4.6 0-8.2 1.6-11 4.8-2.8 3.2-4.2 7.4-4.2 12.5 0 5.2 1.4 9.4 4.2 12.6 2.8 3.2 6.5 4.8 11 4.8 4.6 0 8.2-1.6 11-4.8zM551.3 114.6v10.3h-4.9c-4.6 0-7.8 1.5-9.9 4.4-2 3-3.1 6.7-3.1 11.3v26.2h-11v-52.2h9.8l1.2 7.8c1.5-2.4 3.4-4.4 5.8-5.8 2.4-1.4 5.6-2.1 9.6-2.1h2.5zM556.3 102.1l11-2.1v14.6h12.6v9.7h-12.6v27.2c0 2 .4 3.5 1.2 4.3.8.9 2.2 1.3 4.2 1.3h8.4v9.7h-10.6c-5 0-8.6-1.2-10.8-3.5s-3.4-5.9-3.4-10.7v-50.5z" />
<path class="symbol"
d="M149.1 84.7h-4.8l-44.8 25.9v8.3l44.8 25.9h4.8l44.8-25.9v-8.3l-44.8-25.9zm32.9 30h-35.3V94.4l35.3 20.3zm-35.3 20.4-35.3-20.4 27-15.6v20.2l6.3 3.6h22.9l-20.9 12.2zM99.5 129.9v11l44.8 25.9h4.8l44.8-25.9v-11l-47.2 27.3zM187.3 166.8l6.6-3.8v-11l-25.7 14.8zM99.5 163l6.6 3.8h19.1L99.5 152z" />
</svg>
<h1>Sign in</h1>
<p class="sub">Enter your credentials to continue</p>
<div class="alert" id="login-error" hidden aria-live="polite">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
<span id="login-error-msg">Invalid username or password. Please try again.</span>
</div>
<form class="fields" method="post" action="/oauth/login">
<div class="field">
<label for="username">Username</label>
<input id="username" name="username" type="text" placeholder="you@example.com" autocomplete="username"
required>
</div>
<div class="field">
<label for="password">
Password
<a href="/forgot">Forgot password?</a>
</label>
<input id="password" name="password" type="password" placeholder="••••••••"
autocomplete="current-password" required>
</div>
<div class="field">
<label for="otp">One-time code <span style="font-weight:400;opacity:.6">(optional)</span></label>
<input id="otp" name="otp" type="text" placeholder="000000" maxlength="6" inputmode="numeric"
pattern="\d{6}" autocomplete="one-time-code">
</div>
<div class="remember">
<input type="checkbox" id="remember" name="remember" value="1">
<label for="remember">Remember me for 30 days</label>
</div>
<button type="submit" class="btn">Sign in</button>
</form>
</div>
<script>
document.getElementById('otp').addEventListener('input', function () {
this.value = this.value.replace(/\D/g, '');
if (this.value.length === 6) document.querySelector('.btn').focus();
});
</script>
</body>
</html>