From ca071b14aca950f79ae84cd461046a7db75e21ce Mon Sep 17 00:00:00 2001 From: fylorn <249551762+fylorn@users.noreply.github.com> Date: Thu, 1 Oct 2026 12:05:25 +0800 Subject: [PATCH] Docs in the neon layout - Documentation home: a hero with search across every product, one tile per product with its docs, and the other resources as hairline columns. It drops the product bar, since the tiles lead to each product. - Product bar: the site's segmented control and a matching search box. - Sidebar and table of contents: the current page marked with the mark's cyan-to-magenta bar instead of cyan text; plain group labels. - Articles: a larger, tighter title with the first paragraph as a lede, h2 without rules, neutral inline code, notes without italics, tables in a rounded frame, code blocks with a title bar showing the language and the copy button, a last-updated and edit line, and the previous and next docs as tiles. - Product docs homes list their docs as numbered tiles. - The English documentation home now says ThinkWatch Enterprise uses four of the Core crates, as the Chinese one already did. Co-Authored-By: Claude Opus 5.5 --- src/layouts/DocsLayout.astro | 778 ++++++++++++++++++++----------- src/pages/docs/_DocArticle.astro | 59 ++- src/pages/docs/_DocsHome.astro | 231 ++++++--- src/styles/global.css | 44 +- 4 files changed, 757 insertions(+), 355 deletions(-) diff --git a/src/layouts/DocsLayout.astro b/src/layouts/DocsLayout.astro index 0deb5dc..681def7 100644 --- a/src/layouts/DocsLayout.astro +++ b/src/layouts/DocsLayout.astro @@ -3,6 +3,7 @@ import { productName } from "~/content/docs/_meta"; import Base from "./Base.astro"; import SiteHeader from "~/components/SiteHeader.astro"; import SiteFooter from "~/components/SiteFooter.astro"; +import NeonMotion from "~/components/NeonMotion.astro"; import { docHref, getProduct, @@ -41,6 +42,8 @@ interface Props { modified?: string; /** Where the page's text is edited, when not with the product's other docs */ editUrl?: string; + /** The documentation home: full width, no sidebar or table of contents, search across every product */ + hub?: boolean; } const { @@ -57,6 +60,7 @@ const { published, modified, editUrl, + hub = false, } = Astro.props; const lang = getLang(Astro); const zh = lang === "zh-CN"; @@ -81,9 +85,10 @@ const tocHeadings = headings .filter((h) => h.depth === 2 || h.depth === 3) .map((h) => ({ ...h, text: h.text.replace(/#+\s*$/, "").trim() })); -const itemBase = "flex items-center justify-between gap-2 rounded-lg px-3 text-[15px] transition-colors"; -const itemActive = "text-[var(--color-brand-1)] font-medium"; -const itemIdle = "text-[var(--color-text)]/80 hover:text-[var(--color-text)]"; +const navLabel = zh ? `${productName(p, lang)} 文档导航` : `${productName(p, lang)} documentation`; +const editLabel = zh ? "在 GitHub 上编辑" : "Edit on GitHub"; +const updated = modified?.slice(0, 10); +const updatedLabel = zh ? `最后更新于 ${updated}` : `Last updated ${updated}`; --- - -
-
-
- -
+ )} - {(prev || next) && ( - - )} - - - - {tocHeadings.length > 0 ? ( - + + + + + + {tocHeadings.length > 0 ? ( + + ) : } +
+ + )} +
+ @@ -424,22 +649,28 @@ const itemIdle = "text-[var(--color-text)]/80 hover:text-[var(--color-text)]"; diff --git a/src/pages/docs/_DocArticle.astro b/src/pages/docs/_DocArticle.astro index c4d32e1..20861b6 100644 --- a/src/pages/docs/_DocArticle.astro +++ b/src/pages/docs/_DocArticle.astro @@ -104,24 +104,59 @@ const homeCards = slug ? [] : p.docs.filter((d) => d.slug); {/* The "Import links" page ends with its link builder, which a markdown file cannot hold */} {product === "lite" && slug === "import-links" && } {synced && ( -

+

{zh ? "本页取自 ThinkWatch Core 仓库 " : "This page is published from "} {synced.source} {zh ? `(${synced.ref})。` : ` in the ThinkWatch Core repository, at ${synced.ref}.`}

)} {homeCards.length > 0 && ( -
- {homeCards.map((d) => ( - -
{d.label[lang]}
-

{d.summary?.[lang]}

-
- ))} -
+ )} + + diff --git a/src/pages/docs/_DocsHome.astro b/src/pages/docs/_DocsHome.astro index c61b777..27fa449 100644 --- a/src/pages/docs/_DocsHome.astro +++ b/src/pages/docs/_DocsHome.astro @@ -1,7 +1,8 @@ --- import { productName } from "~/content/docs/_meta"; -// Documentation home (/docs, /zh-CN/docs): intro, one card per product listing -// its docs. It is also ThinkWatch's docs home, so the sidebar shows ThinkWatch. +// Documentation home (/docs, /zh-CN/docs): a short hero with search across +// every product, one tile per product listing its docs, then other resources. +// It is also ThinkWatch Enterprise's docs home ("Overview" in its sidebar). import DocsLayout from "~/layouts/DocsLayout.astro"; import { docHref, products, productHomeHref } from "~/content/docs/_meta"; import { localePath, type Lang } from "~/i18n"; @@ -18,84 +19,210 @@ const copy = zh title: "文档 · ThinkWatch", description: "ThinkWatch 企业版、ThinkWatch Lite 与 ThinkWatch Core 的文档,涵盖架构、部署、配置、API 参考、安全模型、桌面应用与共享核心。", - h1: "文档", + label: "文档", + h1a: "ThinkWatch ", + h1b: "文档", intro: - "三个产品分别提供文档:面向组织的 ThinkWatch 企业版;桌面应用 ThinkWatch Lite,在本机运行网关,也可以连接服务器上的 ThinkWatch Core;以及 ThinkWatch Core,即 ThinkWatch Lite 所基于的网关引擎与 Rust crate,ThinkWatch 企业版也使用其中的四个 crate。可通过上方的切换器选择产品,或从下方卡片进入。", + "三个产品分别提供文档:面向组织的 ThinkWatch 企业版;桌面应用 ThinkWatch Lite,在本机运行网关,也可以连接服务器上的 ThinkWatch Core;以及 ThinkWatch Core,即 ThinkWatch Lite 所基于的网关引擎与 Rust crate,ThinkWatch 企业版也使用其中的四个 crate。", + search: "搜索全部文档", open: (name: string) => `进入 ${name} 文档`, more: "其他资源", + resources: [ + { href: "https://github.com/ThinkWatchProject", title: "GitHub", text: "三个产品的源码、Issues 与 Release。" }, + { href: localePath(lang, "/changelog"), title: "更新日志", text: "各发布版本的变更记录。" }, + { + href: "https://github.com/ThinkWatchProject/ThinkWatch/blob/main/LICENSING.md", + title: "LICENSING.md", + text: "ThinkWatch 企业版的生产环境阈值与商业授权。", + }, + ], } : { title: "Documentation · ThinkWatch", description: "Documentation for ThinkWatch Enterprise, ThinkWatch Lite, and ThinkWatch Core, covering architecture, deployment, configuration, API reference, the security model, the desktop application, and the shared core.", - h1: "Documentation", + label: "Documentation", + h1a: "ThinkWatch ", + h1b: "documentation", intro: - "Documentation is provided for three products: ThinkWatch Enterprise, for organizations; ThinkWatch Lite, a desktop application that runs the gateway locally or connects to ThinkWatch Core on a server; and ThinkWatch Core, the gateway engine and Rust crates that ThinkWatch Lite is built on, three of which ThinkWatch Enterprise also uses. Select a product with the switcher above or from the cards below.", + "Documentation is provided for three products: ThinkWatch Enterprise, for organizations; ThinkWatch Lite, a desktop application that runs the gateway locally or connects to ThinkWatch Core on a server; and ThinkWatch Core, the gateway engine and Rust crates that ThinkWatch Lite is built on, four of which ThinkWatch Enterprise also uses.", + search: "Search all docs", open: (name: string) => `Open ${name} docs`, more: "Additional resources", + resources: [ + { href: "https://github.com/ThinkWatchProject", title: "GitHub", text: "Source, issues and releases for all three products." }, + { href: localePath(lang, "/changelog"), title: "Changelog", text: "Release notes for each version." }, + { + href: "https://github.com/ThinkWatchProject/ThinkWatch/blob/main/LICENSING.md", + title: "LICENSING.md", + text: "Production thresholds and commercial tiers for ThinkWatch Enterprise.", + }, + ], }; --- - -

{copy.h1}

-

{copy.intro}

+ +
+

{copy.label}

+

{copy.h1a}{copy.h1b}

+

{copy.intro}

+ +
- -
-
- {products.map((p) => { +
+ {products.map((p, i) => { const docs = p.docs.filter((d) => d.slug); return ( -
-

- {productName(p, lang)} +
+

+ {productName(p, lang)}

-

{p.tagline[lang]}

-
); })}

-
-

{copy.more}

- {zh ? ( - - ) : ( - - )} -
-
+
+

{copy.more}

+
+ {copy.resources.map((r) => ( + + {r.title} + {r.text} + + ))} +
+
+ + diff --git a/src/styles/global.css b/src/styles/global.css index 41c52de..e3567ce 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -265,9 +265,13 @@ scroll-margin-top: 5rem; position: relative; } -.prose-tw h1 { font-size: 2.25rem; line-height: 1.15; margin-top: 0; margin-bottom: 0.5em; letter-spacing: -0.025em; } -.prose-tw h2 { font-size: 1.6rem; line-height: 1.25; margin-top: 2.4em; margin-bottom: 0.6em; padding-top: 1.4em; border-top: 1px solid rgba(255,255,255,0.06); } -.prose-tw h3 { font-size: 1.2rem; line-height: 1.35; margin-top: 1.9em; margin-bottom: 0.5em; } +.prose-tw h1 { font-size: clamp(2rem, 3.4vw, 2.75rem); line-height: 1.1; margin-top: 0; margin-bottom: 0.45em; letter-spacing: -0.035em; text-wrap: balance; } +:lang(zh-CN) .prose-tw h1 { line-height: 1.22; letter-spacing: -0.01em; } +/* The paragraph under the title reads as the page's lede */ +.prose-tw > h1 + p { font-size: 1.1rem; line-height: 1.7; color: var(--color-muted); } +.prose-tw h2 { font-size: 1.55rem; line-height: 1.25; margin-top: 2.6em; margin-bottom: 0.6em; letter-spacing: -0.025em; } +:lang(zh-CN) .prose-tw h2 { letter-spacing: -0.005em; } +.prose-tw h3 { font-size: 1.15rem; line-height: 1.35; margin-top: 2em; margin-bottom: 0.5em; } .prose-tw h4 { font-size: 1.0rem; line-height: 1.4; margin-top: 1.6em; margin-bottom: 0.4em; color: #e5e7eb; } .prose-tw p, @@ -297,16 +301,17 @@ .prose-tw ul { list-style: disc; } .prose-tw ol { list-style: decimal; } .prose-tw li { margin-top: 0.4em; } -.prose-tw li::marker { color: var(--color-brand-2); } +.prose-tw li::marker { color: var(--color-dim); } +/* A note: the mark's cyan as a rule down its side */ .prose-tw blockquote { - border-left: 2px solid var(--color-brand-2); - padding: 0.25em 0 0.25em 1em; - background: color-mix(in oklab, var(--color-brand-2) 5%, transparent); - border-radius: 0 8px 8px 0; - font-style: italic; + border-left: 2px solid rgb(var(--a1)); + padding: 0.8em 1.1em; + background: rgb(var(--a1) / 0.05); + border-radius: 0 10px 10px 0; } -.prose-tw blockquote p { color: #e5e7eb; } +.prose-tw blockquote p { color: #d4d7dc; } +.prose-tw blockquote > * + * { margin-top: 0.6em; } .prose-tw hr { border: 0; @@ -318,18 +323,18 @@ .prose-tw :not(pre) > code { font-family: var(--font-mono); font-size: 0.85em; - color: var(--color-brand-1); - background: rgba(34, 229, 242, 0.08); - border: 1px solid rgba(34, 229, 242, 0.2); + color: #e6e8eb; + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(255, 255, 255, 0.1); padding: 0.1em 0.4em; - border-radius: 4px; + border-radius: 5px; } /* Code blocks (Shiki output) */ .prose-tw pre.shiki, .prose-tw pre.astro-code { - background: #0c0d0f !important; - border: 1px solid rgba(255,255,255,0.08); + background: #0b0c0e !important; + border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; padding: 1.1rem 1.25rem; font-size: 0.81rem; @@ -358,6 +363,8 @@ .prose-tw .table-scroll { overflow-x: auto; margin: 1.5em 0; + border: 1px solid rgba(255,255,255,0.1); + border-radius: 12px; } .prose-tw .table-scroll > table { margin: 0; } @media (max-width: 40rem) { @@ -379,9 +386,10 @@ } .prose-tw td { padding: 0.6em 1em; - border-bottom: 1px solid rgba(255,255,255,0.05); + border-bottom: 1px solid rgba(255,255,255,0.06); color: #c3c7ce; } +.prose-tw tbody tr:last-child td { border-bottom: 0; } .prose-tw tr:hover td { background: rgba(255,255,255,0.02); } /* Heading anchor link (rehype-autolink-headings) */ @@ -402,7 +410,7 @@ /* Images */ .prose-tw img { max-width: 100%; - border-radius: 10px; + border-radius: 12px; border: 1px solid rgba(255,255,255,0.08); margin: 1.5em 0; }