[teamai] Push 87 resource(s) from XingfenD

This commit is contained in:
2026-09-10 16:10:45 +08:00
parent 425c9c078a
commit 65c04def51
1314 changed files with 211681 additions and 0 deletions
@@ -0,0 +1 @@
registry=https://registry.npmjs.org/
@@ -0,0 +1,69 @@
import { Article, Hero, Lead, Raw } from "reacticle";
import { SectionOpening } from "./sections/01-opening";
// Article.tsx is the ASSEMBLER, owned by the main agent. It imports and orders
// Section components — it must NOT contain Section bodies inline.
//
// 铁律:每个 Section 是独立组件文件(article/sections/NN-*.tsx),坚决不允许把
// 多个 Section 直接写进这里。这样多个 Agent 才能并行各写一个 section 文件,主 Agent
// 在这里负责合并与稳定性。详见 references/section-build.md。
//
// width (narrow/regular/wide/full) + toc 在 Plan Checkpoint 确认,与主题解耦
// (见 references/layout.md)。
export function ArticleDoc() {
return (
<Article toc width="regular">
<Hero
title="文章标题"
subtitle="副标题:一句话框定这篇要解决什么"
meta={[{ label: "日期", value: "2026-06-08" }]}
/>
<Lead>导语:用一两句话框定主题与读者要带走的判断。</Lead>
<SectionOpening />
{/* 在此按顺序加入更多 section 组件:<SectionContext /> <SectionMechanism /> … */}
{/*
─── Colophon ───
每篇 Beautiful Article 必须保留这一段,位置在 </Article> 之前、所有 Section /
Conclusion 之后。它是文章的"印记",告诉读者文章是用什么工作流生成的。
约束:
• 不要删除。不要移到 Hero 旁边或浮动到角落。
• 文本格式固定:Made with beautiful-article(带链接到 github 仓库)· <主题> theme
• 主题名(下方 __THEME__ 占位)由 scaffold 写入;切换主题时同步更新这里和
main.tsx 的 <ThemeProvider theme="...">。
• 样式只能用 --ra-* token,跟随主题自适应;保持低对比、小字、居中。
*/}
<Raw title="">
<footer
style={{
marginTop: "var(--ra-space-7, 3rem)",
paddingTop: "var(--ra-space-4, 1rem)",
borderTop: "1px solid var(--ra-color-border, currentColor)",
color: "var(--ra-color-muted, inherit)",
fontSize: "var(--ra-text-xs, 0.78rem)",
textAlign: "center",
letterSpacing: "0.02em",
opacity: 0.85,
}}
>
Made with{" "}
<a
href="https://github.com/ConardLi/garden-skills"
target="_blank"
rel="noopener noreferrer"
style={{
color: "inherit",
textDecoration: "underline",
textUnderlineOffset: "0.2em",
}}
>
beautiful-article
</a>{" "}
· __THEME__ theme
</footer>
</Raw>
</Article>
);
}
@@ -0,0 +1,172 @@
// Cover.tsx —— 文章封面(独立于 Article,位于 TOC + 正文 + colophon 之上)
//
// 这一文件是 article-specific 的(跟 Article.tsx / sections/*.tsx 同等地位)。
// 主 Agent 在 Phase 4 First Spread 把下面的【封面内容区】替换成按 **主题 + 文章主旨**
// 定制的设计。**外壳(3:4 比例、定位、PDF 分页)不要动**。
//
// 硬约束(详见 references/cover.md):
// 1. **3:4 比例固定(屏幕 + PDF)**:不要改 aspectRatio;打印时 .ra-cover 会自动
// 独占首页,保持屏幕版 3:4 构图以避免 Chromium print 裁切内部布局。
// 让内部元素用百分比 / aspect-ratio / inset 自适应,不要写绝对 px 高度。
// 2. **图文并茂**:必须有视觉元素 + 简短文字(标题 + 可选副题 / 小标签)。
// **禁止纯文字封面**。视觉用什么技术由你选(见约束 5)。
// 3. **主题忠实**:颜色 / 字号 / 字重 / 边框 / 律动**只能用 `--ra-*` token**。
// 切主题时封面要跟随刷新;不要写死颜色 / 字体名 / 像素字号。
// 4. **内容忠实**:封面的视觉主图与文字要呼应正文主旨(看一眼能猜出文章是讲什么的)。
// 5. **技术自由**:内联 SVG / CSS 几何 / Canvas / 复杂 React 组件 / 字体艺术 / 多层
// gradient / mask / clip-path / 任意组合 —— 任选,最终效果好就行。**唯一禁止**:
// 远程图片(offline-first);base64 raster 仅当 Plan Checkpoint "配图模式" 是
// user-assets / ai-generated 才允许。
// 6. **封面不承担正文**:不要把 Lead 第一段、TOC、阅读时间塞进来 —— 封面只承担
// "识别 + 风格信号 + 引起阅读欲望",正文从下面的 Article 开始。
export function Cover() {
return (
<section
className="ra-cover"
aria-label="文章封面"
data-ra-cover=""
style={{
// ── 外壳(请不要动) ──
position: "relative",
width: "100%",
// 屏幕上像"一本立着的书":限宽 48rem(768px);同时**从视口高度反推宽度**
// (100vh - 8rem) * 3/4,确保整个 3:4 封面**一屏看全、不用下拉**。8rem
// (128px) 给顶栏 / 边距 / site nav 等留出充足呼吸(典型场景 site nav 60 +
// 容器顶 padding 32 + 边框 1 ≈ 93px,仍有 35px 余量)。
// 3:4 比例由 aspect-ratio 保证不破。
maxWidth: "min(100%, 48rem, calc((100vh - 8rem) * 3 / 4))",
margin: "0 auto var(--ra-space-7, 3rem) auto",
aspectRatio: "3 / 4",
overflow: "hidden",
// 背景透明:让外层 .ra-root / .gx-reader 的 --ra-color-bg "纸面色" 直接透上来。
// 整片视觉是一张连续的纸,封面不再"自带一块色"。封面的辨识度由内部插画 + 边框
// + 内容排版承担。如果你的封面**确实需要**整体着色(如孟菲斯主题大色块覆盖),
// 可以改成 surface / surface-2 / accent-soft 等任意主题 token。
background: "transparent",
color: "var(--ra-color-fg, inherit)",
borderRadius: "var(--ra-radius-md, 0)",
border: "1px solid var(--ra-color-border, currentColor)",
// 让 ::before 之类的几何装饰可以铺满
isolation: "isolate",
}}
>
{/*
─── 封面内容区 · 在这里写 ───
默认占位长这样:
• 一层主题感的几何装饰(SVG 网格 + 一个 accent 圆 + 描边斜线)
• 居中的占位标题、副题、小标签
构建时**替换为按文章 + 主题定制的封面**。占位是为了
"即使忘了替换,也不会渲染出一团乱",但**不能交付出去**。
*/}
<CoverPlaceholder />
</section>
);
}
// ────────────────────────────────────────────────────────────────────
// 占位实现 —— 主 Agent 把 <CoverPlaceholder /> 替换成本文真正的封面。
// 删掉这个 function 也行;保留它能让占位回退更友好。
// ────────────────────────────────────────────────────────────────────
function CoverPlaceholder() {
return (
<>
{/* 默认占位用了 SVG 是图省事,**不代表"应该用 SVG"** —— 你完全可以删掉这个
* <svg>,换成 CSS 渐变层、Canvas、复杂 React 组件、字体艺术拼贴等任何能产生
* 漂亮视觉的方式。视觉技术由你选,效果好就行。 */}
<svg
viewBox="0 0 1200 1600"
preserveAspectRatio="xMidYMid slice"
aria-hidden="true"
style={{
position: "absolute",
inset: 0,
width: "100%",
height: "100%",
color: "var(--ra-color-border, currentColor)",
opacity: 0.55,
zIndex: 0,
}}
>
<defs>
<pattern id="ra-cover-grid" width="80" height="80" patternUnits="userSpaceOnUse">
<path
d="M 80 0 L 0 0 0 80"
fill="none"
stroke="currentColor"
strokeWidth="0.6"
/>
</pattern>
</defs>
<rect width="1200" height="1600" fill="url(#ra-cover-grid)" />
<circle
cx="900"
cy="1180"
r="220"
fill="var(--ra-color-accent, currentColor)"
opacity="0.18"
/>
<line
x1="80"
y1="1400"
x2="560"
y2="1400"
stroke="currentColor"
strokeWidth="2"
/>
</svg>
{/* 文字层 */}
<div
style={{
position: "absolute",
inset: 0,
zIndex: 1,
display: "grid",
alignContent: "center",
justifyItems: "start",
padding:
"var(--ra-space-7, 3rem) var(--ra-space-8, 4rem) var(--ra-space-7, 3rem) var(--ra-space-8, 4rem)",
gap: "var(--ra-space-3, 0.75rem)",
}}
>
<span
style={{
fontSize: "var(--ra-text-xs, 0.75rem)",
letterSpacing: "0.22em",
textTransform: "uppercase",
color: "var(--ra-color-muted, inherit)",
opacity: 0.85,
}}
>
COVER · 3 : 4 · 占位
</span>
<h1
style={{
margin: 0,
fontSize: "clamp(1.6rem, 4.6vw, var(--ra-text-4xl, 3rem))",
lineHeight: 1.05,
fontWeight: "var(--ra-font-weight-bold, 700)",
color: "var(--ra-color-fg, inherit)",
maxWidth: "70%",
}}
>
按文章主旨 + 主题,在此处设计封面
</h1>
<p
style={{
margin: 0,
fontSize: "var(--ra-text-sm, 0.95rem)",
color: "var(--ra-color-muted, inherit)",
maxWidth: "70%",
lineHeight: 1.4,
}}
>
先读 <code>references/cover.md</code> 与选定主题的 <code>theme-profiles/&lt;id&gt;.md</code>,
再替换 <code>CoverPlaceholder</code> 为本文专属的图文构图。视觉用什么技术(SVG /
CSS / Canvas / 复杂 React 组件 / 任意混搭)由你选,效果好就行;唯一禁止远程图片。
</p>
</div>
</>
);
}
@@ -0,0 +1,26 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { ThemeProvider } from "reacticle";
import "reacticle/styles.css";
// __COVER_IMPORT_BEGIN__ (scaffold.sh 在 --no-cover 时剥掉这一段,连同标记)
import { Cover } from "./Cover";
// __COVER_IMPORT_END__
import { ArticleDoc } from "./Article";
// Entry for the self-contained single-file HTML build.
// Theme is fixed here — change `theme` (must be a registered reacticle theme id:
// "tufte" | "press" | …) to switch the whole look.
//
// 渲染顺序:Cover(封面,可选)→ ArticleDoc(含 TOC + 正文 + colophon)。
// Cover 故意**不**塞进 <Article> 内部(那样会被挤到正文栏旁边),而是和 <ArticleDoc/>
// 在 ThemeProvider 下做兄弟,DOM 顺序天然就是「封面 → TOC → 正文 → colophon」。
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ThemeProvider theme="__THEME__">
{/* __COVER_RENDER_BEGIN__ (scaffold.sh 在 --no-cover 时剥掉这一段,连同标记) */}
<Cover />
{/* __COVER_RENDER_END__ */}
<ArticleDoc />
</ThemeProvider>
</StrictMode>
);
@@ -0,0 +1,30 @@
import { Section, Aside, Raw } from "reacticle";
// One Section per file. In parallel builds a single subagent owns this file and
// must not touch Article.tsx or other section files. See references/section-build.md.
//
// Rules of thumb (references/component-policy.md + raw-policy.md):
// - Prose is the body. Write paragraphs as <Section> children.
// - Semantic components (Aside / Quote / Table / RiskList ...) are accents.
// - Raw is freely used but hand-authored for THIS section, token-driven.
export function SectionOpening() {
return (
<Section index="01" title="第一节">
<p>正文段落用 children —— 这应是文章主体,尽量多写正文,把背景、推理、结论讲清楚。</p>
<p>再写一段,保持阅读节奏。语义组件只在内容确实"是"那个结构时才用。</p>
<Aside tone="principle" label="核心判断">一句话的核心判断,给本节点睛。</Aside>
<Raw title="为本段现写的内联 SVG(用主题 token 取色)">
<svg viewBox="0 0 240 60" width="100%">
<polyline
points="0,50 40,42 80,46 120,20 160,28 200,8 240,14"
fill="none"
stroke="var(--ra-color-accent)"
strokeWidth="2"
/>
</svg>
</Raw>
</Section>
);
}
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Beautiful Article</title>
<!-- Theme fonts. tufte falls back to Georgia; press uses Newsreader. -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,500&family=Source+Serif+4:opsz,wght@8..60,400&family=JetBrains+Mono:wght@400;500&display=swap"
rel="stylesheet"
/>
</head>
<body>
<div id="root"></div>
<script type="module" src="/article/main.tsx"></script>
</body>
</html>
@@ -0,0 +1,26 @@
{
"name": "beautiful-article-workspace",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"html": "npm run build && node -e \"require('fs').mkdirSync('article',{recursive:true});require('fs').copyFileSync('dist/index.html','article/article.html');console.log('built article/article.html')\"",
"typecheck": "tsc --noEmit",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"reacticle": "latest"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "^5.6.3",
"vite": "^5.4.11",
"vite-plugin-singlefile": "^2.0.3"
}
}
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["article"]
}
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}
@@ -0,0 +1,18 @@
import { resolve } from "node:path";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { viteSingleFile } from "vite-plugin-singlefile";
// reacticle is consumed from the published npm package (see package.json).
// Builds a self-contained single-page HTML (CSS + JS inlined, opens offline)
// to dist/index.html. `npm run html` then copies it to article/article.html.
export default defineConfig({
plugins: [react(), viteSingleFile()],
build: {
outDir: "dist",
emptyOutDir: true,
rollupOptions: {
input: resolve(__dirname, "index.html"),
},
},
});