Lemmy – Quick Sign In Mockup

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Lemmy – Join the Fediverse</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="styles.css" />
</head>
<body>

<!-- LANDING -->
<section id="landing" class="page active">
  <img class="logo" src="https://join-lemmy.org/logo.svg" alt="Lemmy logo" />

  <h1 class="brand">Lemmy</h1>

  <p class="tagline">
    A <span class="accent">community-owned</span> social network<br />
    for the <span class="accent">fediverse</span>.
  </p>

  <div class="cta">
    <button class="btn btn-primary" id="quickSignIn">
      Quick Sign In
    </button>
    <button class="btn btn-secondary" id = "setupWizard">
      Use Setup Wizard
    </button>
  </div>
</section>

<!-- SIGNUP -->
<section id="signup" class="page">
  <h1 class="brand small">Join the Fediverse</h1>

  <form class="signup-form">

    <label>
      Choose a Username
      <input type="text" placeholder="yourname" required />
    </label>

    <label>
      Enter your Email Address <span class="optional">(optional)</span>
      <input type="email" placeholder="[email protected]" />
    </label>

    <label>
      Choose a Password
      <input type="password" id="password" required />
      <div class="strength-meter">
        <div id="strengthBar"></div>
      </div>
      <div id="strengthText" class="strength-text">Strength: —</div>
    </label>

    <label>
      Choose a Server
      <select id="serverSelect"></select>
    </label>

    <p class="helper">
      A server was randomly chosen for you. Don’t worry, it doesn’t matter
      which one you choose first and you can always change servers later.
    </p>

  <button type="submit" class="btn btn-primary giant full">
  Join the Fediverse
</button>

  </form>
</section>

<script src="script.js"></script>
</body>
</html>

CSS

:root {
  --bg: #0b0f0d;
  --bg-soft: #121816;
  --text: #e9fff1;
  --muted: #9fd9b6;
  --primary: #63ff9b;
  --primary-strong: #38e27d;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: radial-gradient(circle at top, #0f1a14, #050706);
  color: var(--text);
  font-family: system-ui, -apple-system, BlinkMacSystemFont,
    "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif;
  overflow-x: hidden;
}

/* Pages */

.page {
  max-width: 760px;
  margin: 0 auto;
  padding: 4.5rem 1.5rem 4rem;
  text-align: center;
  display: none;
}

.page.active {
  display: block;
}

/* Logo */

.logo {
  width: 140px;
  margin-bottom: 2rem;
  filter: drop-shadow(0 0 20px rgba(99,255,155,.25));
}

/* Brand */

.brand {
  font-size: 3.4rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--primary);
  text-shadow:
    0 0 12px rgba(99,255,155,.8),
    0 0 50px rgba(99,255,155,.4);
  animation: glowPulse 3s ease-in-out infinite;
}

.brand.small {
  font-size: 2.6rem;
}

/* Tagline */

.tagline {
  margin-top: 1.5rem;
  font-size: 1.4rem;
  line-height: 1.45;
}

.accent {
  color: var(--primary);
  font-weight: 700;
  text-shadow: 0 0 12px rgba(99,255,155,.6);
}

/* CTA */

.cta {
  margin-top: 3.2rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  align-items: center;
}

/* Buttons */

.btn {
  position: relative;
  min-width: 320px;
  padding: 1.1rem 2rem;
  border-radius: 10px;
  border: none;
  cursor: pointer;
  font-size: 1.15rem;
  overflow: hidden;
  transition: transform .15s ease;
}

.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--primary-strong));
  color: #052312;
  font-weight: 700;
  font-size: 1.3rem;
  box-shadow:
    0 0 30px rgba(99,255,155,.6),
    0 0 60px rgba(99,255,155,.4);
}

.btn-secondary {
  background: var(--bg-soft);
  color: var(--text);
  border: 1px solid...

JavaScript

const servers = [
  "lemmy.today",
  "discuss.online",
  "lemmy.world",
  "random.lemmy"
];

const landing = document.getElementById("landing");
const signup = document.getElementById("signup");
const quickSignIn = document.getElementById("quickSignIn");
const setupWizardBtn = document.getElementById("setupWizard");

const serverSelect = document.getElementById("serverSelect");
const passwordInput = document.getElementById("password");
const strengthBar = document.getElementById("strengthBar");
const strengthText = document.getElementById("strengthText");

/* Page switching */

quickSignIn.addEventListener("click", () => {
  landing.classList.remove("active");
  signup.classList.add("active");
});

/* Setup Wizard alert */

setupWizardBtn.addEventListener("click", () => {
  alert("This will open up the usual 'Join a Server' wizard.");
});

/* Populate & randomize server */

servers.forEach(server => {
  const option = document.createElement("option");
  option.value = server;
  option.textContent = server;
  serverSelect.appendChild(option);
});

serverSelect.value =
  servers[Math.floor(Math.random() * servers.length)];

/* Password strength meter */

passwordInput.addEventListener("input", e => {
  const password = e.target.value;
  let strength = 0;

  if (password.length > 7) strength++;
  if (/[A-Z]/.test(password)) strength++;
  if (/[0-9]/.test(password)) strength++;
  if (/[^A-Za-z0-9]/.test(password)) strength++;

  const levels = [
    { w: "25%", c: "red", t: "Weak" },
    { w: "50%", c: "orange", t: "Fair" },
    { w: "75%", c: "yellow", t: "Good" },
    { w: "100%", c: "lime", t: "Strong" }
  ];

  if (strength === 0) {
    strengthBar.style.width = "0%";
    strengthText.textContent = "Strength: —";
  } else {
    const l = levels[strength - 1];
    strengthBar.style.width = l.w;
    strengthBar.style.background = l.c;
    strengthText.textContent = `Strength: ${l.t}`;
  }
});