const SECURITY_HEADERS = {
  'X-Frame-Options': 'DENY',
  'X-Content-Type-Options': 'nosniff',
  'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
  'Permissions-Policy': 'camera=(), microphone=(), geolocation=(), payment=()',
  'Content-Security-Policy': [
    "default-src 'self'",
    "script-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
    "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://fonts.gstatic.com",
    "font-src 'self' https://fonts.gstatic.com",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.github.com",
    "frame-ancestors 'none'",
    "base-uri 'self'",
    "form-action 'self'"
  ].join('; '),
  'Referrer-Policy': 'strict-origin-when-cross-origin',
};

function addSecurityHeaders(response) {
  const r = new Response(response.body, response);
  for (const [k, v] of Object.entries(SECURITY_HEADERS)) {
    r.headers.set(k, v);
  }
  return r;
}

export default {
  async fetch(request, env) {
    return addSecurityHeaders(await _handleFetch(request, env));
  }
}

async function _handleFetch(request, env) {
    const html = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='6' fill='%23FF8C00'/><text x='50%25' y='55%25' dominant-baseline='middle' text-anchor='middle' font-family='monospace' font-weight='bold' font-size='16' fill='white'>A/</text></svg>\">\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"description\" content=\"Aiden is a local-first AI OS for Windows &amp; Linux. Cloud-powered intelligence with local Ollama fallback. 68 bundled skills, 56 built-in tools, multi-provider failover. Open source (AGPL-3.0).\">\n<title>Aiden \u2014 Open Source AI OS for Windows &amp; Linux \u00b7 Local \u00b7 Private \u00b7 Yours</title>\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@300;400;500&display=swap\" rel=\"stylesheet\">\n<style>\n*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}\n:root{\n  --bg:#0e0e0e;--bg1:#141414;--bg2:#1a1a1a;--bg3:#222;\n  --b:#2a2a2a;--b2:#333;--b3:#3a3a3a;\n  --text:#e8e8e8;--muted:#555;--muted2:#888;--muted3:#aaa;\n  --orange:#f97316;--orange2:#fb923c;--odim:rgba(249,115,22,0.1);--odim2:rgba(249,115,22,0.18);\n  --green:#22c55e;--gdim:rgba(34,197,94,0.12);\n  --mono:'JetBrains Mono',monospace;--sans:'Outfit',sans-serif;\n}\nhtml{scroll-behavior:smooth}\nbody{background:var(--bg);color:var(--text);font-family:var(--sans);overflow-x:hidden;line-height:1.6}\ncanvas#bg{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0;pointer-events:none}\n.z{position:relative;z-index:1}\n.wrap{max-width:1080px;margin:0 auto;padding:0 32px}\nnav{position:fixed;top:0;left:0;right:0;z-index:100;background:rgba(14,14,14,0.93);backdrop-filter:blur(18px);border-bottom:1px solid var(--b)}\n.navi{display:flex;align-items:center;justify-content:space-between;height:52px;max-width:1080px;margin:0 auto;padding:0 32px}\n.nlogo{display:flex;align-items:center;gap:9px;text-decoration:none;font-family:var(--mono);font-size:13px;color:var(--text)}\n.lsq{width:24px;height:24px;border-radius:5px;background:var(--orange);display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;color:#000;font-family:var(--mono);flex-shrink:0}\n.nbadge{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:11px;color:var(--green)}\n.ndot{width:5px;height:5px;border-radius:50%;background:var(--green);animation:blink 2s infinite}\n@keyframes blink{0%,100%{opacity:1}50%{opacity:.25}}\n.nlinks{display:flex;align-items:center;gap:4px}\n.nl{font-family:var(--mono);font-size:11px;color:var(--muted2);text-decoration:none;padding:4px 10px;border-radius:4px;transition:color .15s,background .15s}\n.nl:hover{color:var(--text);background:var(--bg2)}\n.ncta{font-family:var(--mono);font-size:11px;color:var(--orange);background:var(--odim);border:1px solid rgba(249,115,22,0.25);padding:4px 14px;border-radius:4px;text-decoration:none;transition:all .15s}\n.ncta:hover{background:var(--odim2);border-color:rgba(249,115,22,0.5)}\n.hero{padding:148px 0 88px}\n.stag{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10px;color:var(--orange);letter-spacing:.12em;text-transform:uppercase;margin-bottom:20px}\n.stag::before{content:'\u25cf';font-size:7px}\nh1.hh{font-size:clamp(38px,5.5vw,72px);font-weight:800;line-height:1.08;letter-spacing:-.02em;margin-bottom:20px}\nh1.hh .o{color:var(--orange)}\n.hsub{font-family:var(--mono);font-size:13px;color:var(--muted2);max-width:580px;line-height:1.8;margin-bottom:36px}\n.hsub strong{color:var(--muted3);font-weight:500}\n.install-note{font-family:var(--mono);font-size:10px;color:var(--muted);margin-bottom:48px}\n.stats{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--b);border:1px solid var(--b);border-radius:10px;overflow:hidden;margin-bottom:80px}\n.sc{background:var(--bg1);padding:22px 18px;text-align:center}\n.sn{font-family:var(--mono);font-size:28px;font-weight:700;color:var(--text);line-height:1;margin-bottom:3px}\n.sn em{color:var(--orange);font-style:normal}\n.sl{font-family:var(--mono);font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}\n.shd{margin-bottom:32px}\n.shd h2{font-size:clamp(22px,3vw,36px);font-weight:700;letter-spacing:-.02em;margin-top:6px}\n.shd p{font-family:var(--mono);font-size:12px;color:var(--muted2);margin-top:6px;line-height:1.7}\n.fg{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--b);border:1px solid var(--b);border-radius:12px;overflow:hidden;margin-bottom:80px}\n.fc{background:var(--bg1);padding:26px 22px;transition:background .2s}\n.fc:hover{background:var(--bg2)}\n.ftag{font-family:var(--mono);font-size:9px;color:var(--orange);text-transform:uppercase;letter-spacing:.12em;margin-bottom:9px;display:flex;align-items:center;gap:5px}\n.ftag::before{content:'\u25cf';font-size:6px}\n.fc h3{font-size:14px;font-weight:600;margin-bottom:6px;letter-spacing:-.01em}\n.fc p{font-family:var(--mono);font-size:11px;color:var(--muted2);line-height:1.65}\n.pills{display:flex;flex-wrap:wrap;gap:4px;margin-top:12px}\n.pl{font-family:var(--mono);font-size:9px;padding:2px 7px;border-radius:3px;background:var(--bg3);border:1px solid var(--b);color:var(--muted2)}\n.pl.new{background:var(--odim);border-color:rgba(249,115,22,.2);color:var(--orange)}\n.tools-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--b);border:1px solid var(--b);border-radius:12px;overflow:hidden;margin-bottom:80px}\n.tool-card{background:var(--bg1);padding:22px 18px;transition:background .2s;cursor:default}\n.tool-card:hover{background:var(--bg2)}\n.tool-icon{width:28px;height:28px;margin-bottom:12px;color:var(--orange);opacity:.85}\n.tool-icon svg{width:100%;height:100%}\n.tool-name{font-size:13px;font-weight:600;margin-bottom:5px;letter-spacing:-.01em}\n.tool-desc{font-family:var(--mono);font-size:10px;color:var(--muted);line-height:1.6}\n.term{background:var(--bg1);border:1px solid var(--b);border-radius:10px;overflow:hidden;margin-bottom:80px}\n.tbar{display:flex;align-items:center;gap:6px;padding:10px 14px;border-bottom:1px solid var(--b);background:rgba(0,0,0,.3)}\n.td{width:9px;height:9px;border-radius:50%}\n.td.r{background:#ff453a}.td.y{background:#ffd60a}.td.g{background:#32d74b}\n.ttit{font-family:var(--mono);font-size:10px;color:var(--muted);margin-left:4px}\n.tbody{padding:20px 22px;font-family:var(--mono);font-size:12px;line-height:2;min-height:280px}\n.tl{display:flex;gap:10px}\n.tps{color:var(--orange)}.tcmd{color:var(--text)}\n.tout{color:var(--muted2);padding-left:16px}\n.tout.ok{color:var(--green)}.tout.ac{color:var(--orange)}.tout.am{color:#fbbf24}.tout.er{color:#f87171}\n.tgap{height:4px}\n.channels{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:80px}\n.ch{background:var(--bg1);border:1px solid var(--b);border-radius:8px;padding:20px;transition:border-color .2s;display:flex;gap:12px;align-items:flex-start}\n.ch:hover{border-color:rgba(249,115,22,.2)}\n.ch-icon{width:22px;height:22px;flex-shrink:0;color:var(--orange);opacity:.8}\n.ch-icon svg{width:100%;height:100%}\n.ch-name{font-size:13px;font-weight:600;margin-bottom:2px}\n.ch-status{font-family:var(--mono);font-size:9px;margin-bottom:5px;font-weight:500}\n.ch-status.live{color:var(--green)}.ch-status.soon{color:#fbbf24}\n.ch-desc{font-family:var(--mono);font-size:10px;color:var(--muted);line-height:1.6}\n.ui-mock{background:var(--bg1);border:1px solid var(--b);border-radius:12px;overflow:hidden;margin-bottom:32px}\n.ui-mock-bar{display:flex;align-items:center;gap:6px;padding:10px 16px;border-bottom:1px solid var(--b);background:rgba(0,0,0,.35)}\n.ui-local-badge{margin-left:auto;display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9px;color:var(--green)}\n.ui-mock-body{display:grid;grid-template-columns:1fr 1px 360px;min-height:400px}\n.ui-divider{background:var(--b)}\n.ui-chat{display:flex;flex-direction:column;min-width:0}\n.chat-hd{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--b)}\n.chat-hd-title{font-family:var(--mono);font-size:11px;color:var(--muted3);font-weight:500}\n.chat-model-badge{font-family:var(--mono);font-size:9px;padding:2px 8px;border-radius:3px;background:var(--odim);border:1px solid rgba(249,115,22,.2);color:var(--orange)}\n.chat-messages{flex:1;padding:16px;display:flex;flex-direction:column;gap:12px;overflow:hidden}\n.msg{display:flex;flex-direction:column;gap:3px;max-width:90%}\n.msg.user{align-self:flex-end;align-items:flex-end}\n.msg.ai{align-self:flex-start;align-items:flex-start}\n.msg-lbl{font-family:var(--mono);font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:.07em}\n.msg-bubble{padding:9px 13px;border-radius:8px;font-family:var(--mono);font-size:12px;line-height:1.6}\n.msg.user .msg-bubble{background:var(--odim);border:1px solid rgba(249,115,22,.22);color:var(--text)}\n.msg.ai .msg-bubble{background:var(--bg2);border:1px solid var(--b);color:var(--muted3)}\n.chat-input-row{display:flex;align-items:center;gap:8px;padding:12px 16px;border-top:1px solid var(--b)}\n.chat-input-box{flex:1;background:var(--bg2);border:1px solid var(--b2);border-radius:6px;padding:8px 12px;font-family:var(--mono);font-size:12px;color:var(--muted3);min-height:34px;display:flex;align-items:center;gap:1px}\n.chat-cursor{color:var(--orange);animation:blink .7s infinite;line-height:1;font-weight:300;font-size:14px}\n.chat-send{width:32px;height:32px;background:var(--orange);border:none;border-radius:5px;color:#000;font-size:13px;cursor:pointer;flex-shrink:0;font-weight:700}\n.ui-log{display:flex;flex-direction:column;background:rgba(0,0,0,.18)}\n.log-hd{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--b)}\n.log-hd-title{font-family:var(--mono);font-size:11px;color:var(--muted3);font-weight:500}\n.log-live{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9px;color:var(--green)}\n.log-body{flex:1;padding:10px 14px;display:flex;flex-direction:column;gap:4px;overflow:hidden}\n.log-entry{display:flex;gap:8px;align-items:flex-start;opacity:0;transform:translateX(6px);transition:opacity .35s,transform .35s}\n.log-entry.show{opacity:1;transform:translateX(0)}\n.log-time{font-family:var(--mono);font-size:9px;color:var(--muted);min-width:34px;padding-top:2px;flex-shrink:0}\n.log-ic{font-size:12px;min-width:18px;padding-top:1px;flex-shrink:0}\n.log-txt{font-family:var(--mono);font-size:10px;line-height:1.55;color:var(--muted2)}\n.log-txt .ok{color:var(--green)}.log-txt .ac{color:var(--orange)}.log-txt .hi{color:var(--muted3)}\n.ui-callouts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:80px}\n.ui-callout{background:var(--bg1);border:1px solid var(--b);border-radius:8px;padding:20px;transition:border-color .2s}\n.ui-callout:hover{border-color:rgba(249,115,22,.22)}\n.uc-icon{font-size:18px;margin-bottom:9px}\n.uc-title{font-size:13px;font-weight:600;margin-bottom:5px}\n.uc-desc{font-family:var(--mono);font-size:11px;color:var(--muted);line-height:1.6}\n.ag{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-bottom:80px}\n.ac{background:var(--bg1);border:1px solid var(--b);border-radius:8px;padding:22px;transition:border-color .2s,background .15s}\n.ac:hover{border-color:rgba(249,115,22,.22);background:var(--bg2)}\n.ai{width:24px;height:24px;margin-bottom:12px;color:var(--orange);opacity:.75}\n.ai svg{width:100%;height:100%}\n.an{font-size:15px;font-weight:700;margin-bottom:4px}\n.ar{font-family:var(--mono);font-size:10px;color:var(--orange);margin-bottom:8px}\n.ad{font-family:var(--mono);font-size:11px;color:var(--muted2);line-height:1.6}\n.cc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:40px}\n.cc-card{background:var(--bg1);border:1px solid var(--b);border-radius:10px;padding:24px;transition:border-color .2s}\n.cc-card:hover{border-color:rgba(249,115,22,.22)}\n.cc-icon{width:28px;height:28px;margin-bottom:12px;color:var(--orange);opacity:.8}\n.cc-icon svg{width:100%;height:100%}\n.cc-name{font-size:14px;font-weight:600;margin-bottom:6px}\n.cc-desc{font-family:var(--mono);font-size:11px;color:var(--muted2);line-height:1.6}\n.cc-demo{background:var(--bg1);border:1px solid var(--b);border-radius:10px;padding:24px;margin-bottom:80px;display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:center}\n.cc-demo-text h3{font-size:18px;font-weight:700;margin-bottom:10px}\n.cc-demo-text p{font-family:var(--mono);font-size:11px;color:var(--muted2);line-height:1.7;margin-bottom:16px}\n.cc-flow{background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px;font-family:var(--mono);font-size:11px;line-height:2}\n.cc-flow .step{color:var(--muted2)}\n.cc-flow .step .num{color:var(--orange);margin-right:8px}\n.cc-flow .step .ok{color:var(--green)}\n.sw-demo{background:var(--bg1);border:1px solid var(--b);border-radius:10px;overflow:hidden;margin-bottom:80px}\n.sw-bar{display:flex;align-items:center;gap:6px;padding:10px 14px;border-bottom:1px solid var(--b);background:rgba(0,0,0,.3)}\n.sw-body{padding:24px;font-family:var(--mono);font-size:12px;line-height:2}\n.sw-body .hi{color:var(--orange)}\n.sw-body .ok{color:var(--green)}\n.sw-body .dim{color:var(--muted)}\n.who-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;margin-bottom:80px}\n.who-card{background:var(--bg1);border:1px solid var(--b);border-radius:10px;padding:20px 22px;transition:border-color .2s}\n.who-card:hover{border-color:rgba(249,115,22,.22)}\n.who-role{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);margin-bottom:8px}\n.who-task{font-family:var(--mono);font-size:12px;color:var(--muted2);line-height:1.7;font-style:italic}\n.wl-wrap{padding:80px 0}\n.wbox{background:var(--bg1);border:1px solid var(--b);border-radius:16px;padding:56px 48px;text-align:center;position:relative;overflow:hidden}\n.wbox::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 50% 0%,rgba(249,115,22,0.06) 0%,transparent 60%);pointer-events:none}\n.wbox h2{font-size:clamp(24px,3.5vw,42px);font-weight:800;letter-spacing:-.025em;margin-bottom:8px}\n.wbox-p{font-family:var(--mono);font-size:12px;color:var(--muted2);max-width:420px;margin:0 auto 32px;line-height:1.7}\n.wbadge{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10px;color:var(--muted2);background:var(--bg2);border:1px solid var(--b);border-radius:20px;padding:4px 12px;margin-bottom:24px}\n.wbadge span{color:var(--green);font-weight:500}\n.eform{display:flex;gap:8px;max-width:440px;margin:0 auto 24px;flex-wrap:wrap;justify-content:center}\n.einput{flex:1;min-width:200px;background:var(--bg2);border:1px solid var(--b2);border-radius:6px;padding:10px 14px;font-family:var(--mono);font-size:12px;color:var(--text);outline:none;transition:border-color .2s}\n.einput::placeholder{color:var(--muted)}\n.einput:focus{border-color:rgba(249,115,22,.4)}\n.einput.err{border-color:rgba(239,68,68,.5)!important}\n.btnp{background:var(--orange);border:none;border-radius:6px;padding:10px 20px;font-family:var(--mono);font-size:12px;font-weight:600;color:#000;cursor:pointer;transition:opacity .15s,transform .1s;white-space:nowrap}\n.btnp:hover{opacity:.88}\n.btnp:active{transform:scale(.97)}\n.wsuc{display:none;font-family:var(--mono);font-size:12px;color:var(--green);margin-bottom:20px}\n.divtxt{font-family:var(--mono);font-size:10px;color:var(--muted);margin-bottom:12px}\n.ctarow{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap}\n.gbtn{display:inline-flex;align-items:center;gap:6px;background:transparent;border:1px solid var(--b2);border-radius:6px;padding:9px 16px;font-family:var(--mono);font-size:11px;color:var(--muted2);text-decoration:none;transition:all .15s;cursor:pointer}\n.gbtn:hover{border-color:var(--b3);color:var(--text);background:var(--bg2)}\n.gbtn svg{width:14px;height:14px;flex-shrink:0}\n.gbtn.disc{border-color:rgba(88,101,242,.25);color:#7289da}\n.gbtn.disc:hover{background:rgba(88,101,242,.07);border-color:rgba(88,101,242,.4)}\n.fr-wrap{padding:0 0 80px}\n.fr-box{background:var(--bg1);border:1px solid var(--b);border-radius:12px;overflow:hidden}\n.fr-top{padding:28px 28px 0}\n.fr-top h3{font-size:18px;font-weight:700;margin-bottom:4px}\n.fr-top p{font-family:var(--mono);font-size:11px;color:var(--muted2);margin-bottom:20px}\n.fr-form{background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:20px;margin-bottom:20px}\n.fr-cats{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}\n.cat-btn{font-family:var(--mono);font-size:10px;padding:4px 10px;border-radius:4px;background:var(--bg3);border:1px solid var(--b);color:var(--muted2);cursor:pointer;transition:all .15s}\n.cat-btn:hover{border-color:var(--b3);color:var(--text)}\n.cat-btn.active{background:var(--odim);border-color:rgba(249,115,22,.35);color:var(--orange)}\n.fr-ta{width:100%;background:var(--bg);border:1px solid var(--b2);border-radius:6px;padding:10px 12px;font-family:var(--mono);font-size:12px;color:var(--text);resize:none;outline:none;line-height:1.6;transition:border-color .2s;min-height:80px}\n.fr-ta::placeholder{color:var(--muted)}\n.fr-ta:focus{border-color:rgba(249,115,22,.35)}\n.fr-submit-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px;flex-wrap:wrap;gap:8px}\n.fr-hint{font-family:var(--mono);font-size:10px;color:var(--muted)}\n.fr-submit{background:var(--orange);border:none;border-radius:5px;padding:8px 18px;font-family:var(--mono);font-size:11px;font-weight:600;color:#000;cursor:pointer;transition:opacity .15s}\n.fr-submit:hover{opacity:.85}\n.fr-feed{border-top:1px solid var(--b)}\n.fr-feed-hd{display:flex;align-items:center;justify-content:space-between;padding:14px 28px;border-bottom:1px solid var(--b)}\n.fr-feed-hd span{font-family:var(--mono);font-size:10px;color:var(--muted2);text-transform:uppercase;letter-spacing:.08em}\n.fr-feed-sort{display:flex;gap:4px}\n.sort-btn{font-family:var(--mono);font-size:9px;padding:3px 8px;border-radius:3px;background:var(--bg2);border:1px solid var(--b);color:var(--muted);cursor:pointer;transition:all .15s}\n.sort-btn.active{background:var(--bg3);color:var(--text);border-color:var(--b3)}\n.fr-list{padding:0 28px 20px}\n.fr-empty{font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;padding:36px 0}\n.fr-item{display:flex;gap:12px;align-items:flex-start;padding:16px 0;border-bottom:1px solid var(--b)}\n.fr-item:last-child{border-bottom:none}\n.fr-vote{display:flex;flex-direction:column;align-items:center;gap:3px;min-width:36px}\n.vbtn{background:var(--bg2);border:1px solid var(--b);border-radius:4px;width:32px;height:28px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:11px;transition:all .15s;flex-shrink:0}\n.vbtn:hover{border-color:rgba(249,115,22,.35);background:var(--odim)}\n.vbtn.voted{background:var(--odim);border-color:rgba(249,115,22,.4);color:var(--orange)}\n.vcount{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--muted3)}\n.fr-content{flex:1;min-width:0}\n.fr-meta{display:flex;align-items:center;gap:8px;margin-bottom:5px;flex-wrap:wrap}\n.cat-pill{font-family:var(--mono);font-size:9px;padding:2px 7px;border-radius:3px;background:var(--odim);border:1px solid rgba(249,115,22,.2);color:var(--orange)}\n.fr-time{font-family:var(--mono);font-size:9px;color:var(--muted)}\n.fr-text{font-family:var(--mono);font-size:12px;color:var(--muted3);line-height:1.6}\nfooter{border-top:1px solid var(--b);padding:32px 0}\n.fi{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:14px}\n.flogo{display:flex;align-items:center;gap:7px;font-family:var(--mono);font-size:11px;color:var(--muted)}\n.flinks{display:flex;gap:16px}\n.flink{font-family:var(--mono);font-size:10px;color:var(--muted);text-decoration:none;transition:color .15s}\n.flink:hover{color:var(--text)}\n@keyframes fadeUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n.a{opacity:0;animation:fadeUp .55s ease forwards}\n.d1{animation-delay:.07s}.d2{animation-delay:.15s}.d3{animation-delay:.23s}.d4{animation-delay:.31s}\n::-webkit-scrollbar{width:3px}::-webkit-scrollbar-track{background:var(--bg)}::-webkit-scrollbar-thumb{background:var(--b2);border-radius:2px}\n.bench-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:var(--b);border:1px solid var(--b);border-radius:12px;overflow:hidden;margin-bottom:80px}\n.bench-card{background:var(--bg1);padding:28px 20px 20px;transition:background .2s;cursor:default}\n.bench-card:hover{background:var(--bg2)}\n.bench-title{font-family:var(--mono);font-size:10px;color:var(--muted2);text-transform:uppercase;letter-spacing:.1em;margin-bottom:20px}\n.bench-bars{display:flex;align-items:flex-end;gap:8px;height:120px;margin-bottom:14px}\n.bench-bar-wrap{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1;height:100%}\n.bench-bar-track{width:100%;flex:1;position:relative;display:flex;align-items:flex-end}\n.bench-bar{width:100%;border-radius:4px 4px 0 0;height:0;transition:height 1s cubic-bezier(.22,1,.36,1);position:relative;cursor:pointer}\n.bench-bar-label{font-family:var(--mono);font-size:9px;color:var(--muted);text-align:center;white-space:nowrap}\n.bench-note{font-family:var(--mono);font-size:10px;color:var(--muted);line-height:1.5;border-top:1px solid var(--b);padding-top:12px;margin-top:2px}\n.bench-note .win-note{color:var(--orange)}\n.bench-tip{position:fixed;background:var(--bg2);border:1px solid var(--b2);border-radius:6px;padding:8px 12px;font-family:var(--mono);font-size:11px;color:var(--muted3);pointer-events:none;z-index:200;display:none;max-width:220px;line-height:1.5}\n.compare-legend{display:flex;align-items:center;gap:20px;flex-wrap:wrap;margin-bottom:32px;font-family:var(--mono);font-size:11px}\n.compare-tagline{font-family:var(--mono);font-size:13px;color:var(--muted2);text-align:center;margin-top:24px;padding-top:24px;border-top:1px solid var(--b)}\n.compare-tagline span{color:var(--orange)}\n@media(max-width:900px){.fg{grid-template-columns:1fr 1fr}.tools-grid{grid-template-columns:repeat(3,1fr)}.channels{grid-template-columns:1fr 1fr}.stats{grid-template-columns:repeat(3,1fr)}.cc-grid{grid-template-columns:1fr 1fr}.cc-demo{grid-template-columns:1fr}.bench-grid{grid-template-columns:repeat(2,1fr)}}\n@media(max-width:640px){.fg,.channels,.cc-grid{grid-template-columns:1fr}.tools-grid{grid-template-columns:repeat(2,1fr)}.stats{grid-template-columns:1fr 1fr}.nlinks .nl{display:none}.hero{padding:110px 0 52px}.wbox{padding:36px 20px}.eform{flex-direction:column}.einput{min-width:unset}.ui-mock-body{grid-template-columns:1fr}.ui-divider,.ui-log{display:none}.ui-callouts{grid-template-columns:1fr}.bench-grid{grid-template-columns:1fr}.who-grid{grid-template-columns:1fr}.ag{grid-template-columns:1fr}}\n</style>\n</head>\n<body>\n<canvas id=\"bg\"></canvas>\n\n<nav>\n  <div class=\"navi\">\n    <a class=\"nlogo\" href=\"#\"><div class=\"lsq\">A/</div>Aiden</a>\n    <div class=\"nbadge\"><span class=\"ndot\"></span>latest \u00b7 open source</div>\n    <div class=\"nlinks\">\n      <a class=\"nl\" href=\"#features\">features</a>\n      <a class=\"nl\" href=\"#computer\">computer control</a>\n      <a class=\"nl\" href=\"#compare\">why Aiden</a>\n      <a class=\"nl\" href=\"#request\">requests</a>\n      <a class=\"nl\" href=\"https://github.com/taracodlabs/aiden\" target=\"_blank\" rel=\"noopener\">github</a>\n      <a class=\"nl\" href=\"https://razorpay.me/@whitelotus9625\" target=\"_blank\" rel=\"noopener\">sponsor</a>\n      <a class=\"ncta\" href=\"https://github.com/taracodlabs/aiden-releases/releases/latest\">download free \u2192</a>\n    </div>\n  </div>\n</nav>\n\n<!-- CINEMATIC INTRO -->\n<section id=\"intro\" style=\"position:relative;z-index:1;height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 32px\">\n  <div id=\"introContent\" style=\"opacity:0;transform:translateY(16px);transition:opacity 1.1s ease,transform 1.1s ease\">\n    <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);letter-spacing:.2em;text-transform:uppercase;margin-bottom:28px\">by Taracod \u00b7 White Lotus</div>\n    <div id=\"glitchText\" style=\"font-size:clamp(52px,10vw,130px);font-weight:900;letter-spacing:-.03em;line-height:1;color:var(--text);font-family:var(--sans);min-height:1.15em\">&nbsp;</div>\n    <div style=\"font-size:clamp(52px,10vw,130px);font-weight:900;letter-spacing:-.03em;line-height:1.05;min-height:1.2em\">\n      <span id=\"typewriterText\" style=\"color:var(--orange)\"></span><span id=\"twCursor\" style=\"color:var(--orange);animation:blink .7s infinite;font-weight:900;font-family:var(--mono)\">_</span>\n    </div>\n    <div id=\"introTagline\" style=\"font-family:var(--mono);font-size:13px;color:var(--muted2);margin-top:32px;letter-spacing:.04em;opacity:0;transition:opacity .8s ease\">Your personal AI. Runs on your machine. Remembers everything.</div>\n  </div>\n  <div id=\"scrollHint\" style=\"position:absolute;bottom:40px;left:50%;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;opacity:0;transition:opacity .8s ease\">\n    <span style=\"font-family:var(--mono);font-size:9px;color:var(--muted);letter-spacing:.15em;text-transform:uppercase\">scroll</span>\n    <div style=\"width:1px;height:32px;background:linear-gradient(to bottom,var(--orange),transparent)\"></div>\n  </div>\n</section>\n\n<section class=\"hero z\">\n  <div class=\"wrap\">\n    <div class=\"stag a d1\">LOCAL-FIRST \u00b7 PRIVATE \u00b7 OPEN SOURCE \u00b7 BETA</div>\n    <h1 class=\"hh a d2\">Your local-first AI OS.<br><span class=\"o\">Runs on Windows + Linux.</span></h1>\n    <p class=\"hsub a d3\">\n      Fast cloud inference with local Ollama fallback. Multi-provider routing keeps Aiden responsive even when individual APIs hiccup.<br>\n      <strong>Your files, memory, and tools stay on your machine.</strong><br>\n      Open source. Zero lock-in.\n    </p>\n    <a href=\"#download\" class=\"ncta a d3\" style=\"display:inline-flex;align-items:center;gap:8px;font-size:13px;padding:12px 24px;border-radius:8px;text-decoration:none;margin-bottom:48px\">Download Free \u2192</a>\n    <div style=\"font-family:monospace;font-size:11px;color:#555;margin-top:8px;\">also available as CLI: npm run cli</div>\n    <div class=\"stats a d4\">\n      <div class=\"sc\"><div class=\"sn\"><em>15+</em></div><div class=\"sl\">AI providers</div></div>\n      <div class=\"sc\"><div class=\"sn\"><em>80+</em></div><div class=\"sl\">built-in tools</div></div>\n      <div class=\"sc\"><div class=\"sn\"><em>68</em></div><div class=\"sl\">bundled skills</div></div>\n      <div class=\"sc\"><div class=\"sn\"><em>&#10003;</em></div><div class=\"sl\">memory across sessions</div></div>\n      <div class=\"sc\"><div class=\"sn\"><em>1-click</em></div><div class=\"sl\">setup</div></div>\n    </div>\n  </div>\n</section>\n\n<section class=\"z\" style=\"padding:0 0 20px\">\n  <div class=\"wrap\">\n    <div style=\"background:var(--bg1);border:1px solid rgba(34,197,94,0.35);border-radius:12px;padding:20px 28px;display:flex;align-items:center;gap:20px;flex-wrap:wrap\">\n      <div style=\"display:flex;align-items:center;gap:8px;flex-shrink:0\">\n        <div style=\"width:8px;height:8px;border-radius:50%;background:var(--green);animation:blink 2s infinite\"></div>\n        <span style=\"font-family:var(--mono);font-size:11px;color:var(--green);font-weight:700;letter-spacing:.08em\">\u25cf OPEN SOURCE \u00b7 AGPL-3.0</span>\n      </div>\n      <div style=\"display:flex;gap:8px;flex-wrap:wrap;flex:1\">\n        <a href=\"https://github.com/taracodlabs/aiden\" target=\"_blank\" rel=\"noopener\"\n          style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:rgba(34,197,94,0.1);border:1px solid rgba(34,197,94,0.3);color:var(--green);text-decoration:none\">View on GitHub \u2192</a>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">Auditable, forkable, yours.</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">68 bundled skills.</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">19 providers supported.</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">Local Ollama fallback supported.</span>\n      </div>\n    </div>\n  </div>\n</section>\n\n<section class=\"z\" style=\"padding:0 0 48px\">\n  <div class=\"wrap\">\n    <div style=\"background:var(--bg1);border:1px solid rgba(249,115,22,.2);border-radius:12px;padding:20px 28px;display:flex;align-items:center;gap:20px;flex-wrap:wrap\">\n      <div style=\"display:flex;align-items:center;gap:8px;flex-shrink:0\">\n        <div style=\"width:8px;height:8px;border-radius:50%;background:var(--orange);animation:blink 2s infinite\"></div>\n        <span style=\"font-family:var(--mono);font-size:11px;color:var(--orange);font-weight:700;letter-spacing:.08em\">JUST UPDATED</span>\n      </div>\n      <div style=\"display:flex;gap:8px;flex-wrap:wrap;flex:1\">\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--odim);border:1px solid rgba(249,115,22,.2);color:var(--orange)\">v4.6</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">sub-agents</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">/spawn-pause</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">/recovery</span>\n        <span style=\"font-family:var(--mono);font-size:10px;padding:3px 10px;border-radius:4px;background:var(--bg2);border:1px solid var(--b);color:var(--muted2)\">56 tools \u00b7 68 skills</span>\n      </div>\n      <a href=\"https://github.com/taracodlabs/aiden-releases/releases/latest\"\n        target=\"_blank\" rel=\"noopener\"\n        style=\"font-family:var(--mono);font-size:10px;color:var(--muted);text-decoration:none;flex-shrink:0;white-space:nowrap\">\n        see full update →\n      </a>\n    </div>\n  </div>\n</section>\n\n<section class=\"wl-wrap z\" id=\"download\">\n  <div class=\"wrap\">\n    <div class=\"shd\" style=\"text-align:center\">\n      <div class=\"stag\" style=\"justify-content:center\">FREE AND OPEN SOURCE</div>\n      <h2>Local-first. Open source.</h2>\n      <p>No subscriptions. No paywalls. Download, run, and build.</p>\n    </div>\n\n\n    <div style=\"max-width:680px;margin:0 auto 48px\">\n      <div style=\"font-family:var(--mono);font-size:10px;color:var(--muted);letter-spacing:.1em;text-transform:uppercase;text-align:center;margin-bottom:16px\">ONE COMMAND — ANY PLATFORM</div>\n      <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 18px;display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px\">\n        <span style=\"font-family:var(--mono);font-size:15px;color:var(--text)\"><span style=\"color:var(--muted)\">$ </span>npx aiden-runtime</span>\n        <button onclick=\"(function(b){navigator.clipboard.writeText('npx aiden-runtime');b.textContent='copied ✓';setTimeout(function(){b.textContent='copy'},1500)})(this)\" style=\"font-family:var(--mono);font-size:11px;color:var(--orange);background:transparent;border:1px solid rgba(249,115,22,.3);border-radius:4px;padding:4px 10px;cursor:pointer;flex-shrink:0;white-space:nowrap\">copy</button>\n      </div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;margin-bottom:16px\">Any platform · Node.js 18+ · no cloning needed</div>\n      <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 18px;display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px\">\n        <span style=\"font-family:var(--mono);font-size:15px;color:var(--text)\"><span style=\"color:var(--muted)\">$ </span>irm aiden.taracod.com/install.ps1 | iex</span>\n        <button onclick=\"(function(b){navigator.clipboard.writeText('irm aiden.taracod.com/install.ps1 | iex');b.textContent='copied ✓';setTimeout(function(){b.textContent='copy'},1500)})(this)\" style=\"font-family:var(--mono);font-size:11px;color:var(--orange);background:transparent;border:1px solid rgba(249,115,22,.3);border-radius:4px;padding:4px 10px;cursor:pointer;flex-shrink:0;white-space:nowrap\">copy</button>\n      </div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;margin-bottom:10px\">Windows 10/11 · PowerShell 5.1+ · Node.js 18+</div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted3);text-align:center;margin-bottom:14px\">Same `aiden-runtime` package on every platform.</div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;margin-bottom:6px\">Linux &amp; macOS — install via CLI:</div>\n      <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 18px;display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px\">\n        <span style=\"font-family:var(--mono);font-size:15px;color:var(--text)\"><span style=\"color:var(--muted)\">$ </span>curl -fsSL aiden.taracod.com/install.sh | bash</span>\n        <button onclick=\"(function(b){navigator.clipboard.writeText(&#39;curl -fsSL aiden.taracod.com/install.sh | bash&#39;);b.textContent=&#39;copied &#10003;&#39;;setTimeout(function(){b.textContent=&#39;copy&#39;},1500)})(this)\" style=\"font-family:var(--mono);font-size:11px;color:var(--orange);background:transparent;border:1px solid rgba(249,115,22,.3);border-radius:4px;padding:4px 10px;cursor:pointer;flex-shrink:0;white-space:nowrap\">copy</button>\n      </div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;margin-bottom:24px\">Linux CLI fallback · WSL · Node 18+</div>\n      <div style=\"display:flex;justify-content:center;gap:12px;flex-wrap:wrap;margin-bottom:24px\">\n        <a href=\"https://www.npmjs.com/package/aiden-runtime\" target=\"_blank\" rel=\"noopener\" class=\"ncta\" style=\"text-decoration:none;padding:10px 20px\">Install via npm &#8594;</a>\n        <a href=\"https://github.com/taracodlabs/aiden\" target=\"_blank\" rel=\"noopener\" class=\"gbtn\">View on GitHub &#8594;</a>\n      </div>\n      <div style=\"border-top:1px solid var(--b);margin-bottom:20px\"></div>\n      <div style=\"font-family:var(--mono);font-size:11px;color:var(--muted);text-align:center;line-height:1.8\">68 bundled skills · 56 built-in tools · 19 providers · Local Ollama · AGPL-3.0 · No account · No telemetry</div>\n    </div>\n  </div>\n</section>\n\n<section id=\"features\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">HOW AIDEN WORKS</div>\n      <h2>Built differently.<br><span style=\"color:var(--orange)\">Works differently.</span></h2>\n      <p>Aiden doesn't just answer questions \u2014 it plans, executes, verifies, and learns. Every action is checked before moving on. Every success is remembered for next time.</p>\n    </div>\n    <div class=\"fg\">\n      <div class=\"fc\">\n        <div class=\"ftag\">Verified Execution</div>\n        <h3>Every action confirmed</h3>\n        <p>Before moving to the next step, Aiden checks that each action actually worked. Errors are detected, classified, and repaired automatically. Zero silent failures.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">auto-verified</span><span class=\"pl\">auto-repair</span><span class=\"pl\">no silent fails</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Goal to Done</div>\n        <h3>Tell it what you want</h3>\n        <p>Describe your goal in plain English. Aiden breaks it into steps, runs them in the right order, handles failures gracefully, and retries with a smarter approach each time.</p>\n        <div class=\"pills\"><span class=\"pl\">parallel execution</span><span class=\"pl\">smart retry</span><span class=\"pl\">auto replan</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Shared Context</div>\n        <h3>Always knows what's happening</h3>\n        <p>Every part of Aiden shares the same context at all times \u2014 what the goal is, what's been done, what's next. Nothing falls through the cracks between steps.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">full context</span><span class=\"pl\">no lost state</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Memory That Lasts</div>\n        <h3>Remembers everything</h3>\n        <p>Aiden remembers across sessions. Durable facts live in MEMORY.md, recent context is distilled into memory on `/quit`, and full session recall happens through `recall_session` for anything older. Always local, always yours.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">MEMORY.md</span><span class=\"pl\">recall_session</span><span class=\"pl\">cross-session</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Learns From Your Files</div>\n        <h3>Your knowledge, always available</h3>\n        <p>Upload your documents, books, and notes. Aiden reads them, understands them, and uses that knowledge in every task. Your personal knowledge base, always private, always local.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">local & private</span><span class=\"pl\">PDF \u00b7 EPUB \u00b7 MD \u00b7 TXT</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Gets Smarter Over Time</div>\n        <h3>Learns what works for you</h3>\n        <p>After every successful task, Aiden captures what worked and uses it next time. The more you use it, the more capable it becomes \u2014 specifically for the way you work.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">auto-learning</span><span class=\"pl\">personal to you</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Works On Any Machine</div>\n        <h3>Auto-configures for your hardware</h3>\n        <p>First run detects your GPU, RAM, and what's already installed. Aiden configures itself for your specific machine \u2014 never downloads what you already have, never overloads your system.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">hardware detection</span><span class=\"pl\">smart auto-setup</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Built to Never Crash</div>\n        <h3>Resilient by design</h3>\n        <p>Every capability has its own timeout and automatic retries. One thing failing never crashes the whole task. Aiden keeps going and finds another way.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">isolated failures</span><span class=\"pl\">automatic retry</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Any AI Model</div>\n        <h3>Your model, your choice</h3>\n        <p>Free local models work out of the box. Add any cloud API key for more power. Aiden automatically picks the right model for each part of a task \u2014 planning, execution, response.</p>\n        <div class=\"pills\"><span class=\"pl\">free local models</span><span class=\"pl\">groq</span><span class=\"pl\">gemini</span><span class=\"pl\">openai</span><span class=\"pl\">xAI</span><span class=\"pl\">DeepSeek</span><span class=\"pl\">Cerebras</span><span class=\"pl\">15+</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Voice I/O</div>\n        <h3>Talk to Aiden</h3>\n        <p>Speech-to-text runs locally on your GPU \u2014 no cloud API, no latency. Aiden speaks responses back with a natural voice. `/voice on` enables it from the CLI; `/listen` records and replies in your terminal.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">local speech</span><span class=\"pl\">natural voice</span><span class=\"pl\">no cloud</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Deep Research</div>\n        <h3>Real research, not just search</h3>\n        <p>Aiden doesn't just search \u2014 it researches. Multiple passes, identifies gaps, fills them with targeted follow-up searches, and synthesises everything into a clear answer.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">multi-pass</span><span class=\"pl\">gap detection</span><span class=\"pl\">real sources</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Always Checks Before Acting</div>\n        <h3>Plans before it does</h3>\n        <p>Every plan is validated before execution begins. Bad plans are caught and rewritten automatically. Aiden never wastes time running a plan that won't work.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">pre-execution check</span><span class=\"pl\">auto re-plan</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Sub-Agents</div>\n        <h3>Spawn focused workers</h3>\n        <p>Aiden spawns sub-agents for focused tasks. Run them in parallel for ensemble or partitioned work \u2014 3 to 5 children, merged into one answer. Each child gets its own intersected toolset, isolated from the parent.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">spawn_sub_agent</span><span class=\"pl\">subagent_fanout</span><span class=\"pl\">parallel</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Kill-Switch</div>\n        <h3>Pause spawning, safely</h3>\n        <p>Daemon running wild? `/spawn-pause on` blocks new sub-agents while in-flight children finish cleanly. Reason captured, status durable across restart, shared across REPL / daemon / MCP runtimes via a single marker.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">/spawn-pause</span><span class=\"pl\">operator-safe</span><span class=\"pl\">durable</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Self-Improvement</div>\n        <h3>Learns from its own failures</h3>\n        <p>Every failure gets a signature. Every recovery gets a report. Run `/recovery list` to see what's been breaking and how Aiden worked around it. Patterns persist across sessions in a durable SQLite ledger.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">/recovery</span><span class=\"pl\">TCE</span><span class=\"pl\">cross-session</span></div>\n    </div>\n  </div>\n</section>\n\n<section id=\"tools\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">WHAT AIDEN CAN DO</div>\n      <h2>Built-in capabilities.<br><span style=\"color:var(--orange)\">No plugins needed.</span></h2>\n      <p>Everything Aiden can do right out of the box \u2014 no setup, no extensions, no coding required.</p>\n    </div>\n    <div class=\"tools-grid\">\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/><path d=\"M8 9l3 3-3 3M13 15h3\"/></svg></div><div class=\"tool-name\">Run Commands</div><div class=\"tool-desc\">Executes system commands on your machine \u2014 installs packages, runs scripts, anything you'd type yourself.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"17\"/><line x1=\"9\" y1=\"14\" x2=\"15\" y2=\"14\"/></svg></div><div class=\"tool-name\">Create &amp; Edit Files</div><div class=\"tool-desc\">Creates, reads, updates, and deletes files and folders anywhere on your computer.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg></div><div class=\"tool-name\">Browse the Web</div><div class=\"tool-desc\">Opens websites, clicks links, fills forms \u2014 operates a real browser just like you would.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/></svg></div><div class=\"tool-name\">Search the Web</div><div class=\"tool-desc\">Searches across multiple sources with automatic fallback \u2014 always finds an answer, never gets blocked.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg></div><div class=\"tool-name\">Run Python Code</div><div class=\"tool-desc\">Writes and runs Python scripts \u2014 data analysis, automation, machine learning, anything Python can do.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/></svg></div><div class=\"tool-name\">Run JavaScript</div><div class=\"tool-desc\">Executes Node.js code \u2014 builds APIs, processes data, runs tests, interacts with packages.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\"/><path d=\"M8 21h8M12 17v4\"/></svg></div><div class=\"tool-name\">Windows Automation</div><div class=\"tool-desc\">Runs Windows system scripts natively \u2014 manages settings, processes, services, and system tasks.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/></svg></div><div class=\"tool-name\">Send Notifications</div><div class=\"tool-desc\">Sends desktop alerts when tasks complete, fail, or need your attention \u2014 always keeps you informed.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\"/><rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\"/><line x1=\"6\" y1=\"6\" x2=\"6.01\" y2=\"6\"/><line x1=\"6\" y1=\"18\" x2=\"6.01\" y2=\"18\"/></svg></div><div class=\"tool-name\">System Awareness</div><div class=\"tool-desc\">Reads your GPU, CPU, RAM, and disk usage \u2014 Aiden knows your machine and works within its limits.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.3h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L7.91 9a16 16 0 0 0 6.1 6.1l1.06-.97a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"/></svg></div><div class=\"tool-name\">Deploy to Vercel</div><div class=\"tool-desc\">Calls the Vercel CLI via shell to push projects live \u2014 Aiden handles the deploy flow including auth check and post-deploy URL capture.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"18\" cy=\"18\" r=\"3\"/><circle cx=\"6\" cy=\"6\" r=\"3\"/><path d=\"M13 6h3a2 2 0 0 1 2 2v7\"/><line x1=\"6\" y1=\"9\" x2=\"6\" y2=\"21\"/></svg></div><div class=\"tool-name\">Git &amp; GitHub</div><div class=\"tool-desc\">Commits code, pushes to GitHub, manages branches \u2014 full version control built in.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg></div><div class=\"tool-name\">Fetch Any URL</div><div class=\"tool-desc\">Downloads content from any web address \u2014 APIs, JSON data, HTML pages, raw files.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z\"/><line x1=\"16\" y1=\"8\" x2=\"2\" y2=\"22\"/><line x1=\"17.5\" y1=\"15\" x2=\"9\" y2=\"15\"/></svg></div><div class=\"tool-name\">Plugin Support</div><div class=\"tool-desc\">Connects to any external tool or service \u2014 extend Aiden's capabilities without coding.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg></div><div class=\"tool-name\">Screen Capture</div><div class=\"tool-desc\">Takes screenshots of your screen \u2014 used for visual automation and computer control.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M5 12h14M12 5l7 7-7 7\"/></svg></div><div class=\"tool-name\">Mouse &amp; Keyboard</div><div class=\"tool-desc\">Keyboard and mouse automation on Windows \u2014 partial today. Covers app launch, key combos, and basic input via `app_input` / `app_launch`.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"/></svg></div><div class=\"tool-name\">Deep Research</div><div class=\"tool-desc\">Multi-pass research with gap detection \u2014 broad overview, then targeted follow-ups until nothing is missing.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\"/><path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\"/></svg></div><div class=\"tool-name\">Knowledge Base</div><div class=\"tool-desc\">Upload your files \u2014 Aiden learns from them. PDF, EPUB, TXT, MD. Stays on your machine, always private.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"2\"/><path d=\"M12 2v3M12 19v3M4.22 4.22l2.12 2.12M17.66 17.66l2.12 2.12M2 12h3M19 12h3M4.22 19.78l2.12-2.12M17.66 6.34l2.12-2.12\"/></svg></div><div class=\"tool-name\">Visual Automation</div><div class=\"tool-desc\">Aiden takes screenshots and reads them via vision-capable models \u2014 describes what's on screen and reasons about the next step. Not a closed-loop autopilot.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/></svg></div><div class=\"tool-name\">Voice Input</div><div class=\"tool-desc\">Local speech-to-text \u2014 talk to Aiden hands-free. Runs on your GPU, nothing goes to any server.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"/><path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\"/><path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\"/></svg></div><div class=\"tool-name\">Voice Output</div><div class=\"tool-desc\">Aiden speaks responses back with a natural voice. No cloud service needed \u2014 runs locally.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"/></svg></div><div class=\"tool-name\">Learns as it Works</div><div class=\"tool-desc\">After every successful task, Aiden captures what worked and applies it automatically next time.</div></div>\n      <div class=\"tool-card\"><div class=\"tool-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M9 11l3 3L22 4\"/><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/></svg></div><div class=\"tool-name\">Scheduled Tasks</div><div class=\"tool-desc\">Create one-shot tasks in plain English. Aiden runs them immediately or on your next prompt.</div></div>\n    </div>\n    <div class=\"term\">\n      <div class=\"tbar\">\n        <div class=\"td r\"></div><div class=\"td y\"></div><div class=\"td g\"></div>\n        <span class=\"ttit\">aiden \u2014 live</span>\n        <span style=\"margin-left:auto;font-family:var(--mono);font-size:9px;color:var(--green);display:flex;align-items:center;gap:5px\"><span style=\"width:5px;height:5px;border-radius:50%;background:var(--green);display:inline-block;animation:blink 1.2s infinite\"></span>local \u00b7 no data sent</span>\n      </div>\n      <div class=\"tbody\" id=\"termBody\" style=\"min-height:280px\"></div>\n    </div>\n  </div>\n</section>\n\n<div style=\"display:flex;gap:32px;justify-content:center;flex-wrap:wrap;padding:40px 20px;max-width:1000px;margin:0 auto;\"><div style=\"max-width:220px;font-size:13px;color:#666;line-height:1.6;\"><span style=\"color:#f97316;font-weight:600;\">7 instant actions</span> — open apps, play music, control volume, zero latency</div><div style=\"max-width:220px;font-size:13px;color:#666;line-height:1.6;\"><span style=\"color:#f97316;font-weight:600;\">Security hardened</span> — shell allowlist, browser isolation, encrypted storage</div><div style=\"max-width:220px;font-size:13px;color:#666;line-height:1.6;\"><span style=\"color:#f97316;font-weight:600;\">Telegram + CLI</span> — chat from phone or terminal, same brain</div><div style=\"max-width:220px;font-size:13px;color:#666;line-height:1.6;\"><span style=\"color:#f97316;font-weight:600;\">IDE compatible</span> — plug into VS Code or Cursor as a local AI backend</div></div>\n\n<!-- COMPUTER CONTROL -->\n<section id=\"computer\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">COMPUTER CONTROL</div>\n      <h2>Aiden can control your computer.</h2>\n      <p>Aiden sees your screen, understands what's there, and takes action. It tries the smart way first, falls back to visual control if needed, and always asks before doing anything risky.</p>\n    </div>\n    <div class=\"cc-grid\">\n      <div class=\"cc-card\">\n        <div class=\"cc-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"/></svg></div>\n        <div class=\"cc-name\">Screen Vision</div>\n        <div class=\"cc-desc\">Aiden takes a screenshot, understands what's on the screen, decides what to do, does it, and verifies it worked. Repeats until the goal is done. All locally, all safely.</div>\n      </div>\n      <div class=\"cc-card\">\n        <div class=\"cc-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\"/><path d=\"M16 3h-8l-2 4h12z\"/></svg></div>\n        <div class=\"cc-name\">Smart Execution</div>\n        <div class=\"cc-desc\">Aiden checks if a service has a proper API before touching the UI. Gmail, Sheets, GitHub, Notion \u2014 it uses their APIs directly. Screen automation is the fallback, not the default. Far more reliable.</div>\n      </div>\n      <div class=\"cc-card\">\n        <div class=\"cc-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/></svg></div>\n        <div class=\"cc-name\">Safety Gate</div>\n        <div class=\"cc-desc\">Before any risky action \u2014 file deletion, sending something externally, anything destructive \u2014 Aiden stops and asks for your approval. You're always in control. 60 second timeout.</div>\n      </div>\n    </div>\n    <div class=\"cc-demo\">\n      <div class=\"cc-demo-text\">\n        <h3>How it works in practice</h3>\n        <p>Give Aiden a goal like \"reply to my unread emails\" and watch it figure out the best approach. It checks for a direct API first, uses it if available, falls back to screen control if not. Every step is verified before moving on.</p>\n        <div class=\"pills\">\n          <span class=\"pl new\">smart first</span>\n          <span class=\"pl\">screen vision</span>\n          <span class=\"pl\">always verified</span>\n          <span class=\"pl\">learns for next time</span>\n        </div>\n      </div>\n      <div class=\"cc-flow\">\n        <div class=\"step\"><span class=\"num\">1</span>\"Reply to my unread emails\"</div>\n        <div class=\"step\"><span class=\"num\">2</span><span style=\"color:var(--orange)\">Safety Gate</span> \u2192 approval requested</div>\n        <div class=\"step\"><span class=\"num\">3</span><span style=\"color:var(--orange)\">Smart Execution</span> \u2192 Gmail API found \u2713</div>\n        <div class=\"step\"><span class=\"num\">4</span><span style=\"color:var(--orange)\">Screen Vision</span> \u2192 screenshot taken</div>\n        <div class=\"step\"><span class=\"num\">5</span>Action decided \u00b7 confidence: high</div>\n        <div class=\"step\"><span class=\"num\">6</span><span style=\"color:var(--green)\">Verified</span> \u2192 email sent \u2713</div>\n        <div class=\"step\"><span class=\"num\">7</span><span style=\"color:var(--green)\">Learned</span> \u2192 pattern saved for next time</div>\n        <div class=\"step\"><span class=\"num\">8</span><span style=\"color:var(--green)\">Done in 2 steps \u00b7 faster next time</span></div>\n      </div>\n    </div>\n  </div>\n</section>\n\n</section>\n\n<section id=\"smarter\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">GETS SMARTER EVERY DAY</div>\n      <h2>The more you use it,<br><span style=\"color:var(--orange)\">the better it gets.</span></h2>\n      <p>Most apps are the same on day 1 as day 100. Aiden is different. Every time you use it, it quietly learns how you work — what you like, what you don't, how you prefer things done. After a few weeks it feels like it knows you.</p>\n    </div>\n\n    <div class=\"fg\" style=\"margin-bottom:48px\">\n      <div class=\"fc\">\n        <div class=\"ftag\">Remembers what worked</div>\n        <h3>Learns your shortcuts</h3>\n        <p>When Aiden finds a good way to do something, it remembers it. Next time you ask for something similar, it already knows the best approach — no need to explain twice.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">automatic</span><span class=\"pl\">gets faster over time</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Knows your preferences</div>\n        <h3>Feels personal to you</h3>\n        <p>Aiden picks up on how you like things — short answers or detailed ones, bullet points or paragraphs, formal or casual. It adjusts without you having to ask.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">learns from you</span><span class=\"pl\">no setup needed</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Builds new skills</div>\n        <h3>Teaches itself new tricks</h3>\n        <p>When Aiden notices it keeps doing the same thing successfully, it turns that into a permanent skill. The more you use it, the more capable it becomes.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">self-improving</span><span class=\"pl\">yours forever</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Skill Library</div>\n        <h3>68 bundled skills auto-load on demand</h3>\n        <p>Aiden ships 68 bundled skills covering development, security, trading, productivity, and more. Successful patterns get mined into new skill candidates automatically \u2014 review them with `/skills review`, promote keepers with `/skills accept &lt;id&gt;`.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\">68 bundled skills</span><span class=\"pl\">auto-mined</span><span class=\"pl\">/skills review</span></div>\n      </div>\n      <div class=\"fc\">\n        <div class=\"ftag\">Context Budget</div>\n        <h3>Always knows what's left</h3>\n        <p>Real-time context tracking shows how many tokens remain before the window fills. Use to see memory citations, active skills, provider health, and budget remaining \u2014 all at a glance.</p>\n        <div class=\"pills\"><span class=\"pl new\">new</span><span class=\"pl\"></span><span class=\"pl\">token budget</span><span class=\"pl\">provider health</span></div>\n      </div>\n    </div>\n\n    <div style=\"background:var(--bg1);border:1px solid var(--b);border-radius:12px;padding:28px;margin-bottom:80px\">\n      <div style=\"font-family:var(--mono);font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.1em;margin-bottom:20px\">Aiden growing with you over time</div>\n      <div style=\"display:grid;grid-template-columns:repeat(4,1fr);gap:16px;text-align:center\">\n        <div>\n          <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted);margin-bottom:12px;text-transform:uppercase\">Day 1</div>\n          <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 12px\">\n            <div style=\"font-family:var(--mono);font-size:22px;font-weight:800;color:var(--muted);line-height:1;margin-bottom:4px\">0</div>\n            <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted)\">habits learned</div>\n          </div>\n          <div style=\"height:3px;background:var(--bg3);border-radius:2px;margin-top:8px\"><div style=\"height:100%;width:5%;background:var(--orange);border-radius:2px\"></div></div>\n        </div>\n        <div>\n          <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted);margin-bottom:12px;text-transform:uppercase\">Week 1</div>\n          <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 12px\">\n            <div style=\"font-family:var(--mono);font-size:22px;font-weight:800;color:var(--muted2);line-height:1;margin-bottom:4px\">12</div>\n            <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted)\">habits learned</div>\n          </div>\n          <div style=\"height:3px;background:var(--bg3);border-radius:2px;margin-top:8px\"><div style=\"height:100%;width:30%;background:var(--orange);border-radius:2px\"></div></div>\n        </div>\n        <div>\n          <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted);margin-bottom:12px;text-transform:uppercase\">Month 1</div>\n          <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 12px\">\n            <div style=\"font-family:var(--mono);font-size:22px;font-weight:800;color:var(--orange);line-height:1;margin-bottom:4px\">47</div>\n            <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted)\">habits learned</div>\n          </div>\n          <div style=\"height:3px;background:var(--bg3);border-radius:2px;margin-top:8px\"><div style=\"height:100%;width:65%;background:var(--orange);border-radius:2px\"></div></div>\n        </div>\n        <div>\n          <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted);margin-bottom:12px;text-transform:uppercase\">Month 3</div>\n          <div style=\"background:var(--bg2);border:1px solid var(--b);border-radius:8px;padding:16px 12px\">\n            <div style=\"font-family:var(--mono);font-size:22px;font-weight:800;color:var(--orange);line-height:1;margin-bottom:4px\">120+</div>\n            <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted)\">habits learned</div>\n          </div>\n          <div style=\"height:3px;background:var(--bg3);border-radius:2px;margin-top:8px\"><div style=\"height:100%;width:100%;background:var(--orange);border-radius:2px\"></div></div>\n        </div>\n      </div>\n      <div style=\"font-family:var(--mono);font-size:10px;color:var(--muted);text-align:center;margin-top:20px;padding-top:20px;border-top:1px solid var(--b)\">\n        Every habit stays on your machine. Nothing is shared. Ever.\n      </div>\n    </div>\n  </div>\n</section>\n\n<section id=\"channels\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">ACCESS FROM ANYWHERE</div>\n      <h2>Control Aiden from anywhere.</h2>\n      <p>Send a goal from your phone. Get results on any device. Multiple ways to reach Aiden \u2014 all working out of the box.</p>\n    </div>\n    <div class=\"channels\">\n      <div class=\"ch\"><div class=\"ch-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M21.16 4.99a10 10 0 0 0-17.84 8.02L2 22l9.07-1.31a10 10 0 0 0 10.09-15.7z\"/></svg></div><div><div class=\"ch-name\">Telegram</div><div class=\"ch-status live\">\u25cf Live</div><div class=\"ch-desc\">Send goals from your phone. Approve risky actions via inline keyboard. Get notified when tasks complete.</div></div></div>\n      <div class=\"ch\"><div class=\"ch-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.3h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 9a16 16 0 0 0 6.1 6.1l.93-.86a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z\"/></svg></div><div><div class=\"ch-name\">WhatsApp</div><div class=\"ch-status live\">\u25cf Live</div><div class=\"ch-desc\">Send goals from your number. Get completion notifications. No third-party API \u2014 runs entirely on your machine.</div></div></div>\n      <div class=\"ch\"><div class=\"ch-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg></div><div><div class=\"ch-name\">Discord</div><div class=\"ch-status live\">\u25cf Live</div><div class=\"ch-desc\">Goal notifications to any channel or DM. Auto-starts when configured.</div></div></div>\n      <div class=\"ch\"><div class=\"ch-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M21 2H3v16h5v4l4-4h5l4-4V2zM11 11V7M16 11V7\"/></svg></div><div><div class=\"ch-name\">Slack</div><div class=\"ch-status live\">\u25cf Live</div><div class=\"ch-desc\">Start goals via DM. Completion and failure notifications to any channel.</div></div></div>\n      <div class=\"ch\"><div class=\"ch-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z\"/><polyline points=\"22,6 12,13 2,6\"/></svg></div><div><div class=\"ch-name\">Email</div><div class=\"ch-status live\">\u25cf Live</div><div class=\"ch-desc\">Email a goal and get a reply when it's done. Full execution summary included.</div></div></div>\n    </div>\n  </div>\n</section>\n\n<section id=\"capabilities\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">WHAT AIDEN SPECIALISES IN</div>\n      <h2>Expert across every domain.</h2>\n      <p>Aiden automatically applies the right expertise for your task. You describe the goal \u2014 Aiden figures out the best approach.</p>\n    </div>\n    <div class=\"ag\">\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/></svg></div>\n        <div class=\"an\">Research</div>\n        <div class=\"ar\">Intelligence & Investigation</div>\n        <div class=\"ad\">Deep web research, market analysis, competitive intelligence, fact-checking. Multi-pass with gap detection \u2014 nothing gets missed.</div>\n      </div>\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg></div>\n        <div class=\"an\">Code & Engineering</div>\n        <div class=\"ar\">Build, Debug, Deploy</div>\n        <div class=\"ad\">Writes, tests, and deploys code across any language. Debugs systematically. Auto-rolls back on deploy failure. Works end to end.</div>\n      </div>\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><polyline points=\"14 2 14 8 20 8\"/></svg></div>\n        <div class=\"an\">Files & Data</div>\n        <div class=\"ar\">Organise, Analyse, Process</div>\n        <div class=\"ad\">Reads, writes, and organises your files. Analyses spreadsheets, PDFs, and documents. Generates reports. Processes data with Python.</div>\n      </div>\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"/></svg></div>\n        <div class=\"an\">Computer Control</div>\n        <div class=\"ar\">Automate Anything</div>\n        <div class=\"ad\">Sees your screen and takes action. Clicks, types, opens apps, fills forms. Works on any application without special setup.</div>\n      </div>\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"10\"/><line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"4\"/><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"14\"/></svg></div>\n        <div class=\"an\">Analysis & Finance</div>\n        <div class=\"ar\">Data, Markets, Insights</div>\n        <div class=\"ad\">SQL queries, data visualisation, stock and market data, financial analysis. Numbers with confidence \u2014 always shows its working.</div>\n      </div>\n      <div class=\"ac\">\n        <div class=\"ai\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"/></svg></div>\n        <div class=\"an\">Writing & Content</div>\n        <div class=\"ar\">Draft, Edit, Publish</div>\n        <div class=\"ad\">Emails, reports, documentation, marketing copy, SEO content. Active voice, clear structure \u2014 never invents facts.</div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<section id=\"compare\" class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">WHY AIDEN</div>\n      <h2>What living on your machine<br><span style=\"color:var(--orange)\">actually means.</span></h2>\n      <p>Cloud AI is powerful. But it lives in a browser tab, forgets you exist between sessions, and can never touch your computer. Aiden is different in ways that matter.</p>\n    </div>\n    <div style=\"position:relative;margin-bottom:32px\">\n      <!-- Orange glow blobs behind the table -->\n      <div style=\"position:absolute;top:-60px;left:-40px;width:320px;height:320px;background:radial-gradient(circle,rgba(249,115,22,0.18) 0%,transparent 70%);pointer-events:none;z-index:0;filter:blur(40px)\"></div>\n      <div style=\"position:absolute;bottom:-40px;right:-40px;width:260px;height:260px;background:radial-gradient(circle,rgba(249,115,22,0.12) 0%,transparent 70%);pointer-events:none;z-index:0;filter:blur(50px)\"></div>\n      <!-- Glass table -->\n      <div style=\"position:relative;z-index:1;background:rgba(20,20,20,0.55);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border:1px solid rgba(249,115,22,0.18);border-radius:18px;overflow:hidden;box-shadow:0 8px 48px rgba(0,0,0,0.45),inset 0 1px 0 rgba(255,255,255,0.04)\">\n        <!-- Header -->\n        <div style=\"display:grid;grid-template-columns:1fr 180px 180px;border-bottom:1px solid rgba(249,115,22,0.12);background:rgba(249,115,22,0.04)\">\n          <div style=\"padding:18px 28px;font-family:var(--mono);font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.12em\">Capability</div>\n          <div style=\"padding:18px 28px;font-family:var(--mono);font-size:12px;font-weight:700;color:var(--orange);text-align:center;border-left:1px solid rgba(249,115,22,0.15);letter-spacing:.04em\">Aiden</div>\n          <div style=\"padding:18px 28px;font-family:var(--mono);font-size:12px;font-weight:600;color:var(--muted2);text-align:center;border-left:1px solid rgba(249,115,22,0.15);letter-spacing:.04em\">Cloud AI</div>\n        </div>\n        <!-- Rows -->\n        <div id=\"compareRows\"></div>\n      </div>\n    </div>\n    <div style=\"font-family:var(--mono);font-size:13px;color:var(--muted2);text-align:center;padding:8px 0 48px\">\n      <span style=\"color:var(--orange)\">\"Cloud AI answers questions.</span> Aiden does things.\"\n    </div>\n  </div>\n</section>\n\n<section class=\"z\" id=\"business\" style=\"padding:0 0 80px\">\n  <div class=\"wrap\">\n    <div class=\"shd\" style=\"text-align:center;padding:0 0 40px\">\n      <div class=\"stag\" style=\"justify-content:center\">FOR TEAMS</div>\n      <h2>Custom skills.<br><span style=\"color:var(--orange)\">Serious automation.</span></h2>\n      <p>Need Aiden wired into your stack? We build bespoke integrations and provide enterprise support.</p>\n    </div>\n\n    <div style=\"display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;max-width:900px;margin:0 auto 48px\">\n\n      <!-- Custom Skills -->\n      <div style=\"background:var(--bg1);border:1px solid rgba(249,115,22,0.25);border-radius:16px;padding:32px 24px\">\n        <div style=\"font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.12em;margin-bottom:12px;color:var(--muted)\">Custom Skills</div>\n        <div style=\"font-family:var(--mono);font-size:13px;color:var(--muted);margin-bottom:12px\">Typical engagement: 2–6 weeks</div>\n        <p style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);line-height:1.6;margin:0 0 20px\">We build custom Aiden skills wired into your stack — any API, any internal tool, fully integrated with your workflows. Source included, deployed to your instance, delivered in weeks not months.</p>\n        <ul style=\"list-style:none;padding:0;margin:0 0 28px;display:flex;flex-direction:column;gap:10px\">\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>We build the skill for you</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Any API or internal tool</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Deployed to your instance</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Full source included</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>2 revision rounds</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Delivered in 2 weeks</li>\n        </ul>\n        <a href=\"/contact?type=custom-skills\" style=\"font-family:var(--mono);font-size:13px;color:var(--orange);text-decoration:none\">Get in touch &#8594;</a>\n      </div>\n\n      <!-- Sponsored Partnerships -->\n      <div style=\"background:var(--bg1);border:1px solid rgba(249,115,22,0.25);border-radius:16px;padding:32px 24px\">\n        <div style=\"font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.12em;margin-bottom:12px;color:var(--muted)\">Sponsored Partnerships</div>\n        <div style=\"font-family:var(--mono);font-size:13px;color:var(--muted);margin-bottom:12px\">Ideal for API providers, dev tools, and fintechs</div>\n        <p style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);line-height:1.6;margin:0 0 20px\">Fund a feature or skill that ships in the public release. Your logo and attribution in the README, priority placement on the roadmap, and permanent contributor credit.</p>\n        <ul style=\"list-style:none;padding:0;margin:0 0 28px;display:flex;flex-direction:column;gap:10px\">\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Fund a skill or feature</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Logo &amp; attribution in README</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Priority roadmap slot</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Co-announce opportunity</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Early access to new releases</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Permanent contributor credit</li>\n        </ul>\n        <a href=\"/contact?type=sponsored\" style=\"font-family:var(--mono);font-size:13px;color:var(--orange);text-decoration:none\">Partner with us &#8594;</a>\n      </div>\n\n      <!-- Self-Hosted Enterprise -->\n      <div style=\"background:var(--bg1);border:1px solid rgba(249,115,22,0.25);border-radius:16px;padding:32px 24px\">\n        <div style=\"font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.12em;margin-bottom:12px;color:var(--muted)\">Self-Hosted Enterprise</div>\n        <div style=\"font-family:var(--mono);font-size:13px;color:var(--muted);margin-bottom:12px\">Custom pricing based on scope</div>\n        <p style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);line-height:1.6;margin:0 0 20px\">Air-gapped deployment, SSO and access controls, dedicated support channel, custom model integrations, SLA options. Run Aiden fully on-prem or in your private cloud.</p>\n        <ul style=\"list-style:none;padding:0;margin:0 0 28px;display:flex;flex-direction:column;gap:10px\">\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Air-gapped deployment</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>SSO &amp; access controls</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Dedicated support channel</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>Custom model integrations</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>SLA available</li>\n          <li style=\"font-family:var(--mono);font-size:12px;color:var(--muted2);display:flex;gap:8px\"><span style=\"color:var(--green);flex-shrink:0\">&#10003;</span>On-prem or private cloud</li>\n        </ul>\n        <a href=\"/contact?type=enterprise\" style=\"font-family:var(--mono);font-size:13px;color:var(--orange);text-decoration:none\">Talk to us &#8594;</a>\n      </div>\n\n    </div>\n\n    <div style=\"text-align:center;margin-top:8px\">\n      <a href=\"mailto:contact@taracod.com\" style=\"font-family:var(--mono);font-size:12px;color:var(--muted);text-decoration:none\">contact@taracod.com</a>\n    </div>\n  </div>\n</section>\n\n<section class=\"z\" style=\"padding:0 0 80px\">\n<div class=\"wrap\">\n    <div class=\"shd\">\n      <div class=\"stag\">ROADMAP</div>\n      <h2>What should we build next?</h2>\n      <p>Submit a feature request. Upvote what others are asking for. We read every single one.</p>\n    </div>\n    <div class=\"fr-box\">\n      <div class=\"fr-top\">\n        <h3>Request a feature</h3>\n        <p>Pick a category and describe your idea briefly.</p>\n        <div class=\"fr-form\">\n          <div class=\"fr-cats\" id=\"catRow\">\n            <button class=\"cat-btn active\" onclick=\"selectCat(this,'tools')\">tools</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'automation')\">automation</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'memory')\">memory</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'channels')\">channels</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'voice')\">voice</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'privacy')\">privacy</button>\n            <button class=\"cat-btn\" onclick=\"selectCat(this,'other')\">other</button>\n          </div>\n          <textarea class=\"fr-ta\" id=\"frText\" placeholder=\"e.g. Add a Notion integration so Aiden can read and write directly to my pages...\" rows=\"3\"></textarea>\n          <div class=\"fr-submit-row\">\n            <span class=\"fr-hint\" id=\"frHint\">Select a category and describe your idea.</span>\n            <button class=\"fr-submit\" onclick=\"submitReq()\">Submit Request \u2192</button>\n          </div>\n        </div>\n      </div>\n      <div class=\"fr-feed\">\n        <div class=\"fr-feed-hd\">\n          <span id=\"reqCount\">0 requests</span>\n          <div class=\"fr-feed-sort\">\n            <button class=\"sort-btn active\" onclick=\"sortBy('votes',this)\">top</button>\n            <button class=\"sort-btn\" onclick=\"sortBy('new',this)\">new</button>\n          </div>\n        </div>\n        <div class=\"fr-list\" id=\"frList\">\n          <div class=\"fr-empty\" id=\"frEmpty\">No requests yet \u2014 be the first to suggest something!</div>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<footer class=\"z\">\n  <div class=\"wrap\">\n    <div class=\"fi\">\n      <div class=\"flogo\">\n        <div class=\"lsq\" style=\"width:20px;height:20px;font-size:9px;border-radius:4px\">A/</div>\n        Aiden \u00a9 2026 \u00b7 Built by <a href=\"https://taracod.com\" target=\"_blank\" rel=\"noopener\" style=\"color:var(--orange);text-decoration:none\">Shiva Deore</a> \u00b7 <a href=\"https://taracod.com\" target=\"_blank\" rel=\"noopener\" style=\"color:var(--orange);text-decoration:none\">Taracod</a> \u00b7 White Lotus\n      </div>\n      <div class=\"flinks\">\n        <a class=\"flink\" href=\"#who\">who uses it</a>\n        <a class=\"flink\" href=\"#features\">what it does</a>\n        <a class=\"flink\" href=\"#computer\">computer control</a>\n        <a class=\"flink\" href=\"#capabilities\">capabilities</a>\n        <a class=\"flink\" href=\"#compare\">why aiden</a>\n        <a class=\"flink\" href=\"#download\">download</a>\n        <a class=\"flink\" href=\"#request\">requests</a>\n        <a class=\"flink\" href=\"/privacy\">privacy</a>\n        <a class=\"flink\" href=\"/terms\">terms</a>\n        <a class=\"flink\" href=\"/disclaimer\">disclaimer</a>\n      </div>\n      <div style=\"display:flex;align-items:center;gap:8px\">\n        <a href=\"https://discord.gg/gMZ3hUnQTm\" target=\"_blank\" rel=\"noopener\" style=\"font-family:var(--mono);font-size:10px;color:var(--muted);text-decoration:none\" onmouseover=\"this.style.color='#7289da'\" onmouseout=\"this.style.color='var(--muted)'\">Discord</a>\n        <span style=\"color:var(--b2)\">\u00b7</span>\n        <a href=\"https://x.com/shivafpx\" target=\"_blank\" rel=\"noopener\" style=\"font-family:var(--mono);font-size:10px;color:var(--muted);text-decoration:none\" onmouseover=\"this.style.color='var(--text)'\" onmouseout=\"this.style.color='var(--muted)'\">X / Twitter</a>\n      </div>\n    </div>\n  </div>\n</footer>\n<div style=\"background:var(--bg1);border-top:1px solid var(--b);padding:10px 32px;font-family:var(--mono);font-size:9px;color:var(--muted);text-align:center\">\n  \u00a9 2026 White Lotus \u00b7 Taracod \u00b7 All rights reserved \u00b7 contact@taracod.com\n</div>\n\n<script>\n// Cinematic intro \u2014 DevOS glitch+settle, Aiden typewriter\n(function(){\n  const GLITCH_CHARS='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*<>/\\\\[]{}';\n  const FINAL_TEXT='DevOS';\n  const TYPEWRITER_TEXT='Aiden';\n\n  function randChar(){return GLITCH_CHARS[Math.floor(Math.random()*GLITCH_CHARS.length)]}\n\n  function glitchSettle(el,finalText,duration,cb){\n    const steps=18;\n    const interval=duration/steps;\n    let step=0;\n    const settled=[];\n    const timer=setInterval(()=>{\n      step++;\n      const progress=step/steps;\n      // How many chars are settled = proportional to progress\n      const numSettled=Math.floor(progress*finalText.length);\n      let display='';\n      for(let i=0;i<finalText.length;i++){\n        if(i<numSettled){\n          display+=finalText[i];\n        } else if(finalText[i]===' '){\n          display+=' ';\n        } else {\n          display+=randChar();\n        }\n      }\n      el.textContent=display;\n      if(step>=steps){\n        clearInterval(timer);\n        el.textContent=finalText;\n        if(cb)cb();\n      }\n    },interval);\n  }\n\n  function typewriter(el,text,speed,cb){\n    let i=0;\n    el.textContent='';\n    const timer=setInterval(()=>{\n      el.textContent+=text[i];\n      i++;\n      if(i>=text.length){\n        clearInterval(timer);\n        if(cb)cb();\n      }\n    },speed);\n  }\n\n  // Fade in container\n  setTimeout(()=>{\n    const ic=document.getElementById('introContent');\n    if(ic){ic.style.opacity='1';ic.style.transform='translateY(0)'}\n  },300);\n\n  // Start glitch on DevOS after fade in\n  setTimeout(()=>{\n    const glitch=document.getElementById('glitchText');\n    if(!glitch)return;\n    glitchSettle(glitch,FINAL_TEXT,700,()=>{\n      // After DevOS settles, start Aiden typewriter\n      setTimeout(()=>{\n        const tw=document.getElementById('typewriterText');\n        if(!tw)return;\n        typewriter(tw,TYPEWRITER_TEXT,90,()=>{\n          // Hide cursor blink after done, show tagline\n          setTimeout(()=>{\n            const cursor=document.getElementById('twCursor');\n            if(cursor)cursor.style.opacity='0';\n            const tagline=document.getElementById('introTagline');\n            if(tagline)tagline.style.opacity='1';\n            // Show scroll hint\n            setTimeout(()=>{\n              const sh=document.getElementById('scrollHint');\n              if(sh)sh.style.opacity='1';\n            },400);\n          },600);\n        });\n      },200);\n    });\n  },800);\n\n  // Fade out on scroll + replay when back at top\n  let hasReplayed=false;\n  let isAnimating=false;\n\n  function runIntroAnimation(){\n    if(isAnimating)return;\n    isAnimating=true;\n    hasReplayed=true;\n\n    // Reset state\n    const glitch=document.getElementById('glitchText');\n    const tw=document.getElementById('typewriterText');\n    const cursor=document.getElementById('twCursor');\n    const tagline=document.getElementById('introTagline');\n    const sh=document.getElementById('scrollHint');\n    if(glitch)glitch.textContent='\u00a0';\n    if(tw)tw.textContent='';\n    if(cursor){cursor.style.opacity='1';}\n    if(tagline)tagline.style.opacity='0';\n    if(sh)sh.style.opacity='0';\n\n    // Run glitch\n    setTimeout(()=>{\n      glitchSettle(glitch,FINAL_TEXT,700,()=>{\n        setTimeout(()=>{\n          typewriter(tw,TYPEWRITER_TEXT,90,()=>{\n            setTimeout(()=>{\n              if(cursor)cursor.style.opacity='0';\n              if(tagline)tagline.style.opacity='1';\n              setTimeout(()=>{if(sh)sh.style.opacity='1';isAnimating=false;},400);\n            },600);\n          });\n        },200);\n      });\n    },100);\n  }\n\n  window.addEventListener('scroll',()=>{\n    const ic=document.getElementById('introContent');\n    const sh=document.getElementById('scrollHint');\n    const scrolled=window.scrollY;\n    const fade=Math.max(0,1-scrolled/300);\n    if(ic)ic.style.opacity=String(Math.max(fade,0));\n    if(sh)sh.style.opacity=String(Math.max(fade*0.7,0));\n\n    // Replay when scrolled back to top\n    if(scrolled<20&&hasReplayed){\n      hasReplayed=false;\n      const ic2=document.getElementById('introContent');\n      if(ic2){ic2.style.opacity='1';ic2.style.transform='translateY(0)';}\n      runIntroAnimation();\n    }\n    if(scrolled>100)hasReplayed=true;\n  },{passive:true});\n})();\n\n(function(){\n  const canvas=document.getElementById('bg');\n  const ctx=canvas.getContext('2d');\n  let W,H,particles,mouse={x:-9999,y:-9999},ripples=[];\n  const CFG={count:110,maxDist:130,cursorDist:140,repelDist:120,repelForce:0.18,spring:0.045,baseSpeed:0.35};\n  function resize(){W=canvas.width=window.innerWidth;H=canvas.height=window.innerHeight}\n  function Particle(){this.x=Math.random()*W;this.y=Math.random()*H;this.ox=this.x;this.oy=this.y;this.vx=(Math.random()-.5)*CFG.baseSpeed;this.vy=(Math.random()-.5)*CFG.baseSpeed;this.r=Math.random()*1.8+.8;this.alpha=Math.random()*.5+.25}\n  function init(){resize();particles=Array.from({length:CFG.count},()=>new Particle())}\n  function addRipple(x,y){ripples.push({x,y,r:0,maxR:200,alpha:.6,speed:6})}\n  function update(){\n    particles.forEach(p=>{\n      p.ox+=p.vx;p.oy+=p.vy;\n      if(p.ox<0||p.ox>W)p.vx*=-1;if(p.oy<0||p.oy>H)p.vy*=-1;\n      const dx=p.x-mouse.x,dy=p.y-mouse.y,dist=Math.sqrt(dx*dx+dy*dy);\n      if(dist<CFG.repelDist&&dist>0){const force=(CFG.repelDist-dist)/CFG.repelDist*CFG.repelForce;p.x+=(dx/dist)*force*18;p.y+=(dy/dist)*force*18}\n      ripples.forEach(rp=>{const rdx=p.x-rp.x,rdy=p.y-rp.y,rd=Math.sqrt(rdx*rdx+rdy*rdy);if(Math.abs(rd-rp.r)<30&&rd>0){const push=(30-Math.abs(rd-rp.r))/30*3.5;p.x+=(rdx/rd)*push;p.y+=(rdy/rd)*push}});\n      p.x+=(p.ox-p.x)*CFG.spring;p.y+=(p.oy-p.y)*CFG.spring;\n    });\n    ripples=ripples.filter(r=>{r.r+=r.speed;r.alpha-=.015;return r.alpha>0&&r.r<r.maxR});\n  }\n  function draw(){\n    ctx.clearRect(0,0,W,H);\n    ripples.forEach(r=>{ctx.beginPath();ctx.arc(r.x,r.y,r.r,0,Math.PI*2);ctx.strokeStyle=`rgba(249,115,22,${r.alpha*0.4})`;ctx.lineWidth=1.5;ctx.stroke()});\n    for(let i=0;i<particles.length;i++)for(let j=i+1;j<particles.length;j++){const a=particles[i],b=particles[j],dx=a.x-b.x,dy=a.y-b.y,d=Math.sqrt(dx*dx+dy*dy);if(d<CFG.maxDist){const opacity=(1-d/CFG.maxDist)*0.15,mda=Math.sqrt((a.x-mouse.x)**2+(a.y-mouse.y)**2),mdb=Math.sqrt((b.x-mouse.x)**2+(b.y-mouse.y)**2),near=mda<CFG.cursorDist||mdb<CFG.cursorDist;ctx.beginPath();ctx.moveTo(a.x,a.y);ctx.lineTo(b.x,b.y);ctx.strokeStyle=`rgba(249,115,22,${Math.min(near?opacity*4.5:opacity,.7)})`;ctx.lineWidth=near?1.2:.5;ctx.stroke()}}\n    particles.forEach(p=>{const md=Math.sqrt((p.x-mouse.x)**2+(p.y-mouse.y)**2),near=md<CFG.cursorDist,r=near?p.r*1.8:p.r,alpha=near?Math.min(p.alpha*2.5,.95):p.alpha;ctx.beginPath();ctx.arc(p.x,p.y,r,0,Math.PI*2);ctx.fillStyle=`rgba(249,115,22,${alpha})`;ctx.fill();if(near){ctx.beginPath();ctx.arc(p.x,p.y,r+3,0,Math.PI*2);ctx.strokeStyle=`rgba(249,115,22,${alpha*0.3})`;ctx.lineWidth=.8;ctx.stroke()}});\n  }\n  function loop(){update();draw();requestAnimationFrame(loop)}\n  window.addEventListener('resize',resize);\n  window.addEventListener('mousemove',e=>{mouse.x=e.clientX;mouse.y=e.clientY});\n  window.addEventListener('mouseleave',()=>{mouse.x=-9999;mouse.y=-9999});\n  document.addEventListener('click',e=>addRipple(e.clientX,e.clientY));\n  init();loop();\n})();\n\n(function(){\n  const SESSIONS=[\n    [{type:'cmd',text:'aiden \"clean up my Downloads folder \u2014 keep the last 30 days\"'},{type:'out',cls:'ac',text:'\u25b8 Planning task...',delay:380},{type:'out',cls:'',text:'  Safety Gate \u2192 approval requested before deleting',delay:300},{type:'out',cls:'ok',text:'  Scanning Downloads: 847 files found',delay:480},{type:'out',cls:'ok',text:'  Identified: 612 files older than 30 days (38.2 GB)',delay:700},{type:'out',cls:'ok',text:'  Approval received \u2192 moving to Trash',delay:600},{type:'out',cls:'ok',text:'  \u2713 612 files moved \u00b7 38.2 GB freed',delay:850},{type:'out',cls:'am',text:'  \u25cf Disk: 78% \u2192 52% \u00b7 Task complete',delay:350},{type:'gap',delay:500}],\n    [{type:'cmd',text:'aiden \"research best standing desk options under \u20b920,000\"'},{type:'out',cls:'ac',text:'\u25b8 Starting deep research...',delay:300},{type:'out',cls:'ok',text:'  Pass 1: searching for standing desk reviews India',delay:500},{type:'out',cls:'ok',text:'  Pass 2: searching for ergonomic desk comparisons 2026',delay:600},{type:'out',cls:'ok',text:'  Gap detected: no height range data \u2014 searching again',delay:700},{type:'out',cls:'ok',text:'  Synthesising 8 sources into report...',delay:500},{type:'out',cls:'ok',text:'  Saving report to Desktop/standing_desks.md',delay:400},{type:'out',cls:'am',text:'  \u25cf Report saved \u00b7 3 top picks identified under \u20b920,000',delay:350},{type:'gap',delay:500}],\n    [{type:'cmd',text:'aiden \"build a Python script to rename all photos by date taken\"'},{type:'out',cls:'ac',text:'\u25b8 Planning...',delay:280},{type:'out',cls:'ok',text:'  Writing script: rename_photos.py',delay:500},{type:'out',cls:'ok',text:'  Testing on 3 sample files...',delay:600},{type:'out',cls:'ok',text:'  \u2713 All 3 renamed correctly \u00b7 verified',delay:500},{type:'out',cls:'ok',text:'  Script saved to Desktop',delay:350},{type:'out',cls:'am',text:'  \u25cf Ready to run on your full photo library',delay:300},{type:'gap',delay:500}],\n    [{type:'cmd',text:'aiden \"monitor my disk every hour and notify me when below 10GB free\"'},{type:'out',cls:'ac',text:'\u25b8 Setting up scheduled task...',delay:400},{type:'out',cls:'ok',text:'  Task created: disk monitor \u00b7 every hour',delay:500},{type:'out',cls:'ok',text:'  Running in background \u00b7 no window needed',delay:400},{type:'out',cls:'am',text:'  \u25cf Active. You will be notified at threshold.',delay:350},{type:'gap',delay:500}],\n  ];\n  const body=document.getElementById('termBody');\n  if(!body)return;\n  let si=0,cur=null;\n  function mkCur(){const c=document.createElement('span');c.style.cssText='display:inline-block;width:7px;height:13px;background:var(--orange);margin-left:1px;vertical-align:middle;animation:blink .75s infinite';return c}\n  function line(cls,html){const d=document.createElement('div');d.className=cls;d.innerHTML=html;body.appendChild(d);body.scrollTop=9999;return d}\n  function sleep(ms){return new Promise(r=>setTimeout(r,ms))}\n  async function type(el,text){el.textContent='';if(cur)el.appendChild(cur);for(let i=0;i<text.length;i++){const t=document.createTextNode(text[i]);el.insertBefore(t,cur);body.scrollTop=9999;await sleep(36+Math.random()*20)}}\n  async function run(steps){for(const s of steps){if(s.type==='gap'){line('tgap','');await sleep(s.delay||350);continue}if(s.type==='cmd'){const row=line('tl','');const ps=document.createElement('span');ps.className='tps';ps.textContent='$ ';const cmd=document.createElement('span');cmd.className='tcmd';cur=mkCur();row.appendChild(ps);row.appendChild(cmd);await sleep(280);await type(cmd,s.text);await sleep(130);if(cur&&cur.parentNode)cur.parentNode.removeChild(cur);cur=null;await sleep(240)}else{await sleep(s.delay||300);const d=line('tout'+(s.cls?' '+s.cls:''),'');d.textContent=s.text;body.scrollTop=9999}}}\n  async function loop(){while(true){await run(SESSIONS[si%SESSIONS.length]);si++;await sleep(400);if(si%SESSIONS.length===0){await sleep(1600);body.style.transition='opacity .4s';body.style.opacity='0';await sleep(420);body.innerHTML='';body.style.opacity='1';await sleep(350)}}}\n  setTimeout(loop,800);\n})();\n\n(function(){\n  const CONVOS=[\n    {user:'What can you see on my machine right now?',logs:[{t:'00:01',ic:'\u25b8',txt:'<span class=\"hi\">Checking system</span> \u2192 scanning your machine'},{t:'00:02',ic:'\u25b8',txt:'<span class=\"ac\">Open windows</span> \u2192 VS Code, Chrome (12 tabs), Spotify'},{t:'00:03',ic:'\u25b8',txt:'<span class=\"hi\">System</span> \u2192 6.2GB RAM free \u00b7 disk 78% full'},{t:'00:04',ic:'\u25b8',txt:'<span class=\"ok\">Context ready</span> \u00b7 responding with awareness'}],reply:'I can see you have VS Code open with a project, 12 Chrome tabs running, and Spotify playing. Your disk is 78% full and you have 6.2GB RAM free. Chrome is using most of it. Want me to do anything about that?'},\n    {user:'Research AI trends in India for 2026 and save a report',logs:[{t:'00:01',ic:'\u25b8',txt:'<span class=\"hi\">Research</span> \u2192 starting multi-pass search'},{t:'00:02',ic:'\u25b8',txt:'<span class=\"ac\">Web search</span> \u2192 fetching 4 sources'},{t:'00:03',ic:'\u25b8',txt:'<span class=\"hi\">Gap detected</span> \u2192 searching for funding data'},{t:'00:04',ic:'\u25b8',txt:'<span class=\"ok\">Saving</span> \u2192 ai_trends_india_2026.md'},{t:'00:05',ic:'\u25b8',txt:'<span class=\"ok\">Done</span> \u00b7 3 passes \u00b7 14,200 chars'}],reply:'Report saved to your Desktop as ai_trends_india_2026.md. Covered funding landscape, key players, government initiatives, and emerging use cases. 3 research passes \u2014 nothing major was missing.'},\n    {user:'Remind me every day at 9am to check my email',logs:[{t:'00:01',ic:'\u25b8',txt:'<span class=\"hi\">Scheduler</span> \u2192 creating daily task'},{t:'00:02',ic:'\u25b8',txt:'<span class=\"ac\">Schedule</span> \u2192 every day at 9:00am'},{t:'00:03',ic:'\u25b8',txt:'<span class=\"ok\">Task saved</span> \u00b7 running in background'},{t:'00:04',ic:'\u25b8',txt:'<span class=\"ok\">Active</span> \u00b7 no window needed'}],reply:\"Done. I'll send you a desktop notification every morning at 9am. Runs in the background \u2014 you don't need to keep anything open.\"},\n  ];\n  const chatMessages=document.getElementById('chatMessages'),chatInputText=document.getElementById('chatInputText'),logBody=document.getElementById('logBody');\n  if(!chatMessages||!chatInputText||!logBody)return;\n  let ci=0;\n  function sleep(ms){return new Promise(r=>setTimeout(r,ms))}\n  async function typeInput(text){chatInputText.textContent='';for(let i=0;i<text.length;i++){chatInputText.textContent+=text[i];await sleep(36+Math.random()*22)}await sleep(300)}\n  function addMsg(who,text){const div=document.createElement('div');div.className='msg '+who;const lbl=document.createElement('div');lbl.className='msg-lbl';lbl.textContent=who==='user'?'You':'Aiden';const bubble=document.createElement('div');bubble.className='msg-bubble';bubble.style.whiteSpace='pre-wrap';bubble.textContent=text;div.appendChild(lbl);div.appendChild(bubble);chatMessages.appendChild(div);chatMessages.scrollTop=9999;return bubble}\n  function addTyping(){const div=document.createElement('div');div.className='msg ai';div.id='typingInd';const lbl=document.createElement('div');lbl.className='msg-lbl';lbl.textContent='Aiden';const bubble=document.createElement('div');bubble.className='msg-bubble';bubble.innerHTML='<span style=\"font-family:var(--mono);font-size:11px;color:var(--muted)\">working locally<span id=\"tDots\"></span></span>';div.appendChild(lbl);div.appendChild(bubble);chatMessages.appendChild(div);chatMessages.scrollTop=9999;let d=0;const iv=setInterval(()=>{const el=document.getElementById('tDots');if(el)el.textContent='.'.repeat((d++%3)+1)},400);div._clear=()=>clearInterval(iv);return div}\n  async function addLog(entry,delay){await sleep(delay);const el=document.createElement('div');el.className='log-entry';el.innerHTML=`<span class=\"log-time\">${entry.t}</span><span class=\"log-ic\">${entry.ic}</span><div class=\"log-txt\">${entry.txt}</div>`;logBody.appendChild(el);logBody.scrollTop=9999;requestAnimationFrame(()=>setTimeout(()=>el.classList.add('show'),20))}\n  async function runConvo(c){await typeInput(c.user);chatInputText.textContent='';addMsg('user',c.user);await sleep(280);const ind=addTyping();for(let i=0;i<c.logs.length;i++)await addLog(c.logs[i],i===0?280:560);await sleep(750);if(ind._clear)ind._clear();ind.remove();addMsg('ai',c.reply);await sleep(2100)}\n  async function loop(){while(true){await runConvo(CONVOS[ci%CONVOS.length]);ci++;if(ci%CONVOS.length===0){await sleep(1300);chatMessages.style.transition='opacity .4s';logBody.style.transition='opacity .4s';chatMessages.style.opacity='0';logBody.style.opacity='0';await sleep(420);chatMessages.innerHTML='';logBody.innerHTML='';chatMessages.style.opacity='1';logBody.style.opacity='1';await sleep(450)}}}\n  setTimeout(loop,1100);\n})();\n\n(function(){\n  const ROWS=[\n    {\n      feature:'Privacy & Data',\n      desc:'Where your data lives',\n      aiden:'Your files and memory stay local. AI requests use private cloud APIs.',\n      aidenOk:true,\n      cloud:'Processed on external servers. May be used for training.',\n      cloudOk:false,\n    },\n    {\n      feature:'Computer Control',\n      desc:'Can it touch your machine',\n      aiden:'Sees your screen, clicks, types, moves files \u2014 full control.',\n      aidenOk:true,\n      cloud:'Lives in a browser tab. Cannot touch your computer.',\n      cloudOk:false,\n    },\n    {\n      feature:'Memory',\n      desc:'Remembers you between sessions',\n      aiden:'Persistent across all sessions forever. Knows your patterns.',\n      aidenOk:true,\n      cloud:'Forgets you when the tab closes. Starts fresh every time.',\n      cloudOk:false,\n    },\n    {\n      feature:'Works Offline',\n      desc:'No internet needed',\n      aiden:'Local AI models \u2014 works with zero internet connection.',\n      aidenOk:true,\n      cloud:'Completely unusable without internet.',\n      cloudOk:false,\n    },\n    {\n      feature:'File Access',\n      desc:'Reads and writes your files',\n      aiden:'Full filesystem access. Creates, edits, organises anything.',\n      aidenOk:true,\n      cloud:'Cannot access your files. Copy-paste only.',\n      cloudOk:false,\n    },\n    {\n      feature:'Runs in Background',\n      desc:'Works while you are away',\n      aiden:'Background service \u2014 scheduled tasks, monitoring, automations.',\n      aidenOk:true,\n      cloud:'Only active when you have a tab open.',\n      cloudOk:false,\n    },\n    {\n      feature:'Scheduled Tasks',\n      desc:'Automates things on a timer',\n      aiden:'Natural language scheduling \u2014 \"every Monday at 9am\".',\n      aidenOk:true,\n      cloud:'No scheduling. No background execution.',\n      cloudOk:false,\n    },\n    {\n      feature:'Learns From Your Files',\n      desc:'Upload your documents',\n      aiden:'Reads your PDFs, books, notes \u2014 uses them in every task.',\n      aidenOk:true,\n      cloud:'No persistent knowledge base. No file learning.',\n      cloudOk:false,\n    },\n  ];\n\n  const container=document.getElementById('compareRows');\n  if(!container)return;\n\n  ROWS.forEach((row,i)=>{\n    const el=document.createElement('div');\n    el.style.cssText=`display:grid;grid-template-columns:1fr 180px 180px;border-bottom:${i<ROWS.length-1?'1px solid rgba(249,115,22,0.08)':'none'};transition:background .15s;`;\n    el.onmouseenter=()=>el.style.background='rgba(249,115,22,0.04)';\n    el.onmouseleave=()=>el.style.background='';\n\n    el.innerHTML=`\n      <div style=\"padding:20px 28px\">\n        <div style=\"font-size:13px;font-weight:600;margin-bottom:3px;letter-spacing:-.01em;color:var(--text)\">${row.feature}</div>\n        <div style=\"font-family:var(--mono);font-size:10px;color:var(--muted)\">${row.desc}</div>\n      </div>\n      <div style=\"padding:20px 28px;border-left:1px solid rgba(249,115,22,0.1);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;text-align:center\">\n        <div style=\"width:28px;height:28px;border-radius:50%;background:rgba(34,197,94,0.12);border:1px solid rgba(34,197,94,0.25);display:flex;align-items:center;justify-content:center;font-size:13px;color:#22c55e;font-weight:700\">${row.aidenOk?'\u2713':'\u2717'}</div>\n        <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted2);line-height:1.6\">${row.aiden}</div>\n      </div>\n      <div style=\"padding:20px 28px;border-left:1px solid rgba(249,115,22,0.1);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;text-align:center\">\n        <div style=\"width:28px;height:28px;border-radius:50%;background:rgba(248,113,113,0.1);border:1px solid rgba(248,113,113,0.2);display:flex;align-items:center;justify-content:center;font-size:13px;color:#f87171;font-weight:700\">${row.cloudOk?'\u2713':'\u2717'}</div>\n        <div style=\"font-family:var(--mono);font-size:9px;color:var(--muted);line-height:1.6\">${row.cloud}</div>\n      </div>\n    `;\n    container.appendChild(el);\n  });\n})();\n\nlet selectedCat='tools',sortMode='votes';\nfunction selectCat(btn,cat){selectedCat=cat;document.querySelectorAll('.cat-btn').forEach(b=>b.classList.remove('active'));btn.classList.add('active')}\nfunction getReqs(){try{return JSON.parse(localStorage.getItem('devos_v2_reqs')||'[]')}catch{return[]}}\nfunction saveReqs(r){try{localStorage.setItem('devos_v2_reqs',JSON.stringify(r))}catch{}}\nfunction getVoted(){try{return JSON.parse(localStorage.getItem('devos_v2_voted')||'[]')}catch{return[]}}\nfunction saveVoted(v){try{localStorage.setItem('devos_v2_voted',JSON.stringify(v))}catch{}}\nfunction timeAgo(ts){const s=Math.floor((Date.now()-ts)/1000);if(s<60)return'just now';if(s<3600)return Math.floor(s/60)+'m ago';if(s<86400)return Math.floor(s/3600)+'h ago';return Math.floor(s/86400)+'d ago'}\nfunction submitReq(){const txt=document.getElementById('frText').value.trim(),hint=document.getElementById('frHint');if(!txt||txt.length<10){hint.style.color='#f87171';hint.textContent='Please add more detail.';setTimeout(()=>{hint.style.color='';hint.textContent='Select a category and describe your idea.'},2500);return}const reqs=getReqs();reqs.push({id:Date.now(),text:txt,cat:selectedCat,votes:1,ts:Date.now()});saveReqs(reqs);const voted=getVoted();voted.push(reqs[reqs.length-1].id);saveVoted(voted);document.getElementById('frText').value='';hint.style.color='var(--green)';hint.textContent='\u2713 Submitted! Thanks.';setTimeout(()=>{hint.style.color='';hint.textContent='Select a category and describe your idea.'},3000);renderFeed()}\nfunction vote(id){const voted=getVoted(),reqs=getReqs(),idx=reqs.findIndex(r=>r.id===id);if(idx===-1)return;if(voted.includes(id)){reqs[idx].votes=Math.max(0,reqs[idx].votes-1);saveVoted(voted.filter(v=>v!==id))}else{reqs[idx].votes++;voted.push(id);saveVoted(voted)}saveReqs(reqs);renderFeed()}\nfunction sortBy(mode,btn){sortMode=mode;document.querySelectorAll('.sort-btn').forEach(b=>b.classList.remove('active'));btn.classList.add('active');renderFeed()}\nfunction renderFeed(){const reqs=getReqs(),voted=getVoted(),list=document.getElementById('frList'),empty=document.getElementById('frEmpty'),countEl=document.getElementById('reqCount');countEl.textContent=reqs.length+' request'+(reqs.length!==1?'s':'');if(!reqs.length){list.innerHTML='';if(!list.contains(empty))list.appendChild(empty);return}empty.remove();let sorted=[...reqs];if(sortMode==='votes')sorted.sort((a,b)=>b.votes-a.votes);else sorted.sort((a,b)=>b.ts-a.ts);list.innerHTML=sorted.map(r=>`<div class=\"fr-item\"><div class=\"fr-vote\"><button class=\"vbtn${voted.includes(r.id)?' voted':''}\" onclick=\"vote(${r.id})\" title=\"${voted.includes(r.id)?'Remove vote':'Upvote'}\">\u25b2</button><span class=\"vcount\">${r.votes}</span></div><div class=\"fr-content\"><div class=\"fr-meta\"><span class=\"cat-pill\">${r.cat}</span><span class=\"fr-time\">${timeAgo(r.ts)}</span></div><div class=\"fr-text\">${r.text.replace(/</g,'&lt;').replace(/>/g,'&gt;')}</div></div></div>`).join('')}\n(function seedExamples(){if(getReqs().length>0)return;const seeds=[{id:3001,text:'Notion integration \u2014 read and write directly to my pages',cat:'tools',votes:18,ts:Date.now()-86400000*3},{id:3002,text:'Voice control \u2014 say a goal out loud and Aiden executes it',cat:'voice',votes:15,ts:Date.now()-86400000*2},{id:3003,text:'Android app to send goals from my phone',cat:'channels',votes:13,ts:Date.now()-86400000},{id:3004,text:'Auto-organise my Downloads folder every week',cat:'automation',votes:11,ts:Date.now()-3600000*8},{id:3005,text:'Calendar integration \u2014 check my schedule before suggesting times',cat:'tools',votes:9,ts:Date.now()-3600000*3},{id:3006,text:'WhatsApp automation \u2014 draft and send replies from a template',cat:'automation',votes:7,ts:Date.now()-3600000}];saveReqs(seeds);saveVoted([])})();\nrenderFeed();\n</script>\n</body>\n</html>\n";
    const url = new URL(request.url);
    const { pathname } = url;
    if (pathname === '/privacy')    return privacyPage();
    if (pathname === '/terms')      return termsPage();
    if (pathname === '/disclaimer') return disclaimerPage();
    if (pathname === '/install.ps1')   return installPs1Route();
    if (pathname === '/install.sh')    return installShRoute();
    if (pathname === '/uninstall.sh')  return uninstallShRoute();
    if (pathname === '/uninstall.ps1') return uninstallPs1Route();
    if (pathname === '/contact' && request.method !== 'POST')         return contactPage(url);
    if (pathname === '/contact/success') return contactSuccessPage(url);
    if (pathname === '/api/contact' && request.method === 'POST') return contactApiHandler(request, env);

    return new Response(html, {
      status: 200,
      headers: {
        "Content-Type": "text/html;charset=UTF-8",
        "Cache-Control": "no-cache, no-store, must-revalidate",
        "X-Version": "aiden-v2-final"
      }
    })
}

// ── Legal page helpers ─────────────────────────────────────────

function legalHtml(title, body) {
  return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>${title} \u2014 Aiden</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='6' fill='%23FF8C00'/><text x='50%25' y='55%25' dominant-baseline='middle' text-anchor='middle' font-family='monospace' font-weight='bold' font-size='16' fill='white'>A/</text></svg>">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#0e0e0e;color:#e8e8e8;font-family:'Outfit',sans-serif;line-height:1.7}
nav{position:sticky;top:0;background:rgba(14,14,14,.95);backdrop-filter:blur(12px);border-bottom:1px solid #222;padding:0 32px;height:52px;display:flex;align-items:center;justify-content:space-between;z-index:100}
.nl{display:flex;align-items:center;gap:8px;font-family:'JetBrains Mono',monospace;font-size:12px;color:#e8e8e8;text-decoration:none}
.sq{width:24px;height:24px;border-radius:5px;background:#f97316;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;color:#000}
.bk{font-family:'JetBrains Mono',monospace;font-size:11px;color:#666;text-decoration:none}
.bk:hover{color:#e8e8e8}
.w{max-width:720px;margin:0 auto;padding:48px 32px 80px}
h1{font-size:28px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}
.meta{font-family:'JetBrains Mono',monospace;font-size:11px;color:#555;margin-bottom:40px}
h2{font-size:13px;font-weight:600;color:#f97316;margin:32px 0 10px;text-transform:uppercase;letter-spacing:.07em;font-family:'JetBrains Mono',monospace}
p{color:#aaa;font-size:14px;margin-bottom:12px}
ul{color:#aaa;font-size:14px;margin:0 0 12px 20px}
li{margin-bottom:6px}
a{color:#f97316;text-decoration:none}
a:hover{text-decoration:underline}
.box{background:#141414;border:1px solid #222;border-left:3px solid #f97316;border-radius:8px;padding:14px 18px;margin:16px 0}
.box p{margin:0;font-family:'JetBrains Mono',monospace;font-size:12px;color:#888}
footer{border-top:1px solid #1a1a1a;padding:24px 32px;text-align:center;font-family:'JetBrains Mono',monospace;font-size:10px;color:#444}
footer a{color:#555;margin:0 8px;text-decoration:none}
footer a:hover{color:#888}
</style>
</head>
<body>
<nav>
  <a class="nl" href="/"><div class="sq">A/</div>Aiden</a>
  <a class="bk" href="/">\u2190 Back</a>
</nav>
<div class="w">${body}</div>
<footer>\u00a9 2026 Taracod \u00b7 White Lotus&nbsp;&nbsp;
  <a href="/">Home</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a><a href="/disclaimer">Disclaimer</a>
  <br><br><a href="mailto:contact@taracod.com">contact@taracod.com</a>
</footer>
</body>
</html>`;
}

function privacyPage() {
  const body = `
<h1>Privacy Policy</h1>
<div class="meta">Effective April 1, 2026 \u00b7 Jurisdiction: India</div>
<div class="box"><p>TL;DR: Aiden processes AI requests through private cloud APIs. We only store your email to send your download link. Your local files and memory never leave your computer.</p></div>
<h2>What We Collect</h2>
<p>Only your <strong>email address</strong>, used solely to deliver your Aiden download link. We do <strong>not</strong> collect conversations, files, usage data, analytics, or telemetry.</p>
<h2>Where Your Data Lives</h2>
<p>Aiden runs entirely on your local machine. All data stays in <code>workspace/</code> on your computer. Your email is stored in Cloudflare KV only to deliver your download link.</p>
<h2>Third-Party Services</h2>
<p><strong>Resend</strong> \u2014 receives your email to send the download link.</p>
<p><strong>Cloudflare</strong> \u2014 hosts this landing page.</p>
<p><strong>AI API Providers</strong> \u2014 when you configure Groq, Gemini, or OpenRouter in Aiden, prompts go directly from your machine to those providers. Taracod is not a party to those requests:</p>
<ul>
  <li><a href="https://groq.com/privacy-policy/" target="_blank">Groq Privacy Policy</a></li>
  <li><a href="https://policies.google.com/privacy" target="_blank">Google / Gemini Privacy Policy</a></li>
  <li><a href="https://openrouter.ai/privacy" target="_blank">OpenRouter Privacy Policy</a></li>
</ul>
<p>With <strong>Ollama</strong> (local mode), all AI processing stays on your machine.</p>
<h2>Your Rights</h2>
<p>Request deletion of your email: <a href="mailto:contact@taracod.com">contact@taracod.com</a>. We will delete within 7 business days.</p>
<h2>Contact</h2>
<p>Taracod / White Lotus \u00b7 <a href="mailto:contact@taracod.com">contact@taracod.com</a></p>`;
  return new Response(legalHtml("Privacy Policy", body), {
    status: 200, headers: { "Content-Type": "text/html;charset=UTF-8" }
  });
}

function termsPage() {
  const body = `
<h1>Terms of Service</h1>
<div class="meta">Effective April 1, 2026 \u00b7 Governing Law: India</div>
<h2>Acceptance</h2>
<p>By downloading, installing, or using Aiden you agree to these Terms.</p>
<h2>License</h2>
<p>Aiden is licensed for <strong>personal use on up to 2 machines</strong>. You may not redistribute, resell, sublicense, or use Aiden commercially without a Pro license.</p>
<h2>What Aiden Does</h2>
<p>Aiden executes commands, reads/writes files, browses the web, and controls your computer per your instructions. You are responsible for all instructions you give Aiden and for reviewing scheduled tasks and automations.</p>
<h2>AI Providers</h2>
<div class="box"><p>Prompts sent to Groq, Gemini, OpenRouter, and other cloud AI providers go directly from your machine to their servers. Taracod is not responsible for API costs, content generated, availability, or data handling by third-party AI providers.</p></div>
<p>You are responsible for all API costs, compliance with provider terms, and the security of your API keys.</p>
<h2>Disclaimer of Warranties</h2>
<p>Aiden is provided "as is" without warranty. We do not guarantee it will be error-free or uninterrupted.</p>
<h2>Limitation of Liability</h2>
<p>Taracod and White Lotus shall not be liable for indirect, incidental, or consequential damages. Our total liability shall not exceed the amount you paid for Aiden in the preceding 12 months.</p>
<h2>Contact</h2>
<p>Taracod / White Lotus \u00b7 <a href="mailto:contact@taracod.com">contact@taracod.com</a></p>`;
  return new Response(legalHtml("Terms of Service", body), {
    status: 200, headers: { "Content-Type": "text/html;charset=UTF-8" }
  });
}

function disclaimerPage() {
  const body = `
<h1>Disclaimer</h1>
<div class="meta">Effective April 1, 2026</div>
<div class="box"><p>Aiden is a powerful tool. Read this before using it for anything important.</p></div>
<h2>AI Outputs</h2>
<p>AI outputs may be inaccurate, incomplete, or confidently wrong. <strong>Always verify important information before acting.</strong> Do not use Aiden for medical, legal, or financial decisions without consulting a qualified professional.</p>
<h2>Computer Control</h2>
<p>Aiden can execute commands, modify files, and control your computer. Review scheduled tasks regularly. You remain solely responsible for all actions taken on your system. Keep backups of important data.</p>
<h2>API Costs</h2>
<p>API calls to cloud providers go directly from your machine. You are responsible for all usage costs. Aiden has a built-in daily budget cap \u2014 configure it in Settings. Taracod is not responsible for unexpected API bills.</p>
<h2>Data Sent to AI APIs</h2>
<p>When prompts are sent to cloud AI providers, those providers' privacy policies apply. Use Ollama (local mode) for maximum privacy.</p>
<h2>No Warranty</h2>
<p>Aiden is provided without warranty. See our <a href="/terms">Terms of Service</a> for full details.</p>
<h2>Contact</h2>
<p><a href="mailto:contact@taracod.com">contact@taracod.com</a></p>`;
  return new Response(legalHtml("Disclaimer", body), {
    status: 200, headers: { "Content-Type": "text/html;charset=UTF-8" }
  });
}

function uninstallShRoute() {
  const script = `#!/usr/bin/env bash
set -e

BOLD="\\033[1m"
GREEN="\\033[0;32m"
DIM="\\033[2m"
NC="\\033[0m"

echo ""
echo -e "\${BOLD}Aiden Uninstaller\${NC}"
echo "──────────────────"

remove_if_exists() {
  if [ -d "$1" ] || [ -f "$1" ]; then
    rm -rf "$1"
    echo -e "  \${GREEN}removed\${NC}  $1"
  fi
}

echo ""
echo "Removing Aiden data and config..."
remove_if_exists "$HOME/.local/share/aiden"
remove_if_exists "$HOME/.config/aiden"

if [[ "$(uname)" == "Darwin" ]]; then
  remove_if_exists "$HOME/Library/Application Support/aiden"
  remove_if_exists "$HOME/Library/Preferences/com.taracod.aiden.plist"
fi

if command -v npm &>/dev/null; then
  npm uninstall -g devos-ai 2>/dev/null && echo -e "  \${GREEN}removed\${NC}  npm global: devos-ai" || true
fi

echo ""
echo -e "\${GREEN}\${BOLD}Done.\${NC} Aiden has been uninstalled."
echo "Thanks for trying Aiden — feedback welcome: discord.gg/gMZ3hUnQTm"
echo ""
`
  return new Response(script, {
    status: 200,
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
      'Cache-Control': 'no-cache',
    }
  })
}

function uninstallPs1Route() {
  // Serve the Windows uninstall script.
  // Usage: irm https://aiden.taracod.com/uninstall.ps1 | iex
  const script = `# Aiden Windows Uninstaller
# Usage:  irm https://aiden.taracod.com/uninstall.ps1 | iex
# Flags:  -KeepWorkspace  -KeepConfig  -Yes

param([switch]$KeepWorkspace,[switch]$KeepConfig,[switch]$Yes)
$ErrorActionPreference="SilentlyContinue"
$E=[char]27;$B="$E[1m";$G="$E[32m";$D="$E[2m";$R="$E[0m"

Write-Host ""
Write-Host ($B+"Aiden - Uninstaller"+$R)
Write-Host ($D+"------------------------------------"+$R)
Write-Host ""

$removed=0

function Rm($p,$l){
  if(Test-Path $p){
    Remove-Item -Recurse -Force $p -EA SilentlyContinue
    Write-Host ("  "+$G+"removed"+$R+"  "+$l)
    $script:removed++
  }else{
    Write-Host ("  "+$D+"skipped"+$R+"  "+$l+" "+$D+"(not found)"+$R)
  }
}

Write-Host "Stopping Aiden server (port 4200)..."
$proc=Get-NetTCPConnection -LocalPort 4200 -State Listen -EA SilentlyContinue|
  Select-Object -First 1 -Expand OwningProcess
if($proc){
  Stop-Process -Id $proc -Force -EA SilentlyContinue
  Write-Host ("  "+$G+"stopped"+$R+"  pid $proc")
}else{
  Write-Host ("  "+$D+"skipped"+$R+"  no process on :4200")
}
Write-Host ""

if(-not $KeepConfig){
  $appData=if($env:APPDATA){$env:APPDATA}else{Join-Path $env:USERPROFILE "AppData\\Roaming"}
  $local=if($env:LOCALAPPDATA){$env:LOCALAPPDATA}else{Join-Path $env:USERPROFILE "AppData\\Local"}
  Write-Host "Removing Aiden user data..."
  Rm (Join-Path $appData "aiden") "%APPDATA%\\aiden"
  Rm (Join-Path $local "aiden") "%LOCALAPPDATA%\\aiden"
  Write-Host ""
}

if(-not $KeepWorkspace){
  $ws=Join-Path $env:USERPROFILE ".aiden-workspace"
  if(Test-Path $ws){
    if(-not $Yes){$a=Read-Host "  Delete workspace? [y/N]"}else{$a="y"}
    if($a -match "^[Yy]"){Rm $ws "~/.aiden-workspace"}
    else{Write-Host ("  "+$D+"kept"+$R+"  workspace")}
    Write-Host ""
  }
}

Write-Host "Checking for npm global install..."
$nl=npm list -g --depth=0 2>$null
if($nl -match "devos-ai|aiden-os|aiden-runtime"){
  $pkg=if($nl -match "aiden-os"){"aiden-os"}
       elseif($nl -match "devos-ai"){"devos-ai"}
       else{"aiden-runtime"}
  npm uninstall -g $pkg 2>$null
  Write-Host ("  "+$G+"removed"+$R+"  npm global: $pkg")
  $removed++
}else{
  Write-Host ("  "+$D+"skipped"+$R+"  no npm global package found")
}
Write-Host ""

if($removed -gt 0){
  Write-Host ($G+$B+"Done."+$R+" Aiden uninstalled ($removed item(s) removed).")
}else{
  Write-Host ($D+"Nothing to remove."+$R)
}
Write-Host ""`
  return new Response(script, {
    status: 200,
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
      'Cache-Control': 'no-cache',
      'Content-Disposition': 'inline; filename=uninstall.ps1',
    }
  })
}

function installShRoute() {
  // Proxy install.sh from the source repo raw URL.
  const RAW_URL = 'https://raw.githubusercontent.com/taracodlabs/aiden-releases/main/install.sh'
  return fetch(RAW_URL).then(res => {
    if (!res.ok) {
      return new Response('#!/usr/bin/env bash\necho "install.sh temporarily unavailable"\nexit 1\n', {
        status: 503,
        headers: { 'Content-Type': 'text/plain;charset=UTF-8' }
      })
    }
    return res.text().then(body => new Response(body, {
      status: 200,
      headers: {
        'Content-Type': 'text/plain;charset=UTF-8',
        'Cache-Control': 'public, max-age=300'
      }
    }))
  })
}

function installPs1Route() {
  // Proxy the install.ps1 from the source repo raw URL.
  // Cache for 5 minutes so updates propagate quickly.
  const RAW_URL = 'https://raw.githubusercontent.com/taracodlabs/aiden-releases/main/install.ps1'
  return fetch(RAW_URL).then(res => {
    if (!res.ok) {
      return new Response('# install.ps1 temporarily unavailable\n', {
        status: 503,
        headers: { 'Content-Type': 'text/plain;charset=UTF-8' }
      })
    }
    return res.text().then(body => new Response(body, {
      status: 200,
      headers: {
        'Content-Type': 'text/plain;charset=UTF-8',
        'Cache-Control': 'public, max-age=300'
      }
    }))
  })
}

// contact_functions.js — appended to landing.js by patch_landing5.js
// Functions: contactPage, contactSuccessPage, contactApiHandler, jsonErr, escHtml

// ── Contact page ──────────────────────────────────────────────────────────

function contactPage(url) {
  const t = url.searchParams.get('type') || '';
  const types = [
    ['', 'Select inquiry type\u2026'],
    ['custom-skills', 'Custom Skills'],
    ['sponsored', 'Sponsored Partnership'],
    ['enterprise', 'Self-Hosted Enterprise'],
    ['other', 'Other'],
  ];
  const opts = types.map(([v, l]) =>
    `<option value="${v}"${t === v ? ' selected' : ''}>${l}</option>`
  ).join('');

  const body = `
<style>
.field{margin-bottom:20px}
.field label{display:block;font-family:'JetBrains Mono',monospace;font-size:11px;color:#666;letter-spacing:.06em;text-transform:uppercase;margin-bottom:6px}
.opt{color:#444;text-transform:none;letter-spacing:0;font-size:10px}
.field input,.field select,.field textarea{width:100%;background:#111;border:1px solid #222;border-radius:6px;padding:10px 14px;font-family:'Outfit',sans-serif;font-size:14px;color:#e8e8e8;outline:none;transition:border-color .15s;-webkit-appearance:none}
.field input:focus,.field select:focus,.field textarea:focus{border-color:#f97316}
.field select{cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:32px}
.field select option{background:#111;color:#e8e8e8}
.field textarea{resize:vertical;min-height:120px;line-height:1.5}
.sub{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:500;background:#f97316;color:#000;border:none;border-radius:6px;padding:12px 28px;cursor:pointer;margin-top:8px;transition:opacity .15s;letter-spacing:.02em}
.sub:hover{opacity:.85}
.sub:disabled{opacity:.5;cursor:not-allowed}
.err{font-family:'JetBrains Mono',monospace;font-size:12px;color:#ef4444;background:#1a0808;border:1px solid #3b1010;border-radius:6px;padding:10px 14px;margin-bottom:16px}
</style>
<h1>Get in touch</h1>
<div class="meta">We respond within 48 hours &middot; <a href="mailto:contact@taracod.com">contact@taracod.com</a></div>
<form id="cf" onsubmit="submitCF(event)" style="margin-top:32px">
  <div class="field">
    <label>Name</label>
    <input type="text" name="name" required placeholder="Your name" autocomplete="name">
  </div>
  <div class="field">
    <label>Email</label>
    <input type="email" name="email" required placeholder="you@company.com" autocomplete="email">
  </div>
  <div class="field">
    <label>Company <span class="opt">(optional)</span></label>
    <input type="text" name="company" placeholder="Acme Corp" autocomplete="organization">
  </div>
  <div class="field">
    <label>Inquiry type</label>
    <select name="type" required>${opts}</select>
  </div>
  <div class="field">
    <label>Message</label>
    <textarea name="message" required minlength="20" rows="6" placeholder="Tell us what you have in mind\u2026"></textarea>
  </div>
  <div class="field">
    <label>How did you hear about Aiden? <span class="opt">(optional)</span></label>
    <input type="text" name="source" placeholder="GitHub, Twitter, a friend\u2026">
  </div>
  <div id="cf-err" class="err" style="display:none"></div>
  <button type="submit" class="sub" id="cf-btn">Send message &#8594;</button>
</form>
<script>
async function submitCF(e) {
  e.preventDefault();
  var btn = document.getElementById('cf-btn');
  var errEl = document.getElementById('cf-err');
  errEl.style.display = 'none';
  btn.disabled = true;
  btn.textContent = 'Sending\u2026';
  var fd = new FormData(e.target);
  var data = {};
  fd.forEach(function(v, k) { data[k] = v; });
  try {
    var res = await fetch('/api/contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
    var json = await res.json();
    if (res.ok && json.success) {
      window.location.href = json.redirect;
    } else {
      throw new Error(json.error || 'Something went wrong. Please try again.');
    }
  } catch(err) {
    errEl.textContent = err.message;
    errEl.style.display = 'block';
    btn.disabled = false;
    btn.textContent = 'Send message \u2192';
  }
}
</script>`;

  return new Response(legalHtml('Contact', body), {
    status: 200, headers: { 'Content-Type': 'text/html;charset=UTF-8' }
  });
}

// ── Contact success page ──────────────────────────────────────────────────

function contactSuccessPage(url) {
  const raw  = url.searchParams.get('name') || '';
  const name = escHtml(raw.slice(0, 80));

  const body = `
<div style="text-align:center;padding:40px 0 32px">
  <svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-bottom:20px">
    <circle cx="28" cy="28" r="27" stroke="#f97316" stroke-width="2"/>
    <path d="M17 28l8 8 14-16" stroke="#f97316" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
  </svg>
  <h1 style="font-size:24px;margin-bottom:12px">Message received</h1>
  <p style="font-size:15px;color:#aaa">Thanks${name ? ' ' + name : ''} &mdash; you'll hear back within 48 hours.</p>
</div>
<div style="border-top:1px solid #1a1a1a;margin:8px 0 32px"></div>
<h2>While you wait</h2>
<ul>
  <li><a href="https://github.com/taracodlabs/aiden-releases">Browse releases on GitHub</a></li>
  <li><a href="/#download">Install Aiden</a> &mdash; one command, done in under a minute</li>
  <li><a href="https://discord.gg/gMZ3hUnQTm">Join the Discord</a> &mdash; community support &amp; updates</li>
  <li><a href="/#business">Read about the FOR TEAMS offering</a></li>
  <li><a href="/">Back to homepage</a></li>
</ul>`;

  return new Response(legalHtml('Message received', body), {
    status: 200, headers: { 'Content-Type': 'text/html;charset=UTF-8' }
  });
}

// ── Contact API handler ───────────────────────────────────────────────────


// Rate limiting: max 5 contact submissions per IP per 15 minutes
async function checkContactRateLimit(request, env) {
  if (!env.CONTACT_SUBMISSIONS) return true; // no KV bound, allow
  const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
  const key = 'ratelimit:contact:' + ip;
  try {
    const current = await env.CONTACT_SUBMISSIONS.get(key);
    const count = current ? parseInt(current, 10) : 0;
    if (count >= 5) return false;
    await env.CONTACT_SUBMISSIONS.put(key, String(count + 1), { expirationTtl: 900 });
    return true;
  } catch (_) {
    return true; // fail open — don't block on KV errors
  }
}

async function contactApiHandler(request, env) {
  // Rate limit: 5 submissions per IP per 15 minutes
  const allowed = await checkContactRateLimit(request, env);
  if (!allowed) {
    return addSecurityHeaders(new Response(
      JSON.stringify({ success: false, error: 'Too many submissions. Please wait 15 minutes before trying again.' }),
      { status: 429, headers: { 'Content-Type': 'application/json' } }
    ));
  }

  try {
    let body;
    try { body = await request.json(); }
    catch(_) { return jsonErr('Invalid JSON body.'); }

    const { name, email, company, type, message, source } = body || {};

    // Validate required fields
    if (!name || typeof name !== 'string' || name.trim().length < 1)
      return jsonErr('Name is required.');
    if (!email || typeof email !== 'string' || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim()))
      return jsonErr('A valid email address is required.');
    if (!type || !['custom-skills','sponsored','enterprise','other'].includes(type))
      return jsonErr('Please select an inquiry type.');
    if (!message || typeof message !== 'string' || message.trim().length < 20)
      return jsonErr('Message must be at least 20 characters.');

    const nameClean    = name.trim().slice(0, 120);
    const emailClean   = email.trim().slice(0, 200);
    const companyClean = (company  || '').trim().slice(0, 120);
    const msgClean     = message.trim().slice(0, 5000);
    const sourceClean  = (source   || '').trim().slice(0, 200);

    const typeLabels = {
      'custom-skills': 'Custom Skills',
      'sponsored':     'Sponsored Partnership',
      'enterprise':    'Self-Hosted Enterprise',
      'other':         'Other',
    };
    const typeLabel = typeLabels[type] || type;

    const ts  = new Date().toISOString();
    const hex = Array.from(crypto.getRandomValues(new Uint8Array(4)))
                     .map(b => b.toString(16).padStart(2, '0')).join('');
    const kvKey = `contact:${ts.slice(0, 10)}:${hex}`;

    // ── KV backup (best-effort) ──────────────────────────────────────────
    if (env && env.CONTACT_SUBMISSIONS) {
      try {
        await env.CONTACT_SUBMISSIONS.put(kvKey, JSON.stringify({
          name: nameClean, email: emailClean, company: companyClean,
          type, message: msgClean, source: sourceClean,
          ts, ua: request.headers.get('User-Agent') || ''
        }), { expirationTtl: 60 * 60 * 24 * 90 });
      } catch (e) {
        console.warn('KV write failed:', e.message);
      }
    } else {
      console.warn('CONTACT_SUBMISSIONS KV binding not configured — skipping KV backup');
    }

    // ── Send via Resend ──────────────────────────────────────────────────
    if (!env || !env.RESEND_API_KEY) {
      console.warn('RESEND_API_KEY not set — skipping email delivery');
    } else {
      const RESEND = 'https://api.resend.com/emails';
      const hdr = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + env.RESEND_API_KEY
      };

      const internalHtml =
        '<!DOCTYPE html><html><body style="font-family:monospace;background:#0e0e0e;color:#e8e8e8;padding:24px;max-width:600px">' +
        '<h2 style="color:#f97316;margin:0 0 16px">New contact: ' + escHtml(typeLabel) + '</h2>' +
        '<table style="width:100%;border-collapse:collapse;margin-bottom:24px">' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;white-space:nowrap;vertical-align:top">Name</td><td style="color:#e8e8e8;padding:6px 0">' + escHtml(nameClean) + '</td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">Email</td><td style="padding:6px 0"><a href="mailto:' + escHtml(emailClean) + '" style="color:#f97316">' + escHtml(emailClean) + '</a></td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">Company</td><td style="color:#e8e8e8;padding:6px 0">' + (escHtml(companyClean) || '&mdash;') + '</td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">Type</td><td style="color:#e8e8e8;padding:6px 0">' + escHtml(typeLabel) + '</td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">Source</td><td style="color:#e8e8e8;padding:6px 0">' + (escHtml(sourceClean) || '&mdash;') + '</td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">Time</td><td style="color:#aaa;padding:6px 0;font-size:12px">' + ts + '</td></tr>' +
        '<tr><td style="color:#888;padding:6px 12px 6px 0;vertical-align:top">KV key</td><td style="color:#555;padding:6px 0;font-size:11px">' + kvKey + '</td></tr>' +
        '</table>' +
        '<div style="background:#141414;border:1px solid #222;border-radius:6px;padding:16px;margin-bottom:24px">' +
        '<div style="color:#666;font-size:11px;margin-bottom:8px;letter-spacing:.06em;text-transform:uppercase">Message</div>' +
        '<p style="color:#ccc;white-space:pre-wrap;margin:0;font-size:13px;line-height:1.6">' + escHtml(msgClean) + '</p>' +
        '</div>' +
        '<p><a href="mailto:' + escHtml(emailClean) + '" style="color:#f97316">Reply directly &rarr;</a></p>' +
        '</body></html>';

      const autoReplyHtml =
        '<!DOCTYPE html><html><body style="font-family:\'Outfit\',sans-serif;background:#0e0e0e;color:#e8e8e8;padding:24px;max-width:600px;line-height:1.7">' +
        '<h2 style="color:#f97316;margin:0 0 20px">Hey ' + escHtml(nameClean) + ',</h2>' +
        '<p style="color:#aaa">Thanks for reaching out &mdash; your message landed safely. I&rsquo;ll read it personally and get back to you within 48 hours.</p>' +
        '<p style="color:#aaa">If it&rsquo;s urgent, you can reach me directly at <a href="mailto:contact@taracod.com" style="color:#f97316">contact@taracod.com</a>.</p>' +
        '<p style="color:#aaa">In the meantime, feel free to <a href="https://github.com/taracodlabs/aiden" style="color:#f97316">check out Aiden on GitHub</a> or <a href="https://aiden.taracod.com/#download" style="color:#f97316">install it now</a> if you haven&rsquo;t already.</p>' +
        '<p style="color:#555;font-size:12px;margin-top:32px;border-top:1px solid #1a1a1a;padding-top:20px">&mdash; Shiva Deore, Taracod &middot; <a href="https://taracod.com" style="color:#555">taracod.com</a></p>' +
        '</body></html>';

      console.log('Resend internal to: contact@taracod.com, auto-reply to:', emailClean);
      const sends = [
        fetch(RESEND, {
          method: 'POST', headers: hdr,
          body: JSON.stringify({
            from:     'Aiden Contact <contact@taracod.com>',
            to:       ['contact@taracod.com'],
            reply_to: emailClean,
            subject:  '[Aiden] ' + typeLabel + ' \u2014 ' + nameClean,
            html:     internalHtml
          })
        }),
        fetch(RESEND, {
          method: 'POST', headers: hdr,
          body: JSON.stringify({
            from:    'Shiva at Taracod <contact@taracod.com>',
            to:      [emailClean],
            subject: 'Got your message \u2014 Aiden / Taracod',
            html:    autoReplyHtml
          })
        })
      ];

      const results = await Promise.allSettled(sends);
      for (let i = 0; i < results.length; i++) {
        const r = results[i];
        if (r.status === 'rejected') {
          console.warn('Resend email', i, 'rejected:', r.reason);
        } else if (r.value && !r.value.ok) {
          const errBody = await r.value.text().catch(() => '');
          console.warn('Resend email', i, 'HTTP error:', r.value.status, errBody.slice(0, 200));
        } else if (r.value && r.value.ok) {
          console.log('Resend email', i, 'sent OK:', r.value.status);
        }
      }
    }

    const redirect = '/contact/success?name=' + encodeURIComponent(nameClean);
    return new Response(JSON.stringify({ success: true, redirect }), {
      status: 200, headers: { 'Content-Type': 'application/json' }
    });

  } catch (e) {
    console.error('contactApiHandler error:', e);
    return jsonErr('Server error. Please try again or email contact@taracod.com.', 500);
  }
}

function jsonErr(msg, status) {
  return new Response(JSON.stringify({ success: false, error: msg }), {
    status: status || 400,
    headers: { 'Content-Type': 'application/json' }
  });
}

function escHtml(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}
