- robotsTxtUrl
- https://tryaibridge.com/
- exists
- true
- rawRobotsTxt
- <!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="/logo.png"><link rel="shortcut icon" href="/logo.png"><link rel="apple-touch-icon" href="/logo.png">
<title>AI Bridge — Fai parlare le AI tra loro</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--bg:#0A0A0F;--surface:#12121A;--surface2:#1A1A2E;--border:#2A2A4A;
--text:#F0F0F5;--text-dim:#7070A0;--yellow:#E8E040;--yellow-dim:rgba(232,224,64,0.08);
--claude:#C97B4B;--gpt:#4B9FC9;--gemini:#4BC99B;--grok:#C94B9B;--deepseek:#9BC94B;
}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--text);font-family:'Inter',sans-serif;line-height:1.6;overflow-x:hidden}
/* NAV */
nav{position:fixed;top:0;left:0;right:0;z-index:100;padding:20px 48px;display:flex;align-items:center;justify-content:space-between;transition:all 0.4s}
nav.scrolled{background:rgba(10,10,15,0.94);backdrop-filter:blur(16px);border-bottom:1px solid var(--border)}
.nav-logo{font-family:'Syne',sans-serif;font-weight:800;font-size:18px;letter-spacing:-0.5px;color:var(--text);text-decoration:none;display:flex;align-items:center;gap:8px}
.nav-dot{width:7px;height:7px;border-radius:50%;background:var(--yellow);box-shadow:0 0 10px var(--yellow)}
.nav-links{display:flex;align-items:center;gap:32px}
.nav-links a{color:var(--text-dim);text-decoration:none;font-size:14px;transition:color 0.2s}
.nav-links a:hover{color:var(--text)}
.nav-cta{background:var(--yellow);color:#0A0A0F;padding:9px 20px;border-radius:6px;font-size:14px;font-weight:700;text-decoration:none;font-family:'Syne',sans-serif;transition:all 0.2s}
.nav-cta:hover{opacity:0.85;transform:translateY(-1px)}
.nav-burger{display:none;background:transparent;border:1px solid var(--border);color:var(--text);width:38px;height:38px;border-radius:6px;font-size:16px;cursor:pointer;align-items:center;justify-content:center;transition:border-color 0.2s}
.nav-burger:hover{border-color:var(--yellow)}
.mobile-menu{display:none}
.mobile-menu[data-open]{display:flex;flex-direction:column;position:fixed;top:64px;left:16px;right:16px;background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:12px;gap:2px;z-index:99;box-shadow:0 12px 32px rgba(0,0,0,0.5)}
.mobile-menu a,.mobile-menu button{color:var(--text-dim);text-decoration:none;font-size:15px;padding:12px 14px;border-radius:8px;transition:background 0.15s,color 0.15s;background:transparent;border:none;text-align:left;font-family:'Inter',sans-serif;cursor:pointer}
.mobile-menu a:hover,.mobile-menu button:hover{background:var(--surface2);color:var(--text)}
.mobile-menu .nav-cta{margin-top:6px;text-align:center}
/* HERO */
.hero{min-height:100vh;display:grid;grid-template-columns:1fr 1fr;align-items:center;padding:100px 48px 60px;gap:60px;max-width:1400px;margin:0 auto}
.hero-eyebrow{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--yellow);margin-bottom:24px;opacity:0;transform:translateY(10px);animation:fadeUp 0.6s 0.1s forwards}
.hero-title{font-family:'Syne',sans-serif;font-size:clamp(48px,6vw,82px);font-weight:800;line-height:1.0;letter-spacing:-2px;margin-bottom:28px;opacity:0;transform:translateY(16px);animation:fadeUp 0.7s 0.2s forwards}
.hero-title em{font-style:normal;color:var(--yellow)}
.hero-sub{font-size:17px;color:var(--text-dim);line-height:1.7;max-width:440px;margin-bottom:40px;opacity:0;transform:translateY(12px);animation:fadeUp 0.7s 0.35s forwards}
.hero-actions{display:flex;align-items:center;gap:20px;flex-wrap:wrap;opacity:0;animation:fadeUp 0.7s 0.5s forwards}
.btn-primary{background:var(--yellow);color:#0A0A0F;padding:14px 28px;border-radius:6px;font-size:15px;font-weight:700;text-decoration:none;font-family:'Syne',sans-serif;display:inline-flex;align-items:center;gap:8px;transition:all 0.2s}
.btn-primary:hover{opacity:0.85;transform:translateY(-2px)}
.btn-secondary{color:var(--text-dim);font-size:14px;text-decoration:none;display:flex;align-items:center;gap:6px;transition:all 0.2s}
.btn-secondary:hover{color:var(--text)}
.btn-secondary .arr{transition:transform 0.2s;display:inline-block}
.btn-secondary:hover .arr{transform:translateX(4px)}
.hero-note{margin-top:18px;font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace;opacity:0;animation:fadeUp 0.7s 0.6s forwards}
@keyframes fadeUp{to{opacity:1;transform:none}}
/* NETWORK CANVAS */
.hero-right{display:flex;align-items:center;justify-content:center;opacity:0;animation:fadeUp 0.8s 0.3s forwards}
#networkCanvas{width:100%;max-width:520px;aspect-ratio:1}
/* DIVIDER */
.divider{height:1px;background:var(--border);max-width:100%;margin:0}
/* SECTION BASE */
.section{padding:100px 48px;max-width:1400px;margin:0 auto}
.section-label{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--yellow);margin-bottom:16px}
.section-title{font-family:'Syne',sans-serif;font-size:clamp(30px,4vw,52px);font-weight:800;letter-spacing:-1.5px;line-height:1.1;margin-bottom:60px}
/* SCROLL REVEAL */
.reveal{opacity:0;transform:translateY(28px);transition:opacity 0.7s cubic-bezier(.2,.8,.3,1),transform 0.7s cubic-bezier(.2,.8,.3,1)}
.reveal.visible{opacity:1;transform:none}
.reveal-delay-1{transition-delay:0.1s}
.reveal-delay-2{transition-delay:0.2s}
.reveal-delay-3{transition-delay:0.3s}
/* STEPS */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:2px}
.step{background:var(--surface);padding:40px 36px;position:relative;overflow:hidden;transition:background 0.3s}
.step:hover{background:var(--surface2)}
.step:first-child{border-radius:12px 0 0 12px}
.step:last-child{border-radius:0 12px 12px 0}
.step-bar{position:absolute;top:0;left:0;right:0;height:2px;background:var(--border);transition:all 0.4s}
.step:hover .step-bar{background:var(--yellow)}
.step-num{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim);margin-bottom:20px;letter-spacing:1px}
.step-title{font-family:'Syne',sans-serif;font-size:20px;font-weight:700;margin-bottom:12px;line-height:1.2}
.step-desc{font-size:14px;color:var(--text-dim);line-height:1.7}
.step-code{margin-top:28px;background:var(--bg);border-radius:8px;padding:16px;font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--text-dim);line-height:1.9;border:1px solid var(--border)}
.step-code .hl{color:var(--yellow)}
.step-code .ok{color:var(--gemini)}
/* TYPEWRITER in step code */
.typewriter{overflow:hidden;white-space:nowrap;border-right:2px solid var(--yellow);animation:typing 2s steps(30,end) infinite alternate,blink 0.8s step-end infinite}
@keyframes typing{from{width:0}to{width:100%}}
@keyframes blink{50%{border-color:transparent}}
/* AI GRID */
.ai-section{padding:80px 48px;border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.ai-section-inner{max-width:1400px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr;gap:80px;align-items:center}
.ai-pills{display:flex;flex-direction:column;gap:2px}
.ai-pill-row{display:flex;gap:2px}
.ai-pill{flex:1;padding:18px 20px;border-radius:4px;display:flex;align-items:center;gap:12px;transition:filter 0.3s,transform 0.3s}
.ai-pill:hover{transform:translateX(4px);filter:brightness(1.2)}
.ai-pill-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;box-shadow:0 0 8px currentColor}
.ai-pill-name{font-family:'Syne',sans-serif;font-weight:700;font-size:14px}
.ai-pill-prov{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
/* BYOK */
.byok-section{padding:100px 48px;max-width:1400px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr;gap:80px;align-items:center}
.code-block{background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:hidden}
.code-header{padding:10px 16px;border-bottom:1px solid var(--border);display:flex;gap:6px;align-items:center}
.code-dot{width:10px;height:10px;border-radius:50%}
.code-body{padding:20px;font-family:'JetBrains Mono',monospace;font-size:12px;line-height:2.2}
.code-body .cm{color:var(--text-dim)}
.code-body .kw{color:var(--gpt)}
.code-body .val{color:var(--yellow)}
.code-body .ok2{color:var(--gemini)}
/* CTA */
.cta-section{padding:140px 48px;text-align:center;position:relative;overflow:hidden}
.cta-glow{position:absolute;inset:0;background:radial-gradient(ellipse 50% 70% at 50% 50%,rgba(232,224,64,0.05) 0%,transparent 65%);pointer-events:none}
.cta-inner{max-width:640px;margin:0 auto;position:relative}
.cta-title{font-family:'Syne',sans-serif;font-size:clamp(36px,5vw,68px);font-weight:800;letter-spacing:-2px;line-height:1.05;margin-bottom:24px}
.cta-sub{font-size:16px;color:var(--text-dim);margin-bottom:44px;line-height:1.7}
.cta-note{margin-top:18px;font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
/* FOOTER */
.footer-wrap{border-top:1px solid var(--border)}
footer{padding:36px 48px;display:flex;align-items:center;justify-content:space-between;max-width:1400px;margin:0 auto}
.footer-logo{font-family:'Syne',sans-serif;font-weight:800;font-size:15px;color:var(--text-dim);display:flex;align-items:center;gap:8px}
.footer-note{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
@media(max-width:900px){
nav{padding:16px 24px}.nav-links{display:none}.nav-burger{display:flex}
.hero{grid-template-columns:1fr;padding:100px 24px 60px;gap:48px}
.hero-right{order:-1}#networkCanvas{max-width:300px}
.section{padding:60px 24px}.steps{grid-template-columns:1fr}
.step:first-child{border-radius:12px 12px 0 0}.step:last-child{border-radius:0 0 12px 12px}
.ai-section{padding:60px 24px}.ai-section-inner{grid-template-columns:1fr;gap:40px}
.byok-section{grid-template-columns:1fr;padding:60px 24px;gap:40px}
.cta-section{padding:80px 24px}
footer{padding:28px 24px;flex-direction:column;gap:14px;text-align:center}
}
/* PRICING */
.pricing-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;max-width:860px;margin:0 auto}
.pricing-card{background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:32px;position:relative;transition:border-color 0.3s}
.pricing-card:hover{border-color:var(--text-dim)}
.pricing-card-pro{border-color:var(--yellow);background:linear-gradient(135deg,#12121A 0%,#1A1A10 100%)}
.pricing-card-pro:hover{border-color:var(--yellow)}
.pricing-popular{position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:var(--yellow);color:#0A0A0F;font-size:11px;font-weight:700;font-family:'Syne',sans-serif;padding:4px 14px;border-radius:20px;white-space:nowrap;letter-spacing:0.3px}
.pricing-badge{display:inline-block;font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:500;letter-spacing:1px;text-transform:uppercase;padding:3px 10px;border-radius:4px;margin-bottom:16px}
.free-badge{background:var(--surface2);color:var(--text-dim);border:1px solid var(--border)}
.pro-badge{background:var(--yellow-dim);color:var(--yellow);border:1px solid rgba(232,224,64,0.3)}
.pricing-price{display:flex;align-items:baseline;gap:4px;margin-bottom:6px}
.price-amount{font-family:'Syne',sans-serif;font-size:42px;font-weight:800;letter-spacing:-2px;color:var(--text)}
.price-period{font-size:14px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
.pricing-sub{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace;margin-bottom:0}
.pricing-divider{height:1px;background:var(--border);margin:24px 0}
.pricing-features{list-style:none;display:flex;flex-direction:column;gap:12px;margin-bottom:28px}
.pricing-features li{display:flex;align-items:center;gap:10px;font-size:14px;line-height:1.4}
.feat-icon{width:18px;height:18px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0}
.feat-icon.ok{background:var(--surface2);color:var(--text-dim)}
.feat-icon.pro-ok{background:rgba(232,224,64,0.12);color:var(--yellow)}
.feat-icon.no{background:transparent;color:var(--text-dim);border:1px solid var(--border)}
.btn-plan{display:block;width:100%;padding:13px;border-radius:8px;font-size:14px;font-weight:700;font-family:'Syne',sans-serif;text-align:center;text-decoration:none;transition:all 0.2s;cursor:pointer;border:none}
.btn-plan-free{background:transparent;border:1px solid var(--border);color:var(--text)}
.btn-plan-free:hover{border-color:var(--text);background:var(--surface2)}
.btn-plan-pro{background:var(--yellow);color:#0A0A0F}
.btn-plan-pro:hover{opacity:0.85;transform:translateY(-1px)}
.pricing-note{margin-top:12px;font-size:11px;color:var(--text-dim);font-family:'JetBrains Mono',monospace;text-align:center}
.pricing-card-team{border-color:#6366f1;background:linear-gradient(135deg,#12121A 0%,#0F0F1A 100%)}
.pricing-card-team:hover{border-color:#818cf8}
.pricing-card-biz{border-color:#06b6d4;background:linear-gradient(135deg,#12121A 0%,#0A1A1A 100%)}
.pricing-card-biz:hover{border-color:#22d3ee}
.pricing-soon{position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:var(--surface2);color:var(--text-dim);border:1px solid var(--border);font-size:11px;font-weight:700;font-family:'Syne',sans-serif;padding:4px 14px;border-radius:20px;white-space:nowrap;letter-spacing:0.3px}
.team-badge{background:rgba(99,102,241,0.15);color:#818cf8}
.biz-badge{background:rgba(6,182,212,0.15);color:#22d3ee}
.btn-plan-soon{background:var(--surface2);border:1px solid var(--border);color:var(--text-dim);cursor:not-allowed;opacity:0.7}
.pricing-users{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace;margin-top:4px}
.billing-toggle{display:flex;gap:4px;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:3px;margin:10px 0 8px}
.billing-btn{flex:1;padding:5px 10px;border-radius:5px;font-size:12px;font-weight:600;font-family:'Syne',sans-serif;cursor:pointer;border:none;background:transparent;color:var(--text-dim);transition:all 0.15s;white-space:nowrap}
.billing-btn.active{background:var(--surface2);color:var(--text)}
.save-tag{background:rgba(232,224,64,0.15);color:var(--yellow);padding:1px 5px;border-radius:3px;font-size:10px;margin-left:3px}
.pricing-toggle-wrap{}
@media(max-width:900px){.pricing-grid{grid-template-columns:1fr}}
/* WAITLIST */
.waitlist-section{padding:100px 48px;position:relative;overflow:hidden}
.waitlist-glow{position:absolute;inset:0;background:radial-gradient(ellipse 60% 50% at 50% 50%,rgba(232,224,64,0.07) 0%,transparent 65%);pointer-events:none}
.waitlist-inner{max-width:600px;margin:0 auto;text-align:center;position:relative}
.waitlist-eyebrow{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--yellow);margin-bottom:16px}
.waitlist-title{font-family:'Syne',sans-serif;font-size:clamp(32px,4.5vw,56px);font-weight:800;letter-spacing:-1.5px;line-height:1.1;margin-bottom:16px}
.waitlist-sub{font-size:16px;color:var(--text-dim);line-height:1.7;margin-bottom:36px}
.waitlist-form{display:flex;gap:8px;max-width:480px;margin:0 auto 16px}
.waitlist-input{flex:1;background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:13px 16px;color:var(--text);font-size:14px;font-family:'Inter',sans-serif;outline:none;transition:border-color 0.2s}
.waitlist-input:focus{border-color:var(--yellow)}
.waitlist-input::placeholder{color:var(--text-dim)}
.waitlist-btn{padding:13px 24px;background:var(--yellow);color:#0A0A0F;border:none;border-radius:8px;font-size:14px;font-weight:700;font-family:'Syne',sans-serif;cursor:pointer;transition:all 0.2s;white-space:nowrap}
.waitlist-btn:hover{opacity:0.85;transform:translateY(-1px)}
.waitlist-btn:disabled{opacity:0.5;cursor:not-allowed;transform:none}
.waitlist-success{background:rgba(75,201,155,0.1);border:1px solid rgba(75,201,155,0.3);border-radius:8px;padding:14px 20px;color:#4BC99B;font-size:14px;font-family:'JetBrains Mono',monospace;display:none;margin:0 auto;max-width:480px}
.waitlist-error{color:#F87171;font-size:12px;font-family:'JetBrains Mono',monospace;margin-top:8px;min-height:16px}
.waitlist-note{font-size:12px;color:var(--text-dim);font-family:'JetBrains Mono',monospace}
@media(max-width:600px){.waitlist-form{flex-direction:column}.waitlist-btn{width:100%}}
.lang-toggle{background:transparent;border:1px solid var(--border);color:var(--text-dim);font-family:var(--mono);font-size:11px;padding:4px 8px;border-radius:4px;cursor:pointer;letter-spacing:1px;transition:all 0.2s;margin-left:8px}.lang-toggle:hover{border-color:var(--yellow);color:var(--yellow)}</style>
<script>
// Safety net only — the real fix is redirect_to pointing at /reset-password
// (see PASSWORD_RESET_REDIRECT_URL) plus that URL being allowlisted in the
// Supabase dashboard. If a stale link or a misconfiguration still lands a
// recovery fragment on the landing page, forward it to /reset-password
// immediately, before anything else on this page runs, preserving the
// fragment so supabase-js there can still parse it.
(function () {
var hash = window.location.hash;
if (!hash) return;
var params = new URLSearchParams(hash.startsWith('#') ? hash.slice(1) : hash);
var isRecovery = params.get('type') === 'recovery';
var isAuthError = !!params.get('error_code') || params.get('error') === 'access_denied' || params.get('error') === 'server_error';
var looksLikeAuthFragment = params.has('access_token') || params.has('refresh_token');
if (isRecovery || (isAuthError && looksLikeAuthFragment)) {
window.location.replace('/reset-password' + hash);
}
})();
</script>
<script src="/assets/analytics.js"></script>
<script>
fetch('/api/public-config').then(r => r.json()).then(cfg => {
window.AIbridgeAnalytics.init(cfg.analytics);
}).catch(() => {});
</script>
</head>
<body>
<nav id="nav">
<a href="#" class="nav-logo"><div class="nav-dot"></div>AI Bridge</a>
<div class="nav-links">
<a href="#how" data-i18n="nav-how">Come funziona</a>
<a href="#models" data-i18n="nav-models">Modelli</a>
<a href="#privacy" data-i18n="nav-privacy">Privacy</a>
<a href="#pricing" data-i18n="nav-pricing">Prezzi</a>
<a href="/cli" data-i18n="nav-cli">CLI</a>
<a href="/demo" class="nav-cta" data-i18n="nav-cta">Prova ora →</a><button onclick="toggleLang()" class="lang-toggle" id="lang-btn">EN</button>
</div>
<button class="nav-burger" id="navBurger" aria-label="Apri menu" aria-expanded="false" aria-controls="mobileMenu" onclick="toggleMobileMenu()">☰</button>
</nav>
<div class="mobile-menu" id="mobileMenu">
<a href="#how" data-i18n="nav-how">Come funziona</a>
<a href="#models" data-i18n="nav-models">Modelli</a>
<a href="#privacy" data-i18n="nav-privacy">Privacy</a>
<a href="#pricing" data-i18n="nav-pricing">Prezzi</a>
<a href="/cli" data-i18n="nav-cli">CLI</a>
<a href="/demo" class="nav-cta" data-i18n="nav-cta">Prova ora →</a>
</div>
<!-- HERO -->
<section class="hero">
<div class="hero-left">
<div class="hero-eyebrow">AI Bridge</div>
<h1 class="hero-title" id="hero-title">Fai parlare<br>le AI<br><em>tra loro.</em></h1>
<p class="hero-sub" data-i18n="hero-sub">Una chat unica dove orchestri Claude, ChatGPT, Gemini e altri. Chiedi a un'AI di confrontarsi con un'altra — lei formula la domanda, tu decidi se inviarla.</p>
<div class="hero-actions">
<a href="/demo" class="btn-primary" data-i18n="hero-cta">Inizia gratis →</a>
<a href="#how" class="btn-secondary" data-i18n="hero-how">Come funziona <span class="arr">→</span></a>
</div>
<div class="hero-note" data-i18n="hero-note">// porta le tue API key — nessun dato salvato</div>
</div>
<div class="hero-right">
<canvas id="networkCanvas"></canvas>
</div>
</section>
<div class="divider"></div>
<!-- HOW -->
<section class="section" id="how">
<div class="reveal"><div class="section-label" data-i18n="how-label">Come funziona</div></div>
<div class="reveal reveal-delay-1"><h2 class="section-title" id="how-title">Tre passi.<br>Nessuna magia nascosta.</h2></div>
<div class="steps">
<div class="step reveal reveal-delay-1">
<div class="step-bar"></div>
<div class="step-num" data-i18n="step1-num">— 01 setup</div>
<div class="step-title" data-i18n="step1-title">Scegli le AI e inserisci le tue key</div>
<div class="step-desc" data-i18n="step1-desc">Seleziona i modelli che vuoi collegare. Le chiavi restano solo nel tuo browser — non transitano su nessun server.</div>
<div class="step-code">
<span style="color:var(--text-dim)">// seleziona almeno 2</span><br>
<span class="ok">✓</span> <span class="hl">Claude</span> sk-ant-...<br>
<span class="ok">✓</span> <span class="hl">ChatGPT</span> sk-proj-...<br>
<span style="color:var(--border)">○ Gemini</span><br>
<span style="color:var(--border)">○ Grok</span>
</div>
</div>
<div class="step reveal reveal-delay-2">
<div class="step-bar"></div>
<div class="step-num" data-i18n="step2-num">— 02 conversa</div>
<div class="step-title" data-i18n="step2-title">Parla con un'AI alla volta, o con tutte</div>
<div class="step-desc" data-i18n="step2-desc">Scegli a chi scrivere con un click. Puoi mandare lo stesso prompt a tutti in parallelo, o fare domande mirate a ciascuno.</div>
<div class="step-code">
<span style="color:var(--text-dim)">// target attivo</span><br>
[<span class="hl">Claude</span>] ChatGPT Tutti<br><br>
Tu → <span style="color:var(--text)">"dammi un'idea per un'app"</span><br>
Claude → <span style="color:var(--text-dim)">"potresti costruire..."</span>
</div>
</div>
<div class="step reveal reveal-delay-3">
<div class="step-bar"></div>
<div class="step-num" data-i18n="step3-num">— 03 passa la parola</div>
<div class="step-title" data-i18n="step3-title">L'AI formula la domanda per l'altra</div>
<div class="step-desc" data-i18n="step3-desc">Dici "chiedi a ChatGPT cosa ne pensa" e Claude scrive da sola la domanda. Tu la vedi e approvi. Nessun copia-incolla.</div>
<div class="step-code">
<span style="color:var(--text-dim)">// anteprima handoff</span><br>
↗ Claude → <span class="hl">ChatGPT</span><br>
<span style="color:var(--text)">"Ho ragionato così...<br>tu sei d'accordo?"</span><br>
[<span class="hl">Invia</span>] [Annulla]
</div>
</div>
</div>
</section>
<div class="divider"></div>
<!-- MODELS -->
<div class="ai-section" id="models">
<div class="ai-section-inner">
<div class="reveal">
<div class="section-label" data-i18n="models-section-title">Modelli supportati</div>
<h2 class="section-title" id="models-title" style="margin-bottom:20px">Cinque AI.<br>Una sola<br>conversazione.</h2>
<p style="color:var(--text-dim);font-size:15px;line-height:1.7;max-width:360px" data-i18n="models-desc">Collega qualsiasi combinazione. Basta selezionare quelle che ti servono e inserire le rispettive key.</p>
</div>
<div class="ai-pills reveal reveal-delay-1">
<div class="ai-pill-row">
<div class="ai-pill" style="background:#1A1208"><div class="ai-pill-dot" style="background:var(--claude);color:var(--claude)"></div><div><div class="ai-pill-name" style="color:var(--claude)">Claude</div><div class="ai-pill-prov">Anthropic</div></div></div>
<div class="ai-pill" style="background:#08121A"><div class="ai-pill-dot" style="background:var(--gpt);color:var(--gpt)"></div><div><div class="ai-pill-name" style="color:var(--gpt)">ChatGPT</div><div class="ai-pill-prov">OpenAI</div></div></div>
</div>
<div class="ai-pill-row">
<div class="ai-pill" style="background:#081A12"><div class="ai-pill-dot" style="background:var(--gemini);color:var(--gemini)"></div><div><div class="ai-pill-name" style="color:var(--gemini)">Gemini</div><div class="ai-pill-prov">Google</div></div></div>
<div class="ai-pill" style="background:#1A0812"><div class="ai-pill-dot" style="background:var(--grok);color:var(--grok)"></div><div><div class="ai-pill-name" style="color:var(--grok)">Grok</div><div class="ai-pill-prov">xAI</div></div></div>
</div>
<div class="ai-pill-row">
<div class="ai-pill" style="background:#121A08;flex:0.5"><div class="ai-pill-dot" style="background:var(--deepseek);color:var(--deepseek)"></div><div><div class="ai-pill-name" style="color:var(--deepseek)">DeepSeek</div><div class="ai-pill-prov">DeepSeek</div></div></div>
<div class="ai-pill" style="background:var(--surface);flex:0.5;justify-content:center"><div style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim)" data-i18n="models-more">+ altri presto</div></div>
</div>
</div>
</div>
</div>
<!-- BYOK -->
<section class="byok-section" id="privacy">
<div class="reveal">
<div class="section-label" data-i18n="privacy-label">Privacy & BYOK</div>
<h2 class="section-title" id="privacy-title" style="margin-bottom:20px">Le tue key.<br>Il tuo browser.<br>Basta.</h2>
<p style="color:var(--text-dim);font-size:15px;line-height:1.7;margin-bottom:20px" data-i18n="privacy-desc1">AI Bridge non ha un backend. Le API key vengono usate direttamente dal tuo browser per chiamare i provider. Non passano mai da noi.</p>
<p style="color:var(--text-dim);font-size:15px;line-height:1.7" data-i18n="privacy-desc2">Porti le tue key, paghi direttamente i provider, controlli ogni singolo passaggio.</p>
</div>
<div class="code-block reveal reveal-delay-1">
<div class="code-header">
<div class="code-dot" style="background:#FF5F57"></div>
<div class="code-dot" style="background:#FEBC2E"></div>
<div class="code-dot" style="background:#28C840"></div>
<span style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim);margin-left:8px">network trace</span>
</div>
<div class="code-body">
<span class="cm">// flusso reale quando invii un messaggio</span><br><br>
<span class="cm">Browser</span><br>
<span class="kw">POST</span> <span class="val">api.anthropic.com/v1/messages</span><br>
<span class="cm">Authorization: Bearer sk-ant-...</span><br>
<span class="ok2">← 200 OK { content: [...] }</span><br><br>
<span class="cm">// nessun server AI Bridge</span><br>
<span class="cm">// nessun log, nessuna registrazione</span><br>
<span class="cm">// zero intermediari</span>
</div>
</div>
</section>
<!-- CTA -->
<!-- PRICING -->
<div class="divider"></div>
<section class="section" id="pricing">
<div class="reveal"><div class="section-label" data-i18n="pricing-label">Prezzi</div></div>
<div class="reveal reveal-delay-1"><h2 class="section-title" id="pricing-title">Semplice.<br>Nessuna sorpresa.</h2></div>
<div class="pricing-grid reveal reveal-delay-2">
<!-- FREE -->
<div class="pricing-card">
<div class="pricing-header">
<div class="pricing-badge free-badge">Free</div>
<div class="pricing-price">
<span class="price-amount">€0</span>
<span class="price-period">/mese</span>
</div>
<div class="pricing-sub" data-i18n="free-desc">Per provare e esplorare</div>
</div>
<div class="pricing-divider"></div>
<ul class="pricing-features">
<li><span class="feat-icon ok">✓</span><span data-i18n="ff-1">1 ora per sessione</span></li>
<li><span class="feat-icon ok">✓</span><span data-i18n="ff-2">3 sessioni salvate</span></li>
<li><span class="feat-icon ok">✓</span><span data-i18n="ff-3">Max 2 AI collegabili</span></li>
<li><span class="feat-icon ok">✓</span><span data-i18n="ff-4">Passaggio di parola tra AI</span></li>
<li><span class="feat-icon no">×</span><span style="color:var(--text-dim)" data-i18n="ff-x1">Più di 2 AI contemporaneamente</span></li>
<li><span class="feat-icon no">×</span><span style="color:var(--text-dim)" data-i18n="ff-x2">Sessioni illimitate</span></li>
</ul>
<a href="/demo" class="btn-plan btn-plan-free" data-i18n="free-cta">Inizia gratis →</a>
</div>
<!-- PRO -->
<div class="pricing-card pricing-card-pro">
<div class="pricing-popular" data-i18n="plan-popular">Più scelto</div>
<div class="pricing-header">
<div class="pricing-badge pro-badge">Pro</div>
<div class="pricing-toggle-wrap">
<div class="pricing-price" id="price-display">
<span class="price-amount" id="price-amount">€12</span>
<span class="price-period" id="price-period">/mese</span>
</div>
<div class="billing-toggle">
<button class="billing-btn active" id="btn-monthly" onclick="setBilling('monthly')" data-i18n="billing-monthly">Mensile</button>
<button class="billing-btn" id="btn-yearly" onclick="setBilling('yearly')" data-i18n-html="billing-annual"><span data-i18n="billing-annual-text">Annuale</span> <span class="save-tag">−33%</span></button>
</div>
</div>
<div class="pricing-sub" id="price-sub" data-i18n="billing-note-monthly">Fatturato mensilmente</div>
</div>
<div class="pricing-divider"></div>
<ul class="pricing-features">
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="pf-1">Utilizzo <strong>illimitato</strong></span></li>
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="pf-2">Sessioni <strong>illimitate</strong></span></li>
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="pf-3">Tutte e <strong>5 le AI</strong> collegabili</span></li>
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="ff-4">Passaggio di parola tra AI</span></li>
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="pf-5">Filtro cronologia per AI</span></li>
<li><span class="feat-icon ok pro-ok">✓</span><span data-i18n="pf-6">Priorità sui nuovi modelli</span></li>
</ul>
<a href="/demo" class="btn-plan btn-plan-pro" data-i18n="pro-cta">Inizia con Pro →</a>
<div class="pricing-note" data-i18n="pro-note">// porta le tue API key — nessun costo nascosto</div>
</div>
<!-- PRO TEAM -->
<div class="pricing-card pricing-card-team">
<div class="pricing-soon">// coming soon</div>
<div class="pricing-header">
<div class="pricing-badge team-badge">Pro Team</div>
<div class="pricing-price">
<span class="price-amount">€29</span>
<span class="price-period">/mese</span>
</div>
<div class="pricing-users" data-i18n="team-users">fino a 3 utenti</div>
</div>
<div class="pricing-divider"></div>
<ul class="pricing-features">
<li><span class="feat-icon ok" style="color:#818cf8">✓</span><span data-i18n="tf-1">Tutto di Pro, per ogni membro</span></li>
<li><span class="feat-icon ok" style="color:#818cf8">✓</span><span data-i18n="tf-2">Sessioni <strong>condivise</strong> tra il team</span></li>
<li><span class="feat-icon ok" style="color:#818cf8">✓</span><span data-i18n="tf-3">Ruoli AI assegnabili per progetto</span></li>
<li><span class="feat-icon ok" style="color:#818cf8">✓</span><span data-i18n="tf-4">Cronologia condivisa</span></li>
<li><span class="feat-icon ok" style="color:#818cf8">✓</span><span data-i18n="tf-5">Dashboard team</span></li>
</ul>
<button class="btn-plan btn-plan-soon" data-i18n="soon-cta" disabled>In arrivo →</button>
<div class="pricing-note" data-i18n="team-note">// contattaci per l'early access</div>
</div>
<!-- BUSINESS -->
<div class="pricing-card pricing-card-biz">
<div class="pricing-soon">// coming soon</div>
<div class="pricing-header">
<div class="pricing-badge biz-badge">Business</div>
<div class="pricing-price">
<span class="price-amount">€79</span>
<span class="price-period">/mese</span>
</div>
<div class="pricing-users" data-i18n="biz-users">fino a 10 utenti</div>
</div>
<div class="pricing-divider"></div>
<ul class="pricing-features">
<li><span class="feat-icon ok" style="color:#22d3ee">✓</span><span data-i18n="bf-1">Tutto di Pro Team</span></li>
<li><span class="feat-icon ok" style="color:#22d3ee">✓</span><span data-i18n="bf-2">Fino a <strong>10 utenti</strong></span></li>
<li><span class="feat-icon ok" style="color:#22d3ee">✓</span><span data-i18n="bf-3">Onboarding dedicato</span></li>
<li><span class="feat-icon ok" style="color:#22d3ee">✓</span><span data-i18n="bf-4">Supporto prioritario</span></li>
<li><span class="feat-icon ok" style="color:#22d3ee">✓</span><span data-i18n="bf-5">API usage analytics avanzati</span></li>
</ul>
<button class="btn-plan btn-plan-soon" data-i18n="soon-cta" disabled>In arrivo →</button>
<div class="pricing-note" data-i18n="biz-note">// <a href="mailto:hello@your-domain.example" style="color:var(--text-dim)">contattaci</a> per un piano custom</div>
</div>
</div>
</section>
<!-- WAITLIST -->
<div class="divider"></div>
<section class="waitlist-section" id="waitlist">
<div class="waitlist-glow"></div>
<div class="waitlist-inner reveal">
<div class="waitlist-eyebrow" data-i18n="cta-eyebrow">// disponibile ora</div>
<h2 class="waitlist-title" id="cta-title">Pronto a mettere le AI al lavoro <em>insieme?</em></h2>
<p class="waitlist-sub" data-i18n="cta-sub">Basta le tue API key. Nessuna registrazione obbligatoria.</p>
<a href="/demo" class="btn-primary" style="display:inline-block;padding:14px 32px;font-size:16px;font-weight:700;border-radius:8px;text-decoration:none" data-i18n="cta-btn">Inizia gratis →</a>
<p class="waitlist-note" style="margin-top:16px"><span data-i18n="cta-note">// accesso immediato — porta le tue key</span></p>
</div>
</section>
<div class="divider"></div>
<div class="footer-wrap">
<footer>
<div class="footer-logo"><div class="nav-dot"></div>AI Bridge</div>
<div class="footer-note"><span data-i18n="footer-note">// built with curiosity — porta le tue key</span></div>
</footer>
</div>
<script>
// NAV SCROLL
window.addEventListener('scroll',()=>{
document.getElementById('nav').classList.toggle('scrolled',scrollY>40);
});
// MOBILE MENU
function toggleMobileMenu(force){
const menu=document.getElementById('mobileMenu');
const burger=document.getElementById('navBurger');
const open = force !== undefined ? force : !menu.hasAttribute('data-open');
menu.toggleAttribute('data-open', open);
burger.setAttribute('aria-expanded', String(open));
}
document.getElementById('mobileMenu').querySelectorAll('a').forEach(a=>{
a.addEventListener('click',()=>toggleMobileMenu(false));
});
document.addEventListener('keydown',(e)=>{
if(e.key==='Escape') toggleMobileMenu(false);
});
// SCROLL REVEAL
const observer=new IntersectionObserver(entries=>{
entries.forEach(e=>{if(e.isIntersecting)e.target.classList.add('visible');});
},{threshold:0.12});
document.querySelectorAll('.reveal').forEach(el=>observer.observe(el));
// ─── NETWORK CANVAS ANIMATION ───────────────────────────────────────────────
const canvas=document.getElementById('networkCanvas');
const ctx=canvas.getContext('2d');
const DPR=window.devicePixelRatio||1;
function resize(){
const w=canvas.offsetWidth;
canvas.width=w*DPR;canvas.height=w*DPR;
canvas.style.height=w+'px';
W=canvas.width;H=canvas.height;
buildLayout();
}
let W,H;
const AI=[
{id:'claude',name:'Claude',color:'#C97B4B',angle:-Math.PI/2-Math.PI/4},
{id:'gpt',name:'ChatGPT',color:'#4B9FC9',angle:-Math.PI/4},
{id:'gemini',name:'Gemini',color:'#4BC99B',angle:Math.PI/2+Math.PI/4},
{id:'grok',name:'Grok',color:'#C94B9B',angle:Math.PI/4},
{id:'deepseek',name:'DeepSeek',color:'#9BC94B',angle:Math.PI/2},
];
let cx,cy,orbitR,nodeR,centerR;
function buildLayout(){
cx=W/2;cy=H/2;
orbitR=W*0.32;
nodeR=W*0.078;
centerR=W*0.085;
AI.forEach(ai=>{
ai.x=cx+Math.cos(ai.angle)*orbitR;
ai.y=cy+Math.sin(ai.angle)*orbitR;
ai.pulse=0;ai.pulseDir=1;
ai.glowAmt=0;
});
}
// Particles traveling along edges
const particles=[];
function spawnParticle(){
const ai=AI[Math.floor(Math.random()*AI.length)];
const toCenter=Math.random()<0.5;
particles.push({
ai,
t:0,
speed:0.008+Math.random()*0.007,
toCenter,
size:DPR*(3.5+Math.random()*3),
alpha:1,
});
ai.pulse=1;ai.glowAmt=1;
}
// Ring pulse emanating from center
const rings=[];
function spawnRing(){
rings.push({r:centerR*0.6,alpha:0.6,color:'#E8E040'});
}
let lastSpawn=0,lastRing=0;
// Floating background dots
const bgDots=Array.from({length:28},()=>({
x:Math.random(),y:Math.random(),
r:Math.random()*1.5+0.5,
alpha:Math.random()*0.15+0.05,
speed:0.00008+Math.random()*0.0001,
angle:Math.random()*Math.PI*2,
}));
function lerp(a,b,t){return a+(b-a)*t;}
function easeInOut(t){return t<0.5?2*t*t:1-Math.pow(-2*t+2,2)/2;}
function draw(ts){
requestAnimationFrame(draw);
ctx.clearRect(0,0,W,H);
// Background dots
bgDots.forEach(d=>{
d.angle+=d.speed;
const x=d.x*W+Math.cos(d.angle)*20;
const y=d.y*H+Math.sin(d.angle)*20;
ctx.beginPath();ctx.arc(x,y,d.r*DPR,0,Math.PI*2);
ctx.fillStyle=`rgba(112,112,160,${d.alpha})`;ctx.fill();
});
// Grid lines (faint)
ctx.strokeStyle='rgba(42,42,74,0.4)';ctx.lineWidth=0.5*DPR;
for(let i=0;i<6;i++){
const x=W*i/5;ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,H);ctx.stroke();
const y=H*i/5;ctx.beginPath();ctx.moveTo(0,y);ctx.lineTo(W,y);ctx.stroke();
}
// Spawn logic
if(ts-lastSpawn>400){spawnParticle();lastSpawn=ts;if(Math.random()<0.4)spawnParticle();}
if(ts-lastRing>1800){spawnRing();lastRing=ts;}
// Connection lines
AI.forEach(ai=>{
const glow=ai.glowAmt>0;
ctx.beginPath();ctx.moveTo(cx,cy);ctx.lineTo(ai.x,ai.y);
if(glow){
ctx.strokeStyle=ai.color+'88';ctx.lineWidth=2*DPR;
}else{
ctx.strokeStyle='rgba(42,42,74,0.6)';ctx.lineWidth=DPR;
}
ctx.stroke();
ai.glowAmt=Math.max(0,ai.glowAmt-0.012);
});
// Rings
for(let i=rings.length-1;i>=0;i--){
const ring=rings[i];
ring.r+=1.8*DPR;ring.alpha-=0.012;
if(ring.alpha<=0){rings.splice(i,1);continue;}
ctx.beginPath();ctx.arc(cx,cy,ring.r,0,Math.PI*2);
ctx.strokeStyle=`rgba(232,224,64,${ring.alpha})`;ctx.lineWidth=1.2*DPR;ctx.stroke();
}
// Particles
for(let i=particles.length-1;i>=0;i--){
const p=particles[i];p.t+=p.speed;
if(p.t>=1){particles.splice(i,1);continue;}
const te=easeInOut(p.t);
let px,py;
if(p.toCenter){px=lerp(p.ai.x,cx,te);py=lerp(p.ai.y,cy,te);}
else{px=lerp(cx,p.ai.x,te);py=lerp(cy,p.ai.y,te);}
const fade=p.t<0.2?p.t/0.2:p.t>0.8?(1-p.t)/0.2:1;
// Glow
const gr=ctx.createRadialGradient(px,py,0,px,py,p.size*3);
gr.addColorStop(0,p.ai.color+'EE');gr.addColorStop(1,p.ai.color+'00');
ctx.beginPath();ctx.arc(px,py,p.size*5,0,Math.PI*2);
ctx.fillStyle=gr;ctx.globalAlpha=fade*0.85;ctx.fill();
// Core
ctx.beginPath();ctx.arc(px,py,p.size,0,Math.PI*2);
ctx.fillStyle=p.ai.color;ctx.globalAlpha=fade;ctx.fill();
ctx.globalAlpha=1;
}
// AI nodes
AI.forEach(ai=>{
// Outer glow
if(ai.glowAmt>0.1){
const gr=ctx.createRadialGradient(ai.x,ai.y,nodeR*0.6,ai.x,ai.y,nodeR*1.8);
gr.addColorStop(0,ai.color+(Math.floor(ai.glowAmt*80).toString(16).padStart(2,'0')));
gr.addColorStop(1,ai.color+'00');
ctx.beginPath();ctx.arc(ai.x,ai.y,nodeR*1.8,0,Math.PI*2);
ctx.fillStyle=gr;ctx.fill();
}
// Outer ring
ctx.beginPath();ctx.arc(ai.x,ai.y,nodeR,0,Math.PI*2);
ctx.strokeStyle=ai.color+(ai.glowAmt>0.1?'DD':'66');
ctx.lineWidth=1.5*DPR;ctx.stroke();
// Inner fill
ctx.beginPath();ctx.arc(ai.x,ai.y,nodeR*0.78,0,Math.PI*2);
ctx.fillStyle='#12121A';ctx.fill();
// Text
ctx.fillStyle=ai.color;
ctx.font=`${Math.floor(9*DPR)}px 'JetBrains Mono'`;
ctx.textAlign='center';ctx.textBaseline='middle';
ctx.fillText('AI',ai.x,ai.y-nodeR*0.18);
ctx.fillStyle='#F0F0F5';
ctx.font=`700 ${Math.floor(11*DPR)}px 'Syne'`;
ctx.fillText(ai.name,ai.x,ai.y+nodeR*0.25);
});
// Center node — YOU
// Outer glow
const cgr=ctx.createRadialGradient(cx,cy,centerR*0.4,cx,cy,centerR*2.2);
cgr.addColorStop(0,'rgba(232,224,64,0.15)');cgr.addColorStop(1,'rgba(232,224,64,0)');
ctx.beginPath();ctx.arc(cx,cy,centerR*2.2,0,Math.PI*2);ctx.fillStyle=cgr;ctx.fill();
// Animated outer ring
const t2=Date.now()/1000;
const pulse=Math.sin(t2*1.8)*0.12+0.88;
ctx.beginPath();ctx.arc(cx,cy,centerR*pulse,0,Math.PI*2);
ctx.strokeStyle='rgba(232,224,64,0.5)';ctx.lineWidth=1.5*DPR;ctx.stroke();
ctx.beginPath();ctx.arc(cx,cy,centerR*0.78,0,Math.PI*2);
ctx.strokeStyle='#E8E040';ctx.lineWidth=2*DPR;ctx.stroke();
ctx.beginPath();ctx.arc(cx,cy,centerR*0.68,0,Math.PI*2);
ctx.fillStyle='#1A1A10';ctx.fill();
ctx.fillStyle='#E8E040';
ctx.font=`${Math.floor(8*DPR)}px 'JetBrains Mono'`;
ctx.textAlign='center';ctx.textBaseline='middle';
ctx.fillText('YOU',cx,cy-centerR*0.18);
ctx.fillStyle='#F0F0F5';
ctx.font=`700 ${Math.floor(11*DPR)}px 'Syne'`;
ctx.fillText('Utente',cx,cy+centerR*0.22);
}
// Use ResizeObserver for accurate canvas sizing
const ro = new ResizeObserver(()=>{ resize(); });
ro.observe(canvas);
function startAnimation(){
resize();
requestAnimationFrame(draw);
// Burst of particles at start
for(let i=0;i<6;i++) setTimeout(spawnParticle, i*150);
setTimeout(spawnRing, 200);
}
if(document.fonts){
document.fonts.ready.then(startAnimation);
}else{
setTimeout(startAnimation, 300);
}
function setBilling(type) {
const monthly = type === 'monthly';
document.getElementById('btn-monthly').classList.toggle('active', monthly);
document.getElementById('btn-yearly').classList.toggle('active', !monthly);
document.getElementById('price-amount').textContent = monthly ? '€12' : '€8';
document.getElementById('price-period').textContent = monthly ? '/mese' : '/mese';
document.getElementById('price-sub').textContent = monthly ? 'Fatturato mensilmente' : '€96 fatturati annualmente';
}
// WAITLIST
// No Supabase URL/key hardcoded here — fetched once from the server's
// public, non-secret config. If this deployment has no Supabase project
// configured (DATA_BACKEND=local, the default), sbConfig stays null and
// the waitlist form degrades gracefully instead of erroring.
let sbConfig = null;
async function loadSbConfig() {
try {
const res = await fetch('/api/public-config');
const cfg = await res.json();
sbConfig = cfg.supabase || null;
} catch {
sbConfig = null;
}
}
loadSbConfig();
async function joinWaitlist() {
const email = document.getElementById('waitlist-email').value.trim();
const btn = document.getElementById('waitlist-btn');
const errEl = document.getElementById('waitlist-error');
const successEl = document.getElementById('waitlist-success');
errEl.textContent = '';
if (!sbConfig) {
errEl.textContent = '// lista d\'attesa non disponibile in questa modalità';
return;
}
if (!email || !email.includes('@')) {
errEl.textContent = '// inserisci un email valida';
return;
}
btn.disabled = true;
btn.textContent = '...';
try {
const res = await fetch(sbConfig.url + '/rest/v1/waitlist', {
method: 'POST',
headers: {
'apikey': sbConfig.anonKey,
'Authorization': 'Bearer ' + sbConfig.anonKey,
'Content-Type': 'application/json',
'Prefer': 'return=minimal',
},
body: JSON.stringify({ email })
});
if (res.status === 201 || res.status === 200) {
document.querySelector('.waitlist-form').style.display = 'none';
successEl.style.display = 'block';
} else if (res.status === 409) {
errEl.textContent = '// questa email è già nella lista!';
btn.disabled = false; btn.textContent = 'Unisciti →';
} else {
throw new Error('Errore ' + res.status);
}
} catch(e) {
errEl.textContent = '// errore: ' + e.message;
btn.disabled = false; btn.textContent = 'Unisciti →';
}
}
</script>
<div id="cookie-banner" style="position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:9999;background:#1A1A24;border:1px solid rgba(255,255,255,0.12);border-radius:12px;padding:16px 20px;display:flex;align-items:center;gap:16px;box-shadow:0 8px 32px rgba(0,0,0,0.5);max-width:600px;width:calc(100% - 48px);font-family:'JetBrains Mono',monospace;font-size:12px;color:#9898A8;">
<div style="flex:1;line-height:1.5">Usiamo cookie tecnici per il funzionamento del sito. Vedi la <a href="/privacy" style="color:#C8C820;text-decoration:none">Privacy Policy</a>.</div>
<div style="display:flex;gap:8px;flex-shrink:0">
<button onclick="cookieChoice(false)" style="padding:7px 14px;border-radius:6px;font-size:11px;font-weight:700;font-family:'JetBrains Mono',monospace;cursor:pointer;background:transparent;border:1px solid rgba(255,255,255,0.15);color:#9898A8">Solo essenziali</button>
<button onclick="cookieChoice(true)" style="padding:7px 14px;border-radius:6px;font-size:11px;font-weight:700;font-family:'JetBrains Mono',monospace;cursor:pointer;background:#C8C820;border:none;color:#0A0A0F">Accetta</button>
</div>
</div>
<script>
(function(){
if(localStorage.getItem('cookie_consent')!==null){
document.getElementById('cookie-banner').style.display='none';
}
})();
function cookieChoice(a){
localStorage.setItem('cookie_consent',a?'accepted':'rejected');
document.getElementById('cookie-banner').style.display='none';
}
</script>
<script>
// ─── i18n ────────────────────────────────────────────────────────────────────
const T = {
it: {
// nav
'nav-how':'Come funziona','nav-models':'Modelli','nav-privacy':'Privacy',
'nav-pricing':'Prezzi','nav-cta':'Prova ora →','nav-cli':'CLI',
// hero
'hero-title':'Fai parlare<br>le AI<br><em>tra loro.</em>',
'hero-sub':"Una chat unica dove orchestri Claude, ChatGPT, Gemini e altri. Chiedi a un'AI di confrontarsi con un'altra — lei formula la domanda, tu decidi se inviarla.",
'hero-cta':'Inizia gratis →',
'hero-how':'Come funziona <span class="arr">→</span>',
'hero-note':'// porta le tue API key — nessun dato salvato',
// how
'how-label':'Come funziona',
'how-title':'Tre passi.<br>Nessuna magia nascosta.',
'step1-num':'— 01 setup','step1-desc':'Seleziona i modelli che vuoi collegare. Le chiavi restano solo nel tuo browser — non transitano su nessun server.',
'step2-num':'— 02 conversa','step2-desc':'Scegli a chi scrivere con un click. Puoi mandare lo stesso prompt a tutti in parallelo, o fare domande mirate a ciascuno.',
'step3-num':'— 03 passa la parola','step3-desc':'Dici "chiedi a ChatGPT cosa ne pensa" e Claude scrive da sola la domanda. Tu la vedi e approvi. Nessun copia-incolla.',
// models
'models-section-title':'Modelli supportati',
'models-title':'Cinque AI.<br>Una sola<br>conversazione.',
'models-desc':'Collega qualsiasi combinazione. Basta selezionare quelle che ti servono e inserire le rispettive key.',
'models-more':'+ altri presto',
// privacy
'privacy-label':'Privacy & BYOK',
'privacy-title':'Le tue key.<br>Il tuo browser.<br>Basta.',
'privacy-desc1':'AI Bridge non ha un backend. Le API key vengono usate direttamente dal tuo browser per chiamare i provider. Non passano mai da noi.',
'privacy-desc2':'Porti le tue key, paghi direttamente i provider, controlli ogni singolo passaggio.',
// pricing
'pricing-label':'Prezzi',
'pricing-title':'Semplice.<br>Nessuna sorpresa.',
'free-desc':'Per provare e esplorare','free-cta':'Inizia gratis →',
'plan-popular':'Più scelto',
'billing-monthly':'Mensile','billing-annual-text':'Annuale',
'billing-note-monthly':'Fatturato mensilmente',
'pro-cta':'Inizia con Pro →',
'team-users':'fino a 3 utenti','biz-users':'fino a 10 utenti',
'soon-cta':'In arrivo →',
// cta
'cta-eyebrow':'// disponibile ora',
'cta-title':'Pronto a mettere le AI al lavoro <em>insieme?</em>',
'cta-sub':'Basta le tue API key. Nessuna registrazione obbligatoria.',
'cta-btn':'Inizia gratis →',
'cta-note':'// accesso immediato — porta le tue key',
// footer
'footer-note':'// built with curiosity — porta le tue key',
'step1-title':'Scegli le AI e inserisci le tue key',
'step2-title':"Parla con un'AI alla volta, o con tutte",
'step3-title':"L'AI formula la domanda per l'altra",
// pricing features
'ff-1':'1 ora per sessione','ff-2':'3 sessioni salvate',
'ff-3':'Max 2 AI collegabili','ff-4':'Passaggio di parola tra AI',
'ff-x1':'Più di 2 AI contemporaneamente','ff-x2':'Sessioni illimitate',
'pf-1':'Utilizzo <strong>illimitato</strong>','pf-2':'Sessioni <strong>illimitate</strong>',
'pf-3':'Tutte e <strong>5 le AI</strong> collegabili',
'pf-5':'Filtro cronologia per AI','pf-6':'Priorità sui nuovi modelli',
'pro-note':'// porta le tue API key — nessun costo nascosto',
'tf-1':'Tutto di Pro, per ogni membro',
'tf-2':'Sessioni <strong>condivise</strong> tra il team',
'tf-3':'Ruoli AI assegnabili per progetto','tf-4':'Cronologia condivisa','tf-5':'Dashboard team',
"team-note":"// contattaci per l'early access",
'bf-1':'Tutto di Pro Team','bf-2':'Fino a <strong>10 utenti</strong>',
'bf-3':'Onboarding dedicato','bf-4':'Supporto prioritario','bf-5':'API usage analytics avanzati',
"biz-note":"// <a href='mailto:hello@your-domain.example' style='color:var(--text-dim)'>contattaci</a> per un piano custom",
},
en: {
// nav
'nav-how':'How it works','nav-models':'Models','nav-privacy':'Privacy',
'nav-pricing':'Pricing','nav-cta':'Try now →','nav-cli':'CLI',
// hero
'hero-title':'Make your AIs<br>talk<br><em>to each other.</em>',
'hero-sub':'A single chat where you orchestrate Claude, ChatGPT, Gemini and more. Ask one AI to challenge another — it writes the question, you decide whether to send it.',
'hero-cta':'Start free →',
'hero-how':'How it works <span class="arr">→</span>',
'hero-note':'// bring your API keys — no data stored',
// how
'how-label':'How it works',
'how-title':'Three steps.<br>No hidden magic.',
'step1-num':'— 01 setup','step1-desc':'Select the models you want to connect. Keys stay only in your browser — they never transit through any server.',
'step2-num':'— 02 converse','step2-desc':'Choose who to write to with one click. Send the same prompt to all in parallel, or ask targeted questions to each.',
'step3-num':'— 03 hand off','step3-desc':'Say "ask ChatGPT what it thinks" and Claude writes the question by itself. You see it and approve. No copy-paste.',
// models
'models-section-title':'Supported models',
'models-title':'Five AIs.<br>One single<br>conversation.',
'models-desc':'Connect any combination. Just select the ones you need and enter the respective keys.',
'models-more':'+ more soon',
// privacy
'privacy-label':'Privacy & BYOK',
'privacy-title':'Your keys.<br>Your browser.<br>Period.',
'privacy-desc1':'AI Bridge has no backend. API keys are used directly by your browser to call the providers. They never pass through us.',
'privacy-desc2':'You bring your keys, pay the providers directly, and control every single step.',
// pricing
'pricing-label':'Pricing',
'pricing-title':'Simple.<br>No surprises.',
'free-desc':'To try and explore','free-cta':'Start free →',
'plan-popular':'Most popular',
'billing-monthly':'Monthly','billing-annual-text':'Annual',
'billing-note-monthly':'Billed monthly',
'pro-cta':'Start Pro →',
'team-users':'up to 3 users','biz-users':'up to 10 users',
'soon-cta':'Coming soon →',
// cta
'cta-eyebrow':'// available now',
'cta-title':'Ready to put your AIs to work <em>together?</em>',
'cta-sub':'Just your API keys. No mandatory registration.',
'cta-btn':'Start free →',
'cta-note':'// instant access — bring your keys',
// footer
'footer-note':'// built with curiosity — bring your keys',
'step1-title':'Choose your AIs and enter your keys',
'step2-title':'Talk to one AI at a time, or all at once',
'step3-title':'The AI formulates the question for the other',
// pricing features
'ff-1':'1 hour per session','ff-2':'3 saved sessions',
'ff-3':'Max 2 AIs connectable','ff-4':'AI-to-AI handoff',
'ff-x1':'More than 2 AIs simultaneously','ff-x2':'Unlimited sessions',
'pf-1':'<strong>Unlimited</strong> usage','pf-2':'<strong>Unlimited</strong> sessions',
'pf-3':'All <strong>5 AIs</strong> connectable',
'pf-5':'Per-AI history filter','pf-6':'Priority on new models',
'pro-note':'// bring your API keys — no hidden costs',
'tf-1':'Everything in Pro, for each member',
'tf-2':'<strong>Shared</strong> sessions across the team',
'tf-3':'Assignable AI roles per project','tf-4':'Shared history','tf-5':'Team dashboard',
'team-note':'// contact us for early access',
'bf-1':'Everything in Pro Team','bf-2':'Up to <strong>10 users</strong>',
'bf-3':'Dedicated onboarding','bf-4':'Priority support','bf-5':'Advanced API usage analytics',
"biz-note":"// <a href='mailto:hello@your-domain.example' style='color:var(--text-dim)'>contact us</a> for a custom plan",
}
};
// Elements translated via innerHTML (IDs)
const ID_TRANS = ['how-title','models-title','privacy-title','pricing-title','hero-title','cta-title'];
let lang = localStorage.getItem('aib-lang') ||
(navigator.language?.startsWith('it') ? 'it' : 'en');
function applyLang(l) {
lang = l;
localStorage.setItem('aib-lang', l);
document.documentElement.lang = l;
const btn = document.getElementById('lang-btn');
if (btn) btn.textContent = l === 'it' ? 'EN' : 'IT';
const t = T[l];
// data-i18n elements
document.querySelectorAll('[data-i18n]').forEach(el => {
const k = el.getAttribute('data-i18n');
if (t[k] !== undefined) el.innerHTML = t[k];
});
// ID-based innerHTML elements
ID_TRANS.forEach(id => {
const el = document.getElementById(id);
if (el && t[id]) el.innerHTML = t[id];
});
// Update billing note dynamically based on current billing cycle
const sub = document.getElementById('price-sub');
if (sub) {
const isYearly = document.getElementById('btn-yearly')?.classList.contains('active');
sub.textContent = isYearly
? (l === 'it' ? 'Fatturato annualmente' : 'Billed annually')
: t['billing-note-monthly'];
}
}
function toggleLang() { applyLang(lang === 'it' ? 'en' : 'it'); }
document.addEventListener('DOMContentLoaded', () => applyLang(lang));
</script>
</body>
</html>