// components-rest.jsx — Workflow, big Mockup (single image slot), Agent, CTA, FAQ, Footer
/* ───────────── Workflow ───────────── */
function FlowArrow() {
return (
);
}
function WorkflowDemoArt({ kind, lang }) {
if (kind === "write") {
const sample = lang === "zh"
? "他从怀里摸出一个油纸包,里面是半块"
: "He pulled a paper-wrapped half-cake from his ";
const highlight = lang === "zh" ? "干饼" : "sleeve";
const action = lang === "zh" ? "建为词条" : "Add to codex";
return (
{sample}
{highlight}
⌘ E · {action}
);
}
if (kind === "codex") {
return (
· {lang === "zh" ? "新建 · 物件" : "New · Object"}
{lang === "zh" ? "苦竹棒 · 江远舟" : "Bamboo staff · Jiang"}
{lang === "zh"
? "拇指粗的苦竹,经手工打磨。日常挑水砍柴用——但能承受兵刃撞击不折。"
: "A polished bamboo staff. For carrying water and chopping wood — yet it does not break against steel."}
{(lang === "zh" ? ["兵器", "代用品", "第 1 章"] : ["weapon", "stand-in", "ch.1"]).map((t, i) => (
{t}
))}
);
}
if (kind === "ref") {
return (
{lang === "zh" ? "他靠在墙边的 " : "He leaned the "}
{lang === "zh" ? "@苦竹棒" : "@bamboo-staff"}
{lang === "zh" ? ",没有起身。" : " against the wall, and did not stand."}
@ · {lang === "zh" ? "正在调用 1 条设定卡" : "1 codex card referenced"}
);
}
return null;
}
function WorkflowSection({ copy, lang }) {
const steps = copy.workflow.steps;
return (
{copy.workflow.eyebrow}
{copy.workflow.title}
{copy.workflow.kicker}
);
}
function FlowStep({ step, num, lang }) {
return (
{num}
{step.tag}
{step.h}
{step.p}
);
}
/* ───────────── BIG MOCKUP ───────────── */
function MockupSection({ copy, lang }) {
return (
{copy.mockup.eyebrow}
{copy.mockup.title}
{copy.mockup.kicker}
{lang === "zh"
? "设定库 / 雨中客 / 卷一 / 第 1 章 · 破庙夜雨"
: "Codex / Rainy Guest / Book I / Ch. 1 · Rain at the Temple"}
{copy.mockup.pins.map((p, i) => (
{String(i + 1).padStart(2, "0")}
{p.t}
))}
);
}
/* ───────────── AGENT SECTION ───────────── */
function AgentSection({ copy, lang }) {
return (
{copy.agent.eyebrow}
{copy.agent.title}
{copy.agent.kicker}
{copy.agent.bullets.map((b, i) => (
{b}
))}
);
}
function AgentChat({ copy, lang }) {
return (
{copy.agent.chat.map((c, i) => (
{c.text}
{c.refs && (
{c.refs.map((r, j) => {r} )}
)}
))}
);
}
/* ───────────── DOWNLOAD CTA ───────────── */
function ReleaseGlyph({ os }) {
// Minimal mono glyphs for each platform — drawn as text, not SVG icons.
// Kept understated so the brand stays paper-and-ink, not vendor logos.
const map = {
Windows: "WIN",
macOS: "MAC",
Linux: "TUX",
};
return {map[os] || os} ;
}
function ReleaseCard({ rel }) {
return (
{rel.os}
{rel.name}
);
}
function DownloadCTA({ copy }) {
return (
{copy.cta.eyebrow}
{copy.cta.title}
{copy.cta.kicker}
{copy.cta.releases && (
)}
{copy.cta.platforms.map((p, i) => (
{p}
))}
);
}
/* ───────────── FAQ ───────────── */
function FAQ({ copy }) {
return (
{copy.faq.eyebrow}
{copy.faq.title}
{copy.faq.items.map((it, i) => (
{it.q}
{it.a}
))}
);
}
/* ───────────── FOOTER ───────────── */
function FooterSocial({ name }) {
// Tiny inline SVG for each social — no clunky boxed labels.
const map = {
"微信": ,
"WeChat": ,
"微博": ,
"Weibo": ,
"X": ,
"GitHub": ,
"Gi": ,
};
return (
{map[name] || }
{name}
);
}
function Footer({ copy }) {
return (
{copy.foot.cols.map((col, i) => (
{col.title}
{col.links.map((l, j) => {l} )}
))}
{copy.foot.socialsLabel || "同行"}
{copy.foot.socials.map((s, i) => )}
);
}
Object.assign(window, {
FlowArrow, WorkflowSection, FlowStep, WorkflowDemoArt,
MockupSection,
AgentSection, AgentChat,
DownloadCTA, ReleaseCard, ReleaseGlyph, FAQ, Footer,
});