<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Aquiles-Image Playground</title>
  <link rel="icon" href="https://res.cloudinary.com/dmtomxyvm/image/upload/v1765043556/aqui_kyhcn8.png" type="image/png">

  <style>
    @font-face {
      font-family: 'GeistPixel';
      font-weight: 400;
      font-style: normal;
      font-display: swap;
      src:
        url('https://cdn.jsdelivr.net/npm/geist@1.7.0/dist/fonts/geist-pixel/GeistPixel-Square.woff2') format('woff2'),
    }
  </style>

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/fontsource/fonts/geist-mono@latest/index.css" />

  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.23.10/babel.min.js"></script>

  <style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    :root {
      --bg:       #0f0f0f;
      --fg:       #ede9df;
      --accent:   #ea580c;
      --muted:    rgba(237,233,223,0.42);
      --border:   rgba(237,233,223,0.75);
      --border-lt: rgba(237,233,223,0.13);
      --card-bg:  #141414;
    }

    html, body {
      min-height: 100vh;
      background-color: var(--bg);
      /* Dot grid */
      background-image: radial-gradient(circle, rgba(237,233,223,0.12) 1px, transparent 1px);
      background-size: 24px 24px;
      font-family: 'Geist Mono', monospace;
      color: var(--fg);
    }

    #root {
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 40px 16px;
    }

    /* ── Section label ── */
    .section-label {
      display: flex;
      align-items: center;
      gap: 14px;
      width: 100%;
      max-width: 440px;
      margin-bottom: 20px;
      animation: fadeUp .5s cubic-bezier(0.22,1,0.36,1) .05s both;
    }
    .section-label span {
      font-size: 9px;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--muted);
      white-space: nowrap;
    }
    .section-label .line {
      flex: 1;
      height: 1px;
      background: var(--border-lt);
    }

    /* ── Card ── */
    .card {
      width: 100%;
      max-width: 440px;
      border: 2px solid var(--border);
      background: var(--card-bg);
      animation: fadeUp .65s cubic-bezier(0.22,1,0.36,1) .15s both;
    }

    /* ── Card header (terminal bar) ── */
    .card-header {
      display: flex;
      align-items: center;
      gap: 8px;
      border-bottom: 2px solid var(--border);
      padding: 10px 16px;
    }
    .dot-orange { width: 8px; height: 8px; background: var(--accent); flex-shrink: 0; }
    .dot-solid  { width: 8px; height: 8px; background: var(--fg); flex-shrink: 0; }
    .dot-empty  { width: 8px; height: 8px; border: 1px solid var(--fg); flex-shrink: 0; }
    .card-header-label {
      margin-left: auto;
      font-size: 9px;
      letter-spacing: .18em;
      text-transform: uppercase;
      color: var(--muted);
    }

    /* ── Title ── */
    .title-wrap {
      padding: 28px 24px 20px;
      border-bottom: 2px solid var(--border);
    }
    .title {
      font-family: 'GeistPixel', 'Geist Mono', monospace;
      font-size: clamp(1.6rem, 6vw, 2.2rem);
      font-weight: 400;
      line-height: 1.1;
      letter-spacing: .02em;
      color: var(--fg);
      image-rendering: pixelated;
      -webkit-font-smoothing: none;
      animation: glitch 6s infinite;
    }
    /* ── Form body ── */
    .card-body {
      padding: 24px;
    }

    /* ── Field ── */
    .field {
      display: flex;
      flex-direction: column;
      gap: 7px;
      margin-bottom: 18px;
    }
    .field-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    .field-label {
      font-size: 9px;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--muted);
      user-select: none;
    }
    .field-tag {
      font-size: 9px;
      letter-spacing: .1em;
      color: var(--accent);
    }

    .field-input {
      background: transparent;
      border: 1px solid var(--border-lt);
      border-left: 2px solid var(--border);
      color: var(--fg);
      padding: 11px 13px;
      font-family: 'Geist Mono', monospace;
      font-size: 13px;
      letter-spacing: .04em;
      width: 100%;
      outline: none;
      transition: border-color .18s ease, background .18s ease;
    }
    .field-input::placeholder { color: rgba(13,13,13,0.22); }
    .field-input:focus {
      border-color: var(--fg);
      border-left-color: var(--accent);
      background: rgba(13,13,13,0.03);
    }

    /* ── Error ── */
    .error {
      display: flex;
      align-items: flex-start;
      gap: 10px;
      border-left: 2px solid var(--accent);
      padding: 10px 14px;
      font-size: 11px;
      letter-spacing: .04em;
      color: var(--accent);
      background: rgba(234,88,12,.06);
      margin-bottom: 18px;
      animation: slideIn .25s ease both;
    }
    .error-code {
      font-size: 9px;
      letter-spacing: .12em;
      color: var(--accent);
      opacity: .6;
      flex-shrink: 0;
      padding-top: 1px;
    }

    /* ── Button ── */
    .btn-wrap {
      width: 100%;
    }
    .btn {
      width: 100%;
      display: flex;
      align-items: center;
      background: var(--fg);
      color: var(--bg);
      border: none;
      font-family: 'Geist Mono', monospace;
      font-size: 11px;
      font-weight: 500;
      letter-spacing: .16em;
      text-transform: uppercase;
      cursor: pointer;
      transition: opacity .15s ease;
      padding: 0;
    }
    .btn:hover:not(:disabled) { opacity: .88; }
    .btn:disabled { opacity: .3; cursor: not-allowed; }

    .btn-icon {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 44px;
      height: 44px;
      background: var(--accent);
      flex-shrink: 0;
      font-size: 18px;
      line-height: 1;
      color: #fff;
    }
    .btn-text {
      padding: 0 18px;
      height: 44px;
      display: flex;
      align-items: center;
    }

    .blink { animation: blink 1s step-end infinite; }

    /* ── Footer ── */
    .footer {
      margin-top: 20px;
      text-align: center;
      font-size: 9px;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--muted);
      animation: fadeUp .65s cubic-bezier(0.22,1,0.36,1) .4s both;
    }
    .footer a {
      color: var(--fg);
      text-decoration: none;
      transition: color .15s;
    }
    .footer a:hover { color: var(--accent); }

    /* ── Keyframes ── */
    @keyframes fadeUp {
      from { opacity: 0; transform: translateY(16px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    @keyframes slideIn {
      from { opacity: 0; transform: translateX(-6px); }
      to   { opacity: 1; transform: translateX(0); }
    }
    @keyframes blink {
      0%, 100% { opacity: 1; }
      50%       { opacity: 0; }
    }
    @keyframes glitch {
      0%, 88%, 100% { transform: translate(0); filter: none; }
      90% { transform: translate(-2px, 1px); filter: hue-rotate(80deg); }
      92% { transform: translate(2px, -1px); filter: hue-rotate(-80deg); }
      94% { transform: translate(-1px, 0); filter: none; }
      96% { transform: translate(1px, 2px); filter: hue-rotate(40deg); }
    }
  </style>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
    function LoginApp() {
      const [username, setUsername] = React.useState("");
      const [password, setPassword] = React.useState("");
      const [error,    setError]    = React.useState("");
      const [loading,  setLoading]  = React.useState(false);
      const [tick,     setTick]     = React.useState(0);

      React.useEffect(() => {
        const id = setInterval(() => setTick(t => t + 1), 2000);
        return () => clearInterval(id);
      }, []);

      async function handleSubmit(e) {
        e.preventDefault();
        setLoading(true);
        setError("");

        const body = new FormData();
        body.append("username", username.trim());
        body.append("password", password);

        try {
          const res = await fetch("/token", {
            method: "POST",
            body,
            redirect: "follow",
          });

          if (res.redirected) { window.location.href = res.url; return; }
          if (res.ok)          { window.location.href = "/";    return; }

          const data = await res.json().catch(() => ({}));
          setError(data.detail || "Invalid credentials.");
        } catch (_) {
          setError("Connection error. Please try again.");
        } finally {
          setLoading(false);
        }
      }

      const canSubmit = username.trim().length > 0 && password.length > 0 && !loading;

      return (
        <div>
          {/* Section label */}
          <div className="section-label">
            <span>{"// AUTH: LOGIN_SYS"}</span>
            <div className="line" />
            <span>{`TICK:${String(tick).padStart(4, "0")}`}</span>
          </div>

          {/* Card */}
          <div className="card">

            {/* Terminal header bar */}
            <div className="card-header">
              <div className="dot-orange" />
              <div className="dot-solid" />
              <div className="dot-empty" />
              <span className="card-header-label">aquiles.auth.sys</span>
            </div>

            {/* Title */}
            <div className="title-wrap">
              <h1 className="title">AQUILES-IMAGE<br />PLAYGROUND</h1>
            </div>

            {/* Form */}
            <div className="card-body">
              <form onSubmit={handleSubmit}>

                <div className="field">
                  <div className="field-row">
                    <label htmlFor="username" className="field-label">Username</label>
                    <span className="field-tag">USR_IDENT</span>
                  </div>
                  <input
                    id="username"
                    type="text"
                    className="field-input"
                    placeholder="your_username"
                    autoComplete="username"
                    value={username}
                    onChange={e => setUsername(e.target.value)}
                    required
                  />
                </div>

                <div className="field">
                  <div className="field-row">
                    <label htmlFor="password" className="field-label">Password</label>
                    <span className="field-tag">SEC_KEY</span>
                  </div>
                  <input
                    id="password"
                    type="password"
                    className="field-input"
                    placeholder="••••••••"
                    autoComplete="current-password"
                    value={password}
                    onChange={e => setPassword(e.target.value)}
                    required
                  />
                </div>

                {error && (
                  <div className="error" role="alert">
                    <span className="error-code">ERR_401</span>
                    <span>{error}</span>
                  </div>
                )}

                <div className="btn-wrap">
                  <button type="submit" className="btn" disabled={!canSubmit}>
                    <span className="btn-icon">→</span>
                    <span className="btn-text">
                      {loading ? (
                        <span>Verifying<span className="blink">_</span></span>
                      ) : "Sign In"}
                    </span>
                  </button>
                </div>

              </form>
            </div>

          </div>

          {/* Footer */}
          <p className="footer">
            Powered by{" "}
            <a href="https://github.com/Aquiles-ai" target="_blank" rel="noopener noreferrer">
              Aquiles-ai
            </a>
          </p>
        </div>
      );
    }

    ReactDOM.createRoot(document.getElementById("root")).render(<LoginApp />);
  </script>
</body>
</html>