<!doctype html>
<meta charset="utf-8">
<title>DDNS Login</title>
<script src="https://cdn.tailwindcss.com"></script>
<body class="min-h-screen flex items-center justify-center bg-gradient-to-br
from-sky-100 to-indigo-100 dark:from-gray-800 dark:to-gray-900
text-gray-800 dark:text-gray-100 antialiased">
<form id="f"
class="w-full max-w-sm space-y-5 bg-white/80 dark:bg-gray-800/80
backdrop-blur-xl p-8 rounded-2xl shadow-xl border
border-gray-200 dark:border-gray-700">
<h1 class="text-2xl font-bold text-center flex items-center justify-center gap-2">
<svg class="w-6 h-6 text-sky-600" fill="none" stroke="currentColor" stroke-width="2"
viewBox="0 0 24 24"><path d="M12 2v20M2 12h20"/></svg>
DDNS Login
</h1>
<div class="space-y-1">
<label class="text-sm font-medium">Username</label>
<input name="username" required
class="input w-full" placeholder="admin">
</div>
<div class="space-y-1">
<label class="text-sm font-medium">Password</label>
<input name="password" type="password" required
class="input w-full" placeholder="•••••••">
</div>
<button
class="w-full py-2 rounded-lg bg-sky-600 text-white font-medium hover:bg-sky-700
transition">Sign in</button>
<p id="err" class="text-center text-rose-500 text-sm hidden">Login failed</p>
</form>
<style>
.input{ @apply border border-gray-300 dark:border-gray-600/70 rounded-lg
px-3 py-2 bg-white/70 dark:bg-gray-700/40 outline-none
focus:ring-2 focus:ring-sky-500/50 transition;}
</style>
<script>
document.getElementById('f').addEventListener('submit', async e => {
e.preventDefault();
const fd = Object.fromEntries(new FormData(e.target));
const r = await fetch('/api/login', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(fd)
});
if (r.ok) {
location.replace('/');
} else {
document.getElementById('err').classList.remove('hidden');
setTimeout(()=>document.getElementById('err').classList.add('hidden'), 3000);
}
});
</script>
</body>