Files
derez.ai/add.html
T

656 lines
28 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add Agent — Derez.ai</title>
<meta name="robots" content="noindex, nofollow" />
<style>
/* ═══════════════════════════════════════════════════════════════
DESIGN TOKENS (matches app.derez.ai design system)
═══════════════════════════════════════════════════════════════ */
:root {
--bg: #000810;
--bg-card: #010f20;
--bg-inner: #000d1a;
--bg-hover: #001a30;
--bg-input: #000813;
--border: #0a3060;
--border-hi: rgba(0,245,255,0.45);
--accent: #00f5ff;
--accent-dim: #002535;
--danger: #ff3b3b;
--danger-dim: #3b0000;
--success: #00ff88;
--warning: #ffaa00;
--text: #c8f0ff;
--text-muted: #2e6a80;
--radius: 8px;
--radius-card: 18px;
--shadow: 0 0 0 1px rgba(0,245,255,0.25), 0 0 60px rgba(0,245,255,0.12), 0 28px 72px rgba(0,0,0,0.9);
--max-width: 1120px;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
scroll-behavior: smooth;
-webkit-font-smoothing: antialiased;
}
body {
font-family: "Courier New", Courier, monospace;
background: var(--bg);
color: var(--text);
font-size: 14px;
line-height: 1.6;
overflow-x: hidden;
}
/* Ambient glow */
body::before {
content: "";
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 60% 50% at 25% 30%, rgba(0, 245, 255, 0.06) 0%, transparent 70%),
radial-gradient(ellipse 50% 60% at 75% 70%, rgba(0, 200, 255, 0.04) 0%, transparent 70%);
pointer-events: none;
z-index: 0;
}
h1, h2, h3, h4 { font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
h2 { font-size: clamp(1.6rem, 3.5vw, 2.4rem); margin-bottom: 0.6em; }
p { color: var(--text-muted); font-size: 14px; }
.container {
max-width: var(--max-width);
margin: 0 auto;
padding: 0 24px;
position: relative;
z-index: 1;
}
/* ── Buttons ─────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 22px;
border-radius: var(--radius);
border: none;
cursor: pointer;
font-size: 14px;
font-weight: 600;
white-space: nowrap;
text-decoration: none;
transition: opacity 0.15s, background 0.15s, transform 0.1s;
}
.btn:hover { opacity: 0.85; text-decoration: none; }
.btn:active { transform: scale(0.97); }
.btn-primary {
background: transparent;
color: #fff;
border: 1px solid var(--accent);
box-shadow: 0 0 8px rgba(0,245,255,0.35), inset 0 0 8px rgba(0,245,255,0.04);
}
.btn-primary:hover {
background: rgba(0,245,255,0.08);
box-shadow: 0 0 14px rgba(0,245,255,0.5), inset 0 0 10px rgba(0,245,255,0.06);
}
.btn-lg {
padding: 12px 28px;
font-size: 13px;
border-radius: 8px;
}
.btn-block {
width: 100%;
justify-content: center;
}
/* ══════════════════════════════════════════════════════════
PRICING (1:1 copy from index.html)
══════════════════════════════════════════════════════════ */
section {
padding: 80px 0;
}
.section-title {
text-align: center;
max-width: 640px;
margin: 0 auto 16px;
}
.section-sub {
text-align: center;
max-width: 560px;
margin: 0 auto 50px;
font-size: 1rem;
}
.pricing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
max-width: 960px;
margin: 0 auto;
}
.pricing-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-card);
padding: 36px 28px;
text-align: center;
box-shadow: var(--shadow);
position: relative;
transition: border-color 0.2s, transform 0.2s;
display: flex;
flex-direction: column;
}
.pricing-card.featured {
border-color: var(--accent);
background: linear-gradient(180deg, rgba(0, 245, 255, 0.05) 0%, var(--bg-card) 100%);
transform: scale(1.04);
}
.pricing-perks {
list-style: none;
text-align: left;
margin: 14px 0 24px;
flex: 1;
}
.pricing-card .btn-block {
margin-top: auto;
}
.pricing-badge {
position: absolute;
top: -11px;
left: 50%;
transform: translateX(-50%);
background: var(--accent);
color: #000;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 3px 18px;
border-radius: 20px;
}
.pricing-badge-coupon {
display: none;
font-size: 12px;
font-weight: 700;
color: #f59e0b;
background: rgba(245, 158, 11, 0.1);
border: 1px solid rgba(245, 158, 11, 0.25);
border-radius: 6px;
padding: 3px 10px;
margin-top: 8px;
margin-bottom: 4px;
line-height: 1.4;
letter-spacing: 0.02em;
}
.pricing-badge-coupon.visible { display: inline-block; }
.pricing-badge-coupon.free {
color: #22c55e;
background: rgba(34, 197, 94, 0.1);
border-color: rgba(34, 197, 94, 0.25);
}
.pricing-plan-name {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--accent);
margin-bottom: 6px;
}
.pricing-amount {
font-size: 3rem;
font-weight: 800;
color: var(--text);
line-height: 1;
}
.pricing-amount .pricing-currency { font-size: 1.4rem; vertical-align: super; }
.pricing-period {
font-size: 0.9rem;
font-weight: 500;
color: var(--text-muted);
}
.pricing-yearly-bonus {
display: none;
font-size: 12px;
color: var(--success);
font-weight: 600;
margin-top: 4px;
}
.pricing-yearly-bonus.show { display: block; }
.pricing-plan-desc {
font-size: 12px;
color: var(--text-muted);
margin: 10px 0 14px;
line-height: 1.5;
}
.pricing-plan-quota {
font-size: 13px;
font-weight: 600;
color: var(--text);
padding: 8px 0;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
margin-bottom: 14px;
}
.pricing-perks li {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 4px 0;
font-size: 13px;
color: var(--text);
}
.pricing-perks li svg {
flex-shrink: 0;
margin-top: 3px;
color: var(--text-muted);
}
.pricing-perks li .plus-icon {
color: var(--success);
font-weight: 700;
font-size: 15px;
line-height: 1;
margin-top: 3px;
flex-shrink: 0;
}
.pricing-perks li.new-feature { color: var(--text); }
/* ── Config box ─────────────────────────────── */
.pricing-config-box {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
margin-bottom: 36px;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-card);
padding: 14px 24px;
flex-wrap: wrap;
}
.pricing-config-label {
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
white-space: nowrap;
}
.pricing-config-select {
appearance: none;
-webkit-appearance: none;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
padding: 6px 30px 6px 12px;
cursor: pointer;
outline: none;
transition: border-color 0.2s;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 8px center;
min-width: 110px;
}
.pricing-config-select:hover { border-color: var(--accent); }
.pricing-config-select:focus { border-color: var(--accent); }
.pricing-config-input {
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
padding: 6px 12px;
outline: none;
transition: border-color 0.2s;
width: 120px;
}
.pricing-config-input:focus { border-color: var(--accent); }
.pricing-config-input::placeholder { color: var(--text-muted); opacity: 0.6; }
#pricing-email { width: 156px; }
#pricing-email.invalid { border-color: var(--danger); box-shadow: 0 0 0 2px rgba(255, 59, 59, 0.2); }
.pricing-toast {
position: fixed;
bottom: 100px;
left: 50%;
transform: translateX(-50%) translateY(20px);
background: var(--bg-card);
border: 1px solid var(--danger);
border-radius: var(--radius-card);
padding: 16px 24px;
box-shadow: 0 8px 32px rgba(0,0,0,0.3);
font-size: 14px;
color: var(--text);
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
z-index: 9999;
max-width: 420px;
text-align: center;
pointer-events: none;
}
.pricing-toast.show {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(0);
}
@media (max-width: 900px) {
.pricing-grid { grid-template-columns: 1fr; max-width: 420px; }
.pricing-card.featured { transform: none; }
}
</style>
</head>
<body>
<section id="pricing">
<div class="container">
<!-- ── Config: agent, billing, location ── -->
<div class="pricing-config-box">
<span class="pricing-config-label">Configure and buy your agent</span>
<select class="pricing-config-select" id="pricing-agent">
<option value="hermes" selected>Hermes</option>
</select>
<select class="pricing-config-select" id="pricing-period">
<option value="monthly">Monthly</option>
<option value="yearly" selected>Yearly</option>
</select>
<select class="pricing-config-select" id="pricing-location">
<option value="france">France</option>
</select>
<input type="email" class="pricing-config-input" id="pricing-email" placeholder="Email" autocomplete="email" />
<input type="text" class="pricing-config-input" id="pricing-coupon" placeholder="Coupon code" />
<input type="hidden" id="utm_source" />
<input type="hidden" id="utm_medium" />
<input type="hidden" id="utm_campaign" />
<input type="hidden" id="utm_term" />
<input type="hidden" id="utm_content" />
</div>
<!-- ── Plans grid ── -->
<div class="pricing-grid">
<!-- Trainee -->
<div class="pricing-card">
<div class="pricing-plan-name">Trainee</div>
<div class="pricing-amount" id="amount-trainee">
<span class="pricing-currency">$</span>4<span class="pricing-decimal">.99</span>
</div>
<div class="pricing-period" id="period-trainee">/ month</div>
<div class="pricing-badge-coupon" id="badge-trainee">First Month <span class="badge-price"></span></div>
<div class="pricing-yearly-bonus" id="bonus-trainee">✨ +$4.99 OpenRouter credits</div>
<p class="pricing-plan-desc">For getting started with your first agent.</p>
<div class="pricing-plan-quota">1GB RAM &middot; 10GB HDD</div>
<ul class="pricing-perks">
<li class="new-feature">
<span class="plus-icon">+</span>
Your Agent's Office
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Management dashboard
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Daily automatic backups
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
OpenRouter key included
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Prompt Builder &amp; Skills
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Support chat with human escalation
</li>
</ul>
<button class="btn btn-primary btn-block" onclick="hireAgent('trainee')">Continue with Stripe</button>
</div>
<!-- Junior -->
<div class="pricing-card featured">
<span class="pricing-badge">Popular</span>
<div class="pricing-plan-name">Junior</div>
<div class="pricing-amount" id="amount-junior">
<span class="pricing-currency">$</span>9<span class="pricing-decimal">.50</span>
</div>
<div class="pricing-period" id="period-junior">/ month</div>
<div class="pricing-badge-coupon" id="badge-junior">First Month <span class="badge-price"></span></div>
<div class="pricing-yearly-bonus" id="bonus-junior">✨ +$9.50 OpenRouter credits</div>
<p class="pricing-plan-desc">The sweet spot for most users.</p>
<div class="pricing-plan-quota">2GB RAM &middot; 20GB HDD</div>
<ul class="pricing-perks">
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Your Agent's Office
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Management dashboard
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Daily automatic backups
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
OpenRouter key included
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Prompt Builder &amp; Skills
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Support chat with human escalation
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
SSH access to your container
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
On-demand backups
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Higher API key credit allocation
</li>
</ul>
<button class="btn btn-primary btn-block" onclick="hireAgent('junior')">Continue with Stripe</button>
</div>
<!-- Senior -->
<div class="pricing-card">
<div class="pricing-plan-name">Senior</div>
<div class="pricing-amount" id="amount-senior">
<span class="pricing-currency">$</span>17<span class="pricing-decimal">.50</span>
</div>
<div class="pricing-period" id="period-senior">/ month</div>
<div class="pricing-badge-coupon" id="badge-senior">First Month <span class="badge-price"></span></div>
<div class="pricing-yearly-bonus" id="bonus-senior">✨ +$17.50 OpenRouter credits</div>
<p class="pricing-plan-desc">For power users and teams.</p>
<div class="pricing-plan-quota">4GB RAM &middot; 40GB HDD</div>
<ul class="pricing-perks">
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Your Agent's Office
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Management dashboard
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Daily automatic backups
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
OpenRouter key included
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Prompt Builder &amp; Skills
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Support chat with human escalation
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
SSH access to your container
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
On-demand backups
</li>
<li>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Higher API key credit allocation
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Email access for your agent
</li>
<li class="new-feature">
<span class="plus-icon">+</span>
Highest API key credit allocation
</li>
</ul>
<button class="btn btn-primary btn-block" onclick="hireAgent('senior')">Continue with Stripe</button>
</div>
</div>
</div>
</section>
<div class="pricing-toast" id="pricing-toast"></div>
<script>
// ── Signup Webhook URLs (matching app.derez.ai) ──────────
const ORDER_WEBHOOK = "https://n8n.derez.ai/webhook/payment";
/* ── Period / billing update ──────────────────────────── */
function updatePeriodDisplay() {
const sel = document.getElementById('pricing-period');
const yearly = sel.value === 'yearly';
document.getElementById('bonus-trainee').classList.toggle('show', yearly);
document.getElementById('bonus-junior').classList.toggle('show', yearly);
document.getElementById('bonus-senior').classList.toggle('show', yearly);
document.getElementById('period-trainee').textContent = yearly ? '/ month ✦ yearly' : '/ month';
document.getElementById('period-junior').textContent = yearly ? '/ month ✦ yearly' : '/ month';
document.getElementById('period-senior').textContent = yearly ? '/ month ✦ yearly' : '/ month';
}
document.getElementById('pricing-period').addEventListener('change', updatePeriodDisplay);
updatePeriodDisplay();
/* ── Capture UTM params from URL ──────────────────────── */
(function () {
const params = new URLSearchParams(window.location.search);
['source', 'medium', 'campaign', 'term', 'content'].forEach(function (key) {
const val = params.get('utm_' + key);
if (val) document.getElementById('utm_' + key).value = val;
});
})();
/* ── Buy Agent Webhook ────────────────────────────────── */
function showPricingToast(msg) {
const el = document.getElementById('pricing-toast');
el.textContent = msg;
el.classList.add('show');
if (window._pricingToastTimer) clearTimeout(window._pricingToastTimer);
window._pricingToastTimer = setTimeout(function () {
el.classList.remove('show');
}, 20000);
}
async function hireAgent(product) {
const agent = document.getElementById('pricing-agent').value;
const period = document.getElementById('pricing-period').value;
const location = document.getElementById('pricing-location').value;
const email = document.getElementById('pricing-email').value.trim();
const coupon = document.getElementById('pricing-coupon').value.trim();
// Validate email
const emailInput = document.getElementById('pricing-email');
emailInput.classList.remove('invalid');
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
emailInput.classList.add('invalid');
showPricingToast('Please configure your agent and provide a valid email address.');
emailInput.focus();
return;
}
try {
const form = document.createElement('form');
form.method = 'POST';
form.action = ORDER_WEBHOOK;
form.target = '_self';
form.style.display = 'none';
const fields = {
product: product,
agent: agent,
period: period,
location: location,
email: email || '',
coupon: coupon || '',
utm_source: document.getElementById('utm_source').value || '',
utm_medium: document.getElementById('utm_medium').value || '',
utm_campaign: document.getElementById('utm_campaign').value || '',
utm_term: document.getElementById('utm_term').value || '',
utm_content: document.getElementById('utm_content').value || '',
};
Object.keys(fields).forEach(function (key) {
const inp = document.createElement('input');
inp.type = 'hidden';
inp.name = key;
inp.value = fields[key];
form.appendChild(inp);
});
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
} catch (err) {
console.error('Order webhook failed:', err);
}
}
/* ── Coupon Badges ──────────────────────────────────────── */
const COUPONS = { friends499: 499, creator950: 950, friends1750: 1750 };
const PLAN_PRICES = { trainee: 499, junior: 950, senior: 1750 };
function centsToDollar(c) { return '$' + (c / 100).toFixed(2); }
function updateCouponBadges() {
var code = document.getElementById('pricing-coupon').value.trim().toLowerCase();
var discount = COUPONS[code];
['trainee','junior','senior'].forEach(function(plan) {
var badge = document.getElementById('badge-' + plan);
if (discount !== undefined) {
var firstMonth = Math.max(0, PLAN_PRICES[plan] - discount);
badge.querySelector('.badge-price').textContent = centsToDollar(firstMonth);
badge.classList.add('visible');
if (firstMonth === 0) badge.classList.add('free');
else badge.classList.remove('free');
} else {
badge.classList.remove('visible', 'free');
badge.querySelector('.badge-price').textContent = '—';
}
});
}
document.getElementById('pricing-coupon').addEventListener('input', updateCouponBadges);
</script>
</body>
</html>