108 lines
4.3 KiB
Cheetah
108 lines
4.3 KiB
Cheetah
{{define "page"}}
|
|
<div class="checkout-wrapper">
|
|
<div class="checkout-card glass fade-in">
|
|
<span class="label accent">Get started</span>
|
|
<h1 style="margin-top:0.5rem">Your vault awaits</h1>
|
|
|
|
<div class="price-display">
|
|
<span class="price-amount">$12</span>
|
|
<span class="price-period">/year</span>
|
|
</div>
|
|
<div class="price-note">
|
|
30-day money-back guarantee. No questions asked.
|
|
</div>
|
|
|
|
<hr class="divider">
|
|
|
|
<ul class="feature-list">
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
Zero-knowledge encryption — we cannot read your vault
|
|
</li>
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
Field-level AI visibility — agents see what you allow
|
|
</li>
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
23 global regions — pick where your data lives
|
|
</li>
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
WebAuthn PRF — hardware key is the only key
|
|
</li>
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
FIPS 140-3 certified cryptography
|
|
</li>
|
|
<li>
|
|
<svg class="check" viewBox="0 0 16 16" width="16" height="16"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 1 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" fill="currentColor"/></svg>
|
|
MCP, CLI, browser extension, REST API
|
|
</li>
|
|
</ul>
|
|
|
|
<hr class="divider">
|
|
|
|
<form id="checkout-form" onsubmit="return startCheckout(event)">
|
|
<div class="field">
|
|
<label for="checkout-email">Email address</label>
|
|
<input type="email" id="checkout-email" class="input" placeholder="you@example.com" required autocomplete="email" autofocus>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary btn-block btn-lg" id="checkout-btn">
|
|
Continue to payment
|
|
</button>
|
|
</form>
|
|
|
|
<div class="login-footer">
|
|
Already have an account? <a href="{{.Base}}/login">Sign in</a>
|
|
</div>
|
|
|
|
<div style="text-align:center;margin-top:1rem">
|
|
<span style="font-size:0.75rem;color:var(--text-secondary)">
|
|
Payments processed by Stripe. Cancel anytime.
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "scripts"}}
|
|
<script>
|
|
async function startCheckout(e) {
|
|
e.preventDefault();
|
|
const email = document.getElementById('checkout-email').value;
|
|
const btn = document.getElementById('checkout-btn');
|
|
btn.disabled = true;
|
|
btn.textContent = 'Redirecting to Stripe…';
|
|
|
|
try {
|
|
const resp = await fetch('{{.Base}}/api/checkout', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email })
|
|
});
|
|
if (!resp.ok) throw new Error('Could not start checkout');
|
|
const { url } = await resp.json();
|
|
window.location.href = url;
|
|
} catch (err) {
|
|
showToast(err.message, 'error');
|
|
btn.disabled = false;
|
|
btn.textContent = 'Continue to payment';
|
|
}
|
|
}
|
|
|
|
function showToast(msg, type) {
|
|
let t = document.querySelector('.toast');
|
|
if (!t) {
|
|
t = document.createElement('div');
|
|
t.className = 'toast';
|
|
document.body.appendChild(t);
|
|
}
|
|
t.textContent = msg;
|
|
t.className = 'toast ' + type;
|
|
requestAnimationFrame(() => t.classList.add('show'));
|
|
setTimeout(() => t.classList.remove('show'), type === 'error' ? 6000 : 3000);
|
|
}
|
|
</script>
|
|
{{end}}
|