Astraea v1.0 — multi-agent WA family-law assistant
Eight specialist agents over a 16-book verified WA law corpus (RAG with citations), per-user document vault, WA court-form PDF auto-fill, comms missions with DV safety guard, no-KYC auth, TTS. Self-hosted: Flask + SQLite + Ollama, stdlib-only RAG. Includes README, LICENSE (MIT + not-legal-advice notice), DEPLOY runbook, .gitignore.
This commit is contained in:
124
templates/landing.html
Normal file
124
templates/landing.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Astraea — Your Washington Divorce Attorney</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
background: #05070f; color: #e8edfb; overflow-x: hidden; -webkit-font-smoothing: antialiased;
|
||||
}
|
||||
.hero {
|
||||
position: relative; min-height: 100vh; display: flex; align-items: center;
|
||||
background: radial-gradient(1200px 700px at 50% -10%, #16224a 0%, #070b1a 60%, #05070f 100%);
|
||||
}
|
||||
.hero-bg { position: absolute; inset: 0; overflow: hidden; }
|
||||
.hero-bg img {
|
||||
width: 100%; height: 100%; object-fit: cover; opacity: .55;
|
||||
-webkit-mask-image: radial-gradient(ellipse at 50% 40%, #000 30%, transparent 75%);
|
||||
mask-image: radial-gradient(ellipse at 50% 40%, #000 30%, transparent 75%);
|
||||
}
|
||||
.hero-overlay { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(5,7,15,.35), rgba(5,7,15,.9) 80%, #05070f); }
|
||||
.wrap { position: relative; z-index: 2; width: 100%; max-width: 1180px; margin: 0 auto; padding: 40px 26px; }
|
||||
header { display: flex; align-items: center; justify-content: space-between; }
|
||||
.brand { display: flex; align-items: center; gap: 13px; }
|
||||
.logo { width: 46px; height: 46px; border-radius: 13px; background: linear-gradient(135deg,#6ea8ff,#a78bfa); display: grid; place-items: center; font-size: 24px; box-shadow: 0 0 26px rgba(124,155,255,.55); }
|
||||
.brand h1 { font-size: 24px; font-weight: 800; letter-spacing: .4px; }
|
||||
.brand h1 span { color: #f5d06f; }
|
||||
.pill { font-size: 12px; color: #aeb8d9; border: 1px solid #233055; padding: 6px 13px; border-radius: 999px; display: flex; align-items: center; gap: 7px; }
|
||||
.dot { width: 8px; height: 8px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 10px #4ade80; }
|
||||
|
||||
.hero-content { display: grid; grid-template-columns: 1.25fr .75fr; gap: 50px; align-items: center; padding: 60px 0 40px; }
|
||||
.left h2 { font-size: clamp(34px, 5vw, 60px); line-height: 1.05; font-weight: 800; letter-spacing: -1px; }
|
||||
.left h2 .grad { background: linear-gradient(90deg,#7dd3fc,#a78bfa,#f0abfc); -webkit-background-clip: text; background-clip: text; color: transparent; }
|
||||
.left .sub { color: #aeb8d9; font-size: 18px; line-height: 1.6; margin-top: 20px; max-width: 560px; }
|
||||
.left .sub b { color: #e8edfb; }
|
||||
.agents-row { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 26px; }
|
||||
.agent-chip { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; padding: 8px 13px; border-radius: 999px; border: 1px solid #233055; background: rgba(16,24,50,.6); }
|
||||
.cta-row { margin-top: 34px; display: flex; gap: 14px; flex-wrap: wrap; }
|
||||
.btn { border: none; border-radius: 13px; padding: 15px 28px; font-size: 16px; font-weight: 700; cursor: pointer; transition: transform .12s ease, box-shadow .2s ease; }
|
||||
.btn-primary { background: linear-gradient(135deg,#3b82f6,#6366f1); color: #fff; box-shadow: 0 10px 30px rgba(59,130,246,.4); }
|
||||
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 40px rgba(59,130,246,.55); }
|
||||
.btn-ghost { background: rgba(16,24,50,.6); color: #e8edfb; border: 1px solid #233055; }
|
||||
|
||||
.card {
|
||||
background: linear-gradient(180deg, rgba(20,29,61,.9), rgba(16,24,50,.85));
|
||||
border: 1px solid #233055; border-radius: 20px; padding: 28px;
|
||||
box-shadow: 0 30px 70px rgba(0,0,0,.5); backdrop-filter: blur(8px);
|
||||
}
|
||||
.card h3 { font-size: 20px; font-weight: 700; margin-bottom: 4px; }
|
||||
.card .hint { color: #8b98c4; font-size: 13px; margin-bottom: 20px; }
|
||||
.field { margin-bottom: 15px; }
|
||||
.field label { display: block; font-size: 12.5px; color: #aeb8d9; margin-bottom: 6px; }
|
||||
.field input { width: 100%; background: #0c142e; border: 1px solid #233055; color: #e8edfb; border-radius: 11px; padding: 12px 14px; font-size: 15px; outline: none; }
|
||||
.field input:focus { border-color: #6366f1; }
|
||||
.err { color: #fca5a5; font-size: 13px; margin-bottom: 12px; min-height: 18px; }
|
||||
.tabs { display: flex; gap: 4px; margin-bottom: 20px; background: #0c142e; border-radius: 11px; padding: 4px; }
|
||||
.tabs button { flex: 1; border: none; background: transparent; color: #8b98c4; padding: 10px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; }
|
||||
.tabs button.on { background: #1c2748; color: #e8edfb; }
|
||||
footer { text-align: center; padding: 20px 0 40px; color: #5a658a; font-size: 12.5px; }
|
||||
footer a { color: #8b98c4; }
|
||||
@media (max-width: 860px) { .hero-content { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hero">
|
||||
<div class="hero-bg"><img src="/static/hero.png" alt="Astraea"></div>
|
||||
<div class="hero-overlay"></div>
|
||||
<div class="wrap">
|
||||
<header>
|
||||
<div class="brand"><div class="logo">⚖️</div><div><h1>ASTRA<span>EA</span></h1></div></div>
|
||||
<div class="pill"><span class="dot"></span> Washington family law, on your side</div>
|
||||
</header>
|
||||
<div class="hero-content">
|
||||
<div class="left">
|
||||
<h2>Your personal<br><span class="grad">divorce attorney</span>,<br>reinvented.</h2>
|
||||
<p class="sub">Astraea is a constellation of <b>eight Washington State legal specialists</b> — grounded in the real Revised Code of Washington and <b>verified case law</b> — that give you sound legal advice on the facts, prep your court paperwork on demand, and even handle professional correspondence for you.</p>
|
||||
<div class="agents-row">
|
||||
{% for a in agents %}<div class="agent-chip">{{ a.emoji }} {{ a.name.split(' & ')[0].split(' ')[0] }}</div>{% endfor %}
|
||||
</div>
|
||||
<div class="cta-row">
|
||||
<button class="btn btn-primary" onclick="document.getElementById('auth').scrollIntoView({behavior:'smooth'})">Begin your case →</button>
|
||||
<button class="btn btn-ghost" onclick="window.location.href='/app'">I have an account</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" id="auth">
|
||||
<h3>Welcome back</h3>
|
||||
<div class="hint">No email, no verification. Just you and your counsel.</div>
|
||||
<div class="tabs">
|
||||
<button id="tabLogin" class="on" onclick="setTab('login')">Sign in</button>
|
||||
<button id="tabRegister" onclick="setTab('register')">Create account</button>
|
||||
</div>
|
||||
<div class="err" id="err"></div>
|
||||
<div class="field"><label>Username</label><input id="u" autocomplete="username"></div>
|
||||
<div class="field"><label>Password</label><input id="p" type="password" autocomplete="current-password"></div>
|
||||
<button class="btn btn-primary" style="width:100%" id="go">Sign in</button>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
Astraea provides practical legal guidance grounded in Washington statute and case law — not a substitute for a licensed attorney.
|
||||
<br><a href="https://buymeacoffee.com/r26xrthzttg" target="_blank" rel="noopener">☕ Support Astraea</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let mode = 'login';
|
||||
function setTab(m){ mode = m; document.getElementById('tabLogin').classList.toggle('on', m==='login'); document.getElementById('tabRegister').classList.toggle('on', m==='register'); document.getElementById('go').textContent = m==='login' ? 'Sign in' : 'Create account'; }
|
||||
async function go(){
|
||||
const u = document.getElementById('u').value.trim(), p = document.getElementById('p').value;
|
||||
const err = document.getElementById('err');
|
||||
if(!u || !p){ err.textContent = 'Enter a username and password.'; return; }
|
||||
const r = await fetch('/api/'+mode, {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({username:u, password:p})});
|
||||
const d = await r.json();
|
||||
if(!r.ok){ err.textContent = d.error || 'Something went wrong'; return; }
|
||||
localStorage.setItem('astraea_token', d.token);
|
||||
localStorage.setItem('astraea_user', d.username);
|
||||
window.location.href = '/app';
|
||||
}
|
||||
document.getElementById('go').onclick = go;
|
||||
document.getElementById('p').addEventListener('keydown', e => { if(e.key==='Enter') go(); });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user