{% extends 'base.html' %}
{% block title %}Sign in — AgentForms{% endblock %}
{% block head_extra %}
<style nonce="{{ csp_nonce }}">
main {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 40px 24px;
}
.login-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 40px;
width: 100%;
max-width: 420px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
}
.login-card h1 {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
text-align: center;
color: var(--text);
letter-spacing: -0.02em;
}
.login-card .subtitle {
color: var(--text-muted);
text-align: center;
margin-bottom: 24px;
font-size: 14px;
}
.login-card .card-header {
text-align: center;
margin-bottom: 24px;
}
.login-card .card-header .logo {
font-size: 28px;
font-weight: 700;
color: var(--text);
letter-spacing: -0.02em;
}
.login-card .card-header .logo span {
color: var(--accent);
}
.login-card input {
margin: 8px 0;
width: 100%;
padding: 12px 14px;
border: 1.5px solid #ddd;
border-radius: 6px;
font-size: 16px;
line-height: 1.4;
background: #fafafa;
transition: border-color 0.15s, box-shadow 0.15s;
min-height: 48px;
box-sizing: border-box;
}
.login-card input:focus {
outline: none;
border-color: #4F46E5;
background: #fff;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.login-card .btn {
width: 100%;
margin-top: 12px;
padding: 12px;
}
.login-card .btn-secondary {
background: var(--text-muted);
}
.login-card .btn-secondary:hover {
background: #555;
}
.error {
background: #fef2f2;
border: 1px solid #fecaca;
color: #991b1b;
padding: 10px 14px;
border-radius: 6px;
margin-bottom: 16px;
font-size: 13px;
}
.error ul {
margin: 4px 0 0 16px;
}
.success-msg {
background: var(--accent-dim);
border: 1px solid rgba(16, 185, 129, 0.2);
color: var(--accent-bright);
padding: 10px 14px;
border-radius: 6px;
margin-bottom: 16px;
font-size: 13px;
text-align: center;
}
.remember {
display: flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-size: 13px;
color: var(--text-muted);
}
.remember input {
width: auto;
margin: 0;
accent-color: var(--accent);
}
.tabs {
display: flex;
margin-bottom: 24px;
border-bottom: 2px solid var(--border);
}
.tab {
flex: 1;
padding: 10px;
text-align: center;
cursor: pointer;
font-size: 14px;
font-weight: 500;
color: var(--text-muted);
border-bottom: 2px solid transparent;
margin-bottom: -2px;
transition: all 0.15s;
background: none;
border-top: none;
border-left: none;
border-right: none;
font-family: var(--font);
}
.tab:hover {
color: var(--text);
}
.tab.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.tab-content { display: none; }
.tab-content.active { display: block; }
.btn-github {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 12px;
background: #24292f;
color: white;
text-align: center;
text-decoration: none;
border-radius: 6px;
border: none;
cursor: pointer;
font-size: 14px;
font-weight: 600;
margin-top: 12px;
transition: background 0.15s;
font-family: var(--font);
}
.btn-github:hover {
background: #1f2328;
}
.divider {
display: flex;
align-items: center;
gap: 12px;
margin: 16px 0;
color: var(--text-dim);
font-size: 12px;
}
.divider::before, .divider::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.magic-hint {
font-size: 12px;
color: var(--text-muted);
text-align: center;
margin-top: 4px;
}
.auth-footer {
text-align: center;
font-size: 13px;
margin-top: 16px;
color: var(--text-muted);
}
.auth-footer a {
color: var(--accent);
font-weight: 500;
}
@media (max-width: 480px) {
.login-card {
padding: 24px;
border-radius: 8px;
}
.login-card h1 {
font-size: 20px;
}
}
</style>
{% endblock %}
{% block content %}
<main>
<div class="login-card">
<div class="card-header">
<div class="logo">Agent<span>Forms</span></div>
</div>
<h1>Sign in</h1>
<p class="subtitle">Access your form relay dashboard</p>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="{{ 'success-msg' if category == 'success' else 'error' }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% if errors %}
<div class="error">
<ul>
{% for e in errors %}<li>{{ e }}</li>{% endfor %}
</ul>
</div>
{% endif %}
<div class="tabs">
<button type="button" class="tab active" data-tab="password">Password</button>
<button type="button" class="tab" data-tab="magic">Magic Link</button>
</div>
<div class="tab-content active" id="tab-password">
<form method="POST" action="{{ url_for('auth.login') }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"/>
{% if next %}<input type="hidden" name="next" value="{{ next }}">{% endif %}
<input type="email" name="email" placeholder="Email" required value="{{ email or '' }}" autofocus aria-label="Email address">
<input type="password" name="password" placeholder="Password" required aria-label="Password">
<label class="remember">
<input type="checkbox" name="remember"> Remember me
</label>
<button type="submit" class="btn">Sign in</button>
</form>
</div>
<div class="tab-content" id="tab-magic">
<form method="POST" action="{{ url_for('auth.magic_login_request') }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"/>
<input type="email" name="email" placeholder="Email" required value="{{ email or '' }}" aria-label="Email address for magic link">
<button type="submit" class="btn">Send Login Link</button>
</form>
<p class="magic-hint">Check your inbox — link expires in 15 minutes</p>
</div>
<div class="divider">or</div>
<a href="/auth/github" class="btn-github">
<svg width="18" height="18" viewBox="0 0 16 16" fill="white">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
</svg>
Sign in with GitHub
</a>
<p class="auth-footer">Don't have an account? <a href="{{ url_for('auth.register') }}">Sign up</a></p>
</div>
</main>
{% endblock %}
{% block scripts %}
<script src="/static/js/login-inline.js"></script>
{% endblock %}