skill-forge-hub 1.0.7 → 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 (133) hide show
  1. package/CHANGELOG.en.md +9 -0
  2. package/CHANGELOG.md +9 -0
  3. package/README.en.md +18 -7
  4. package/README.md +18 -7
  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 +2 -1
  48. package/docs/architecture.md +2 -1
  49. package/docs/install.en.md +56 -0
  50. package/docs/install.md +56 -0
  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 +11 -1
  64. package/meta-forge/resources/forge-rules.md +4 -1
  65. package/meta-forge/resources/skillforge-guide.html +408 -0
  66. package/meta-forge/resources/skillforge-guide.txt +131 -0
  67. package/monthly-report/SKILL.md +10 -0
  68. package/monthly-report/resources/disk-and-html.md +1 -0
  69. package/monthly-report/resources/reference.html +1 -1
  70. package/monthly-report/resources/skillforge-guide.html +408 -0
  71. package/monthly-report/resources/skillforge-guide.txt +131 -0
  72. package/one-pager/SKILL.md +71 -0
  73. package/one-pager/resources/content.md +18 -0
  74. package/one-pager/resources/generate.md +16 -0
  75. package/one-pager/resources/html-rules.md +21 -0
  76. package/one-pager/resources/reference.html +209 -0
  77. package/one-pager/resources/skillforge-guide.html +408 -0
  78. package/one-pager/resources/skillforge-guide.txt +131 -0
  79. package/one-pager/resources/usage-guide.md +23 -0
  80. package/one-pager/user-config.md +11 -0
  81. package/package.json +10 -1
  82. package/prompt-pouch/SKILL.md +12 -1
  83. package/prompt-pouch/resources/reference.html +1 -1
  84. package/prompt-pouch/resources/skillforge-guide.html +408 -0
  85. package/prompt-pouch/resources/skillforge-guide.txt +131 -0
  86. package/quarterly-report/SKILL.md +10 -0
  87. package/quarterly-report/resources/disk-and-html.md +1 -0
  88. package/quarterly-report/resources/reference.html +1 -1
  89. package/quarterly-report/resources/skillforge-guide.html +408 -0
  90. package/quarterly-report/resources/skillforge-guide.txt +131 -0
  91. package/release-notes/SKILL.md +54 -0
  92. package/release-notes/resources/collect.md +17 -0
  93. package/release-notes/resources/publish-checklist.md +11 -0
  94. package/release-notes/resources/skillforge-guide.html +408 -0
  95. package/release-notes/resources/skillforge-guide.txt +131 -0
  96. package/release-notes/resources/usage-guide.md +25 -0
  97. package/release-notes/resources/write.md +27 -0
  98. package/release-notes/user-config.md +15 -0
  99. package/skill-doctor/SKILL.md +53 -0
  100. package/skill-doctor/resources/checks.md +27 -0
  101. package/skill-doctor/resources/report.md +26 -0
  102. package/skill-doctor/resources/skillforge-guide.html +408 -0
  103. package/skill-doctor/resources/skillforge-guide.txt +131 -0
  104. package/skill-doctor/resources/usage-guide.md +22 -0
  105. package/skill-doctor/user-config.md +9 -0
  106. package/spec-doc2spec/SKILL.md +10 -0
  107. package/spec-doc2spec/resources/skillforge-guide.html +408 -0
  108. package/spec-doc2spec/resources/skillforge-guide.txt +131 -0
  109. package/spec-spec2doc/SKILL.md +10 -0
  110. package/spec-spec2doc/resources/skillforge-guide.html +408 -0
  111. package/spec-spec2doc/resources/skillforge-guide.txt +131 -0
  112. package/team-report-collector/SKILL.md +70 -0
  113. package/team-report-collector/resources/collect.md +23 -0
  114. package/team-report-collector/resources/generate.md +14 -0
  115. package/team-report-collector/resources/html-rules.md +22 -0
  116. package/team-report-collector/resources/reference.html +384 -0
  117. package/team-report-collector/resources/skillforge-guide.html +408 -0
  118. package/team-report-collector/resources/skillforge-guide.txt +131 -0
  119. package/team-report-collector/resources/usage-guide.md +25 -0
  120. package/team-report-collector/user-config.md +12 -0
  121. package/twin-docs/SKILL.md +53 -0
  122. package/twin-docs/resources/glossary.md +12 -0
  123. package/twin-docs/resources/skillforge-guide.html +408 -0
  124. package/twin-docs/resources/skillforge-guide.txt +131 -0
  125. package/twin-docs/resources/sync-check.md +15 -0
  126. package/twin-docs/resources/translate.md +20 -0
  127. package/twin-docs/resources/usage-guide.md +24 -0
  128. package/twin-docs/user-config.md +11 -0
  129. package/weekly-report/SKILL.md +10 -0
  130. package/weekly-report/resources/disk-and-html.md +1 -1
  131. package/weekly-report/resources/reference.html +1 -1
  132. package/weekly-report/resources/skillforge-guide.html +408 -0
  133. package/weekly-report/resources/skillforge-guide.txt +131 -0
@@ -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>