dsh-plugin-deck-studio 0.0.0-stage → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -2
  3. package/client.js +500 -0
  4. package/cordis.example.yml +163 -0
  5. package/cordis.patch.yml +147 -0
  6. package/index.js +2340 -0
  7. package/lib/config.js +204 -0
  8. package/lib/content-density.js +98 -0
  9. package/lib/deck-brief.js +87 -0
  10. package/lib/deck-docs.js +1095 -0
  11. package/lib/deck-rules.js +124 -0
  12. package/lib/deck-templates.js +149 -0
  13. package/lib/deck-workspace.js +480 -0
  14. package/lib/design-style.js +157 -0
  15. package/lib/designs.js +175 -0
  16. package/lib/diff.js +88 -0
  17. package/lib/exporter.js +336 -0
  18. package/lib/faq.js +300 -0
  19. package/lib/git-commit.js +87 -0
  20. package/lib/home-catalog.js +249 -0
  21. package/lib/png.js +275 -0
  22. package/lib/proposal-decision.js +204 -0
  23. package/lib/render-nodes.js +171 -0
  24. package/lib/render-settings.js +213 -0
  25. package/lib/render.js +287 -0
  26. package/lib/review-personas.js +258 -0
  27. package/lib/script-style.js +55 -0
  28. package/lib/script-writer.js +165 -0
  29. package/lib/source-adapter.js +327 -0
  30. package/lib/store.js +212 -0
  31. package/lib/tools.js +2594 -0
  32. package/lib/watermark.js +137 -0
  33. package/package.json +66 -4
  34. package/seeds/resources/deckline-logo.png +0 -0
  35. package/seeds/resources/deckline-logo.svg +12 -0
  36. package/seeds/resources/deckline-mark.png +0 -0
  37. package/seeds/resources/index.json +19 -0
  38. package/seeds/samples/BIZ-01.jpg +0 -0
  39. package/seeds/samples/BIZ-02.jpg +0 -0
  40. package/seeds/samples/BIZ-03.jpg +0 -0
  41. package/seeds/samples/EDT-01.jpg +0 -0
  42. package/seeds/samples/EDT-02.jpg +0 -0
  43. package/seeds/samples/EDT-03.jpg +0 -0
  44. package/seeds/samples/FYI-01.jpg +0 -0
  45. package/seeds/samples/FYI-02.jpg +0 -0
  46. package/seeds/samples/FYI-03.jpg +0 -0
  47. package/seeds/samples/GRD-01.jpg +0 -0
  48. package/seeds/samples/GRD-02.jpg +0 -0
  49. package/seeds/samples/GRD-03.jpg +0 -0
  50. package/seeds/samples/JPN-01.jpg +0 -0
  51. package/seeds/samples/JPN-02.jpg +0 -0
  52. package/seeds/samples/JPN-03.jpg +0 -0
  53. package/seeds/samples/SKT-01.jpg +0 -0
  54. package/seeds/samples/SKT-02.jpg +0 -0
  55. package/seeds/samples/SKT-03.jpg +0 -0
  56. package/seeds/samples/SWS-01.jpg +0 -0
  57. package/seeds/samples/SWS-02.jpg +0 -0
  58. package/seeds/samples/SWS-03.jpg +0 -0
  59. package/seeds/samples/TEC-01.jpg +0 -0
  60. package/seeds/samples/TEC-02.jpg +0 -0
  61. package/seeds/samples/TEC-03.jpg +0 -0
  62. package/seeds/styles/BIZ.json +22 -0
  63. package/seeds/styles/EDT.json +22 -0
  64. package/seeds/styles/FYI.json +22 -0
  65. package/seeds/styles/GRD.json +22 -0
  66. package/seeds/styles/JPN.json +22 -0
  67. package/seeds/styles/SKT.json +22 -0
  68. package/seeds/styles/SWS.json +22 -0
  69. package/seeds/styles/TEC.json +22 -0
  70. package/ui/logo.svg +20 -0
  71. package/ui/workbench.css +687 -0
  72. package/ui/workbench.html +4554 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Logo 水印(F-125):assets 分类 → 列举可选水印 → 给整份 deck 的页面盖 logo。
3
+ *
4
+ * 负责人口径(2026-10-23):
5
+ * - assets 里按分类放素材,至少有一类 `logo`,可以放多个;
6
+ * - 用户跟 Agent 说「我要加水印」,能选哪个 logo;默认盖 **右上角**;
7
+ * - 每个页面都盖;原图不覆盖——水印产物写新的 revision(vNNN),旧图保留。
8
+ *
9
+ * 实现:纯 node(zlib)自己解 / 编 PNG(见 lib/png.js),不引 sharp/canvas。
10
+ * 页面图与 logo 都必须是 PNG;SVG logo 会明确提示先转 PNG,而不是静默跳过。
11
+ *
12
+ * @module dsh-plugin-deck-studio/watermark
13
+ */
14
+
15
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
16
+ import { basename, extname, join, relative } from "node:path";
17
+ import { compositeLogo, decodePng, encodePng } from "./png.js";
18
+
19
+ /** 水印位置(默认右上角)。 */
20
+ export const WATERMARK_POSITIONS = ["top-right", "top-left", "bottom-right", "bottom-left", "center"];
21
+
22
+ export const WATERMARK_POSITION_LABELS = {
23
+ "top-right": "右上角(默认)",
24
+ "top-left": "左上角",
25
+ "bottom-right": "右下角",
26
+ "bottom-left": "左下角",
27
+ center: "居中",
28
+ };
29
+
30
+ const IMAGE_EXTS = new Set([".png", ".jpg", ".jpeg", ".svg"]);
31
+
32
+ /** 资产分类根目录:仓库 `assets/`(按子目录分类,如 logo/)。 */
33
+ export function assetsRootOf(repoRoot) {
34
+ return join(repoRoot, "assets");
35
+ }
36
+
37
+ /**
38
+ * 扫描 assets/ 下的分类与素材。
39
+ * @returns {{categories: Array<{category: string, items: Array<{id: string, name: string, category: string, format: string, bytes: number, path: string, watermarkable: boolean}>}>}}
40
+ */
41
+ export function listAssets(repoRoot) {
42
+ const root = assetsRootOf(repoRoot);
43
+ if (!existsSync(root)) return { categories: [], root };
44
+ const categories = [];
45
+ for (const entry of readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
46
+ if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
47
+ const dir = join(root, entry.name);
48
+ const items = [];
49
+ for (const file of readdirSync(dir).sort()) {
50
+ const ext = extname(file).toLowerCase();
51
+ if (!IMAGE_EXTS.has(ext) || file.startsWith(".")) continue;
52
+ const path = join(dir, file);
53
+ const stat = statSync(path);
54
+ if (!stat.isFile()) continue;
55
+ items.push({
56
+ id: `${entry.name}/${file}`,
57
+ name: file,
58
+ category: entry.name,
59
+ format: ext.replace(".", ""),
60
+ bytes: stat.size,
61
+ path,
62
+ // 只有 PNG 能直接合成(zlib 自己解);SVG/JPG 明确提示先转 PNG。
63
+ watermarkable: ext === ".png",
64
+ });
65
+ }
66
+ if (items.length) categories.push({ category: entry.name, items });
67
+ }
68
+ return { categories, root };
69
+ }
70
+
71
+ /** 支持做水印的素材(PNG),供 Agent 选择。 */
72
+ export function listWatermarkAssets(repoRoot) {
73
+ const { categories, root } = listAssets(repoRoot);
74
+ const items = categories.flatMap((category) => category.items).filter((item) => item.watermarkable);
75
+ return { root, categories, items };
76
+ }
77
+
78
+ /**
79
+ * 按 Agent 给的名字找素材:id(logo/x.png)/ 文件名(x.png)/ 基名(x)都可以;
80
+ * 找不到或有歧义都返回候选,让 Agent 能自己纠正而不是瞎猜。
81
+ */
82
+ export function findAsset(repoRoot, query) {
83
+ // 找素材时把 SVG/JPG 也算进来:用户报了 SVG 名字时要能明确说「需要先转 PNG」,
84
+ // 而不是回一句「没找到」。
85
+ const { categories } = listAssets(repoRoot);
86
+ const items = categories.flatMap((category) => category.items);
87
+ const raw = String(query ?? "").trim();
88
+ if (!raw) return { ok: false, reason: "empty", candidates: items };
89
+ const needle = raw.toLowerCase().replace(/\\/g, "/");
90
+ const qualified = needle.includes("/") ? needle : null;
91
+ const matches = items.filter((item) => {
92
+ const id = item.id.toLowerCase();
93
+ const name = item.name.toLowerCase();
94
+ const stem = name.replace(/\.[^.]+$/, "");
95
+ if (qualified) return id === qualified || id.endsWith(`/${qualified}`);
96
+ return name === needle || stem === needle || id === needle;
97
+ });
98
+ if (matches.length === 1) return { ok: true, asset: matches[0] };
99
+ if (matches.length > 1) return { ok: false, reason: "ambiguous", candidates: matches };
100
+ // 宽松兜底:唯一子串命中
101
+ const loose = items.filter((item) => item.id.toLowerCase().includes(needle) || item.name.toLowerCase().includes(needle));
102
+ if (loose.length === 1) return { ok: true, asset: loose[0] };
103
+ if (loose.length > 1) return { ok: false, reason: "ambiguous", candidates: loose };
104
+ return { ok: false, reason: "not-found", candidates: items };
105
+ }
106
+
107
+ /** 把一张页面 PNG + logo PNG 合成水印后的 PNG Buffer。 */
108
+ export function watermarkPng({ pageBuffer, logoBuffer, position = "top-right", opacity = 0.85, scale = 0.14, margin = 0.04 }) {
109
+ const page = decodePng(pageBuffer);
110
+ const logo = decodePng(logoBuffer);
111
+ const { image, placement } = compositeLogo({ page, logo, position, opacity, scale, margin });
112
+ return { buffer: encodePng(image), size: `${image.width}x${image.height}`, placement };
113
+ }
114
+
115
+ /** 给 Agent 看的一行位置说明。 */
116
+ export function positionLine() {
117
+ return WATERMARK_POSITIONS.map((key) => `${key}(${WATERMARK_POSITION_LABELS[key]})`).join(" / ");
118
+ }
119
+
120
+ /** 报告里用的相对路径(不把本机绝对路径泄给用户/Agent)。 */
121
+ export function displayPath(repoRoot, path) {
122
+ try {
123
+ const rel = relative(repoRoot, path);
124
+ return rel.startsWith("..") ? basename(path) : rel;
125
+ } catch {
126
+ return basename(path);
127
+ }
128
+ }
129
+
130
+ /** 读 PNG 文件(水印流程用,统一错误文案)。 */
131
+ export function readPngFile(path) {
132
+ const buffer = readFileSync(path);
133
+ if (!buffer.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {
134
+ throw new Error(`不是 PNG:${basename(path)}`);
135
+ }
136
+ return buffer;
137
+ }
package/package.json CHANGED
@@ -1,6 +1,68 @@
1
1
  {
2
2
  "name": "dsh-plugin-deck-studio",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.2",
4
+ "private": false,
5
+ "description": "Deckline:DSH image deck 工作台插件 —— 原生 Chat + 整页图片 deck 工作区 + 设计风格(design)库;出图按页留痕、可点名批量连出,产物本地可追踪。",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./index.js",
9
+ "exports": {
10
+ ".": "./index.js",
11
+ "./client": "./client.js",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "keywords": [
15
+ "dsh",
16
+ "dsh-plugin",
17
+ "deepseek-harness",
18
+ "deck",
19
+ "image-deck",
20
+ "presentation",
21
+ "slides",
22
+ "deckline"
23
+ ],
24
+ "engines": {
25
+ "node": "^22.19.0 || >=24.0.0",
26
+ "dsh": ">=0.1.7-0 <0.3.0"
27
+ },
28
+ "scripts": {
29
+ "verify": "node verify/smoke.mjs",
30
+ "prepublishOnly": "node verify/smoke.mjs"
31
+ },
32
+ "dsh": {
33
+ "bundle": {
34
+ "patch": "./cordis.patch.yml"
35
+ },
36
+ "client": {
37
+ "platform": "web",
38
+ "immediately": true,
39
+ "inject": [
40
+ "renderer",
41
+ "layout",
42
+ "sidebar"
43
+ ]
44
+ }
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/yuna78/dsh-deck-studio.git",
49
+ "directory": "plugin/deck-studio"
50
+ },
51
+ "homepage": "https://github.com/yuna78/dsh-deck-studio#readme",
52
+ "bugs": {
53
+ "url": "https://github.com/yuna78/dsh-deck-studio/issues"
54
+ },
55
+ "peerDependencies": {
56
+ "@deepseek-ai/dsh": ">=0.1.7-0 <0.2.0 || >=0.2.0-0 <0.3.0 || >=0.2.1-0 <0.3.0"
57
+ },
58
+ "author": "Yuna",
59
+ "files": [
60
+ "index.js",
61
+ "client.js",
62
+ "lib/",
63
+ "ui/",
64
+ "seeds/",
65
+ "cordis.patch.yml",
66
+ "cordis.example.yml"
67
+ ]
68
+ }
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 392 96" width="392" height="96" role="img" aria-label="Deckline">
2
+ <rect width="96" height="96" rx="22" fill="#0c4651"/>
3
+ <g fill="none" stroke-linejoin="round">
4
+ <path d="M28 66V38c0-3 2-5 5-5h26c3 0 5 2 5 5v28" stroke="#faf8f2" stroke-width="4.5" stroke-linecap="round"/>
5
+ <path d="M38 30V24c0-2 1.5-3.5 3.5-3.5h22c2 0 3.5 1.5 3.5 3.5v28" stroke="#1496a8" stroke-width="4" stroke-linecap="round" opacity=".9"/>
6
+ <path d="M37 47h17" stroke="#faf8f2" stroke-width="4" stroke-linecap="round"/>
7
+ <path d="M37 56h11" stroke="#c5882f" stroke-width="4" stroke-linecap="round"/>
8
+ </g>
9
+ <circle cx="63" cy="60" r="5.5" fill="#c5882f"/>
10
+ <text x="116" y="58" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif" font-size="34" font-weight="650" fill="#0c4651" letter-spacing=".5">Deckline</text>
11
+ <text x="117" y="78" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif" fill="#5d777b" letter-spacing="1.8" font-size="10.5">IMAGE DECK STUDIO · DSH PLUGIN</text>
12
+ </svg>
@@ -0,0 +1,19 @@
1
+ {
2
+ "items": [
3
+ {
4
+ "name": "deckline-logo",
5
+ "file": "deckline-logo.png",
6
+ "description": "Deckline 字标(横版,透明底)"
7
+ },
8
+ {
9
+ "name": "deckline-logo-svg",
10
+ "file": "deckline-logo.svg",
11
+ "description": "Deckline 字标矢量版"
12
+ },
13
+ {
14
+ "name": "deckline-mark",
15
+ "file": "deckline-mark.png",
16
+ "description": "Deckline 图标(方形)"
17
+ }
18
+ ]
19
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "BIZ",
3
+ "name": "商务咨询(蓝灰)",
4
+ "description": "顶级咨询公司信息页:白底、深海军蓝与灰蓝主色、少量暖橙强调;细线表格、三栏框架图、数据图卡;字号层级克制、留白充足;专业、可信、可打印。",
5
+ "constraints": "不要深色背景、不要霓虹渐变、不要 3D、不要卡通插画、不要照片拼贴、不要阴影与投影、不要圆角大卡片、不要彩色斑块;不要超过一处暖橙强调;行动标题不要写成栏目名或口号;不要在 prompt 里出现任何机构或客户品牌名(统一写作「顶级战略咨询机构提案质感」)。",
6
+ "reference": "McKinsey / BCG 提案页风格",
7
+ "styleBrief": "商务咨询信息页(顶级战略咨询机构提案质感):纯白纸面 #FFFFFF。主色深海军蓝 #1F3864(标题与正文),次级灰蓝 #5B7DB1(说明与次级信息),分隔线浅灰蓝 #A9B8CC;暖橙 #D97A2B 只作单一强调点(关键数字 / 推荐项 / 箭头),占画面面积 ≤5%,每页只强调一处。所有笔触为 0.5–1px 细线:表格横线、三栏分隔、连接线都锐利干净,表头底线可略加粗,不堆叠竖线。16:9 信息页结构:左上角小号章节标签 + 一行行动标题(结论句,深海军蓝,克制字号)+ 主图或主表(细线表格 / 三栏框架 / 数据图卡 / 极简柱状图)+ 右下小字口径注释 + 页脚来源与页码。字号 4 级(章节标签 / 行动标题 / 分组小标题 / 正文注释),留白充足,信息密度中高,一页只讲一个论点。专业、可信、可打印;无阴影、无渐变、无圆角大卡。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面 / 章节页",
11
+ "brief": "白底咨询封面页:左上角小号章节标签「FRAMEWORK」;中央两行深海军蓝大标题(12 字内),标题下一道 0.5px 细线;底部一行两段小字说明与页码;右侧大面积留白,只用一枚暖橙细线箭头或小色块作唯一强调。"
12
+ },
13
+ {
14
+ "title": "三栏框架页",
15
+ "brief": "白底三栏框架页:一行结论式行动标题;主区三栏等宽,每栏顶部灰蓝色细线框标题、下面 3 条短条目,条目间 0.5px 浅灰蓝横线,不堆叠竖线;第三栏顶部加一枚暖橙圆点强调;底部一行小字口径说明与页脚来源页码。"
16
+ },
17
+ {
18
+ "title": "数据图卡页",
19
+ "brief": "白底数据页:一行带数字的结论式行动标题;上方 3 张并排数据卡(超大号深海军蓝数字 + 一行灰蓝说明 + 极细上边线,无边框无阴影);下方极简柱状图(只有水平细基线,柱体深浅蓝灰分层,关键一根暖橙,无网格无图例框);右下小字口径注释与页脚来源页码。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "EDT",
3
+ "name": "杂志编辑(衬线大标题)",
4
+ "description": "杂志/画册编辑风:奶油白底、粗衬线大标题、严格栅格、大号引文、黑色正文与朱红强调、细线分隔;版面有节奏、可读性强。",
5
+ "constraints": "不要卡通、不要渐变、不要 3D、不要贴纸元素、不要密集数据表、不要高饱和荧光色、不要出现真实品牌 logo 或人物照片。",
6
+ "reference": "Monocle / Kinfolk 版式",
7
+ "styleBrief": "杂志编辑排版(Monocle / Kinfolk 纸刊质感):奶油白纸底 #FBF7EF,无渐变、无阴影。标题用粗重衬线大字(宋体 / 明朝体方向的 display serif),黑色 #1A1A1A 与朱红 #C0392B 两个颜色做视觉节奏;小标签用全大写字母 + 加宽字距 + 细字重。严格栅格:大标题常压左侧 2/3,右侧放一张低饱和建筑或纸感照片(无人、无品牌);下方细线分隔、大号引文(带超大引号、可朱红)、三栏编号 01/02/03 短段落。装饰只用几何色块(圆弧 / 半圆 / 三角)与细线,不用插画和 3D。信息密度中低,留白大,编辑节奏强。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面",
11
+ "brief": "奶油白纸刊封面:左侧两行粗衬线大标题(第一行黑色、第二行朱红,12 字内),标题上方一行加宽字距全大写小标签;右侧一张低饱和建筑 / 纸面照片(无人);左下大号朱红引文与两行导语;底部细线与页码。"
12
+ },
13
+ {
14
+ "title": "双栏文章页",
15
+ "brief": "奶油白内容页:左侧超大字号的朱红引号与一段引文(3–5 字朱红强调)+ 两行导语;右侧两栏小字号黑体正文(行距松),栏间 0.5px 细线;页脚一行页码与栏目名;整页只用一个几何色块作装饰。"
16
+ },
17
+ {
18
+ "title": "三栏编号页",
19
+ "brief": "奶油白三栏页:顶部一行粗衬线标题 + 一行加宽字距小标签;下方 01/02/03 三栏,每栏顶部朱红编号与加粗小标题、一段 2–3 行正文,栏间 0.5px 细线;底部细线与页码,留白充足。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "FYI",
3
+ "name": "高端深色(玻璃质感)",
4
+ "description": "深色高端发布会风格:近黑炭底、半透明玻璃面板、紫青极光渐变、细发光线条、金色点缀;大标题居中或左对齐,信息面板悬浮;有电影感与高级感。",
5
+ "constraints": "不要白底、不要卡通、不要密集小字、不要廉价渐变、不要照片人物、不要彩色图标堆叠、不要出现真实公司 logo。",
6
+ "reference": "Apple 发布会 / 高端 SaaS keynote",
7
+ "styleBrief": "高端深色 keynote(发布会质感):近黑炭底 #0B0F14,半透明玻璃拟态面板(1px 内发光细边 + 轻微模糊),背景紫青极光渐变光晕(紫 #7C4DFF / 青 #22D3EE,低透明度),香槟金 #D4AF7A 只用于数字和细线。标题用优雅衬线大字(白色),小标签用全大写加宽字距的金色细字。信息块少而大:并排玻璃卡片,卡内超大金色数字 + 一行说明 + 极简发光折线;底部细金线与页码点。整体电影感、深色、留白大、无杂色、无照片人物。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面",
11
+ "brief": "近黑 keynote 封面:中央两行白色衬线大标题(12 字内,第二行可香槟金),上方一枚金色细短线;背景紫青极光光晕与玻璃拟态几何面板;底部三个小圆点页码与细金线。"
12
+ },
13
+ {
14
+ "title": "双玻璃数据卡",
15
+ "brief": "近黑深色页:左上小号金色标签 + 一行白色标题;中部两个并列玻璃拟态卡片,各含全大写金色小标签、超大金色数字(如 +42%)、一行白色说明、极细发光折线;背景紫青光晕;底部细线与页码。"
16
+ },
17
+ {
18
+ "title": "特性 / 路线页",
19
+ "brief": "近黑深色页:一行白色标题;下方三个玻璃拟态特性卡横排(细线图标 + 金色小标题 + 两行说明),或一条金色细线时间轴带 4 个发光节点与白色小标签;背景极光暗光晕,留白大。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "GRD",
3
+ "name": "渐变极光(深色玻璃 · 编辑感)",
4
+ "description": "深色编辑风:近黑炭底 + 紫青极光丝带 + 玻璃圆角面板 + 香槟金细线;标题居左、中文大字重、留白大;克制、昂贵、有编辑感。",
5
+ "constraints": "不要 3D 球体/环、不要满屏高饱和渐变、不要英文营销 slogan/假数字、不要照片/写实人物、不要卡通插画、不要密集小字、不要商务蓝灰模板感、不要真实品牌 logo。",
6
+ "reference": "Linear / Vercel 官网视觉",
7
+ "styleBrief": "深色玻璃极光(编辑感):近黑炭底 #0B0F12,四角更深;一条紫 #7C3AED 到青 #22D3EE 的低饱和极光丝带从左下向右上缓慢流动,边缘柔化、不刺眼;玻璃质感圆角面板(半透明深色 + 1px 浅白描边 + 轻模糊 + 深投影)承载内容;香槟金 #D8B26A 极细弧线与短线做点缀(0.5–1px);标题居左、白色无衬线大字重,副标题白色 70%;信息块少而整(1–3 块),中文为主,留白大、层级清楚;整体克制、昂贵、有编辑感。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面",
11
+ "brief": "深色极光封面:居左两行白色无衬线大字标题(第二行香槟金),下方一行白色 70% 副标题;右侧一张玻璃面板内三行中文要点,各配细线图标;紫青极光自左下向右上流动,一条香槟金细弧线穿过标题区;左下角一行小字署名。"
12
+ },
13
+ {
14
+ "title": "三栏内容",
15
+ "brief": "深色内容页:顶部一行白色标题 + 一行白色 70% 副标题;中部三张并排玻璃卡片,各含细线图标、中文短标题、两行中文说明,卡片间以香槟金细线连接;背景极光克制、右上角弱光晕;底部一行小字页码。"
16
+ },
17
+ {
18
+ "title": "对比 / 矩阵",
19
+ "brief": "深色对比页:顶部一行白色标题;中部两列玻璃面板对照(左「现在」右「之后」),每列 3 条中文短句、细线分隔,列间一条香槟金细线;背景极光只在边缘,信息区干净。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "JPN",
3
+ "name": "日系极简(纸感)",
4
+ "description": "日系纸感极简:米白/浅砂纸底、低饱和藏青与朱色点缀、细小宋体/明朝体标题、细线框、大量留白;版面安静、克制、有呼吸感。",
5
+ "constraints": "不要高饱和、不要渐变、不要 3D、不要大色块、不要卡通、不要粗黑体大字、不要阴影。",
6
+ "reference": "無印良品 / 日本杂志内页",
7
+ "styleBrief": "日系极简纸感:米白和纸底 #F7F3EA(可有极细纸纹),低饱和藏青 #2E4057 作文字与细线框,朱色 #B85C4A 只作极小点缀(短线 / 小圆点 / 一个词)。标题用细字重明朝体 / 宋体,字号不大、字距略松;正文小字号、行距大。版面大量留白:常见结构是左上两行主标题 + 右上角落款小字,下方 3 个细线框卡片(01/02/03 + 居中细线图形 + 加宽字距英文小标题 + 两行说明)。装饰只用细线、圆、半圆、斜线排线;绝不渐变 / 3D / 大色块 / 插画。安静、克制、有呼吸感。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面",
11
+ "brief": "米白和纸底封面:左上两行细明朝体标题(藏青,第一行 8–10 字、第二行略小),标题下一行加宽字距全大写小标签;右上角两行朱色小字注记与一枚朱色短横线;页面下部大面积留白,右下角细线与页码。"
12
+ },
13
+ {
14
+ "title": "三卡片页",
15
+ "brief": "米白纸感页:上方一行藏青细明朝体标题 + 一行灰蓝色小标签;下方三个等宽细线框卡片,每张顶部 01/02/03 小数字、中间极简细线图形(圆 / 双圆交叠 / 阶梯柱)、下方加宽字距英文小标题与两行小字说明;卡片间留白充足,无阴影。"
16
+ },
17
+ {
18
+ "title": "单栏留白页",
19
+ "brief": "米白纸感页:左侧一列窄栏(占 1/3):细明朝体标题两行 + 一段 4–5 行小字正文 + 朱色短线;右侧大面积留白,仅一枚极细线圆或斜线排线图形;底部细线与页码。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "SKT",
3
+ "name": "手绘白板(工作坊)",
4
+ "description": "工作坊手绘白板风:白板白底、马克笔手绘线、便签、箭头、手写感标题、蓝绿橙三色高亮;轻松、可参与、适合研讨。",
5
+ "constraints": "不要照片、不要 3D、不要渐变、不要商业模板感、不要密集小字、不要写实人物。",
6
+ "reference": "白板工作坊 / sketchnote",
7
+ "styleBrief": "手绘白板工作坊:白板白底 #FFFFFF,马克笔线条(深蓝 #1F4E9C、绿 #2E8B57、橙 #E67E22 三色),线条略抖有手感、末端圆润;标题用手写马克笔大字(可带下划线 / 底色块),小标签用全大写手写体。信息结构用便签(黄 / 浅绿 / 浅蓝)、箭头、圆形序号、简单手绘图标(灯泡 / 靶心 / 齿轮 / 对话框 / 小人 / 阶梯)。不用照片、不用 3D、不用渐变;版面轻松、可参与、留白够,适合研讨。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "三段流程",
11
+ "brief": "白板手绘页:顶部手写马克笔大标题(深蓝,下面一道蓝色手绘下划线);主区三段横向流程,每段圆形序号 1/2/3 + 绿色 / 橙色手绘小标题 + 一行副标题,段内 2–3 条手绘圆点条目与 2–3 张黄 / 绿便签,段间橙色手绘箭头连接;底部一条手绘「Outcome」横条与 3 个手绘图标小结果。"
12
+ },
13
+ {
14
+ "title": "四步工作坊流程",
15
+ "brief": "白板手绘页:顶部手写大标题「WORKSHOP FLOW」与两侧手绘短线;中部四个略微倾斜的手绘方框横向排列(浅蓝 / 浅绿 / 浅绿 / 浅橙底),每框一个手绘图标(地图定位 / 对话小人 / 灯泡 / 清单)与手写标签,框间绿色与橙色手绘箭头;底部一条橙色手绘弧形箭头贯穿。"
16
+ },
17
+ {
18
+ "title": "2×2 象限",
19
+ "brief": "白板手绘页:顶部手写大标题与右侧手绘椭圆注记;主区 2×2 象限,用深蓝手绘细线分四格,每格圆形序号 1–4 + 手写小标题 + 一个手绘图标 + 2–3 张彩色便签;底部两个手绘椭圆「CONSENSUS → TO VALIDATE」用橙绿箭头连接。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "SWS",
3
+ "name": "瑞士极简(黑白红)",
4
+ "description": "瑞士国际主义风格:纯白底、超大黑体标题、严格网格、极少颜色(黑 + 一个正红)、大留白;强对比、现代、克制。",
5
+ "constraints": "不要渐变、不要阴影、不要装饰图形、不要多色、不要卡通、不要照片、不要圆角。",
6
+ "reference": "瑞士国际主义 / Helvetica 海报",
7
+ "styleBrief": "瑞士国际主义海报:纯白底 #FFFFFF,无渐变、无阴影。主标题用超大无衬线黑体(Helvetica 方向,字号占版面 1/3 以上,常被边缘裁切),黑色 #111111;唯一彩色是正红 #E2231A,只出现在一个几何形状(大圆 / 三角 / 一条短线)或一个关键词上。严格网格:大标题左上,右侧大几何色块;下部 01/02/03 三栏,黑色 1px 细竖线分隔,栏内加粗小标签 + 2 行小字正文。字距紧、行距紧、留白极大;只允许黑 / 白 / 红三色与几何形状,禁止插画、照片、渐变、阴影、装饰图形。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "封面",
11
+ "brief": "白底瑞士海报封面:左上三行超大黑色无衬线标题(可被左边缘裁切);标题下一行加宽字距全大写小标签与一条红色短横线;右上一个大红色圆与一个黑色直角三角形;底部细线与页码。"
12
+ },
13
+ {
14
+ "title": "三栏信息页",
15
+ "brief": "白底瑞士网格页:顶部一行大号黑色无衬线标题(12 字内);下方 01/02/03 三栏,栏间黑色 1px 竖线,每栏顶部大号黑色编号 + 加粗小标题 + 2–3 行小字正文;某处一枚正红小色块作唯一强调;底部页码细线。"
16
+ },
17
+ {
18
+ "title": "数字 / 图表页",
19
+ "brief": "白底瑞士数据页:左上超大黑色数字或短标题;右侧极简图表(黑 / 灰柱或折线,唯一一根正红,无网格无图例);下方 3 条细线注释与页码;整页只有黑白红三色与细线。"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "abbr": "TEC",
3
+ "name": "科技蓝图(等距)",
4
+ "description": "科技蓝图风:深海军蓝网格底、青白技术线条、等距系统/架构图、等宽字体标签、发光节点;像工程蓝图和架构白皮书。",
5
+ "constraints": "不要照片、不要卡通、不要渐变光效泛滥、不要彩色斑块、不要写实人物、不要真实品牌 logo。",
6
+ "reference": "架构白皮书 / 工程蓝图",
7
+ "styleBrief": "科技蓝图 / 等距架构图:深海军蓝底 #0A1628,叠加极淡青色网格(#1E3A5F);主体是等距(isometric)线框模块:节点、服务器、数据库、云、客户端,用青白色 #7DD3FC 细线与发光边,节点间正交折线连接 + 小箭头;标签用等宽字体(monospace)全大写小字,外加带边框的图例 / 清单面板(不发光)。点缀极少量暖色 #F59E0B 强调关键节点。整体像工程蓝图 / 架构白皮书,信息密度高但网格秩序强;无照片、无卡通、无廉价霓虹。",
8
+ "baselineBriefs": [
9
+ {
10
+ "title": "架构总览",
11
+ "brief": "深蓝蓝图底 + 青色细网格:顶部左侧大号等宽字体标题「SCALABLE PLATFORM」与左侧竖排三条小标签;中央等距架构图:顶部云节点 → 负载均衡 → 三个服务节点 → 数据库 / 缓存 / 存储,青白细线发光连接;左右下角三个带边框清单面板(KEY COMPONENTS / SCALING / LEGEND),等宽小字;少量橙色光点强调关键连接。"
12
+ },
13
+ {
14
+ "title": "等距流程图",
15
+ "brief": "深蓝蓝图页:顶部等宽字体标题一行 + 小标签;中部等距步骤流程 4 个模块(输入 / 处理 / 服务 / 输出)沿对角线排列,青白发光细线与正交折线箭头连接,每个模块下方等宽小字标签;右侧一个带边框说明面板;底部页码与网格。"
16
+ },
17
+ {
18
+ "title": "分层架构页",
19
+ "brief": "深蓝蓝图页:左侧等宽标题 + 五行分层清单(客户端 / 接入 / 服务 / 数据 / 观测),每行带细线图标;右侧等距分层堆叠图(3–4 层平台,青白细线,层间发光箭头),标注各层关键组件;少量橙色强调数据层;底部图例面板。"
20
+ }
21
+ ]
22
+ }
package/ui/logo.svg ADDED
@@ -0,0 +1,20 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" fill="none">
2
+ <defs>
3
+ <linearGradient id="bg" x1="4" y1="2" x2="60" y2="62" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#0e5563"/><stop offset="1" stop-color="#08343d"/>
5
+ </linearGradient>
6
+ <linearGradient id="gold" x1="40" y1="8" x2="58" y2="26" gradientUnits="userSpaceOnUse">
7
+ <stop stop-color="#e8b45c"/><stop offset="1" stop-color="#c5882f"/>
8
+ </linearGradient>
9
+ <linearGradient id="card" x1="18" y1="16" x2="50" y2="44" gradientUnits="userSpaceOnUse">
10
+ <stop stop-color="#fffdf8"/><stop offset="1" stop-color="#efe8d9"/>
11
+ </linearGradient>
12
+ </defs>
13
+ <rect width="64" height="64" rx="16" fill="url(#bg)"/>
14
+ <rect x="13" y="34" width="34" height="21" rx="3.5" fill="#faf8f2" opacity=".28" transform="rotate(-10 30 44.5)"/>
15
+ <rect x="15" y="26" width="34" height="21" rx="3.5" fill="#faf8f2" opacity=".55" transform="rotate(-5 32 36.5)"/>
16
+ <rect x="17" y="17" width="34" height="22" rx="3.5" fill="url(#card)"/>
17
+ <rect x="22" y="23" width="19" height="2.6" rx="1.3" fill="#0f6975"/>
18
+ <rect x="22" y="29" width="12" height="2.2" rx="1.1" fill="#1496a8" opacity=".75"/>
19
+ <path d="M48.5 9.5l2.2 5.4 5.4 2.2-5.4 2.2-2.2 5.4-2.2-5.4-5.4-2.2 5.4-2.2z" fill="url(#gold)"/>
20
+ </svg>