blankify

Passwords are dying - this passkey login is the future 🔑 #css #html #passkey #password #coding

Source Code

index.html
<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Sign in with a passkey</title>
  <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;700;800&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <main class="card">
    <div class="scanner">
      <img src="fingerprint.svg" />
    </div>
    <h1 class="title">Sign in with a passkey</h1>
    <p class="subtitle">Use your fingerprint or face - no password to remember.</p>
    <button class="primary">🔑 Continue with passkey</button>
    <a class="secondary" href="#">Use a password instead</a>
    <p class="trust">🔒 End-to-end encrypted</p>
  </main>
  <script src="script.js" type="text/javascript"></script>
</body>
</html>
styles.css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Plus Jakarta Sans", sans-serif;
  background: radial-gradient(70% 50% at 50% 14%, rgba(249, 115, 22, 0.22), transparent 60%), #06070b;
}

.card {
  width: 350px;
  padding: 42px 34px;
  text-align: center;
  background: linear-gradient(180deg, #141823, #0b0e16);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 26px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55);
}

.scanner {
  position: relative;
  width: 112px;
  height: 112px;
  margin: 0 auto 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1.5px solid rgba(251, 146, 60, 0.45);
  background: radial-gradient(circle, rgba(249, 115, 22, 0.22), transparent 70%);
  box-shadow: 0 0 44px -6px rgba(249, 115, 22, 0.55);
}

.scanner img {
  filter: drop-shadow(0 0 8px rgba(249, 115, 22, 0.6));
}

.title {
  font-size: 24px;
  font-weight: 800;
  color: #f2f5fa;
}

.subtitle {
  margin: 10px auto 28px;
  max-width: 290px;
  font-size: 14px;
  line-height: 1.5;
  color: #939cad;
}

.primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  padding: 15px;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  color: #1c0a02;
  background: linear-gradient(135deg, #fdba74, #f97316 55%, #ea580c);
  border: none;
  border-radius: 14px;
  cursor: pointer;
  transition: filter 0.3s;
}

.primary:hover {
  filter: brightness(1.08);
}

.secondary {
  display: inline-block;
  margin-top: 18px;
  font-size: 13.5px;
  font-weight: 600;
  color: #8b94a3;
  text-decoration: none;
}

.trust {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 26px;
  padding-top: 20px;
  font-size: 12px;
  color: #6f7888;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.scanner::after {
  content: "";
  position: absolute;
  inset: -9px;
  border-radius: 50%;
  border: 1px solid rgba(249, 115, 22, 0.16);
}
script.js
// Passkey continue flow - simulates a successful WebAuthn ceremony.
const button = document.querySelector(".primary");

button.addEventListener("click", () => {
  button.disabled = true;
  button.textContent = "Verifying...";

  // In a real app this is navigator.credentials.get({ publicKey }).
  setTimeout(() => {
    button.textContent = "Verified ✓";
    button.style.background = "linear-gradient(135deg, #4ade80, #16a34a)";
    button.style.color = "#03130a";
  }, 1100);
});