<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="referrer" content="strict-origin-when-cross-origin">
<title>AtomCode · 在你的终端中运行的 AI 编程助手</title>
<meta name="description" content="AtomCode — Claude Code 的开源平替。连接任意大模型,自主多步执行,30 秒上手。">
<link rel="icon" type="image/png" href="https://cdn-static.gitcode.host/static/images/logo-favicon.png">
<style>
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0;background:#0a0a0a;color:#fff;font-family:"PingFang SC","Microsoft YaHei",Inter,sans-serif;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
button,input,textarea,select{font-family:inherit;border:none;outline:none;color:inherit;background:none}
button{cursor:pointer;padding:0}
:root{
--bg:#0a0a0a;--panel:#111;--paper:#f6f3ec;
--line:rgba(255,255,255,.10);
--muted:rgba(255,255,255,.55);
--accent:#e8a050;
--rust:#b7410e;
--green:#69d28a;
--red:#ff6e6e;
--blue:#7aa6ff;
--mono:Menlo,Monaco,Consolas,"Courier New",monospace;
}
.progress-track{position:fixed;top:0;left:0;right:0;height:2px;z-index:1001;background:rgba(255,255,255,.04);pointer-events:none}
.progress-bar{height:100%;width:0;background:linear-gradient(90deg,#e8a050,#f6f3ec 60%,#e8a050);background-size:200% 100%;box-shadow:0 0 10px rgba(232,160,80,.55);animation:shineFlow 3s linear infinite;transition:width .12s linear}
@keyframes shineFlow{0%{background-position:0 0}100%{background-position:200% 0}}
.aurora{position:fixed;inset:0;z-index:9000;pointer-events:none;background:radial-gradient(circle 360px at var(--mx,-200px) var(--my,-200px),rgba(232,160,80,.18) 0%,rgba(232,160,80,.06) 30%,rgba(232,160,80,0) 60%);mix-blend-mode:screen}
.ripple{position:fixed;left:0;top:0;width:8px;height:8px;border-radius:50%;pointer-events:none;z-index:9100;background:rgba(232,160,80,.55);transform:translate(-50%,-50%);animation:rip .65s cubic-bezier(.22,1,.36,1) forwards}
@keyframes rip{0%{width:6px;height:6px;background:rgba(232,160,80,.85)}100%{width:160px;height:160px;background:rgba(232,160,80,0)}}
.toast{position:fixed;bottom:40px;left:50%;transform:translateX(-50%);z-index:2000;padding:12px 24px;font-size:13px;letter-spacing:1px;background:#000;color:#f6f3ec;border:1px solid var(--accent);border-radius:6px;font-family:var(--mono);opacity:0;transition:opacity .2s,transform .2s;white-space:nowrap}
.toast.show{opacity:1;transform:translateX(-50%) translateY(-6px)}
[data-magnetic]{transition:transform .35s cubic-bezier(.22,1,.36,1);will-change:transform}
.hdr{position:fixed;top:0;left:0;right:0;z-index:1000;height:60px;padding:0 30px;display:flex;align-items:center;justify-content:space-between;background:rgba(10,10,10,.55);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--line);transition:background .25s}
.hdr.scrolled{background:rgba(10,10,10,.92)}
.hdr-logo{display:flex;align-items:center;gap:10px;font-family:Inter,sans-serif;font-weight:600;font-size:15px;letter-spacing:.5px}
.hdr-logo img{width:24px;height:24px;border-radius:6px;flex-shrink:0}
.ver{display:inline-flex;align-items:center;padding:2px 7px;margin-left:6px;font-family:var(--mono);font-size:10px;letter-spacing:.5px;color:var(--accent);border:1px solid rgba(232,160,80,.4);border-radius:3px;font-weight:500;background:rgba(232,160,80,.08);transition:all .25s}
.ver:hover{background:var(--accent);color:#000;border-color:var(--accent)}
.hdr-nav{display:flex;align-items:center;gap:22px;font-family:var(--mono);font-size:12px;letter-spacing:1.5px;text-transform:uppercase}
.hdr-nav a{position:relative;padding:6px 2px;line-height:1;color:rgba(255,255,255,.65);transition:color .2s}
.hdr-nav a::after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:var(--accent);transform:scaleX(0);transform-origin:left;transition:transform .25s}
.hdr-nav a:hover,.hdr-nav a.active{color:#fff}
.hdr-nav a.active::after{transform:scaleX(1)}
.hdr-nav a.nav-cp{color:var(--accent);position:relative;padding-left:14px;display:inline-flex;align-items:center;gap:8px}
.hdr-nav a.nav-cp::before{content:"";position:absolute;left:4px;top:50%;width:5px;height:5px;border-radius:50%;background:var(--accent);transform:translateY(-50%);box-shadow:0 0 6px var(--accent);animation:dotPulse 2s ease-in-out infinite}
.hdr-nav a.nav-cp:hover{color:#fff}
.hdr-nav a.nav-cp .free-badge{padding:1px 6px;font-size:9px;font-weight:600;letter-spacing:1px;background:rgba(232,160,80,.18);color:var(--accent);border:1px solid rgba(232,160,80,.4);border-radius:3px;text-transform:uppercase}
html.light .hdr-nav a.nav-cp{color:#c87618}
html.light .hdr-nav a.nav-cp::before{background:#c87618;box-shadow:0 0 6px #c87618}
html.light .hdr-nav a.nav-cp:hover{color:#0d0d0d}
html.light .hdr-nav a.nav-cp .free-badge{background:rgba(200,118,24,.12);color:#c87618;border-color:rgba(200,118,24,.4)}
.hdr-right{display:flex;gap:10px;align-items:center}
.btn-pill{height:32px;padding:0 14px;display:inline-flex;align-items:center;gap:6px;border:1px solid rgba(255,255,255,.25);font-size:11px;letter-spacing:1.5px;color:#fff;font-family:var(--mono);transition:background .2s,color .2s,border-color .2s}
.btn-pill:hover{background:#fff;color:#000;border-color:#fff}
.btn-pill.primary{background:var(--accent);color:#000;border-color:var(--accent)}
.btn-pill.primary:hover{background:#fff;color:#000;border-color:#fff}
.icon-btn{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.2);color:rgba(255,255,255,.75);transition:all .2s}
.icon-btn:hover{color:#fff;border-color:#fff;background:rgba(255,255,255,.05)}
.hero{position:relative;padding:130px 30px 80px;overflow:hidden}
.hero::before{content:"";position:absolute;inset:0;background:
radial-gradient(ellipse 80% 50% at 50% 0%,rgba(232,160,80,.15),transparent 60%),
repeating-linear-gradient(transparent 0,transparent 39px,rgba(255,255,255,.025) 40px);
pointer-events:none}
.hero-wrap{width:min(1180px,100%);margin:0 auto;display:grid;grid-template-columns:1.1fr 1fr;gap:60px;align-items:center;position:relative}
.hero-wrap > *{min-width:0}
.hero-left .badge{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;letter-spacing:2.5px;color:var(--accent);text-transform:uppercase;padding:6px 12px;border:1px solid rgba(232,160,80,.35);border-radius:999px;margin-bottom:22px}
.hero-left .badge .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);animation:dotPulse 2s ease-in-out infinite}
@keyframes dotPulse{0%,50%{opacity:1}25%{opacity:.3}}
.hero h1{margin:0 0 18px;font-family:Inter,sans-serif;font-size:60px;font-weight:600;line-height:1.05;letter-spacing:-1.5px}
.hero h1 .l1{display:block;background:linear-gradient(180deg,#fff,#9ba3b3);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero h1 .l2{display:block;background:linear-gradient(90deg,#e8a050,#ffd194);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero .sub{font-size:16px;line-height:1.7;color:rgba(255,255,255,.7);max-width:560px;margin:0 0 32px}
.hero .sub b{color:#fff;font-weight:500}
.install-box{background:#000;border:1px solid var(--line);border-radius:10px;overflow:hidden;font-family:var(--mono);max-width:560px}
.install-tabs{display:flex;border-bottom:1px solid var(--line);background:rgba(255,255,255,.02)}
.install-tab{padding:11px 16px;font-size:11px;letter-spacing:1.5px;color:rgba(255,255,255,.55);cursor:pointer;border-right:1px solid var(--line);transition:color .2s,background .2s;display:flex;align-items:center;gap:6px}
.install-tab.active{color:var(--accent);background:rgba(232,160,80,.06)}
.install-tab .ind{font-size:10px;color:var(--green);opacity:0;transition:opacity .2s}
.install-tab.active .ind{opacity:1}
.install-body{padding:18px 18px 14px;position:relative}
`irm https://…/install.ps1 | iex` is ~94 chars vs ~520 px
container) wrap visually instead of triggering Windows' chunky
10-12 px default horizontal scrollbar. JS copy uses the
underlying string verbatim, so the wrap is purely visual.
`overflow-x:auto` + the thin scrollbar style below stay as a
belt-and-suspenders for any pathological token that's longer
than the container with no break-opportunity. */
set, CSS spec promotes the default `overflow-y:visible` to
`auto` (can't mix visible with non-visible on the other axis),
which silently spawned a vertical scrollbar on any sub-pixel
content overhang. Also zero the default `<pre>` margin so the
element fits its container snugly. */
.install-cmd{font-size:13px;color:#e8e8e8;white-space:pre-wrap;word-break:break-word;overflow-x:auto;overflow-y:hidden;margin:0;line-height:1.5;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.2) transparent}
.install-cmd::-webkit-scrollbar{height:6px}
.install-cmd::-webkit-scrollbar-track{background:transparent}
.install-cmd::-webkit-scrollbar-thumb{background:rgba(255,255,255,.18);border-radius:3px}
.install-cmd::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.3)}
.install-cmd .accent{color:var(--accent)}
.install-cmd .str{color:#9ecbff}
.install-cmd .com{color:rgba(255,255,255,.4)}
blank lines (macOS curl ‖ Windows irm, Releases URL ‖ curl pipe).
Each section becomes its own bordered card. The action bar at the
top doubles as a section header — leading `#` comment in the
METHOD_CMDS string ("# macOS / Linux / HarmonyOS PC", etc.) is
pulled out as the bar label, button sits at the right, code below
contains only executable lines. Saves the row of vertical space
that a separate comment row would have cost, and the comment is
never going into the clipboard either way. */
.install-cmd-list{display:flex;flex-direction:column;gap:10px}
.install-cmd-section{border:1px solid rgba(255,255,255,.06);border-radius:6px;background:rgba(255,255,255,.02);overflow:hidden}
.install-cmd-section .cp-bar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 6px 4px 12px;background:rgba(255,255,255,.025);border-bottom:1px solid rgba(255,255,255,.05)}
.install-cmd-section .cp-bar .label{font-family:var(--mono);font-size:10.5px;letter-spacing:.5px;color:rgba(255,255,255,.5);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.install-cmd-section .install-cmd{margin:0;padding:10px 12px}
.install-cmd-section .cp-btn{padding:3px 10px;font-size:10px;letter-spacing:1px;background:transparent;border-color:rgba(232,160,80,.28);color:rgba(232,160,80,.85);opacity:.85;transition:background .2s,color .2s,border-color .2s,opacity .15s;flex-shrink:0}
.install-cmd-section:hover .cp-btn{opacity:1}
.install-cmd-section .cp-btn:hover{background:var(--accent);color:#000;border-color:var(--accent)}
.install-cmd-section .cp-btn.copied{opacity:1;background:var(--green);color:#000;border-color:var(--green)}
.install-actions{margin-top:14px;display:flex;align-items:center;justify-content:space-between;font-size:11px;letter-spacing:.5px;color:rgba(255,255,255,.45)}
.install-actions .left{display:flex;align-items:center;gap:10px}
.cp-btn{padding:7px 14px;background:rgba(232,160,80,.18);border:1px solid rgba(232,160,80,.4);color:var(--accent);font-family:var(--mono);font-size:11px;letter-spacing:1.5px;transition:all .2s}
.cp-btn:hover{background:var(--accent);color:#000}
.cp-btn.copied{background:var(--green);color:#000;border-color:var(--green)}
.hero-cta{margin-top:22px;display:flex;gap:14px;flex-wrap:wrap}
.btn{padding:14px 22px;font-family:var(--mono);font-size:12px;letter-spacing:1.8px;transition:all .2s ease;display:inline-flex;align-items:center;gap:8px}
.btn-primary{background:var(--accent);color:#000;border:1px solid var(--accent);font-weight:600;box-shadow:0 8px 26px rgba(232,160,80,.25)}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 14px 36px rgba(232,160,80,.45)}
.btn-outline{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}
.btn-outline:hover{background:#fff;color:#000;border-color:#fff}
.terminal{background:#000;border:1px solid var(--line);border-radius:12px;font-family:var(--mono);font-size:13px;line-height:1.65;box-shadow:0 24px 60px rgba(0,0,0,.6);overflow:hidden}
.term-head{padding:10px 14px;background:rgba(255,255,255,.03);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;color:rgba(255,255,255,.5);font-size:11px;letter-spacing:1px}
.term-dots{display:flex;gap:6px}
.term-dots span{width:10px;height:10px;border-radius:50%}
.term-dots span:nth-child(1){background:#ff5f56}
.term-dots span:nth-child(2){background:#ffbd2e}
.term-dots span:nth-child(3){background:#27c93f}
.term-title{flex:1;text-align:center;color:rgba(255,255,255,.4)}
.term-tag{font-size:10px;letter-spacing:1.5px;color:rgba(255,255,255,.4);padding:2px 8px;border:1px solid var(--line)}
.term-chips{display:flex;gap:6px;padding:10px 14px;border-bottom:1px solid var(--line);background:rgba(255,255,255,.015)}
.term-chip{padding:5px 11px;font-size:11px;letter-spacing:.5px;color:rgba(255,255,255,.55);border:1px solid var(--line);transition:all .2s;cursor:pointer}
.term-chip:hover{color:#fff;border-color:rgba(232,160,80,.5)}
.term-chip.active{background:var(--accent);color:#000;border-color:var(--accent);font-weight:500}
.term-body{padding:16px 18px;min-height:380px;max-height:380px;overflow:auto;color:#d8d8d8}
.tl{display:block;margin:2px 0;opacity:0;transform:translateY(4px);animation:tlIn .25s ease forwards;white-space:pre-wrap;word-break:break-word}
@keyframes tlIn{to{opacity:1;transform:translateY(0)}}
.tl.user{color:var(--accent);font-weight:500}
.tl.user::before{content:"› ";color:rgba(232,160,80,.7)}
.tl.thinking{color:rgba(255,255,255,.55);font-style:italic}
.tl.thinking::before{content:"~ "}
.tl.tool{color:var(--blue)}
.tl.tool::before{content:"▸ "}
.tl.output{color:rgba(255,255,255,.7);padding-left:14px;border-left:2px solid var(--line)}
.tl.success{color:var(--green)}
.tl.success::before{content:"✓ "}
.tl.error{color:var(--red)}
.tl.assistant{color:#fff;background:rgba(232,160,80,.08);padding:8px 12px;margin-top:8px;border-left:2px solid var(--accent)}
.tl.diff-add{color:var(--green)}
.tl.diff-del{color:var(--red)}
.caret{display:inline-block;width:8px;height:14px;background:var(--accent);vertical-align:middle;margin-left:2px;animation:blink 1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
.stats{padding:80px 30px 40px}
.stats-wrap{width:min(1180px,100%);margin:0 auto;display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.stat-card{padding:32px 24px;border:1px solid var(--line);background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0));position:relative;cursor:default;transition:border-color .25s,transform .3s}
.stat-card:hover{border-color:rgba(232,160,80,.45);transform:translateY(-3px)}
.stat-card .v{font-family:Inter,sans-serif;font-size:56px;font-weight:600;line-height:1;letter-spacing:-2px;color:#fff;font-variant-numeric:tabular-nums}
.stat-card .v .suf{font-size:24px;color:var(--accent);margin-left:4px}
.stat-card .l{margin-top:10px;font-family:var(--mono);font-size:12px;letter-spacing:1.5px;color:rgba(255,255,255,.55);text-transform:uppercase}
.stat-card .pop{position:absolute;top:100%;left:0;right:0;margin-top:8px;background:#000;border:1px solid var(--line);padding:14px;font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.7);line-height:1.6;opacity:0;pointer-events:none;transform:translateY(-4px);transition:all .2s ease;z-index:10}
.stat-card:hover .pop{opacity:1;pointer-events:auto;transform:translateY(0)}
.stat-card .pop b{color:var(--accent)}
.section-head{width:min(1180px,100%);margin:0 auto 40px;display:flex;align-items:flex-end;justify-content:space-between;flex-wrap:wrap;gap:20px;padding:0 12px;border-bottom:1px solid var(--line);padding-bottom:18px}
.section-head h2{margin:0;font-family:Inter,sans-serif;font-size:34px;font-weight:600;letter-spacing:-1px;color:#fff}
.section-head h2 .mono{font-family:var(--mono);font-size:14px;color:var(--accent);letter-spacing:3px;text-transform:uppercase;display:block;margin-bottom:8px;font-weight:400}
.section-head .hint{font-family:var(--mono);font-size:12px;color:rgba(255,255,255,.5);letter-spacing:1px}
.features{padding:60px 30px 100px}
.grid-features{width:min(1180px,100%);margin:0 auto;display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.feat{position:relative;padding:28px 26px 22px;border:1px solid var(--line);background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0));transition:border-color .25s,transform .3s cubic-bezier(.22,1,.36,1);overflow:hidden;min-height:280px;display:flex;flex-direction:column}
.feat::before{content:"";position:absolute;inset:0;background:radial-gradient(circle 220px at var(--mx,50%) var(--my,50%),rgba(232,160,80,.16),transparent 60%);opacity:0;transition:opacity .25s;pointer-events:none}
.feat:hover::before{opacity:1}
.feat:hover{border-color:rgba(232,160,80,.45);transform:translateY(-2px)}
.feat > *{position:relative;z-index:1}
.feat .icon{width:40px;height:40px;border-radius:8px;background:rgba(232,160,80,.15);color:var(--accent);display:flex;align-items:center;justify-content:center;margin-bottom:14px;font-family:Inter,sans-serif;font-weight:700;font-size:18px}
.feat h3{margin:0 0 8px;font-family:Inter,sans-serif;font-size:18px;font-weight:600;color:#fff}
.feat p{margin:0;font-size:13px;line-height:1.65;color:rgba(255,255,255,.6)}
.feat .demo{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);flex:1;display:flex;align-items:center;justify-content:center;min-height:90px}
.agent-loop{display:flex;gap:8px;align-items:center;font-family:var(--mono);font-size:11px;letter-spacing:.5px;color:rgba(255,255,255,.6)}
.agent-loop .node{padding:6px 10px;border:1px solid var(--line);transition:all .3s}
.agent-loop .node.active{background:rgba(232,160,80,.18);color:var(--accent);border-color:var(--accent)}
.agent-loop .arrow{color:rgba(255,255,255,.3)}
.model-strip{display:flex;gap:8px;animation:strip 12s linear infinite;white-space:nowrap}
@keyframes strip{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.model-strip span{padding:6px 12px;background:rgba(255,255,255,.05);border:1px solid var(--line);font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.7);letter-spacing:.5px;flex-shrink:0}
.graph-mini{width:100%;height:80px}
.vis-drop{width:100%;padding:14px;border:1px dashed rgba(232,160,80,.4);background:rgba(232,160,80,.04);font-family:var(--mono);font-size:11px;color:rgba(232,160,80,.8);text-align:center;letter-spacing:.5px}
.vis-drop b{color:var(--accent);font-weight:500}
.gitcmd{font-family:var(--mono);font-size:11px;line-height:1.8;width:100%}
.gitcmd .l1{color:var(--accent)}
.gitcmd .l2{color:var(--green)}
.plugin-row{display:flex;gap:6px;width:100%;overflow:hidden}
.plugin-row .p{flex:1;padding:8px 10px;border:1px solid var(--line);font-family:var(--mono);font-size:10px;color:rgba(255,255,255,.7);letter-spacing:.3px;background:rgba(255,255,255,.02)}
.plugin-row .p b{color:#fff;display:block;font-size:11px;font-weight:500}
.plugins{padding:60px 30px 100px;background:linear-gradient(180deg,rgba(255,255,255,.015),transparent)}
.plugin-wrap{width:min(1180px,100%);margin:0 auto}
.plugin-grid{display:grid;grid-template-columns:1fr 1fr;gap:24px}
.plugin-grid>.plugin-install{height:100%}
.plugin-features{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.plugin-feat{padding:22px 18px;border:1px solid var(--line);background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0));transition:border-color .25s,transform .3s cubic-bezier(.22,1,.36,1)}
.plugin-feat:hover{border-color:rgba(232,160,80,.45);transform:translateY(-1px)}
.plugin-feat .icon{width:32px;height:32px;border-radius:6px;background:rgba(232,160,80,.15);color:var(--accent);display:flex;align-items:center;justify-content:center;margin-bottom:10px;font-size:15px;font-weight:700}
.plugin-feat h3{margin:0 0 6px;font-family:Inter,sans-serif;font-size:15px;font-weight:600;color:#fff}
.plugin-feat p{margin:0;font-size:12px;line-height:1.6;color:rgba(255,255,255,.55)}
.plugin-install{background:#000;border:1px solid var(--line);border-radius:10px;overflow:hidden;font-family:var(--mono);flex:1;display:flex;flex-direction:column}
.plugin-install .pi-head{padding:12px 16px;background:rgba(255,255,255,.03);border-bottom:1px solid var(--line);font-size:11px;letter-spacing:1.5px;color:var(--accent)}
.plugin-install .pi-body{padding:18px;display:flex;flex-direction:column;gap:14px;flex:1}
.plugin-install .pi-item{border:1px solid rgba(255,255,255,.06);border-radius:6px;background:rgba(255,255,255,.015);overflow:hidden}
.plugin-install .pi-item .pi-label{padding:5px 12px;background:rgba(255,255,255,.025);border-bottom:1px solid rgba(255,255,255,.05);font-size:10.5px;letter-spacing:.5px;color:rgba(255,255,255,.5)}
.plugin-install .pi-item .pi-url{display:block;padding:10px 12px;font-size:12px;color:var(--accent);text-decoration:none;line-height:1.5;word-break:break-all}
.plugin-install .pi-item .pi-url:hover{text-decoration:underline}
.plugin-install .pi-item .pi-cmd{margin:0;padding:10px 12px;font-size:12px;color:#e8e8e8;white-space:pre-wrap;line-height:1.5}
.pi-steps{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;padding:8px 12px;font-size:11px;color:rgba(255,255,255,.65)}
.pi-steps+.pi-steps{padding-top:0}
.pi-step-num{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background:rgba(232,160,80,.18);color:var(--accent);font-size:7px;font-weight:600;flex-shrink:0}
.pi-steps .pi-url{display:block;width:100%;margin-top:4px;padding:0 0 0 24px;font-size:12px;color:var(--accent);text-decoration:none;word-break:break-all}
.pi-steps .pi-url:hover{text-decoration:underline}
.pi-steps .pi-cmd{width:100%;margin:4px 0 0 24px;font-size:12px;color:#e8e8e8;white-space:pre-wrap;line-height:1.5;font-family:var(--mono)}
.pi-item .cp-bar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 6px 4px 12px;background:rgba(255,255,255,.025);border-bottom:1px solid rgba(255,255,255,.05)}
.pi-item .cp-bar .label{font-family:var(--mono);font-size:10.5px;letter-spacing:.5px;color:rgba(255,255,255,.5);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pi-item .cp-btn{opacity:.85}
.pi-item:hover .cp-btn{opacity:1}
.pi-steps .cp-btn{flex-shrink:0;margin-left:auto}
.plugin-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:32px}
.plugin-stat{padding:24px 20px;border:1px solid var(--line);background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0));text-align:center;transition:border-color .25s,transform .3s}
.plugin-stat:hover{border-color:rgba(232,160,80,.45);transform:translateY(-3px)}
.plugin-stat .v{font-family:Inter,sans-serif;font-size:40px;font-weight:600;color:#fff}
.plugin-stat .v .suf{font-size:18px;color:var(--accent);margin-left:2px}
.plugin-stat .l{margin-top:6px;font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.5);letter-spacing:1.5px;text-transform:uppercase}
.compare{padding:60px 30px 100px;background:linear-gradient(180deg,rgba(255,255,255,.015),transparent)}
.cmp-wrap{width:min(1180px,100%);margin:0 auto}
.cmp-controls{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;margin-bottom:24px}
.cmp-chips{display:flex;gap:6px;flex-wrap:wrap}
.cmp-chip{padding:7px 12px;border:1px solid var(--line);font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.65);letter-spacing:.5px;transition:all .2s}
.cmp-chip:hover{border-color:rgba(232,160,80,.5);color:#fff}
.cmp-chip.active{background:var(--accent);color:#000;border-color:var(--accent);font-weight:500}
.cmp-toggle{display:flex;align-items:center;gap:10px;font-family:var(--mono);font-size:12px;color:rgba(255,255,255,.7);letter-spacing:.5px;cursor:pointer;user-select:none}
.cmp-toggle .sw{width:36px;height:20px;background:rgba(255,255,255,.1);border:1px solid var(--line);border-radius:10px;position:relative;transition:background .25s}
.cmp-toggle .sw::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .25s}
.cmp-toggle.on .sw{background:var(--accent);border-color:var(--accent)}
.cmp-toggle.on .sw::after{transform:translateX(16px);background:#000}
.perf{margin-bottom:40px;padding:24px;background:rgba(255,255,255,.015);border:1px solid var(--line)}
.perf h3{margin:0 0 8px;font-family:Inter,sans-serif;font-size:18px;font-weight:600;color:#fff}
.perf .desc{font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.5);margin-bottom:18px;letter-spacing:.5px}
.perf-legend{display:flex;gap:18px;margin-bottom:14px;font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.6);letter-spacing:.5px}
.perf-legend .sw{width:12px;height:12px;display:inline-block;vertical-align:middle;margin-right:6px}
.perf-legend .sw.a{background:var(--accent)}
.perf-legend .sw.c{background:rgba(255,255,255,.4)}
.perf-row{display:grid;grid-template-columns:1.4fr 1fr 90px;gap:14px;align-items:center;padding:10px 0;border-top:1px dashed var(--line);font-family:var(--mono);font-size:12px}
.perf-row .name{color:rgba(255,255,255,.8)}
.perf-bars{display:flex;flex-direction:column;gap:5px}
.perf-bar{height:16px;background:rgba(255,255,255,.05);position:relative;overflow:hidden;border-radius:3px}
.perf-bar .fill{height:100%;transition:width 1s cubic-bezier(.22,1,.36,1)}
.perf-bar.a .fill{background:linear-gradient(90deg,var(--accent),#ffd194)}
.perf-bar.c .fill{background:rgba(255,255,255,.4)}
.perf-bar .lbl{position:absolute;right:4px;top:50%;transform:translateY(-50%);font-size:9px;font-weight:600;letter-spacing:.4px;padding:1px 6px;border-radius:3px;background:rgba(0,0,0,.6);color:#fff}
.perf-status{font-family:var(--mono);font-size:11px;letter-spacing:.5px;text-align:right}
.perf-status.eq{color:var(--green)}
.perf-status.near{color:var(--blue)}
.perf-status.gap{color:var(--accent)}
.ftab-wrap{border:1px solid var(--line);overflow-x:auto;position:relative}
.ftab{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:13px;min-width:600px}
.ftab th{background:#000;text-align:left;padding:14px 18px;font-size:11px;font-weight:500;letter-spacing:1.5px;color:rgba(255,255,255,.55);text-transform:uppercase;border-bottom:1px solid var(--line)}
.ftab th.atom{color:var(--accent)}
.ftab th.claude{color:rgba(255,255,255,.7)}
.ftab td{padding:14px 18px;border-bottom:1px solid var(--line);color:rgba(255,255,255,.8);transition:background .2s}
.ftab tr:hover td{background:rgba(232,160,80,.04)}
.ftab tr:last-child td{border-bottom:none}
.ftab td.win{color:var(--accent);font-weight:500}
.ftab td.lose{color:rgba(255,255,255,.5)}
.ftab .cat{display:inline-block;padding:2px 7px;font-size:10px;background:rgba(255,255,255,.06);border:1px solid var(--line);margin-right:8px;letter-spacing:.5px}
.ftab tr.hidden{display:none}
.gap-note{margin-top:28px;padding:18px 20px;border:1px dashed var(--line);background:rgba(232,160,80,.03);font-family:var(--mono);font-size:12px;line-height:1.7;color:rgba(255,255,255,.7)}
.gap-note b{color:var(--accent)}
.install{padding:60px 30px 100px}
.install-wrap{width:min(1180px,100%);margin:0 auto}
.install-grid{display:grid;grid-template-columns:1.1fr 1fr;gap:32px;align-items:flex-start}
.install-grid > *{min-width:0}
.install-block{background:#000;border:1px solid var(--line);border-radius:10px;overflow:hidden}
.stepper{display:grid;grid-template-columns:repeat(3,1fr);gap:0;font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.6);letter-spacing:1px;margin-top:0;margin-bottom:24px;border:1px solid var(--line)}
.step{padding:18px 20px;border-right:1px solid var(--line);position:relative}
.step:last-child{border-right:none}
.step .n{font-size:24px;color:var(--accent);font-weight:600;font-family:Inter,sans-serif;letter-spacing:-.5px}
.step .t{margin-top:6px;font-size:13px;color:#fff;font-family:Inter,sans-serif}
.step .d{margin-top:4px;font-size:11px;color:rgba(255,255,255,.5)}
.step .ch{position:absolute;top:50%;right:-10px;transform:translateY(-50%);background:#000;border:1px solid var(--line);color:rgba(255,255,255,.45);width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;z-index:1}
.step:last-child .ch{display:none}
.download-row{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:14px}
.dl-btn{padding:10px 14px;background:rgba(255,255,255,.03);border:1px solid var(--line);font-family:var(--mono);font-size:12px;color:#fff;letter-spacing:.5px;display:flex;justify-content:space-between;align-items:center;transition:all .2s}
.dl-btn:hover{border-color:var(--accent);color:var(--accent)}
.dl-btn small{color:rgba(255,255,255,.4);font-size:10px}
.wiz{background:#000;border:1px solid var(--line);border-radius:10px;font-family:var(--mono);font-size:13px;color:#d8d8d8;overflow:hidden}
.wiz-head{padding:12px 16px;background:rgba(255,255,255,.03);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:1.5px;color:var(--accent)}
.wiz-body{padding:18px 18px;line-height:1.7}
.wiz-step{display:none}
.wiz-step.active{display:block}
.wiz-step .tt{color:var(--accent);margin-bottom:6px;font-size:12px;letter-spacing:1.5px}
.wiz-step .qq{color:#fff;margin-bottom:14px;font-size:14px}
.wiz-step .opt{padding:10px 12px;border:1px solid var(--line);margin-bottom:6px;cursor:pointer;transition:all .2s;display:flex;justify-content:space-between;align-items:center}
.wiz-step .opt:hover,.wiz-step .opt.sel{border-color:var(--accent);background:rgba(232,160,80,.06);color:#fff}
.wiz-step .opt small{color:rgba(255,255,255,.4);font-size:10px}
.wiz-step .intro-list{list-style:none;margin:8px 0 14px;padding:0;color:rgba(255,255,255,.8);font-size:13px;line-height:2}
.wiz-step .intro-list li{padding-left:14px;position:relative}
.wiz-step .intro-list li::before{content:"•";position:absolute;left:0;color:var(--accent)}
.wiz-step .intro-hint{margin-top:14px;padding-top:10px;border-top:1px dashed var(--line);font-size:11px;color:rgba(255,255,255,.5);letter-spacing:.5px}
.wiz-step .intro-hint.inline{margin:0 0 14px;padding-top:0;border-top:none}
.wiz-nav-hint{margin-top:14px;padding:10px 12px;border:1px dashed var(--line);font-size:11px;color:rgba(255,255,255,.5);letter-spacing:.5px;text-align:center}
.wiz-nav{margin-top:14px;display:flex;justify-content:space-between;align-items:center}
.wiz-dots{display:flex;gap:6px}
.wiz-dots span{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.2)}
.wiz-dots span.on{background:var(--accent)}
.wiz-nav button{padding:6px 12px;border:1px solid var(--line);font-size:11px;letter-spacing:1px;color:rgba(255,255,255,.7);transition:all .2s}
.wiz-nav button:hover{color:#fff;border-color:#fff}
.ftr{padding:50px 30px 30px;text-align:center;font-family:Outfit,Inter,sans-serif;font-size:12px;color:rgba(255,255,255,.4);border-top:1px solid var(--line)}
.ftr-row{margin-bottom:14px;font-family:var(--mono);letter-spacing:1px}
.ftr-row a{margin:0 6px}
.ftr-row a:hover{color:#fff}
.ftr-tag{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border:1px solid var(--line);font-family:var(--mono);font-size:11px;color:var(--rust);margin-top:8px}
html.light{color-scheme:light}
html.light body{background:#f6f3ec;color:#0d0d0d}
html.light .aurora{mix-blend-mode:multiply;background:radial-gradient(circle 360px at var(--mx,-200px) var(--my,-200px),rgba(232,160,80,.30) 0%,rgba(232,160,80,.10) 30%,rgba(232,160,80,0) 60%)}
html.light .ripple{background:rgba(200,118,24,.55)}
html.light .progress-track{background:rgba(0,0,0,.05)}
html.light .hdr{background:rgba(246,243,236,.6);border-bottom-color:rgba(0,0,0,.10);color:#0d0d0d}
html.light .hdr.scrolled{background:rgba(246,243,236,.92)}
html.light .hdr-nav a{color:rgba(0,0,0,.55)}
html.light .hdr-nav a:hover,html.light .hdr-nav a.active{color:#0d0d0d}
html.light .btn-pill{color:#0d0d0d;border-color:rgba(0,0,0,.25)}
html.light .btn-pill:hover{background:#0d0d0d;color:#fff;border-color:#0d0d0d}
html.light .btn-pill.primary{background:#c87618;color:#fff;border-color:#c87618}
html.light .btn-pill.primary:hover{background:#0d0d0d;color:#fff;border-color:#0d0d0d}
html.light .icon-btn{color:rgba(0,0,0,.65);border-color:rgba(0,0,0,.2)}
html.light .icon-btn:hover{color:#fff;background:#0d0d0d;border-color:#0d0d0d}
html.light .ver{color:#c87618;border-color:rgba(200,118,24,.5);background:rgba(232,160,80,.10)}
html.light .ver:hover{background:#c87618;color:#fff}
html.light .hero::before{background:radial-gradient(ellipse 80% 50% at 50% 0%,rgba(232,160,80,.20),transparent 60%),repeating-linear-gradient(transparent 0,transparent 39px,rgba(0,0,0,.045) 40px)}
html.light .hero h1 .l1{background:linear-gradient(180deg,#0d0d0d,#5a5a5a);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
html.light .hero h1 .l2{background:linear-gradient(90deg,#c87618,#e8a050);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
html.light .hero .sub{color:rgba(0,0,0,.7)}
html.light .hero .sub b{color:#0d0d0d}
html.light .hero-left .badge{color:#c87618;border-color:rgba(200,118,24,.4);background:rgba(255,255,255,.5)}
html.light .hero-left .badge .dot{background:#c87618;box-shadow:0 0 8px #c87618}
html.light .btn-primary{background:#c87618;color:#fff;border-color:#c87618;box-shadow:0 8px 26px rgba(200,118,24,.25)}
html.light .btn-primary:hover{box-shadow:0 14px 36px rgba(200,118,24,.4)}
html.light .btn-outline{color:#0d0d0d;border-color:rgba(0,0,0,.4)}
html.light .btn-outline:hover{background:#0d0d0d;color:#fff;border-color:#0d0d0d}
html.light .section-head h2{color:#0d0d0d}
html.light .section-head{border-bottom-color:rgba(0,0,0,.12)}
html.light .section-head .hint{color:rgba(0,0,0,.5)}
html.light .section-head h2 .mono{color:#c87618}
html.light .stats .stat-card,html.light .feat,html.light .perf,html.light .ftab-wrap,html.light .stepper,html.light .step,html.light .dl-btn,html.light .gap-note{background:#fff;border-color:rgba(0,0,0,.10)}
html.light .stats .stat-card:hover,html.light .feat:hover{border-color:rgba(200,118,24,.5)}
html.light .stat-card .v{color:#0d0d0d}
html.light .stat-card .v .suf{color:#c87618}
html.light .stat-card .l{color:rgba(0,0,0,.55)}
html.light .feat h3,html.light .perf h3{color:#0d0d0d}
html.light .feat p,html.light .perf .desc,html.light .perf-legend{color:rgba(0,0,0,.6)}
html.light .feat .demo{border-top-color:rgba(0,0,0,.08)}
html.light .feat .icon{background:rgba(232,160,80,.20);color:#c87618}
html.light .agent-loop .node{border-color:rgba(0,0,0,.12);color:rgba(0,0,0,.7);background:#fff}
html.light .agent-loop .node.active{background:rgba(232,160,80,.18);color:#c87618;border-color:#c87618}
html.light .agent-loop .arrow{color:rgba(0,0,0,.3)}
html.light .model-strip span{background:#fff;border-color:rgba(0,0,0,.10);color:rgba(0,0,0,.7)}
html.light .vis-drop{color:#c87618;background:rgba(232,160,80,.06);border-color:rgba(200,118,24,.45)}
html.light .plugin-row .p{background:#fff;border-color:rgba(0,0,0,.10);color:rgba(0,0,0,.7)}
html.light .plugin-row .p b{color:#0d0d0d}
html.light .plugin-feat{border-color:rgba(0,0,0,.10);background:#fff}
html.light .plugin-feat:hover{border-color:rgba(200,118,24,.45)}
html.light .plugin-feat .icon{background:rgba(200,118,24,.12);color:#c87618}
html.light .plugin-feat h3{color:#0d0d0d}
html.light .plugin-feat p{color:rgba(0,0,0,.55)}
html.light .plugin-install{background:#fff;border-color:rgba(0,0,0,.10)}
html.light .plugin-install .pi-head{color:#c87618;background:rgba(0,0,0,.02);border-bottom-color:rgba(0,0,0,.08)}
html.light .plugin-install .pi-item{border-color:rgba(0,0,0,.08);background:rgba(0,0,0,.01)}
html.light .plugin-install .pi-item .pi-label{background:rgba(0,0,0,.025);border-bottom-color:rgba(0,0,0,.05);color:rgba(0,0,0,.5)}
html.light .plugin-install .pi-item .pi-url{color:#c87618}
html.light .plugin-install .pi-item .pi-cmd{color:#0d0d0d}
html.light .pi-step-num{background:rgba(200,118,24,.12);color:#c87618}
html.light .pi-steps{color:rgba(0,0,0,.55)}
html.light .pi-steps .pi-url{color:#c87618}
html.light .pi-item .cp-bar{background:rgba(0,0,0,.025);border-bottom-color:rgba(0,0,0,.05)}
html.light .pi-item .cp-bar .label{color:rgba(0,0,0,.5)}
html.light .plugin-stat{border-color:rgba(0,0,0,.10);background:#fff}
html.light .plugin-stat:hover{border-color:rgba(200,118,24,.45)}
html.light .plugin-stat .v{color:#0d0d0d}
html.light .plugin-stat .v .suf{color:#c87618}
html.light .plugin-stat .l{color:rgba(0,0,0,.5)}
html.light .gitcmd .l1{color:#c87618}
html.light .gitcmd .l2{color:#2e8a4e}
html.light .ftab th{background:#fff;color:rgba(0,0,0,.55);border-bottom-color:rgba(0,0,0,.10)}
html.light .ftab th.atom{color:#c87618}
html.light .ftab th.claude{color:rgba(0,0,0,.7)}
html.light .ftab td{color:rgba(0,0,0,.85);border-bottom-color:rgba(0,0,0,.08)}
html.light .ftab tr:hover td{background:rgba(232,160,80,.06)}
html.light .ftab td.win{color:#c87618}
html.light .ftab td.lose{color:rgba(0,0,0,.45)}
html.light .ftab .cat{background:rgba(0,0,0,.04);border-color:rgba(0,0,0,.08);color:rgba(0,0,0,.6)}
html.light .perf{background:#fff}
html.light .perf-bar{background:rgba(0,0,0,.06)}
html.light .perf-bar.c .fill{background:rgba(0,0,0,.45)}
html.light .perf-bar .lbl{background:rgba(255,255,255,.94);color:#0d0d0d}
html.light .perf-row{border-top-color:rgba(0,0,0,.08)}
html.light .perf-row .name{color:rgba(0,0,0,.8)}
html.light .perf-status.eq{color:#3b9c61}
html.light .perf-status.near{color:#4675c4}
html.light .perf-status.gap{color:#c87618}
html.light .gap-note{color:rgba(0,0,0,.72);border-color:rgba(0,0,0,.18);background:rgba(232,160,80,.06)}
html.light .gap-note b{color:#c87618}
html.light .cmp-chip,html.light .term-chip{color:rgba(0,0,0,.65);border-color:rgba(0,0,0,.12);background:rgba(255,255,255,.5)}
html.light .cmp-chip:hover,html.light .term-chip:hover{color:#0d0d0d;background:#fff;border-color:rgba(200,118,24,.5)}
html.light .cmp-chip.active,html.light .term-chip.active{background:#c87618;color:#fff;border-color:#c87618}
html.light .cmp-toggle{color:rgba(0,0,0,.7)}
html.light .cmp-toggle .sw{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.12)}
html.light .cmp-toggle.on .sw{background:#c87618;border-color:#c87618}
html.light .step{border-right-color:rgba(0,0,0,.10)}
html.light .step .d,html.light .step .ch{color:rgba(0,0,0,.55)}
html.light .step .n{color:#c87618}
html.light .step .t{color:#0d0d0d}
html.light .step .ch{background:#fff;border-color:rgba(0,0,0,.1)}
html.light .dl-btn{color:#0d0d0d;background:rgba(255,255,255,.5)}
html.light .dl-btn small{color:rgba(0,0,0,.45)}
html.light .dl-btn:hover{border-color:#c87618;color:#c87618}
html.light .ftr{color:rgba(0,0,0,.55);border-top-color:rgba(0,0,0,.10)}
html.light .ftr a:hover{color:#0d0d0d}
html.light .ftr-tag{background:#fff;color:#b7410e;border-color:rgba(0,0,0,.1)}
.theme-icon{display:inline-flex;width:14px;height:14px;align-items:center;justify-content:center}
.mb-toggle{display:none}
.mb-drawer{display:none}
@media (max-width:1024px){
.hero-wrap{grid-template-columns:1fr;gap:40px}
.stats-wrap{grid-template-columns:repeat(2,1fr)}
.grid-features{grid-template-columns:repeat(2,1fr)}
.install-grid{grid-template-columns:1fr}
}
@media (max-width:768px){
.hdr{padding:0 14px;height:52px}
.hdr-nav{display:none}
.hdr-right{gap:6px}
.hdr-right .btn-pill{display:none}
.ver{padding:1px 5px;margin-left:5px;font-size:9px;letter-spacing:.3px}
.mb-toggle{display:inline-flex}
.hero{padding:100px 16px 60px}
.hero-wrap{gap:32px}
.hero h1{font-size:36px;letter-spacing:-1px}
.hero .sub{font-size:15px;margin-bottom:24px}
.hero-left{min-width:0;max-width:100%}
.hero-left .badge{
display:flex;align-items:flex-start;flex-wrap:nowrap;
width:fit-content;max-width:100%;
font-size:10px;letter-spacing:1px;padding:6px 12px;line-height:1.5;
}
.hero-left .badge .dot{margin-top:5px;flex-shrink:0}
.hero-left .badge > span:last-child{white-space:normal}
.install-box{width:100%;max-width:100%}
.install-body{min-width:0;padding:14px 14px 12px}
.install-cmd{min-width:0;font-size:12px}
.install-cmd-section .cp-bar{padding:3px 5px 3px 9px}
.install-cmd-section .cp-bar .label{font-size:9.5px;letter-spacing:.3px}
.install-cmd-section .install-cmd{padding:8px 10px}
.install-cmd-section .cp-btn{padding:2px 9px;font-size:9.5px;letter-spacing:.5px;opacity:1}
.install-actions{flex-wrap:wrap;gap:8px;font-size:10.5px;margin-top:12px}
.install-actions .left{min-width:0;flex:1}
.cp-btn{white-space:nowrap;padding:6px 12px;font-size:10.5px;letter-spacing:1px}
.terminal{min-width:0;max-width:100%}
.hero-cta{margin-top:18px;gap:10px}
.hero-cta .btn{padding:12px 18px;font-size:11px;letter-spacing:1.4px;flex:1;justify-content:center}
.install-tabs{flex-wrap:wrap}
.install-tab{flex:1;min-width:50%;justify-content:center;border-bottom:1px solid var(--line)}
.install-tab:nth-child(2n){border-right:none}
.install-tab:nth-last-child(-n+2){border-bottom:none}
.terminal{margin-top:8px}
.term-body{padding:12px 14px;min-height:300px;max-height:300px;font-size:12px}
.term-chips{flex-wrap:wrap;padding:8px 10px}
.term-chip{font-size:10px;padding:4px 8px;letter-spacing:.3px}
.stats{padding:48px 16px 24px}
.stats-wrap,.grid-features{grid-template-columns:1fr}
.stats-wrap{gap:10px}
.stat-card{padding:22px 18px}
.stat-card .v{font-size:42px}
.stat-card .v .suf{font-size:18px}
.stat-card .l{font-size:11px;letter-spacing:1.2px}
.stat-card .pop{display:none}
.features{padding:40px 16px 60px}
.compare{padding:40px 16px 60px}
.install{padding:40px 16px 80px}
.section-head{padding:0 4px;padding-bottom:14px;margin-bottom:28px;gap:10px}
.section-head h2{font-size:22px;letter-spacing:-.5px}
.section-head h2 .mono{font-size:11px;letter-spacing:2px;margin-bottom:6px}
.section-head .hint{font-size:11px;letter-spacing:.5px}
.feat{padding:22px 20px 18px;min-height:0}
.feat h3{font-size:16px}
.feat p{font-size:12.5px}
.feat .demo{margin-top:12px;padding-top:12px;min-height:60px}
.perf{padding:18px}
.perf h3{font-size:16px}
.perf-row{grid-template-columns:1fr;gap:6px;padding:12px 0}
.perf-status{text-align:left}
.cmp-controls{gap:10px;margin-bottom:18px}
.cmp-toggle{font-size:11px}
.ftab th,.ftab td{padding:10px 12px;font-size:12px}
.gap-note{padding:14px;font-size:11.5px;margin-top:20px}
.stepper{grid-template-columns:1fr;margin-top:18px}
.step{padding:14px 18px;border-right:none;border-bottom:1px solid var(--line)}
.step:last-child{border-bottom:none}
.step .ch{display:none}
.step:last-child .ch{display:none}
.download-row{grid-template-columns:1fr 1fr}
.wiz-body{padding:14px}
.wiz-step .qq{font-size:13px}
.ftr{padding:36px 16px calc(48px + env(safe-area-inset-bottom,0px))}
.ftr-row a{display:inline-block;padding:4px 0}
.mb-drawer{display:flex;flex-direction:column;position:fixed;top:52px;left:0;right:0;
z-index:999;background:rgba(10,10,10,.96);backdrop-filter:blur(16px);
-webkit-backdrop-filter:blur(16px);
border-bottom:1px solid var(--line);
transform:translateY(-110%);transition:transform .28s ease;
visibility:hidden;
padding:6px 16px 18px;
max-height:calc(100vh - 52px);overflow-y:auto;
}
.mb-drawer.open{transform:translateY(0);visibility:visible}
.mb-drawer a{padding:14px 6px;font-family:var(--mono);font-size:13px;letter-spacing:1.5px;
color:rgba(255,255,255,.78);border-bottom:1px solid var(--line);
text-transform:uppercase;display:flex;align-items:center;gap:8px;
}
.mb-drawer a:hover,.mb-drawer a:active{color:var(--accent)}
.mb-drawer a.cp{color:var(--accent)}
.mb-drawer a .free-badge{padding:1px 6px;font-size:9px;font-weight:600;letter-spacing:1px;
background:rgba(232,160,80,.18);color:var(--accent);
border:1px solid rgba(232,160,80,.4);border-radius:3px;text-transform:uppercase;
}
.mb-drawer a.cta{
margin-top:10px;background:var(--accent);color:#000;font-weight:600;
border:1px solid var(--accent);justify-content:center;border-bottom:none;
font-size:12px;letter-spacing:1.6px;
}
.mb-drawer a.cta:hover,.mb-drawer a.cta:active{color:#000;background:#ffd194}
html.light .mb-drawer{background:rgba(246,243,236,.96)}
html.light .mb-drawer a{color:rgba(0,0,0,.78);border-bottom-color:rgba(0,0,0,.10)}
html.light .mb-drawer a:hover,html.light .mb-drawer a:active{color:#c87618}
html.light .mb-drawer a.cp{color:#c87618}
html.light .mb-drawer a.cta{background:#c87618;color:#fff;border-color:#c87618}
html.light .mb-drawer a.cta:hover,html.light .mb-drawer a.cta:active{background:#0d0d0d;color:#fff}
.plugin-grid{grid-template-columns:1fr}
.plugin-features{grid-template-columns:1fr}
.plugins{padding:40px 16px 60px}
.plugin-stats{grid-template-columns:1fr}
}
@media (max-width:380px){
.install-tabs{flex-direction:column}
.install-tab{min-width:100%;border-right:none;border-bottom:1px solid var(--line)}
.install-tab:last-child{border-bottom:none}
.hero-cta{flex-direction:column}
.hero-cta .btn{width:100%}
}
</style>
</head>
<body>
<div class="progress-track"><div class="progress-bar" id="progressBar"></div></div>
<div class="aurora" id="aurora"></div>
<header class="hdr" id="hdr">
<a class="hdr-logo" href="#top">
<img src="https://cdn-news.gitcode.com/news/atomcode-icon1.png" alt="AtomCode">
<span data-scramble>AtomCode</span>
<span class="ver" id="verBadge" title="当前版本">v4.24.2</span>
</a>
<nav class="hdr-nav" id="hdrNav">
<a href="#features" data-section="features" data-i18n="nav.features">功能</a>
<a href="#editor-plugins" data-section="editor-plugins" data-i18n="nav.plugins">IDE插件</a>
<a href="#install" data-section="install" data-i18n="nav.install">安装</a>
<a href="./docs/index.html" target="_blank" rel="noopener" data-i18n="nav.docs">文档</a>
<a href="https://atomcode-plugin.atomgit.com" target="_blank" rel="noopener" data-i18n="nav.marketplace">Skills</a>
<a class="nav-cp" href="https://ai.atomgit.com/serverless-api" target="_blank" rel="noopener">
<span data-i18n="nav.codingplan">Coding Plan</span>
</a>
</nav>
<div class="hdr-right">
<button class="icon-btn" id="themeBtn" aria-label="主题">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
</button>
<button class="icon-btn" id="langBtn" aria-label="语言">中</button>
<a class="btn-pill" href="https://atomgit.com/atomgit_atomcode/atomcode" target="_blank" rel="noopener" data-i18n="btn.repo">开源仓库</a>
<a class="btn-pill primary" href="#install" data-i18n="btn.start">立即开始</a>
<button class="icon-btn mb-toggle" id="mbToggle" aria-label="菜单" aria-expanded="false">☰</button>
</div>
</header>
<nav class="mb-drawer" id="mbDrawer" aria-label="移动端导航">
<a href="#features" data-i18n="nav.features">功能</a>
<a href="#editor-plugins" data-i18n="nav.plugins">IDE插件</a>
<a href="#install" data-i18n="nav.install">安装</a>
<a href="./docs/index.html" target="_blank" rel="noopener" data-i18n="nav.docs">文档</a>
<a href="https://atomcode-plugin.atomgit.com" target="_blank" rel="noopener" data-i18n="nav.marketplace">Skills</a>
<a class="cp" href="https://ai.atomgit.com/serverless-api" target="_blank" rel="noopener">
<span data-i18n="nav.codingplan">Coding Plan</span>
</a>
<a href="https://atomgit.com/atomgit_atomcode/atomcode" target="_blank" rel="noopener" data-i18n="btn.repo">开源仓库</a>
<a class="cta" href="#install" data-i18n="btn.start.arrow">立即开始 →</a>
</nav>
<section class="hero" id="top">
<div class="hero-wrap">
<div class="hero-left">
<div class="badge"><span class="dot"></span><span data-i18n="hero.badge">开源 · 多模型 · 100% AI 生成 · Rust 1.88+</span></div>
<h1>
<span class="l1" data-i18n="hero.t1">AI 编程助手</span>
<span class="l2" data-i18n="hero.t2">在你的终端中运行</span>
</h1>
<p class="sub" data-i18n-html="hero.sub">Claude Code / Cursor Agent 的<b>开源平替</b>,住在你的终端里。连接任意 OpenAI 兼容大模型,自主读文件、改代码、跑测试、自我验证 —— 用 Rust 构建。本项目<b>100% 由 AI 生成</b>。</p>
<div class="install-box" id="heroInstall">
<div class="install-tabs" id="osTabs">
<div class="install-tab" data-os="mac"><span>macOS</span><span class="ind">●</span></div>
<div class="install-tab" data-os="linux"><span>Linux</span><span class="ind">●</span></div>
<div class="install-tab" data-os="win"><span>Windows</span><span class="ind">●</span></div>
<div class="install-tab" data-os="harmony"><span>HarmonyOS</span><span class="ind">●</span></div>
</div>
<div class="install-body">
<pre class="install-cmd" id="osCmd"></pre>
<div class="install-actions">
<div class="left">
<span id="osHint">自动检测 · 已选 macOS</span>
</div>
<button class="cp-btn" id="copyInstall" data-magnetic data-i18n="install.copy">📋 复制命令</button>
</div>
</div>
</div>
<div class="hero-cta">
<a href="#install" class="btn btn-primary" data-i18n="btn.start.arrow">立即开始 →</a>
<a href="#compare" class="btn btn-outline" data-i18n="btn.viewcompare">查看对比</a>
</div>
</div>
<div class="terminal" id="terminal">
<div class="term-head">
<div class="term-dots"><span></span><span></span><span></span></div>
<div class="term-title">atomcode · ~/repo</div>
<div class="term-tag">LIVE DEMO</div>
</div>
<div class="term-chips" id="termChips">
<button class="term-chip active" data-flow="bug" data-i18n="flow.bug">修复登录 bug</button>
<button class="term-chip" data-flow="refactor" data-i18n="flow.refactor">模块重构</button>
<button class="term-chip" data-flow="devserver" data-i18n="flow.devserver">启动 Dev Server</button>
</div>
<div class="term-body" id="termBody"></div>
</div>
</div>
</section>
<section class="stats">
<div class="stats-wrap">
<div class="stat-card"><div class="v"><span data-count="21">0</span></div><div class="l" data-i18n="stats.tools">内置工具</div>
<div class="pop" data-i18n-html="stats.tools.pop"><b>read_file · write_file · edit_file · search_replace · bash · grep · glob · list_dir · cd · web_search · web_fetch · auto_fix · use_skill</b> + 8 个代码图谱工具 = 21 个</div>
</div>
<div class="stat-card"><div class="v"><span data-count="8">0</span></div><div class="l" data-i18n="stats.graph">代码图谱工具</div>
<div class="pop" data-i18n-html="stats.graph.pop"><b>list_symbols · read_symbol · find_references · trace_callers · trace_callees · trace_chain · file_deps · blast_radius</b></div>
</div>
<div class="stat-card"><div class="v"><span data-count="8">0</span><span class="suf">+</span></div><div class="l" data-i18n="stats.providers">支持的模型</div>
<div class="pop" data-i18n-html="stats.providers.pop">Claude (Sonnet 4.5/4.6, Opus 4.6) · OpenAI (GPT-4o/4.1) · DeepSeek (V3/R1) · GLM (4/5) · Qwen (Plus/Max) · SiliconFlow · Ollama · 任意 <b>OpenAI 兼容 API</b></div>
</div>
<div class="stat-card"><div class="v"><span data-count="6">0</span></div><div class="l" data-i18n="stats.platforms">支持平台</div>
<div class="pop" data-i18n-html="stats.platforms.pop">macOS (Apple Silicon · Intel) · Linux (x64 + arm64) · HarmonyOS PC · Windows · 共 6 个二进制变体</div>
</div>
</div>
</section>
<section class="features" id="features">
<div class="section-head">
<h2><span class="mono" data-i18n="sec.cap.tag">// 01 · 能力</span><span data-i18n="sec.cap.title">为开发者而生的能力组合</span></h2>
<div class="hint" data-i18n="sec.cap.hint">为需要 Claude Code 强大能力但想用任意大模型的开发者打造</div>
</div>
<div class="grid-features">
<article class="feat">
<div class="icon">⟳</div>
<h3 data-i18n="feat.agent.t">智能 Agent 循环</h3>
<p data-i18n="feat.agent.d">自主多步执行:读取、编辑、运行、网络检索、自我验证 —— 循环执行直至任务完成。</p>
<div class="demo">
<div class="agent-loop" id="agentLoop">
<span class="node" data-i18n="loop.read">读取</span><span class="arrow">→</span>
<span class="node" data-i18n="loop.edit">编辑</span><span class="arrow">→</span>
<span class="node" data-i18n="loop.run">运行</span><span class="arrow">→</span>
<span class="node" data-i18n="loop.verify">验证</span>
</div>
</div>
</article>
<article class="feat">
<div class="icon">⊕</div>
<h3 data-i18n="feat.prov.t">多模型支持</h3>
<p data-i18n="feat.prov.d">Claude、OpenAI、DeepSeek、GLM、Qwen、Ollama —— 任意 OpenAI 兼容 API 皆可接入,国产大模型一视同仁。</p>
<div class="demo" style="overflow:hidden">
<div class="model-strip">
<span>Claude Sonnet 4.6</span><span>Opus 4.6</span><span>GPT-4o</span><span>GPT-4.1</span><span>DeepSeek V3</span><span>DeepSeek R1</span><span>GLM-5</span><span>Qwen-Max</span><span>SiliconFlow</span><span>Ollama</span>
<span>Claude Sonnet 4.6</span><span>Opus 4.6</span><span>GPT-4o</span><span>GPT-4.1</span><span>DeepSeek V3</span><span>DeepSeek R1</span><span>GLM-5</span><span>Qwen-Max</span><span>SiliconFlow</span><span>Ollama</span>
</div>
</div>
</article>
<article class="feat">
<div class="icon">⌘</div>
<h3 data-i18n="feat.graph.t">代码图谱</h3>
<p data-i18n="feat.graph.d">符号索引、调用链追踪、引用查找、影响面分析 —— 8 个内置工具让模型真正读懂大型代码库。</p>
<div class="demo">
<svg class="graph-mini" viewBox="0 0 240 80">
<g stroke="rgba(232,160,80,.4)" stroke-width="1" fill="none">
<line x1="40" y1="40" x2="100" y2="20" class="ln"/>
<line x1="40" y1="40" x2="100" y2="60" class="ln"/>
<line x1="100" y1="20" x2="160" y2="10" class="ln"/>
<line x1="100" y1="20" x2="160" y2="40" class="ln"/>
<line x1="100" y1="60" x2="160" y2="60" class="ln"/>
<line x1="160" y1="40" x2="200" y2="40" class="ln"/>
</g>
<g fill="#e8a050">
<circle cx="40" cy="40" r="5"/>
<circle cx="100" cy="20" r="4"/>
<circle cx="100" cy="60" r="4"/>
<circle cx="160" cy="10" r="3"/>
<circle cx="160" cy="40" r="3"/>
<circle cx="160" cy="60" r="3"/>
<circle cx="200" cy="40" r="3" opacity=".5"/>
</g>
</svg>
</div>
</article>
<article class="feat">
<div class="icon">▣</div>
<h3 data-i18n="feat.images.t">图片附件与 VL 预处理</h3>
<p data-i18n="feat.images.d">Ctrl+V 粘贴截图、Finder 拖拽、iTerm2 路径自动识别 —— 主模型不支持图片时,自动 VL 预处理 OCR 给主模型。</p>
<div class="demo">
<div class="vis-drop" data-i18n-html="feat.images.demo">📎 <b>Ctrl + V</b> 粘贴截图 · 或拖入图片</div>
</div>
</article>
<article class="feat">
<div class="icon">⎇</div>
<h3 data-i18n="feat.atomgit.t">AtomGit 原生集成</h3>
<p data-i18n="feat.atomgit.d">AtomGit OAuth 一键登录、终端内 /issue 创建 Issue、企业微信扫码登录 —— 与开源生态无缝对接。</p>
<div class="demo">
<div class="gitcmd">
<div class="l1">› /issue create "auth callback 404"</div>
<div class="l2">✓ atomgit.com/.../atomcode/issues/124</div>
</div>
</div>
</article>
<article class="feat">
<div class="icon">⊞</div>
<h3 data-i18n="feat.eco.t">Skills 与 Plugin 生态</h3>
<p data-i18n="feat.eco.d">Skills 写你自己的斜杠命令;/plugin install <git-repo> 一键拿别人的命令、hook、skill —— 与 Claude Code 生态兼容。</p>
<div class="demo">
<div class="plugin-row">
<div class="p"><b>/review</b><span data-i18n="plugin.review">代码审阅</span></div>
<div class="p"><b>/test</b><span data-i18n="plugin.test">跑测试</span></div>
<div class="p"><b>/security</b><span data-i18n="plugin.security">安全审查</span></div>
</div>
</div>
</article>
</div>
</section>
<section class="plugins" id="editor-plugins">
<div class="section-head">
<h2><span class="mono" data-i18n="sec.plug.tag">// 02 · 插件</span><span data-i18n="sec.plug.title">终端之外,在 IDE 里也能用</span></h2>
<div class="hint" data-i18n="sec.plug.hint">VS Code 插件已上架 · 终端级 AI 能力无缝接入编辑器</div>
</div>
<div class="plugin-wrap">
<div class="plugin-grid">
<div class="plugin-features">
<article class="plugin-feat">
<div class="icon">▣</div>
<h3 data-i18n="plug.sidebar.t">侧边栏聊天</h3>
<p data-i18n="plug.sidebar.d">在 Activity Bar 中打开 AtomCode 面板,不离开编辑器即可与 AI 对话</p>
</article>
<article class="plugin-feat">
<div class="icon">☰</div>
<h3 data-i18n="plug.context.t">右键菜单</h3>
<p data-i18n="plug.context.d">选中代码 → 右键 Explain / Fix / Optimize / Add to Chat,全语言支持</p>
</article>
<article class="plugin-feat">
<div class="icon">⇅</div>
<h3 data-i18n="plug.diff.t">Diff 代码预览</h3>
<p data-i18n="plug.diff.d">所有代码变更以 VS Code 原生 diff 视图展示,确认后才写入文件</p>
</article>
<article class="plugin-feat">
<div class="icon">⚙</div>
<h3 data-i18n="plug.model.t">多模型 + Thinking</h3>
<p data-i18n="plug.model.d">Claude / OpenAI / DeepSeek / GLM / Qwen / Ollama,支持 thinking 参数配置</p>
</article>
<article class="plugin-feat">
<div class="icon">💬</div>
<h3 data-i18n="plug.session.t">会话管理</h3>
<p data-i18n="plug.session.d">按时间分组的历史会话,支持搜索、重命名、删除、恢复</p>
</article>
<article class="plugin-feat">
<div class="icon">★</div>
<h3 data-i18n="plug.atomgit.t">AtomGit 集成</h3>
<p data-i18n="plug.atomgit.d">OAuth 一键登录,CodingPlan 免费额度,/login /codingplan 命令</p>
</article>
</div>
<div class="plugin-install">
<div class="pi-head">●●● <span data-i18n="plug.install.head">安装 AtomCode for VS Code</span></div>
<div class="pi-body">
<div class="pi-item">
<div class="pi-label" data-i18n="plug.install.mkt"># 从 Marketplace 安装(推荐)</div>
<a class="pi-url" href="https://marketplace.visualstudio.com/items?itemName=atomcode-tools.atomcode-tools" target="_blank" rel="noopener">marketplace.visualstudio.com/items?itemName=atomcode-tools.atomcode-tools</a>
</div>
<div class="pi-item">
<div class="cp-bar">
<span class="label" data-i18n="plug.install.cmd"># 或通过命令行安装</span>
<button class="cp-btn pi-cp" type="button" data-i18n="install.copy.short">📋 复制</button>
</div>
<pre class="pi-cmd">code --install-extension atomcode-tools.atomcode-tools</pre>
</div>
<div class="pi-item">
<div class="cp-bar">
<span class="label" data-i18n="plug.install.vsix"># 或下载 .vsix 手动安装</span>
</div>
<div class="pi-steps">
<span class="pi-step-num">1</span>
<span data-i18n="plug.install.download">下载 .vsix 文件</span>
<a class="pi-url" href="https://marketplace.visualstudio.com/_apis/public/gallery/publishers/atomcode-tools/vsextensions/atomcode-tools/0.0.8/vspackage" target="_blank" rel="noopener" data-i18n="plug.install.dl-link">点击下载 atomcode-tools-0.0.8.vsix</a>
</div>
<div class="pi-steps">
<span class="pi-step-num">2</span>
<span data-i18n="plug.install.run">运行安装命令</span>
<button class="cp-btn pi-cp" type="button" data-i18n="install.copy.short">📋 复制</button>
<pre class="pi-cmd">code --install-extension atomcode-tools-0.0.8.vsix</pre>
</div>
</div>
</div>
</div>
</div>
<div class="plugin-stats">
<div class="plugin-stat">
<div class="v">10</div>
<div class="l" data-i18n="plug.stat.cmds">内置命令</div>
</div>
<div class="plugin-stat">
<div class="v">8</div>
<div class="l" data-i18n="plug.stat.slash">斜杠命令</div>
</div>
<div class="plugin-stat">
<div class="v">1.85<span class="suf">+</span></div>
<div class="l" data-i18n="plug.stat.vscode">VS Code 版本</div>
</div>
</div>
</div>
</section>
<section class="compare" id="compare">
<div class="section-head">
<h2><span class="mono" data-i18n="sec.cmp.tag">// 03 · 对比</span><span data-i18n="sec.cmp.title">AtomCode 与 Claude Code 对比</span></h2>
<div class="hint" data-i18n="sec.cmp.hint">相同模型基准测试 · 基于真实编程任务测量</div>
</div>
<div class="cmp-wrap">
<div class="perf">
<h3 data-i18n="perf.title">任务性能(相同模型)</h3>
<div class="desc" data-i18n="perf.desc">越短越好 · 完成同一任务平均步骤数</div>
<div class="perf-legend">
<span><span class="sw a"></span>AtomCode</span>
<span><span class="sw c"></span>Claude Code</span>
</div>
<div id="perfList"></div>
</div>
<div class="cmp-controls">
<div class="cmp-chips" id="cmpChips">
<button class="cmp-chip active" data-cat="all" data-i18n="cmp.all">全部</button>
<button class="cmp-chip" data-cat="price" data-i18n="cmp.price">价格</button>
<button class="cmp-chip" data-cat="license" data-i18n="cmp.license">协议</button>
<button class="cmp-chip" data-cat="model" data-i18n="cmp.model">模型</button>
<button class="cmp-chip" data-cat="tools" data-i18n="cmp.tools">工具</button>
<button class="cmp-chip" data-cat="integration" data-i18n="cmp.integration">集成</button>
</div>
<div class="cmp-toggle" id="diffToggle">
<div class="sw"></div>
<span data-i18n="cmp.diffonly">只看差异</span>
</div>
</div>
<div class="ftab-wrap">
<table class="ftab" id="ftab">
<thead>
<tr>
<th style="width:42%" data-i18n="ftab.feature">功能</th>
<th class="atom" style="width:29%">AtomCode</th>
<th class="claude" style="width:29%">Claude Code</th>
</tr>
</thead>
<tbody id="ftabBody"></tbody>
</table>
</div>
<div class="gap-note" data-i18n-html="gap.body">
<b>关于"复杂任务多 30% 步骤"</b><br>
AtomCode 更倾向"小步快跑 + 自我验证":每个动作可单独 <b>/undo</b>,对话上下文更细更易干预;Claude Code 在复杂场景偏好"大刀阔斧"一步到位。
—— 两种工程哲学,并非孰优孰劣。需要稳健与可干预,选 AtomCode;需要速度与一气呵成,选 Claude Code。
</div>
</div>
</section>
<section class="install" id="install">
<div class="section-head">
<h2><span class="mono" data-i18n="sec.inst.tag">// 04 · 安装</span><span data-i18n="sec.inst.title">30 秒快速开始</span></h2>
<div class="hint" data-i18n="sec.inst.hint">一条命令完成安装 · 就这么简单</div>
</div>
<div class="install-wrap">
<div class="install-grid">
<div>
<div class="install-block">
<div class="install-tabs">
<div class="install-tab active" data-method="oneclick"><span data-i18n="inst.oneclick">一键脚本</span></div>
<div class="install-tab" data-method="source"><span data-i18n="inst.source">从源码构建</span></div>
<div class="install-tab" data-method="binary"><span data-i18n="inst.binary">下载二进制</span></div>
</div>
<div class="install-body">
<div class="install-cmd-list" id="methodCmd"></div>
<div class="install-actions">
<div class="left">
<span id="methodHint">macOS / Linux / HarmonyOS PC</span>
</div>
</div>
</div>
</div>
<div class="download-row" id="downloadRow"></div>
</div>
<div>
<div class="stepper" id="stepper">
<div class="step">
<div class="ch">›</div>
<div class="n">01</div>
<div class="t" data-i18n="step1.t">运行命令</div>
<div class="d" data-i18n="step1.d">脚本自动下载并安装到 /usr/local/bin</div>
</div>
<div class="step">
<div class="ch">›</div>
<div class="n">02</div>
<div class="t" data-i18n="step2.t">配置 API Key</div>
<div class="d" data-i18n="step2.d">OpenAI / Claude / CodingPlan 任一即可</div>
</div>
<div class="step">
<div class="n">03</div>
<div class="t" data-i18n="step3.t">cd 进项目跑 atomcode</div>
<div class="d" data-i18n="step3.d">第一次会进 3 步启动向导</div>
</div>
</div>
<div class="wiz" id="wiz">
<div class="wiz-head">
<span>●●●</span> <span data-i18n="wiz.head">atomcode · 首次运行 — 3 步启动向导</span>
</div>
<div class="wiz-body">
<div class="wiz-step active" data-step="1">
<div class="tt" data-i18n="wiz.s1.tt">第 1/3 步 · 欢迎</div>
<div class="qq" data-i18n="wiz.s1.qq">版本 v4.24.2 · 在终端里运行的 AI 编程代理</div>
<ul class="intro-list">
<li data-i18n="wiz.s1.b1">多步骤 agent loop · 内置代码图工具</li>
<li data-i18n="wiz.s1.b2">兼容所有 OpenAI 风格 API</li>
<li data-i18n="wiz.s1.b3">通过 CodingPlan 获取免费额度</li>
</ul>
<div class="intro-hint" data-i18n="wiz.s1.hint">按 Enter 继续 · Ctrl+C 可随时退出</div>
</div>
<div class="wiz-step" data-step="2">
<div class="tt" data-i18n="wiz.s2.tt">第 2/3 步 · 语言</div>
<div class="qq" data-i18n="wiz.s2.qq">Choose your language / 选择语言</div>
<div class="intro-hint inline" data-i18n="wiz.s2.prompt">选择界面语言。任何时候都可以用 /language 修改。</div>
<div class="opt"><span data-i18n="wiz.s2.o1">自动检测 (LC_ALL / LANG)</span> <small>1</small></div>
<div class="opt sel"><span data-i18n="wiz.s2.o2">简体中文 (Simplified Chinese)</span> <small>2</small></div>
<div class="opt"><span data-i18n="wiz.s2.o3">English</span> <small>3</small></div>
</div>
<div class="wiz-step" data-step="3">
<div class="tt" data-i18n="wiz.s3.tt">第 3/3 步 · 配置</div>
<div class="qq" data-i18n="wiz.s3.qq">想怎么开始?</div>
<div class="opt sel"><span data-i18n="wiz.s3.o1">配置 CodingPlan</span> <small data-i18n="wiz.s3.o1.hint">免费额度 · 推荐</small></div>
<div class="opt"><span data-i18n="wiz.s3.o2">手动配置</span> <small data-i18n="wiz.s3.o2.hint">使用 API key</small></div>
<div class="opt"><span data-i18n="wiz.s3.o3">暂时跳过</span> <small data-i18n="wiz.s3.o3.hint">稍后再说</small></div>
</div>
<div class="wiz-nav-hint" data-i18n="wiz.nav">1-3 选择 · Enter 确认 · ← 返回 · Esc 跳过</div>
<div class="wiz-nav">
<button id="wizPrev" data-i18n="wiz.prev">← 上一步</button>
<div class="wiz-dots" id="wizDots"><span class="on"></span><span></span><span></span></div>
<button id="wizNext" data-i18n="wiz.next">下一步 →</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<footer class="ftr">
<div class="ftr-row" data-i18n-html="ftr.links">
<a href="#top">官网</a> · <a href="./docs/index.html" target="_blank" rel="noopener">文档</a> · <a href="https://ai.atomgit.com/serverless-api" target="_blank" rel="noopener">CodingPlan</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode" target="_blank" rel="noopener">开源仓库</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode/issues" target="_blank" rel="noopener">Issue</a>
</div>
<div data-i18n="ftr.copy">© 2026 AtomCode · MIT 许可证</div>
<div class="ftr-tag" data-i18n="ftr.rust">⚙ 用 Rust 构建</div>
</footer>
<div class="toast" id="toast">✓ 已复制</div>
<script>
var LANG='zh';
try{
const s=localStorage.getItem('atomcode_lang');
if(s==='zh'||s==='en') LANG=s;
else LANG=(navigator.language||'').toLowerCase().startsWith('zh')?'zh':'en';
}catch(e){}
const VERSION='v4.24.2';
const T={
'nav.features':{zh:'功能',en:'Features'},
'nav.compare':{zh:'对比',en:'Compare'},
'nav.install':{zh:'安装',en:'Install'},
'nav.docs':{zh:'文档',en:'Docs'},
'nav.marketplace':{zh:'Skills',en:'Skills'},
'nav.plugins':{zh:'IDE插件',en:'IDE Plugins'},
'nav.codingplan':{zh:'Coding Plan',en:'Coding Plan'},
'btn.repo':{zh:'开源仓库',en:'Repository'},
'btn.start':{zh:'立即开始',en:'Get Started'},
'btn.start.arrow':{zh:'立即开始 →',en:'Get Started →'},
'btn.viewcompare':{zh:'查看对比',en:'View Comparison'},
'hero.badge':{zh:'开源 · 多模型 · 100% AI 生成 · Rust 1.88+',en:'Open Source · Multi-Provider · 100% AI-generated · Rust 1.88+'},
'hero.t1':{zh:'AI 编程助手',en:'AI Coding Agent'},
'hero.t2':{zh:'在你的终端中运行',en:'in Your Terminal'},
'hero.sub':{zh:'Claude Code / Cursor Agent 的<b>开源平替</b>,住在你的终端里。连接任意 OpenAI 兼容大模型,自主读文件、改代码、跑测试、自我验证 —— 用 Rust 构建。本项目<b>100% 由 AI 生成</b>。',
en:"<b>Open-source alternative</b> to Claude Code / Cursor Agent, living in your terminal. Connect any OpenAI-compatible LLM, autonomously read, edit, test, self-verify — built with Rust. <b>100% AI-generated codebase.</b>"},
'install.copy':{zh:'📋 复制命令',en:'📋 Copy command'},
'install.copy.short':{zh:'📋 复制',en:'📋 Copy'},
'flow.bug':{zh:'修复登录 bug',en:'Fix login bug'},
'flow.refactor':{zh:'模块重构',en:'Module refactor'},
'flow.devserver':{zh:'启动 Dev Server',en:'Start dev server'},
'loop.read':{zh:'读取',en:'Read'},
'loop.edit':{zh:'编辑',en:'Edit'},
'loop.run':{zh:'运行',en:'Run'},
'loop.verify':{zh:'验证',en:'Verify'},
'stats.tools':{zh:'内置工具',en:'Built-in Tools'},
'stats.graph':{zh:'代码图谱工具',en:'Code Graph Tools'},
'stats.providers':{zh:'支持的模型',en:'LLM Providers'},
'stats.platforms':{zh:'支持平台',en:'Platforms'},
'stats.tools.pop':{zh:'<b>read_file · write_file · edit_file · search_replace · bash · grep · glob · list_dir · cd · web_search · web_fetch · auto_fix · use_skill</b> + 8 个代码图谱工具 = 21 个',
en:'<b>read_file · write_file · edit_file · search_replace · bash · grep · glob · list_dir · cd · web_search · web_fetch · auto_fix · use_skill</b> + 8 code graph tools = 21 total'},
'stats.graph.pop':{zh:'<b>list_symbols · read_symbol · find_references · trace_callers · trace_callees · trace_chain · file_deps · blast_radius</b>',
en:'<b>list_symbols · read_symbol · find_references · trace_callers · trace_callees · trace_chain · file_deps · blast_radius</b>'},
'stats.providers.pop':{zh:'Claude (Sonnet 4.5/4.6, Opus 4.6) · OpenAI (GPT-4o/4.1) · DeepSeek (V3/R1) · GLM (4/5) · Qwen (Plus/Max) · SiliconFlow · Ollama · 任意 <b>OpenAI 兼容 API</b>',
en:'Claude (Sonnet 4.5/4.6, Opus 4.6) · OpenAI (GPT-4o/4.1) · DeepSeek (V3/R1) · GLM (4/5) · Qwen (Plus/Max) · SiliconFlow · Ollama · any <b>OpenAI-compatible API</b>'},
'stats.platforms.pop':{zh:'macOS (Apple Silicon · Intel) · Linux (x64 + arm64) · HarmonyOS PC · Windows · 共 6 个二进制变体',
en:'macOS (Apple Silicon · Intel) · Linux (x64 + arm64) · HarmonyOS PC · Windows · 6 binary variants total'},
'sec.cap.tag':{zh:'// 01 · 能力',en:'// 01 · Capabilities'},
'sec.cap.title':{zh:'为开发者而生的能力组合',en:'Capabilities built for developers'},
'sec.cap.hint':{zh:'为需要 Claude Code 强大能力但想用任意大模型的开发者打造',en:'For developers who want Claude Code-level capability with any LLM'},
'sec.plug.tag':{zh:'// 02 · 插件',en:'// 02 · Plugins'},
'sec.plug.title':{zh:'终端之外,在 IDE 里也能用',en:'Beyond the terminal, inside your IDE'},
'sec.plug.hint':{zh:'VS Code 插件已上架 · 终端级 AI 能力无缝接入编辑器',en:'VS Code extension available · terminal-grade AI inside your editor'},
'sec.cmp.tag':{zh:'// 03 · 对比',en:'// 03 · Compare'},
'sec.cmp.title':{zh:'AtomCode 与 Claude Code 对比',en:'AtomCode vs Claude Code'},
'sec.cmp.hint':{zh:'相同模型基准测试 · 基于真实编程任务测量',en:'Same-model benchmarks · measured on real coding tasks'},
'sec.inst.tag':{zh:'// 04 · 安装',en:'// 04 · Install'},
'sec.inst.title':{zh:'30 秒快速开始',en:'30-second quickstart'},
'sec.inst.hint':{zh:'一条命令完成安装 · 就这么简单',en:'One command. That simple.'},
'feat.agent.t':{zh:'智能 Agent 循环',en:'Smart Agent Loop'},
'feat.agent.d':{zh:'自主多步执行:读取、编辑、运行、网络检索、自我验证 —— 循环执行直至任务完成。',
en:'Autonomous multi-step execution: read, edit, run, web fetch, self-verify — loops until done.'},
'feat.prov.t':{zh:'多模型支持',en:'Multi-Provider Support'},
'feat.prov.d':{zh:'Claude、OpenAI、DeepSeek、GLM、Qwen、Ollama —— 任意 OpenAI 兼容 API 皆可接入,国产大模型一视同仁。',
en:'Claude, OpenAI, DeepSeek, GLM, Qwen, Ollama — any OpenAI-compatible API. Chinese LLMs first-class.'},
'feat.graph.t':{zh:'代码图谱',en:'Code Graph'},
'feat.graph.d':{zh:'符号索引、调用链追踪、引用查找、影响面分析 —— 8 个内置工具让模型真正读懂大型代码库。',
en:'Symbol index, call-graph, ref-find, impact analysis — 8 built-in tools so the model really understands large codebases.'},
'feat.images.t':{zh:'图片附件与 VL 预处理',en:'Image Attachment & VL Preprocess'},
'feat.images.d':{zh:'Ctrl+V 粘贴截图、Finder 拖拽、iTerm2 路径自动识别 —— 主模型不支持图片时,自动 VL 预处理 OCR 给主模型。',
en:'Ctrl+V paste, Finder drag, iTerm2 path auto-detect — when the main model lacks vision, falls back to VL preprocessor (OCR + describe).'},
'feat.images.demo':{zh:'📎 <b>Ctrl + V</b> 粘贴截图 · 或拖入图片',en:'📎 <b>Ctrl + V</b> paste screenshot · or drop an image'},
'feat.atomgit.t':{zh:'AtomGit 原生集成',en:'AtomGit Native Integration'},
'feat.atomgit.d':{zh:'AtomGit OAuth 一键登录、终端内 /issue 创建 Issue、企业微信扫码登录 —— 与开源生态无缝对接。',
en:'AtomGit OAuth login, terminal /issue, WeCom QR login — seamless with the open-source ecosystem.'},
'feat.eco.t':{zh:'Skills + Plugin 生态',en:'Skills + Plugin Ecosystem'},
'feat.eco.d':{zh:'Skills 写你自己的斜杠命令;/plugin install <git-repo> 一键拿别人的命令、hook、skill —— 与 Claude Code 生态兼容。',
en:'Write your own slash commands as Skills; /plugin install <git-repo> grabs packs of commands, hooks, skills — Claude Code ecosystem compatible.'},
'plug.sidebar.t':{zh:'侧边栏聊天',en:'Sidebar Chat'},
'plug.sidebar.d':{zh:'在 Activity Bar 中打开 AtomCode 面板,不离开编辑器即可与 AI 对话',en:'Open AtomCode in the Activity Bar and chat with AI without leaving the editor'},
'plug.context.t':{zh:'右键菜单',en:'Context Menu'},
'plug.context.d':{zh:'选中代码 → 右键 Explain / Fix / Optimize / Add to Chat,全语言支持',en:'Select code → right-click Explain / Fix / Optimize / Add to Chat, all languages'},
'plug.diff.t':{zh:'Diff 代码预览',en:'Diff Preview'},
'plug.diff.d':{zh:'所有代码变更以 VS Code 原生 diff 视图展示,确认后才写入文件',en:'All code changes shown as VS Code native diffs, written only after approval'},
'plug.model.t':{zh:'多模型 + Thinking',en:'Multi-Model + Thinking'},
'plug.model.d':{zh:'Claude / OpenAI / DeepSeek / GLM / Qwen / Ollama,支持 thinking 参数配置',en:'Claude / OpenAI / DeepSeek / GLM / Qwen / Ollama, with thinking parameter support'},
'plug.session.t':{zh:'会话管理',en:'Session Management'},
'plug.session.d':{zh:'按时间分组的历史会话,支持搜索、重命名、删除、恢复',en:'Time-grouped session history with search, rename, delete, and restore'},
'plug.atomgit.t':{zh:'AtomGit 集成',en:'AtomGit Integration'},
'plug.atomgit.d':{zh:'OAuth 一键登录,CodingPlan 免费额度,/login /codingplan 命令',en:'OAuth one-click login, CodingPlan free tier, /login /codingplan commands'},
'plug.install.head':{zh:'安装 AtomCode for VS Code',en:'Install AtomCode for VS Code'},
'plug.install.mkt':{zh:'# 从 Marketplace 安装(推荐)',en:'# Install from Marketplace (recommended)'},
'plug.install.cmd':{zh:'# 或通过命令行安装',en:'# Or install via command line'},
'plug.install.vsix':{zh:'# 或下载 .vsix 手动安装',en:'# Or download .vsix to install manually'},
'plug.install.download':{zh:'下载 .vsix 文件',en:'Download .vsix file'},
'plug.install.dl-link':{zh:'点击下载 atomcode-tools-0.0.8.vsix',en:'Download atomcode-tools-0.0.8.vsix'},
'plug.install.run':{zh:'运行安装命令',en:'Run install command'},
'plug.stat.cmds':{zh:'内置命令',en:'Built-in Commands'},
'plug.stat.slash':{zh:'斜杠命令',en:'Slash Commands'},
'plug.stat.vscode':{zh:'VS Code 版本',en:'VS Code Version'},
'plugin.review':{zh:'代码审阅',en:'Code review'},
'plugin.test':{zh:'跑测试',en:'Run tests'},
'plugin.security':{zh:'安全审查',en:'Security audit'},
'perf.title':{zh:'任务性能(相同模型)',en:'Task Performance (Same Model)'},
'perf.desc':{zh:'越短越好 · 完成同一任务平均步骤数',en:'Lower is better · avg steps to complete a task'},
'cmp.all':{zh:'全部',en:'All'},
'cmp.price':{zh:'价格',en:'Price'},
'cmp.license':{zh:'协议',en:'License'},
'cmp.model':{zh:'模型',en:'Model'},
'cmp.tools':{zh:'工具',en:'Tools'},
'cmp.integration':{zh:'集成',en:'Integration'},
'cmp.diffonly':{zh:'只看差异',en:'Diff only'},
'ftab.feature':{zh:'功能',en:'Feature'},
'gap.body':{zh:'<b>关于"复杂任务多 30% 步骤"</b><br>AtomCode 更倾向"小步快跑 + 自我验证":每个动作可单独 <b>/undo</b>,对话上下文更细更易干预;Claude Code 在复杂场景偏好"大刀阔斧"一步到位。 —— 两种工程哲学,并非孰优孰劣。需要稳健与可干预,选 AtomCode;需要速度与一气呵成,选 Claude Code。',
en:'<b>About the "30% more steps on complex tasks"</b><br>AtomCode favors "small steps + self-verify": each action is independently <b>/undo</b>-able and context is fine-grained, easy to steer mid-flight. Claude Code prefers "one bold sweep" on complex jobs. — Two engineering philosophies, neither inherently better. Want safety and intervention? AtomCode. Want speed and one-shot? Claude Code.'},
'inst.oneclick':{zh:'一键脚本',en:'One-click script'},
'inst.source':{zh:'从源码构建',en:'From source'},
'inst.binary':{zh:'下载二进制',en:'Binary download'},
'step1.t':{zh:'运行命令',en:'Run command'},
'step1.d':{zh:'脚本自动下载到 /usr/local/bin 或 ~/.local/bin',en:'Script installs to /usr/local/bin or ~/.local/bin'},
'step2.t':{zh:'配置 provider',en:'Configure provider'},
'step2.d':{zh:'Claude / OpenAI / DeepSeek / GLM / Qwen / Ollama 任一 · 或 /login 走 AtomGit OAuth',en:'Pick any provider · Claude / OpenAI / DeepSeek / GLM / Qwen / Ollama · or /login via AtomGit OAuth'},
'step3.t':{zh:'cd 进项目跑 atomcode',en:'cd into project, run atomcode'},
'step3.d':{zh:'第一次会进 3 步启动向导 · 配置存 ~/.atomcode/config.toml',en:'First run launches a 3-step wizard · config at ~/.atomcode/config.toml'},
'wiz.head':{zh:'atomcode · 首次运行 — 3 步启动向导',en:'atomcode · First run — 3-step wizard'},
'wiz.s1.tt':{zh:'第 1/3 步 · 欢迎',en:'Step 1/3 · Welcome'},
'wiz.s1.qq':{zh:`版本 ${VERSION} · 在终端里运行的 AI 编程代理`,en:`Version ${VERSION} · AI coding agent in your terminal`},
'wiz.s1.b1':{zh:'多步骤 agent loop · 内置代码图工具',en:'Multi-step agent loop · built-in code-graph tools'},
'wiz.s1.b2':{zh:'兼容所有 OpenAI 风格 API',en:'Connects to any OpenAI-compatible API'},
'wiz.s1.b3':{zh:'通过 CodingPlan 获取免费额度',en:'Free tokens via CodingPlan'},
'wiz.s1.hint':{zh:'按 Enter 继续 · Ctrl+C 可随时退出',en:'Press Enter to continue · Ctrl+C exits at any point'},
'wiz.s2.tt':{zh:'第 2/3 步 · 语言',en:'Step 2/3 · Language'},
'wiz.s2.qq':{zh:'Choose your language / 选择语言',en:'Choose your language / 选择语言'},
'wiz.s2.prompt':{zh:'选择界面语言。任何时候都可以用 /language 修改。',en:'Pick the UI language. You can change it any time with /language.'},
'wiz.s2.o1':{zh:'自动检测 (LC_ALL / LANG)',en:'Auto-detect (LC_ALL / LANG)'},
'wiz.s2.o2':{zh:'简体中文 (Simplified Chinese)',en:'简体中文 (Simplified Chinese)'},
'wiz.s2.o3':{zh:'English',en:'English'},
'wiz.s3.tt':{zh:'第 3/3 步 · 配置',en:'Step 3/3 · Setup'},
'wiz.s3.qq':{zh:'想怎么开始?',en:'How would you like to set up?'},
'wiz.s3.o1':{zh:'配置 CodingPlan',en:'Set up CodingPlan'},
'wiz.s3.o1.hint':{zh:'免费额度 · 推荐',en:'Free tokens · recommended'},
'wiz.s3.o2':{zh:'手动配置',en:'Configure manually'},
'wiz.s3.o2.hint':{zh:'使用 API key',en:'API key'},
'wiz.s3.o3':{zh:'暂时跳过',en:'Skip for now'},
'wiz.s3.o3.hint':{zh:'稍后再说',en:'explore first'},
'wiz.nav':{zh:'1-3 选择 · Enter 确认 · ← 返回 · Esc 跳过',en:'1-3 select · Enter confirm · ← back · Esc skip'},
'wiz.prev':{zh:'← 上一步',en:'← Back'},
'wiz.next':{zh:'下一步 →',en:'Next →'},
'wiz.done':{zh:'✓ 完成',en:'✓ Done'},
'ftr.links':{zh:'<a href="#top">官网</a> · <a href="./docs/index.html" target="_blank" rel="noopener">文档</a> · <a href="https://ai.atomgit.com/serverless-api" target="_blank" rel="noopener">CodingPlan</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode" target="_blank" rel="noopener">开源仓库</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode/issues" target="_blank" rel="noopener">Issue</a>',
en:'<a href="#top">Website</a> · <a href="./docs/index.html" target="_blank" rel="noopener">Docs</a> · <a href="https://ai.atomgit.com/serverless-api" target="_blank" rel="noopener">CodingPlan</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode" target="_blank" rel="noopener">Repository</a> · <a href="https://atomgit.com/atomgit_atomcode/atomcode/issues" target="_blank" rel="noopener">Issues</a>'},
'ftr.copy':{zh:'© 2026 AtomCode · MIT 许可证',en:'© 2026 AtomCode · MIT License'},
'ftr.rust':{zh:'⚙ 用 Rust 构建',en:'⚙ Built with Rust'},
'toast.install.copied':{zh:'✓ 安装命令已复制 · 粘贴到终端运行',en:'✓ Install command copied · paste into your terminal'},
'toast.copied':{zh:'✓ 已复制 · 粘贴到终端运行',en:'✓ Copied · paste into your terminal'},
'toast.theme.light':{zh:'☀ 已切换到 Light',en:'☀ Switched to Light'},
'toast.theme.dark':{zh:'☾ 已切换到 Dark',en:'☾ Switched to Dark'},
'toast.lang.zh':{zh:'已切换到 简体中文',en:'Switched to 简体中文'},
'toast.lang.en':{zh:'已切换到 English',en:'Switched to English'},
'meta.title':{zh:'AtomCode · 在你的终端中运行的 AI 编程助手',en:'AtomCode · AI Coding Agent in Your Terminal'},
'meta.desc':{zh:'AtomCode — Claude Code 的开源平替。连接任意大模型,自主多步执行,30 秒上手。',en:'AtomCode — open-source alternative to Claude Code. Connect any LLM, autonomous multi-step execution, 30-second setup.'},
'aria.theme':{zh:'切换主题',en:'Toggle theme'},
'aria.lang':{zh:'切换语言',en:'Toggle language'},
'tip.ver':{zh:'当前版本',en:'Current version'},
'os.mac':{zh:'macOS · Intel / Apple Silicon',en:'macOS · Intel / Apple Silicon'},
'os.linux':{zh:'Linux · x86_64 / arm64',en:'Linux · x86_64 / arm64'},
'os.win':{zh:'Windows · PowerShell',en:'Windows · PowerShell'},
'os.harmony':{zh:'HarmonyOS PC · arm64',en:'HarmonyOS PC · arm64'},
'os.auto':{zh:'✓ 自动检测 · ',en:'✓ Auto-detected · '},
'method.oneclick':{zh:'macOS / Linux / HarmonyOS PC + Windows · 自动选 PATH',en:'macOS / Linux / HarmonyOS PC + Windows · auto PATH'},
'method.source':{zh:'需要 Rust 1.88+ · cargo install 到 ~/.cargo/bin/atomcode',en:'Rust 1.88+ required · cargo install to ~/.cargo/bin/atomcode'},
'method.binary':{zh:'6 个平台 · 预编译 · 单文件运行',en:'6 platforms · prebuilt · single-file run'},
};
function t(k){const v=T[k];if(!v)return k;return v[LANG]||v.zh||k;}
function tx(x){if(typeof x==='string')return x;if(x&&typeof x==='object'&&x[LANG]!==undefined)return x[LANG];return String(x);}
function applyI18n(){
document.documentElement.lang=LANG==='zh'?'zh-CN':'en';
document.title=t('meta.title');
const md=document.querySelector('meta[name="description"]'); if(md) md.setAttribute('content',t('meta.desc'));
const vb=document.getElementById('verBadge'); if(vb) vb.title=t('tip.ver');
const tb=document.getElementById('themeBtn'); if(tb) tb.setAttribute('aria-label',t('aria.theme'));
const lb=document.getElementById('langBtn'); if(lb) lb.setAttribute('aria-label',t('aria.lang'));
document.querySelectorAll('[data-i18n]').forEach(el=>{el.textContent=t(el.dataset.i18n);});
document.querySelectorAll('[data-i18n-html]').forEach(el=>{el.innerHTML=t(el.dataset.i18nHtml);});
}
const RELEASE_BASE='https://atomgit.com/atomgit_atomcode/atomcode/releases/download/'+VERSION;
const SCRIPT_BASE='https://raw.atomgit.com/atomgit_atomcode/atomcode/raw/main/scripts';
const INVITE_PARAM=new URLSearchParams(window.location.search).get('invite')||'';
const INVITE_CODE=/^[A-Za-z0-9]{8}$/.test(INVITE_PARAM)?INVITE_PARAM:'';
function unixInstallCmd(){
return `curl -fsSL ${SCRIPT_BASE}/install.sh | sh${INVITE_CODE?` -s -- --invite=${INVITE_CODE}`:''}`;
}
function winInstallCmd(){
return INVITE_CODE
? `$env:ATOMCODE_INVITE='${INVITE_CODE}'; irm ${SCRIPT_BASE}/install.ps1 | iex`
: `irm ${SCRIPT_BASE}/install.ps1 | iex`;
}
const OS_CMDS={
mac:unixInstallCmd(),
linux:unixInstallCmd(),
win:winInstallCmd(),
harmony:unixInstallCmd(),
};
function osHint(os){return t('os.'+os);}
const METHOD_CMDS={
oneclick:{zh:`# macOS / Linux / HarmonyOS PC\n${unixInstallCmd()}\n\n# Windows · PowerShell\n${winInstallCmd()}`,
en:`# macOS / Linux / HarmonyOS PC\n${unixInstallCmd()}\n\n# Windows · PowerShell\n${winInstallCmd()}`},
source:{zh:`# 需要 Rust 1.88+\ngit clone https://atomgit.com/atomgit_atomcode/atomcode.git\ncd atomcode\ncargo build --release\ncp target/release/atomcode ~/.local/bin/\natomcode --version # 验证安装`,
en:`# Requires Rust 1.88+\ngit clone https://atomgit.com/atomgit_atomcode/atomcode.git\ncd atomcode\ncargo build --release\ncp target/release/atomcode ~/.local/bin/\natomcode --version # verify install`},
binary:{zh:`# 从 Releases 页面下载\nhttps://atomgit.com/atomgit_atomcode/atomcode/releases/latest\n\n# 或直接 curl 取对应平台\ncurl -L -o atomcode \\\n ${RELEASE_BASE}/atomcode-${VERSION}-darwin-arm64\nchmod +x atomcode && mv atomcode /usr/local/bin/`,
en:`# Download from Releases page\nhttps://atomgit.com/atomgit_atomcode/atomcode/releases/latest\n\n# Or curl for your platform\ncurl -L -o atomcode \\\n ${RELEASE_BASE}/atomcode-${VERSION}-darwin-arm64\nchmod +x atomcode && mv atomcode /usr/local/bin/`},
};
function methodHint(m){return t('method.'+m);}
const DOWNLOADS=[
{os:'macOS · Apple Silicon',arch:'darwin-arm64',file:`atomcode-${VERSION}-darwin-arm64`},
{os:'macOS · Intel',arch:'darwin-x64',file:`atomcode-${VERSION}-darwin-x64`},
{os:'Linux x64',arch:'linux-x64',file:`atomcode-${VERSION}-linux-x64`},
{os:'Linux arm64',arch:'linux-arm64',file:`atomcode-${VERSION}-linux-arm64`},
{os:'HarmonyOS PC',arch:'ohos-arm64',file:`atomcode-${VERSION}-ohos-arm64`},
{os:'Windows',arch:'windows-x64',file:`atomcode-${VERSION}-windows-x64.exe`},
];
const FLOWS={
bug:[
[80,'user',{zh:'修复登录后 404 的 bug',en:'Fix the login bug where users get 404 after OAuth'}],
[500,'thinking',{zh:'我来检查 OAuth 回调处理器。',en:"I'll investigate the OAuth callback handler."}],
[700,'tool',{zh:'read_file src/auth/callback.ts',en:'read_file src/auth/callback.ts'}],
[900,'output','export async function callback(req) {\n const code = req.query.code;\n return redirect(`/dashboard`);\n}'],
[600,'tool',{zh:'find_references baseUrl (3 处)',en:'find_references baseUrl (3 hits)'}],
[600,'tool',{zh:'edit_file src/auth/callback.ts',en:'edit_file src/auth/callback.ts'}],
[400,'diff-add','+ const base = process.env.BASE_URL ?? "";'],
[120,'diff-add','+ return redirect(`${base}/dashboard`);'],
[120,'diff-del','- return redirect(`/dashboard`);'],
[500,'output',{zh:'已编辑 src/auth/callback.ts (+2 -1) · file_history 已快照',en:'Edited src/auth/callback.ts (+2 -1) · file_history snapshot saved'}],
[600,'tool','auto_fix · cargo build'],
[900,'success',{zh:'构建成功 · 0 warnings',en:'Build succeeded · 0 warnings'}],
[500,'tool',{zh:'bash · cargo test auth::callback',en:'bash · cargo test auth::callback'}],
[800,'success',{zh:'3 passed · 0 failed',en:'3 passed · 0 failed'}],
[400,'assistant',{zh:'已修复。重定向 URL 缺少基础路径。/undo 可回滚本轮编辑,/diff 查看变更。',en:'Fixed. The redirect URL was missing the base path. /undo to roll back this turn, /diff to view the change.'}],
],
refactor:[
[80,'user',{zh:'把 src/services/user.ts 按职责拆分',en:'Split src/services/user.ts by responsibility'}],
[400,'thinking',{zh:'我先用代码图谱看 user.ts 的依赖关系。',en:'Let me inspect user.ts dependencies via the code graph.'}],
[600,'tool','list_symbols src/services/user.ts'],
[600,'output',{zh:'UserService · 14 methods · 3 关注点',en:'UserService · 14 methods · 3 concerns'}],
[500,'tool','trace_callers UserService.* · blast_radius'],
[800,'output','authentication ← 4 methods\nprofile ← 5 methods\nbilling ← 5 methods'],
[400,'tool',{zh:'write_file src/services/user/auth.ts',en:'write_file src/services/user/auth.ts'}],
[200,'tool',{zh:'write_file src/services/user/profile.ts',en:'write_file src/services/user/profile.ts'}],
[200,'tool',{zh:'write_file src/services/user/billing.ts',en:'write_file src/services/user/billing.ts'}],
[400,'tool',{zh:'search_replace · 迁移 8 处引用',en:'search_replace · migrate 8 references'}],
[700,'success',{zh:'重构完成 · 14 methods 拆为 3 模块',en:'Refactor done · 14 methods split into 3 modules'}],
[400,'tool','auto_fix · cargo build · cargo test'],
[600,'success',{zh:'build ok · 47 passed',en:'build ok · 47 passed'}],
[400,'assistant',{zh:'已按 auth / profile / billing 拆分。/undo 通过 git stash checkpoint 一键回滚本轮。',en:'Split into auth / profile / billing. /undo restores via git stash checkpoint.'}],
],
devserver:[
[80,'user',{zh:'启动 dev server',en:'Start the dev server'}],
[400,'thinking',{zh:'我先看 package.json 找启动脚本。',en:"Let me check package.json for the start script."}],
[500,'tool',{zh:'read_file package.json',en:'read_file package.json'}],
[600,'output','{ "scripts": { "dev": "vite", "build": "vite build" } }'],
[400,'tool',{zh:'bash · 检查端口 3000',en:'bash · check port 3000'}],
[400,'output',{zh:'端口 3000 空闲',en:'Port 3000 is free'}],
[500,'tool',{zh:'bash · npm run dev(自动 nohup 包装)',en:'bash · npm run dev (auto-nohup wrap)'}],
[1200,'output','VITE v5.4.0 ready in 312 ms'],
[100,'output',' ➜ Local: http://localhost:3000/'],
[100,'output',' ➜ Network: http://192.168.1.5:3000/'],
[400,'success',{zh:'Dev server 已就绪 · devserver 自动检测器已识别',en:'Dev server ready · auto-detected by devserver module'}],
[400,'assistant',{zh:'已启动 vite。访问 http://localhost:3000/ 即可。',en:'Vite started. Visit http://localhost:3000/.'}],
],
};
const PERF=[
{task:{zh:'简单编辑(样式修改)',en:'Simple edit (style change)'},a:3,c:3,s:{zh:'持平',en:'Same'},k:'eq'},
{task:{zh:'模块重构',en:'Module refactor'},a:7,c:6,s:{zh:'接近',en:'Close'},k:'near'},
{task:{zh:'启动开发服务器',en:'Dev server launch'},a:4,c:4,s:{zh:'持平',en:'Same'},k:'eq'},
{task:{zh:'Bug 修复',en:'Bug fix'},a:5,c:5,s:{zh:'持平',en:'Same'},k:'eq'},
{task:{zh:'复杂任务(新库+调试)',en:'Complex (new lib + debug)'},a:13,c:10,s:{zh:'差距 ~30%',en:'~30% gap'},k:'gap'},
];
const FEAT=[
{cat:'license', catL:{zh:'协议',en:'License'}, f:{zh:'开源协议',en:'License'}, a:{zh:'✓ MIT 开源',en:'✓ MIT'}, c:{zh:'闭源',en:'Closed source'}, win:'a'},
{cat:'model', catL:{zh:'模型',en:'Model'}, f:{zh:'模型接入',en:'Provider access'}, a:{zh:'✓ 任意 OpenAI 兼容',en:'✓ Any OpenAI-compatible'}, c:{zh:'仅 Claude',en:'Claude only'}, win:'a'},
{cat:'model', catL:{zh:'模型',en:'Model'}, f:{zh:'本地模型 (Ollama)',en:'Local model (Ollama)'}, a:{zh:'✓ 已支持',en:'✓ Supported'}, c:{zh:'✗ 不支持',en:'✗ Not supported'}, win:'a'},
{cat:'tools', catL:{zh:'工具',en:'Tools'}, f:{zh:'代码图谱工具',en:'Code graph tools'}, a:{zh:'✓ 8 个内置',en:'✓ 8 built-in'}, c:{zh:'基础文本检索',en:'Basic text search'}, win:'a'},
{cat:'tools', catL:{zh:'工具',en:'Tools'}, f:{zh:'/undo 一键回滚',en:'/undo one-click rollback'}, a:{zh:'✓ 已支持',en:'✓ Supported'}, c:{zh:'手动 git',en:'Manual git'}, win:'a'},
{cat:'integration',catL:{zh:'集成',en:'Integration'}, f:{zh:'AtomGit 原生集成',en:'AtomGit native integration'}, a:{zh:'✓ OAuth + /issue',en:'✓ OAuth + /issue'}, c:{zh:'✗ 不支持',en:'✗ Not supported'}, win:'a'},
{cat:'tools', catL:{zh:'工具',en:'Tools'}, f:{zh:'MCP 支持',en:'MCP support'}, a:{zh:'✓ 已支持',en:'✓ Supported'}, c:{zh:'✓ 已支持',en:'✓ Supported'}, win:'='},
{cat:'tools', catL:{zh:'工具',en:'Tools'}, f:{zh:'视觉 / 截图',en:'Vision / screenshot'}, a:{zh:'✓ 已支持',en:'✓ Supported'}, c:{zh:'✓ 已支持',en:'✓ Supported'}, win:'='},
{cat:'price', catL:{zh:'价格',en:'Price'}, f:{zh:'费用',en:'Pricing'}, a:{zh:'CodingPlan 限免 · 自带 API',en:'CodingPlan free tier · BYO API'}, c:{zh:'订阅 + API',en:'Subscription + API'}, win:'a'},
];
HarmonyOS ArkWeb, plain http:// pages, and some embedded browsers don't
expose `navigator.clipboard`, so the old `navigator.clipboard && writeText`
silently no-opped while the UI still flashed "✓ Copied" — paste yielded
nothing. Fall back to a hidden <textarea> + execCommand so copy works there. */
function legacyCopy(text){
try{
const ta=document.createElement('textarea');
ta.value=text;
ta.setAttribute('readonly','');
ta.style.position='fixed';
ta.style.left='-9999px';
ta.style.top='0';
document.body.appendChild(ta);
ta.focus();ta.select();
try{ta.setSelectionRange(0,text.length);}catch(e){}
const ok=document.execCommand('copy');
document.body.removeChild(ta);
return ok;
}catch(e){return false;}
}
function copyText(text){
if(navigator.clipboard&&window.isSecureContext){
return navigator.clipboard.writeText(text).catch(()=>legacyCopy(text));
}
return Promise.resolve(legacyCopy(text));
}
let HERO_AUTO=true,HERO_OS='mac';
(function(){
const tabs=document.getElementById('osTabs');
const cmd=document.getElementById('osCmd');
const hint=document.getElementById('osHint');
const toast=document.getElementById('toast');
function detect(){
const ua=navigator.userAgent||'';
if(/OpenHarmony|HarmonyOS|Harmony|ArkWeb/i.test(ua)) return 'harmony';
if(/Mac/i.test(ua)) return 'mac';
if(/Win/i.test(ua)) return 'win';
return 'linux';
}
function highlight(text){
const stash=[];
text=text.replace(/(https?:\/\/\S+)/g,(m)=>{stash.push(['str',m]);return '\x00'+(stash.length-1)+'\x00';});
text=text.replace(/\b(curl|irm|iex|bash|wget|git|cd|cargo|npm|export)\b/g,'<span class="accent">$1</span>');
return text.replace(/\x00(\d+)\x00/g,(_,i)=>`<span class="${stash[i][0]}">${stash[i][1]}</span>`);
}
window.applyHeroInstall=function(){
tabs.querySelectorAll('.install-tab').forEach(t=>t.classList.toggle('active',t.dataset.os===HERO_OS));
cmd.innerHTML=highlight(OS_CMDS[HERO_OS]);
hint.textContent=(HERO_AUTO?t('os.auto'):'')+osHint(HERO_OS);
};
HERO_OS=detect();HERO_AUTO=true;applyHeroInstall();
tabs.addEventListener('click',e=>{const tb=e.target.closest('.install-tab');if(!tb)return;HERO_OS=tb.dataset.os;HERO_AUTO=false;applyHeroInstall();});
document.getElementById('copyInstall').addEventListener('click',()=>{
copyText(OS_CMDS[HERO_OS]);
const btn=document.getElementById('copyInstall');btn.classList.add('copied');btn.textContent=LANG==='zh'?'✓ 已复制':'✓ Copied';
toast.textContent=t('toast.install.copied');toast.classList.add('show');
setTimeout(()=>{toast.classList.remove('show')},1800);
setTimeout(()=>{btn.classList.remove('copied');btn.textContent=t('install.copy')},1800);
});
})();
let CUR_FLOW='bug';
window.playTerminal=null;
(function(){
const chips=document.getElementById('termChips');
const body=document.getElementById('termBody');
let timers=[];
function clear(){timers.forEach(clearTimeout);timers=[];body.innerHTML='';}
function appendCaret(){
const c=document.createElement('span');c.className='caret';c.id='termCaret';body.appendChild(c);
body.scrollTop=body.scrollHeight;
}
function play(flow){
CUR_FLOW=flow;
clear();
let acc=0;
FLOWS[flow].forEach(([d,kind,text])=>{
acc+=d;
timers.push(setTimeout(()=>{
const ex=document.getElementById('termCaret');if(ex)ex.remove();
const ln=document.createElement('span');
ln.className='tl '+kind;
ln.textContent=tx(text);
body.appendChild(ln);
appendCaret();
},acc));
});
timers.push(setTimeout(()=>{
const ex=document.getElementById('termCaret');if(ex)ex.remove();
},acc+1200));
}
window.playTerminal=play;
chips.addEventListener('click',e=>{
const b=e.target.closest('.term-chip');if(!b)return;
chips.querySelectorAll('.term-chip').forEach(x=>x.classList.remove('active'));
b.classList.add('active');
play(b.dataset.flow);
});
play('bug');
})();
(function(){
const io=new IntersectionObserver(entries=>{
entries.forEach(en=>{
if(en.isIntersecting&&!en.target._done){
en.target._done=true;
const tgt=parseInt(en.target.dataset.count,10);
const dur=1200,t0=performance.now();
const step=t=>{
const k=Math.min(1,(t-t0)/dur),e=1-Math.pow(1-k,3);
en.target.textContent=Math.floor(tgt*e);
if(k<1) requestAnimationFrame(step);else en.target.textContent=tgt;
};
requestAnimationFrame(step);
}
});
},{threshold:.4});
document.querySelectorAll('[data-count]').forEach(el=>io.observe(el));
})();
(function(){
const nodes=document.querySelectorAll('#agentLoop .node');
let i=0;
setInterval(()=>{nodes.forEach((n,k)=>n.classList.toggle('active',k===i));i=(i+1)%nodes.length;},800);
})();
document.body.addEventListener('mousemove',e=>{
const card=e.target.closest('.feat');if(!card) return;
const r=card.getBoundingClientRect();
card.style.setProperty('--mx',((e.clientX-r.left)/r.width*100)+'%');
card.style.setProperty('--my',((e.clientY-r.top)/r.height*100)+'%');
});
window.renderPerf=null;
(function(){
const list=document.getElementById('perfList');
const max=Math.max(...PERF.flatMap(p=>[p.a,p.c]));
function render(animate){
list.innerHTML='';
const stepWord=LANG==='zh'?'步':' steps';
PERF.forEach(p=>{
const row=document.createElement('div');
row.className='perf-row';
row.innerHTML=`
<div class="name">${tx(p.task)}</div>
<div class="perf-bars">
<div class="perf-bar a"><div class="fill" data-w="${p.a/max*100}" style="width:0"></div><span class="lbl">A: ${p.a}${stepWord}</span></div>
<div class="perf-bar c"><div class="fill" data-w="${p.c/max*100}" style="width:0"></div><span class="lbl">C: ${p.c}${stepWord}</span></div>
</div>
<div class="perf-status ${p.k}">${tx(p.s)}</div>`;
list.appendChild(row);
});
if(animate){
list.querySelectorAll('.perf-bar .fill').forEach((f,i)=>{
setTimeout(()=>{f.style.width=f.dataset.w+'%'},80+i*60);
});
} else {
list.querySelectorAll('.perf-bar .fill').forEach(f=>{f.style.transition='none';f.style.width=f.dataset.w+'%';requestAnimationFrame(()=>{f.style.transition=''})});
}
}
window.renderPerf=render;
render(false);
const io=new IntersectionObserver(entries=>{
entries.forEach(en=>{
if(en.isIntersecting){
list.querySelectorAll('.perf-bar .fill').forEach(f=>{f.style.width='0'});
requestAnimationFrame(()=>{
list.querySelectorAll('.perf-bar .fill').forEach((f,i)=>{setTimeout(()=>{f.style.width=f.dataset.w+'%'},80+i*60);});
});
io.disconnect();
}
});
},{threshold:.3});
io.observe(list);
})();
window.renderFtab=null;
(function(){
const tbody=document.getElementById('ftabBody');
let activeCat='all',onlyDiff=false;
function render(){
tbody.innerHTML=FEAT.map(f=>`
<tr data-cat="${f.cat}" data-win="${f.win}">
<td><span class="cat">${tx(f.catL)}</span>${tx(f.f)}</td>
<td class="${f.win==='a'?'win':''}">${tx(f.a)}</td>
<td class="${f.win==='a'?'lose':''}">${tx(f.c)}</td>
</tr>`).join('');
apply();
}
function apply(){
tbody.querySelectorAll('tr').forEach(tr=>{
const ok=(activeCat==='all'||tr.dataset.cat===activeCat)&&(!onlyDiff||tr.dataset.win==='a');
tr.classList.toggle('hidden',!ok);
});
}
window.renderFtab=render;
render();
document.getElementById('cmpChips').addEventListener('click',e=>{
const b=e.target.closest('.cmp-chip');if(!b)return;
document.querySelectorAll('.cmp-chip').forEach(x=>x.classList.remove('active'));
b.classList.add('active');activeCat=b.dataset.cat;apply();
});
document.getElementById('diffToggle').addEventListener('click',e=>{
const el=e.currentTarget;el.classList.toggle('on');onlyDiff=el.classList.contains('on');apply();
});
})();
let CUR_METHOD='oneclick',CUR_WIZ_STEP=1;
window.applyMethod=null;
window.applyWizardNav=null;
(function(){
const tabs=document.querySelector('#install .install-tabs');
const cmd=document.getElementById('methodCmd');
const hint=document.getElementById('methodHint');
const toast=document.getElementById('toast');
function highlight(text){
const stash=[];
text=text.replace(/(#[^\n]*)/g,(m)=>{stash.push(['com',m]);return '\x00'+(stash.length-1)+'\x00';});
text=text.replace(/(https?:\/\/\S+)/g,(m)=>{stash.push(['str',m]);return '\x00'+(stash.length-1)+'\x00';});
text=text.replace(/\b(curl|irm|iex|bash|wget|git|cd|cargo|npm|export|chmod|mv)\b/g,'<span class="accent">$1</span>');
return text.replace(/\x00(\d+)\x00/g,(_,i)=>`<span class="${stash[i][0]}">${stash[i][1]}</span>`);
}
function extractLabel(text){
const lines=text.split('\n');
const labelParts=[];
let i=0;
while(i<lines.length){
if(/^\s*$/.test(lines[i])){i++;continue;}
if(/^\s*#/.test(lines[i])){labelParts.push(lines[i].replace(/^\s*#\s*/,'').trim());i++;continue;}
break;
}
const label=labelParts.filter(s=>s.length>0).join(' · ');
const body=lines.slice(i).join('\n').replace(/^\n+|\n+$/g,'');
return [label,body];
}
function show(m){
CUR_METHOD=m;
tabs.querySelectorAll('.install-tab').forEach(tb=>tb.classList.toggle('active',tb.dataset.method===m));
const raw=tx(METHOD_CMDS[m]);
const sections=raw.split(/\n[ \t]*\n/).map(s=>s.replace(/^\n+|\n+$/g,'')).filter(s=>s.length>0);
const label=t('install.copy.short');
const parsed=sections.map(extractLabel);
cmd.innerHTML=parsed.map(([lbl,body])=>
`<div class="install-cmd-section">`
+`<div class="cp-bar"><span class="label">${lbl}</span>`
+`<button class="cp-btn cp-section" type="button">${label}</button></div>`
+`<pre class="install-cmd">${highlight(body)}</pre>`
+`</div>`).join('');
cmd.querySelectorAll('.cp-section').forEach((btn,i)=>{btn.__copy=parsed[i][1]});
hint.textContent=methodHint(m);
}
window.applyMethod=()=>show(CUR_METHOD);
show('oneclick');
tabs.addEventListener('click',e=>{const tb=e.target.closest('.install-tab');if(!tb)return;show(tb.dataset.method);});
cmd.addEventListener('click',e=>{
const btn=e.target.closest('.cp-section');
if(!btn)return;
const text=btn.__copy||'';
copyText(text);
btn.classList.add('copied');
btn.textContent=LANG==='zh'?'✓ 已复制':'✓ Copied';
toast.textContent=t('toast.copied');toast.classList.add('show');
setTimeout(()=>{toast.classList.remove('show')},1600);
setTimeout(()=>{btn.classList.remove('copied');btn.textContent=t('install.copy.short')},1600);
});
(function(){
const toast=document.getElementById('toast');
document.addEventListener('click',e=>{
const btn=e.target.closest('.pi-cp');
if(!btn)return;
const pre=btn.closest('.pi-item, .pi-steps')?.querySelector('pre');
if(!pre)return;
const text=pre.textContent||'';
copyText(text);
btn.classList.add('copied');
btn.textContent=LANG==='zh'?'✓ 已复制':'✓ Copied';
toast.textContent=t('toast.copied');toast.classList.add('show');
setTimeout(()=>{toast.classList.remove('show')},1600);
setTimeout(()=>{btn.classList.remove('copied');btn.textContent=t('install.copy.short')},1600);
});
})();
document.getElementById('downloadRow').innerHTML=DOWNLOADS.map(d=>`
<a class="dl-btn" href="${RELEASE_BASE}/${d.file}" target="_blank" rel="noopener"><span>↓ ${d.os}</span><small>${d.arch}</small></a>`).join('');
const next=document.getElementById('wizNext'),prev=document.getElementById('wizPrev');
function go(){
document.querySelectorAll('.wiz-step').forEach(s=>s.classList.toggle('active',+s.dataset.step===CUR_WIZ_STEP));
document.querySelectorAll('#wizDots span').forEach((d,i)=>d.classList.toggle('on',i<CUR_WIZ_STEP));
prev.disabled=(CUR_WIZ_STEP===1);next.textContent=CUR_WIZ_STEP===3?t('wiz.done'):t('wiz.next');
}
window.applyWizardNav=go;
next.addEventListener('click',()=>{CUR_WIZ_STEP=CUR_WIZ_STEP<3?CUR_WIZ_STEP+1:1;go();});
prev.addEventListener('click',()=>{if(CUR_WIZ_STEP>1){CUR_WIZ_STEP--;go();}});
document.querySelectorAll('.wiz-step .opt').forEach(o=>{
o.addEventListener('click',()=>{
o.parentNode.querySelectorAll('.opt').forEach(x=>x.classList.remove('sel'));
o.classList.add('sel');
});
});
})();
(function(){
const aurora=document.getElementById('aurora');
let tx=-300,ty=-300,x=tx,y=ty;
addEventListener('mousemove',e=>{tx=e.clientX;ty=e.clientY});
(function tick(){x+=(tx-x)*.18;y+=(ty-y)*.18;aurora.style.setProperty('--mx',x+'px');aurora.style.setProperty('--my',y+'px');requestAnimationFrame(tick);})();
addEventListener('click',e=>{
if(e.target.closest('input,textarea,select')) return;
const r=document.createElement('div');r.className='ripple';
r.style.left=e.clientX+'px';r.style.top=e.clientY+'px';
document.body.appendChild(r);setTimeout(()=>r.remove(),700);
});
})();
(function(){
const bar=document.getElementById('progressBar'),hdr=document.getElementById('hdr');
const sections=['features','editor-plugins','compare','install'];
function tick(){
const max=Math.max(1,document.documentElement.scrollHeight-innerHeight);
bar.style.width=(scrollY/max*100).toFixed(2)+'%';
hdr.classList.toggle('scrolled',scrollY>40);
let cur=null;
for(const id of sections){const el=document.getElementById(id);if(!el)continue;const r=el.getBoundingClientRect();if(r.top<=innerHeight*0.35) cur=id;}
document.querySelectorAll('.hdr-nav a').forEach(a=>a.classList.toggle('active',a.dataset.section===cur));
}
tick();addEventListener('scroll',tick,{passive:true});
})();
(function(){
const els=Array.from(document.querySelectorAll('[data-magnetic]')).map(el=>({el,tx:0,ty:0,x:0,y:0}));
let mx=-9999,my=-9999;
addEventListener('mousemove',e=>{mx=e.clientX;my=e.clientY});
function loop(){
for(const it of els){
const r=it.el.getBoundingClientRect();
if(r.bottom<0||r.top>innerHeight){it.tx=it.ty=0}
else{
const cx=r.left+r.width/2,cy=r.top+r.height/2;
const dx=mx-cx,dy=my-cy,d=Math.hypot(dx,dy);
const R=Math.max(r.width,r.height)*1.3+30;
if(d<R){const k=(1-d/R)*.3;it.tx=dx*k;it.ty=dy*k}else{it.tx=0;it.ty=0}
}
it.x+=(it.tx-it.x)*.22;it.y+=(it.ty-it.y)*.22;
it.el.style.transform=(Math.abs(it.x)<.1&&Math.abs(it.y)<.1)?'':`translate(${it.x.toFixed(1)}px,${it.y.toFixed(1)}px)`;
}
requestAnimationFrame(loop);
}
loop();
})();
(function(){
const A='!<>-_\\/[]{}—=+*^?#@$%&|~01',C='零壹贰叁肆伍陆柒捌玖原码原子计算激励';
function scramble(el){
if(el._busy)return;
const orig=el.dataset._t||el.textContent;el.dataset._t=orig;
const chars=Array.from(orig);const total=Math.max(18,chars.length*2+10);let f=0;el._busy=true;
(function step(){
let out='';for(let i=0;i<chars.length;i++){
const ch=chars[i];const s=(i/chars.length)*total*.55,e=s+total*.35;
if(f>=e||/[\s,.·—:;\/\(\)\[\]\/]/.test(ch)){out+=ch;continue}
if(f<s){out+=ch;continue}
const p=/[A-Za-z0-9]/.test(ch)?A:/[一-龥]/.test(ch)?C:A;
out+=p[(Math.random()*p.length)|0];
}
el.textContent=out;f++;if(f<total) requestAnimationFrame(step);else{el.textContent=orig;el._busy=false}
})();
}
document.querySelectorAll('[data-scramble]').forEach(el=>{el.dataset._t=el.textContent;el.addEventListener('mouseenter',()=>scramble(el))});
})();
(function(){
const btn=document.getElementById('themeBtn');
const html=document.documentElement;
const toastEl=document.getElementById('toast');
const SUN='<svg class="theme-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>';
const MOON='<svg class="theme-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';
function apply(theme,announce){
const light=theme==='light';
html.classList.toggle('light',light);
btn.innerHTML=light?SUN:MOON;
btn.setAttribute('aria-label',light?'Switch to dark':'Switch to light');
try{localStorage.setItem('atomcode_theme',theme)}catch(e){}
if(announce){
toastEl.textContent=t(light?'toast.theme.light':'toast.theme.dark');
toastEl.classList.add('show');setTimeout(()=>toastEl.classList.remove('show'),1200);
}
}
let saved='dark';
try{saved=localStorage.getItem('atomcode_theme')||(matchMedia('(prefers-color-scheme: light)').matches?'light':'dark')}catch(e){}
apply(saved,false);
btn.addEventListener('click',()=>{apply(html.classList.contains('light')?'dark':'light',true);});
})();
(function(){
const btn=document.getElementById('langBtn');
const toastEl=document.getElementById('toast');
function syncBtn(){btn.textContent=LANG==='zh'?'EN':'中';btn.setAttribute('aria-label',LANG==='zh'?'Switch to English':'切换到 中文');}
function applyAll(){
applyI18n();
syncBtn();
if(window.renderPerf) window.renderPerf(false);
if(window.renderFtab) window.renderFtab();
if(window.applyMethod) window.applyMethod();
if(window.applyHeroInstall) window.applyHeroInstall();
if(window.applyWizardNav) window.applyWizardNav();
if(window.playTerminal) window.playTerminal(CUR_FLOW);
}
applyAll();
btn.addEventListener('click',()=>{
LANG=LANG==='zh'?'en':'zh';
try{localStorage.setItem('atomcode_lang',LANG)}catch(e){}
applyAll();
toastEl.textContent=t('toast.lang.'+LANG);
toastEl.classList.add('show');setTimeout(()=>toastEl.classList.remove('show'),1200);
});
})();
(function(){
const tog=document.getElementById('mbToggle');
const drawer=document.getElementById('mbDrawer');
if(!tog||!drawer) return;
function close(){drawer.classList.remove('open');tog.setAttribute('aria-expanded','false');tog.textContent='☰';document.body.style.overflow=''}
function open(){drawer.classList.add('open');tog.setAttribute('aria-expanded','true');tog.textContent='✕';document.body.style.overflow='hidden'}
tog.addEventListener('click',e=>{e.stopPropagation();drawer.classList.contains('open')?close():open()});
drawer.querySelectorAll('a').forEach(a=>a.addEventListener('click',close));
document.addEventListener('click',e=>{
if(!drawer.classList.contains('open'))return;
if(drawer.contains(e.target)||tog.contains(e.target))return;
close();
});
window.addEventListener('resize',()=>{if(window.innerWidth>768)close()});
})();
</script>
</body>
</html>