skill-forge-hub 1.0.6 → 1.1.0

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 (134) hide show
  1. package/CHANGELOG.en.md +203 -0
  2. package/CHANGELOG.md +18 -0
  3. package/README.en.md +110 -0
  4. package/README.md +64 -59
  5. package/annual-report/SKILL.md +10 -0
  6. package/annual-report/resources/disk-and-html.md +1 -0
  7. package/annual-report/resources/reference.html +1 -1
  8. package/annual-report/resources/skillforge-guide.html +408 -0
  9. package/annual-report/resources/skillforge-guide.txt +131 -0
  10. package/article-to-html/SKILL.md +12 -0
  11. package/article-to-html/resources/skillforge-guide.html +408 -0
  12. package/article-to-html/resources/skillforge-guide.txt +131 -0
  13. package/cli.js +6 -5
  14. package/commit-heatmap/SKILL.md +70 -0
  15. package/commit-heatmap/resources/collect.md +22 -0
  16. package/commit-heatmap/resources/generate.md +15 -0
  17. package/commit-heatmap/resources/html-rules.md +21 -0
  18. package/commit-heatmap/resources/reference.html +228 -0
  19. package/commit-heatmap/resources/skillforge-guide.html +408 -0
  20. package/commit-heatmap/resources/skillforge-guide.txt +131 -0
  21. package/commit-heatmap/resources/usage-guide.md +23 -0
  22. package/commit-heatmap/user-config.md +12 -0
  23. package/daily-report/SKILL.md +10 -0
  24. package/daily-report/resources/disk-and-html.md +1 -1
  25. package/daily-report/resources/reference.html +1 -1
  26. package/daily-report/resources/skillforge-guide.html +408 -0
  27. package/daily-report/resources/skillforge-guide.txt +131 -0
  28. package/data-prepper/SKILL.md +54 -0
  29. package/data-prepper/resources/clean-rules.md +18 -0
  30. package/data-prepper/resources/overview.md +17 -0
  31. package/data-prepper/resources/read-data.md +13 -0
  32. package/data-prepper/resources/skillforge-guide.html +408 -0
  33. package/data-prepper/resources/skillforge-guide.txt +131 -0
  34. package/data-prepper/resources/usage-guide.md +24 -0
  35. package/data-prepper/user-config.md +11 -0
  36. package/decision-log/SKILL.md +53 -0
  37. package/decision-log/resources/index.md +21 -0
  38. package/decision-log/resources/record.md +19 -0
  39. package/decision-log/resources/skillforge-guide.html +408 -0
  40. package/decision-log/resources/skillforge-guide.txt +131 -0
  41. package/decision-log/resources/usage-guide.md +23 -0
  42. package/decision-log/user-config.md +9 -0
  43. package/deck-stage/SKILL.md +11 -1
  44. package/deck-stage/resources/cover-template.html +1 -1
  45. package/deck-stage/resources/skillforge-guide.html +408 -0
  46. package/deck-stage/resources/skillforge-guide.txt +131 -0
  47. package/docs/architecture.en.md +96 -0
  48. package/docs/architecture.md +71 -64
  49. package/docs/install.en.md +125 -0
  50. package/docs/install.md +88 -34
  51. package/docs/usage-examples.en.md +50 -0
  52. package/docs/usage-examples.md +50 -0
  53. package/magic-deck/SKILL.md +11 -1
  54. package/magic-deck/resources/deck-spec.md +1 -1
  55. package/magic-deck/resources/reference.html +1 -1
  56. package/magic-deck/resources/skillforge-guide.html +408 -0
  57. package/magic-deck/resources/skillforge-guide.txt +131 -0
  58. package/meeting-minutes/SKILL.md +10 -0
  59. package/meeting-minutes/resources/disk-and-html.md +1 -0
  60. package/meeting-minutes/resources/reference.html +1 -1
  61. package/meeting-minutes/resources/skillforge-guide.html +408 -0
  62. package/meeting-minutes/resources/skillforge-guide.txt +131 -0
  63. package/meta-forge/SKILL.md +14 -4
  64. package/meta-forge/resources/forge-rules.md +7 -1
  65. package/meta-forge/resources/skillforge-guide.html +408 -0
  66. package/meta-forge/resources/skillforge-guide.txt +131 -0
  67. package/meta-forge/resources/usage-guide.md +2 -2
  68. package/monthly-report/SKILL.md +10 -0
  69. package/monthly-report/resources/disk-and-html.md +1 -0
  70. package/monthly-report/resources/reference.html +1 -1
  71. package/monthly-report/resources/skillforge-guide.html +408 -0
  72. package/monthly-report/resources/skillforge-guide.txt +131 -0
  73. package/one-pager/SKILL.md +71 -0
  74. package/one-pager/resources/content.md +18 -0
  75. package/one-pager/resources/generate.md +16 -0
  76. package/one-pager/resources/html-rules.md +21 -0
  77. package/one-pager/resources/reference.html +209 -0
  78. package/one-pager/resources/skillforge-guide.html +408 -0
  79. package/one-pager/resources/skillforge-guide.txt +131 -0
  80. package/one-pager/resources/usage-guide.md +23 -0
  81. package/one-pager/user-config.md +11 -0
  82. package/package.json +13 -2
  83. package/prompt-pouch/SKILL.md +12 -1
  84. package/prompt-pouch/resources/reference.html +1 -1
  85. package/prompt-pouch/resources/skillforge-guide.html +408 -0
  86. package/prompt-pouch/resources/skillforge-guide.txt +131 -0
  87. package/quarterly-report/SKILL.md +10 -0
  88. package/quarterly-report/resources/disk-and-html.md +1 -0
  89. package/quarterly-report/resources/reference.html +1 -1
  90. package/quarterly-report/resources/skillforge-guide.html +408 -0
  91. package/quarterly-report/resources/skillforge-guide.txt +131 -0
  92. package/release-notes/SKILL.md +54 -0
  93. package/release-notes/resources/collect.md +17 -0
  94. package/release-notes/resources/publish-checklist.md +11 -0
  95. package/release-notes/resources/skillforge-guide.html +408 -0
  96. package/release-notes/resources/skillforge-guide.txt +131 -0
  97. package/release-notes/resources/usage-guide.md +25 -0
  98. package/release-notes/resources/write.md +27 -0
  99. package/release-notes/user-config.md +15 -0
  100. package/skill-doctor/SKILL.md +53 -0
  101. package/skill-doctor/resources/checks.md +27 -0
  102. package/skill-doctor/resources/report.md +26 -0
  103. package/skill-doctor/resources/skillforge-guide.html +408 -0
  104. package/skill-doctor/resources/skillforge-guide.txt +131 -0
  105. package/skill-doctor/resources/usage-guide.md +22 -0
  106. package/skill-doctor/user-config.md +9 -0
  107. package/spec-doc2spec/SKILL.md +10 -0
  108. package/spec-doc2spec/resources/skillforge-guide.html +408 -0
  109. package/spec-doc2spec/resources/skillforge-guide.txt +131 -0
  110. package/spec-spec2doc/SKILL.md +10 -0
  111. package/spec-spec2doc/resources/skillforge-guide.html +408 -0
  112. package/spec-spec2doc/resources/skillforge-guide.txt +131 -0
  113. package/team-report-collector/SKILL.md +70 -0
  114. package/team-report-collector/resources/collect.md +23 -0
  115. package/team-report-collector/resources/generate.md +14 -0
  116. package/team-report-collector/resources/html-rules.md +22 -0
  117. package/team-report-collector/resources/reference.html +384 -0
  118. package/team-report-collector/resources/skillforge-guide.html +408 -0
  119. package/team-report-collector/resources/skillforge-guide.txt +131 -0
  120. package/team-report-collector/resources/usage-guide.md +25 -0
  121. package/team-report-collector/user-config.md +12 -0
  122. package/twin-docs/SKILL.md +53 -0
  123. package/twin-docs/resources/glossary.md +12 -0
  124. package/twin-docs/resources/skillforge-guide.html +408 -0
  125. package/twin-docs/resources/skillforge-guide.txt +131 -0
  126. package/twin-docs/resources/sync-check.md +15 -0
  127. package/twin-docs/resources/translate.md +20 -0
  128. package/twin-docs/resources/usage-guide.md +24 -0
  129. package/twin-docs/user-config.md +11 -0
  130. package/weekly-report/SKILL.md +10 -0
  131. package/weekly-report/resources/disk-and-html.md +1 -1
  132. package/weekly-report/resources/reference.html +1 -1
  133. package/weekly-report/resources/skillforge-guide.html +408 -0
  134. package/weekly-report/resources/skillforge-guide.txt +131 -0
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: one-pager
3
+ description: 把一个主题/一句话想法变成一页纸 HTML 海报(大标题 + 金句 + 要点块 + 页脚,纵向一屏排版、适合分享/打印/截图),并可用 ?shot 参数截出 PNG 图片。当用户请求一页纸、一张海报、one-pager、做张海报、一页介绍、金句海报时使用。
4
+ allowed-tools: Bash, Read, Write
5
+ disable-model-invocation: false
6
+ ---
7
+
8
+ # 一页纸海报(one-pager)
9
+
10
+ 一句话主题进 → 一屏海报出:内容提炼 → HTML 海报(纵向一屏、打印友好)→ 可选 PNG 截图。
11
+
12
+ ## 生成流程
13
+
14
+ 0. **读用户配置**(THEME/DIR/OPEN_HTML/SHOT/ASPECT)→ 先 Read 同目录 `user-config.md`
15
+ 1. **内容提炼**(主题句 → 标题/金句/要点块,问清再动)→ 读 `resources/content.md`
16
+ 2. **生成 HTML**(先 Read reference.html 骨架替换数据)→ 读 `resources/generate.md` 与 `resources/html-rules.md` 两份
17
+ 2.5 **交付前自检**(硬门禁不可跳过):HTML 文件写好后——
18
+ - 挂 pageerror 监听用 Chrome headless 访问页面(零容忍报错)→ 截全页 PNG Read 自查:标题/金句/要点块齐全、一屏内无溢出、无豆腐块缺字
19
+ - SHOT: true 时用 Chrome headless 带 `?shot` 参数截 PNG 落盘(同海报文件名 .png)
20
+ - 任何报错或视觉问题:修 HTML → 重检;全绿才进第 3 步
21
+ 3. **使用咨询**(用户只问「一页纸海报怎么用」等用法、未要求生成)→ 读 `resources/usage-guide.md`,将其内容原样输出(首行标题改为「一页纸海报使用指南」),不提炼内容、不落盘、不开浏览器
22
+
23
+ ## ⚙️ 配置与自定义
24
+
25
+ **执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(THEME/DIR/OPEN_HTML/SHOT/ASPECT)都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.md.upstream` 对照文件,可按需手动合并新配置点。
26
+
27
+ - **THEME**:海报主题,tech 深蓝科技(默认)/ biz 浅色商务 / mono IDEA 黑亮 / light IDEA 白亮 / warm 温暖渐变;生成时写 `<html data-theme="THEME值">` 定默认,页面右下角换肤坞随点随换(localStorage 记忆,键按页内嵌唯一 ID 隔离、多份产物互不串台、改名/移动目录记忆不丢;生成时头部写 `<meta name="poster-id" content="<UUID>">`,每次 crypto.randomUUID() 生成标准 UUID v4(8-4-4-4-12 十六进制,禁止手写变体、禁止沿用占位与旧值);落盘写文件前顺扫落盘目录下本技能命名的 html,读各文件 id meta 查重,撞号重掷至不重复)
28
+
29
+ ## 配置版本机制(升级保护)
30
+
31
+ 本 skill 当前配置版本为 `1`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明不一致:
32
+
33
+ 1. 先将旧 user-config.md 备份为 `user-config.md.bak-<时间戳>`(同目录,绝不删除旧值)
34
+ 2. 按本节「配置升级规则」迁移字段:新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认
35
+ 3. 更新 CONFIG_VERSION 为当前版本
36
+ 4. 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」
37
+
38
+ 升级本 skill 时,配置结构如有变化必须同步更新本节的当前版本号与迁移说明;禁止在未声明版本变更的情况下静默修改配置语义。
39
+ ## 文档同步自检纪律(维护者必读)
40
+
41
+ 修改本 skill 任一文件(SKILL.md / user-config.md / resources/*)后,必须 grep 全文核对相关关键词在各文件间一致(字段名 / 流程节点 / 模板名改名时新旧词全仓核对,旧词零残留才算完成)。
42
+ ## 🔧 报修处理流程(用户报页面问题时)
43
+
44
+ 用户说「这个页面效果不对 / 布局乱了 / 有 UI 问题 / 样式错了 / 交互坏了」(常附截图或指出具体现象)→ 按以下流程处理,不以「重新生成一份」敷衍:
45
+
46
+ 1. **立标准**:先 Read 本 skill 目录 `resources/reference.html`——它就是设计标准答案(布局/配色/交互全在代码里)
47
+ 2. **找问题**:Read 用户那份问题 html 文件,与 reference 逐处比对(结构顺序 / CSS 变量 / 关键类名 / 交互 JS),定位跑偏处;用户给了截图则按截图现象反查
48
+ 3. **修复**:以 reference 为准修复那份 html(只修跑偏处,不动正确内容;reference 与 html 不一致时以 reference 为准)
49
+ 4. **自证**:Chrome headless 访问修复后页面截全页 PNG,Read 自查修复点恢复标准效果
50
+ 5. **汇报**:一句话说清问题根因 + 修复了什么 + 附截图;若根因在 reference.html 自身,顺修 reference.html 对应处并在汇报中说明「参考模板已同步修正」
51
+
52
+
53
+ ## 产物升级(回炉)
54
+
55
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="one-pager@2">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧海报/回炉」时:扫落盘目录读版本戳筛旧版(无版本戳或缺少 `<meta name="poster-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 poster-id meta 值(换 ID = 主题记忆失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧海报都升级成新样式』即可一键升级」。
56
+
57
+ ## 规则速览
58
+
59
+ - 一屏原则:海报纵向一屏展示(内容自适应缩放不滚动出第二屏);要点块 3-5 条,每条 15-30 字,禁止长篇大论
60
+ - 内容问清再动:主题句不够明确时先与用户确认标题/要点口径,不猜
61
+ - 零侵权:系统字体栈、禁止 CDN/外链资源,页面离线双击可开;页脚署名固定 GENERATED BY AI TEAM
62
+ - 落盘完成后对话必须报告落盘位置:完整路径清单(html + 可选 png),并注明 html 是否已在浏览器打开
63
+
64
+ ---
65
+
66
+ ## 🔍 SkillForge 使用指引(整体咨询时触发)
67
+
68
+ 当用户询问 **SkillForge 本身**(不是单个技能用法)——「skillforge 怎么用 / 使用说明 / 使用指引 / 是什么」「技能怎么安装 / 怎么升级 / 装了哪些技能 / 技能清单」「skill-forge ls / init / update 等命令怎么用」「技能安装器 / 技能锻造坊」等(中英文、近似说法均可,关键词可自由扩展):
69
+ 1. Read 同目录 `resources/skillforge-guide.txt` 全文,按其内容整理回答(命令与参数以 txt 为准,勿自行编造)
70
+ 2. 用系统命令打开同目录 `resources/skillforge-guide.html`(macOS `open`,Windows `start`),让用户在浏览器看排版版
71
+ 3. 用户只问单个技能怎么用时(如「日报怎么用」)不触发本指引,走本技能的使用说明
@@ -0,0 +1,18 @@
1
+ # 内容提炼(阶段 1)
2
+
3
+ ## 输入形态
4
+
5
+ 用户给一句话主题(「做一张『AI 改变工作』的海报」)或一段文字/已有文档 → 提炼四要素:
6
+
7
+ | 要素 | 规则 |
8
+ |:---|:---|
9
+ | 标题 | 6-14 字,主题凝练(如「AI 改变工作」) |
10
+ | 金句 | 1 句 12-30 字,有感染力、点题 |
11
+ | 要点块 | 3-5 条,每条 15-30 字,动词开头(「重塑流程」「释放创造」) |
12
+ | 页脚注 | 可选:日期/来源一行小字(默认为空) |
13
+
14
+ ## 纪律
15
+
16
+ - **问清再动**:主题句过简(如「做个海报」)时,先输出提炼草稿(标题/金句/要点)AskUserQuestion 确认后再生成;用户给了明确内容则直接进阶段 2
17
+ - 金句不抄名人名言冒充原创(引用需标注出处);要点不堆砌形容词,写实的动作与效果
18
+ - 示例数据脱敏:演示用「AI 改变工作」等通用主题,禁止真实团队名/项目名/人名
@@ -0,0 +1,16 @@
1
+ # 生成 HTML(阶段 2)
2
+
3
+ 先 Read `resources/reference.html` 全文,以其为骨架模板逐处替换数据:
4
+
5
+ 1. **meta**:`sf-template` 版本戳保持当前模板版本;`poster-id` 换成新 UUID(crypto.randomUUID() 标准 v4,落盘前顺扫落盘目录下本技能命名的 html 读 id meta 查重,撞号重掷)
6
+ 2. **标题/金句/要点块/页脚注**:替换 `<h1>`、`.quote`、`.points` 内 li、`.footnote` 内容(要点块 3-5 条逐条 li)
7
+ 3. **`<title>`** 与海报标题一致
8
+ 4. 其余(CSS/JS/结构)一律不许动;样式参数解释与禁止项见 `resources/html-rules.md`
9
+
10
+ ## 落盘与截图
11
+
12
+ - 文件名 `poster-<主题slug>.html`(英文 slug 化标题,如 poster-ai-work.html;DIR: auto 时落当前工作目录 posters/ 子目录,不存在则创建)
13
+ - 同目录同时落 `poster-<主题slug>.md` 内容底稿(标题/金句/要点/页脚四要素纯文本,html 永远可从它重建——数据真相源)
14
+ - OPEN_HTML: true 且落盘了 html 时自动打开浏览器(macOS:open <html文件>;Windows PowerShell:Start-Process <html文件>)
15
+ - SHOT: true 时用 Chrome headless 截 PNG:`--headless --disable-gpu --no-sandbox --hide-scrollbars --user-data-dir=<临时目录> --screenshot=<png路径> --window-size=<宽>,<高> --virtual-time-budget=4000 "file:///<html路径>?shot"`(Windows 用 node url.pathToFileURL 生成 URL);按 ASPECT 定窗口(3:4 → 900,1200;1:1 → 1000,1000;16:9 → 1600,900);禁止用 `--headless=new`;Chrome 不存在换 Edge,都无则跳过并对话注明
16
+ - **落盘完成后对话报告落盘位置**:完整路径清单(html + md + 可选 png),并注明 html 是否已在浏览器打开、截图是否跳过
@@ -0,0 +1,21 @@
1
+ > ⛔ **Reference 铁律(最高优先)**:本目录 `reference.html` 是定稿样式源码。生成 HTML 时必须先 Read `resources/reference.html` 与本文件两份,以 reference.html 为骨架模板逐处替换数据(标题/金句/要点 li/页脚注/poster-id UUID),本文件的描述是参数解释、变体规则与禁止项;两者冲突时**以 reference.html 为准**。修改本 skill 的 HTML 效果时,必须同步更新 `resources/reference.html` 与本文档的对应描述,禁止只改一处。
2
+
3
+ # 海报 HTML 版式(一屏五主题 + 科技感背景层)
4
+
5
+ ## 版式总览
6
+
7
+ - 一屏海报:`.stage` 纵向 flex 满视口(100svh)内排布标题区/金句区/要点区/页脚,内容多时自动缩放字号(JS 按内容高度收缩,禁止滚动出第二屏);页面 body 不产生滚动条(overflow hidden)
8
+ - 五主题:tech 深蓝科技(默认)/ biz 浅色商务 / mono IDEA 黑亮 / light IDEA 白亮 / warm 温暖渐变,色值与 daily-report 同一套 12 核心契约;`html[data-theme]` 运行时切换;右下角换肤坞五色点随点随换、localStorage 记忆(键 `poster:<ID>-theme`,ID = 页内嵌 poster-id meta,多份产物互不串台、改名/移动目录记忆不丢);旧版三主题值不在五主题列表,启动时自动回落 tech
9
+ - 科技感背景层四件套(与日报/周报同款):SVG 微噪点(opacity .04,mono 退隐)+ 60px 网格底纹 + 星点(biz/light/warm 退隐 .28、mono 灰白化)+ 全屏扫描线与循环光带;内容版心 .stage-inner max-width 60%(与其它页面版心同宽)
10
+ - 字体全用系统本地字体栈(system-ui + ui-monospace/'SF Mono'/Menlo/Consolas,品牌字体 PingFang/YaHei/apple-system 零出现),禁止 CDN、@import、外链 CSS/JS/图片/网络字体——页面离线双击可开
11
+ - 多文件隔离(必植):头部写 `<meta name="poster-id" content="<UUID>">`(crypto.randomUUID() 标准 UUID v4);localStorage 键一律 `poster:<ID>-xxx`,禁止裸通用键名;页面 JS 启动时校验 id meta——非法或缺失(占位残留/手写变体/误沿用旧值)时按路径键(`'sf-heal:' + location.pathname`)自愈为 crypto.randomUUID() 标准 v4 并回写 meta,console.warn 显性报警;路径键持久化保证同文件跨打开稳定复用;合法 UUID 原样放行
12
+ - 版本戳:`<meta name="sf-template" content="one-pager@2">`(模板升级递增 @N)
13
+ - 视觉层次:大标题 40-56px 渐变字(linear-gradient 背景裁切文字)+ 装饰分隔线(渐变短横线);金句区斜体 18-22px + 左右引号装饰;要点块 3-5 条各带序号圆点(渐变球)+ 每条一行短句;页脚 10px muted
14
+ - 入场动画:标题/金句/要点错峰上浮淡入;fill-mode 必须用 backwards 严禁 both;IntersectionObserver + 2s 兜底 setTimeout 强制全显(headless 截图 / 打印预览环境内容不得永久隐藏)
15
+ - ?shot 截图模式:页面 JS 检测 location.search 含 shot 时给 html 挂 data-shot 属性(CSS 关闭入场动画直接终态,headless 虚拟时间下动画帧不推进会停在初始帧导致截图空白)、强制全部内容 opacity 1、隐藏换肤坞,body padding 归零,输出纯海报画面
16
+ - 页脚署名固定 GENERATED BY AI TEAM(禁止真实团队名/项目名)
17
+
18
+ ## 内容规则
19
+
20
+ - 要点块 3-5 条:每条 15-30 字,动词开头;超过 5 条合并取舍,不足 3 条向用户再要
21
+ - 金句 12-30 字;标题 6-14 字;超长自动截断提示用户改短
@@ -0,0 +1,209 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN" data-theme="tech">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="sf-template" content="one-pager@2">
7
+ <meta name="poster-id" content="REF-POSTER-0000">
8
+ <title>AI 改变工作 · 一页纸海报</title>
9
+ <style>
10
+ /* ═══ 五主题令牌:与 daily-report 同一套 12 核心契约;html[data-theme] 运行时切换,THEME 生成时定默认 ═══ */
11
+ :root, [data-theme="tech"]{
12
+ --bg:#0a1929; --bg2:#071525; --panel:rgba(11,30,55,.9); --panel-solid:#0b1e37;
13
+ --text:#bae6fd; --muted:#5b7fa5; --accent:#0ea5e9; --accent2:#14b8a6;
14
+ --border:rgba(14,165,233,.18); --glow:rgba(14,165,233,.35); --glow-soft:rgba(14,165,233,.15);
15
+ --title-grad:linear-gradient(90deg,#7dd3fc,#0ea5e9 45%,#818cf8);
16
+ --tag-bg:rgba(14,165,233,.12);
17
+ --scan:rgba(0,240,255,.2); --scan-dim:rgba(0,240,255,.05);
18
+ }
19
+ [data-theme="biz"]{
20
+ --bg:#e8ecf5; --bg2:#dde3ef; --panel:rgba(255,255,255,.97); --panel-solid:#ffffff;
21
+ --text:#1e293b; --muted:#64748b; --accent:#2563eb; --accent2:#0891b2;
22
+ --border:rgba(37,99,235,.14); --glow:rgba(37,99,235,.18); --glow-soft:rgba(37,99,235,.12);
23
+ --title-grad:linear-gradient(90deg,#1e40af,#2563eb 55%,#0891b2);
24
+ --tag-bg:rgba(37,99,235,.08);
25
+ --scan:rgba(37,99,235,.14); --scan-dim:rgba(37,99,235,.04);
26
+ }
27
+ [data-theme="mono"]{ /* IDEA 黑亮:JetBrains New UI Dark 官方 */
28
+ --bg:#1e1f22; --bg2:#2b2d30; --panel:rgba(43,45,48,.95); --panel-solid:#2b2d30;
29
+ --text:#dfe1e5; --muted:#9aa0a6; --accent:#3574f0; --accent2:#5e9aff;
30
+ --border:rgba(53,116,240,.26); --glow:rgba(53,116,240,.3); --glow-soft:rgba(53,116,240,.13);
31
+ --title-grad:linear-gradient(90deg,#dfe1e5,#5e9aff 50%,#3574f0);
32
+ --tag-bg:rgba(53,116,240,.13);
33
+ --scan:rgba(223,225,229,.18); --scan-dim:rgba(223,225,229,.07);
34
+ }
35
+ [data-theme="light"]{ /* IDEA 白亮:IntelliJ Light 官方 */
36
+ --bg:#ffffff; --bg2:#f2f2f2; --panel:rgba(255,255,255,.98); --panel-solid:#ffffff;
37
+ --text:#1e1f22; --muted:#6e7781; --accent:#2675bf; --accent2:#4a9be0;
38
+ --border:rgba(38,117,191,.18); --glow:rgba(38,117,191,.2); --glow-soft:rgba(38,117,191,.1);
39
+ --title-grad:linear-gradient(90deg,#1e5f9f,#2675bf 55%,#4a9be0);
40
+ --tag-bg:rgba(38,117,191,.08);
41
+ --scan:rgba(38,117,191,.12); --scan-dim:rgba(38,117,191,.04);
42
+ }
43
+ [data-theme="warm"]{
44
+ --bg:#f7ebd9; --bg2:#efe0c8; --panel:rgba(255,250,243,.97); --panel-solid:#fffaf3;
45
+ --text:#43301f; --muted:#8a7565; --accent:#d97706; --accent2:#ea580c;
46
+ --border:rgba(217,119,6,.18); --glow:rgba(217,119,6,.22); --glow-soft:rgba(217,119,6,.14);
47
+ --title-grad:linear-gradient(90deg,#b45309,#d97706 50%,#ea580c);
48
+ --tag-bg:rgba(217,119,6,.08);
49
+ --scan:rgba(217,119,6,.16); --scan-dim:rgba(217,119,6,.04);
50
+ }
51
+ /* 浅色主题下星点氛围自然退隐 */
52
+ [data-theme="biz"] .stars, [data-theme="light"] .stars, [data-theme="warm"] .stars{ opacity:.28; }
53
+ /* mono 黑亮下氛围换装:星点改中性灰白,噪点层同退(不泛蓝) */
54
+ [data-theme="mono"] .stars{ background-image:
55
+ radial-gradient(1px 1px at 12% 18%, rgba(223,225,229,.32), transparent),
56
+ radial-gradient(1px 1px at 28% 64%, rgba(223,225,229,.28), transparent),
57
+ radial-gradient(1.5px 1.5px at 41% 32%, rgba(223,225,229,.26), transparent),
58
+ radial-gradient(1px 1px at 56% 78%, rgba(223,225,229,.24), transparent),
59
+ radial-gradient(1px 1px at 67% 12%, rgba(223,225,229,.26), transparent),
60
+ radial-gradient(1.5px 1.5px at 79% 52%, rgba(223,225,229,.28), transparent),
61
+ radial-gradient(1px 1px at 88% 86%, rgba(223,225,229,.3), transparent),
62
+ radial-gradient(1px 1px at 93% 24%, rgba(223,225,229,.3), transparent); }
63
+ [data-theme="mono"] body::before{ display:none; }
64
+
65
+ *{margin:0;padding:0;box-sizing:border-box}
66
+ html,body{height:100%;background:var(--bg)}
67
+ body{color:var(--text);font-family:system-ui,'Segoe UI',Roboto,sans-serif;overflow:hidden;position:relative}
68
+ body::before{
69
+ content:''; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.04;
70
+ background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
71
+ }
72
+ .grid-pattern{
73
+ position:fixed; inset:0; z-index:0; pointer-events:none;
74
+ background-image:linear-gradient(var(--scan-dim) 1px, transparent 1px),linear-gradient(90deg, var(--scan-dim) 1px, transparent 1px);
75
+ background-size:60px 60px;
76
+ }
77
+ .stars{
78
+ position:fixed; inset:0; z-index:0; pointer-events:none;
79
+ background-image:
80
+ radial-gradient(1px 1px at 12% 18%, rgba(255,255,255,.38), transparent),
81
+ radial-gradient(1px 1px at 28% 64%, rgba(0,240,255,.48), transparent),
82
+ radial-gradient(1.5px 1.5px at 41% 32%, rgba(255,255,255,.3), transparent),
83
+ radial-gradient(1px 1px at 56% 78%, rgba(168,85,247,.4), transparent),
84
+ radial-gradient(1px 1px at 67% 12%, rgba(0,255,136,.4), transparent),
85
+ radial-gradient(1.5px 1.5px at 79% 52%, rgba(0,240,255,.45), transparent),
86
+ radial-gradient(1px 1px at 88% 86%, rgba(255,255,255,.34), transparent),
87
+ radial-gradient(1px 1px at 93% 24%, rgba(0,240,255,.5), transparent);
88
+ }
89
+ .scanlines{
90
+ position:fixed; inset:0; z-index:999; pointer-events:none;
91
+ background:repeating-linear-gradient(0deg, transparent 0 2px, var(--scan-dim) 2px 4px);
92
+ }
93
+ .scanband{
94
+ position:fixed; left:0; right:0; height:150px; z-index:998; pointer-events:none;
95
+ background:linear-gradient(180deg, transparent, var(--scan-dim) 50%, transparent);
96
+ animation:scanMove 11s linear infinite;
97
+ }
98
+ @keyframes scanMove{ from{top:-22%;} to{top:112%;} }
99
+ .stage{height:100svh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:6vh 8vw;text-align:center;position:relative;z-index:1}
100
+ .stage-inner{width:min(60%,1200px)}
101
+ .badge{font-size:12px;letter-spacing:3px;color:var(--accent);margin-bottom:22px;animation:riseIn .5s ease backwards;animation-delay:0s}
102
+ h1{font-size:64px;line-height:1.2;font-weight:800;letter-spacing:2px;background:var(--title-grad);-webkit-background-clip:text;background-clip:text;color:transparent;margin-bottom:18px;animation:riseIn .5s ease backwards;animation-delay:.13s;text-shadow:0 0 40px var(--glow)}
103
+ .divider{width:64px;height:2px;background:var(--title-grad);border-radius:2px;margin:0 auto 26px;animation:riseIn .5s ease backwards;animation-delay:.26s}
104
+ .quote{font-size:22px;font-style:italic;color:var(--text);line-height:1.8;margin-bottom:40px;animation:riseIn .5s ease backwards;animation-delay:.39s}
105
+ .quote::before{content:"「";color:var(--accent)}
106
+ .quote::after{content:"」";color:var(--accent)}
107
+ .points{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-bottom:44px;text-align:left;animation:riseIn .5s ease backwards;animation-delay:.52s}
108
+ .points li{display:flex;align-items:flex-start;gap:12px;font-size:16px;line-height:1.7;color:var(--text);background:var(--panel);border:1px solid var(--border);border-radius:6px;padding:18px 16px}
109
+ .points li .dot{width:9px;height:9px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent2));box-shadow:0 0 12px var(--glow);flex:none;margin-top:8px}
110
+ footer{font-size:10px;color:var(--muted);letter-spacing:1px;animation:riseIn .5s ease backwards;animation-delay:.65s}
111
+ .footnote{font-size:11px;color:var(--muted);margin-top:8px}
112
+ @keyframes riseIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
113
+ .theme-dock{position:fixed;right:14px;bottom:14px;display:flex;gap:8px;background:var(--panel);border:1px solid var(--border);border-radius:20px;padding:7px 10px;z-index:9}
114
+ .th-dot{width:14px;height:14px;border-radius:50%;cursor:pointer;border:1.5px solid rgba(127,127,127,.35);transition:transform .15s ease}
115
+ .th-dot:hover{transform:scale(1.18)}
116
+ .th-dot.on{border-color:var(--text)}
117
+ .th-dot[data-t="tech"]{background:#0ea5e9}
118
+ .th-dot[data-t="biz"]{background:#2563eb}
119
+ .th-dot[data-t="mono"]{background:#1e1f22}
120
+ .th-dot[data-t="light"]{background:#ffffff}
121
+ .th-dot[data-t="warm"]{background:#d97706}
122
+ @media (max-width:680px){h1{font-size:36px}.quote{font-size:16px}.points li{font-size:14px}.points{grid-template-columns:1fr}}
123
+ html[data-shot] .stage-inner>*{animation:none!important}
124
+ </style>
125
+ </head>
126
+ <body>
127
+ <div class="grid-pattern"></div>
128
+ <div class="stars"></div>
129
+ <div class="scanband"></div>
130
+ <div class="scanlines"></div>
131
+ <div class="stage" id="stage">
132
+ <div class="stage-inner">
133
+ <div class="badge">ONE PAGER</div>
134
+ <h1>AI 改变工作</h1>
135
+ <div class="divider"></div>
136
+ <div class="quote">让机器做重复的事,让人做有温度的事</div>
137
+ <ul class="points">
138
+ <li><span class="dot"></span>重塑流程,把琐碎交给算法</li>
139
+ <li><span class="dot"></span>释放创造,把时间还给思考</li>
140
+ <li><span class="dot"></span>数据驱动,把决策交给证据</li>
141
+ </ul>
142
+ <footer>GENERATED BY AI TEAM</footer>
143
+ <div class="footnote"></div>
144
+ </div>
145
+ </div>
146
+ <div class="theme-dock" id="dock">
147
+ <span class="th-dot on" data-t="tech" title="深蓝科技"></span>
148
+ <span class="th-dot" data-t="biz" title="浅色商务"></span>
149
+ <span class="th-dot" data-t="mono" title="IDEA 黑亮"></span>
150
+ <span class="th-dot" data-t="light" title="IDEA 白亮"></span>
151
+ <span class="th-dot" data-t="warm" title="温暖渐变"></span>
152
+ </div>
153
+ <script>
154
+ (function(){
155
+ var KEY = 'sf-heal:' + location.pathname;
156
+ var m = document.querySelector('meta[name="poster-id"]');
157
+ var ok = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(m ? m.content : '');
158
+ var ID;
159
+ if (ok) { ID = m.content; }
160
+ else {
161
+ var v = localStorage.getItem(KEY);
162
+ if (!v) { v = crypto.randomUUID(); localStorage.setItem(KEY, v); }
163
+ ID = v;
164
+ m.setAttribute('content', v);
165
+ console.warn('[poster] 非法 id meta 已自愈为 ' + v);
166
+ }
167
+ /* 主题换肤:五套配色随点随换;记忆上次选择(localStorage,失败静默);旧版三主题值自动回落 tech */
168
+ var THEMES = ['tech','biz','mono','light','warm'];
169
+ var THEME_KEY = 'poster:' + ID + '-theme';
170
+ var savedTheme = null;
171
+ try { savedTheme = localStorage.getItem(THEME_KEY); } catch(e) {}
172
+ if (savedTheme && THEMES.indexOf(savedTheme) !== -1) document.documentElement.setAttribute('data-theme', savedTheme);
173
+ var cur = document.documentElement.getAttribute('data-theme');
174
+ if (THEMES.indexOf(cur) === -1) { cur = 'tech'; document.documentElement.setAttribute('data-theme', cur); }
175
+ document.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-t') === cur); });
176
+ document.querySelectorAll('.th-dot').forEach(function(d){
177
+ d.addEventListener('click', function(){
178
+ var t = d.getAttribute('data-t');
179
+ document.documentElement.setAttribute('data-theme', t);
180
+ try { localStorage.setItem(THEME_KEY, t); } catch(e) {}
181
+ document.querySelectorAll('.th-dot').forEach(function(x){ x.classList.toggle('on', x === d); });
182
+ });
183
+ });
184
+ function fit(){
185
+ var stage = document.getElementById('stage');
186
+ var scale = Math.min(1, window.innerHeight / (stage.scrollHeight + 1));
187
+ if (scale < 1) {
188
+ stage.style.transform = 'scale(' + scale + ')';
189
+ stage.style.transformOrigin = 'center center';
190
+ }
191
+ }
192
+ fit();
193
+ window.addEventListener('resize', fit);
194
+ if (location.search.indexOf('shot') !== -1) {
195
+ document.documentElement.setAttribute('data-shot', '1');
196
+ document.querySelectorAll('.stage-inner > *').forEach(function(c){ c.style.opacity = '1'; c.style.transform = 'none'; });
197
+ document.getElementById('dock').style.display = 'none';
198
+ }
199
+ if ('IntersectionObserver' in window) {
200
+ var io = new IntersectionObserver(function(es){
201
+ es.forEach(function(e){ if (e.isIntersecting) { e.target.style.opacity = '1'; e.target.style.transform = 'none'; io.unobserve(e.target); } });
202
+ }, {threshold:.1});
203
+ document.querySelectorAll('.stage-inner > *').forEach(function(c){ io.observe(c); });
204
+ setTimeout(function(){ document.querySelectorAll('.stage-inner > *').forEach(function(c){ c.style.opacity = '1'; c.style.transform = 'none'; }); }, 2000);
205
+ }
206
+ })();
207
+ </script>
208
+ </body>
209
+ </html>