<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Password Strength</title>
  <style>
    /* ── Reset & base ─────────────────────────────────────────── */
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    body {
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 28px;
      background: #0f1117;
      font-family: "Inter", "Segoe UI", system-ui, sans-serif;
      color: #e2e8f0;
    }

    /* ── Page header ──────────────────────────────────────────── */
    .page-header {
      text-align: center;
    }

    .page-header h1 {
      font-size: 1.75rem;
      font-weight: 700;
      letter-spacing: .01em;
      color: #e2e8f0;
      margin-bottom: 6px;
    }

    .page-header p {
      font-size: .875rem;
      color: #475569;
      letter-spacing: .02em;
    }

    /* ── Card ─────────────────────────────────────────────────── */
    .card {
      width: min(420px, 92vw);
      background: #1a1d27;
      border: 1px solid #2d3148;
      border-radius: 16px;
      padding: 40px 36px 36px;
      box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
    }

    .card h1 {
      font-size: 1.15rem;
      font-weight: 600;
      letter-spacing: .04em;
      color: #94a3b8;
      text-transform: uppercase;
      margin-bottom: 28px;
    }

    /* ── Input wrapper ────────────────────────────────────────── */
    .input-wrap {
      position: relative;
      margin-bottom: 22px;
    }

    .input-wrap input {
      width: 100%;
      padding: 14px 46px 14px 16px;
      border-radius: 10px;
      border: 1.5px solid #2d3148;
      background: #0f1117;
      color: #e2e8f0;
      font-size: 1rem;
      font-family: "JetBrains Mono", "Fira Code", monospace;
      letter-spacing: .05em;
      outline: none;
      transition: border-color .2s;
      caret-color: #818cf8;
    }

    .input-wrap input:focus {
      border-color: #818cf8;
    }

    /* eye toggle */
    .eye-btn {
      position: absolute;
      right: 12px;
      top: 50%;
      transform: translateY(-50%);
      background: none;
      border: none;
      cursor: pointer;
      color: #475569;
      display: flex;
      align-items: center;
      transition: color .2s;
    }
    .eye-btn:hover { color: #94a3b8; }

    /* ── Segmented bar ────────────────────────────────────────── */
    .bar-wrap {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 6px;
      margin-bottom: 20px;
    }

    .seg {
      height: 6px;
      border-radius: 99px;
      background: #2d3148;
      transition: background .35s ease, opacity .35s ease;
    }

    /* colour classes applied via JS */
    .seg.active-1 { background: #ef4444; }          /* red */
    .seg.active-2 { background: #f59e0b; }          /* amber */
    .seg.active-3 { background: #86efac; }          /* light green */
    .seg.active-4 { background: #16a34a; }          /* dark green */

    /* ── Score label ──────────────────────────────────────────── */
    .score-label {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
      margin-bottom: 18px;
      min-height: 22px;
    }

    .score-label .strength-text {
      font-size: .82rem;
      font-weight: 600;
      letter-spacing: .06em;
      text-transform: uppercase;
      transition: color .35s;
    }

    .score-label .crack-time {
      font-size: .78rem;
      color: #475569;
    }

    /* ── Feedback ─────────────────────────────────────────────── */
    .feedback {
      min-height: 40px;
      font-size: .82rem;
      color: #64748b;
      line-height: 1.55;
      transition: opacity .2s;
    }

    .feedback .warning {
      color: #f59e0b;
      margin-bottom: 4px;
    }

    .feedback .hint::before {
      content: "→ ";
      color: #475569;
    }
  </style>
</head>
<body>

<header class="page-header">
  <h1>Password Strength Evaluator</h1>
  <p>How hard would it be to crack your password?</p>
</header>

<div class="card">
  <h1>Password Strength</h1>

  <!-- Input -->
  <div class="input-wrap">
    <input
      id="pwd"
      type="password"
      placeholder="Enter a password…"
      autocomplete="off"
      spellcheck="false"
    />
    <button class="eye-btn" id="eye" aria-label="Show/hide password" type="button">
      <!-- eye-off icon (default: password hidden) -->
      <svg id="icon-off" width="18" height="18" viewBox="0 0 24 24" fill="none"
           stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
        <path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
        <line x1="1" y1="1" x2="23" y2="23"/>
      </svg>
      <!-- eye icon (shown when password is visible) -->
      <svg id="icon-on" width="18" height="18" viewBox="0 0 24 24" fill="none"
           stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
           style="display:none">
        <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
        <circle cx="12" cy="12" r="3"/>
      </svg>
    </button>
  </div>

  <!-- Segmented bar -->
  <div class="bar-wrap" id="bar">
    <div class="seg" id="s1"></div>
    <div class="seg" id="s2"></div>
    <div class="seg" id="s3"></div>
    <div class="seg" id="s4"></div>
  </div>

  <!-- Score label -->
  <div class="score-label">
    <span class="strength-text" id="strength-text"></span>
    <span class="crack-time"  id="crack-time"></span>
  </div>

  <!-- Feedback -->
  <div class="feedback" id="feedback"></div>
</div>

<script>
  const LABELS = ["", "Very weak", "Weak", "Fair", "Strong", "Very strong"];
  const COLORS = ["", "#ef4444", "#f59e0b", "#86efac", "#16a34a"];

  const input    = document.getElementById("pwd");
  const segments = [1,2,3,4].map(i => document.getElementById("s" + i));
  const strengthText = document.getElementById("strength-text");
  const crackTime    = document.getElementById("crack-time");
  const feedback     = document.getElementById("feedback");
  const eye          = document.getElementById("eye");
  const iconOff      = document.getElementById("icon-off");
  const iconOn       = document.getElementById("icon-on");

  // ── Eye toggle ────────────────────────────────────────────────
  eye.addEventListener("click", () => {
    const hidden = input.type === "password";
    input.type = hidden ? "text" : "password";
    iconOff.style.display = hidden ? "none"  : "";
    iconOn.style.display  = hidden ? ""      : "none";
    input.focus();
  });

  // ── Debounce ─────────────────────────────────────────────────
  let timer = null;
  input.addEventListener("input", () => {
    clearTimeout(timer);
    timer = setTimeout(evaluate, 120);
  });

  // ── Evaluate ─────────────────────────────────────────────────
  async function evaluate() {
    const pwd = input.value;

    if (!pwd) {
      reset();
      return;
    }

    const res  = await fetch("/evaluate", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ password: pwd }),
    });
    const data = await res.json();

    const score = data.score;          // 0-4
    // zxcvbn score 0 → treat as 1 segment visually when something is typed
    const visual = pwd.length > 0 ? Math.max(score, 1) : 0;

    updateBar(visual);
    updateLabel(visual, data.crack_time);
    updateFeedback(data.warning, data.suggestions);
  }

  function updateBar(visual) {
    segments.forEach((seg, idx) => {
      // Remove all active classes
      seg.className = "seg";
      if (idx < visual) {
        seg.classList.add("active-" + visual);
      }
    });
  }

  function updateLabel(visual, crack) {
    strengthText.textContent = visual ? LABELS[visual] : "";
    strengthText.style.color = visual ? COLORS[visual] : "";
    crackTime.textContent    = crack  ? `~${crack} to crack` : "";
  }

  function updateFeedback(warning, suggestions) {
    let html = "";
    if (warning)
      html += `<div class="warning">${warning}</div>`;
    suggestions.forEach(s => {
      html += `<div class="hint">${s}</div>`;
    });
    feedback.innerHTML = html;
  }

  function reset() {
    segments.forEach(s => s.className = "seg");
    strengthText.textContent = "";
    crackTime.textContent    = "";
    feedback.innerHTML       = "";
  }
</script>
</body>
</html>
