diff --git a/apps/site/assets/ai-session.png b/apps/site/assets/ai-session.png new file mode 100644 index 0000000..293ecb0 Binary files /dev/null and b/apps/site/assets/ai-session.png differ diff --git a/apps/site/assets/documents.png b/apps/site/assets/documents.png new file mode 100644 index 0000000..2302631 Binary files /dev/null and b/apps/site/assets/documents.png differ diff --git a/apps/site/assets/explore.png b/apps/site/assets/explore.png new file mode 100644 index 0000000..2fc5ad5 Binary files /dev/null and b/apps/site/assets/explore.png differ diff --git a/apps/site/assets/senlinai-icon.svg b/apps/site/assets/senlinai-icon.svg new file mode 100644 index 0000000..dc3662b --- /dev/null +++ b/apps/site/assets/senlinai-icon.svg @@ -0,0 +1,10 @@ + + 森林AI 图标 + + + + + + + + diff --git a/apps/site/assets/workspace.png b/apps/site/assets/workspace.png new file mode 100644 index 0000000..1e2dcc1 Binary files /dev/null and b/apps/site/assets/workspace.png differ diff --git a/apps/site/design-qa.md b/apps/site/design-qa.md new file mode 100644 index 0000000..ea906d8 --- /dev/null +++ b/apps/site/design-qa.md @@ -0,0 +1,39 @@ +# Design QA + +## Comparison target + +- Source visual truth: `C:\Users\david\.codex\generated_images\019f92c1-c086-7b62-9e3e-8942418c08bb\exec-92a2158c-b865-4c30-a1af-bd75a8410bd2.png` (the selected final design, option 1). +- Supporting product references: `docs/screen/login.png`, `docs/screen/workspace.png`, `docs/screen/export.png`, `docs/screen/p3.png`, and `docs/screen/p4.png`. +- Intended implementation: `apps/site/index.html` at a desktop viewport matching the selected long-form landing page. +- Implementation screenshot: unavailable. + +## Evidence and state + +- Source assets were opened and inspected before implementation. +- The page uses the supplied official logo and product screenshots rather than recreated logo or product-preview artwork. +- Primary interactions in code: “下载” scrolls to the download section; “WEB 登录” links to `https://agent.senlin.ai`. +- Static resource validation passed: all six referenced assets exist and the WEB login URL is present. +- Backend tests and the existing `web_v1` production build passed. + +## Required fidelity surfaces + +- Fonts and typography: implemented with the existing Chinese system-font stack, a high-contrast display hierarchy, and compact utility text aligned with the source system. +- Spacing and layout rhythm: implemented as an 1440px-centered desktop grid with a left text / right product-preview hero and responsive single-column fallback. +- Colors and visual tokens: uses the source product’s cobalt `#165DFF`, pale gray workspace surfaces, thin blue-gray separators, and navy footer/status treatment. +- Image quality and asset fidelity: uses supplied SVG logo and supplied product captures for workbench, exploration, documents, and AI conversation. +- Copy and content: includes project context, exploration data, project documents, expert AI conversations, private deployment, and human confirmation. + +## Findings + +- [P1] Browser-rendered visual comparison is unavailable. + - Evidence: the in-app browser could not initialize in this environment because of a system path error, so no implementation screenshot or same-viewport composite comparison could be captured. + - Impact: typography, crop, spacing and responsive behavior have not been verified against the selected visual target in a browser. + - Fix: restore in-app browser access, capture the homepage at the selected desktop viewport, compare it side-by-side with the source visual, and resolve any P0/P1/P2 differences. + +## Comparison history + +- Initial pass: blocked before browser capture; no visual comparison iteration is available. + +## Final result + +final result: blocked diff --git a/apps/site/index.html b/apps/site/index.html new file mode 100644 index 0000000..84814d4 --- /dev/null +++ b/apps/site/index.html @@ -0,0 +1,105 @@ + + + + + + + 森林AI · 项目驱动的智能工作台 + + + + + +
+
+
+

私有部署 · 团队协作 · 智能决策

+

把工作收进项目,
用 AI 给出建议,
由人来确认结果

+

森林AI 面向知识工作者与内部团队,将计划、探索数据、资料和专家对话沉淀在同一个项目空间。

+ +

私有部署,数据自有,安全可控

+
+
+ 森林AI统一工作台,展示项目、计划、AI 会话与知识资料 +
+
+ +
+
+

01

+

项目即上下文,
让所有信息回到同一处。

+

计划、任务、笔记、资料和对话始终归属于项目。团队不必在分散工具间反复寻找背景,工作进展与知识沉淀清晰可追溯。

+
+
+
项目空间

聚合目标、计划与工作动态。

+
统一工作台

跨项目掌握待办与关键进展。

+
资料可追溯

让每一份内容保留明确归属。

+
+
+ +
+
+
+ 森林AI探索页面,集中浏览多来源数据并沉淀到项目 +
探索数据
+
+
+ 森林AI项目笔记资料页面,集中管理项目内文档 +
项目资料
+
+
+
+

02

+

探索信息,
沉淀为项目资料。

+

从多个外部数据源集中浏览信息,将值得保留的内容沉淀到项目。探索不止是阅读,更是为下一步决策建立可靠的资料基础。

+
+
探索数据
按来源浏览与筛选,保留信息出处。
+
笔记资料
文档、附件和 Markdown 笔记随项目持续积累。
+
+
+
+ +
+
+

03

+

与专家 AI 对话,
建议由人确认。

+

选择合适的专业角色,在项目上下文中获得分析与建议。AI 输出先作为候选草稿呈现,只有人工确认后才会成为正式任务、笔记或资料。

+
+ 收集建议确认 +
+
+
+ 森林AI专家选择与项目内 AI 会话界面 +
+
+ +
+
+

在你的环境中,安全使用专业 AI

+

私有部署,数据自有,
团队协作始终可控。

+
+
+ WEB 登录 +

客户端下载包由部署管理员提供;已有工作台可直接登录 WEB 版本。

+
+
+
+ + + + diff --git a/apps/site/styles.css b/apps/site/styles.css new file mode 100644 index 0000000..ea17c46 --- /dev/null +++ b/apps/site/styles.css @@ -0,0 +1,107 @@ +:root { + color: #17233a; + background: #ffffff; + font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif; + font-synthesis: none; +} + +* { box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { margin: 0; min-width: 320px; background: #fff; } +a { color: inherit; text-decoration: none; } + +.site-header { + align-items: center; + background: rgba(255, 255, 255, .96); + border-bottom: 1px solid #edf0f5; + display: flex; + height: 76px; + justify-content: space-between; + padding: 0 clamp(24px, 5vw, 80px); + position: sticky; + top: 0; + z-index: 5; +} + +.brand { align-items: center; display: inline-flex; font-size: 20px; font-weight: 750; gap: 9px; letter-spacing: -.5px; } +.brand img { border-radius: 9px; display: block; } +nav { align-items: center; display: flex; gap: 16px; font-size: 15px; font-weight: 650; } +.download-link { border: 1px solid #bad0ff; border-radius: 6px; color: #165dff; padding: 10px 18px; } +.login-link { background: #165dff; border-radius: 6px; color: white; padding: 11px 19px; } +.download-link:hover, .text-action:hover { background: #edf4ff; } +.login-link:hover, .button-primary:hover { background: #0e4cda; } + +.section-shell { margin: 0 auto; max-width: 1440px; padding-left: clamp(24px, 5vw, 80px); padding-right: clamp(24px, 5vw, 80px); } +.hero { display: grid; gap: clamp(36px, 6vw, 92px); grid-template-columns: minmax(300px, .82fr) minmax(540px, 1.3fr); min-height: 720px; overflow: hidden; padding-bottom: 80px; padding-top: clamp(62px, 9vw, 130px); } +.hero-copy { align-self: center; max-width: 460px; } +.eyebrow, .section-index { color: #165dff; font-size: 14px; font-weight: 750; letter-spacing: .03em; margin: 0 0 22px; } +h1, h2 { color: #13203a; letter-spacing: -.065em; margin: 0; } +h1 { font-size: clamp(42px, 5vw, 72px); line-height: 1.16; } +h2 { font-size: clamp(32px, 3.2vw, 49px); line-height: 1.2; } +.hero-description, .section-heading > p:not(.section-index), .showcase-copy > p:not(.section-index) { color: #5f6d84; font-size: 17px; line-height: 1.9; margin: 28px 0; } +.hero-actions { align-items: center; display: flex; flex-wrap: wrap; gap: 25px; margin-top: 36px; } +.button { border-radius: 6px; display: inline-flex; font-size: 16px; font-weight: 700; justify-content: center; padding: 15px 27px; transition: background .18s ease; } +.button-primary { background: #165dff; box-shadow: 0 10px 24px rgba(22, 93, 255, .18); color: #fff; } +.text-action { color: #165dff; font-size: 16px; font-weight: 700; padding: 12px 4px; } +.text-action span { font-size: 22px; margin-left: 4px; vertical-align: -1px; } +.hero-note { color: #68768d; font-size: 14px; margin: 31px 0 0; } +.hero-product { align-self: center; background: #f6f9ff; border: 1px solid #e7eefb; border-radius: 12px; box-shadow: 0 28px 55px rgba(39, 75, 130, .13); overflow: hidden; } +.hero-product img, .showcase-image img { display: block; height: auto; width: 100%; } + +.context-section { border-top: 1px solid #edf0f5; display: grid; gap: 70px; grid-template-columns: minmax(300px, .9fr) minmax(450px, 1.1fr); padding-bottom: 120px; padding-top: 120px; } +.section-heading > p:not(.section-index) { max-width: 510px; } +.context-points { border-left: 1px solid #dce6f5; display: grid; grid-template-columns: repeat(3, 1fr); padding-left: 34px; } +.context-points article { padding: 7px 28px 10px; } +.context-points article + article { border-left: 1px solid #e8edf5; } +.context-points span { color: #1c2c49; font-size: 18px; font-weight: 750; } +.context-points p { color: #728098; font-size: 14px; line-height: 1.75; } + +.showcase { align-items: center; background: #f7f9fd; display: grid; gap: clamp(40px, 7vw, 110px); grid-template-columns: minmax(420px, 1.15fr) minmax(300px, .85fr); margin-bottom: 0; max-width: none; padding-bottom: 108px; padding-top: 108px; } +.showcase-image { background: #fff; border: 1px solid #e4eaf3; box-shadow: 0 22px 48px rgba(30, 55, 95, .09); overflow: hidden; } +.data-preview-grid { display: grid; gap: 12px; grid-template-columns: 1.22fr .78fr; padding: 12px; } +.data-preview-grid figure { margin: 0; min-width: 0; } +.data-preview-grid figcaption { color: #61718a; font-size: 13px; font-weight: 700; padding: 9px 2px 1px; } +.showcase-copy { max-width: 460px; } +.showcase-copy dl { border-top: 1px solid #dce4ef; margin: 32px 0 0; } +.showcase-copy dl div { border-bottom: 1px solid #dce4ef; padding: 15px 0; } +dt { color: #1b2a47; font-size: 16px; font-weight: 750; } +dd { color: #718097; font-size: 14px; margin: 7px 0 0; } +.showcase-reversed { background: #fff; grid-template-columns: minmax(300px, .85fr) minmax(420px, 1.15fr); } +.workflow { align-items: center; display: flex; gap: 12px; margin-top: 34px; } +.workflow span, .workflow strong { border: 1px solid #dbe5f5; border-radius: 5px; color: #587093; font-size: 14px; padding: 9px 13px; } +.workflow strong { background: #165dff; border-color: #165dff; color: #fff; } +.workflow i { background: #9ebdff; height: 1px; width: 22px; } + +.download-section { align-items: center; background: #eff5ff; display: flex; justify-content: space-between; max-width: none; padding-bottom: 88px; padding-top: 88px; } +.download-section h2 { font-size: clamp(31px, 3.2vw, 47px); } +.download-actions { max-width: 315px; } +.download-actions p { color: #6c7b92; font-size: 14px; line-height: 1.7; margin: 16px 0 0; } +.site-footer { align-items: center; background: #13213a; color: #fff; display: flex; font-size: 13px; justify-content: space-between; padding: 24px clamp(24px, 5vw, 80px); } +.site-footer .brand { font-size: 15px; } + +@media (max-width: 980px) { + .hero, .context-section, .showcase, .showcase-reversed { grid-template-columns: 1fr; } + .hero { min-height: auto; padding-bottom: 74px; } + .hero-copy, .showcase-copy { max-width: 620px; } + .context-section { gap: 36px; } + .context-points { padding-left: 0; } + .showcase { gap: 46px; } + .showcase-reversed .showcase-copy { grid-row: 1; } +} + +@media (max-width: 640px) { + .site-header { height: 66px; padding: 0 18px; } + .brand { font-size: 17px; gap: 7px; } + nav { gap: 8px; font-size: 13px; } + .download-link, .login-link { padding: 8px 10px; } + .section-shell { padding-left: 20px; padding-right: 20px; } + .hero { padding-top: 60px; } + h1 { font-size: 43px; } + .context-section, .showcase { padding-bottom: 72px; padding-top: 72px; } + .context-points { border-left: 0; grid-template-columns: 1fr; } + .context-points article { border-bottom: 1px solid #e8edf5; padding: 18px 0; } + .context-points article + article { border-left: 0; } + .download-section { align-items: flex-start; flex-direction: column; gap: 30px; padding-bottom: 64px; padding-top: 64px; } + .workflow { flex-wrap: wrap; } + .data-preview-grid { grid-template-columns: 1fr; } +} diff --git a/scripts/build-web-linux.sh b/scripts/build-web-linux.sh index 43f4565..e740d9f 100755 --- a/scripts/build-web-linux.sh +++ b/scripts/build-web-linux.sh @@ -3,14 +3,15 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BUILD_DIR="$ROOT_DIR/.builds/linux" -BACKEND_DIR="$BUILD_DIR/backend" +BACKEND_DIR="$BUILD_DIR/app" WEB_DIR="$BUILD_DIR/web_v1" +SITE_DIR="$BUILD_DIR/site" # Override GOARCH when building for another Linux architecture, for example arm64. GOARCH="${GOARCH:-amd64}" -rm -rf "$BACKEND_DIR" "$WEB_DIR" -mkdir -p "$BACKEND_DIR" "$WEB_DIR" +rm -rf "$BACKEND_DIR" "$WEB_DIR" "$SITE_DIR" +mkdir -p "$BACKEND_DIR" "$WEB_DIR" "$SITE_DIR" ( cd "$ROOT_DIR/backend" @@ -24,5 +25,8 @@ mkdir -p "$BACKEND_DIR" "$WEB_DIR" cp -R dist/. "$WEB_DIR/" ) +cp -R "$ROOT_DIR/apps/site/." "$SITE_DIR/" + echo "Linux backend: $BACKEND_DIR/senlin-agent-api" echo "Web build: $WEB_DIR" +echo "Official site: $SITE_DIR"