@@ -283,15 +283,42 @@ function formPage(local: boolean): string {
283283 <details class="alt"><summary>或:体检公开仓库 URL</summary>${ urlForm } </details>` : ''
284284
285285 return page ( 'ShellWard 合规体检' , `
286- <div class="hero">
287- <div class="logo">🛡️ Shell<span>Ward</span> 合规网关</div>
288- <h1>AI 应用合规体检</h1>
289- <p class="sub">${ local ? '选你的项目,' : '贴公开仓库链接,' } 30 秒查出数据出境 / 硬编码密钥 / 个人信息暴露等中国合规红线。</p>
290- ${ local ? localForms : urlForm }
286+ <nav class="nav">
287+ <div class="logo">🛡️ Shell<span>Ward</span> <em>合规网关</em></div>
288+ <a class="ghbtn" href="https://github.com/jnMetaCode/shellward" target="_blank">★ GitHub Star</a>
289+ </nav>
290+ <main class="wrap">
291+ <header class="hd">
292+ <div class="tag">网安法 2026 · PIPL · 等保2.0 · 数据出境 · AI标识</div>
293+ <h1>30 秒,查出你的 AI 项目<br>踩了哪些 <span class="hl">中国合规红线</span></h1>
294+ <p class="sub">数据出境 · 硬编码密钥 · 个人信息暴露 —— 精确到 <code>文件:行</code>,并给出境内替代建议。${ local ? '<b>私有代码不出本机。</b>' : '' } </p>
295+ </header>
296+
297+ <section class="card">
298+ ${ local ? localForms : urlForm }
299+ </section>
300+
301+ <section class="checks">
302+ <div class="chk"><span>🌐</span><b>数据出境</b><i>境外大模型端点/SDK</i></div>
303+ <div class="chk"><span>🔑</span><b>硬编码密钥</b><i>OpenAI/GitHub/AWS…</i></div>
304+ <div class="chk"><span>🪪</span><b>个人信息</b><i>身份证/手机/银行卡</i></div>
305+ <div class="chk"><span>📂</span><b>.env 暴露</b><i>权限/明文密钥</i></div>
306+ </section>
307+
291308 <p class="demo">🤔 想先看效果? <a href="/demo">▶ 看一个含风险的示例报告</a></p>
292- <p class="foot">网安法 2026 · PIPL · 等保2.0 · 数据出境 · AI标识 | 零依赖 · 开源 ·
293- <a href="https://github.com/jnMetaCode/shellward">GitHub ⭐</a></p>
294- </div>
309+
310+ <section class="trust">
311+ <div><b>🔒 ${ local ? '不出本机' : '不存储代码' } </b>${ local ? '服务端直读本机,零上传' : '公开仓库浅克隆,用完即删' } </div>
312+ <div><b>📦 零依赖</b>可在信创/离线环境跑</div>
313+ <div><b>⚖️ 开源</b>Apache-2.0,代码全公开</div>
314+ <div><b>🇨🇳 中文优先</b>为中国监管而生</div>
315+ </section>
316+
317+ <footer class="ft">
318+ 公众号「AI不止语」· 技术问答 · 实战文章 |
319+ <a href="https://github.com/jnMetaCode/shellward" target="_blank">github.com/jnMetaCode/shellward</a> · Apache-2.0
320+ </footer>
321+ </main>
295322 <div id="overlay" class="overlay"><div class="spin"></div><div id="ovtext">扫描中…</div></div>
296323 ${ local ? BROWSE_SCRIPT : '' } ` )
297324}
@@ -366,55 +393,59 @@ function page(title: string, body: string): string {
366393 return `<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
367394<meta name="viewport" content="width=device-width,initial-scale=1"><title>${ esc ( title ) } </title>
368395<style>
369- *{box-sizing:border-box}body{margin:0;min-height:100vh;display:grid;place-items:center;
370- background:linear-gradient(135deg,#eef1f6,#e2e8f0 );color:#0f172a;
396+ *{box-sizing:border-box}
397+ body{margin:0;min-height:100vh; background:linear-gradient(180deg,#f4f7fb,#e8edf4 );color:#0f172a;
371398font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif}
372- .hero{background:#fff;max-width:580px;width:92%;margin:40px;padding:38px 40px 34px;border-radius:18px;
373- box-shadow:0 12px 40px rgba(15,23,42,.12);text-align:center;border-top:4px solid #cb0000}
374- .logo{font-weight:800;font-size:15px;letter-spacing:.2px}.logo span{color:#cb0000}
375- h1{font-size:29px;margin:12px 0 8px;letter-spacing:-.5px}
376- .sub{color:#64748b;margin:0 0 24px;font-size:15px}
399+ a{color:#cb0000;text-decoration:none}
400+ .nav{display:flex;justify-content:space-between;align-items:center;max-width:760px;margin:0 auto;padding:18px 24px}
401+ .logo{font-weight:800;font-size:17px}.logo span{color:#cb0000}
402+ .logo em{font-style:normal;color:#94a3b8;font-weight:600;font-size:13px;margin-left:5px}
403+ .ghbtn{border:1px solid #cbd5e1;border-radius:8px;padding:7px 14px;font-size:13px;font-weight:700;color:#0f172a;background:#fff;transition:.15s}
404+ .ghbtn:hover{border-color:#cb0000;color:#cb0000}
405+ .wrap{max-width:760px;margin:0 auto;padding:0 24px 48px}
406+ .hd{text-align:center;padding:22px 0 26px}
407+ .tag{display:inline-block;background:#fef2f2;color:#cb0000;font-size:12px;font-weight:700;padding:5px 14px;border-radius:999px;margin-bottom:16px}
408+ h1{font-size:34px;line-height:1.25;margin:0 0 12px;letter-spacing:-.6px}
409+ h1 .hl{color:#cb0000}
410+ .sub{color:#475569;font-size:16px;max-width:580px;margin:0 auto}
411+ .sub code{background:#eef2f7;padding:1px 6px;border-radius:5px;font-size:14px}
412+ .card{background:#fff;border-radius:16px;padding:24px 26px;box-shadow:0 10px 30px rgba(15,23,42,.10);border-top:3px solid #cb0000}
377413form{display:flex;flex-direction:column;gap:10px;text-align:left}
378414label{font-size:13px;font-weight:700;color:#334155}
379- input{padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;font-size:16px ;width:100%}
415+ input{padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;font-size:15px ;width:100%}
380416input:focus{outline:none;border-color:#cb0000;box-shadow:0 0 0 3px rgba(203,0,0,.12)}
381- .hint{font-size:12.5px;color:#64748b;margin:2px 0 6px;line-height:1.55}
382- .hint code{background:#f1f5f9;padding:1px 6px;border-radius:5px}
383- /* 文件选择器:美化成虚线投放区 + 红色按钮 */
384- input[type=file]{width:100%;padding:20px 16px;border:2px dashed #cbd5e1;border-radius:12px;
385- background:#f8fafc;cursor:pointer;font-size:14px;color:#64748b;transition:.15s}
386- input[type=file]:hover{border-color:#cb0000;background:#fff}
387- input[type=file]::file-selector-button{background:#cb0000;color:#fff;border:0;border-radius:8px;
388- padding:9px 18px;margin-right:14px;font-weight:700;font-size:14px;cursor:pointer}
389- input[type=file]::file-selector-button:hover{background:#a80000}
390- button{background:#cb0000;color:#fff;border:0;border-radius:10px;padding:14px;font-size:16px;
391- font-weight:700;cursor:pointer;margin-top:4px;transition:.15s}button:hover{background:#a80000}
392- button:disabled{background:#94a3b8;cursor:default}
393- form{margin:0 0 14px}.or{text-align:center;color:#94a3b8;font-size:13px;margin:6px 0 14px}
394- .status{display:none;margin:10px 0 0;padding:10px 14px;border-radius:8px;background:#f1f5f9;
395- color:#334155;font-size:13.5px;border-left:3px solid #cb0000;text-align:left}
396- .pathrow{display:flex;gap:8px}
417+ button{background:#cb0000;color:#fff;border:0;border-radius:10px;padding:14px;font-size:16px;font-weight:700;cursor:pointer;transition:.15s}
418+ button:hover{background:#a80000}button:disabled{background:#94a3b8;cursor:default}
419+ .hint{font-size:12.5px;color:#64748b;margin:8px 0 0;line-height:1.55}
420+ code,.hint code{background:#eef2f7;padding:1px 6px;border-radius:5px;font-size:12.5px}
421+ .pathrow{display:flex;gap:8px;margin-top:6px}
397422.pathrow input{flex:1;font-family:ui-monospace,Menlo,monospace;font-size:13px}
398- .pathrow button{margin-top:0;white-space:nowrap;padding:14px 22px}
399- .demo{margin:18px 0 0;font-size:13px;color:#475569}.demo a{font-weight:600}
400- .overlay{display:none;position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:99;
423+ .pathrow button{padding:14px 22px;white-space:nowrap}
424+ .browser{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden;margin:10px 0 0;text-align:left}
425+ .dirs{list-style:none;margin:0;padding:0;max-height:200px;overflow-y:auto}
426+ .dirs li{padding:9px 14px;border-top:1px solid #eef2f7;cursor:pointer;font-size:14px}
427+ .dirs li:first-child{border-top:0}.dirs li:hover{background:#f8fafc}
428+ .dirs li.up{color:#cb0000;font-weight:600}.dirs li.empty{color:#94a3b8;cursor:default;font-size:13px}
429+ details.alt{margin:14px 0 0;border-top:1px dashed #e2e8f0;padding-top:12px}
430+ details.alt summary{cursor:pointer;color:#cb0000;font-size:13px;font-weight:600}
431+ details.alt[open] summary{margin-bottom:10px}
432+ .checks{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:22px 0}
433+ .chk{background:#fff;border:1px solid #eef2f7;border-radius:12px;padding:16px 10px;text-align:center}
434+ .chk span{font-size:24px;display:block;margin-bottom:6px}
435+ .chk b{display:block;font-size:14px}.chk i{font-style:normal;color:#94a3b8;font-size:11px;display:block;margin-top:3px}
436+ .demo{text-align:center;font-size:13.5px;color:#475569;margin:6px 0 22px}.demo a{font-weight:700}
437+ .trust{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:0 0 26px}
438+ .trust div{background:#f8fafc;border-radius:10px;padding:14px 12px;font-size:11.5px;color:#64748b;line-height:1.5}
439+ .trust b{display:block;color:#0f172a;font-size:13px;margin-bottom:3px}
440+ .ft{text-align:center;color:#94a3b8;font-size:12.5px;padding-top:14px;border-top:1px solid #e3e9f1}
441+ .overlay{display:none;position:fixed;inset:0;background:rgba(15,23,42,.6);z-index:99;
401442flex-direction:column;align-items:center;justify-content:center;color:#fff;gap:16px;font-size:15px;font-weight:600}
402- .spin{width:46px;height:46px;border:4px solid rgba(255,255,255,.25);border-top-color:#fff;
403- border-radius:50%;animation:sp .8s linear infinite}
443+ .spin{width:46px;height:46px;border:4px solid rgba(255,255,255,.25);border-top-color:#fff;border-radius:50%;animation:sp .8s linear infinite}
404444@keyframes sp{to{transform:rotate(360deg)}}
405- details.alt{margin:6px 0 10px;text-align:left}
406- details.alt summary{cursor:pointer;color:#cb0000;font-size:13px;font-weight:600;padding:6px 0}
407- details.alt[open] summary{margin-bottom:8px}
408- .browser{border:1px solid #cbd5e1;border-radius:10px;overflow:hidden;margin:4px 0 10px;text-align:left}
409- .bpath{background:#0f172a;color:#93c5fd;font-family:ui-monospace,Menlo,monospace;font-size:12px;
410- padding:9px 12px;word-break:break-all}
411- .dirs{list-style:none;margin:0;padding:0;max-height:240px;overflow-y:auto}
412- .dirs li{padding:9px 14px;border-top:1px solid #eef2f7;cursor:pointer;font-size:14px}
413- .dirs li:hover{background:#f1f5f9}
414- .dirs li.up{color:#cb0000;font-weight:600}
415- .dirs li.empty{color:#94a3b8;cursor:default;font-size:13px}
416- .foot{margin:24px 0 0;font-size:12.5px;color:#94a3b8}.foot a,.back{color:#cb0000;text-decoration:none}
417- .back{font-weight:600}
445+ /* 错误页复用 */
446+ .hero{background:#fff;max-width:520px;margin:60px auto;padding:36px;border-radius:16px;box-shadow:0 10px 30px rgba(15,23,42,.1);text-align:center}
447+ .hero .logo{font-size:15px}.back{font-weight:600}
448+ @media(max-width:560px){h1{font-size:26px}.checks,.trust{grid-template-columns:repeat(2,1fr)}}
418449</style></head><body>${ body } </body></html>`
419450}
420451
0 commit comments